All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m1s
727 lines
52 KiB
JavaScript
727 lines
52 KiB
JavaScript
/* teach - woorddata: algemene kaart, thema's, gedeelde woordbronnen */
|
||
/* =========================================================
|
||
Letter game data
|
||
==========================================================*/
|
||
const DOTCODE = {
|
||
a:[1], b:[1,2], c:[1,4], d:[1,4,5], e:[1,5], f:[1,2,4], g:[1,2,4,5], h:[1,2,5],
|
||
i:[2,4], j:[2,4,5], k:[1,3], l:[1,2,3], m:[1,3,4], n:[1,3,4,5], o:[1,3,5],
|
||
p:[1,2,3,4], q:[1,2,3,4,5], r:[1,2,3,5], s:[2,3,4], t:[2,3,4,5], u:[1,3,6],
|
||
v:[1,2,3,6], w:[2,4,5,6], x:[1,3,4,6], y:[1,3,4,5,6], z:[1,3,5,6]
|
||
};
|
||
/* cijferblokken gebruikten hiervoor de braille a-j-patronen, maar die
|
||
gebruiken nooit posities 3/6 (de onderste rij) - op een kind-oog leken
|
||
alle tien blokken daardoor op elkaar. Een eigen codetabel die alle zes
|
||
stippen inzet, geeft elk cijfer een echt eigen vorm. */
|
||
const DIGIT_DOTCODE = {
|
||
"0":[], "1":[2], "2":[2,5], "3":[1,2,3], "4":[1,3,4,6],
|
||
"5":[1,2,3,4,5], "6":[1,2,3,4,5,6], "7":[1,2,4,5], "8":[1,2,3,4,6], "9":[1,4,6]
|
||
};
|
||
/* Klassenmanagement (v0.4.34-beta e.v.): rekenen is het eerste vakgebied waarvan
|
||
de leerlijn direct in getalgrenzen te vertalen is (SLO/TULE: groep 3
|
||
automatiseert optellen/aftrekken t/m 20, groep 4 t/m 100, groep 5 t/m 1000,
|
||
groep 6 t/m 10.000 met de tafels verder uitgebouwd, groep 7-8 bouwen daarop
|
||
voort). math.js gebruikt dit als de daadwerkelijke inhoud zodra een leerling
|
||
een groep heeft (zie mathRangeFor hieronder) - zonder groep blijft het oude,
|
||
vaste 10/20/100-gedrag exact bestaan. */
|
||
const SLO_MATH_RANGES = {
|
||
1:{addSub:10, timesTable:5},
|
||
2:{addSub:10, timesTable:5},
|
||
3:{addSub:20, timesTable:5},
|
||
4:{addSub:100, timesTable:10},
|
||
5:{addSub:1000, timesTable:10},
|
||
6:{addSub:10000,timesTable:12},
|
||
7:{addSub:10000,timesTable:12},
|
||
8:{addSub:10000,timesTable:12},
|
||
};
|
||
/* niveau (1-3) is de verfijning BINNEN een groep - een breukdeel van de
|
||
groep-grens, nooit onder de kleinste bestaande standaardwaarde (10) of
|
||
onder tafel 3. Levert bij ontbrekend yearGroup expres geen waarde (math.js
|
||
valt dan terug op zijn eigen oude vaste 10/20/100-logica). */
|
||
function mathRangeFor(yearGroup, level){
|
||
if(yearGroup == null) return null;
|
||
const g = SLO_MATH_RANGES[Math.max(1, Math.min(8, +yearGroup || 1))];
|
||
if(!g) return null;
|
||
const frac = level===1 ? .25 : level===2 ? .6 : 1;
|
||
return {
|
||
addSub: Math.max(10, Math.round(g.addSub*frac/5)*5),
|
||
timesTable: Math.max(3, Math.round(g.timesTable*frac)),
|
||
};
|
||
}
|
||
const VOWELS = "aeiou";
|
||
function dotGrid(letter){
|
||
const code = (Object.prototype.hasOwnProperty.call(DIGIT_DOTCODE, letter) ? DIGIT_DOTCODE[letter] : DOTCODE[letter]) || [];
|
||
const grid = document.createElement("div");
|
||
grid.className = "dots";
|
||
[1,4,2,5,3,6].forEach(p=>{
|
||
const d = document.createElement("i");
|
||
d.className = code.includes(p) ? "on" : "off";
|
||
grid.appendChild(d);
|
||
});
|
||
return grid;
|
||
}
|
||
|
||
/* De taalplaatjes hebben één centrale bron. Daardoor gebruiken de spelletjes,
|
||
de themakiezer en de afbeeldingenbibliotheek altijd dezelfde woorden en
|
||
verdwijnen oude plaatjes niet wanneer de woordenschat wordt uitgebreid. */
|
||
const LANGUAGE_THEME_DEFS = [
|
||
{id:"animals", icon:"🐾", nl:"Dieren", en:"Animals", colors:["#eaf7df","#cdeeb5"]},
|
||
{id:"food", icon:"🍎", nl:"Eten & drinken", en:"Food & drink", colors:["#fff0dc","#ffd9aa"]},
|
||
{id:"nature", icon:"🌿", nl:"Natuur & weer", en:"Nature & weather", colors:["#e4f7ee","#bfead4"]},
|
||
{id:"travel", icon:"🚲", nl:"Onderweg", en:"Getting around", colors:["#e6f3ff","#beddf8"]},
|
||
{id:"home", icon:"🎒", nl:"Thuis & school", en:"Home & school", colors:["#f1ecff","#d9ccff"]},
|
||
{id:"body", icon:"👕", nl:"Lichaam & kleding", en:"Body & clothes", colors:["#ffeaf1","#ffcbdc"]},
|
||
{id:"actions", icon:"🏃", nl:"Doen", en:"Actions", colors:["#fff8d9","#f6e8a4"]},
|
||
{id:"feelings", icon:"🙂", nl:"Gevoelens", en:"Feelings", colors:["#e9f5ff","#c8e4fa"]},
|
||
{id:"people", icon:"👨👩👧", nl:"Mensen & familie", en:"People & family", colors:["#fff0f4","#ffd3df"]},
|
||
{id:"play", icon:"🏀", nl:"Spelen & sport", en:"Play & sports", colors:["#fff4dc","#ffdca8"]},
|
||
{id:"places", icon:"🏘️", nl:"Plekken & beroepen", en:"Places & jobs", colors:["#e8f3ff","#c9e2fb"]},
|
||
{id:"time", icon:"📅", nl:"Tijd & feest", en:"Time & celebrations", colors:["#f2edff","#ddd1ff"]},
|
||
{id:"arts", icon:"🎨", nl:"Kunst & muziek", en:"Arts & music", colors:["#fff0fa","#f4ccec"]},
|
||
{id:"science", icon:"🔬", nl:"Onderzoeken & techniek", en:"Science & technology", colors:["#e7f7f5","#bfe9e3"]},
|
||
{id:"learning", icon:"📚", nl:"Taal & rekenen", en:"Language & maths", colors:["#fff7df","#f3dfa6"]},
|
||
{id:"society", icon:"🌍", nl:"Samenleven & wereld", en:"Society & world", colors:["#e8f1ff","#c8daf7"]}
|
||
];
|
||
const LANGUAGE_CONCEPTS = [
|
||
["monkey","animals","aap","monkey","🐵"],
|
||
["cat","animals","kat","cat","🐈"],
|
||
["dog","animals","hond","dog","🐕"],
|
||
["fish","animals","vis","fish","🐟"],
|
||
["hen","animals","kip","hen","🐔"],
|
||
["mouse","animals","muis","mouse","🐭"],
|
||
["bear","animals","beer","bear","🐻"],
|
||
["duck","animals","eend","duck","🦆"],
|
||
["frog","animals","kikker","frog","🐸"],
|
||
["bee","animals","bij","bee","🐝"],
|
||
["cow","animals","koe","cow","🐄"],
|
||
["pig","animals","varken","pig","🐷"],
|
||
["owl","animals","uil","owl","🦉"],
|
||
["goat","animals","geit","goat","🐐"],
|
||
["hare","animals","haas","hare","🐇"],
|
||
["horse","animals","paard","horse","🐴"],
|
||
["lion","animals","leeuw","lion","🦁"],
|
||
["ant","animals","mier","ant","🐜"],
|
||
["egg","food","ei","egg","🥚"],
|
||
["apple","food","appel","apple","🍎"],
|
||
["pear","food","peer","pear","🍐"],
|
||
["cheese","food","kaas","cheese","🧀"],
|
||
["milk","food","melk","milk","🥛"],
|
||
["cake","food","taart","cake","🎂"],
|
||
["bread","food","brood","bread","🍞"],
|
||
["soup","food","soep","soup","🥣"],
|
||
["rice","food","rijst","rice","🍚"],
|
||
["corn","food","mais","corn","🌽"],
|
||
["grape","food","druif","grape","🍇"],
|
||
["strawberry","food","aardbei","strawberry","🍓"],
|
||
["candy","food","snoep","candy","🍬"],
|
||
["lemon","food","citroen","lemon","🍋"],
|
||
["pizza","food","pizza","pizza","🍕"],
|
||
["juice","food","sap","juice","🧃"],
|
||
["cookie","food","koek","cookie","🍪"],
|
||
["carrot","food","wortel","carrot","🥕"],
|
||
["sun","nature","zon","sun","☀️"],
|
||
["moon","nature","maan","moon","🌙"],
|
||
["star","nature","ster","star","⭐"],
|
||
["tree","nature","boom","tree","🌳"],
|
||
["rose","nature","roos","rose","🌹"],
|
||
["fire","nature","vuur","fire","🔥"],
|
||
["flower","nature","bloem","flower","🌷"],
|
||
["leaf","nature","blad","leaf","🍃"],
|
||
["cloud","nature","wolk","cloud","☁️"],
|
||
["rain","nature","regen","rain","🌧️"],
|
||
["snow","nature","sneeuw","snow","❄️"],
|
||
["water","nature","water","water","💧"],
|
||
["stone","nature","steen","stone","🪨"],
|
||
["sand","nature","zand","sand","🏖️"],
|
||
["sea","nature","zee","sea","🌊"],
|
||
["forest","nature","bos","forest","🌲"],
|
||
["grass","nature","gras","grass","🌱"],
|
||
["wind","nature","wind","wind","💨"],
|
||
["rainbow","nature","regenboog","rainbow","🌈"],
|
||
["car","travel","auto","car","🚗"],
|
||
["bike","travel","fiets","bike","🚲"],
|
||
["boat","travel","boot","boat","⛵"],
|
||
["train","travel","trein","train","🚂"],
|
||
["bus","travel","bus","bus","🚌"],
|
||
["taxi","travel","taxi","taxi","🚕"],
|
||
["truck","travel","vrachtauto","truck","🚚"],
|
||
["jet","travel","vliegtuig","plane","✈️"],
|
||
["tram","travel","tram","tram","🚋"],
|
||
["ship","travel","schip","ship","🚢"],
|
||
["rocket","travel","raket","rocket","🚀"],
|
||
["road","travel","weg","road","🛣️"],
|
||
["wheel","travel","wiel","wheel","🛞"],
|
||
["sail","travel","zeil","sail","⛵"],
|
||
["scooter","travel","step","scooter","🛴"],
|
||
["tractor","travel","tractor","tractor","🚜"],
|
||
["helicopter","travel","helikopter","helicopter","🚁"],
|
||
["house","home","huis","house","🏠"],
|
||
["book","home","boek","book","📕"],
|
||
["pen","home","pen","pen","🖊️"],
|
||
["pencil","home","potlood","pencil","✏️"],
|
||
["bag","home","tas","bag","🎒"],
|
||
["coat","home","jas","coat","🧥"],
|
||
["chair","home","stoel","chair","🪑"],
|
||
["bed","home","bed","bed","🛏️"],
|
||
["door","home","deur","door","🚪"],
|
||
["clock","home","klok","clock","⏰"],
|
||
["glasses","home","bril","glasses","👓"],
|
||
["ball","home","bal","ball","⚽"],
|
||
["doll","home","pop","doll","🪆"],
|
||
["block","home","blok","block","🧱"],
|
||
["key","home","sleutel","key","🔑"],
|
||
["lamp","home","lamp","lamp","💡"],
|
||
["cup","home","beker","cup","🥤"],
|
||
["brush","home","borstel","brush","🪥"],
|
||
["drum","home","trommel","drum","🥁"],
|
||
["gift","home","cadeau","gift","🎁"],
|
||
["paint","home","verf","paint","🎨"],
|
||
["scissors","home","schaar","scissors","✂️"],
|
||
["desk","home","bureau","desk","🗄️"],
|
||
["school","home","school","school","🏫"],
|
||
["hand","body","hand","hand","✋"],
|
||
["foot","body","voet","foot","🦶"],
|
||
["nose","body","neus","nose","👃"],
|
||
["eye","body","oog","eye","👁️"],
|
||
["ear","body","oor","ear","👂"],
|
||
["mouth","body","mond","mouth","👄"],
|
||
["hair","body","haar","hair","🧑🦱"],
|
||
["head","body","hoofd","head","🙂"],
|
||
["arm","body","arm","arm","💪"],
|
||
["leg","body","been","leg","🦵"],
|
||
["cap","body","pet","cap","🧢"],
|
||
["sock","body","sok","sock","🧦"],
|
||
["shoe","body","schoen","shoe","👟"],
|
||
["dress","body","jurk","dress","👗"],
|
||
["shirt","body","shirt","shirt","👕"],
|
||
["glove","body","want","glove","🧤"],
|
||
["pants","body","broek","trousers","👖"],
|
||
["skirt","body","rok","skirt","👗"],
|
||
["tooth","body","tand","tooth","🦷"],
|
||
["read","actions","lezen","read","📖"],
|
||
["eat","actions","eten","eat","🍽️"],
|
||
["drink","actions","drinken","drink","🥤"],
|
||
["sleep","actions","slapen","sleep","😴"],
|
||
["walk","actions","lopen","walk","🚶"],
|
||
["swim","actions","zwemmen","swim","🏊"],
|
||
["jump","actions","springen","jump","🤸"],
|
||
["laugh","actions","lachen","laugh","😄"],
|
||
["cry","actions","huilen","cry","😢"],
|
||
["sing","actions","zingen","sing","🎤"],
|
||
["dance","actions","dansen","dance","💃"],
|
||
["draw","actions","tekenen","draw","🖍️"],
|
||
["write","actions","schrijven","write","✍️"],
|
||
["play","actions","spelen","play","🧸"],
|
||
["sit","actions","zitten","sit","🧎"],
|
||
["run","actions","rennen","run","🏃"],
|
||
["climb","actions","klimmen","climb","🧗"],
|
||
["wave","actions","zwaaien","wave","👋"],
|
||
["look","actions","kijken","look","👀"],
|
||
["think","actions","denken","think","🤔"],
|
||
["happy","feelings","blij","happy","😀"],
|
||
["sad","feelings","verdrietig","sad","😢"],
|
||
["angry","feelings","boos","angry","😠"],
|
||
["scared","feelings","bang","scared","😨"],
|
||
["tired","feelings","moe","tired","🥱"],
|
||
["sick","feelings","ziek","sick","🤒"],
|
||
["proud","feelings","trots","proud","😌"],
|
||
["calm","feelings","rustig","calm","🙂"],
|
||
["surprised","feelings","verrast","surprised","😮"],
|
||
["excited","feelings","enthousiast","excited","🤩"],
|
||
["bird","animals","vogel","bird","🐦"],
|
||
["rabbit","animals","konijn","rabbit","🐰"],
|
||
["fox","animals","vos","fox","🦊"],
|
||
["butterfly","animals","vlinder","butterfly","🦋"],
|
||
["snail","animals","slak","snail","🐌"],
|
||
["ladybird","animals","lieveheersbeestje","ladybird","🐞"],
|
||
["spider","animals","spin","spider","🕷️"],
|
||
["turtle","animals","schildpad","turtle","🐢"],
|
||
["dolphin","animals","dolfijn","dolphin","🐬"],
|
||
["elephant","animals","olifant","elephant","🐘"],
|
||
["giraffe","animals","giraf","giraffe","🦒"],
|
||
["sheep","animals","schaap","sheep","🐑"],
|
||
["banana","food","banaan","banana","🍌"],
|
||
["orange","food","sinaasappel","orange","🍊"],
|
||
["watermelon","food","watermeloen","watermelon","🍉"],
|
||
["cherry","food","kers","cherry","🍒"],
|
||
["tomato","food","tomaat","tomato","🍅"],
|
||
["potato","food","aardappel","potato","🥔"],
|
||
["pancake","food","pannenkoek","pancake","🥞"],
|
||
["honey","food","honing","honey","🍯"],
|
||
["chocolate","food","chocolade","chocolate","🍫"],
|
||
["ice","food","ijs","ice","🍦"],
|
||
["sandwich","food","boterham","sandwich","🥪"],
|
||
["yoghurt","food","yoghurt","yoghurt","🥣"],
|
||
["mountain","nature","berg","mountain","⛰️"],
|
||
["island","nature","eiland","island","🏝️"],
|
||
["beach","nature","strand","beach","🏖️"],
|
||
["river","nature","rivier","river","🏞️"],
|
||
["lightning","nature","bliksem","lightning","⚡"],
|
||
["fog","nature","mist","fog","🌫️"],
|
||
["autumn","nature","herfst","autumn","🍂"],
|
||
["spring","nature","lente","spring","🌼"],
|
||
["summer","nature","zomer","summer","🌞"],
|
||
["winter","nature","winter","winter","⛄"],
|
||
["seed","nature","zaad","seed","🌰"],
|
||
["motorcycle","travel","motor","motorcycle","🏍️"],
|
||
["ambulance","travel","ambulance","ambulance","🚑"],
|
||
["firetruck","travel","brandweerauto","firetruck","🚒"],
|
||
["policecar","travel","politieauto","policecar","🚓"],
|
||
["subway","travel","metro","subway","🚇"],
|
||
["canoe","travel","kano","canoe","🛶"],
|
||
["bridge","travel","brug","bridge","🌉"],
|
||
["tunnel","travel","tunnel","tunnel","🚇"],
|
||
["trafficlight","travel","stoplicht","trafficlight","🚦"],
|
||
["station","travel","station","station","🚉"],
|
||
["airport","travel","vliegveld","airport","🛫"],
|
||
["mirror","home","spiegel","mirror","🪞"],
|
||
["sofa","home","bank","sofa","🛋️"],
|
||
["toilet","home","wc","toilet","🚽"],
|
||
["shower","home","douche","shower","🚿"],
|
||
["broom","home","bezem","broom","🧹"],
|
||
["spoon","home","lepel","spoon","🥄"],
|
||
["fork","home","vork","fork","🍴"],
|
||
["plate","home","bord","plate","🍽️"],
|
||
["computer","home","computer","computer","💻"],
|
||
["phone","home","telefoon","phone","📱"],
|
||
["window","home","raam","window","🪟"],
|
||
["finger","body","vinger","finger","☝️"],
|
||
["thumb","body","duim","thumb","👍"],
|
||
["knee","body","knie","knee","🦵"],
|
||
["heart","body","hart","heart","❤️"],
|
||
["brain","body","hersenen","brain","🧠"],
|
||
["bone","body","bot","bone","🦴"],
|
||
["tongue","body","tong","tongue","👅"],
|
||
["blood","body","bloed","blood","🩸"],
|
||
["hat","body","hoed","hat","👒"],
|
||
["boot","body","laars","boot","🥾"],
|
||
["scarf","body","sjaal","scarf","🧣"],
|
||
["cook","actions","koken","cook","🧑🍳"],
|
||
["bake","actions","bakken","bake","🧁"],
|
||
["cycle","actions","fietsen","cycle","🚴"],
|
||
["drive","actions","rijden","drive","🚙"],
|
||
["open","actions","openen","open","📂"],
|
||
["close","actions","sluiten","close","📕"],
|
||
["wash","actions","wassen","wash","🧼"],
|
||
["help","actions","helpen","help","🤝"],
|
||
["listen","actions","luisteren","listen","👂"],
|
||
["smell","actions","ruiken","smell","👃"],
|
||
["shy","feelings","verlegen","shy","😊"],
|
||
["curious","feelings","nieuwsgierig","curious","🧐"],
|
||
["confused","feelings","verward","confused","😕"],
|
||
["lonely","feelings","eenzaam","lonely","😔"],
|
||
["friendly","feelings","vriendelijk","friendly","🙂"],
|
||
["brave","feelings","dapper","brave","🦸"],
|
||
["jealous","feelings","jaloers","jealous","😒"],
|
||
["bored","feelings","verveeld","bored","🥱"],
|
||
["relieved","feelings","opgelucht","relieved","😌"],
|
||
["silly","feelings","grappig","silly","🤪"],
|
||
["baby","people","baby","baby","👶"],
|
||
["child","people","kind","child","🧒"],
|
||
["boy","people","jongen","boy","👦"],
|
||
["girl","people","meisje","girl","👧"],
|
||
["mother","people","moeder","mother","👩"],
|
||
["father","people","vader","father","👨"],
|
||
["sister","people","zus","sister","👧"],
|
||
["brother","people","broer","brother","👦"],
|
||
["grandmother","people","oma","grandmother","👵"],
|
||
["grandfather","people","opa","grandfather","👴"],
|
||
["family","people","familie","family","👨👩👧👦"],
|
||
["friend","people","vriend","friend","🧑🤝🧑"],
|
||
["teacher","people","leerkracht","teacher","🧑🏫"],
|
||
["pupil","people","leerling","pupil","🧑🎓"],
|
||
["neighbor","people","buur","neighbor","🏘️"],
|
||
["woman","people","vrouw","woman","👩"],
|
||
["man","people","man","man","👨"],
|
||
["person","people","mens","person","🧑"],
|
||
["twins","people","tweeling","twins","👯"],
|
||
["group","people","groep","group","👥"],
|
||
["football","play","voetbal","football","⚽"],
|
||
["basketball","play","basketbal","basketball","🏀"],
|
||
["tennis","play","tennis","tennis","🎾"],
|
||
["hockey","play","hockey","hockey","🏑"],
|
||
["volleyball","play","volleybal","volleyball","🏐"],
|
||
["skating","play","schaatsen","skating","⛸️"],
|
||
["ski","play","ski","ski","🎿"],
|
||
["cycling","play","wielrennen","cycling","🚴"],
|
||
["running","play","hardlopen","running","🏃"],
|
||
["playground","play","speeltuin","playground","🛝"],
|
||
["bowling","play","bowlen","bowling","🎳"],
|
||
["slide","play","glijbaan","slide","🛝"],
|
||
["kite","play","vlieger","kite","🪁"],
|
||
["puzzle","play","puzzel","puzzle","🧩"],
|
||
["game","play","spel","game","🎮"],
|
||
["dice","play","dobbelsteen","dice","🎲"],
|
||
["marble","play","knikker","marble","🔵"],
|
||
["teddy","play","knuffel","teddy","🧸"],
|
||
["cards","play","kaarten","cards","🃏"],
|
||
["chess","play","schaken","chess","♟️"],
|
||
["medal","play","medaille","medal","🏅"],
|
||
["shop","places","winkel","shop","🏪"],
|
||
["bakery","places","bakkerij","bakery","🥐"],
|
||
["hospital","places","ziekenhuis","hospital","🏥"],
|
||
["doctor","places","dokter","doctor","🧑⚕️"],
|
||
["police","places","politie","police","👮"],
|
||
["firefighter","places","brandweer","firefighter","🧑🚒"],
|
||
["farm","places","boerderij","farm","🏡"],
|
||
["farmer","places","boer","farmer","🧑🌾"],
|
||
["library","places","bibliotheek","library","📚"],
|
||
["librarian","places","bibliothecaris","librarian","📚"],
|
||
["park","places","park","park","🏞️"],
|
||
["zoo","places","dierentuin","zoo","🦒"],
|
||
["museum","places","museum","museum","🏛️"],
|
||
["restaurant","places","restaurant","restaurant","🍽️"],
|
||
["kitchen","places","keuken","kitchen","🍳"],
|
||
["classroom","places","klas","classroom","🏫"],
|
||
["office","places","kantoor","office","🏢"],
|
||
["garage","places","garage","garage","🚗"],
|
||
["postman","places","postbode","postman","📬"],
|
||
["nurse","places","verpleegkundige","nurse","🧑⚕️"],
|
||
["dentist","places","tandarts","dentist","🦷"],
|
||
["builder","places","bouwer","builder","👷"],
|
||
["chef","places","kok","chef","🧑🍳"],
|
||
["hairdresser","places","kapper","hairdresser","💇"],
|
||
["market","places","markt","market","🛍️"],
|
||
["city","places","stad","city","🏙️"],
|
||
["village","places","dorp","village","🏘️"],
|
||
["church","places","kerk","church","⛪"],
|
||
["pool","places","zwembad","pool","🏊"],
|
||
["morning","time","ochtend","morning","🌅"],
|
||
["afternoon","time","middag","afternoon","🌤️"],
|
||
["evening","time","avond","evening","🌇"],
|
||
["night","time","nacht","night","🌙"],
|
||
["today","time","vandaag","today","📅"],
|
||
["tomorrow","time","morgen","tomorrow","➡️"],
|
||
["yesterday","time","gisteren","yesterday","⬅️"],
|
||
["day","time","dag","day","☀️"],
|
||
["week","time","week","week","🗓️"],
|
||
["month","time","maand","month","📆"],
|
||
["year","time","jaar","year","🎆"],
|
||
["birthday","time","verjaardag","birthday","🎂"],
|
||
["party","time","feest","party","🥳"],
|
||
["candle","time","kaars","candle","🕯️"],
|
||
["balloon","time","ballon","balloon","🎈"],
|
||
["flag","time","vlag","flag","🚩"],
|
||
["crown","time","kroon","crown","👑"],
|
||
["christmas","time","kerst","christmas","🎄"],
|
||
["easter","time","pasen","easter","🐣"],
|
||
["garland","time","slinger","garland","🎊"],
|
||
["calendar","time","kalender","calendar","📅"],
|
||
["hour","time","uur","hour","🕐"],
|
||
["minute","time","minuut","minute","⏱️"],
|
||
["season","time","seizoen","season","🍁"]
|
||
].map(([id,theme,nl,en,pic])=>({id,theme,nl,en,pic}));
|
||
|
||
/* Gecontroleerde Nederlandse beeldcorrecties. Bestaande handgekozen emoji
|
||
blijven de terugval; deze lijst corrigeert polyseme woorden en geeft veel
|
||
voorkomende concrete woorden een specifieker beeld. */
|
||
const LANGUAGE_PICTURE_EXACT=Object.freeze({
|
||
groentekraam:"🥕🏪",veehouderij:"🐄",wastafel:"🚰",woonkamermeubel:"🛋️",badkamertegel:"🚿",prullenbak:"🗑️",
|
||
tekstproductie:"✍️📄",verdrietverwerking:"😢🧠",bezorgd:"😟",ouderverzorging:"👩❤️",spierkracht:"💪",
|
||
schoolslag:"🏊",wedstrijdreglement:"🏀📋",toneelspeler:"🎭",spellingspatroon:"🔤",meetinstrument:"📐",
|
||
lentebloem:"🌼",zomerdag:"🌞",herfstblad:"🍂",winterjas:"⛄",jaargetijde:"🍁",gitaarspel:"🎸",
|
||
ruimtestation:"🛰️",boekje:"📖",muziek:"🎶",onderzoeksverslag:"🧪📋",grondrecht:"⚖️",
|
||
bol:"🥯",toast:"🍞",korst:"🍞",kruimel:"🍞",karnemelk:"🥛",room:"🥛",boter:"🧈",vla:"🍮",
|
||
brie:"🧀",plak:"🧀",friet:"🍟",puree:"🥔",schil:"🥔",knol:"🥔",prei:"🥬",kool:"🥬",boon:"🫘",erwtje:"🫛",
|
||
koek:"🍪",snoep:"🍬",wafel:"🧇",gebakje:"🧁",slagroom:"🍰",
|
||
stam:"🌳",tak:"🌿",wortel:"🌱",stengel:"🌱",knop:"🌷",boeket:"💐",druppel:"💧",plas:"💦",sloot:"🏞️",beek:"🏞️",
|
||
licht:"☀️",schaduw:"◐",bui:"🌦️",vorst:"🥶",hagel:"🌨️",vlok:"❄️",aarde:"🌍",grond:"🟫",kiem:"🌱",
|
||
bus:"🚌",taxi:"🚕",rit:"🛣️",band:"🛞",step:"🛴",pedaal:"🚲",bel:"🔔",stuur:"🚲",rail:"🛤️",spoor:"🛤️",
|
||
roeispaan:"🚣",vleugel:"✈️",piloot:"🧑✈️",vlucht:"✈️",pad:"🥾",bocht:"↪️",streep:"➖",file:"🚗🚗",route:"🗺️",
|
||
kast:"🗄️",nachtkast:"🗄️",slaapkamer:"🛏️",slaapkamerraam:"🪟",flat:"🏢",hut:"🛖",dak:"🏠",muur:"🧱",deken:"🛏️",kussen:"🛏️",kruk:"🪑",slot:"🔒",sleutel:"🔑",
|
||
pan:"🍳",pot:"🍲",kom:"🥣",lepel:"🥄",bad:"🛁",douche:"🚿",wc:"🚽",kraan:"🚰",zeep:"🧼",
|
||
stof:"🫧",vuil:"🗑️",bezem:"🧹",dweil:"🧽",spons:"🧽",
|
||
duim:"👍",vinger:"☝️",nagel:"💅",pols:"⌚",teen:"🦶",hiel:"🦶",enkel:"🦵",knie:"🦵",
|
||
wang:"🙂",kin:"🙂",nek:"🧣",keel:"🗣️",lip:"👄",kies:"🦷",tong:"👅",speeksel:"💧",gebit:"😁",
|
||
trui:"👕",broek:"👖",rok:"👗",long:"🫁",bloed:"🩸",bot:"🦴",spier:"💪",skelet:"🦴",
|
||
bewegingsapparaat:"🦴",bewegingsrichting:"🧭",lichaamsbeweging:"🤸",bewegingsreeks:"🔄",bewegingsoefening:"🤸",bewegingspatroon:"💃",gaan:"🚶",stap:"👣",staan:"🧍",zitten:"🪑",racen:"🏁",sprinten:"🏃",haasten:"⏩",vluchten:"🏃",
|
||
hupsen:"🐇",bukken:"🙇",rollen:"🤸",draaien:"🔄",blad:"📄",zin:"📝",tekst:"📄",schrift:"📓",
|
||
praten:"🗣️",zeggen:"💬",vragen:"❓",roepen:"📣",fluisteren:"🤫",delen:"🤲",geven:"🎁",halen:"📥",brengen:"📤",
|
||
leuk:"😀",fijn:"😊",glimlach:"🙂",sip:"😔",verdriet:"😢",pijn:"🤕",kwaad:"😠",ruzie:"💢",zorgen:"😟",
|
||
rust:"🧘",kalm:"🙂",stil:"🤫",zacht:"🪶",ademen:"🌬️",dapper:"🦸",durven:"💪",winnen:"🏆",raar:"🤔",wauw:"🤩",
|
||
gezin:"👨👩👧👦",ouders:"👪",mama:"👩",tante:"👩",dochter:"👧",papa:"👨",oom:"👨",zoon:"👦",
|
||
jongen:"👦",meisje:"👧",kleuter:"🧒",puber:"🧑",maat:"🧑🤝🧑",buur:"🏘️",gast:"🧑",juf:"👩🏫",meester:"👨🏫",
|
||
leraar:"🧑🏫",mentor:"🧑🏫",coach:"🧑🏫",team:"👥",klas:"🏫",paar:"👫",kring:"⭕",
|
||
kaart:"🃏",doel:"🥅",trap:"⚽",veld:"🏟️",basket:"🏀",korf:"🧺",worp:"🤾",score:"💯",punt:"🔵",stuk:"🧩",rand:"🧩",
|
||
plaat:"🖼️",beer:"🧸",blok:"🧱",pion:"♟️",plons:"💦",slag:"🏊",prijs:"🏆",beker:"🏆",medaille:"🏅",
|
||
straat:"🛣️",landingsbaan:"🛬",plattegrond:"🗺️",landbouwer:"🧑🌾",plein:"🏘️",les:"📚",gym:"🤸",kassa:"🧾",kar:"🛒",mand:"🧺",klant:"🧑",arts:"🧑⚕️",zaal:"🚪",zorg:"❤️",
|
||
boer:"🧑🌾",stal:"🏚️",schuur:"🏚️",land:"🌾",erf:"🏡",balie:"🛎️",lezer:"📖",buurt:"🏘️",vijver:"🏞️",
|
||
dag:"☀️",uur:"🕐",tijd:"⏰",middag:"🌤️",vroeg:"🌅",wakker:"⏰",ontbijt:"🥣",avond:"🌇",laat:"🌙",
|
||
donker:"🌑",week:"🗓️",maand:"📆",jaar:"🎆",datum:"📅",agenda:"📒",feest:"🥳",kaars:"🕯️",ballon:"🎈",
|
||
lente:"🌼",zomer:"🌞",herfst:"🍂",winter:"⛄",seconde:"⏱️",kwart:"¼",half:"½",duur:"⏳",
|
||
kleur:"🌈",verf:"🎨",kwast:"🖌️",doek:"🖼️",palet:"🎨",tekening:"🖍️",lijn:"➖",vorm:"🔷",vak:"◻️",
|
||
toon:"🎵",lied:"🎶",stem:"🗣️",klank:"🔊",trom:"🥁",fluit:"🪈",snaar:"🎸",toets:"🎹",
|
||
dans:"💃",sprong:"🤸",draai:"🔄",toneel:"🎭",rol:"🎭",pak:"👔",podium:"🎭",foto:"📷",film:"🎬",lens:"📷",
|
||
zoeken:"🔎",vraag:"❓",vondst:"💡",proef:"🧪",test:"✅",buis:"🧪",mengen:"🥣",
|
||
magneet:"🧲",ijzer:"🔩",pool:"🧲",kracht:"💪",wiel:"🛞",as:"⚙️",tand:"🦷",veer:"🪶",hefboom:"⚖️",
|
||
stroom:"⚡",draad:"🧵",stekker:"🔌",digitaal:"💻",internet:"🌐",programmeren:"🧑💻",computer:"💻",muis:"🖱️",scherm:"🖥️",bestand:"📄",ruimte:"🌌",
|
||
planeet:"🪐",raket:"🚀",satelliet:"🛰️",heelal:"🌌",astronaut:"🧑🚀",
|
||
letter:"🔤",woord:"🔠",naam:"🏷️",teken:"✍️",komma:",",titel:"🏷️",prent:"🖼️",taal:"🗣️",
|
||
spraak:"💬",verhaal:"📖",nul:"0️⃣",een:"1️⃣",twee:"2️⃣",drie:"3️⃣",getal:"🔢",cijfer:"🔣",reeks:"🔢",
|
||
som:"➕",plus:"➕",min:"➖",keer:"✖️",hoek:"📐",vlak:"◻️",lengte:"📏",
|
||
samen:"🤝",hulp:"🆘",beurt:"🔄",afspraak:"🤝",regel:"📋",wijk:"🏘️",wereld:"🌍",grens:"🚧",
|
||
noord:"⬆️",zuid:"⬇️",oost:"➡️",west:"⬅️",plek:"📍",richting:"🧭",nieuws:"📰",krant:"🗞️",bericht:"💬",
|
||
radio:"📻",media:"📺",afval:"🗑️",bak:"🗑️",glas:"♻️",papier:"📄",recht:"⚖️",plicht:"📋",keus:"🔀",
|
||
wet:"⚖️",eerlijk:"⚖️",mening:"💭",besluit:"✅"
|
||
});
|
||
/* Betekenisdragende delen voor samenstellingen. Het familiebeeld blijft
|
||
voorop staan; maximaal één tweede symbool verduidelijkt het onderscheid. */
|
||
const LANGUAGE_PICTURE_HINTS=Object.freeze([
|
||
["bescherming","🛡️"],["veiligheid","🛡️"],["verzorging","🧼"],["vaardigheid","🎯"],["onderzoek","🔬"],
|
||
["bereiding","🍳"],["productie","🏭"],["verwerking","🏭"],["organisatie","📋"],["ontwikkeling","📈"],
|
||
["geschiedenis","📜"],["industrie","🏭"],["maatschappij","🌍"],["informatie","ℹ️"],["technologie","💻"],
|
||
["wedstrijd","🏆"],["training","🏋️"],["strategie","♟️"],["berekening","🧮"],["verdeling","📊"],
|
||
["winkel","🏪"],["fabriek","🏭"],["bedrijf","🏭"],["centrum","🏙️"],["gebouw","🏢"],["kamer","🚪"],
|
||
["boek","📕"],["schrift","📓"],["kaart","🗺️"],["verslag","📋"],["bericht","💬"],["programma","💻"],
|
||
["verlichting","💡"],["licht","💡"],["water","💧"],["lucht","🌬️"],["grond","🟫"],["bloem","🌷"],
|
||
["boom","🌳"],["tuin","🌱"],["weide","🌿"],["storm","🌪️"],["regen","🌧️"],["sneeuw","❄️"],
|
||
["bak","📦"],["voer","🍽️"],["hok","🏠"],["stal","🏚️"],["riem","🦮"],["kooi","🪹"],
|
||
["boot","⛵"],["reis","🧳"],["straat","🏘️"],["station","🚉"],["haven","⚓"],
|
||
["deur","🚪"],["raam","🪟"],["kast","🗄️"],["tafel","🪑"],["stoel","🪑"],["bed","🛏️"],
|
||
["zorg","❤️"],["hulp","🤝"],["school","🏫"],["leer","📚"],["taal","🔤"],["reken","🧮"],
|
||
["spel","🎲"],["sport","🏅"],["feest","🥳"],["dag","📅"],["tijd","⏰"],["jaar","🗓️"],
|
||
["kracht","💪"],["energie","⚡"],["stroom","⚡"],["machine","⚙️"],["instrument","🎵"],["muziek","🎶"],
|
||
["groep","👥"],["team","👥"],["familie","👨👩👧"],["ouder","👪"],["kind","🧒"],["mens","🧑"],
|
||
["wereld","🌍"],["milieu","♻️"],["afval","🗑️"],["bestuur","🏛️"]
|
||
]);
|
||
function languageProgressionPicture(word,fallback){
|
||
if(LANGUAGE_PICTURE_EXACT[word])return LANGUAGE_PICTURE_EXACT[word];
|
||
const match=LANGUAGE_PICTURE_HINTS.filter(([part])=>word.includes(part)).sort((a,b)=>b[0].length-a[0].length)
|
||
.find(([,emoji])=>emoji!==fallback);
|
||
return match?fallback+match[1]:fallback
|
||
}
|
||
|
||
/* Ruim duizend aanvullende Nederlandse woorden, geordend in woordfamilies.
|
||
Iedere regel loopt bewust van een kort, concreet basiswoord naar langere
|
||
afleidingen, samenstellingen en schooltaal. De positie op de regel bepaalt
|
||
het eerste leerjaar waarin het woord wordt aangeboden; hogere leerjaren
|
||
behouden de eerder aangeboden woorden. Woorden die al in LANGUAGE_CONCEPTS
|
||
staan worden hieronder automatisch overgeslagen. */
|
||
const LANGUAGE_NL_PROGRESSION_FAMILIES={
|
||
animals:"🐈|kat,poes,kitten,kater,katten,poesje,kattenbak,kattenvoer,huiskat,kattenluik,zwerfkat,kattenkwaad\n🐕|hond,pup,reu,teef,honden,pupje,hondenhok,hondenriem,waakhond,hondensport,geleidehond,hondenbezitter\n🐴|paard,pony,veulen,merrie,hengst,paardenstal,paardrijden,renpaard,paardensprong,paardentrailer,paardenverzorging,paardrijwedstrijd\n🐦|vogel,mus,merel,kraai,duif,nestje,vogelvoer,zangvogel,trekvogel,vogelkooi,vogelkenner,vogelbescherming\n🐟|vis,karper,baars,haai,rog,visje,vijvervis,zeedier,visnet,vissersboot,onderwaterdier,waterdierenverblijf\n🐞|mier,bij,wesp,kever,vlinder,rups,insectenhotel,bijenkorf,sprinkhaan,lieveheersbeestje,insectenkenner,insectenonderzoek\n🐄|koe,kalf,geit,schaap,varken,lammetje,kippenhok,melkkoe,boerderijdier,dierenweide,dierenverzorger,veehouderij",
|
||
food:"🍞|brood,bol,toast,korst,kruimel,broodje,volkorenbrood,broodmes,bakkerij,broodbeleg,broodtrommel,broodbereiding\n🍎|fruit,appel,peer,pruim,kers,appeltje,fruitsap,fruitmand,boomgaard,vruchtvlees,fruitsoorten,fruitteeltbedrijf\n🥛|melk,karnemelk,room,boter,vla,melkpak,melkglas,zuivel,melkboer,melkproduct,zuivelfabriek,voedingsmiddel\n🧀|kaas,brie,gaten,plak,korst,kaasje,kaasplank,kaasschaaf,kaaswinkel,smeerkaas,kaasbereiding,zuivelproduct\n🥔|aardappel,friet,puree,schil,knol,pieper,aardappelmes,stamppot,aardappelveld,aardappelplant,aardappelgerecht,aardappelverwerking\n🥕|groente,wortel,prei,kool,boon,erwtje,groentesoep,snijplank,moestuin,groentekraam,groentesoorten,groentegerecht\n🍰|taart,koek,snoep,cake,wafel,gebakje,slagroom,taartpunt,bakvorm,koekjesdeeg,feestmaaltijd,suikergehalte",
|
||
nature:"🌳|boom,stam,tak,blad,wortel,boompje,boomschors,boomkroon,loofboom,naaldboom,boomsoorten,bomenonderzoek\n🌷|bloem,roos,tulp,stengel,knop,bloempje,bloempot,bloembol,boeket,zonnebloem,bloemenweide,bloembestuiving\n💧|water,druppel,plas,sloot,beek,waterkant,drinkwater,waterput,grondwater,waterleiding,waterzuivering,waterkringloop\n☀️|zon,maan,ster,licht,schaduw,zonnetje,zonlicht,maansikkel,sterrenhemel,zonsopgang,zonnestraling,sterrenstelsel\n🌧️|regen,wolk,wind,mist,bui,regendruppel,regenjas,wolkbreuk,weersbericht,regenboog,neerslaggebied,weersverwachting\n❄️|sneeuw,ijs,vorst,hagel,vlok,sneeuwpop,ijskoud,sneeuwbal,winterweer,sneeuwstorm,temperatuurdaling,winterlandschap\n🌱|aarde,grond,zaad,kiem,plant,zaadje,potgrond,plantengroei,bodemlaag,bodemvruchtbaarheid,voedingsstoffen,kiemingsproces",
|
||
travel:"🚗|auto,bus,taxi,rit,band,autootje,autodeur,autoruit,parkeerplek,autoweg,automobilist,verkeersveiligheid\n🚲|fiets,step,pedaal,bel,stuur,fietsje,fietspad,fietspomp,bakfiets,fietstocht,fietsenmaker,fietsverlichting\n🚂|trein,tram,rail,spoor,rit,treintje,perron,station,spoorlijn,treinreis,treinmachinist,spoorwegovergang\n⛵|boot,schip,kano,zeil,roeispaan,bootje,zeilboot,reddingsboei,haven,scheepsdek,binnenvaartschip,scheepvaartverkeer\n✈️|vliegtuig,jet,vleugel,piloot,vlucht,vliegveld,landingsbaan,luchtvaart,vliegreis,verkeerstoren,passagiersvliegtuig,luchtvaartmaatschappij\n🛣️|weg,pad,brug,tunnel,bocht,wegdek,kruispunt,rotonde,rijbaan,wegwijzer,infrastructuur,verkeersknooppunt\n🚦|licht,bord,streep,file,route,stoplicht,verkeersbord,zebrapad,voorrang,weggebruiker,verkeersregelaar,verkeerssituatie",
|
||
home:"🏠|huis,flat,hut,dak,muur,huisje,voordeur,woonkamer,rijtjeshuis,woonwijk,huizenblok,woninginrichting\n🛏️|bed,kast,lamp,deken,kussen,bedje,nachtkast,bedlamp,slaapkamer,dekbedovertrek,slaapvertrek,slaapkamerraam\n🪑|stoel,tafel,bank,kruk,kast,stoeltje,tafelblad,eettafel,boekenkast,stoelzitting,meubelwinkel,woonkamermeubel\n🚪|deur,raam,slot,sleutel,bel,deurtje,deurklink,vensterbank,raamkozijn,voordeurbel,inbraakbeveiliging,toegangssysteem\n🍳|pan,pot,kom,bord,lepel,pannetje,koekenpan,keukenkast,aanrecht,afwasborstel,keukengerei,voedselbereiding\n🚿|bad,douche,wc,kraan,zeep,badje,handdoek,wastafel,badkamer,tandenborstel,waterbesparing,badkamertegel\n🧹|stof,vuil,bezem,dweil,spons,stofdoek,afwasmiddel,prullenbak,schoonmaak,schoonmaker,schoonmaakmiddel,huishoudelijkehulp",
|
||
body:"✋|hand,duim,vinger,nagel,pols,handje,vingertop,handpalm,wijsvinger,vingerafdruk,handbeweging,handvaardigheid\n🦶|voet,teen,hiel,enkel,knie,voetje,voetzool,knieschijf,onderbeen,voetstap,lichaamshouding,bewegingsapparaat\n🙂|hoofd,wang,kin,nek,keel,hoofdje,voorhoofd,achterhoofd,gezicht,gezichtsvorm,gelaatsuitdrukking,hoofdbescherming\n👁️|oog,oor,neus,mond,lip,oogje,ooglid,neusgat,wenkbrauw,zintuig,gehoororgaan,waarnemingsvermogen\n🦷|tand,kies,tong,speeksel,gebit,tandje,tandvlees,tandenborstel,tandarts,mondzorg,tandheelkunde,gebitsverzorging\n👕|jas,shirt,trui,broek,rok,jasje,regenbroek,winterjas,kledingkast,kledingmaat,kledingstuk,kledingindustrie\n❤️|hart,long,bloed,bot,spier,hartslag,bloedvat,longinhoud,skelet,spierkracht,bloedsomloop,ademhalingsstelsel",
|
||
actions:"🚶|gaan,lopen,stap,staan,zitten,wandelen,voetstap,doorlopen,oversteken,vooruitgaan,verplaatsing,bewegingsrichting\n🏃|rennen,racen,sprinten,haasten,vluchten,hardlopen,renbaan,wedloop,marathon,snelheidsmeter,hardloopwedstrijd,uithoudingsvermogen\n🤸|springen,hupsen,bukken,rollen,draaien,sprongetje,springtouw,koprol,evenwicht,lichaamsbeweging,bewegingsreeks,bewegingsoefening\n📖|lezen,boek,blad,zin,tekst,leesboek,voorlezen,leesbril,leeshoek,leesstrategie,leesvaardigheid,tekstinterpretatie\n✍️|schrijven,pen,schrift,letter,woord,opschrijven,handschrift,schrijfboek,schrijfregel,schrijfopdracht,schrijfvaardigheid,tekstproductie\n🗣️|praten,zeggen,vragen,roepen,fluisteren,vertellen,spreekbeurt,gesprek,uitspraak,woordkeuze,taalgebruik,gespreksvaardigheid\n🤝|helpen,delen,geven,halen,brengen,hulpje,samenwerken,meehelpen,ondersteunen,hulpverlening,samenwerkingsvorm,verantwoordelijkheid",
|
||
feelings:"😀|blij,leuk,fijn,lachen,vrolijk,glimlach,plezier,opgewekt,tevreden,blijheid,enthousiasme,geluksgevoel\n😢|sip,moe,verdriet,pijn,huilen,traantje,teleurgesteld,verdrietig,somber,eenzaamheid,teleurstelling,verdrietverwerking\n😠|boos,kwaad,ruzie,mopperen,grommen,boosheid,driftig,prikkelbaar,woedend,meningsverschil,frustratie,conflictbeheersing\n😨|bang,eng,schrik,zorgen,trillen,angstig,schrikken,onzeker,bezorgd,angstgevoel,onveiligheid,zelfbescherming\n🙂|rust,kalm,stil,zacht,ademen,rustig,ontspannen,geduldig,vertrouwd,ontspanning,zelfbeheersing,ademhalingsoefening\n😌|trots,dapper,sterk,durven,winnen,trotsheid,moedig,zelfstandig,zelfvertrouwen,doorzetter,doorzettingsvermogen,zelfwaardering\n🤩|nieuw,raar,wauw,vragen,kijken,verrast,benieuwd,nieuwsgierig,verwondering,belangstelling,onderzoekshouding,ontdekkingsvreugde",
|
||
people:"👨👩👧|familie,gezin,kind,baby,ouders,gezinnetje,familielid,stiefouder,grootouder,familieband,gezinssituatie,familiegeschiedenis\n👩|mama,moeder,vrouw,tante,dochter,moedertje,schoonmoeder,moederdag,moederfiguur,moederschap,ouderverzorging,gezinsverantwoordelijkheid\n👨|papa,vader,man,oom,zoon,vadertje,schoonvader,vaderdag,vaderfiguur,vaderschap,oudercontact,opvoedingsverantwoordelijkheid\n🧒|kind,jongen,meisje,kleuter,puber,kindje,schoolkind,leeftijdgenoot,jeugd,ontwikkeling,kinderrechten,identiteitsontwikkeling\n🧑🤝🧑|vriend,maat,buur,gast,club,vriendje,vriendschap,buurkind,kennismaking,groepsgenoot,vertrouwenspersoon,vriendschapsrelatie\n🧑🏫|juf,meester,leraar,mentor,coach,leerkracht,lesgever,schoolteam,begeleider,onderwijsassistent,onderwijsprofessional,leerlingbegeleiding\n👥|groep,team,klas,paar,kring,groepje,klasgenoot,teamlid,samenkomst,groepswerk,groepsvorming,groepsdynamiek",
|
||
play:"⚽|bal,doel,trap,team,veld,balletje,voetbal,doelman,wedstrijd,voetballer,voetbaltraining,competitiewedstrijd\n🏀|basket,korf,worp,score,punt,gooien,basketbal,dribbelen,balbezit,teamsport,sportvereniging,wedstrijdreglement\n🧩|puzzel,stuk,vorm,rand,plaat,puzzelstuk,legpuzzel,denkspel,oplossing,puzzelboek,probleemoplossing,denkstrategie\n🧸|pop,beer,blok,trein,auto,popje,knuffel,bouwblok,speelgoed,speelkamer,speelgoedwinkel,fantasiespel\n🎲|spel,beurt,dobbelsteen,kaart,pion,spelletje,spelregel,bordspel,tegenstander,winnaar,spelstrategie,gezelschapsspel\n🏊|zwemmen,duiken,bad,plons,slag,zwemband,zwembad,schoolslag,duikplank,zwemles,zwemvaardigheid,waterveiligheid\n🏅|sport,spel,prijs,beker,medaille,sporter,sportdag,training,kampioen,sportprestatie,sportiviteit,wedstrijdorganisatie",
|
||
places:"🏫|school,klas,plein,les,gym,schooltje,schoolbank,schoolplein,schoolgebouw,schooljaar,schoolorganisatie,onderwijsomgeving\n🏪|winkel,kassa,kar,mand,klant,winkeltje,winkelier,winkelstraat,boodschap,winkelcentrum,klantenservice,detailhandel\n🏥|arts,dokter,bed,zaal,zorg,ziekenhuis,verpleegkundige,wachtkamer,behandeling,zorgverlening,gezondheidszorg,ziekenhuisafdeling\n🏡|boer,stal,schuur,land,erf,boerderij,landbouwer,akkerbouw,boerenbedrijf,landbouwgrond,landbouwmachine,voedselproductie\n📚|boek,kast,balie,pas,lezer,bibliotheek,boekenkast,bibliothecaris,uitleentermijn,boekenafdeling,informatiedienst,mediatheekbeheer\n🏙️|stad,dorp,straat,plein,buurt,stadje,dorpsplein,woonplaats,stadscentrum,gemeentehuis,stedelijkgebied,bevolkingsdichtheid\n🏞️|park,bos,veld,pad,vijver,parkje,speelweide,natuurpark,wandelroute,recreatiegebied,landschapsbeheer,natuurvoorziening",
|
||
time:"☀️|dag,uur,tijd,klok,middag,dagje,daglicht,dagdeel,dagritme,tijdstip,dagindeling,tijdswaarneming\n🌅|ochtend,vroeg,wakker,ontbijt,zonsopgang,ochtendlicht,ochtendritueel,schoolochtend,dagbegin,ochtendspits,ochtendprogramma,ochtendactiviteit\n🌇|avond,laat,eten,donker,zonsondergang,avondlicht,avondeten,bedtijd,dagafsluiting,avondprogramma,avondschemering,avondvoorstelling\n🗓️|week,maand,jaar,datum,agenda,weekje,weekdag,maandblad,jaartal,kalenderjaar,tijdrekening,kalenderindeling\n🎂|feest,taart,kaars,cadeau,ballon,feestje,verjaardag,feestmuts,feestdag,uitnodiging,feestversiering,verjaardagsviering\n🍂|lente,zomer,herfst,winter,seizoen,lentebloem,zomerdag,herfstblad,winterjas,seizoenswissel,jaargetijde,seizoensverschijnsel\n⏱️|minuut,seconde,kwart,half,duur,minuutje,tijdsduur,stopwatch,kwartier,wachttijd,tijdseenheid,tijdsberekening",
|
||
arts:"🎨|kleur,verf,kwast,doek,palet,kleurtje,verfpot,schilderen,schilderij,kunstschilder,kleurgebruik,schildertechniek\n🖍️|tekening,lijn,vorm,punt,vak,tekenen,kleurplaat,schetsboek,omtrek,tekenmateriaal,beeldverhaal,illustratietechniek\n🎵|toon,lied,stem,klank,maat,liedje,muziek,nootbalk,melodie,muzikant,muziekstuk,muziekuitvoering\n🥁|trom,fluit,snaar,toets,bel,trommel,instrument,gitaarspel,slagwerk,muziekles,muziekinstrument,instrumentenfamilie\n💃|dans,stap,sprong,draai,pas,dansje,dansvloer,dansgroep,choreografie,dansvoorstelling,bewegingspatroon,podiumkunst\n🎭|toneel,rol,pak,tekst,podium,toneelstuk,acteur,optreden,voorstelling,toneelspeler,podiumverlichting,theatervoorstelling\n📷|foto,film,beeld,lens,flits,fotootje,camera,fotoboek,filmopname,fotograaf,beeldbewerking,mediaproductie",
|
||
science:"🔍|kijken,zoeken,vraag,vondst,spoor,onderzoek,waarnemen,vergrootglas,ontdekking,onderzoeker,waarneming,onderzoeksresultaat\n🧪|proef,test,buis,stof,mengen,proefje,reactie,meetglas,experiment,laboratorium,proefopstelling,onderzoeksverslag\n🧲|magneet,ijzer,pool,kracht,veld,aantrekken,afstoten,magnetisch,kompasnaald,magneetkracht,magnetisme,natuurverschijnsel\n⚙️|wiel,as,tand,veer,hefboom,tandwiel,overbrenging,mechaniek,machine,werktuig,bewegingsenergie,machinewerking\n💡|licht,stroom,draad,lamp,stekker,schakelaar,batterij,stroomkring,elektrisch,elektriciteit,energieverbruik,energievoorziening\n💻|computer,muis,toets,scherm,bestand,computerprogramma,toetsenbord,beeldscherm,digitaal,internet,programmeren,informatietechnologie\n🚀|ruimte,maan,planeet,ster,raket,ruimtevaart,satelliet,heelal,astronaut,zonnestelsel,ruimtestation,ruimteonderzoek",
|
||
learning:"🔤|letter,klank,woord,naam,teken,alfabet,lettergreep,klinker,medeklinker,lettervolgorde,klankstructuur,spellingspatroon\n📝|zin,punt,komma,vraag,tekst,zinnetje,hoofdletter,leesteken,zinsdeel,zinsbouw,tekstverband,taalbeschouwing\n📖|boek,blad,kaft,titel,prent,boekje,hoofdstuk,inhoudsopgave,schrijver,boekbespreking,literatuur,leeservaring\n🗣️|taal,stem,spraak,gesprek,verhaal,vertellen,luisteraar,spreker,spreekbeurt,gespreksregel,taalgebruik,communicatievaardigheid\n🔢|nul,een,twee,drie,getal,cijfer,reeks,getallenlijn,getalbeeld,plaatswaarde,getalstructuur,getalnotatie\n➕|som,plus,min,keer,delen,optellen,aftrekken,uitkomst,bewerking,rekenregel,rekenstrategie,bewerkingsvolgorde\n📐|vorm,lijn,hoek,vlak,lengte,driehoek,rechthoek,meetlat,oppervlakte,omtrekberekening,meetinstrument,meetkundigevorm",
|
||
society:"🤝|samen,hulp,beurt,afspraak,regel,samenwerken,overleggen,taakverdeling,deelname,samenleving,samenwerkingsverband,maatschappijleer\n🏘️|buurt,wijk,dorp,stad,straat,buurthuis,woonwijk,gemeente,provincie,stadsbestuur,gemeenteraad,gebiedsindeling\n🌍|wereld,land,zee,kaart,grens,wereldbol,landkaart,continent,werelddeel,bevolking,wereldbevolking,wereldburgerschap\n🗺️|noord,zuid,oost,west,plek,richting,kompas,kaartteken,plattegrond,schaalverdeling,herkenningspunt,kaartvaardigheid\n📰|nieuws,krant,bericht,radio,media,nieuwsblad,journalist,nieuwsbron,actualiteit,nieuwsbericht,betrouwbaarheid,mediageletterdheid\n♻️|afval,bak,glas,papier,natuur,recyclen,hergebruik,afvalbak,milieuzorg,afvalscheiding,duurzaamheid,grondstoffengebruik\n⚖️|recht,plicht,keus,stem,wet,eerlijk,verkiezing,mening,besluit,democratie,grondrecht,besluitvorming"
|
||
};
|
||
const LANGUAGE_PROGRESSION_YEARS=[1,2,3,3,4,5,5,6,7,8,7,8];
|
||
const LANGUAGE_NL_PROGRESSION_WORDS=(()=>{
|
||
const seen=new Set(LANGUAGE_CONCEPTS.map(item=>item.nl)),out=[];
|
||
Object.entries(LANGUAGE_NL_PROGRESSION_FAMILIES).forEach(([theme,rows])=>rows.split("\n").forEach(row=>{
|
||
const [pic,list]=row.split("|");let familyPosition=0;
|
||
list.split(",").forEach(raw=>{
|
||
const word=raw.trim();if(!word||seen.has(word))return;seen.add(word);
|
||
const slug=word.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z]/g,"");
|
||
const yearGroup=LANGUAGE_PROGRESSION_YEARS[Math.min(familyPosition++,LANGUAGE_PROGRESSION_YEARS.length-1)];
|
||
out.push({id:"nl-"+theme+"-"+slug,theme,nl:word,pic:languageProgressionPicture(word,pic),yearGroup,pictureChecked:true});
|
||
});
|
||
}));
|
||
return out
|
||
})();
|
||
|
||
/* De vertrouwde startkaart blijft exact dezelfde 30 woorden houden. */
|
||
const START_WORD_KEYS = {
|
||
nl:["monkey","fish","sun","cat","ball","egg","tree","house","moon","boat","hen","mouse","book","star","rose","fire","bike","cake","coat","glasses","clock","pear","cheese","duck","hand","foot","nose","eye","ear","mouth"],
|
||
en:["cat","dog","sun","egg","ball","fish","tree","moon","boat","star","book","cake","house","mouse","apple","train","fire","rose","bear","duck","frog","bee","cow","pig","hand","foot","nose","eye","ear","milk"]
|
||
};
|
||
const WORDS = Object.fromEntries(["nl","en"].map(lang=>[
|
||
lang, START_WORD_KEYS[lang].map(id=>{
|
||
const concept=LANGUAGE_CONCEPTS.find(item=>item.id===id);
|
||
return [concept[lang],concept.pic];
|
||
})
|
||
]));
|
||
|
||
function languageBuiltinWords(lang=LANG){
|
||
return lang==="nl"?LANGUAGE_CONCEPTS.concat(LANGUAGE_NL_PROGRESSION_WORDS):LANGUAGE_CONCEPTS
|
||
}
|
||
function languageThemeList(lang=LANG){
|
||
return LANGUAGE_THEME_DEFS.map(theme=>({
|
||
...theme,
|
||
name:theme[lang],
|
||
words:languageBuiltinWords(lang).filter(item=>item.theme===theme.id)
|
||
.map(item=>[item[lang]||item.nl,item.pic,item.yearGroup||null])
|
||
})).filter(theme=>theme.words.length);
|
||
}
|
||
function languageEmojiDataUrl(emoji,colors=["#f4f8ff","#dce9fa"]){
|
||
const fontSize=emoji.length>4?104:emoji.length>2?122:148;
|
||
const svg=`<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320" viewBox="0 0 320 320"><defs><linearGradient id="g" x2="1" y2="1"><stop stop-color="${colors[0]}"/><stop offset="1" stop-color="${colors[1]}"/></linearGradient></defs><rect width="320" height="320" rx="48" fill="url(#g)"/><circle cx="160" cy="160" r="112" fill="#fff" opacity=".92"/><text x="160" y="177" text-anchor="middle" dominant-baseline="middle" font-family="Apple Color Emoji,Segoe UI Emoji,Noto Color Emoji,sans-serif" font-size="${fontSize}">${emoji}</text></svg>`;
|
||
return "data:image/svg+xml;charset=utf-8,"+encodeURIComponent(svg);
|
||
}
|
||
function languagePictureCatalog(lang=LANG){
|
||
const builtinThemes=languageThemeList(lang).map((theme,index)=>({
|
||
id:-200-index,nameNl:theme.nl,nameEn:theme.en,scope:"global",filterOnly:true,
|
||
languageBuiltin:true,wordPicture:true,icon:theme.icon
|
||
}));
|
||
const themeIds=new Map(LANGUAGE_THEME_DEFS.map((theme,index)=>[theme.id,-200-index]));
|
||
const images=languageBuiltinWords(lang).map((item,index)=>{
|
||
const theme=LANGUAGE_THEME_DEFS.find(def=>def.id===item.theme);
|
||
const name=item[lang]||item.nl;
|
||
return {
|
||
id:-1000-index,name,folder:`Taal/Woordenschat/${theme[lang]}`,
|
||
scope:"global",themes:[themeIds.get(item.theme)],tags:[item.nl,item.en,theme.nl,theme.en].filter(Boolean),
|
||
src:languageEmojiDataUrl(item.pic,theme.colors),value:item.pic,canManage:false,canDelete:false,
|
||
wordPicture:true,builtin:true,yearGroup:item.yearGroup||null
|
||
};
|
||
});
|
||
const ownThemes=[];
|
||
const customImages=[];
|
||
let customId=-5000;
|
||
const addOwn=(words,name,folder,themeId)=>{
|
||
(words||[]).forEach(([word,pic])=>{
|
||
if(!word||!pic)return;
|
||
customImages.push({
|
||
id:customId--,name:word,folder,scope:"personal",themes:[themeId],tags:[word,name],
|
||
src:isImg(pic)?pic:languageEmojiDataUrl(pic),value:pic,canManage:false,canDelete:false,
|
||
wordPicture:true,builtin:false
|
||
});
|
||
});
|
||
};
|
||
const generalThemeId=-400;
|
||
ownThemes.push({id:generalThemeId,nameNl:"Mijn woordkaarten",nameEn:"My word cards",scope:"personal",filterOnly:true,wordPicture:true,icon:"⭐"});
|
||
addOwn(GENERAL_EXTRA[lang],lang==="nl"?"Mijn woordkaarten":"My word cards","Taal/Mijn woordkaarten",generalThemeId);
|
||
THEMES[lang].forEach((theme,index)=>{
|
||
const id=-401-index;
|
||
ownThemes.push({id,nameNl:theme.name,nameEn:theme.name,scope:"personal",filterOnly:true,wordPicture:true,icon:"📁"});
|
||
addOwn(theme.words,theme.name,["Taal/Mijn thema’s",theme.folder,theme.name].filter(Boolean).join("/"),id);
|
||
});
|
||
return {themes:builtinThemes.concat(ownThemes),images:images.concat(customImages)};
|
||
}
|
||
/* teacher's own additions to the general card (persisted per user) */
|
||
let GENERAL_EXTRA = {nl:[], en:[]};
|
||
function generalList(){ return WORDS[LANG].concat(GENERAL_EXTRA[LANG]); }
|
||
const shuffle = a => { a=a.slice(); for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1)); [a[i],a[j]]=[a[j],a[i]];} return a; };
|
||
|
||
/* custom themes: folders of own words.
|
||
{nl:[{name:"Herfst", words:[[word,pic],...]}], en:[...]} */
|
||
let THEMES = {nl:[], en:[]};
|
||
|
||
/* ankerbibliotheek: los van borden bewaarde ankerdiagrammen, herbruikbaar op
|
||
elk bord. [{id, name, folder?, cells, pics}] - cells/pics in dezelfde vorm
|
||
als de widget-staat van anchor.js; folder is een pad ("A/B") zoals bij de
|
||
thema's en borden in de mappenverkenner. */
|
||
let ANCHOR_LIB = [];
|
||
function themesFromData(data){
|
||
if(!data) return {nl:[],en:[]};
|
||
if(data.themes) return data.themes;
|
||
/* migrate old flat word lists into one theme */
|
||
const t = {nl:[],en:[]};
|
||
if(data.words) ["nl","en"].forEach(l=>{
|
||
if(Array.isArray(data.words[l]) && data.words[l].length)
|
||
t[l] = [{name: l==="nl" ? "Mijn woorden" : "My words", words: data.words[l]}];
|
||
});
|
||
return t;
|
||
}
|
||
const isImg = p => typeof p==="string" && /^(?:data:|https?:|blob:|\/)/.test(p);
|
||
function setPic(el, pic){
|
||
if(isImg(pic)){ el.innerHTML = ""; const im = document.createElement("img"); im.src = pic; im.alt=""; el.appendChild(im); }
|
||
else el.textContent = pic;
|
||
}
|
||
|
||
/* ---- ARASAAC pictogram lookup (shared by the word editor + anchor grid) ---- */
|
||
async function arasaacSearch(term, lang){
|
||
const resp = await fetch(`https://api.arasaac.org/api/pictograms/${lang}/search/${encodeURIComponent(term)}`);
|
||
if(!resp.ok) throw new Error("http "+resp.status);
|
||
return resp.json();
|
||
}
|
||
const arasaacUrl = id => `https://static.arasaac.org/pictograms/${id}/${id}_300.png`;
|
||
|
||
/* ---- shared word source (general card + themes + anchor grids) ---- */
|
||
/* anchor-word widgets register their words here so every language widget
|
||
can use them as a theme automatically */
|
||
let ANCHORS = []; /* [{el, name, words:[[w,pic],...]}] */
|
||
function anchorSources(){
|
||
ANCHORS = ANCHORS.filter(a=>a.el && document.contains(a.el));
|
||
return ANCHORS.filter(a=>a.words.length);
|
||
}
|
||
function normWordSource(card){
|
||
if(typeof card==="string"){
|
||
if(card.startsWith("b:")){
|
||
if(languageThemeList().some(theme=>theme.id===card.slice(2))) return card;
|
||
}else if(card.startsWith("t")){
|
||
const th = THEMES[LANG][+card.slice(1)];
|
||
if(th && th.words.length) return card;
|
||
}else if(card.startsWith("a")){
|
||
if(anchorSources()[+card.slice(1)]) return card;
|
||
}
|
||
}
|
||
return "g";
|
||
}
|
||
function wordSourceList(card){
|
||
card = normWordSource(card);
|
||
if(card.startsWith("b:")) return languageThemeList().find(theme=>theme.id===card.slice(2)).words;
|
||
if(card.startsWith("t")) return THEMES[LANG][+card.slice(1)].words;
|
||
if(card.startsWith("a")) return anchorSources()[+card.slice(1)].words;
|
||
return generalList();
|
||
}
|
||
function fillWordSourceSel(sel, card){
|
||
sel.innerHTML = "";
|
||
const og = document.createElement("option");
|
||
og.value = "g"; og.textContent = "⭐ "+T("cardStart");
|
||
sel.appendChild(og);
|
||
const builtinGroup = document.createElement("optgroup");
|
||
builtinGroup.label = "📚 "+T("wordThemes");
|
||
languageThemeList().forEach(theme=>{
|
||
const option=document.createElement("option");
|
||
option.value="b:"+theme.id;
|
||
option.textContent=`${theme.icon} ${theme.name} (${theme.words.length})`;
|
||
builtinGroup.appendChild(option);
|
||
});
|
||
sel.appendChild(builtinGroup);
|
||
/* thema's zonder map bovenaan, daarna per map gegroepeerd (optgroup) -
|
||
zelfde indeling als de theme-dropdown in de woorden-editor */
|
||
const groups = new Map();
|
||
THEMES[LANG].forEach((th,i)=>{
|
||
if(!th.words.length) return;
|
||
const f = th.folder || "";
|
||
if(!groups.has(f)) groups.set(f, []);
|
||
groups.get(f).push([th, i]);
|
||
});
|
||
const addOpt = (parent, th, i)=>{
|
||
const o = document.createElement("option");
|
||
o.value = "t"+i; o.textContent = "★ "+th.name;
|
||
parent.appendChild(o);
|
||
};
|
||
(groups.get("") || []).forEach(([th,i])=>addOpt(sel, th, i));
|
||
[...groups.keys()].filter(f=>f).sort().forEach(f=>{
|
||
const grp = document.createElement("optgroup");
|
||
grp.label = "📁 " + f;
|
||
groups.get(f).forEach(([th,i])=>addOpt(grp, th, i));
|
||
sel.appendChild(grp);
|
||
});
|
||
anchorSources().forEach((a,i)=>{
|
||
const o = document.createElement("option");
|
||
o.value = "a"+i; o.textContent = "⚓ "+a.name;
|
||
sel.appendChild(o);
|
||
});
|
||
sel.value = normWordSource(card);
|
||
if(sel.selectedIndex < 0) sel.selectedIndex = 0;
|
||
}
|
||
|
||
/* emoji palette (grouped) */
|
||
const splitEmoji = s => {
|
||
const out = [];
|
||
for(const ch of s){
|
||
if(out.length && (ch==="️" || ch==="")) out[out.length-1]+=ch;
|
||
else if(out.length && out[out.length-1].endsWith("")) out[out.length-1]+=ch;
|
||
else out.push(ch);
|
||
}
|
||
return out;
|
||
};
|
||
const EMOJI_CATS = [
|
||
splitEmoji("🐵🐶🐱🐭🐹🐰🦊🐻🐼🐨🐯🦁🐮🐷🐸🐔🐧🐦🦆🦉🐴🦄🐝🐛🦋🐌🐞🐠🐟🐬🐳🐢🐍🦎🐘🦒"),
|
||
splitEmoji("🍎🍐🍊🍋🍌🍉🍇🍓🍒🍑🥝🍅🥕🌽🥔🧀🥚🍞🥐🥞🍕🍟🍦🍪🎂🍫🍬🥛🧃🍯"),
|
||
splitEmoji("🌳🌲🌴🌵🌷🌹🌻🌸💐🍄⭐🌙☀️⛅🌈❄️🔥💧🌊🪨"),
|
||
splitEmoji("🚗🚕🚌🚑🚒🚜🚲🛴🏍️🚂✈️🚁⛵🚀🛶🚢"),
|
||
splitEmoji("⚽🏀🎈🎁🧸📕✏️🖍️✂️🎨🥁🎸👓⌚⏰💡🔑🧤🧢👟👗🧥🛏️🪑🚪🏠"),
|
||
splitEmoji("✋👂👃👁️👄🦶😀😢😴🤧👶👦👧👵👴")
|
||
];
|