diff --git a/VERSION b/VERSION index f5d2f80..50cd108 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.72-beta +0.3.73-beta diff --git a/public/img/world/ATTRIBUTION.md b/public/img/world/ATTRIBUTION.md index 40474c2..16319f1 100644 --- a/public/img/world/ATTRIBUTION.md +++ b/public/img/world/ATTRIBUTION.md @@ -16,6 +16,16 @@ aan de hand van de bestandsbeschrijvingen op Wikimedia Commons. | `trees/maple.webp` | [Acer-pseudoplatanus](https://commons.wikimedia.org/wiki/File:Acer-pseudoplatanus.jpg) | MPF | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | | `trees/willow.webp` | [Salix alba an der Isar](https://commons.wikimedia.org/wiki/File:Salix_alba_an_der_Isar.jpg) | Burkhard Mücke | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | | `trees/alder.webp` | [Alnus glutinosa 011](https://commons.wikimedia.org/wiki/File:Alnus_glutinosa_011.jpg) | Willow | [CC BY 2.5](https://creativecommons.org/licenses/by/2.5/) | +| `trees/lime.webp` | [Winterlinde (Wiki Loves Earth 2015)](https://commons.wikimedia.org/wiki/File:012_2015_05_06_Winterlinde_(Wiki_Loves_Earth_2015).jpg) | Friedrich Haag | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `trees/ash.webp` | [Fraxinus excelsior 001](https://commons.wikimedia.org/wiki/File:Fraxinus_excelsior_001.jpg) | Willow | [CC BY 2.5](https://creativecommons.org/licenses/by/2.5/) | +| `trees/sweet-chestnut.webp` | [Anatolian sweet chestnut](https://commons.wikimedia.org/wiki/File:Castanea_sativa_-_Anatolian_sweet_chestnut_04.jpg) | Zeynel Cebeci | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `trees/rowan.webp` | [Rowan tree 20081002b](https://commons.wikimedia.org/wiki/File:Rowan_tree_20081002b.jpg) | Eeno11 | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `trees/hawthorn.webp` | [Crataegus monogyna in Joncret](https://commons.wikimedia.org/wiki/File:Crataegus_monogyna_in_Joncret_AR1aJPG.jpg) | Jean-Pol GRANDMONT | [CC BY 2.5](https://creativecommons.org/licenses/by/2.5/) | +| `trees/aspen.webp` | [Populus tremula 004](https://commons.wikimedia.org/wiki/File:Populus_tremula_004.jpg) | Willow | [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/) | +| `trees/spruce.webp` | [Kuusk Keila-Paldiski rdt ääres](https://commons.wikimedia.org/wiki/File:Kuusk_Keila-Paldiski_rdt_%C3%A4%C3%A4res.jpg) | Ivar Leidus | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `trees/larch.webp` | [European larch – Larix decidua](https://commons.wikimedia.org/wiki/File:European_larch_-_Larix_decidua.jpg) | MrPanyGoff | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `trees/yew.webp` | [Witch’s Yew Tree](https://commons.wikimedia.org/wiki/File:2020_Witch%E2%80%99s_Yew_Tree_IRL.jpg) | Blarney Castle Estate | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `trees/elm.webp` | [Ulmus minor tree](https://commons.wikimedia.org/wiki/File:Ulmus_minor_tree.jpg) | Ptelea | [Publiek domein](https://commons.wikimedia.org/wiki/Commons:Copyright_tags#Public_domain) | ## Bladeren en naalden @@ -29,6 +39,16 @@ aan de hand van de bestandsbeschrijvingen op Wikimedia Commons. | `leaves/maple.webp` | [Acer pseudoplatanus 003](https://commons.wikimedia.org/wiki/File:Acer_pseudoplatanus_003.jpg) | Willow | [CC BY 2.5](https://creativecommons.org/licenses/by/2.5/) | | `leaves/willow.webp` | [20160721Salix alba1](https://commons.wikimedia.org/wiki/File:20160721Salix_alba1.jpg) | AnRo0002 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | | `leaves/alder.webp` | [20200531Alnus glutinosa2](https://commons.wikimedia.org/wiki/File:20200531Alnus_glutinosa2.jpg) | AnRo0002 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | +| `leaves/lime.webp` | [Herbarium Tilia cordata img-007](https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Tilia_cordata._img-007.jpg) | Dmitry Makeev | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `leaves/ash.webp` | [Herbarium Fraxinus img-015](https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Fraxinus._img-015.jpg) | Dmitry Makeev | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `leaves/sweet-chestnut.webp` | [Castanea sativa leaves and immature fruit](https://commons.wikimedia.org/wiki/File:Castanea_sativa_leaves_and_immature_fruit.jpg) | Ekir | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `leaves/rowan.webp` | [Herbarium Sorbus aucuparia img-005](https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Sorbus_aucuparia._img-005.jpg) | Dmitry Makeev | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `leaves/hawthorn.webp` | [Crataegus monogyna – leaves and stipules](https://commons.wikimedia.org/wiki/File:(MHNT)_Crataegus_monogyna_-_Leaves_and_stipules.jpg) | Didier Descouens | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `leaves/aspen.webp` | [Herbarium Populus tremula img-017](https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Populus_tremula._img-017.jpg) | Dmitry Makeev | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `leaves/spruce.webp` | [Picea abies needles in Väsmestorp](https://commons.wikimedia.org/wiki/File:Picea_abies_needles_in_V%C3%A4smestorp_2024-10-29_(0261).jpg) | Achird | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `leaves/larch.webp` | [Larix decidua needles and male cones](https://commons.wikimedia.org/wiki/File:Larix_decidua_needles_and_male_cones.JPG) | Rosser1954 / Roger Griffith | [Publiek domein](https://commons.wikimedia.org/wiki/Commons:Copyright_tags#Public_domain) | +| `leaves/yew.webp` | [Yew berries](https://commons.wikimedia.org/wiki/File:Yew_berries_(50578142398).jpg) | hedera.baltica | [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/) | +| `leaves/elm.webp` | [Elm leaves (Ulmus minor)](https://commons.wikimedia.org/wiki/File:Elm_leaves_(Ulmus_minor).jpg) | Daniel Capilla | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | ## Vogels @@ -42,6 +62,33 @@ aan de hand van de bestandsbeschrijvingen op Wikimedia Commons. | `birds/house-sparrow.webp` | [Huismus, man](https://commons.wikimedia.org/wiki/File:Huismus,_man.jpg) | JrPol | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | | `birds/magpie.webp` | [Сорока (Pica pica), Калининград](https://commons.wikimedia.org/wiki/File:%D0%A1%D0%BE%D1%80%D0%BE%D0%BA%D0%B0_(Pica_pica),_%D0%9A%D0%B0%D0%BB%D0%B8%D0%BD%D0%B8%D0%BD%D0%B3%D1%80%D0%B0%D0%B4.jpg) | Dion Art | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | | `birds/woodpecker.webp` | [Grote bonte specht](https://commons.wikimedia.org/wiki/File:Grote_bonte_specht.JPG) | Usitea | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `birds/chaffinch.webp` | [Fringilla coelebs chaffinch male](https://commons.wikimedia.org/wiki/File:Fringilla_coelebs_chaffinch_male_edit2.jpg) | MichaelMaggs / Arad | [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/) | +| `birds/starling.webp` | [Sturnus vulgaris – England – standing](https://commons.wikimedia.org/wiki/File:Sturnus_vulgaris_-England_-standing-8.jpg) | Mark Robinson | [CC BY 2.0](https://creativecommons.org/licenses/by/2.0/) | +| `birds/grey-heron.webp` | [Grey heron 2022 04 03 03](https://commons.wikimedia.org/wiki/File:Grey_heron_2022_04_03_03.jpg) | Alexis Lours | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | +| `birds/mute-swan.webp` | [Wild Mute swan at Lake Geneva](https://commons.wikimedia.org/wiki/File:093_Wild_Mute_swan_at_Lake_Geneva_during_sunset_Photo_by_Giles_Laurent.jpg) | Giles Laurent | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `birds/coot.webp` | [Fulica atra – Common coot](https://commons.wikimedia.org/wiki/File:Fulica_atra_-_Common_coot,_Adana_2016-11-12_01-1.jpg) | Zeynel Cebeci | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `birds/greylag-goose.webp` | [Graugans Anser Anser](https://commons.wikimedia.org/wiki/File:Graugans_Anser_Anser.jpg) | H005 / Pro2 | [Publiek domein](https://commons.wikimedia.org/wiki/Commons:Copyright_tags#Public_domain) | +| `birds/collared-dove.webp` | [Eurasian Collared Dove](https://commons.wikimedia.org/wiki/File:Streptopelia_decaocto_-_Eurasian_Collared_Dove_05.jpg) | Zeynel Cebeci | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `birds/wren.webp` | [Eurasian wren](https://commons.wikimedia.org/wiki/File:Eurasian_wren_(Troglodytes_troglodytes).jpg) | Alexis Lours | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | +| `birds/buzzard.webp` | [Buteo buteo juv Log](https://commons.wikimedia.org/wiki/File:Buteo_buteo_juv_Log_(2).jpg) | Yerpo | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `birds/barn-owl.webp` | [Tyto alba 1 Luc Viatour](https://commons.wikimedia.org/wiki/File:Tyto_alba_1_Luc_Viatour.jpg) | Luc Viatour | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | + +## Wilde planten + +| Bestand | Bronwerk | Maker | Licentie | +| --- | --- | --- | --- | +| `plants/dandelion.webp` | [Paardenbloem (Taraxacum officinale)](https://commons.wikimedia.org/wiki/File:Paardenbloem_(Taraxacum_officinale)_06.JPG) | Dominicus Johannes Bergsma | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `plants/nettle.webp` | [Brandnetel, Urtica dioica](https://commons.wikimedia.org/wiki/File:Brandnetel,_Urtica_dioica,_Locatie,_Famberhorst.jpg) | Dominicus Johannes Bergsma | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `plants/daisy.webp` | [Bellis perennis full plant](https://commons.wikimedia.org/wiki/File:Bellis_perennis_full_plant.jpg) | Grand-Duc | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `plants/red-clover.webp` | [Trifolium pratense](https://commons.wikimedia.org/wiki/File:Trifolium_pratense_RF.jpg) | Robert Flogaus-Faust | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | +| `plants/white-deadnettle.webp` | [Lamium album](https://commons.wikimedia.org/wiki/File:Lamium_album_RF.jpg) | Robert Flogaus-Faust | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | +| `plants/cow-parsley.webp` | [Fluitenkruid (Anthriscus sylvestris)](https://commons.wikimedia.org/wiki/File:Fluitenkruid_(Anthriscus_sylvestris)_26-04-2020._(actm.)_02.jpg) | Agnes Monkelbaan | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `plants/yarrow.webp` | [Achillea millefolium](https://commons.wikimedia.org/wiki/File:Achillea_millefolium_(52354).jpg) | Rhododendrites | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `plants/ribwort-plantain.webp` | [Plantago lanceolata kz09](https://commons.wikimedia.org/wiki/File:Plantago_lanceolata_kz09.jpg) | Krzysztof Ziarnek, Kenraiz | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `plants/common-poppy.webp` | [Papaver rhoeas LC0050](https://commons.wikimedia.org/wiki/File:Papaver_rhoeas_LC0050.jpg) | Jörg Hempel | [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/) | +| `plants/chicory.webp` | [Cichorium intybus](https://commons.wikimedia.org/wiki/File:Cichorium_intybus_TK_2021-07-12_1.jpg) | T. Kebert | [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | +| `plants/foxglove.webp` | [Digitalis purpurea LC0101](https://commons.wikimedia.org/wiki/File:Digitalis_purpurea_LC0101.jpg) | Jörg Hempel | [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) | +| `plants/common-sorrel.webp` | [Rumex acetosa in Aveyron](https://commons.wikimedia.org/wiki/File:Rumex_acetosa_in_Aveyron_(7).jpg) | Tournasol7 | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | ## Topografie diff --git a/public/img/world/birds/barn-owl.webp b/public/img/world/birds/barn-owl.webp new file mode 100644 index 0000000..af020c0 Binary files /dev/null and b/public/img/world/birds/barn-owl.webp differ diff --git a/public/img/world/birds/buzzard.webp b/public/img/world/birds/buzzard.webp new file mode 100644 index 0000000..3a26689 Binary files /dev/null and b/public/img/world/birds/buzzard.webp differ diff --git a/public/img/world/birds/chaffinch.webp b/public/img/world/birds/chaffinch.webp new file mode 100644 index 0000000..18940a4 Binary files /dev/null and b/public/img/world/birds/chaffinch.webp differ diff --git a/public/img/world/birds/collared-dove.webp b/public/img/world/birds/collared-dove.webp new file mode 100644 index 0000000..697842f Binary files /dev/null and b/public/img/world/birds/collared-dove.webp differ diff --git a/public/img/world/birds/coot.webp b/public/img/world/birds/coot.webp new file mode 100644 index 0000000..a8faa54 Binary files /dev/null and b/public/img/world/birds/coot.webp differ diff --git a/public/img/world/birds/grey-heron.webp b/public/img/world/birds/grey-heron.webp new file mode 100644 index 0000000..ba10791 Binary files /dev/null and b/public/img/world/birds/grey-heron.webp differ diff --git a/public/img/world/birds/greylag-goose.webp b/public/img/world/birds/greylag-goose.webp new file mode 100644 index 0000000..b90604b Binary files /dev/null and b/public/img/world/birds/greylag-goose.webp differ diff --git a/public/img/world/birds/mute-swan.webp b/public/img/world/birds/mute-swan.webp new file mode 100644 index 0000000..cb2329c Binary files /dev/null and b/public/img/world/birds/mute-swan.webp differ diff --git a/public/img/world/birds/starling.webp b/public/img/world/birds/starling.webp new file mode 100644 index 0000000..d093a63 Binary files /dev/null and b/public/img/world/birds/starling.webp differ diff --git a/public/img/world/birds/wren.webp b/public/img/world/birds/wren.webp new file mode 100644 index 0000000..cc6bd22 Binary files /dev/null and b/public/img/world/birds/wren.webp differ diff --git a/public/img/world/leaves/ash.webp b/public/img/world/leaves/ash.webp new file mode 100644 index 0000000..6e33f55 Binary files /dev/null and b/public/img/world/leaves/ash.webp differ diff --git a/public/img/world/leaves/aspen.webp b/public/img/world/leaves/aspen.webp new file mode 100644 index 0000000..b012fda Binary files /dev/null and b/public/img/world/leaves/aspen.webp differ diff --git a/public/img/world/leaves/elm.webp b/public/img/world/leaves/elm.webp new file mode 100644 index 0000000..9227e4d Binary files /dev/null and b/public/img/world/leaves/elm.webp differ diff --git a/public/img/world/leaves/hawthorn.webp b/public/img/world/leaves/hawthorn.webp new file mode 100644 index 0000000..bbcc94e Binary files /dev/null and b/public/img/world/leaves/hawthorn.webp differ diff --git a/public/img/world/leaves/larch.webp b/public/img/world/leaves/larch.webp new file mode 100644 index 0000000..da3d326 Binary files /dev/null and b/public/img/world/leaves/larch.webp differ diff --git a/public/img/world/leaves/lime.webp b/public/img/world/leaves/lime.webp new file mode 100644 index 0000000..ebcbaee Binary files /dev/null and b/public/img/world/leaves/lime.webp differ diff --git a/public/img/world/leaves/rowan.webp b/public/img/world/leaves/rowan.webp new file mode 100644 index 0000000..e779fc2 Binary files /dev/null and b/public/img/world/leaves/rowan.webp differ diff --git a/public/img/world/leaves/spruce.webp b/public/img/world/leaves/spruce.webp new file mode 100644 index 0000000..e09023b Binary files /dev/null and b/public/img/world/leaves/spruce.webp differ diff --git a/public/img/world/leaves/sweet-chestnut.webp b/public/img/world/leaves/sweet-chestnut.webp new file mode 100644 index 0000000..5a09972 Binary files /dev/null and b/public/img/world/leaves/sweet-chestnut.webp differ diff --git a/public/img/world/leaves/yew.webp b/public/img/world/leaves/yew.webp new file mode 100644 index 0000000..1c4c791 Binary files /dev/null and b/public/img/world/leaves/yew.webp differ diff --git a/public/img/world/plants/chicory.webp b/public/img/world/plants/chicory.webp new file mode 100644 index 0000000..c948d16 Binary files /dev/null and b/public/img/world/plants/chicory.webp differ diff --git a/public/img/world/plants/common-poppy.webp b/public/img/world/plants/common-poppy.webp new file mode 100644 index 0000000..50be211 Binary files /dev/null and b/public/img/world/plants/common-poppy.webp differ diff --git a/public/img/world/plants/common-sorrel.webp b/public/img/world/plants/common-sorrel.webp new file mode 100644 index 0000000..c5017cc Binary files /dev/null and b/public/img/world/plants/common-sorrel.webp differ diff --git a/public/img/world/plants/cow-parsley.webp b/public/img/world/plants/cow-parsley.webp new file mode 100644 index 0000000..e5af540 Binary files /dev/null and b/public/img/world/plants/cow-parsley.webp differ diff --git a/public/img/world/plants/daisy.webp b/public/img/world/plants/daisy.webp new file mode 100644 index 0000000..6145949 Binary files /dev/null and b/public/img/world/plants/daisy.webp differ diff --git a/public/img/world/plants/dandelion.webp b/public/img/world/plants/dandelion.webp new file mode 100644 index 0000000..d37fd0d Binary files /dev/null and b/public/img/world/plants/dandelion.webp differ diff --git a/public/img/world/plants/foxglove.webp b/public/img/world/plants/foxglove.webp new file mode 100644 index 0000000..480a58d Binary files /dev/null and b/public/img/world/plants/foxglove.webp differ diff --git a/public/img/world/plants/nettle.webp b/public/img/world/plants/nettle.webp new file mode 100644 index 0000000..88efd57 Binary files /dev/null and b/public/img/world/plants/nettle.webp differ diff --git a/public/img/world/plants/red-clover.webp b/public/img/world/plants/red-clover.webp new file mode 100644 index 0000000..f22d64e Binary files /dev/null and b/public/img/world/plants/red-clover.webp differ diff --git a/public/img/world/plants/ribwort-plantain.webp b/public/img/world/plants/ribwort-plantain.webp new file mode 100644 index 0000000..9751e09 Binary files /dev/null and b/public/img/world/plants/ribwort-plantain.webp differ diff --git a/public/img/world/plants/white-deadnettle.webp b/public/img/world/plants/white-deadnettle.webp new file mode 100644 index 0000000..f5563c5 Binary files /dev/null and b/public/img/world/plants/white-deadnettle.webp differ diff --git a/public/img/world/plants/yarrow.webp b/public/img/world/plants/yarrow.webp new file mode 100644 index 0000000..852acf3 Binary files /dev/null and b/public/img/world/plants/yarrow.webp differ diff --git a/public/img/world/trees/ash.webp b/public/img/world/trees/ash.webp new file mode 100644 index 0000000..60186e4 Binary files /dev/null and b/public/img/world/trees/ash.webp differ diff --git a/public/img/world/trees/aspen.webp b/public/img/world/trees/aspen.webp new file mode 100644 index 0000000..1769081 Binary files /dev/null and b/public/img/world/trees/aspen.webp differ diff --git a/public/img/world/trees/elm.webp b/public/img/world/trees/elm.webp new file mode 100644 index 0000000..dc8c563 Binary files /dev/null and b/public/img/world/trees/elm.webp differ diff --git a/public/img/world/trees/hawthorn.webp b/public/img/world/trees/hawthorn.webp new file mode 100644 index 0000000..ec18a3e Binary files /dev/null and b/public/img/world/trees/hawthorn.webp differ diff --git a/public/img/world/trees/larch.webp b/public/img/world/trees/larch.webp new file mode 100644 index 0000000..ec67193 Binary files /dev/null and b/public/img/world/trees/larch.webp differ diff --git a/public/img/world/trees/lime.webp b/public/img/world/trees/lime.webp new file mode 100644 index 0000000..80edde6 Binary files /dev/null and b/public/img/world/trees/lime.webp differ diff --git a/public/img/world/trees/rowan.webp b/public/img/world/trees/rowan.webp new file mode 100644 index 0000000..1da8d66 Binary files /dev/null and b/public/img/world/trees/rowan.webp differ diff --git a/public/img/world/trees/spruce.webp b/public/img/world/trees/spruce.webp new file mode 100644 index 0000000..a140bec Binary files /dev/null and b/public/img/world/trees/spruce.webp differ diff --git a/public/img/world/trees/sweet-chestnut.webp b/public/img/world/trees/sweet-chestnut.webp new file mode 100644 index 0000000..899e16c Binary files /dev/null and b/public/img/world/trees/sweet-chestnut.webp differ diff --git a/public/img/world/trees/yew.webp b/public/img/world/trees/yew.webp new file mode 100644 index 0000000..d59de8a Binary files /dev/null and b/public/img/world/trees/yew.webp differ diff --git a/public/js/board.js b/public/js/board.js index d1be138..f56ec7f 100644 --- a/public/js/board.js +++ b/public/js/board.js @@ -48,6 +48,7 @@ const REGISTRY = [ { id:"wordtypes", cat:"taal", icon:"🎨", w:600, h:410, minW:380, minH:290, mount:mountWordtypes }, { id:"trees", cat:"world", icon:"🌳", w:620, h:600, minW:360, minH:400, mount:mountTrees }, { id:"birds", cat:"world", icon:"🐦", w:620, h:600, minW:360, minH:400, mount:mountBirds }, + { id:"plants", cat:"world", icon:"🌼", w:620, h:600, minW:360, minH:400, mount:mountPlants }, { id:"topography", cat:"world", icon:"🗺️", w:680, h:640, minW:380, minH:440, mount:mountTopography }, { id:"write", cat:"tools", icon:"✏️", w:560, h:440, minW:360, minH:280, mount:mountWrite }, { id:"mind", cat:"tools", icon:"🕸️", w:640, h:480, minW:420, minH:320, mount:mountMind }, @@ -1567,4 +1568,3 @@ function renderStrip(){ boardStrip.appendChild(add); } document.addEventListener("langchange", updateBoardsUI); - diff --git a/public/js/core.js b/public/js/core.js index 632db56..9c61d77 100644 --- a/public/js/core.js +++ b/public/js/core.js @@ -2,7 +2,7 @@ "use strict"; /* version — shown until /api/version resolves (or if the fetch fails, e.g. offline). Kept in sync by hand with the VERSION file at the repo root on every release. */ -const VERSION = "0.3.72-beta"; +const VERSION = "0.3.73-beta"; (function(){ const tag = document.getElementById("verTag"); tag.textContent = "v"+VERSION; @@ -119,15 +119,16 @@ const I18N = { wg_clock:"Oefenklok", wg_clock_d:"Leer kloktijden op vier niveaus met meerdere leerwijzen en spellen.", wg_placevalue:"Plaatswaardetabel", wg_placevalue_d:"Ontdek de waarde van cijfers tot honderdduizend.", wg_money:"Geldrekenen", wg_money_d:"Oefen bedragen maken, geld tellen en wisselgeld op drie niveaus.", - wg_trees:"Bomen & bladeren", wg_trees_d:"Leer acht Nederlandse boomsoorten met vijf foto-, kenmerk- en koppeloefeningen.", - wg_birds:"Vogels herkennen", wg_birds_d:"Leer acht Nederlandse vogels met vier foto-, kenmerk- en naamoefeningen.", + wg_trees:"Bomen & bladeren", wg_trees_d:"Leer achttien Nederlandse boomsoorten met vijf foto-, kenmerk- en koppeloefeningen.", + wg_birds:"Vogels herkennen", wg_birds_d:"Leer achttien Nederlandse vogels met vier foto-, kenmerk- en naamoefeningen.", + wg_plants:"Wilde planten", wg_plants_d:"Herken twaalf algemene wilde planten aan echte foto's en duidelijke veldkenmerken.", wg_topography:"Topografie Nederland", wg_topography_d:"Oefen provincies, plaatsen, landsdelen, rivieren en werelddelen op nauwkeurige kaarten.", worldActivity:"Werkvorm", worldLearn:"Leren", worldQuiz:"Quiz", worldExercise:"Oefening", worldLevel:"Niveau", worldTreeView:"Wat zie je?", worldTreeWhole:"Hele boom", worldTreeLeaf:"Blad", worldTreeMixed:"Boom en blad", worldExerciseRecognize:"Herken de soort", worldExercisePair:"Koppel boom en blad", worldExerciseClue:"Raad met kenmerken", worldExercisePhoto:"Kies de juiste foto", worldExerciseLatin:"Wetenschappelijke naam", - worldScore:"Score: {score} · reeks: {streak}", worldExploreHint:"Bekijk de kenmerken en vergelijk de soorten.", worldQuestionTree:"Welke boom zie je?", worldQuestionLeaf:"Bij welke boom hoort dit blad?", worldQuestionBird:"Welke vogel zie je?", - worldQuestionPair:"Bij welke boom horen deze boom en dit blad?", worldQuestionClue:"Welke soort hoort bij deze kenmerken?", worldQuestionLatin:"Welke soort hoort bij deze wetenschappelijke naam?", worldFindTreePhoto:"Tik op de foto van de {name}.", worldFindBirdPhoto:"Tik op de foto van de {name}.", + worldScore:"Score: {score} · reeks: {streak}", worldExploreHint:"Bekijk de kenmerken en vergelijk de soorten.", worldQuestionTree:"Welke boom zie je?", worldQuestionLeaf:"Bij welke boom hoort dit blad?", worldQuestionBird:"Welke vogel zie je?", worldQuestionPlant:"Welke wilde plant zie je?", + worldQuestionPair:"Bij welke boom horen deze boom en dit blad?", worldQuestionClue:"Welke soort hoort bij deze kenmerken?", worldQuestionLatin:"Welke soort hoort bij deze wetenschappelijke naam?", worldFindTreePhoto:"Tik op de foto van de {name}.", worldFindBirdPhoto:"Tik op de foto van de {name}.", worldFindPlantPhoto:"Tik op de foto van de {name}.", worldCorrect:"Goed herkend! 🌟", worldTryAgain:"Kijk nog eens goed naar de kenmerken.", worldNext:"Volgende opdracht", - worldPhotoTree:"Boom", worldPhotoLeaf:"Blad of naalden", worldPhotoBird:"Vogel", worldPhotoCredit:"Foto: {author} · {license}", worldPhotoOption:"Afbeelding {number}", + worldPhotoTree:"Boom", worldPhotoLeaf:"Blad of naalden", worldPhotoBird:"Vogel", worldPhotoPlant:"Wilde plant", worldPhotoCredit:"Foto: {author} · {license}", worldPhotoOption:"Afbeelding {number}", topoMode:"Oefenen met", topoProvinces:"Provincies", topoCapitals:"Provinciehoofdsteden", topoCities:"Belangrijke steden", topoRegions:"Landsdelen", topoRivers:"Rivieren", topoContinents:"Werelddelen", topoMapLabel:"Kaart van Nederland", topoWorldMapLabel:"Kaart van de wereld", topoExploreHint:"Bekijk de echte provinciegrenzen en vergelijk de ligging van de plaatsen.", topoExploreRegions:"Bekijk welke provincies samen Noord-, Oost-, West- en Zuid-Nederland vormen.", topoExploreRivers:"Volg de loop van de grote Nederlandse rivieren van grens tot delta.", topoExploreContinents:"Vergelijk de vorm en ligging van de zeven werelddelen.", topoFindProvince:"Tik op de provincie {name}.", topoFindCapital:"Waar ligt provinciehoofdstad {name}?", topoFindCity:"Waar ligt {name}?", topoFindRegion:"Tik op {name}.", topoFindRiver:"Tik op de rivier {name}.", topoFindContinent:"Tik op het werelddeel {name}.", topoMapSource:"Kaart: Gust Justice · CC BY-SA 4.0", topoWorldMapSource:"Wereldkaart: Natural Earth · publiek domein", @@ -392,15 +393,16 @@ const I18N = { wg_clock:"Practice clock", wg_clock_d:"Learn time at four levels with multiple learning styles and games.", wg_placevalue:"Place value", wg_placevalue_d:"Explore digit values up to hundred thousands.", wg_money:"Money", wg_money_d:"Practise making amounts, counting money and change at three levels.", - wg_trees:"Trees & leaves", wg_trees_d:"Learn eight Dutch tree species with five photo, feature and matching exercises.", - wg_birds:"Bird identification", wg_birds_d:"Learn eight Dutch birds with four photo, feature and naming exercises.", + wg_trees:"Trees & leaves", wg_trees_d:"Learn eighteen Dutch tree species with five photo, feature and matching exercises.", + wg_birds:"Bird identification", wg_birds_d:"Learn eighteen Dutch birds with four photo, feature and naming exercises.", + wg_plants:"Wild plants", wg_plants_d:"Recognise twelve common wild plants from real photographs and clear field marks.", wg_topography:"Map of the Netherlands", wg_topography_d:"Practise provinces, places, regions, rivers and continents on accurate maps.", worldActivity:"Activity", worldLearn:"Learn", worldQuiz:"Quiz", worldExercise:"Exercise", worldLevel:"Level", worldTreeView:"What do you see?", worldTreeWhole:"Whole tree", worldTreeLeaf:"Leaf", worldTreeMixed:"Tree and leaf", worldExerciseRecognize:"Recognise the species", worldExercisePair:"Match tree and leaf", worldExerciseClue:"Guess from features", worldExercisePhoto:"Choose the correct photo", worldExerciseLatin:"Scientific name", - worldScore:"Score: {score} · streak: {streak}", worldExploreHint:"Study the features and compare the species.", worldQuestionTree:"Which tree do you see?", worldQuestionLeaf:"Which tree does this leaf belong to?", worldQuestionBird:"Which bird do you see?", - worldQuestionPair:"Which species do this tree and leaf belong to?", worldQuestionClue:"Which species matches these features?", worldQuestionLatin:"Which species matches this scientific name?", worldFindTreePhoto:"Tap the photograph of the {name}.", worldFindBirdPhoto:"Tap the photograph of the {name}.", + worldScore:"Score: {score} · streak: {streak}", worldExploreHint:"Study the features and compare the species.", worldQuestionTree:"Which tree do you see?", worldQuestionLeaf:"Which tree does this leaf belong to?", worldQuestionBird:"Which bird do you see?", worldQuestionPlant:"Which wild plant do you see?", + worldQuestionPair:"Which species do this tree and leaf belong to?", worldQuestionClue:"Which species matches these features?", worldQuestionLatin:"Which species matches this scientific name?", worldFindTreePhoto:"Tap the photograph of the {name}.", worldFindBirdPhoto:"Tap the photograph of the {name}.", worldFindPlantPhoto:"Tap the photograph of the {name}.", worldCorrect:"Well recognised! 🌟", worldTryAgain:"Take another close look at the features.", worldNext:"Next task", - worldPhotoTree:"Tree", worldPhotoLeaf:"Leaf or needles", worldPhotoBird:"Bird", worldPhotoCredit:"Photo: {author} · {license}", worldPhotoOption:"Image {number}", + worldPhotoTree:"Tree", worldPhotoLeaf:"Leaf or needles", worldPhotoBird:"Bird", worldPhotoPlant:"Wild plant", worldPhotoCredit:"Photo: {author} · {license}", worldPhotoOption:"Image {number}", topoMode:"Practise", topoProvinces:"Provinces", topoCapitals:"Provincial capitals", topoCities:"Important cities", topoRegions:"Regions", topoRivers:"Rivers", topoContinents:"Continents", topoMapLabel:"Map of the Netherlands", topoWorldMapLabel:"Map of the world", topoExploreHint:"Study the real provincial boundaries and compare the locations of the places.", topoExploreRegions:"Study which provinces make up the northern, eastern, western and southern Netherlands.", topoExploreRivers:"Follow the major Dutch rivers from the border to the delta.", topoExploreContinents:"Compare the shapes and locations of the seven continents.", topoFindProvince:"Tap the province {name}.", topoFindCapital:"Where is the provincial capital {name}?", topoFindCity:"Where is {name}?", topoFindRegion:"Tap {name}.", topoFindRiver:"Tap the river {name}.", topoFindContinent:"Tap the continent {name}.", topoMapSource:"Map: Gust Justice · CC BY-SA 4.0", topoWorldMapSource:"World map: Natural Earth · public domain", diff --git a/public/js/widgets/world.js b/public/js/widgets/world.js index b25b3cb..8af4c1b 100644 --- a/public/js/widgets/world.js +++ b/public/js/widgets/world.js @@ -36,6 +36,46 @@ const WORLD_MEDIA=Object.freeze({ tree:worldMedia("trees/alder.webp","Willow","CC BY 2.5","https://commons.wikimedia.org/wiki/File:Alnus_glutinosa_011.jpg"), leaf:worldMedia("leaves/alder.webp","AnRo0002","CC0 1.0","https://commons.wikimedia.org/wiki/File:20200531Alnus_glutinosa2.jpg"), }, + lime:{ + tree:worldMedia("trees/lime.webp","Friedrich Haag","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:012_2015_05_06_Winterlinde_(Wiki_Loves_Earth_2015).jpg"), + leaf:worldMedia("leaves/lime.webp","Dmitry Makeev","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Tilia_cordata._img-007.jpg"), + }, + ash:{ + tree:worldMedia("trees/ash.webp","Willow","CC BY 2.5","https://commons.wikimedia.org/wiki/File:Fraxinus_excelsior_001.jpg"), + leaf:worldMedia("leaves/ash.webp","Dmitry Makeev","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Fraxinus._img-015.jpg"), + }, + sweet_chestnut:{ + tree:worldMedia("trees/sweet-chestnut.webp","Zeynel Cebeci","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Castanea_sativa_-_Anatolian_sweet_chestnut_04.jpg"), + leaf:worldMedia("leaves/sweet-chestnut.webp","Ekir","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Castanea_sativa_leaves_and_immature_fruit.jpg"), + }, + rowan:{ + tree:worldMedia("trees/rowan.webp","Eeno11","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Rowan_tree_20081002b.jpg"), + leaf:worldMedia("leaves/rowan.webp","Dmitry Makeev","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Sorbus_aucuparia._img-005.jpg"), + }, + hawthorn:{ + tree:worldMedia("trees/hawthorn.webp","Jean-Pol GRANDMONT","CC BY 2.5","https://commons.wikimedia.org/wiki/File:Crataegus_monogyna_in_Joncret_AR1aJPG.jpg"), + leaf:worldMedia("leaves/hawthorn.webp","Didier Descouens","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:(MHNT)_Crataegus_monogyna_-_Leaves_and_stipules.jpg"), + }, + aspen:{ + tree:worldMedia("trees/aspen.webp","Willow","CC BY-SA 2.5","https://commons.wikimedia.org/wiki/File:Populus_tremula_004.jpg"), + leaf:worldMedia("leaves/aspen.webp","Dmitry Makeev","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:2020_year._Herbarium._Populus_tremula._img-017.jpg"), + }, + spruce:{ + tree:worldMedia("trees/spruce.webp","Ivar Leidus","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Kuusk_Keila-Paldiski_rdt_%C3%A4%C3%A4res.jpg"), + leaf:worldMedia("leaves/spruce.webp","Achird","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Picea_abies_needles_in_V%C3%A4smestorp_2024-10-29_(0261).jpg"), + }, + larch:{ + tree:worldMedia("trees/larch.webp","MrPanyGoff","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:European_larch_-_Larix_decidua.jpg"), + leaf:worldMedia("leaves/larch.webp","Rosser1954 / Roger Griffith","Public domain","https://commons.wikimedia.org/wiki/File:Larix_decidua_needles_and_male_cones.JPG"), + }, + yew:{ + tree:worldMedia("trees/yew.webp","Blarney Castle Estate","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:2020_Witch%E2%80%99s_Yew_Tree_IRL.jpg"), + leaf:worldMedia("leaves/yew.webp","hedera.baltica","CC BY-SA 2.0","https://commons.wikimedia.org/wiki/File:Yew_berries_(50578142398).jpg"), + }, + elm:{ + tree:worldMedia("trees/elm.webp","Ptelea","Public domain","https://commons.wikimedia.org/wiki/File:Ulmus_minor_tree.jpg"), + leaf:worldMedia("leaves/elm.webp","Daniel Capilla","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Elm_leaves_(Ulmus_minor).jpg"), + }, robin:{bird:worldMedia("birds/robin.webp","Rasbak","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Erithacus_rubecula,_Roodborstje.jpg")}, great_tit:{bird:worldMedia("birds/great-tit.webp","Sławek Staszczuk","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Parus_major_m.jpg")}, blackbird:{bird:worldMedia("birds/blackbird.webp","Malene Thyssen","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Solsort.jpg")}, @@ -44,6 +84,28 @@ const WORLD_MEDIA=Object.freeze({ house_sparrow:{bird:worldMedia("birds/house-sparrow.webp","JrPol","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Huismus,_man.jpg")}, magpie:{bird:worldMedia("birds/magpie.webp","Dion Art","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:%D0%A1%D0%BE%D1%80%D0%BE%D0%BA%D0%B0_(Pica_pica),_%D0%9A%D0%B0%D0%BB%D0%B8%D0%BD%D0%B8%D0%BD%D0%B3%D1%80%D0%B0%D0%B4.jpg")}, woodpecker:{bird:worldMedia("birds/woodpecker.webp","Usitea","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Grote_bonte_specht.JPG")}, + chaffinch:{bird:worldMedia("birds/chaffinch.webp","MichaelMaggs / Arad","CC BY-SA 2.5","https://commons.wikimedia.org/wiki/File:Fringilla_coelebs_chaffinch_male_edit2.jpg")}, + starling:{bird:worldMedia("birds/starling.webp","Mark Robinson","CC BY 2.0","https://commons.wikimedia.org/wiki/File:Sturnus_vulgaris_-England_-standing-8.jpg")}, + grey_heron:{bird:worldMedia("birds/grey-heron.webp","Alexis Lours","CC BY 4.0","https://commons.wikimedia.org/wiki/File:Grey_heron_2022_04_03_03.jpg")}, + mute_swan:{bird:worldMedia("birds/mute-swan.webp","Giles Laurent","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:093_Wild_Mute_swan_at_Lake_Geneva_during_sunset_Photo_by_Giles_Laurent.jpg")}, + coot:{bird:worldMedia("birds/coot.webp","Zeynel Cebeci","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Fulica_atra_-_Common_coot,_Adana_2016-11-12_01-1.jpg")}, + greylag_goose:{bird:worldMedia("birds/greylag-goose.webp","H005 / Pro2","Public domain","https://commons.wikimedia.org/wiki/File:Graugans_Anser_Anser.jpg")}, + collared_dove:{bird:worldMedia("birds/collared-dove.webp","Zeynel Cebeci","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Streptopelia_decaocto_-_Eurasian_Collared_Dove_05.jpg")}, + wren:{bird:worldMedia("birds/wren.webp","Alexis Lours","CC BY 4.0","https://commons.wikimedia.org/wiki/File:Eurasian_wren_(Troglodytes_troglodytes).jpg")}, + buzzard:{bird:worldMedia("birds/buzzard.webp","Yerpo","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Buteo_buteo_juv_Log_(2).jpg")}, + barn_owl:{bird:worldMedia("birds/barn-owl.webp","Luc Viatour","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Tyto_alba_1_Luc_Viatour.jpg")}, + dandelion:{plant:worldMedia("plants/dandelion.webp","Dominicus Johannes Bergsma","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Paardenbloem_(Taraxacum_officinale)_06.JPG")}, + nettle:{plant:worldMedia("plants/nettle.webp","Dominicus Johannes Bergsma","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Brandnetel,_Urtica_dioica,_Locatie,_Famberhorst.jpg")}, + daisy:{plant:worldMedia("plants/daisy.webp","Grand-Duc","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Bellis_perennis_full_plant.jpg")}, + red_clover:{plant:worldMedia("plants/red-clover.webp","Robert Flogaus-Faust","CC BY 4.0","https://commons.wikimedia.org/wiki/File:Trifolium_pratense_RF.jpg")}, + white_deadnettle:{plant:worldMedia("plants/white-deadnettle.webp","Robert Flogaus-Faust","CC BY 4.0","https://commons.wikimedia.org/wiki/File:Lamium_album_RF.jpg")}, + cow_parsley:{plant:worldMedia("plants/cow-parsley.webp","Agnes Monkelbaan","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Fluitenkruid_(Anthriscus_sylvestris)_26-04-2020._(actm.)_02.jpg")}, + yarrow:{plant:worldMedia("plants/yarrow.webp","Rhododendrites","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Achillea_millefolium_(52354).jpg")}, + ribwort_plantain:{plant:worldMedia("plants/ribwort-plantain.webp","Krzysztof Ziarnek, Kenraiz","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Plantago_lanceolata_kz09.jpg")}, + common_poppy:{plant:worldMedia("plants/common-poppy.webp","Jörg Hempel","CC BY-SA 2.5","https://commons.wikimedia.org/wiki/File:Papaver_rhoeas_LC0050.jpg")}, + chicory:{plant:worldMedia("plants/chicory.webp","T. Kebert","CC BY-SA 4.0","https://commons.wikimedia.org/wiki/File:Cichorium_intybus_TK_2021-07-12_1.jpg")}, + foxglove:{plant:worldMedia("plants/foxglove.webp","Jörg Hempel","CC BY-SA 3.0","https://commons.wikimedia.org/wiki/File:Digitalis_purpurea_LC0101.jpg")}, + common_sorrel:{plant:worldMedia("plants/common-sorrel.webp","Tournasol7","CC BY 4.0","https://commons.wikimedia.org/wiki/File:Rumex_acetosa_in_Aveyron_(7).jpg")}, }); const WORLD_TREES=Object.freeze([ @@ -55,6 +117,16 @@ const WORLD_TREES=Object.freeze([ {id:"maple",nl:"Gewone esdoorn",en:"Sycamore maple",latin:"Acer pseudoplatanus",tier:2,hintNl:"Groot handvormig blad met vijf puntige lobben en gevleugelde zaden.",hintEn:"Large hand-shaped leaf with five pointed lobes and winged seeds."}, {id:"willow",nl:"Schietwilg",en:"White willow",latin:"Salix alba",tier:3,hintNl:"Brede, losse kroon en lange smalle bladeren met een zilverige onderkant.",hintEn:"Broad open crown and long narrow leaves with a silvery underside."}, {id:"alder",nl:"Zwarte els",en:"Black alder",latin:"Alnus glutinosa",tier:3,hintNl:"Ronde bladeren met een ingedeukte top en kleine houtige elzenproppen.",hintEn:"Rounded leaves with a notched tip and small woody alder cones."}, + {id:"lime",nl:"Winterlinde",en:"Small-leaved lime",latin:"Tilia cordata",tier:1,hintNl:"Hartvormige bladeren en kleine nootjes aan een bleek, vleugelachtig schutblad.",hintEn:"Heart-shaped leaves and small nutlets attached to a pale, wing-like bract."}, + {id:"ash",nl:"Gewone es",en:"European ash",latin:"Fraxinus excelsior",tier:1,hintNl:"Zwarte knoppen en geveerde bladeren met zeven tot dertien deelblaadjes.",hintEn:"Black buds and pinnate leaves with seven to thirteen leaflets."}, + {id:"sweet_chestnut",nl:"Tamme kastanje",en:"Sweet chestnut",latin:"Castanea sativa",tier:1,hintNl:"Lange, scherp gezaagde bladeren en kastanjes in een dicht stekelige bolster.",hintEn:"Long, sharply toothed leaves and chestnuts in a densely spiny husk."}, + {id:"rowan",nl:"Wilde lijsterbes",en:"Rowan",latin:"Sorbus aucuparia",tier:2,hintNl:"Geveerde bladeren, witte bloemschermen en trossen oranjerode bessen.",hintEn:"Pinnate leaves, clusters of white flowers and bunches of orange-red berries."}, + {id:"hawthorn",nl:"Eenstijlige meidoorn",en:"Common hawthorn",latin:"Crataegus monogyna",tier:2,hintNl:"Doornige takken, diep gelobde bladeren, witte bloemen en rode vruchten.",hintEn:"Thorny branches, deeply lobed leaves, white flowers and red fruits."}, + {id:"aspen",nl:"Ratelpopulier",en:"Aspen",latin:"Populus tremula",tier:2,hintNl:"Bijna ronde bladeren aan een afgeplatte steel die al bij weinig wind trillen.",hintEn:"Almost round leaves on a flattened stalk that tremble in the slightest breeze."}, + {id:"spruce",nl:"Fijnspar",en:"Norway spruce",latin:"Picea abies",tier:2,hintNl:"Korte scherpe naalden rondom de twijg en lange kegels die omlaag hangen.",hintEn:"Short sharp needles all around the twig and long cones that hang down."}, + {id:"larch",nl:"Europese lariks",en:"European larch",latin:"Larix decidua",tier:3,hintNl:"Zachte naalden in bundeltjes; als enige gewone naaldboom laat hij ze in de herfst vallen.",hintEn:"Soft needles in clusters; unlike most conifers it sheds them in autumn."}, + {id:"yew",nl:"Taxus",en:"European yew",latin:"Taxus baccata",tier:3,hintNl:"Donkergroene platte naalden en rode besachtige zaadmantels; de plant is giftig.",hintEn:"Dark green flat needles and red berry-like arils; the plant is poisonous."}, + {id:"elm",nl:"Gladde iep",en:"Field elm",latin:"Ulmus minor",tier:3,hintNl:"Ruwe gezaagde bladeren met een opvallend scheve bladvoet.",hintEn:"Rough, toothed leaves with a noticeably uneven base."}, ]); const WORLD_BIRDS=Object.freeze([ @@ -66,6 +138,31 @@ const WORLD_BIRDS=Object.freeze([ {id:"house_sparrow",nl:"Huismus",en:"House sparrow",latin:"Passer domesticus",tier:2,hintNl:"Bruin gestreepte rug; het mannetje heeft een grijze kruin en zwarte bef.",hintEn:"Brown streaked back; the male has a grey crown and black bib."}, {id:"magpie",nl:"Ekster",en:"Eurasian magpie",latin:"Pica pica",tier:3,hintNl:"Zwart-wit verenkleed met blauwgroene glans en een opvallend lange staart.",hintEn:"Black-and-white plumage with a blue-green sheen and a very long tail."}, {id:"woodpecker",nl:"Grote bonte specht",en:"Great spotted woodpecker",latin:"Dendrocopos major",tier:3,hintNl:"Zwart-wit met rode veren onder de staart; het mannetje heeft rood in de nek.",hintEn:"Black and white with red beneath the tail; the male has red on the nape."}, + {id:"chaffinch",nl:"Vink",en:"Common chaffinch",latin:"Fringilla coelebs",tier:1,hintNl:"Het mannetje heeft een blauwgrijze kop, roestbruine borst en twee witte vleugelstrepen.",hintEn:"The male has a blue-grey head, rusty breast and two white wing bars."}, + {id:"starling",nl:"Spreeuw",en:"Common starling",latin:"Sturnus vulgaris",tier:1,hintNl:"Donker verenkleed met metaalglans en lichte spikkels, plus een korte staart.",hintEn:"Dark, iridescent plumage with pale speckles and a short tail."}, + {id:"grey_heron",nl:"Blauwe reiger",en:"Grey heron",latin:"Ardea cinerea",tier:1,hintNl:"Grote grijze watervogel met lange poten, een lange hals en dolkvormige snavel.",hintEn:"Large grey waterbird with long legs, a long neck and dagger-shaped bill."}, + {id:"mute_swan",nl:"Knobbelzwaan",en:"Mute swan",latin:"Cygnus olor",tier:1,hintNl:"Grote witte zwaan met een oranje snavel en zwarte knobbel aan de basis.",hintEn:"Large white swan with an orange bill and a black knob at its base."}, + {id:"coot",nl:"Meerkoet",en:"Eurasian coot",latin:"Fulica atra",tier:2,hintNl:"Zwarte watervogel met een opvallend witte snavel en witte voorhoofdsplaat.",hintEn:"Black waterbird with a striking white bill and white forehead shield."}, + {id:"greylag_goose",nl:"Grauwe gans",en:"Greylag goose",latin:"Anser anser",tier:2,hintNl:"Grote grijsbruine gans met een stevige oranje of roze snavel en roze poten.",hintEn:"Large grey-brown goose with a stout orange or pink bill and pink legs."}, + {id:"collared_dove",nl:"Turkse tortel",en:"Eurasian collared dove",latin:"Streptopelia decaocto",tier:2,hintNl:"Licht beigegrijs met een smalle zwarte halsband en een lange, rechte staart.",hintEn:"Pale beige-grey with a narrow black neck collar and a long, square-ended tail."}, + {id:"wren",nl:"Winterkoning",en:"Eurasian wren",latin:"Troglodytes troglodytes",tier:2,hintNl:"Heel klein bruin vogeltje met fijne bandjes en een kort staartje dat vaak rechtop staat.",hintEn:"Very small brown bird with fine barring and a short tail often held upright."}, + {id:"buzzard",nl:"Buizerd",en:"Common buzzard",latin:"Buteo buteo",tier:3,hintNl:"Brede vleugels, korte staart en een verenkleed dat van donkerbruin tot bijna wit varieert.",hintEn:"Broad wings, a short tail and plumage varying from dark brown to nearly white."}, + {id:"barn_owl",nl:"Kerkuil",en:"Barn owl",latin:"Tyto alba",tier:3,hintNl:"Lichte uil met een goudbruine rug en een wit, hartvormig gezicht.",hintEn:"Pale owl with a golden-brown back and a white, heart-shaped face."}, +]); + +const WORLD_PLANTS=Object.freeze([ + {id:"dandelion",nl:"Paardenbloem",en:"Dandelion",latin:"Taraxacum officinale",tier:1,hintNl:"Gele bloemhoofdjes, een holle stengel met melksap en later een ronde pluizenbol.",hintEn:"Yellow flower heads, a hollow stem with milky sap and later a round seed clock."}, + {id:"nettle",nl:"Grote brandnetel",en:"Stinging nettle",latin:"Urtica dioica",tier:1,hintNl:"Tegenoverstaande, scherp gezaagde bladeren met brandharen op stengel en blad.",hintEn:"Opposite, sharply toothed leaves with stinging hairs on stems and leaves."}, + {id:"daisy",nl:"Madeliefje",en:"Common daisy",latin:"Bellis perennis",tier:1,hintNl:"Laag rozet met lepelvormige blaadjes en witte bloemen rond een geel hart.",hintEn:"Low rosette of spoon-shaped leaves and white flowers around a yellow centre."}, + {id:"red_clover",nl:"Rode klaver",en:"Red clover",latin:"Trifolium pratense",tier:1,hintNl:"Ronde roze-paarse bloemhoofdjes en bladeren van drie vaak licht gevlekte deelblaadjes.",hintEn:"Round pink-purple flower heads and leaves of three often pale-marked leaflets."}, + {id:"white_deadnettle",nl:"Witte dovenetel",en:"White dead-nettle",latin:"Lamium album",tier:2,hintNl:"Lijkt op brandnetel maar prikt niet; witte lipbloemen staan in kransen rond de stengel.",hintEn:"Looks like a nettle but does not sting; white lipped flowers circle the stem."}, + {id:"cow_parsley",nl:"Fluitenkruid",en:"Cow parsley",latin:"Anthriscus sylvestris",tier:2,hintNl:"Fijne varenachtige bladeren en luchtige schermen met heel veel kleine witte bloemen.",hintEn:"Delicate fern-like leaves and airy umbels of many tiny white flowers."}, + {id:"yarrow",nl:"Duizendblad",en:"Yarrow",latin:"Achillea millefolium",tier:2,hintNl:"Heel fijn verdeelde bladeren en platte schermen met kleine witte bloemhoofdjes.",hintEn:"Very finely divided leaves and flat clusters of small white flower heads."}, + {id:"ribwort_plantain",nl:"Smalle weegbree",en:"Ribwort plantain",latin:"Plantago lanceolata",tier:2,hintNl:"Smalle bladeren met sterke evenwijdige nerven en bruine aren op geribde stelen.",hintEn:"Narrow leaves with strong parallel veins and brown spikes on ribbed stems."}, + {id:"common_poppy",nl:"Grote klaproos",en:"Common poppy",latin:"Papaver rhoeas",tier:2,hintNl:"Vier papierdunne rode kroonbladen, vaak met een donkere vlek rond het zwarte hart.",hintEn:"Four papery red petals, often with a dark blotch around the black centre."}, + {id:"chicory",nl:"Wilde cichorei",en:"Common chicory",latin:"Cichorium intybus",tier:3,hintNl:"Helderblauwe lintbloemen staan vrijwel direct langs een stijve vertakte stengel.",hintEn:"Bright blue ray flowers grow almost directly along a stiff branching stem."}, + {id:"foxglove",nl:"Vingerhoedskruid",en:"Foxglove",latin:"Digitalis purpurea",tier:3,hintNl:"Hoge aar met roze-paarse klokvormige bloemen die van binnen gevlekt zijn; giftig.",hintEn:"Tall spike of pink-purple bell-shaped flowers, spotted inside; poisonous."}, + {id:"common_sorrel",nl:"Veldzuring",en:"Common sorrel",latin:"Rumex acetosa",tier:3,hintNl:"Pijlvormige bladeren en een losse roodgroene pluim met heel kleine bloemetjes.",hintEn:"Arrow-shaped leaves and a loose red-green panicle of tiny flowers."}, ]); const NL_PROVINCES=Object.freeze([ @@ -148,22 +245,24 @@ const worldSelect=(value,items)=>{ return select; }; const worldLevelPool=(items,level)=>items.filter(item=>item.tier<=level); +const worldMediaKind=(type,view)=>type==="birds"?"bird":type==="plants"?"plant":view; +const worldPhotoLabel=kind=>T(kind==="bird"?"worldPhotoBird":kind==="plant"?"worldPhotoPlant":kind==="leaf"?"worldPhotoLeaf":"worldPhotoTree"); function worldPhoto(item,type,view){ - const kind=type==="birds"?"bird":view; + const kind=worldMediaKind(type,view); const media=WORLD_MEDIA[item.id]?.[kind]; const figure=document.createElement("figure"); figure.className="world-photo world-photo-"+kind; const image=document.createElement("img"); image.className="world-picture"; - image.alt=T(kind==="bird"?"worldPhotoBird":kind==="leaf"?"worldPhotoLeaf":"worldPhotoTree"); + image.alt=worldPhotoLabel(kind); image.draggable=false; image.loading="lazy"; image.decoding="async"; image.src=WORLD_MEDIA_ROOT+media.file; const badge=document.createElement("span"); badge.className="world-photo-badge"; - badge.textContent=T(kind==="bird"?"worldPhotoBird":kind==="leaf"?"worldPhotoLeaf":"worldPhotoTree"); + badge.textContent=worldPhotoLabel(kind); const credit=document.createElement("a"); credit.className="world-photo-credit"; credit.href=media.source; @@ -183,7 +282,7 @@ function worldVisual(item,type,view){ } function worldPhotoOption(item,type,view,index,onChoose,status){ - const kind=type==="birds"?"bird":view; + const kind=worldMediaKind(type,view); const media=WORLD_MEDIA[item.id]?.[kind]; const figure=document.createElement("figure"); figure.className="world-photo-choice"+(status?" "+status:""); @@ -229,7 +328,7 @@ function mountWorldQuiz(root,init,config){ ?[["recognize","worldExerciseRecognize"],["pair","worldExercisePair"],["clue","worldExerciseClue"],["photo","worldExercisePhoto"],["latin","worldExerciseLatin"]] :[["recognize","worldExerciseRecognize"],["clue","worldExerciseClue"],["photo","worldExercisePhoto"],["latin","worldExerciseLatin"]]; const S=Object.assign({ - activity:"quiz",exercise:"recognize",level:1,view:config.type==="trees"?"mixed":"bird", + activity:"quiz",exercise:"recognize",level:1,view:config.type==="trees"?"mixed":config.type==="birds"?"bird":"plant", score:0,streak:0,target:"",taskView:"",options:[],picked:"",solved:false,feedback:"", },init||{}); S.level=Math.max(1,Math.min(3,+S.level||1)); @@ -255,7 +354,7 @@ function mountWorldQuiz(root,init,config){ S.target=target.id; S.taskView=config.type==="trees" ?S.exercise==="pair"?"mixed":S.view==="mixed"?(Math.random()<.5?"tree":"leaf"):S.view - :"bird"; + :config.type==="birds"?"bird":"plant"; S.options=worldShuffle([target,...worldShuffle(items.filter(item=>item.id!==target.id)).slice(0,3)]).map(item=>item.id); S.picked=""; S.solved=false; @@ -278,7 +377,7 @@ function mountWorldQuiz(root,init,config){ pool().forEach(item=>{ const card=document.createElement("article"); card.className="world-specimen"; - card.append(worldVisual(item,config.type,config.type==="trees"?S.view:"bird"),worldIdentity(item)); + card.append(worldVisual(item,config.type,config.type==="trees"?S.view:config.type==="birds"?"bird":"plant"),worldIdentity(item)); const hint=document.createElement("p"); hint.textContent=worldHint(item); card.append(hint); @@ -314,7 +413,8 @@ function mountWorldQuiz(root,init,config){ card.className="world-task-card"; const question=document.createElement("h3"); if(S.exercise==="photo"){ - question.textContent=T(config.type==="birds"?"worldFindBirdPhoto":"worldFindTreePhoto").replace("{name}",worldName(item)); + const photoQuestion=config.type==="birds"?"worldFindBirdPhoto":config.type==="plants"?"worldFindPlantPhoto":"worldFindTreePhoto"; + question.textContent=T(photoQuestion).replace("{name}",worldName(item)); card.append(question); const answers=document.createElement("div"); answers.className="world-photo-answers"; @@ -322,7 +422,7 @@ function mountWorldQuiz(root,init,config){ const option=config.items.find(entry=>entry.id===id); if(!option)return; const status=S.solved&&id===S.target?"correct":S.feedback==="bad"&&id===S.picked?"wrong":""; - const optionView=config.type==="trees"?(S.taskView==="mixed"?"tree":S.taskView):"bird"; + const optionView=config.type==="trees"?(S.taskView==="mixed"?"tree":S.taskView):config.type==="birds"?"bird":"plant"; answers.append(worldPhotoOption(option,config.type,optionView,index,()=>answer(id),status)); }); card.append(answers); @@ -340,7 +440,8 @@ function mountWorldQuiz(root,init,config){ question.textContent=T("worldQuestionPair"); prompt.append(worldVisual(item,config.type,"mixed")); }else{ - question.textContent=T(config.type==="birds"?"worldQuestionBird":S.taskView==="leaf"?"worldQuestionLeaf":"worldQuestionTree"); + const questionKey=config.type==="birds"?"worldQuestionBird":config.type==="plants"?"worldQuestionPlant":S.taskView==="leaf"?"worldQuestionLeaf":"worldQuestionTree"; + question.textContent=T(questionKey); prompt.append(worldVisual(item,config.type,S.taskView)); } card.append(question,prompt); @@ -387,6 +488,7 @@ function mountWorldQuiz(root,init,config){ function mountTrees(root,init){return mountWorldQuiz(root,init,{type:"trees",items:WORLD_TREES})} function mountBirds(root,init){return mountWorldQuiz(root,init,{type:"birds",items:WORLD_BIRDS})} +function mountPlants(root,init){return mountWorldQuiz(root,init,{type:"plants",items:WORLD_PLANTS})} const SVG_NS="http://www.w3.org/2000/svg"; const TOPO_MAP_ASSET=WORLD_MEDIA_ROOT+"netherlands-provinces.svg"; diff --git a/test/widgets.test.js b/test/widgets.test.js index 24a8195..822ec71 100644 --- a/test/widgets.test.js +++ b/test/widgets.test.js @@ -5,7 +5,7 @@ import {runInNewContext} from 'node:vm'; const ids=['birthday','numberline','sentence']; const learningIds=['fractions','clock','placevalue','money','wordtypes','schedule','mood','poll']; -const worldIds=['trees','birds','topography']; +const worldIds=['trees','birds','plants','topography']; test('nieuwe widgets zijn geladen vóór het widgetregister', async()=>{ const html=await readFile('public/index.html','utf8'); @@ -58,7 +58,7 @@ test('nieuwe widgets zijn tweetalig beschreven', async()=>{ test('wereldoriëntatiewidgets laden, registreren en vertalen', async()=>{ const [html,board,source,core]=await Promise.all([readFile('public/index.html','utf8'),readFile('public/js/board.js','utf8'),readFile('public/js/widgets/world.js','utf8'),readFile('public/js/core.js','utf8')]); assert.ok(html.indexOf('js/widgets/world.js'){ assert.equal((core.match(new RegExp('wg_'+id+'_d:','g'))||[]).length,2,id); } assert.equal((core.match(/catWorld:/g)||[]).length,2); - for(const key of ['worldActivity','worldLearn','worldQuiz','worldExercise','worldExerciseRecognize','worldExercisePair','worldExerciseClue','worldExercisePhoto','worldExerciseLatin','worldTreeView','worldQuestionLeaf','worldQuestionBird','worldQuestionPair','worldQuestionClue','worldQuestionLatin','worldFindTreePhoto','worldFindBirdPhoto','worldPhotoTree','worldPhotoLeaf','worldPhotoBird','worldPhotoCredit','worldPhotoOption','topoProvinces','topoCapitals','topoCities','topoRegions','topoRivers','topoContinents','topoFindProvince','topoFindCapital','topoFindCity','topoFindRegion','topoFindRiver','topoFindContinent','topoMapSource','topoWorldMapSource'])assert.equal((core.match(new RegExp(key+':','g'))||[]).length,2,key); + for(const key of ['worldActivity','worldLearn','worldQuiz','worldExercise','worldExerciseRecognize','worldExercisePair','worldExerciseClue','worldExercisePhoto','worldExerciseLatin','worldTreeView','worldQuestionLeaf','worldQuestionBird','worldQuestionPlant','worldQuestionPair','worldQuestionClue','worldQuestionLatin','worldFindTreePhoto','worldFindBirdPhoto','worldFindPlantPhoto','worldPhotoTree','worldPhotoLeaf','worldPhotoBird','worldPhotoPlant','worldPhotoCredit','worldPhotoOption','topoProvinces','topoCapitals','topoCities','topoRegions','topoRivers','topoContinents','topoFindProvince','topoFindCapital','topoFindCity','topoFindRegion','topoFindRiver','topoFindContinent','topoMapSource','topoWorldMapSource'])assert.equal((core.match(new RegExp(key+':','g'))||[]).length,2,key); for(const exercise of ['recognize','pair','clue','photo','latin'])assert.ok(source.includes('"'+exercise+'"'),exercise); for(const mode of ['regions','rivers','continents'])assert.ok(source.includes('["'+mode+'","topo'),mode); assert.match(source,/getState/); @@ -83,18 +83,19 @@ test('wereldoriëntatiedata bevat echte soortmedia en uitgebreide topografie', a readFile('public/img/world/ATTRIBUTION.md','utf8'), ]); const context={}; - runInNewContext(source+';globalThis.__world={trees:WORLD_TREES,birds:WORLD_BIRDS,media:WORLD_MEDIA,provinces:NL_PROVINCES,cities:NL_CITIES,regions:NL_REGIONS,rivers:NL_RIVERS,continents:WORLD_CONTINENTS}',context); + runInNewContext(source+';globalThis.__world={trees:WORLD_TREES,birds:WORLD_BIRDS,plants:WORLD_PLANTS,media:WORLD_MEDIA,provinces:NL_PROVINCES,cities:NL_CITIES,regions:NL_REGIONS,rivers:NL_RIVERS,continents:WORLD_CONTINENTS}',context); const data=JSON.parse(JSON.stringify(context.__world)); - assert.equal(data.trees.length,8); - assert.equal(data.birds.length,8); + assert.equal(data.trees.length,18); + assert.equal(data.birds.length,18); + assert.equal(data.plants.length,12); assert.equal(data.provinces.length,12); assert.equal(data.cities.filter(city=>city.capital).length,12); assert.equal(data.cities.filter(city=>!city.capital).length,8); assert.equal(data.regions.length,4); assert.equal(data.rivers.length,5); assert.equal(data.continents.length,7); - for(const collection of [data.trees,data.birds,data.provinces,data.cities,data.regions,data.rivers,data.continents])assert.equal(new Set(collection.map(item=>item.id)).size,collection.length); - for(const item of [...data.trees,...data.birds])assert.ok(item.nl&&item.en&&item.latin&&item.hintNl&&item.hintEn&&item.tier>=1&&item.tier<=3,item.id); + for(const collection of [data.trees,data.birds,data.plants,data.provinces,data.cities,data.regions,data.rivers,data.continents])assert.equal(new Set(collection.map(item=>item.id)).size,collection.length); + for(const item of [...data.trees,...data.birds,...data.plants])assert.ok(item.nl&&item.en&&item.latin&&item.hintNl&&item.hintEn&&item.tier>=1&&item.tier<=3,item.id); const assetPaths=[]; for(const tree of data.trees){ assert.ok(data.media[tree.id]?.tree?.file&&data.media[tree.id]?.leaf?.file,tree.id); @@ -104,7 +105,11 @@ test('wereldoriëntatiedata bevat echte soortmedia en uitgebreide topografie', a assert.ok(data.media[bird.id]?.bird?.file,bird.id); assetPaths.push(data.media[bird.id].bird.file); } - assert.equal(new Set(assetPaths).size,24); + for(const plant of data.plants){ + assert.ok(data.media[plant.id]?.plant?.file,plant.id); + assetPaths.push(data.media[plant.id].plant.file); + } + assert.equal(new Set(assetPaths).size,66); for(const relativePath of assetPaths){ const image=await readFile('public/img/world/'+relativePath); assert.ok(image.length>10_000,relativePath+' is geen bruikbare foto'); @@ -319,6 +324,7 @@ test('alle geregistreerde widgets hebben mobiele dekking en passen op een 320px- mdiv:'.mt-pad', trees:'.world-gallery', birds:'.world-picture', + plants:'.world-picture', topography:'.topo-map', mpct:'.mt-pad', numberline:'.nlw-settings',