/* 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})); /* 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,yearGroup}); }); })); 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 svg=`${emoji}`; 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("โœ‹๐Ÿ‘‚๐Ÿ‘ƒ๐Ÿ‘๏ธ๐Ÿ‘„๐Ÿฆถ๐Ÿ˜€๐Ÿ˜ข๐Ÿ˜ด๐Ÿคง๐Ÿ‘ถ๐Ÿ‘ฆ๐Ÿ‘ง๐Ÿ‘ต๐Ÿ‘ด") ];