cognikit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +316 -0
  3. package/dist/core/BaseInteraction.d.ts +78 -0
  4. package/dist/core/index.d.ts +1 -0
  5. package/dist/core/utilities/ProgressTracker.d.ts +58 -0
  6. package/dist/core/utilities/ScoringTracker.d.ts +0 -0
  7. package/dist/core/utilities/index.d.ts +1 -0
  8. package/dist/engines/index.d.ts +2 -0
  9. package/dist/engines/tables/implementation/graders.d.ts +23 -0
  10. package/dist/engines/tables/implementation/index.d.ts +4 -0
  11. package/dist/engines/tables/implementation/parsers.d.ts +36 -0
  12. package/dist/engines/tables/implementation/utils.d.ts +18 -0
  13. package/dist/engines/tables/implementation/validators.d.ts +9 -0
  14. package/dist/engines/tables/index.d.ts +2 -0
  15. package/dist/engines/tables/script.d.ts +37 -0
  16. package/dist/engines/text/implementation/graders.d.ts +69 -0
  17. package/dist/engines/text/implementation/index.d.ts +3 -0
  18. package/dist/engines/text/implementation/parsers.d.ts +9 -0
  19. package/dist/engines/text/implementation/validators.d.ts +41 -0
  20. package/dist/engines/text/index.d.ts +2 -0
  21. package/dist/engines/text/script.d.ts +56 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +4518 -0
  24. package/dist/index.js.map +7 -0
  25. package/dist/interactions/adjacency-table/index.d.ts +26 -0
  26. package/dist/interactions/categorize-the-words/index.d.ts +2 -0
  27. package/dist/interactions/categorize-the-words/sequential.d.ts +33 -0
  28. package/dist/interactions/categorize-the-words/static.d.ts +22 -0
  29. package/dist/interactions/classification-matrix/index.d.ts +31 -0
  30. package/dist/interactions/fill-blanks/index.d.ts +2 -0
  31. package/dist/interactions/fill-blanks/sequential.d.ts +32 -0
  32. package/dist/interactions/fill-blanks/static.d.ts +23 -0
  33. package/dist/interactions/index.d.ts +17 -0
  34. package/dist/interactions/list-recall/implementation/grader.d.ts +0 -0
  35. package/dist/interactions/list-recall/implementation/index.d.ts +0 -0
  36. package/dist/interactions/list-recall/implementation/parser.d.ts +0 -0
  37. package/dist/interactions/list-recall/implementation/validator.d.ts +0 -0
  38. package/dist/interactions/list-recall/index.d.ts +1 -0
  39. package/dist/interactions/list-recall/script.d.ts +25 -0
  40. package/dist/interactions/lookup-table/index.d.ts +26 -0
  41. package/dist/interactions/mark-the-words/index.d.ts +2 -0
  42. package/dist/interactions/mark-the-words/sequential.d.ts +34 -0
  43. package/dist/interactions/mark-the-words/static.d.ts +40 -0
  44. package/dist/interactions/mcq-mrq/implementation/grader.d.ts +20 -0
  45. package/dist/interactions/mcq-mrq/implementation/index.d.ts +3 -0
  46. package/dist/interactions/mcq-mrq/implementation/parser.d.ts +21 -0
  47. package/dist/interactions/mcq-mrq/implementation/validator.d.ts +17 -0
  48. package/dist/interactions/mcq-mrq/index.d.ts +2 -0
  49. package/dist/interactions/mcq-mrq/script.d.ts +37 -0
  50. package/dist/interactions/nary-choice-table/index.d.ts +28 -0
  51. package/dist/interactions/open-classification/index.d.ts +32 -0
  52. package/dist/interactions/rank-order/implementation/grader.d.ts +15 -0
  53. package/dist/interactions/rank-order/implementation/index.d.ts +3 -0
  54. package/dist/interactions/rank-order/implementation/parser.d.ts +25 -0
  55. package/dist/interactions/rank-order/implementation/validator.d.ts +3 -0
  56. package/dist/interactions/rank-order/index.d.ts +2 -0
  57. package/dist/interactions/rank-order/script.d.ts +39 -0
  58. package/dist/interactions/register-builtins.d.ts +1 -0
  59. package/dist/interactions/registry.d.ts +30 -0
  60. package/dist/interactions/sequential-classification/index.d.ts +49 -0
  61. package/dist/interactions/shared/association-implementation/grader.d.ts +3 -0
  62. package/dist/interactions/shared/association-implementation/index.d.ts +1 -0
  63. package/dist/interactions/shared/association-implementation/parser.d.ts +0 -0
  64. package/dist/interactions/shared/association-implementation/validator.d.ts +0 -0
  65. package/dist/interactions/shared/classification-implementation/grader.d.ts +3 -0
  66. package/dist/interactions/shared/classification-implementation/index.d.ts +1 -0
  67. package/dist/interactions/shared/classification-implementation/parser.d.ts +11 -0
  68. package/dist/interactions/shared/classification-implementation/validator.d.ts +3 -0
  69. package/dist/interactions/simultaneous-association/index.d.ts +34 -0
  70. package/dist/interactions/text-transformation/index.d.ts +2 -0
  71. package/dist/interactions/text-transformation/sequential.d.ts +37 -0
  72. package/dist/interactions/text-transformation/static.d.ts +47 -0
  73. package/dist/shared/assets.d.ts +6 -0
  74. package/dist/shared/dsl.d.ts +9 -0
  75. package/dist/shared/index.d.ts +4 -0
  76. package/dist/shared/managers/AnimationsManager.d.ts +55 -0
  77. package/dist/shared/managers/SoundManager.d.ts +78 -0
  78. package/dist/shared/managers/index.d.ts +3 -0
  79. package/dist/shared/types.d.ts +25 -0
  80. package/dist/shared/utils.d.ts +13 -0
  81. package/dist/shell/index.d.ts +1 -0
  82. package/dist/shell/simple-shell/index.d.ts +1 -0
  83. package/dist/shell/simple-shell/script.d.ts +61 -0
  84. package/dist/types/Assets.d.ts +40 -0
  85. package/dist/types/Data.d.ts +32 -0
  86. package/dist/types/Global.d.ts +24 -0
  87. package/dist/types/Grading.d.ts +8 -0
  88. package/dist/types/Input.d.ts +35 -0
  89. package/dist/types/Interactions.d.ts +28 -0
  90. package/dist/types/Tables.d.ts +40 -0
  91. package/dist/types/Text.d.ts +125 -0
  92. package/dist/types/index.d.ts +3 -0
  93. package/dist/ui/index.d.ts +2 -0
  94. package/dist/ui/input/color/color-picker.d.ts +37 -0
  95. package/dist/ui/input/color/index.d.ts +0 -0
  96. package/dist/ui/input/index.d.ts +1 -0
  97. package/dist/ui/input/input/index.d.ts +1 -0
  98. package/dist/ui/input/input/input.d.ts +22 -0
  99. package/dist/ui/input/letter/index.d.ts +0 -0
  100. package/dist/ui/input/letter/letter-picker.d.ts +27 -0
  101. package/dist/ui/misc/block.d.ts +14 -0
  102. package/dist/ui/misc/chip/chip.d.ts +46 -0
  103. package/dist/ui/misc/chip/index.d.ts +1 -0
  104. package/dist/ui/misc/dialog.d.ts +24 -0
  105. package/dist/ui/misc/index.d.ts +4 -0
  106. package/dist/ui/misc/media.d.ts +54 -0
  107. package/package.json +59 -0
package/dist/index.js ADDED
@@ -0,0 +1,4518 @@
1
+ var Re=class{constructor(){this._current=0;this._total=0}initialize(n){if(n<0)throw new Error("Total must be non-negative");this._total=n,this._current=0}setCurrent(n){n<0?this._current=0:n>this._total?this._current=this._total:this._current=n}increment(){this._current<this._total&&this._current++}decrement(){this._current>0&&this._current--}reset(){this._current=0}getPercentage(){return this._total===0?0:Math.round(this._current/this._total*100)}isComplete(){return this._current===this._total&&this._total>0}get current(){return this._current}get total(){return this._total}get remaining(){return Math.max(0,this._total-this._current)}};var ai=`
2
+ @keyframes shake {
3
+ 0%, 100% { transform: translateX(0); }
4
+ 25% { transform: translateX(-8px); }
5
+ 75% { transform: translateX(8px); }
6
+ }
7
+
8
+ @keyframes pulse-green {
9
+ 0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4); }
10
+ 70% { box-shadow: 0 0 0 15px rgba(34, 197, 94, 0); }
11
+ 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
12
+ }
13
+
14
+ @keyframes bounce-in {
15
+ 0% { opacity: 0; transform: scale(0.3); }
16
+ 100% { opacity: 1; transform: scale(1); }
17
+ }
18
+
19
+ @keyframes float {
20
+ 0%, 100% { transform: translateY(0); }
21
+ 50% { transform: translateY(-10px); }
22
+ }
23
+
24
+ @keyframes rubber {
25
+ 0% { transform: scale3d(1, 1, 1); }
26
+ 30% { transform: scale3d(1.25, 0.75, 1); }
27
+ 40% { transform: scale3d(0.75, 1.25, 1); }
28
+ 50% { transform: scale3d(1.15, 0.85, 1); }
29
+ 100% { transform: scale3d(1, 1, 1); }
30
+ }
31
+
32
+ @keyframes jello {
33
+ 11.1% { transform: none; }
34
+ 22.2% { transform: skewX(-12.5deg) skewY(-12.5deg); }
35
+ 44.4% { transform: skewX(6.25deg) skewY(6.25deg); }
36
+ 66.6% { transform: skewX(-1.56deg) skewY(-1.56deg); }
37
+ 100% { transform: none; }
38
+ }
39
+
40
+ @keyframes heartbeat {
41
+ 0% { transform: translateY(-50%) scale(1); }
42
+ 14% { transform: translateY(-50%) scale(1.1); }
43
+ 28% { transform: translateY(-50%) scale(1); }
44
+ 42% { transform: translateY(-50%) scale(1.1); }
45
+ 70% { transform: translateY(-50%) scale(1); }
46
+ }
47
+
48
+ @keyframes shimmer {
49
+ 0% { background-position: 200% 0; }
50
+ 100% { background-position: -200% 0; }
51
+ }
52
+
53
+ @keyframes wobble {
54
+ 0%, 100% { transform: translateX(0); }
55
+ 25% { transform: rotate(-5deg); }
56
+ 75% { transform: rotate(5deg); }
57
+ }
58
+
59
+ @keyframes pop {
60
+ 0% { transform: scale(0); }
61
+ 100% { transform: scale(1); }
62
+ }
63
+
64
+ @keyframes fade-slide {
65
+ from { opacity:0; transform: translateY(10px); }
66
+ to { opacity:1; transform: translateY(0); }
67
+ }
68
+
69
+ @keyframes swing {
70
+ 20% { transform: rotate(15deg); }
71
+ 40% { transform: rotate(-10deg); }
72
+ 60% { transform: rotate(5deg); }
73
+ 80% { transform: rotate(-5deg); }
74
+ 100% { transform: rotate(0deg); }
75
+ }
76
+
77
+ @keyframes spin-pulse {
78
+ 0% { transform: translateY(-50%) scale(1) rotate(0deg); }
79
+ 50% { transform: translateY(-50%) scale(1.8) rotate(180deg); color: #fbbc05; }
80
+ 100% { transform: translateY(-50%) scale(1) rotate(360deg); }
81
+ }
82
+
83
+ @keyframes flash {
84
+ 0%, 50%, 100% { opacity: 1; }
85
+ 25%, 75% { opacity: 0; }
86
+ }
87
+
88
+ @keyframes orbit {
89
+ 0% { transform: rotate(0deg) translateX(0) rotate(0deg); }
90
+ 50% { transform: rotate(180deg) translateX(50px) rotate(-180deg) scale(1.5); }
91
+ 100% { transform: rotate(360deg) translateX(0) rotate(-360deg); }
92
+ }
93
+ `,bt={shake:"0.4s","pulse-green":"2s infinite","bounce-in":"0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55)",float:"3s ease-in-out infinite",rubber:"0.6s",jello:"0.8s",heartbeat:"1.5s ease-in-out infinite",shimmer:"2s infinite",wobble:"4s infinite",pop:"0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)","fade-slide":"0.5s ease-out",swing:"2s infinite",flash:"0.5s",orbit:"1s ease-in-out","spin-pulse":"3s cubic-bezier(0.175, 0.885, 0.32, 1.275) infinite"},M=class{constructor(){this.isEnabled=!1}static{this.injectedRoots=new WeakSet}static injectKeyframes(n){if(this.injectedRoots.has(n))return;let t=document.createElement("style");t.textContent=ai,n.prepend(t),this.injectedRoots.add(n)}animate(n,t,r){if(!this.isEnabled)return;n.style.animation="";let i=r?.duration||"",a=r?.timing||"",o=r?.iterations||"",s=r?.delay||"",l="";i||a||o||s?l=`${t} ${i} ${a} ${s} ${o}`.trim():l=`${t} ${bt[t]}`,n.style.animation=l}stop(n){n.style.animation=""}animateFor(n,t,r,i){this.isEnabled&&(this.animate(n,t,i),setTimeout(()=>{this.stop(n)},r))}getAvailableAnimations(){return Object.keys(bt)}addAnimationClass(n,t){this.isEnabled&&n.classList.add(`anim-${t}`)}removeAnimationClass(n,t){n.classList.remove(`anim-${t}`)}};var B=class{constructor(){this.isEnabled=!0;this.audioCache=new Map;this.activeSounds=new Set;this.baseUrl="assets/audio/";this.localSounds={success:"success.mp3",failure:"failure.mp3",pop:"pop.mp3","low-time":"low-time.mp3",start:"start.mp3",flip:"flip.mp3"};if(typeof window<"u"){let n=document.querySelector("base")?.href||window.location.origin;this.baseUrl=new URL("assets/audio/",n).href}}async playSound(n,t={}){if(this.isEnabled)try{let r=this.resolveUrl(n),i=await this.getAudio(r);this.configureAudio(i,t),await this.playAudio(i,t)}catch(r){let i=r instanceof Error?r:new Error(String(r));console.warn(`[SoundManager] Failed to play sound "${n}":`,i.message),t.onError&&t.onError(i)}}async preload(n){let t=n.map(async r=>{try{let i=this.resolveUrl(r);await this.getAudio(i)}catch(i){console.warn(`[SoundManager] Failed to preload sound "${r}":`,i)}});await Promise.allSettled(t)}stopAll(){this.activeSounds.forEach(n=>{n.pause(),n.currentTime=0}),this.activeSounds.clear()}stop(n){let t=this.resolveUrl(n),r=this.audioCache.get(t);r&&(r.pause(),r.currentTime=0,this.activeSounds.delete(r))}clearCache(){this.stopAll(),this.audioCache.clear()}setGlobalVolume(n){let t=Math.max(0,Math.min(1,n));this.activeSounds.forEach(r=>{r.volume=t})}resolveUrl(n){if(n in this.localSounds){let t=this.localSounds[n];return`${this.baseUrl}${t}`}return n.startsWith("http://")||n.startsWith("https://")?n:`${this.baseUrl}${n}`}async getAudio(n){if(this.audioCache.has(n))return this.audioCache.get(n).cloneNode(!0);let t=new Audio,r=new Promise((i,a)=>{let o=setTimeout(()=>{a(new Error("Audio loading timeout"))},1e4);t.addEventListener("canplaythrough",()=>{clearTimeout(o),i()},{once:!0}),t.addEventListener("error",()=>{clearTimeout(o),a(new Error(`Failed to load audio: ${n}`))},{once:!0})});return t.src=n,t.preload="auto",t.load(),await r,this.audioCache.set(n,t),t.cloneNode(!0)}configureAudio(n,t){n.volume=t.volume!==void 0?Math.max(0,Math.min(1,t.volume)):1,n.loop=t.loop??!1,n.playbackRate=t.playbackRate??1,t.fadeIn&&t.fadeIn>0&&(n.volume=0,this.fadeVolume(n,t.volume??1,t.fadeIn))}async playAudio(n,t){this.activeSounds.add(n);let r=()=>{this.activeSounds.delete(n),t.onEnd&&t.onEnd()};n.addEventListener("ended",r,{once:!0}),t.fadeOut&&t.fadeOut>0&&!t.loop&&n.addEventListener("timeupdate",()=>{n.duration-n.currentTime<=t.fadeOut/1e3&&this.fadeVolume(n,0,t.fadeOut)});try{await n.play()}catch(i){throw this.activeSounds.delete(n),new Error(`Playback failed: ${i instanceof Error?i.message:String(i)}`)}}fadeVolume(n,t,r){let i=n.volume,a=t-i,o=Date.now(),s=()=>{let l=Date.now()-o,c=Math.min(l/r,1);n.volume=i+a*c,c<1&&this.activeSounds.has(n)&&requestAnimationFrame(s)};requestAnimationFrame(s)}},Pe=new B;var x=class extends HTMLElement{constructor(t,r,i,a){super();this.isValid=!0;this.implementsProgress=!0;this._initialized=!1;this.errors="";if(!t||!r){console.warn("[BaseInteraction] Constructor called without required parameters"),this.id=crypto.randomUUID(),this.data=t,this.config=r||{},this.assets=i||null,this.isValid=!1;return}if(this.id=crypto.randomUUID(),this.data=t,this.config=r,this.assets=i||null,a){let o=a(this.data);o.ok||(this.isValid=!1,Object.entries(o.errors).forEach(([s,l])=>{this.errors=`${this.errors}
94
+ ${s}: ${l}`}))}this.progressTracker=new Re,this.soundManager=new B,this.animationsManager=new M,this.animationsManager.isEnabled=this.config?.animationsEnabled??!0,this.soundManager.isEnabled=this.config?.soundEnabled??!0,this.setAttribute("variant",this.config?.variant??"elegant")}connectedCallback(){if(!this._initialized){if(this._initialized=!0,!this.isValid)return;this.initialize(),requestAnimationFrame(()=>{this.render(),this.emitReady()})}}disconnectedCallback(){this.cleanup()}initialize(){}cleanup(){}initializeProgress(t){this.progressTracker.initialize(t),this.emitProgress()}setProgress(t){this.progressTracker.setCurrent(t),this.emitProgress()}incrementProgress(){this.progressTracker.increment(),this.emitProgress()}decrementProgress(){this.progressTracker.decrement(),this.emitProgress()}getProgress(){return{current:this.progressTracker.current,total:this.progressTracker.total,percentage:this.progressTracker.getPercentage()}}emitReady(){this.dispatchEvent(new CustomEvent("interaction:ready",{detail:{id:this.id},bubbles:!0,composed:!0}))}emitProgress(){let t=this.getProgress();this.dispatchEvent(new CustomEvent("interaction:progress",{detail:t,bubbles:!0,composed:!0}))}emitStateChange(){this.dispatchEvent(new CustomEvent("interaction:state-change",{detail:{state:this.getCurrentState(),isComplete:this.isInteractionComplete()},bubbles:!0,composed:!0}))}emitComplete(){this.dispatchEvent(new CustomEvent("interaction:complete",{detail:{state:this.getCurrentState(),id:this.id},bubbles:!0,composed:!0}))}emitHintShown(t){this.dispatchEvent(new CustomEvent("interaction:hint-shown",{detail:{message:t},bubbles:!0,composed:!0}))}emitError(t,r){this.dispatchEvent(new CustomEvent("interaction:error",{detail:{error:t,message:r||t.message},bubbles:!0,composed:!0}))}onChange(t){}setSteps(t){}submit(){this.setAttribute("inert",""),this.emitComplete()}hint(){this.onHint()}reset(){this.progressTracker.reset(),this.emitProgress(),this.removeAttribute("inert"),this.render()}set(t){this.config.variant=t,this.setAttribute("variant",t),this.onVariantChange(t)}get(){return this.getAttribute("variant")||this.config.variant||"outline"}};var oi=`
95
+ <style>
96
+ :host {
97
+ display: block;
98
+ cursor: pointer;
99
+ --accent-color: rgb(var(--edu-first-accent));
100
+ }
101
+
102
+ .block {
103
+ display: flex;
104
+ flex-direction: column;
105
+ color: rgb(var(--edu-ink));
106
+ align-items: center;
107
+ justify-content: center;
108
+ gap: 0.5rem;
109
+ padding: 1rem;
110
+ background: rgb(var(--edu-bg));
111
+ border: 2px solid rgb(var(--edu-border));
112
+ border-radius: var(--edu-radius);
113
+ height: 100%;
114
+ box-sizing: border-box;
115
+ transition: all 0.2s ease;
116
+ text-align: center;
117
+ width: 100%;
118
+ min-height: 44px;
119
+ }
120
+
121
+ .block:hover {
122
+ transform: translateY(-2px);
123
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.15);
124
+ }
125
+
126
+ .block[variant="elegant"] {
127
+ background: rgb(var(--edu-card));
128
+ border-radius: 8px;
129
+ color: rgb(var(--edu-ink));
130
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.1);
131
+ border-left: 4px solid var(--accent-color);
132
+ }
133
+
134
+ .block[variant="elegant"]:hover {
135
+ box-shadow: 0 6px 16px rgba(var(--edu-shadow-color), 0.15);
136
+ transform: translateY(-3px);
137
+ }
138
+
139
+ .block[variant="playful"] {
140
+ background: var(--accent-color);
141
+ border: none;
142
+ color: rgb(var(--edu-inverted-ink));
143
+ border-radius: 16px;
144
+ box-shadow: 2px 2px 0px rgba(var(--edu-shadow-color) / 0.2);
145
+ }
146
+
147
+ .block[variant="playful"]:hover {
148
+ transform: translateY(-2px) rotate(-2deg);
149
+ box-shadow: 0 6px 16px rgba(var(--edu-first-accent), 0.4);
150
+ }
151
+
152
+ .block[variant="outline"] {
153
+ background: transparent;
154
+ border: 2px solid var(--accent-color);
155
+ border-top: 6px solid var(--accent-color);
156
+ border-radius: 0;
157
+ }
158
+
159
+ .block[variant="outline"]:hover {
160
+ background: rgb(var(--edu-first-accent) / 0.1);
161
+ border-width: 3px;
162
+ }
163
+
164
+ .block[variant="letter"] {
165
+ font-family: georgia, serif;
166
+ color: rgb(var(--edu-ink));
167
+ background: rgb(var(--edu-card));
168
+ border: 1px solid rgb(var(--edu-border));
169
+ border-radius: 4px;
170
+ box-shadow: inset 0 0 0 1px rgba(var(--edu-shadow-color), 0.05);
171
+ }
172
+
173
+ .block[variant="letter"]:hover {
174
+ box-shadow:
175
+ inset 0 0 0 1px rgba(var(--edu-shadow-color), 0.05),
176
+ 0 2px 6px rgba(var(--edu-shadow-color), 0.1);
177
+ }
178
+
179
+ .block[variant="minimal"] {
180
+ background: rgb(var(--edu-card));
181
+ color: rgb(var(--edu-ink));
182
+ border: 1px solid rgb(var(--edu-border));
183
+ border-radius: 6px;
184
+ padding: 0.75rem;
185
+ }
186
+
187
+ .block[variant="minimal"]:hover {
188
+ border-color: rgb(var(--edu-first-accent) / 0.5);
189
+ box-shadow: 0 1px 4px rgba(var(--edu-shadow-color), 0.1);
190
+ }
191
+
192
+ .block[variant="glass"] {
193
+ background: rgba(var(--edu-card), 0.7);
194
+ backdrop-filter: blur(10px);
195
+ border: 2px solid rgba(var(--edu-border), 0.35);
196
+ border-radius: 12px;
197
+ }
198
+
199
+ .block[variant="glass"]:hover {
200
+ background: rgba(var(--edu-card), 0.85);
201
+ border-color: rgba(var(--edu-first-accent), 0.5);
202
+ }
203
+
204
+ .block[variant="card"] {
205
+ background: rgb(var(--edu-card));
206
+ border: 2px solid rgb(var(--edu-border));
207
+ border-radius: 8px;
208
+ box-shadow: 0 2px 8px rgba(var(--edu-shadow-color), 0.08);
209
+ }
210
+
211
+ .block[variant="card"]:hover {
212
+ border-color: rgb(var(--edu-first-accent));
213
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.12);
214
+ }
215
+
216
+ .block[variant="sign"] {
217
+ background: rgb(var(--edu-card));
218
+ border: 4px double rgb(var(--edu-border));
219
+ color: rgb(var(--edu-ink));
220
+ border-radius: 0;
221
+ text-align: center;
222
+ text-transform: uppercase;
223
+ letter-spacing: 2px;
224
+ font-weight: 700;
225
+ }
226
+
227
+ .block[variant="sign"]:hover {
228
+ border-color: var(--accent-color);
229
+ background: var(accent-color);
230
+ }
231
+
232
+ .block[variant="empty"] {
233
+ background: transparent;
234
+ color: rgb(var(--edu-ink));
235
+ border: 3px solid rgb(var(--edu-ink));
236
+ border-radius: 0;
237
+ padding: 0.75rem;
238
+ }
239
+
240
+ .block[variant="empty"]:hover {
241
+ background: var(--accent-color);
242
+ color: rgb(var(--edu-inverted-ink));
243
+ border-color: rgb(var(--edu-ink));
244
+ }
245
+ </style>
246
+ <div class="block" part="block">
247
+ <slot></slot>
248
+ </div>
249
+ `,G=class extends HTMLElement{static get observedAttributes(){return["variant"]}constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=oi,this.$blockEl=this.shadowRoot.querySelector(".block"),M.injectKeyframes(this.shadowRoot)}connectedCallback(){this.hasAttribute("variant")||(this.variant="outline"),this.sync()}attributeChangedCallback(){this.sync()}sync(){this.$blockEl&&this.$blockEl.setAttribute("variant",this.variant)}getBlock(){return this.$blockEl}get variant(){return this.getAttribute("variant")??"outline"}set variant(n){this.setAttribute("variant",n)}setAccentColor(n){this.shadowRoot.host.style.setProperty("--accent-color",n)}removeSelf(){this.remove()}};customElements.get("edu-block")||customElements.define("edu-block",G);var vt=`<div class="chip-container" part="container">
250
+
251
+ <div class="content-zone" part="content-zone" role="button" tabindex="0" aria-pressed="false">
252
+ <span class="prefix" part="prefix"></span>
253
+
254
+ <div class="content-inner" part="content">
255
+ <slot></slot>
256
+ </div>
257
+
258
+ <!-- Shows for: audio, video, tts, anchor, interactive, data, dynamic, composite -->
259
+ <button class="modality-action" part="modality-action" type="button" aria-label="Modality action">
260
+ <svg class="icon" width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
261
+ <!-- Icon will be set dynamically based on modality -->
262
+ <img src="assets/icons/drag-vertical-svgrepo-com.svg" alt="..." width="24" height="24"/>
263
+ </svg>
264
+ </button>
265
+
266
+ <span class="drag-handle" part="drag-handle">
267
+ <img src="assets/icons/drag-horizontal-svgrepo-com.svg" alt="..." width="24" height="24"/>
268
+ </span>
269
+
270
+ </div>
271
+ </div>
272
+
273
+
274
+ `;var xt=`/* ==================== BASE STYLES ==================== */
275
+
276
+ * { box-sizing: border-box; }
277
+
278
+ :host {
279
+ display: inline-block;
280
+ --chip-color: rgb(var(--edu-first-accent));
281
+ --chip-colored-color: #d1d1d1;
282
+ }
283
+
284
+ :host([colored]) {
285
+ & .chip-container { position: relative; }
286
+
287
+ & .chip-container::after {
288
+ content: '';
289
+ position: absolute;
290
+ top: -2px;
291
+ left: -2px;
292
+ right: -2px;
293
+ bottom: -2px;
294
+ border-radius: 10px;
295
+ background: var(--chip-colored-color);
296
+ opacity: 0.18;
297
+ mix-blend-mode: multiply;
298
+ z-index: 2;
299
+ pointer-events: none;
300
+ }
301
+ }
302
+
303
+ :host([aria-disabled]) {
304
+ opacity: 0.4;
305
+ cursor: not-allowed;
306
+ }
307
+
308
+ .chip-container {
309
+ display: flex;
310
+ flex-direction: column;
311
+ align-items: center;
312
+ position: relative;
313
+ width: 100%;height: 100%;
314
+ }
315
+
316
+ ::slotted(img.chip-image) {
317
+ border: 1px solid rgb(var(--edu-border));
318
+ }
319
+
320
+ /* ==================== PREFIX ==================== */
321
+
322
+ .prefix {
323
+ display: none;
324
+ font-weight: 600;
325
+ color: rgb(var(--edu-second-ink));
326
+ flex-shrink: 0;
327
+ margin-right: 1rem;
328
+ position: relative;
329
+ z-index: 1;
330
+ }
331
+
332
+ :host([prefix]) .prefix {
333
+ display: inline-flex;
334
+ }
335
+
336
+ /* ==================== CONTENT ZONE ==================== */
337
+
338
+ .content-zone {
339
+ display: flex;
340
+ align-items: center;
341
+ justify-content: center;
342
+ position: relative;
343
+ background: rgb(var(--edu-card));
344
+ border: 1px solid rgb(var(--edu-border));
345
+ padding: 0.5rem 1rem;
346
+ cursor: pointer;
347
+ font-size: 1rem;
348
+ font-weight: 500;
349
+ text-align: center;
350
+ transition: all 0.2s ease;
351
+ user-select: none;
352
+ margin: 0.25rem;
353
+ border-radius: var(--edu-radius);
354
+ color: rgb(var(--edu-ink));
355
+ width: 100%;
356
+ height: 100%;
357
+ box-sizing: border-box;
358
+ z-index: 1;
359
+ }
360
+
361
+ .content-zone:hover:not([aria-disabled="true"]) {
362
+ box-shadow: 0 2px 8px rgb(var(--edu-shadow-color) / 0.15);
363
+ }
364
+
365
+ .content-zone:active:not([aria-disabled="true"]) {
366
+ }
367
+
368
+ .content-zone[aria-disabled="true"] {
369
+ opacity: 0.5;
370
+ cursor: not-allowed;
371
+ }
372
+
373
+ .content-zone:focus-visible {
374
+ outline: 2px solid var(--chip-color);
375
+ outline-offset: 2px;
376
+ }
377
+
378
+ /* ==================== CONTENT INNER ==================== */
379
+
380
+ .content-inner {
381
+ flex: 1;
382
+ display: flex;
383
+ align-items: center;
384
+ justify-content: center;
385
+ min-width: 0;
386
+ }
387
+
388
+ /* ==================== MODALITY ACTION BUTTON ==================== */
389
+
390
+ .modality-action {
391
+ position: absolute;
392
+ top: 50%;
393
+ left: 50%;
394
+ display: none;
395
+ align-items: center;
396
+ justify-content: center;
397
+ width: 36px;
398
+ height: 36px;
399
+ border-radius: 50%;
400
+ border: none;
401
+ background: var(--chip-color);
402
+ color: rgb(var(--edu-inverted-ink));
403
+ cursor: pointer;
404
+ transition: all 0.2s;
405
+ z-index: 10;
406
+ box-shadow: 0 2px 8px rgba(var(--edu-shadow-color), 0.2);
407
+ }
408
+
409
+ .modality-action:hover:not(:disabled) {
410
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.3);
411
+ }
412
+
413
+ .modality-action:active:not(:disabled) {
414
+ }
415
+
416
+ .modality-action:disabled {
417
+ opacity: 0.5;
418
+ cursor: not-allowed;
419
+ }
420
+
421
+ /* ==================== DRAG HANDLE ==================== */
422
+
423
+ .drag-handle {
424
+ display: none;
425
+ align-items: center;
426
+ justify-content: center;
427
+ background-color: rgb(var(--edu-muted) / 0.6);
428
+ color: rgb(var(--edu-third-ink));
429
+ cursor: grab;
430
+ flex-shrink: 0;
431
+ padding: 0.25rem;
432
+ border-radius: 4px;
433
+ transition: all 0.2s;
434
+ position: relative;
435
+ z-index: 1;
436
+ }
437
+
438
+ .drag-handle:hover {
439
+ background: rgb(var(--edu-muted));
440
+ color: rgb(var(--edu-first-accent));
441
+ }
442
+
443
+ .drag-handle:active {
444
+ cursor: grabbing;
445
+ background-color: rgb(var(--edu-muted) / 0.9);
446
+ }
447
+
448
+ :host([draggable]) .drag-handle {
449
+ display: flex;
450
+ }
451
+
452
+ .drag-handle[aria-disabled="true"] {
453
+ opacity: 0.5;
454
+ cursor: not-allowed;
455
+ }
456
+
457
+
458
+ /* ==================== SELECTED STATE (ENHANCED) ==================== */
459
+
460
+ :host([selected]) .content-zone {
461
+ box-shadow: 0 0 0 3px rgba(var(--chip-color), 0.3);
462
+ border-color: var(--chip-color);
463
+ background: rgba(var(--chip-color), 0.1);
464
+ }
465
+
466
+ /* ==================== STATE FEEDBACK ==================== */
467
+
468
+ :host([state="correct"]) .content-zone {
469
+ border: 4px solid rgb(var(--edu-success));
470
+ background: rgba(var(--edu-success), 0.1);
471
+ box-shadow: 0 0 0 2px rgb(var(--edu-success) / 0.2);
472
+ }
473
+
474
+ :host([state="correct"]) .content-zone::after {
475
+ content: '\u2713';
476
+ position: absolute;
477
+ top: -8px;
478
+ right: -8px;
479
+ width: 24px;
480
+ height: 24px;
481
+ background: rgb(var(--edu-success));
482
+ color: white;
483
+ display: flex;
484
+ align-items: center;
485
+ justify-content: center;
486
+ font-size: 14px;
487
+ font-weight: bold;
488
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
489
+ }
490
+
491
+ :host([state="wrong"]) .content-zone {
492
+ border: 4px solid rgb(var(--edu-error));
493
+ background: rgb(var(--edu-error) / 0.1);
494
+ box-shadow: 0 0 0 2px rgb(var(--edu-error) / 0.2);
495
+ }
496
+
497
+ :host([state="wrong"]) .content-zone::after {
498
+ content: '\u2717';
499
+ position: absolute;
500
+ top: -8px;
501
+ right: -8px;
502
+ width: 24px;
503
+ height: 24px;
504
+ background: rgb(var(--edu-error));
505
+ color: white;
506
+ display: flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ font-size: 14px;
510
+ font-weight: bold;
511
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
512
+ }
513
+
514
+ :host([state="missed"]) .content-zone {
515
+ border: 4px solid rgb(var(--edu-warning));
516
+ background: rgb(var(--edu-warning) / 0.1);
517
+ box-shadow: 0 0 0 2px rgb(var(--edu-warning) / 0.2);
518
+ }
519
+
520
+ :host([state="missed"]) .content-zone::after {
521
+ content: '!';
522
+ position: absolute;
523
+ top: -8px;
524
+ right: -8px;
525
+ width: 24px;
526
+ height: 24px;
527
+ background: rgb(var(--edu-warning));
528
+ color: rgb(var(--edu-ink));
529
+ display: flex;
530
+ align-items: center;
531
+ justify-content: center;
532
+ font-size: 14px;
533
+ font-weight: bold;
534
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
535
+ }
536
+
537
+ /* ==================== VARIANT: ELEGANT ==================== */
538
+
539
+ :host([variant="elegant"]) .content-zone {
540
+ background-color: rgb(var(--edu-card));
541
+ color: rgb(var(--edu-ink) / 0.8);
542
+ border-radius: 4px;
543
+ box-shadow: 4px 4px 0 rgb(var(--edu-border));
544
+ }
545
+
546
+ :host([variant="elegant"]) .content-zone:hover:not([aria-disabled="true"]) {
547
+ box-shadow: 1px 1px 0 rgb(var(--edu-border));
548
+ }
549
+
550
+ :host([variant="elegant"]) .content-zone:active:not([aria-disabled="true"]) {
551
+ box-shadow: 0 0 0 rgb(var(--edu-border));
552
+ }
553
+
554
+ :host([variant="elegant"]) .prefix {
555
+ color: var(--chip-color);
556
+ }
557
+
558
+ :host([variant="elegant"][selected]) .content-zone {
559
+ border-color: var(--chip-color);
560
+ background: rgb(var(--chip-color) / 0.1);
561
+ box-shadow: 0 0 0 3px rgb(var(--chip-color) / 0.3);
562
+ }
563
+
564
+ :host([variant="elegant"]) ::slotted(img.chip-image) {
565
+ border: none;
566
+ border-radius: 4px;
567
+ box-shadow: 4px 4px 0 rgb(var(--edu-border));
568
+ }
569
+
570
+ /* ==================== VARIANT: PLAYFUL ==================== */
571
+
572
+ :host([variant="playful"]) .content-zone {
573
+ background: var(--chip-color);
574
+ color: rgb(var(--edu-inverted-ink));
575
+ border-radius: 12px;
576
+ border: none;
577
+ box-shadow: 0 4px 12px rgb(var(--chip-color) / 0.3);
578
+ font-weight: 600;
579
+ }
580
+
581
+ :host([variant="playful"]) .content-zone:hover:not([aria-disabled="true"]) {
582
+ box-shadow: 0 6px 16px rgba(var(--chip-color), 0.4);
583
+ }
584
+
585
+ :host([variant="playful"]) .content-zone:active:not([aria-disabled="true"]) {
586
+ }
587
+
588
+ :host([variant="playful"]) .prefix {
589
+ color: rgb(var(--edu-inverted-ink));
590
+ opacity: 0.9;
591
+ }
592
+
593
+ :host([variant="playful"]) .modality-action {
594
+ background: rgb(var(--edu-card));
595
+ color: var(--chip-color);
596
+ }
597
+
598
+ :host([variant="playful"][selected]) .content-zone {
599
+ box-shadow: 0 0 0 3px rgb(var(--edu-first-accent) / 0.4), 0 6px 16px rgb(var(--edu-first-accent) / 0.4);
600
+ }
601
+
602
+ :host([variant="playful"]) ::slotted(img.chip-image) {
603
+ border: 4px solid rgb(var(--edu-border) / 0.6);
604
+ border-radius: 4px;
605
+ }
606
+
607
+
608
+ /* ==================== VARIANT: OUTLINE ==================== */
609
+
610
+ :host([variant="outline"]) .content-zone {
611
+ background: transparent;
612
+ border: 2px solid var(--chip-color);
613
+ border-radius: 0;
614
+ color: rgb(var(--edu-ink));
615
+ }
616
+
617
+ :host([variant="outline"]) .content-zone:hover:not([aria-disabled="true"]) {
618
+ background: var(--chip-color);
619
+ border-color: rgb(var(--edu-inverted-ink));
620
+ color: rgb(var(--edu-inverted-ink));
621
+ }
622
+
623
+ :host([variant="outline"]) .content-zone:hover:not([aria-disabled="true"]) .prefix {
624
+ color: rgb(var(--edu-inverted-ink));
625
+ }
626
+
627
+ :host([variant="outline"][selected]) .content-zone {
628
+ background: rgba(var(--chip-color), 0.1);
629
+ border-color: var(--chip-color);
630
+ color: rgb(var(--edu-ink));
631
+ border-width: 6px;
632
+ }
633
+
634
+ :host([variant="outline"]) ::slotted(img.chip-image) {
635
+ border: 2px solid rgb(var(--edu-first-accent));
636
+ }
637
+
638
+ /* ==================== VARIANT: EMPTY ==================== */
639
+
640
+ :host([variant="empty"]) .content-zone {
641
+ background: transparent;
642
+ border-radius: 0;
643
+ color: rgb(var(--edu-ink));
644
+ padding: 0.25rem 0.5rem;
645
+ border: 3px solid rgb(var(--edu-ink));
646
+ }
647
+
648
+ :host([variant="empty"]) .content-zone:hover:not([aria-disabled="true"]) {
649
+ background: rgb(var(--edu-muted));
650
+ }
651
+
652
+ :host([variant="empty"]) .content-zone:active:not([aria-disabled="true"]) {
653
+ background: rgb(var(--edu-border));
654
+ }
655
+
656
+ :host([variant="empty"][selected]) .content-zone {
657
+ background: rgb(var(--edu-first-accent) / 0.15);
658
+ border-color: var(--chip-color);
659
+ }
660
+
661
+ /* ==================== VARIANT: LETTER ==================== */
662
+
663
+ :host([variant="letter"]) .content-zone {
664
+ font-family: georgia, serif;
665
+ box-shadow: inset 0 0 0 1px rgba(var(--edu-shadow-color), 0.05);
666
+ border-radius: 2px;
667
+ background: rgb(var(--edu-card));
668
+ color: rgb(var(--edu-ink));
669
+ font-size: 0.95rem;
670
+ letter-spacing: 0.5px;
671
+ }
672
+
673
+ :host([variant="letter"]) .content-zone:hover:not([aria-disabled="true"]) {
674
+ box-shadow:
675
+ inset 0 0 0 1px rgba(var(--edu-shadow-color), 0.05),
676
+ 0 2px 6px rgba(var(--edu-shadow-color), 0.1);
677
+ }
678
+
679
+ :host([variant="letter"]) .prefix {
680
+ font-family: georgia, serif;
681
+ font-style: italic;
682
+ }
683
+
684
+ :host([variant="letter"]) .content-inner {
685
+ font-family: georgia, serif;
686
+ }
687
+
688
+ :host([variant="letter"][selected]) .content-zone {
689
+ border-color: var(--chip-color);
690
+ background: rgb(var(--edu-muted));
691
+ box-shadow: 0 0 0 2px rgba(var(--chip-color), 0.3);
692
+ }
693
+
694
+ /* ==================== VARIANT: MINIMAL ==================== */
695
+
696
+ :host([variant="minimal"]) .content-zone {
697
+ background: rgb(var(--edu-card));
698
+ border: 1px solid rgb(var(--edu-border));
699
+ border-radius: 6px;
700
+ color: rgb(var(--edu-ink));
701
+ padding: 0.4rem 0.75rem;
702
+ font-size: 0.9rem;
703
+ }
704
+
705
+ :host([variant="minimal"]) .content-zone:hover:not([aria-disabled="true"]) {
706
+ border-color: rgba(var(--chip-color), 0.5);
707
+ box-shadow: 0 1px 4px rgba(var(--edu-shadow-color), 0.1);
708
+ }
709
+
710
+ :host([variant="minimal"][selected]) .content-zone {
711
+ border-color: var(--chip-color);
712
+ background: rgba(var(--chip-color), 0.08);
713
+ }
714
+
715
+ /* ==================== VARIANT: GLASS ==================== */
716
+
717
+ :host([variant="glass"]) .content-zone {
718
+ background: rgb(var(--edu-card));
719
+ border: 2px solid rgb(var(--edu-border));
720
+ border-radius: 0;
721
+ color: rgb(var(--edu-ink));
722
+ padding: 0.5rem 1.2rem;
723
+ font-weight: 700;
724
+ letter-spacing: 1.5px;
725
+ font-size: 0.9rem;
726
+ }
727
+
728
+ :host([variant="glass"]) .content-zone:hover:not([aria-disabled="true"]) {
729
+ background: var(--chip-color);
730
+ color: rgb(var(--edu-inverted-ink));
731
+ border-color: var(--chip-color);
732
+ }
733
+
734
+ :host([variant="glass"]) .content-zone:active:not([aria-disabled="true"]) {
735
+ background: rgba(var(--chip-color), 0.9);
736
+ }
737
+
738
+ :host([variant="glass"]) .prefix {
739
+ font-weight: 800;
740
+ }
741
+
742
+ :host([variant="glass"][selected]) .content-zone {
743
+ background: rgba(var(--chip-color), 0.15);
744
+ border-color: var(--chip-color);
745
+ box-shadow: 0 0 0 2px rgba(var(--chip-color), 0.3);
746
+ }
747
+
748
+ /* ==================== VARIANT: CARD ==================== */
749
+
750
+ :host([variant="card"]) .content-zone {
751
+ background: transparent;
752
+ border: 2px solid rgb(var(--edu-border));
753
+ border-radius: 4px;
754
+ color: rgb(var(--edu-ink));
755
+ }
756
+
757
+ :host([variant="card"]) .content-zone:hover:not([aria-disabled="true"]) {
758
+ background: rgb(var(--edu-muted));
759
+ border-color: var(--chip-color);
760
+ }
761
+
762
+ :host([variant="card"]) .content-zone:active:not([aria-disabled="true"]) {
763
+ background: rgb(var(--edu-border));
764
+ }
765
+
766
+ :host([variant="card"]) .prefix {
767
+ color: var(--chip-color);
768
+ }
769
+
770
+ :host([variant="card"][selected]) .content-zone {
771
+ border-color: var(--chip-color);
772
+ box-shadow: 0 0 0 3px rgba(var(--chip-color), 0.2);
773
+ }
774
+
775
+ /* ==================== VARIANT: SIGN ==================== */
776
+
777
+ :host([variant="sign"]) .content-zone {
778
+ background: rgb(var(--edu-card));
779
+ border-radius: 0;
780
+ color: rgb(var(--edu-ink));
781
+ padding: 0.5rem 1.2rem;
782
+ font-size: 0.9rem;
783
+ font-weight: bold;
784
+ transform: skewX(-10deg);
785
+ text-transform: uppercase;
786
+ letter-spacing: 0.2rem;
787
+ }
788
+
789
+ :host([variant="sign"]) .content-zone:hover:not([aria-disabled="true"]) {
790
+ background: var(--chip-color);
791
+ color: rgb(var(--edu-inverted-ink));
792
+ border-color: var(--chip-color);
793
+ }
794
+
795
+ :host([variant="sign"]) .content-zone:active:not([aria-disabled="true"]) {
796
+ background: rgba(var(--chip-color), 0.9);
797
+ }
798
+
799
+ :host([variant="sign"]) .prefix {
800
+ font-weight: 800;
801
+ }
802
+
803
+ :host([variant="sign"]) .content-inner {
804
+ transform: skewX(10deg);
805
+ }
806
+
807
+ :host([variant="sign"][selected]) .content-zone {
808
+ background: var(--chip-color);
809
+ color: rgb(var(--edu-inverted-ink));
810
+ border-color: var(--chip-color);
811
+ box-shadow: 0 0 0 3px rgba(var(--chip-color), 0.3);
812
+ }
813
+
814
+ :host([variant="sign"]) ::slotted(img.chip-image) {
815
+ transform: skewX(-10deg);
816
+ }
817
+ `;var ci=`
818
+ <style>
819
+ :host {
820
+ display: none;
821
+ position: fixed;
822
+ inset: 0;
823
+ z-index: 9999;
824
+ align-items: center;
825
+ justify-content: center;
826
+ }
827
+
828
+ :host([open]) {
829
+ display: flex;
830
+ }
831
+
832
+ .backdrop {
833
+ position: absolute;
834
+ inset: 0;
835
+ background: rgba(0, 0, 0, 0.6);
836
+ backdrop-filter: blur(4px);
837
+ animation: fadeIn 0.2s ease;
838
+ }
839
+
840
+ .dialog {
841
+ position: relative;
842
+ background: rgb(var(--edu-card));
843
+ border-radius: 16px;
844
+ max-width: min(90vw, 600px);
845
+ max-height: min(90vh, 800px);
846
+ width: 100%;
847
+ box-shadow: 0 25px 50px -12px rgba(var(--edu-shadow-color), 0.5);
848
+ display: flex;
849
+ flex-direction: column;
850
+ animation: slideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
851
+ overflow: hidden;
852
+ }
853
+
854
+ .header {
855
+ padding: 1.5rem;
856
+ border-bottom: 2px solid rgb(var(--edu-border));
857
+ display: flex;
858
+ align-items: center;
859
+ justify-content: space-between;
860
+ flex-shrink: 0;
861
+ }
862
+
863
+ .header h3 {
864
+ margin: 0;
865
+ color: rgb(var(--edu-ink));
866
+ font-size: 1.25rem;
867
+ font-weight: 600;
868
+ }
869
+
870
+ .close-btn {
871
+ background: transparent;
872
+ border: none;
873
+ cursor: pointer;
874
+ padding: 0.5rem;
875
+ border-radius: 8px;
876
+ color: rgb(var(--edu-third-ink));
877
+ transition: all 0.2s;
878
+ display: flex;
879
+ align-items: center;
880
+ justify-content: center;
881
+ }
882
+
883
+ .close-btn:hover {
884
+ background: rgb(var(--edu-muted));
885
+ color: rgb(var(--edu-ink));
886
+ }
887
+
888
+ .content {
889
+ padding: 1.5rem;
890
+ overflow-y: auto;
891
+ flex: 1;
892
+ color: rgb(var(--edu-second-ink));
893
+ }
894
+
895
+ .content::-webkit-scrollbar {
896
+ width: 8px;
897
+ }
898
+
899
+ .content::-webkit-scrollbar-track {
900
+ background: rgb(var(--edu-muted));
901
+ border-radius: 4px;
902
+ }
903
+
904
+ .content::-webkit-scrollbar-thumb {
905
+ background: rgb(var(--edu-border));
906
+ border-radius: 4px;
907
+ }
908
+
909
+ .content::-webkit-scrollbar-thumb:hover {
910
+ background: rgb(var(--edu-third-ink));
911
+ }
912
+
913
+ .footer {
914
+ padding: 1rem 1.5rem;
915
+ border-top: 2px solid rgb(var(--edu-border));
916
+ display: flex;
917
+ justify-content: flex-end;
918
+ gap: 0.75rem;
919
+ flex-shrink: 0;
920
+ }
921
+
922
+ .footer button {
923
+ padding: 0.75rem 1.5rem;
924
+ border-radius: 8px;
925
+ border: none;
926
+ font-weight: 600;
927
+ cursor: pointer;
928
+ transition: all 0.2s;
929
+ font-size: 0.95rem;
930
+ }
931
+
932
+ .footer button.primary {
933
+ background: rgb(var(--edu-first-accent));
934
+ color: rgb(var(--edu-inverted-ink));
935
+ }
936
+
937
+ .footer button.primary:hover {
938
+ filter: brightness(1.1);
939
+ transform: translateY(-1px);
940
+ }
941
+
942
+ .footer button.secondary {
943
+ background: rgb(var(--edu-muted));
944
+ color: rgb(var(--edu-ink));
945
+ }
946
+
947
+ .footer button.secondary:hover {
948
+ background: rgb(var(--edu-border));
949
+ }
950
+
951
+ @keyframes fadeIn {
952
+ from { opacity: 0; }
953
+ to { opacity: 1; }
954
+ }
955
+
956
+ @keyframes slideUp {
957
+ from {
958
+ opacity: 0;
959
+ transform: translateY(20px) scale(0.95);
960
+ }
961
+ to {
962
+ opacity: 1;
963
+ transform: translateY(0) scale(1);
964
+ }
965
+ }
966
+
967
+ @media (max-width: 640px) {
968
+ .dialog {
969
+ max-width: 95vw;
970
+ max-height: 95vh;
971
+ border-radius: 12px;
972
+ }
973
+
974
+ .header, .content, .footer {
975
+ padding: 1rem;
976
+ }
977
+ }
978
+ </style>
979
+
980
+ <div class="backdrop" part="backdrop"></div>
981
+ <div class="dialog" part="dialog">
982
+ <div class="header" part="header">
983
+ <h3 id="title"></h3>
984
+ <button class="close-btn" part="close-btn" aria-label="Close dialog">
985
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor">
986
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 6l8 8M14 6l-8 8"/>
987
+ </svg>
988
+ </button>
989
+ </div>
990
+ <div class="content" part="content">
991
+ <slot></slot>
992
+ </div>
993
+ <div class="footer" part="footer" style="display: none;">
994
+ <slot name="footer"></slot>
995
+ </div>
996
+ </div>
997
+ `,de=class extends HTMLElement{constructor(){super();this.handleEscape=t=>{t.key==="Escape"&&this.hasAttribute("open")&&this.close()};this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=ci,this.$backdrop=this.shadowRoot.querySelector(".backdrop"),this.$dialog=this.shadowRoot.querySelector(".dialog"),this.$title=this.shadowRoot.querySelector("#title"),this.$content=this.shadowRoot.querySelector(".content"),this.$footer=this.shadowRoot.querySelector(".footer"),this.$closeBtn=this.shadowRoot.querySelector(".close-btn")}static get observedAttributes(){return["open","title"]}connectedCallback(){this.$backdrop.addEventListener("click",()=>this.close()),this.$closeBtn.addEventListener("click",()=>this.close()),document.addEventListener("keydown",this.handleEscape);let t=this.shadowRoot.querySelector('slot[name="footer"]');t.addEventListener("slotchange",()=>{let r=t.assignedNodes().length>0;this.$footer.style.display=r?"flex":"none"})}disconnectedCallback(){document.removeEventListener("keydown",this.handleEscape)}attributeChangedCallback(t,r,i){t==="title"?this.$title.textContent=i||"":t==="open"&&i!==r&&(this.hasAttribute("open")?document.body.style.overflow="hidden":document.body.style.overflow="")}open(){this.setAttribute("open",""),this.dispatchEvent(new CustomEvent("dialog:open",{bubbles:!0,composed:!0}))}close(){this.removeAttribute("open"),this.dispatchEvent(new CustomEvent("dialog:close",{bubbles:!0,composed:!0}))}setContent(t){this.$content.innerHTML=t}get isOpen(){return this.hasAttribute("open")}get title(){return this.getAttribute("title")||""}set title(t){this.setAttribute("title",t)}};customElements.get("edu-dialog")||customElements.define("edu-dialog",de);function L(e,n,t){if(!t||!e.startsWith("@:")||e.length<3){n.textContent=e;return}let r=e.slice(2,e.length);if(!t[r]){n.textContent=r;return}let i=t[r],a=i.type;switch(n.modality=a,a){case"image":n.data=i.url;break;case"video":break;case"audio":break;case"html":n.data=i.content;break}}var Qe=class extends HTMLElement{static get observedAttributes(){return["accent","variant","selected","prefix","disabled","modality","state","display","color","colored","draggable"]}constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=vt;let n=document.createElement("style");n.textContent=xt,this.shadowRoot.append(n),this.$prefix=this.shadowRoot.querySelector(".prefix"),this.$chip=this.shadowRoot.querySelector(".content-zone"),this.$dragHandler=this.shadowRoot.querySelector(".drag-handle"),this.$dialog=new de,M.injectKeyframes(this.shadowRoot)}connectedCallback(){this.hasAttribute("variant")||(this.variant="outline"),this.sync()}attributeChangedCallback(){this.sync()}getButton(){return this.$chip}getPrefix(){return this.$prefix}getDragHandler(){return this.$dragHandler}sync(){this.hasAttribute("prefix")&&(this.$prefix.textContent=this.prefix??""),this.hasAttribute("draggable")&&(this.style.userSelect="none",this.style.touchAction="none");let n=this.selected?"true":"false";this.$chip.setAttribute("aria-pressed",n)}updateContent(){if(!this.hasAttribute("data")||!this.hasAttribute("modality"))return;let n=this.getAttribute("modality"),t=this.getAttribute("data");switch(n){case"image":this.innerHTML=`<img src="${t}" alt="no image" class="chip-image" width="64" height="64"/>`;break;case"audio":break;case"video":break;case"html":this.innerHTML=t}}get variant(){return this.getAttribute("variant")??"outline"}set variant(n){this.setAttribute("variant",n)}get prefix(){return this.getAttribute("prefix")}set prefix(n){n==null||n===""?this.removeAttribute("prefix"):this.setAttribute("prefix",String(n))}get chipState(){return this.getAttribute("state")}set chipState(n){n==null?this.removeAttribute("state"):this.setAttribute("state",String(n))}get draggable(){return this.hasAttribute("draggable")}set draggable(n){n==null||n===!1?this.removeAttribute("draggable"):this.setAttribute("draggable","true")}get color(){return this.getAttribute("color")}set color(n){n==null||n===""?this.removeAttribute("color"):(this.setAttribute("color",String(n)),this.style.setProperty("--chip-colored-color",String(n)))}get colored(){return this.hasAttribute("colored")}set colored(n){n?this.setAttribute("colored","true"):this.removeAttribute("colored")}set data(n){n==null||n===""?this.removeAttribute("data"):(this.setAttribute("data",String(n)),this.updateContent())}set modality(n){n==null?this.removeAttribute("modality"):(console.log(1),this.setAttribute("modality",String(n)),this.updateContent())}get disabled(){return this.hasAttribute("disabled")}set disabled(n){n?(this.setAttribute("aria-disabled","true"),this.$chip.setAttribute("aria-disabled","true"),this.$dragHandler.setAttribute("aria-disabled","true")):(this.removeAttribute("aria-disabled"),this.$chip.removeAttribute("aria-disabled"),this.$dragHandler.removeAttribute("aria-disabled"))}get selected(){return this.hasAttribute("selected")}set selected(n){n?this.setAttribute("selected",""):this.removeAttribute("selected")}get value(){return this.getAttribute("value")??""}set value(n){this.setAttribute("value",String(n))}toggle(n){return typeof n=="boolean"?this.selected=n:this.selected=!this.selected,this.selected}removeSelf(){this.remove()}};customElements.get("edu-chip")||customElements.define("edu-chip",Qe);function wt(e,n,t){if(n.innerHTML="",!e.startsWith("@:")||!t||e.length<3){n.textContent=e;return}let r=e.slice(2),i=t[r];if(!i){n.textContent=r;return}console.log("DIALOG",i.dialog),i.dialog===!0?di(n,i):ui(n,i)}function di(e,n){let t=document.createElement("button");t.className="media-dialog-trigger";let r={image:'<img src="assets/icons/image.svg" alt="image" width="24" height="24">View Image</img>',video:'<img src="assets/icons/video.svg" alt="image" width="24" height="24">Play Video</img>',audio:'<img src="assets/icons/audio.svg" alt="image" width="24" height="24">Play Audio</img>',html:'<img src="assets/icons/data.svg" alt="image" width="24" height="24">View Content</img>',tts:'<img src="assets/icons/audio.svg" alt="image" width="24" height="24">Play Audio</img>'};t.innerHTML=r[n.type],t.style.cssText=`
998
+ width: 80%;
999
+ justify-content: center;
1000
+ padding: 1rem 1.5rem;
1001
+ background: rgb(var(--edu-first-accent));
1002
+ color: white;
1003
+ border: none;
1004
+ border-radius: 8px;
1005
+ font-size: 1rem;
1006
+ font-weight: 600;
1007
+ cursor: pointer;
1008
+ transition: all 0.2s;
1009
+ display: inline-flex;
1010
+ align-items: center;
1011
+ gap: 0.5rem;
1012
+ `,t.addEventListener("mouseenter",()=>{t.style.transform="translateY(-2px)",t.style.boxShadow="0 4px 12px rgba(0,0,0,0.15)"}),t.addEventListener("mouseleave",()=>{t.style.transform="translateY(0)",t.style.boxShadow="none"}),t.addEventListener("click",()=>{yt(n)}),e.appendChild(t)}function ui(e,n){let t=document.createElement("div");t.style.cssText=`
1013
+ position: relative;
1014
+ display: flex;
1015
+ justify-content: center;
1016
+ align-items: center;
1017
+ width: 100%;
1018
+ max-height: clamp(140px, 26cqh, 240px);
1019
+ overflow-y: auto;
1020
+ overflow-x: hidden;`;let r=document.createElement("edu-media");r.setAttribute("type",n.type),n.type==="image"||n.type==="video"||n.type==="audio"?r.setAttribute("data",n.url):(n.type==="html"||n.type==="tts")&&r.setAttribute("data",n.content);let i={};n.type==="image"&&n.size?i.size=n.size:n.type==="video"&&n.span?i.span=n.span:(n.type==="audio"||n.type==="tts")&&n.volume!==void 0&&(i.volume=n.volume),Object.keys(i).length>0&&r.setAttribute("spec",JSON.stringify(i));let a=document.createElement("button");a.className="media-expand-button",a.title="Expand to full view",a.innerHTML=`
1021
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor">
1022
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1023
+ d="M3 7V3h4M17 7V3h-4M3 13v4h4M17 13v4h-4"/>
1024
+ </svg>
1025
+ `,a.style.cssText=`
1026
+ position: absolute;
1027
+ top: 0.5rem;
1028
+ right: 0.5rem;
1029
+ background: rgba(0, 0, 0, 0.7);
1030
+ color: white;
1031
+ border: none;
1032
+ border-radius: 6px;
1033
+ padding: 0.5rem;
1034
+ cursor: pointer;
1035
+ display: flex;
1036
+ align-items: center;
1037
+ justify-content: center;
1038
+ transition: all 0.2s;
1039
+ z-index: 10;
1040
+ opacity: 0.8;
1041
+ `,a.addEventListener("mouseenter",()=>{a.style.opacity="1",a.style.transform="scale(1.1)"}),a.addEventListener("mouseleave",()=>{a.style.opacity="0.8",a.style.transform="scale(1)"}),a.addEventListener("click",()=>{yt(n)}),t.appendChild(r),t.appendChild(a),e.appendChild(t)}function yt(e){let n=document.querySelector("edu-dialog#asset-dialog");n||(n=document.createElement("edu-dialog"),n.id="asset-dialog",document.body.appendChild(n));let t={image:"Image",video:"Video",audio:"Audio",html:"Content",tts:"Audio"};n.title=t[e.type];let r=document.createElement("edu-media");r.setAttribute("type",e.type),e.type==="image"||e.type==="video"||e.type==="audio"?r.setAttribute("data",e.url):(e.type==="html"||e.type==="tts")&&r.setAttribute("data",e.content);let i={};e.type==="image"&&e.size?i.size="large":e.type==="video"&&e.span?i.span=e.span:(e.type==="audio"||e.type==="tts")&&e.volume!==void 0&&(i.volume=e.volume),Object.keys(i).length>0&&r.setAttribute("spec",JSON.stringify(i)),n.innerHTML="",n.appendChild(r),n.open()}var Xe=class extends HTMLElement{constructor(){super();this.mediaType=null;this.mediaData=null;this.mediaSpec=null;this.audioPlaying=!1;this.currentAudioUrl=null}static get observedAttributes(){return["type","data","spec"]}connectedCallback(){this.render()}attributeChangedCallback(t,r,i){if(r!==i){if(t==="type")this.mediaType=i;else if(t==="data")this.mediaData=i;else if(t==="spec")try{this.mediaSpec=i?JSON.parse(i):null}catch{console.warn("[EduMedia] Invalid spec JSON:",i),this.mediaSpec=null}this.isConnected&&this.render()}}disconnectedCallback(){this.audioPlaying&&this.currentAudioUrl&&(Pe.stop(this.currentAudioUrl),this.audioPlaying=!1)}render(){if(!this.mediaType||!this.mediaData){this.innerHTML="";return}switch(this.mediaType){case"image":this.renderImage();break;case"video":this.renderVideo();break;case"audio":this.renderAudio();break;case"html":this.renderHtml();break;case"tts":this.innerHTML='<div style="font-style: italic; color: gray;">TTS not yet supported</div>';break;default:console.warn(`[EduMedia] Unknown media type: ${this.mediaType}`),this.innerHTML=""}}renderImage(){let t=this.mediaSpec?.size||"medium";this.innerHTML=`
1042
+ <style>
1043
+ :host {
1044
+ display: block;
1045
+ width: 100%;
1046
+ }
1047
+
1048
+ .media-image {
1049
+ width: 100%;
1050
+ max-height: clamp(140px, 26cqh, 240px);
1051
+ display: block;
1052
+ object-fit: contain;
1053
+ border: 2px solid rgb(var(--edu-ink));
1054
+ }
1055
+
1056
+ .media-image.small {
1057
+ max-width: 200px;
1058
+ }
1059
+
1060
+ .media-image.medium {
1061
+ max-width: 400px;
1062
+ }
1063
+
1064
+ .media-image.large {
1065
+ max-width: 100%;
1066
+ }
1067
+ </style>
1068
+ <img class="media-image ${t}" src="${this.mediaData}" alt="Media content" />
1069
+ `}renderVideo(){let t=this.mediaSpec?.span,r=t?`data-from="${t.from}" data-to="${t.to}"`:"";if(this.innerHTML=`
1070
+ <style>
1071
+ :host {
1072
+ display: block;
1073
+ width: 100%;
1074
+ }
1075
+
1076
+ .media-video {
1077
+ width: 100%;
1078
+ max-height: clamp(160px, 28cqh, 280px);
1079
+ height: auto;
1080
+ display: block;
1081
+ border: 2px solid rgb(var(--edu-ink));
1082
+ }
1083
+ </style>
1084
+ <video class="media-video" controls ${r}>
1085
+ <source src="${this.mediaData}" />
1086
+ Your browser does not support the video tag.
1087
+ </video>
1088
+ `,t){let i=this.querySelector("video");if(i){let a=this.parseTime(t.from),o=this.parseTime(t.to);i.addEventListener("loadedmetadata",()=>{a!==null&&(i.currentTime=a)}),o!==null&&i.addEventListener("timeupdate",()=>{i.currentTime>=o&&i.pause()})}}}renderAudio(){let t=this.mediaSpec?.volume!==void 0?this.mediaSpec.volume/100:1,r=this.mediaSpec?.loop??!1;this.innerHTML=`
1089
+ <style>
1090
+ :host {
1091
+ display: block;
1092
+ width: 100%;
1093
+ }
1094
+
1095
+ .media-audio {
1096
+ display: flex;
1097
+ align-items: center;
1098
+ gap: 1rem;
1099
+ padding: 1rem;
1100
+ background: rgba(var(--edu-first-accent), 0.1);
1101
+ border-radius: 8px;
1102
+ }
1103
+
1104
+ .audio-button {
1105
+ display: flex;
1106
+ align-items: center;
1107
+ justify-content: center;
1108
+ width: 48px;
1109
+ height: 48px;
1110
+ background: rgb(var(--edu-first-accent));
1111
+ border: none;
1112
+ border-radius: 50%;
1113
+ cursor: pointer;
1114
+ transition: all 0.2s ease;
1115
+ }
1116
+
1117
+ .audio-button:hover {
1118
+ transform: scale(1.05);
1119
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
1120
+ }
1121
+
1122
+ .audio-button:active {
1123
+ transform: scale(0.95);
1124
+ }
1125
+
1126
+ .audio-button svg {
1127
+ width: 24px;
1128
+ height: 24px;
1129
+ fill: white;
1130
+ }
1131
+
1132
+ .audio-label {
1133
+ flex: 1;
1134
+ font-size: 0.9rem;
1135
+ color: rgb(var(--edu-ink));
1136
+ }
1137
+ </style>
1138
+ <div class="media-audio">
1139
+ <button class="audio-button" title="Play audio">
1140
+ <img src="assets/icons/audio.svg" alt="Audio" width="24" height="24"/>
1141
+ </button>
1142
+ <div class="audio-label">Audio clip</div>
1143
+ </div>
1144
+ `;let i=this.querySelector(".audio-button");i&&i.addEventListener("click",async()=>{this.audioPlaying?(Pe.stop(this.mediaData),this.audioPlaying=!1,this.currentAudioUrl=null,i.title="Play audio"):(this.currentAudioUrl=this.mediaData,console.log(this.currentAudioUrl),await Pe.playSound(this.mediaData,{volume:t,loop:r,onEnd:()=>{this.audioPlaying=!1,this.currentAudioUrl=null,i.title="Play audio"},onError:a=>{console.error("[EduMedia] Audio playback error:",a),this.audioPlaying=!1,this.currentAudioUrl=null,i.title="Play audio"}}),this.audioPlaying=!0,i.title="Stop audio")})}renderHtml(){this.innerHTML=`
1145
+ <style>
1146
+ :host {
1147
+ display: block;
1148
+ width: 100%;
1149
+ }
1150
+
1151
+ .media-html {
1152
+ width: 100%;
1153
+ color: rgb(var(--edu-ink));
1154
+ }
1155
+
1156
+ .media-html * {
1157
+ max-width: 100%;
1158
+ }
1159
+ </style>
1160
+ <div class="media-html">${this.mediaData}</div>
1161
+ `}parseTime(t){let r=t.split(":").map(i=>parseInt(i,10));return r.length===2?r[0]*60+r[1]:r.length===3?r[0]*3600+r[1]*60+r[2]:null}};customElements.get("edu-media")||customElements.define("edu-media",Xe);var pi=`
1162
+ :host {
1163
+ display: inline-flex;
1164
+ align-items: center;
1165
+ width: auto;
1166
+ font-family: inherit;
1167
+ color: rgb(var(--edu-ink));
1168
+ }
1169
+
1170
+ /* --- SHARED BASE STYLES --- */
1171
+ .control {
1172
+ width: 100%;
1173
+ box-sizing: border-box;
1174
+ padding: 0.6rem 1rem;
1175
+ font-size: 1rem;
1176
+ transition: all 0.2s ease;
1177
+ border: 1px solid rgb(var(--edu-border));
1178
+ border-radius: 4px;
1179
+ outline: none;
1180
+ background: rgb(var(--edu-bg));
1181
+ color: rgb(var(--edu-ink));
1182
+ font-family: inherit;
1183
+ }
1184
+
1185
+ .control:focus {
1186
+ border-color: rgb(var(--edu-first-accent));
1187
+ box-shadow: 0 0 0 2px rgb(var(--edu-first-accent) / 0.2);
1188
+ }
1189
+
1190
+ .control[type="checkbox"],
1191
+ .control[type="radio"] {
1192
+ width: 18px;
1193
+ height: 18px;
1194
+ padding: 0;
1195
+ accent-color: rgb(var(--edu-first-accent));
1196
+ }
1197
+
1198
+ button.control {
1199
+ cursor: pointer;
1200
+ }
1201
+
1202
+ slot {
1203
+ display: none;
1204
+ }
1205
+
1206
+ :host([disabled]) .control {
1207
+ opacity: 0.6;
1208
+ cursor: not-allowed;
1209
+ }
1210
+
1211
+ /* --- VARIANTS --- */
1212
+
1213
+ :host([variant="elegant"]) .control {
1214
+ border-radius: 0;
1215
+ border-bottom: 2px solid rgb(var(--edu-first-accent));
1216
+ background: rgb(var(--edu-card));
1217
+ letter-spacing: 1px;
1218
+ text-transform: uppercase;
1219
+ font-size: 0.8rem;
1220
+ }
1221
+
1222
+ :host([variant="playful"]) .control {
1223
+ border-radius: 50px;
1224
+ background: rgb(var(--edu-first-accent) / 0.7);
1225
+ border: 2px solid rgb(var(--edu-first-accent));
1226
+ font-weight: 700;
1227
+ color: rgb(var(--edu-inverted-ink));
1228
+ }
1229
+
1230
+ :host([variant="outline"]) .control {
1231
+ background: transparent;
1232
+ border: 2px solid rgb(var(--edu-first-accent));
1233
+ color: rgb(var(--edu-ink));
1234
+ }
1235
+
1236
+ :host([variant="letter"]) .control {
1237
+ background: rgb(var(--edu-card));
1238
+ border: 1px solid rgb(var(--edu-muted));
1239
+ font-family: georgia, serif;
1240
+ font-style: italic;
1241
+ box-shadow: 2px 2px 0 rgb(var(--edu-muted));
1242
+ }
1243
+
1244
+ :host([variant="sign"]) .control {
1245
+ background: rgb(var(--edu-bg));
1246
+ font-weight: 800;
1247
+ text-transform: uppercase;
1248
+ letter-spacing: 2px;
1249
+ border-radius: 4px;
1250
+ }
1251
+
1252
+ :host([variant="minimal"]) .control {
1253
+ background: rgb(var(--edu-bg));
1254
+ border: 1px solid rgb(var(--edu-border));
1255
+ }
1256
+
1257
+ :host([variant="glass"]) .control {
1258
+ background: rgba(var(--edu-card), 0.7);
1259
+ backdrop-filter: blur(10px);
1260
+ border: 2px solid rgba(var(--edu-border), 0.35);
1261
+ }
1262
+
1263
+ :host([variant="empty"]) .control {
1264
+ background: transparent;
1265
+ border: 2px solid rgb(var(--edu-border));
1266
+ }
1267
+
1268
+ /* --- STATE FEEDBACK --- */
1269
+ :host([state="correct"]) .control {
1270
+ border: 2px solid rgb(var(--edu-success));
1271
+ background: rgb(var(--edu-success) / 0.1);
1272
+ box-shadow: 0 0 0 2px rgb(var(--edu-success) / 0.2);
1273
+ }
1274
+
1275
+ :host([state="wrong"]) .control {
1276
+ border: 2px solid rgb(var(--edu-error));
1277
+ background: rgb(var(--edu-error) / 0.1);
1278
+ box-shadow: 0 0 0 2px rgb(var(--edu-error) / 0.2);
1279
+ }
1280
+
1281
+ :host([state="missed"]) .control {
1282
+ border: 2px solid rgb(var(--edu-warning));
1283
+ background: rgb(var(--edu-warning) / 0.1);
1284
+ box-shadow: 0 0 0 2px rgb(var(--edu-warning) / 0.2);
1285
+ }
1286
+ `,hi=["input","select","textarea","button"],qe=class extends HTMLElement{constructor(){super();this.$slot=null;this.controlEl=null;this.currentTag="input";this.handleSlotChange=()=>{this.syncAttributes(),this.syncContent()};this.attachShadow({mode:"open"})}static get observedAttributes(){return["as","variant","state","disabled","readonly","required","placeholder","value","type","name","autocomplete","min","max","step","pattern","rows","cols","multiple","size"]}connectedCallback(){this.hasAttribute("variant")||(this.variant="outline"),this.render(),this.$slot?.addEventListener("slotchange",this.handleSlotChange),this.syncAttributes(),this.syncContent()}disconnectedCallback(){this.$slot?.removeEventListener("slotchange",this.handleSlotChange)}attributeChangedCallback(t,r,i){r!==i&&(t==="as"&&this.render(),this.syncAttributes(),this.syncContent())}getTag(){let t=(this.getAttribute("as")??"input").toLowerCase();return hi.includes(t)?t:"input"}render(){let t=this.getTag();if(this.controlEl&&this.currentTag===t)return;this.currentTag=t,this.shadowRoot.innerHTML="";let r=document.createElement("style");r.textContent=pi,this.shadowRoot.append(r);let i=document.createElement(t);i.className="control",i.setAttribute("part","control"),this.$slot=document.createElement("slot"),this.shadowRoot.append(i,this.$slot),this.controlEl=i}applyAttr(t){this.controlEl&&(this.hasAttribute(t)?this.controlEl.setAttribute(t,this.getAttribute(t)??""):this.controlEl.removeAttribute(t))}applyBoolAttr(t){this.controlEl&&(this.hasAttribute(t)?this.controlEl.setAttribute(t,""):this.controlEl.removeAttribute(t))}syncAttributes(){this.controlEl&&(this.applyBoolAttr("disabled"),this.applyBoolAttr("readonly"),this.applyBoolAttr("required"),this.applyAttr("placeholder"),this.applyAttr("name"),this.applyAttr("autocomplete"),this.applyAttr("min"),this.applyAttr("max"),this.applyAttr("step"),this.applyAttr("pattern"),this.controlEl instanceof HTMLInputElement&&this.applyAttr("type"),this.controlEl instanceof HTMLTextAreaElement&&(this.applyAttr("rows"),this.applyAttr("cols")),this.controlEl instanceof HTMLSelectElement&&(this.applyBoolAttr("multiple"),this.applyAttr("size")),"value"in this.controlEl&&(this.hasAttribute("value")?this.controlEl.value=this.getAttribute("value")??"":this.controlEl.value=""))}syncContent(){if(!this.controlEl||!this.$slot)return;let r=this.$slot.assignedNodes({flatten:!0}).filter(i=>i.nodeType===Node.TEXT_NODE?i.textContent?.trim():i.nodeType===Node.ELEMENT_NODE);if(this.controlEl instanceof HTMLSelectElement){this.controlEl.innerHTML="",r.forEach(i=>{(i instanceof HTMLOptionElement||i instanceof HTMLOptGroupElement)&&this.controlEl.append(i.cloneNode(!0))});return}if(this.controlEl instanceof HTMLButtonElement){this.controlEl.innerHTML="",r.forEach(i=>{this.controlEl.append(i.cloneNode(!0))});return}if(this.controlEl instanceof HTMLTextAreaElement&&!this.hasAttribute("value")){let i=r.map(a=>a.textContent??"").join("");this.controlEl.value=i}}get variant(){return this.getAttribute("variant")??"outline"}set variant(t){this.setAttribute("variant",t)}get value(){return this.controlEl&&"value"in this.controlEl?this.controlEl.value:this.getAttribute("value")??""}set value(t){this.setAttribute("value",String(t)),this.controlEl&&"value"in this.controlEl&&(this.controlEl.value=t)}};customElements.get("edu-input")||customElements.define("edu-input",qe);function zo(e){let n=[],t=[],r=new Map,i={},a=/^\s*(?<category>[A-Z_](?:[A-Z0-9_]* ?[A-Z0-9_]+)*)\s*=\s*(?<items>[^;]+?)\s*;\s*$/gm,o=[...e.matchAll(a)];o.length===0&&(i["parse.noMatches"]="No valid category entries found. Expected lines like: CATEGORY = item1 | item2;");let s=new Set;for(let c of o){let d=c.groups?.category??"",u=c.groups?.items??"",p=d.trim().toLowerCase();if(r.has(p)){i[`parse.duplicateCategory.${p}`]=`Duplicate category "${p}" was defined more than once. Merge them into a single entry.`;continue}let h=u.split("|").map(g=>g.replace(/\s+/g," ").trim()).filter(Boolean);if(h.length===0){i[`parse.emptyCategory.${p}`]=`Category "${p}" has no items. Expected at least one item before ';'.`,t.push(p),r.set(p,[]);continue}t.push(p);for(let g of h)s.has(g)||(s.add(g),n.push(g));r.set(p,h)}let l={rows:n,cols:t,answerKey:r};return Object.keys(i).length>0?{data:l,errors:i}:{data:l}}function Ho(e){let n={},t=[],r=new Map,i=/^\s*(?<category>[a-z_](?:[a-z0-9_]* ?[a-z0-9_]+)*)\s*=\s*(?<values>[^;]+?)\s*;/gim,a=[...e.matchAll(i)];if(a.length===0)return n["parse.noMatches"]="No valid category entries found. Expected lines like: category = val1 | val2;",{data:{rows:[],cols:[],answerKey:{}},errors:n};let o=new Set;for(let d of a){let u=d.groups?.category??"",p=d.groups?.values??"",h=u.trim().toLowerCase();if(o.has(h)){n[`parse.duplicateCategory.${h}`]=`Duplicate category "${h}" was defined more than once.`;continue}o.add(h);let g=p.split("|").map(m=>m.trim()).filter(Boolean);t.push(h),r.set(h,g)}let s=t.length;for(let d of t){let u=r.get(d)??[],p=s-1;u.length!==p&&(n[`parse.valueCount.${d}`]=`Category "${d}" has ${u.length} values, but expected ${p} (n-1 where n=${s}).`)}let l={};for(let d=0;d<t.length;d++){let u=t[d],p=r.get(u)??[];l[u]={};let h=0;for(let g=0;g<t.length;g++){if(d===g)continue;let m=t[g],b=p[h],w=null;if(b!==void 0&&b!==""){let v=Number(b);w=isNaN(v)?b:v}l[u][m]=w,h++}}let c={rows:t,cols:t,answerKey:l};return Object.keys(n).length>0?{data:c,errors:n}:{data:c}}function Go(e){let n={},t=[],r=[],i={},a=/^\s*=\s*(?<cols>[^;]+?)\s*;/m,o=e.match(a);if(!o)return n["parse.noHeader"]="Missing header line. Expected first line like: = col1 | col2 | col3;",{data:{rows:[],cols:[],answerKey:{}},errors:n};if(t=(o.groups?.cols??"").split("|").map(p=>p.trim()).filter(Boolean),t.length===0)return n["parse.emptyHeader"]='Header line has no columns. Expected at least one column after "=".',{data:{rows:[],cols:[],answerKey:{}},errors:n};let l=/^\s*(?<row>[^=]+?)\s*=\s*(?<values>[^;]+?)\s*;/gm,c=[...e.matchAll(l)],d=new Set;for(let p of c){let h=p.groups?.row??"",g=p.groups?.values??"";if(h.trim()==="")continue;let m=h.trim();if(d.has(m)){n[`parse.duplicateRow.${m}`]=`Duplicate row "${m}" was defined more than once.`;continue}d.add(m);let b=g.split("|").map(w=>w.trim()).filter(w=>w!=="");if(b.length!==t.length){n[`parse.valueCount.${m}`]=`Row "${m}" has ${b.length} values, but expected ${t.length} (matching column count).`;continue}r.push(m),i[m]={};for(let w=0;w<t.length;w++){let v=t[w],P=b[w];if(P==="-"){i[m][v]=null;continue}let U=null;if(P!==void 0&&P!==""){let ft=Number(P);U=isNaN(ft)?P:ft}i[m][v]=U}}r.length===0&&(n["parse.noRows"]="No data rows found. Expected at least one line like: row = val1 | val2;");let u={rows:r,cols:t,answerKey:i};return Object.keys(n).length>0?{data:u,errors:n}:{data:u}}function Oo(e,n="classification"){let t={},r=e.answerKey;e.cols.length===0&&(t["cols.empty"]="No categories were found. Expected at least one CATEGORY = ... ; entry."),e.rows.length===0&&(t["rows.empty"]="No row items were found. Expected at least one item in any category.");for(let i of e.cols)e.rows.includes(i)&&(t[`cols.rowConflict.${i}`]=`Category "${i}" is also present as an item. Category labels cannot be used as row items.`);for(let i of e.cols){let a=r.get(i);if(!a){t[`answerKey.missing.${i}`]=`Category "${i}" has no entry in answerKey. This usually indicates a parser issue.`;continue}a.length===0&&(t[`answerKey.emptyCategory.${i}`]=`Category "${i}" has no items. Each category must include at least one item.`)}for(let[i,a]of r.entries()){let o=new Set;for(let s of a){if(o.has(s)){t[`answerKey.duplicateItem.${i}`]=`Category "${i}" includes duplicate item "${s}". Remove duplicates.`;break}o.add(s)}}if(n==="n-ary"){let i=new Map;for(let[a,o]of r.entries())for(let s of o){let l=i.get(s);l?l.push(a):i.set(s,[a])}for(let a of e.rows){let o=i.get(a)??[];if(o.length===0){t[`nary.unassigned.${a}`]=`Item "${a}" is not assigned to any category. In n-ary tables, every item must belong to exactly one category.`;continue}o.length>1&&(t[`nary.multiCategory.${a}`]=`Item "${a}" appears in multiple categories (${o.join(", ")}). In n-ary tables, items must belong to exactly one category.`)}}return Object.keys(t).length>0?{ok:!1,errors:t}:{ok:!0}}function Vo(e){let n={};if(e.rows.length===0&&(n["rows.empty"]="No rows found. Expected at least one category."),e.cols.length===0&&(n["cols.empty"]="No columns found. Expected at least one category."),e.rows.length!==e.cols.length)n["symmetry.lengthMismatch"]=`Rows (${e.rows.length}) and columns (${e.cols.length}) must have the same length for adjacency tables.`;else{let t=new Set(e.rows),r=new Set(e.cols);for(let i of e.rows)r.has(i)||(n[`symmetry.rowNotInCols.${i}`]=`Row "${i}" does not appear in columns. Adjacency tables must be symmetric.`);for(let i of e.cols)t.has(i)||(n[`symmetry.colNotInRows.${i}`]=`Column "${i}" does not appear in rows. Adjacency tables must be symmetric.`)}for(let t of e.rows){if(!e.answerKey[t]){n[`answerKey.missingRow.${t}`]=`Row "${t}" has no entry in answer key.`;continue}for(let r of e.cols)if(t===r){let i=e.answerKey[t][r];i!=null&&(n[`answerKey.diagonalValue.${t}`]=`Diagonal cell (${t}, ${t}) should be empty, but has value "${i}".`)}else e.answerKey[t][r]===void 0&&(n[`answerKey.missingCell.${t}.${r}`]=`Missing value at cell (${t}, ${r}). All non-diagonal cells must have values.`)}return Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0}}function Fo(e){let n={};e.cols.length===0&&(n["cols.empty"]="No columns found. Expected at least one column in header line."),e.rows.length===0&&(n["rows.empty"]="No rows found. Expected at least one data row.");let t=new Set(e.cols);for(let r of e.rows)t.has(r)&&(n[`naming.rowColConflict.${r}`]=`Row name "${r}" is also a column name. This creates ambiguity and should be avoided.`);for(let r of e.rows){if(!e.answerKey[r]){n[`answerKey.missingRow.${r}`]=`Row "${r}" has no entry in answer key.`;continue}for(let i of e.cols)e.answerKey[r][i]===void 0&&(n[`answerKey.missingCell.${r}.${i}`]=`Missing value at cell (${r}, ${i}). Cells must have values or be marked as disabled with '-'.`)}return Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0}}function ue(e){let n=[];for(let t of Object.values(e))for(let r of Object.values(t))r!==null&&n.push(r);return n}function Be(e){let n=ue(e);return Array.from(new Set(n))}function ze(e){let n=new Set(e.filter(t=>t!==null));return e.every(t=>t===null||typeof t=="number")?"number":n.size>0&&n.size<=10?"select":"text"}function pe(e,n){return e===null||n===null?!1:typeof e=="number"&&typeof n=="number"?Math.abs(e-n)<1e-4:String(e).trim()===String(n).trim()}function Et(e,n,t){let r=0,i=t.length;for(let o of t){let s=n[o]?.selectedCols??[],l=null;for(let[c,d]of e.entries())if(d.includes(o)){l=c;break}s.length===1&&s[0]===l&&r++}return{score:i>0?Math.round(r/i*100):0,correct:r,total:i}}function Ct(e,n,t,r){let i=0,a=0;for(let s of t)for(let l of r){let c=e[s]?.[l];if(c===null)continue;let d=n[s]?.values[l];a++,pe(c,d)&&i++}return{score:a>0?Math.round(i/a*100):0,correct:i,total:a}}function St(e,n,t,r){let i=0,a=0;for(let s of t){let l=new Set(n[s]?.selectedCols??[]),c=new Set;for(let[d,u]of e.entries())u.includes(s)&&c.add(d);for(let d of r){let u=c.has(d),p=l.has(d);u===p&&i++,a++}}return{score:a>0?Math.round(i/a*100):0,correct:i,total:a}}function kt(e,n,t){let r=0,i=0;for(let o of t)for(let s of t){if(o===s)continue;let l=e[o]?.[s],c=n[o]?.values[s];i++,pe(l,c)&&r++}return{score:i>0?Math.round(r/i*100):0,correct:r,total:i}}function Tt(e,n,t){let r={};for(let i of t){r[i]={};for(let a of t){if(i===a)continue;let o=e[i]?.[a],s=n[i]?.values[a];s==null||s===""?r[i][a]="missed":pe(o,s)?r[i][a]="correct":r[i][a]="wrong"}}return r}function $t(e,n,t,r){let i={};for(let a of t){i[a]={};for(let o of r){let s=e[a]?.[o];if(s===null)continue;let l=n[a]?.values[o];l==null||l===""?i[a][o]="missed":pe(s,l)?i[a][o]="correct":i[a][o]="wrong"}}return i}function At(e,n,t,r){let i={};for(let a of t){i[a]={};let o=new Set(n[a]?.selectedCols??[]),s=new Set;for(let[l,c]of e.entries())c.includes(a)&&s.add(l);for(let l of r){let c=s.has(l),d=o.has(l);c===d?i[a][l]="correct":!d&&c?i[a][l]="missed":i[a][l]="wrong"}}return i}function _t(e,n,t){let r={};for(let i of t){r[i]={};let a=n[i]?.selectedCols??[],o=null;for(let[s,l]of e.entries())if(l.includes(i)){o=s;break}if(a.length===1){let s=a[0];s===o?r[i][s]="correct":r[i][s]="wrong"}else a.length===0&&o&&(r[i][o]="missed")}return r}var It=`/* ===========================================
1287
+ BASE TABLE STYLES
1288
+ =========================================== */
1289
+
1290
+ :host {
1291
+ display: block;
1292
+ width: 100%;
1293
+ container-type: inline-size;
1294
+ }
1295
+
1296
+ .wrap {
1297
+ width: 100%;
1298
+ overflow-x: auto;
1299
+ overflow-y: visible;
1300
+ }
1301
+
1302
+ table {
1303
+ width: 100%;
1304
+ border-collapse: collapse;
1305
+ background: rgb(var(--edu-bg));
1306
+ table-layout: auto;
1307
+ }
1308
+
1309
+ /* Cell base styles with text wrapping */
1310
+ td, th {
1311
+ padding: clamp(0.4rem, 1.4cqw, 0.75rem);
1312
+ text-align: center;
1313
+ vertical-align: middle;
1314
+ border: 1px solid rgb(var(--edu-border));
1315
+ color: rgb(var(--edu-ink));
1316
+ font-size: clamp(0.8rem, 1.8cqw, 0.95rem);
1317
+ line-height: 1.2;
1318
+
1319
+ /* Text wrapping and overflow handling */
1320
+ word-wrap: break-word;
1321
+ overflow-wrap: break-word;
1322
+ word-break: break-word;
1323
+ hyphens: auto;
1324
+ max-width: clamp(120px, 26cqw, 220px);
1325
+ min-width: clamp(56px, 12cqw, 90px);
1326
+ }
1327
+
1328
+ th {
1329
+ font-weight: 600;
1330
+ background: rgb(var(--edu-card));
1331
+ }
1332
+
1333
+ /* First column (row headers) */
1334
+ th[scope="row"] {
1335
+ text-align: left;
1336
+ font-weight: 500;
1337
+ background: rgb(var(--edu-card));
1338
+ white-space: normal;
1339
+ }
1340
+
1341
+ /* Disabled cells */
1342
+ .disabled-cell {
1343
+ background: rgb(var(--edu-muted));
1344
+ cursor: not-allowed;
1345
+ opacity: 0.5;
1346
+ }
1347
+
1348
+ /* Grading feedback states */
1349
+ .cell-correct {
1350
+ background: rgb(var(--edu-success) / 0.15);
1351
+ border-color: rgb(var(--edu-success) / 0.5) !important;
1352
+ }
1353
+
1354
+ .cell-wrong {
1355
+ background: rgb(var(--edu-error) / 0.15);
1356
+ border-color: rgb(var(--edu-error) / 0.5) !important;
1357
+ }
1358
+
1359
+ .cell-missed {
1360
+ background: rgb(var(--edu-warning) / 0.15);
1361
+ border-color: rgb(var(--edu-warning) / 0.5) !important;
1362
+ }
1363
+
1364
+ /* Form inputs base styles */
1365
+ input[type="text"],
1366
+ input[type="number"],
1367
+ select {
1368
+ width: 100%;
1369
+ max-width: 100%;
1370
+ padding: clamp(0.35rem, 1.2cqw, 0.5rem);
1371
+ border: 1px solid rgb(var(--edu-border));
1372
+ border-radius: 4px;
1373
+ outline: none;
1374
+ font-family: inherit;
1375
+ font-size: clamp(0.8rem, 1.6cqw, 0.9rem);
1376
+ background: rgb(var(--edu-bg));
1377
+ color: rgb(var(--edu-ink));
1378
+ transition: border-color 0.2s ease;
1379
+ }
1380
+
1381
+ input[type="text"]:focus,
1382
+ input[type="number"]:focus,
1383
+ select:focus {
1384
+ border-color: rgb(var(--edu-first-accent));
1385
+ box-shadow: 0 0 0 2px rgb(var(--edu-first-accent) / 0.15);
1386
+ }
1387
+
1388
+ input[type="checkbox"],
1389
+ input[type="radio"] {
1390
+ width: clamp(14px, 3.2cqw, 18px);
1391
+ height: clamp(14px, 3.2cqw, 18px);
1392
+ cursor: pointer;
1393
+ accent-color: rgb(var(--edu-first-accent));
1394
+ }
1395
+
1396
+ /* ===========================================
1397
+ VARIANT: ELEGANT
1398
+ Refined with subtle box shadows
1399
+ =========================================== */
1400
+
1401
+ :host([variant="elegant"]) {
1402
+ & table {
1403
+ border-collapse: separate;
1404
+ border-spacing: 6;
1405
+ }
1406
+
1407
+ & th {
1408
+ text-transform: uppercase;
1409
+ letter-spacing: 1px;
1410
+ font-size: 0.75rem;
1411
+ font-weight: 600;
1412
+ background: rgb(var(--edu-card));
1413
+ border: none;
1414
+ border-bottom: 2px solid rgb(var(--edu-border));
1415
+ padding: 1rem 0.75rem;
1416
+ }
1417
+
1418
+ & td {
1419
+ border: none;
1420
+ border-bottom: 1px solid rgb(var(--edu-border) / 0.3);
1421
+ box-shadow: inset 0 0 0 1px rgb(var(--edu-border) / 0.1);
1422
+ transition: background 0.2s ease;
1423
+ }
1424
+
1425
+ & td:hover {
1426
+ background: rgb(var(--edu-muted) / 0.3);
1427
+ }
1428
+
1429
+ & th[scope="row"] {
1430
+ font-weight: 500;
1431
+ text-transform: none;
1432
+ letter-spacing: 0;
1433
+ font-size: 0.95rem;
1434
+ }
1435
+
1436
+ & input[type="text"],
1437
+ & input[type="number"],
1438
+ & select {
1439
+ border: none;
1440
+ border-bottom: 1px solid rgb(var(--edu-border));
1441
+ border-radius: 0;
1442
+ background: transparent;
1443
+ }
1444
+
1445
+ & .disabled-cell {
1446
+ background: rgb(var(--edu-muted) / 0.4);
1447
+ }
1448
+ }
1449
+
1450
+ /* ===========================================
1451
+ VARIANT: PLAYFUL
1452
+ Bright, rounded, with color accents
1453
+ =========================================== */
1454
+
1455
+ :host([variant="playful"]) {
1456
+ & table {
1457
+ border-collapse: separate;
1458
+ border-spacing: 6px;
1459
+ }
1460
+
1461
+ & th,
1462
+ & td {
1463
+ border-radius: 8px;
1464
+ border: 2px solid rgb(var(--edu-border));
1465
+ background: rgb(var(--edu-bg));
1466
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
1467
+ }
1468
+
1469
+ & th {
1470
+ background: linear-gradient(135deg, rgb(var(--edu-first-accent) / 0.15), rgb(var(--edu-first-accent) / 0.05));
1471
+ color: rgb(var(--edu-ink));
1472
+ font-weight: 700;
1473
+ }
1474
+
1475
+ & td:hover:not(.disabled-cell) {
1476
+ transform: translateY(-2px);
1477
+ box-shadow: 0 4px 8px rgb(var(--edu-shadow-color) / 0.2);
1478
+ }
1479
+
1480
+ & input[type="text"],
1481
+ & input[type="number"],
1482
+ & select {
1483
+ border: 2px solid rgb(var(--edu-border));
1484
+ border-radius: 12px;
1485
+ background: rgb(var(--edu-bg));
1486
+ }
1487
+
1488
+ & input[type="checkbox"],
1489
+ & input[type="radio"] {
1490
+ transform: scale(1.2);
1491
+ }
1492
+
1493
+ & .disabled-cell {
1494
+ background: rgb(var(--edu-muted));
1495
+ opacity: 0.6;
1496
+ }
1497
+ }
1498
+
1499
+ /* ===========================================
1500
+ VARIANT: OUTLINE
1501
+ Bold borders, clean lines
1502
+ =========================================== */
1503
+
1504
+ :host([variant="outline"]) {
1505
+ & table {
1506
+ background: transparent;
1507
+ border: 3px solid rgb(var(--edu-border));
1508
+ }
1509
+
1510
+ & th,
1511
+ & td {
1512
+ border: 2px solid rgb(var(--edu-border));
1513
+ font-weight: 500;
1514
+ }
1515
+
1516
+ & th {
1517
+ background: rgb(var(--edu-first-accent) / 0.2);
1518
+ font-weight: 700;
1519
+ text-transform: uppercase;
1520
+ letter-spacing: 0.5px;
1521
+ font-size: 0.85rem;
1522
+ }
1523
+
1524
+ & input[type="text"],
1525
+ & input[type="number"],
1526
+ & select {
1527
+ border: 3px solid rgb(var(--edu-border));
1528
+ border-radius: 0;
1529
+ box-shadow: 2px 2px 0px rgb(var(--edu-border) / 0.3);
1530
+ background: rgb(var(--edu-bg));
1531
+ }
1532
+
1533
+ & input[type="text"]:focus,
1534
+ & input[type="number"]:focus,
1535
+ & select:focus {
1536
+ box-shadow: 3px 3px 0px rgb(var(--edu-first-accent));
1537
+ }
1538
+
1539
+ & .disabled-cell {
1540
+ background: repeating-linear-gradient(
1541
+ 45deg,
1542
+ rgb(var(--edu-muted)),
1543
+ rgb(var(--edu-muted)) 10px,
1544
+ rgb(var(--edu-border) / 0.3) 10px,
1545
+ rgb(var(--edu-border) / 0.3) 20px
1546
+ );
1547
+ }
1548
+ }
1549
+
1550
+ /* ===========================================
1551
+ VARIANT: LETTER
1552
+ Typography-focused with serif fonts
1553
+ =========================================== */
1554
+
1555
+ :host([variant="letter"]) {
1556
+ & table {
1557
+ background: transparent;
1558
+ }
1559
+
1560
+ & th,
1561
+ & td {
1562
+ border: none;
1563
+ border-bottom: 1px solid rgb(var(--edu-border));
1564
+ font-family: Georgia, serif;
1565
+ letter-spacing: 0.3px;
1566
+ }
1567
+
1568
+ & th {
1569
+ color: rgb(var(--edu-ink));
1570
+ font-weight: 500;
1571
+ font-size: 1rem;
1572
+ font-style: italic;
1573
+ padding-bottom: 0.5rem;
1574
+ }
1575
+
1576
+ & th[scope="row"] {
1577
+ font-weight: 600;
1578
+ font-style: normal;
1579
+ }
1580
+
1581
+ & td {
1582
+ font-size: 0.95rem;
1583
+ }
1584
+
1585
+ & input[type="text"],
1586
+ & input[type="number"],
1587
+ & select {
1588
+ border: none;
1589
+ border-bottom: 1px dashed rgb(var(--edu-border));
1590
+ border-radius: 0;
1591
+ background: transparent;
1592
+ font-family: Georgia, serif;
1593
+ color: rgb(var(--edu-ink) / 0.9);
1594
+ }
1595
+
1596
+ & .disabled-cell {
1597
+ background: transparent;
1598
+ color: rgb(var(--edu-ink) / 0.3);
1599
+ font-style: italic;
1600
+ }
1601
+ }
1602
+
1603
+ /* ===========================================
1604
+ VARIANT: SIGN
1605
+ Bold, industrial, high-contrast
1606
+ =========================================== */
1607
+
1608
+ :host([variant="sign"]) {
1609
+ & table {
1610
+ border: 3px solid rgb(var(--edu-ink));
1611
+ }
1612
+
1613
+ & th {
1614
+ background: rgb(var(--edu-ink));
1615
+ color: rgb(var(--edu-inverted-ink));
1616
+ text-transform: uppercase;
1617
+ font-style: italic;
1618
+ font-weight: 700;
1619
+ letter-spacing: 1.5px;
1620
+ border: 2px solid rgb(var(--edu-ink));
1621
+ padding: 1rem;
1622
+ }
1623
+
1624
+ & td {
1625
+ border: 2px solid rgb(var(--edu-ink));
1626
+ font-weight: 600;
1627
+ }
1628
+
1629
+ & th[scope="row"] {
1630
+ background: rgb(var(--edu-card));
1631
+ color: rgb(var(--edu-ink));
1632
+ font-style: normal;
1633
+ }
1634
+
1635
+ & input[type="text"],
1636
+ & input[type="number"],
1637
+ & select {
1638
+ border: 2px solid rgb(var(--edu-ink));
1639
+ border-radius: 0;
1640
+ background: rgb(var(--edu-bg));
1641
+ font-weight: 600;
1642
+ }
1643
+
1644
+ & .disabled-cell {
1645
+ background: repeating-linear-gradient(
1646
+ 135deg,
1647
+ rgb(var(--edu-card)),
1648
+ rgb(var(--edu-card)) 8px,
1649
+ rgb(var(--edu-ink) / 0.2) 8px,
1650
+ rgb(var(--edu-ink) / 0.2) 16px
1651
+ );
1652
+ }
1653
+ }
1654
+
1655
+ /* ===========================================
1656
+ VARIANT: MINIMAL
1657
+ Clean, spacious, understated
1658
+ =========================================== */
1659
+
1660
+ :host([variant="minimal"]) {
1661
+ & table {
1662
+ border: none;
1663
+ }
1664
+
1665
+ & th {
1666
+ border: none;
1667
+ border-bottom: 1px solid rgb(var(--edu-border));
1668
+ background: transparent;
1669
+ color: rgb(var(--edu-ink));
1670
+ font-weight: 500;
1671
+ font-size: 0.9rem;
1672
+ padding: 0.5rem 0.75rem;
1673
+ }
1674
+
1675
+ & td {
1676
+ border: none;
1677
+ border-bottom: 1px solid rgb(var(--edu-border) / 0.5);
1678
+ background: transparent;
1679
+ }
1680
+
1681
+ & tr:last-child td {
1682
+ border-bottom: none;
1683
+ }
1684
+
1685
+ & input[type="text"],
1686
+ & input[type="number"],
1687
+ & select {
1688
+ border: none;
1689
+ border-bottom: 1px solid rgb(var(--edu-border) / 0.5);
1690
+ border-radius: 0;
1691
+ background: transparent;
1692
+ padding: 0.25rem;
1693
+ }
1694
+
1695
+ & input[type="text"]:focus,
1696
+ & input[type="number"]:focus,
1697
+ & select:focus {
1698
+ border-bottom-color: rgb(var(--edu-first-accent));
1699
+ box-shadow: none;
1700
+ }
1701
+
1702
+ & .disabled-cell {
1703
+ background: transparent;
1704
+ color: rgb(var(--edu-ink) / 0.3);
1705
+ }
1706
+ }
1707
+
1708
+ /* ===========================================
1709
+ VARIANT: GLASS
1710
+ Frosted glass effect with depth
1711
+ =========================================== */
1712
+
1713
+ :host([variant="glass"]) {
1714
+ & table {
1715
+ background: rgb(var(--edu-bg) / 0.7);
1716
+ backdrop-filter: blur(10px);
1717
+ border: 1px solid rgb(var(--edu-border) / 0.3);
1718
+ border-radius: 12px;
1719
+ overflow: hidden;
1720
+ }
1721
+
1722
+ & th,
1723
+ & td {
1724
+ border: 1px solid rgb(var(--edu-border) / 0.2);
1725
+ background: rgb(var(--edu-bg) / 0.4);
1726
+ }
1727
+
1728
+ & th {
1729
+ color: rgb(var(--edu-ink));
1730
+ font-weight: 600;
1731
+ background: rgb(var(--edu-card) / 0.6);
1732
+ backdrop-filter: blur(5px);
1733
+ border-bottom: 2px solid rgb(var(--edu-border) / 0.4);
1734
+ }
1735
+
1736
+ & input[type="text"],
1737
+ & input[type="number"],
1738
+ & select {
1739
+ background: rgb(var(--edu-bg) / 0.5);
1740
+ border: 1px solid rgb(var(--edu-border) / 0.3);
1741
+ border-radius: 6px;
1742
+ backdrop-filter: blur(5px);
1743
+ }
1744
+
1745
+ & input[type="text"]:focus,
1746
+ & input[type="number"]:focus,
1747
+ & select:focus {
1748
+ background: rgb(var(--edu-bg) / 0.8);
1749
+ border-color: rgb(var(--edu-first-accent) / 0.6);
1750
+ }
1751
+
1752
+ & .disabled-cell {
1753
+ background: rgb(var(--edu-muted) / 0.3);
1754
+ backdrop-filter: blur(3px);
1755
+ }
1756
+ }
1757
+
1758
+ /* ===========================================
1759
+ VARIANT: EMPTY
1760
+ Bare minimum, dashed borders
1761
+ =========================================== */
1762
+
1763
+ :host([variant="empty"]) {
1764
+ & table {
1765
+ border: none;
1766
+ background: none;
1767
+ }
1768
+
1769
+ & th,
1770
+ & td {
1771
+ border: 1px dashed rgb(var(--edu-border));
1772
+ background: transparent;
1773
+ }
1774
+
1775
+ & th {
1776
+ background: transparent;
1777
+ color: rgb(var(--edu-ink));
1778
+ font-weight: 600;
1779
+ }
1780
+
1781
+ & input[type="text"],
1782
+ & input[type="number"],
1783
+ & select {
1784
+ border: none;
1785
+ border-bottom: 1px dashed rgb(var(--edu-border));
1786
+ border-radius: 0;
1787
+ background: transparent;
1788
+ }
1789
+
1790
+ & .disabled-cell {
1791
+ background: transparent;
1792
+ opacity: 0.4;
1793
+ }
1794
+ }
1795
+
1796
+ /* ===========================================
1797
+ RESPONSIVE BEHAVIOR
1798
+ =========================================== */
1799
+
1800
+ @container (max-width: 720px) {
1801
+ td, th {
1802
+ padding: clamp(0.35rem, 1.2cqw, 0.5rem);
1803
+ font-size: clamp(0.75rem, 1.6cqw, 0.85rem);
1804
+ min-width: clamp(52px, 11cqw, 70px);
1805
+ }
1806
+
1807
+ input[type="text"],
1808
+ input[type="number"],
1809
+ select {
1810
+ font-size: clamp(0.75rem, 1.4cqw, 0.85rem);
1811
+ padding: clamp(0.3rem, 1cqw, 0.4rem);
1812
+ }
1813
+
1814
+ input[type="checkbox"],
1815
+ input[type="radio"] {
1816
+ width: clamp(12px, 2.8cqw, 16px);
1817
+ height: clamp(12px, 2.8cqw, 16px);
1818
+ }
1819
+ }
1820
+
1821
+ @container (max-width: 480px) {
1822
+ td, th {
1823
+ padding: clamp(0.3rem, 1cqw, 0.4rem);
1824
+ font-size: clamp(0.7rem, 1.4cqw, 0.8rem);
1825
+ max-width: clamp(90px, 30cqw, 120px);
1826
+ min-width: clamp(48px, 10cqw, 60px);
1827
+ }
1828
+ }
1829
+ `;function Ut(e){return typeof e>"u"||e===null}function mi(e){return typeof e=="object"&&e!==null}function fi(e){return Array.isArray(e)?e:Ut(e)?[]:[e]}function bi(e,n){var t,r,i,a;if(n)for(a=Object.keys(n),t=0,r=a.length;t<r;t+=1)i=a[t],e[i]=n[i];return e}function vi(e,n){var t="",r;for(r=0;r<n;r+=1)t+=e;return t}function xi(e){return e===0&&Number.NEGATIVE_INFINITY===1/e}var wi=Ut,yi=mi,Ei=fi,Ci=vi,Si=xi,ki=bi,C={isNothing:wi,isObject:yi,toArray:Ei,repeat:Ci,isNegativeZero:Si,extend:ki};function Yt(e,n){var t="",r=e.reason||"(unknown reason)";return e.mark?(e.mark.name&&(t+='in "'+e.mark.name+'" '),t+="("+(e.mark.line+1)+":"+(e.mark.column+1)+")",!n&&e.mark.snippet&&(t+=`
1830
+
1831
+ `+e.mark.snippet),r+" "+t):r}function ge(e,n){Error.call(this),this.name="YAMLException",this.reason=e,this.mark=n,this.message=Yt(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}ge.prototype=Object.create(Error.prototype);ge.prototype.constructor=ge;ge.prototype.toString=function(n){return this.name+": "+Yt(this,n)};var A=ge;function Ze(e,n,t,r,i){var a="",o="",s=Math.floor(i/2)-1;return r-n>s&&(a=" ... ",n=r-s+a.length),t-r>s&&(o=" ...",t=r+s-o.length),{str:a+e.slice(n,t).replace(/\t/g,"\u2192")+o,pos:r-n+a.length}}function Je(e,n){return C.repeat(" ",n-e.length)+e}function Ti(e,n){if(n=Object.create(n||null),!e.buffer)return null;n.maxLength||(n.maxLength=79),typeof n.indent!="number"&&(n.indent=1),typeof n.linesBefore!="number"&&(n.linesBefore=3),typeof n.linesAfter!="number"&&(n.linesAfter=2);for(var t=/\r?\n|\r|\0/g,r=[0],i=[],a,o=-1;a=t.exec(e.buffer);)i.push(a.index),r.push(a.index+a[0].length),e.position<=a.index&&o<0&&(o=r.length-2);o<0&&(o=r.length-1);var s="",l,c,d=Math.min(e.line+n.linesAfter,i.length).toString().length,u=n.maxLength-(n.indent+d+3);for(l=1;l<=n.linesBefore&&!(o-l<0);l++)c=Ze(e.buffer,r[o-l],i[o-l],e.position-(r[o]-r[o-l]),u),s=C.repeat(" ",n.indent)+Je((e.line-l+1).toString(),d)+" | "+c.str+`
1832
+ `+s;for(c=Ze(e.buffer,r[o],i[o],e.position,u),s+=C.repeat(" ",n.indent)+Je((e.line+1).toString(),d)+" | "+c.str+`
1833
+ `,s+=C.repeat("-",n.indent+d+3+c.pos)+`^
1834
+ `,l=1;l<=n.linesAfter&&!(o+l>=i.length);l++)c=Ze(e.buffer,r[o+l],i[o+l],e.position-(r[o]-r[o+l]),u),s+=C.repeat(" ",n.indent)+Je((e.line+l+1).toString(),d)+" | "+c.str+`
1835
+ `;return s.replace(/\n$/,"")}var $i=Ti,Ai=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],_i=["scalar","sequence","mapping"];function Ii(e){var n={};return e!==null&&Object.keys(e).forEach(function(t){e[t].forEach(function(r){n[String(r)]=t})}),n}function Mi(e,n){if(n=n||{},Object.keys(n).forEach(function(t){if(Ai.indexOf(t)===-1)throw new A('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.options=n,this.tag=e,this.kind=n.kind||null,this.resolve=n.resolve||function(){return!0},this.construct=n.construct||function(t){return t},this.instanceOf=n.instanceOf||null,this.predicate=n.predicate||null,this.represent=n.represent||null,this.representName=n.representName||null,this.defaultStyle=n.defaultStyle||null,this.multi=n.multi||!1,this.styleAliases=Ii(n.styleAliases||null),_i.indexOf(this.kind)===-1)throw new A('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var T=Mi;function Mt(e,n){var t=[];return e[n].forEach(function(r){var i=t.length;t.forEach(function(a,o){a.tag===r.tag&&a.kind===r.kind&&a.multi===r.multi&&(i=o)}),t[i]=r}),t}function Li(){var e={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},n,t;function r(i){i.multi?(e.multi[i.kind].push(i),e.multi.fallback.push(i)):e[i.kind][i.tag]=e.fallback[i.tag]=i}for(n=0,t=arguments.length;n<t;n+=1)arguments[n].forEach(r);return e}function tt(e){return this.extend(e)}tt.prototype.extend=function(n){var t=[],r=[];if(n instanceof T)r.push(n);else if(Array.isArray(n))r=r.concat(n);else if(n&&(Array.isArray(n.implicit)||Array.isArray(n.explicit)))n.implicit&&(t=t.concat(n.implicit)),n.explicit&&(r=r.concat(n.explicit));else throw new A("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.forEach(function(a){if(!(a instanceof T))throw new A("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(a.loadKind&&a.loadKind!=="scalar")throw new A("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(a.multi)throw new A("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")}),r.forEach(function(a){if(!(a instanceof T))throw new A("Specified list of YAML types (or a single Type object) contains a non-Type object.")});var i=Object.create(tt.prototype);return i.implicit=(this.implicit||[]).concat(t),i.explicit=(this.explicit||[]).concat(r),i.compiledImplicit=Mt(i,"implicit"),i.compiledExplicit=Mt(i,"explicit"),i.compiledTypeMap=Li(i.compiledImplicit,i.compiledExplicit),i};var Kt=tt,Wt=new T("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return e!==null?e:""}}),Qt=new T("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return e!==null?e:[]}}),Xt=new T("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return e!==null?e:{}}}),Zt=new Kt({explicit:[Wt,Qt,Xt]});function Di(e){if(e===null)return!0;var n=e.length;return n===1&&e==="~"||n===4&&(e==="null"||e==="Null"||e==="NULL")}function Ri(){return null}function Pi(e){return e===null}var Jt=new T("tag:yaml.org,2002:null",{kind:"scalar",resolve:Di,construct:Ri,predicate:Pi,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"});function qi(e){if(e===null)return!1;var n=e.length;return n===4&&(e==="true"||e==="True"||e==="TRUE")||n===5&&(e==="false"||e==="False"||e==="FALSE")}function Bi(e){return e==="true"||e==="True"||e==="TRUE"}function zi(e){return Object.prototype.toString.call(e)==="[object Boolean]"}var er=new T("tag:yaml.org,2002:bool",{kind:"scalar",resolve:qi,construct:Bi,predicate:zi,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"});function Hi(e){return 48<=e&&e<=57||65<=e&&e<=70||97<=e&&e<=102}function Gi(e){return 48<=e&&e<=55}function Ni(e){return 48<=e&&e<=57}function Oi(e){if(e===null)return!1;var n=e.length,t=0,r=!1,i;if(!n)return!1;if(i=e[t],(i==="-"||i==="+")&&(i=e[++t]),i==="0"){if(t+1===n)return!0;if(i=e[++t],i==="b"){for(t++;t<n;t++)if(i=e[t],i!=="_"){if(i!=="0"&&i!=="1")return!1;r=!0}return r&&i!=="_"}if(i==="x"){for(t++;t<n;t++)if(i=e[t],i!=="_"){if(!Hi(e.charCodeAt(t)))return!1;r=!0}return r&&i!=="_"}if(i==="o"){for(t++;t<n;t++)if(i=e[t],i!=="_"){if(!Gi(e.charCodeAt(t)))return!1;r=!0}return r&&i!=="_"}}if(i==="_")return!1;for(;t<n;t++)if(i=e[t],i!=="_"){if(!Ni(e.charCodeAt(t)))return!1;r=!0}return!(!r||i==="_")}function Vi(e){var n=e,t=1,r;if(n.indexOf("_")!==-1&&(n=n.replace(/_/g,"")),r=n[0],(r==="-"||r==="+")&&(r==="-"&&(t=-1),n=n.slice(1),r=n[0]),n==="0")return 0;if(r==="0"){if(n[1]==="b")return t*parseInt(n.slice(2),2);if(n[1]==="x")return t*parseInt(n.slice(2),16);if(n[1]==="o")return t*parseInt(n.slice(2),8)}return t*parseInt(n,10)}function Fi(e){return Object.prototype.toString.call(e)==="[object Number]"&&e%1===0&&!C.isNegativeZero(e)}var tr=new T("tag:yaml.org,2002:int",{kind:"scalar",resolve:Oi,construct:Vi,predicate:Fi,represent:{binary:function(e){return e>=0?"0b"+e.toString(2):"-0b"+e.toString(2).slice(1)},octal:function(e){return e>=0?"0o"+e.toString(8):"-0o"+e.toString(8).slice(1)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return e>=0?"0x"+e.toString(16).toUpperCase():"-0x"+e.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),ji=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function Ui(e){return!(e===null||!ji.test(e)||e[e.length-1]==="_")}function Yi(e){var n,t;return n=e.replace(/_/g,"").toLowerCase(),t=n[0]==="-"?-1:1,"+-".indexOf(n[0])>=0&&(n=n.slice(1)),n===".inf"?t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:n===".nan"?NaN:t*parseFloat(n,10)}var Ki=/^[-+]?[0-9]+e/;function Wi(e,n){var t;if(isNaN(e))switch(n){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(n){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(n){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(C.isNegativeZero(e))return"-0.0";return t=e.toString(10),Ki.test(t)?t.replace("e",".e"):t}function Qi(e){return Object.prototype.toString.call(e)==="[object Number]"&&(e%1!==0||C.isNegativeZero(e))}var rr=new T("tag:yaml.org,2002:float",{kind:"scalar",resolve:Ui,construct:Yi,predicate:Qi,represent:Wi,defaultStyle:"lowercase"}),ir=Zt.extend({implicit:[Jt,er,tr,rr]}),nr=ir,ar=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),or=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function Xi(e){return e===null?!1:ar.exec(e)!==null||or.exec(e)!==null}function Zi(e){var n,t,r,i,a,o,s,l=0,c=null,d,u,p;if(n=ar.exec(e),n===null&&(n=or.exec(e)),n===null)throw new Error("Date resolve error");if(t=+n[1],r=+n[2]-1,i=+n[3],!n[4])return new Date(Date.UTC(t,r,i));if(a=+n[4],o=+n[5],s=+n[6],n[7]){for(l=n[7].slice(0,3);l.length<3;)l+="0";l=+l}return n[9]&&(d=+n[10],u=+(n[11]||0),c=(d*60+u)*6e4,n[9]==="-"&&(c=-c)),p=new Date(Date.UTC(t,r,i,a,o,s,l)),c&&p.setTime(p.getTime()-c),p}function Ji(e){return e.toISOString()}var sr=new T("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:Xi,construct:Zi,instanceOf:Date,represent:Ji});function en(e){return e==="<<"||e===null}var lr=new T("tag:yaml.org,2002:merge",{kind:"scalar",resolve:en}),ot=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
1836
+ \r`;function tn(e){if(e===null)return!1;var n,t,r=0,i=e.length,a=ot;for(t=0;t<i;t++)if(n=a.indexOf(e.charAt(t)),!(n>64)){if(n<0)return!1;r+=6}return r%8===0}function rn(e){var n,t,r=e.replace(/[\r\n=]/g,""),i=r.length,a=ot,o=0,s=[];for(n=0;n<i;n++)n%4===0&&n&&(s.push(o>>16&255),s.push(o>>8&255),s.push(o&255)),o=o<<6|a.indexOf(r.charAt(n));return t=i%4*6,t===0?(s.push(o>>16&255),s.push(o>>8&255),s.push(o&255)):t===18?(s.push(o>>10&255),s.push(o>>2&255)):t===12&&s.push(o>>4&255),new Uint8Array(s)}function nn(e){var n="",t=0,r,i,a=e.length,o=ot;for(r=0;r<a;r++)r%3===0&&r&&(n+=o[t>>18&63],n+=o[t>>12&63],n+=o[t>>6&63],n+=o[t&63]),t=(t<<8)+e[r];return i=a%3,i===0?(n+=o[t>>18&63],n+=o[t>>12&63],n+=o[t>>6&63],n+=o[t&63]):i===2?(n+=o[t>>10&63],n+=o[t>>4&63],n+=o[t<<2&63],n+=o[64]):i===1&&(n+=o[t>>2&63],n+=o[t<<4&63],n+=o[64],n+=o[64]),n}function an(e){return Object.prototype.toString.call(e)==="[object Uint8Array]"}var cr=new T("tag:yaml.org,2002:binary",{kind:"scalar",resolve:tn,construct:rn,predicate:an,represent:nn}),on=Object.prototype.hasOwnProperty,sn=Object.prototype.toString;function ln(e){if(e===null)return!0;var n=[],t,r,i,a,o,s=e;for(t=0,r=s.length;t<r;t+=1){if(i=s[t],o=!1,sn.call(i)!=="[object Object]")return!1;for(a in i)if(on.call(i,a))if(!o)o=!0;else return!1;if(!o)return!1;if(n.indexOf(a)===-1)n.push(a);else return!1}return!0}function cn(e){return e!==null?e:[]}var dr=new T("tag:yaml.org,2002:omap",{kind:"sequence",resolve:ln,construct:cn}),dn=Object.prototype.toString;function un(e){if(e===null)return!0;var n,t,r,i,a,o=e;for(a=new Array(o.length),n=0,t=o.length;n<t;n+=1){if(r=o[n],dn.call(r)!=="[object Object]"||(i=Object.keys(r),i.length!==1))return!1;a[n]=[i[0],r[i[0]]]}return!0}function pn(e){if(e===null)return[];var n,t,r,i,a,o=e;for(a=new Array(o.length),n=0,t=o.length;n<t;n+=1)r=o[n],i=Object.keys(r),a[n]=[i[0],r[i[0]]];return a}var ur=new T("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:un,construct:pn}),hn=Object.prototype.hasOwnProperty;function gn(e){if(e===null)return!0;var n,t=e;for(n in t)if(hn.call(t,n)&&t[n]!==null)return!1;return!0}function mn(e){return e!==null?e:{}}var pr=new T("tag:yaml.org,2002:set",{kind:"mapping",resolve:gn,construct:mn}),st=nr.extend({implicit:[sr,lr],explicit:[cr,dr,ur,pr]}),H=Object.prototype.hasOwnProperty,He=1,hr=2,gr=3,Ge=4,et=1,fn=2,Lt=3,bn=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,vn=/[\x85\u2028\u2029]/,xn=/[,\[\]\{\}]/,mr=/^(?:!|!!|![a-z\-]+!)$/i,fr=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function Dt(e){return Object.prototype.toString.call(e)}function D(e){return e===10||e===13}function O(e){return e===9||e===32}function _(e){return e===9||e===32||e===10||e===13}function K(e){return e===44||e===91||e===93||e===123||e===125}function wn(e){var n;return 48<=e&&e<=57?e-48:(n=e|32,97<=n&&n<=102?n-97+10:-1)}function yn(e){return e===120?2:e===117?4:e===85?8:0}function En(e){return 48<=e&&e<=57?e-48:-1}function Rt(e){return e===48?"\0":e===97?"\x07":e===98?"\b":e===116||e===9?" ":e===110?`
1837
+ `:e===118?"\v":e===102?"\f":e===114?"\r":e===101?"\x1B":e===32?" ":e===34?'"':e===47?"/":e===92?"\\":e===78?"\x85":e===95?"\xA0":e===76?"\u2028":e===80?"\u2029":""}function Cn(e){return e<=65535?String.fromCharCode(e):String.fromCharCode((e-65536>>10)+55296,(e-65536&1023)+56320)}function br(e,n,t){n==="__proto__"?Object.defineProperty(e,n,{configurable:!0,enumerable:!0,writable:!0,value:t}):e[n]=t}var vr=new Array(256),xr=new Array(256);for(N=0;N<256;N++)vr[N]=Rt(N)?1:0,xr[N]=Rt(N);var N;function Sn(e,n){this.input=e,this.filename=n.filename||null,this.schema=n.schema||st,this.onWarning=n.onWarning||null,this.legacy=n.legacy||!1,this.json=n.json||!1,this.listener=n.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function wr(e,n){var t={name:e.filename,buffer:e.input.slice(0,-1),position:e.position,line:e.line,column:e.position-e.lineStart};return t.snippet=$i(t),new A(n,t)}function f(e,n){throw wr(e,n)}function Ne(e,n){e.onWarning&&e.onWarning.call(null,wr(e,n))}var Pt={YAML:function(n,t,r){var i,a,o;n.version!==null&&f(n,"duplication of %YAML directive"),r.length!==1&&f(n,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(r[0]),i===null&&f(n,"ill-formed argument of the YAML directive"),a=parseInt(i[1],10),o=parseInt(i[2],10),a!==1&&f(n,"unacceptable YAML version of the document"),n.version=r[0],n.checkLineBreaks=o<2,o!==1&&o!==2&&Ne(n,"unsupported YAML version of the document")},TAG:function(n,t,r){var i,a;r.length!==2&&f(n,"TAG directive accepts exactly two arguments"),i=r[0],a=r[1],mr.test(i)||f(n,"ill-formed tag handle (first argument) of the TAG directive"),H.call(n.tagMap,i)&&f(n,'there is a previously declared suffix for "'+i+'" tag handle'),fr.test(a)||f(n,"ill-formed tag prefix (second argument) of the TAG directive");try{a=decodeURIComponent(a)}catch{f(n,"tag prefix is malformed: "+a)}n.tagMap[i]=a}};function z(e,n,t,r){var i,a,o,s;if(n<t){if(s=e.input.slice(n,t),r)for(i=0,a=s.length;i<a;i+=1)o=s.charCodeAt(i),o===9||32<=o&&o<=1114111||f(e,"expected valid JSON character");else bn.test(s)&&f(e,"the stream contains non-printable characters");e.result+=s}}function qt(e,n,t,r){var i,a,o,s;for(C.isObject(t)||f(e,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(t),o=0,s=i.length;o<s;o+=1)a=i[o],H.call(n,a)||(br(n,a,t[a]),r[a]=!0)}function W(e,n,t,r,i,a,o,s,l){var c,d;if(Array.isArray(i))for(i=Array.prototype.slice.call(i),c=0,d=i.length;c<d;c+=1)Array.isArray(i[c])&&f(e,"nested arrays are not supported inside keys"),typeof i=="object"&&Dt(i[c])==="[object Object]"&&(i[c]="[object Object]");if(typeof i=="object"&&Dt(i)==="[object Object]"&&(i="[object Object]"),i=String(i),n===null&&(n={}),r==="tag:yaml.org,2002:merge")if(Array.isArray(a))for(c=0,d=a.length;c<d;c+=1)qt(e,n,a[c],t);else qt(e,n,a,t);else!e.json&&!H.call(t,i)&&H.call(n,i)&&(e.line=o||e.line,e.lineStart=s||e.lineStart,e.position=l||e.position,f(e,"duplicated mapping key")),br(n,i,a),delete t[i];return n}function lt(e){var n;n=e.input.charCodeAt(e.position),n===10?e.position++:n===13?(e.position++,e.input.charCodeAt(e.position)===10&&e.position++):f(e,"a line break is expected"),e.line+=1,e.lineStart=e.position,e.firstTabInLine=-1}function y(e,n,t){for(var r=0,i=e.input.charCodeAt(e.position);i!==0;){for(;O(i);)i===9&&e.firstTabInLine===-1&&(e.firstTabInLine=e.position),i=e.input.charCodeAt(++e.position);if(n&&i===35)do i=e.input.charCodeAt(++e.position);while(i!==10&&i!==13&&i!==0);if(D(i))for(lt(e),i=e.input.charCodeAt(e.position),r++,e.lineIndent=0;i===32;)e.lineIndent++,i=e.input.charCodeAt(++e.position);else break}return t!==-1&&r!==0&&e.lineIndent<t&&Ne(e,"deficient indentation"),r}function Fe(e){var n=e.position,t;return t=e.input.charCodeAt(n),!!((t===45||t===46)&&t===e.input.charCodeAt(n+1)&&t===e.input.charCodeAt(n+2)&&(n+=3,t=e.input.charCodeAt(n),t===0||_(t)))}function ct(e,n){n===1?e.result+=" ":n>1&&(e.result+=C.repeat(`
1838
+ `,n-1))}function kn(e,n,t){var r,i,a,o,s,l,c,d,u=e.kind,p=e.result,h;if(h=e.input.charCodeAt(e.position),_(h)||K(h)||h===35||h===38||h===42||h===33||h===124||h===62||h===39||h===34||h===37||h===64||h===96||(h===63||h===45)&&(i=e.input.charCodeAt(e.position+1),_(i)||t&&K(i)))return!1;for(e.kind="scalar",e.result="",a=o=e.position,s=!1;h!==0;){if(h===58){if(i=e.input.charCodeAt(e.position+1),_(i)||t&&K(i))break}else if(h===35){if(r=e.input.charCodeAt(e.position-1),_(r))break}else{if(e.position===e.lineStart&&Fe(e)||t&&K(h))break;if(D(h))if(l=e.line,c=e.lineStart,d=e.lineIndent,y(e,!1,-1),e.lineIndent>=n){s=!0,h=e.input.charCodeAt(e.position);continue}else{e.position=o,e.line=l,e.lineStart=c,e.lineIndent=d;break}}s&&(z(e,a,o,!1),ct(e,e.line-l),a=o=e.position,s=!1),O(h)||(o=e.position+1),h=e.input.charCodeAt(++e.position)}return z(e,a,o,!1),e.result?!0:(e.kind=u,e.result=p,!1)}function Tn(e,n){var t,r,i;if(t=e.input.charCodeAt(e.position),t!==39)return!1;for(e.kind="scalar",e.result="",e.position++,r=i=e.position;(t=e.input.charCodeAt(e.position))!==0;)if(t===39)if(z(e,r,e.position,!0),t=e.input.charCodeAt(++e.position),t===39)r=e.position,e.position++,i=e.position;else return!0;else D(t)?(z(e,r,i,!0),ct(e,y(e,!1,n)),r=i=e.position):e.position===e.lineStart&&Fe(e)?f(e,"unexpected end of the document within a single quoted scalar"):(e.position++,i=e.position);f(e,"unexpected end of the stream within a single quoted scalar")}function $n(e,n){var t,r,i,a,o,s;if(s=e.input.charCodeAt(e.position),s!==34)return!1;for(e.kind="scalar",e.result="",e.position++,t=r=e.position;(s=e.input.charCodeAt(e.position))!==0;){if(s===34)return z(e,t,e.position,!0),e.position++,!0;if(s===92){if(z(e,t,e.position,!0),s=e.input.charCodeAt(++e.position),D(s))y(e,!1,n);else if(s<256&&vr[s])e.result+=xr[s],e.position++;else if((o=yn(s))>0){for(i=o,a=0;i>0;i--)s=e.input.charCodeAt(++e.position),(o=wn(s))>=0?a=(a<<4)+o:f(e,"expected hexadecimal character");e.result+=Cn(a),e.position++}else f(e,"unknown escape sequence");t=r=e.position}else D(s)?(z(e,t,r,!0),ct(e,y(e,!1,n)),t=r=e.position):e.position===e.lineStart&&Fe(e)?f(e,"unexpected end of the document within a double quoted scalar"):(e.position++,r=e.position)}f(e,"unexpected end of the stream within a double quoted scalar")}function An(e,n){var t=!0,r,i,a,o=e.tag,s,l=e.anchor,c,d,u,p,h,g=Object.create(null),m,b,w,v;if(v=e.input.charCodeAt(e.position),v===91)d=93,h=!1,s=[];else if(v===123)d=125,h=!0,s={};else return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=s),v=e.input.charCodeAt(++e.position);v!==0;){if(y(e,!0,n),v=e.input.charCodeAt(e.position),v===d)return e.position++,e.tag=o,e.anchor=l,e.kind=h?"mapping":"sequence",e.result=s,!0;t?v===44&&f(e,"expected the node content, but found ','"):f(e,"missed comma between flow collection entries"),b=m=w=null,u=p=!1,v===63&&(c=e.input.charCodeAt(e.position+1),_(c)&&(u=p=!0,e.position++,y(e,!0,n))),r=e.line,i=e.lineStart,a=e.position,Q(e,n,He,!1,!0),b=e.tag,m=e.result,y(e,!0,n),v=e.input.charCodeAt(e.position),(p||e.line===r)&&v===58&&(u=!0,v=e.input.charCodeAt(++e.position),y(e,!0,n),Q(e,n,He,!1,!0),w=e.result),h?W(e,s,g,b,m,w,r,i,a):u?s.push(W(e,null,g,b,m,w,r,i,a)):s.push(m),y(e,!0,n),v=e.input.charCodeAt(e.position),v===44?(t=!0,v=e.input.charCodeAt(++e.position)):t=!1}f(e,"unexpected end of the stream within a flow collection")}function _n(e,n){var t,r,i=et,a=!1,o=!1,s=n,l=0,c=!1,d,u;if(u=e.input.charCodeAt(e.position),u===124)r=!1;else if(u===62)r=!0;else return!1;for(e.kind="scalar",e.result="";u!==0;)if(u=e.input.charCodeAt(++e.position),u===43||u===45)et===i?i=u===43?Lt:fn:f(e,"repeat of a chomping mode identifier");else if((d=En(u))>=0)d===0?f(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?f(e,"repeat of an indentation width identifier"):(s=n+d-1,o=!0);else break;if(O(u)){do u=e.input.charCodeAt(++e.position);while(O(u));if(u===35)do u=e.input.charCodeAt(++e.position);while(!D(u)&&u!==0)}for(;u!==0;){for(lt(e),e.lineIndent=0,u=e.input.charCodeAt(e.position);(!o||e.lineIndent<s)&&u===32;)e.lineIndent++,u=e.input.charCodeAt(++e.position);if(!o&&e.lineIndent>s&&(s=e.lineIndent),D(u)){l++;continue}if(e.lineIndent<s){i===Lt?e.result+=C.repeat(`
1839
+ `,a?1+l:l):i===et&&a&&(e.result+=`
1840
+ `);break}for(r?O(u)?(c=!0,e.result+=C.repeat(`
1841
+ `,a?1+l:l)):c?(c=!1,e.result+=C.repeat(`
1842
+ `,l+1)):l===0?a&&(e.result+=" "):e.result+=C.repeat(`
1843
+ `,l):e.result+=C.repeat(`
1844
+ `,a?1+l:l),a=!0,o=!0,l=0,t=e.position;!D(u)&&u!==0;)u=e.input.charCodeAt(++e.position);z(e,t,e.position,!1)}return!0}function Bt(e,n){var t,r=e.tag,i=e.anchor,a=[],o,s=!1,l;if(e.firstTabInLine!==-1)return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=a),l=e.input.charCodeAt(e.position);l!==0&&(e.firstTabInLine!==-1&&(e.position=e.firstTabInLine,f(e,"tab characters must not be used in indentation")),!(l!==45||(o=e.input.charCodeAt(e.position+1),!_(o))));){if(s=!0,e.position++,y(e,!0,-1)&&e.lineIndent<=n){a.push(null),l=e.input.charCodeAt(e.position);continue}if(t=e.line,Q(e,n,gr,!1,!0),a.push(e.result),y(e,!0,-1),l=e.input.charCodeAt(e.position),(e.line===t||e.lineIndent>n)&&l!==0)f(e,"bad indentation of a sequence entry");else if(e.lineIndent<n)break}return s?(e.tag=r,e.anchor=i,e.kind="sequence",e.result=a,!0):!1}function In(e,n,t){var r,i,a,o,s,l,c=e.tag,d=e.anchor,u={},p=Object.create(null),h=null,g=null,m=null,b=!1,w=!1,v;if(e.firstTabInLine!==-1)return!1;for(e.anchor!==null&&(e.anchorMap[e.anchor]=u),v=e.input.charCodeAt(e.position);v!==0;){if(!b&&e.firstTabInLine!==-1&&(e.position=e.firstTabInLine,f(e,"tab characters must not be used in indentation")),r=e.input.charCodeAt(e.position+1),a=e.line,(v===63||v===58)&&_(r))v===63?(b&&(W(e,u,p,h,g,null,o,s,l),h=g=m=null),w=!0,b=!0,i=!0):b?(b=!1,i=!0):f(e,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),e.position+=1,v=r;else{if(o=e.line,s=e.lineStart,l=e.position,!Q(e,t,hr,!1,!0))break;if(e.line===a){for(v=e.input.charCodeAt(e.position);O(v);)v=e.input.charCodeAt(++e.position);if(v===58)v=e.input.charCodeAt(++e.position),_(v)||f(e,"a whitespace character is expected after the key-value separator within a block mapping"),b&&(W(e,u,p,h,g,null,o,s,l),h=g=m=null),w=!0,b=!1,i=!1,h=e.tag,g=e.result;else if(w)f(e,"can not read an implicit mapping pair; a colon is missed");else return e.tag=c,e.anchor=d,!0}else if(w)f(e,"can not read a block mapping entry; a multiline key may not be an implicit key");else return e.tag=c,e.anchor=d,!0}if((e.line===a||e.lineIndent>n)&&(b&&(o=e.line,s=e.lineStart,l=e.position),Q(e,n,Ge,!0,i)&&(b?g=e.result:m=e.result),b||(W(e,u,p,h,g,m,o,s,l),h=g=m=null),y(e,!0,-1),v=e.input.charCodeAt(e.position)),(e.line===a||e.lineIndent>n)&&v!==0)f(e,"bad indentation of a mapping entry");else if(e.lineIndent<n)break}return b&&W(e,u,p,h,g,null,o,s,l),w&&(e.tag=c,e.anchor=d,e.kind="mapping",e.result=u),w}function Mn(e){var n,t=!1,r=!1,i,a,o;if(o=e.input.charCodeAt(e.position),o!==33)return!1;if(e.tag!==null&&f(e,"duplication of a tag property"),o=e.input.charCodeAt(++e.position),o===60?(t=!0,o=e.input.charCodeAt(++e.position)):o===33?(r=!0,i="!!",o=e.input.charCodeAt(++e.position)):i="!",n=e.position,t){do o=e.input.charCodeAt(++e.position);while(o!==0&&o!==62);e.position<e.length?(a=e.input.slice(n,e.position),o=e.input.charCodeAt(++e.position)):f(e,"unexpected end of the stream within a verbatim tag")}else{for(;o!==0&&!_(o);)o===33&&(r?f(e,"tag suffix cannot contain exclamation marks"):(i=e.input.slice(n-1,e.position+1),mr.test(i)||f(e,"named tag handle cannot contain such characters"),r=!0,n=e.position+1)),o=e.input.charCodeAt(++e.position);a=e.input.slice(n,e.position),xn.test(a)&&f(e,"tag suffix cannot contain flow indicator characters")}a&&!fr.test(a)&&f(e,"tag name cannot contain such characters: "+a);try{a=decodeURIComponent(a)}catch{f(e,"tag name is malformed: "+a)}return t?e.tag=a:H.call(e.tagMap,i)?e.tag=e.tagMap[i]+a:i==="!"?e.tag="!"+a:i==="!!"?e.tag="tag:yaml.org,2002:"+a:f(e,'undeclared tag handle "'+i+'"'),!0}function Ln(e){var n,t;if(t=e.input.charCodeAt(e.position),t!==38)return!1;for(e.anchor!==null&&f(e,"duplication of an anchor property"),t=e.input.charCodeAt(++e.position),n=e.position;t!==0&&!_(t)&&!K(t);)t=e.input.charCodeAt(++e.position);return e.position===n&&f(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(n,e.position),!0}function Dn(e){var n,t,r;if(r=e.input.charCodeAt(e.position),r!==42)return!1;for(r=e.input.charCodeAt(++e.position),n=e.position;r!==0&&!_(r)&&!K(r);)r=e.input.charCodeAt(++e.position);return e.position===n&&f(e,"name of an alias node must contain at least one character"),t=e.input.slice(n,e.position),H.call(e.anchorMap,t)||f(e,'unidentified alias "'+t+'"'),e.result=e.anchorMap[t],y(e,!0,-1),!0}function Q(e,n,t,r,i){var a,o,s,l=1,c=!1,d=!1,u,p,h,g,m,b;if(e.listener!==null&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,a=o=s=Ge===t||gr===t,r&&y(e,!0,-1)&&(c=!0,e.lineIndent>n?l=1:e.lineIndent===n?l=0:e.lineIndent<n&&(l=-1)),l===1)for(;Mn(e)||Ln(e);)y(e,!0,-1)?(c=!0,s=a,e.lineIndent>n?l=1:e.lineIndent===n?l=0:e.lineIndent<n&&(l=-1)):s=!1;if(s&&(s=c||i),(l===1||Ge===t)&&(He===t||hr===t?m=n:m=n+1,b=e.position-e.lineStart,l===1?s&&(Bt(e,b)||In(e,b,m))||An(e,m)?d=!0:(o&&_n(e,m)||Tn(e,m)||$n(e,m)?d=!0:Dn(e)?(d=!0,(e.tag!==null||e.anchor!==null)&&f(e,"alias node should not have any properties")):kn(e,m,He===t)&&(d=!0,e.tag===null&&(e.tag="?")),e.anchor!==null&&(e.anchorMap[e.anchor]=e.result)):l===0&&(d=s&&Bt(e,b))),e.tag===null)e.anchor!==null&&(e.anchorMap[e.anchor]=e.result);else if(e.tag==="?"){for(e.result!==null&&e.kind!=="scalar"&&f(e,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+e.kind+'"'),u=0,p=e.implicitTypes.length;u<p;u+=1)if(g=e.implicitTypes[u],g.resolve(e.result)){e.result=g.construct(e.result),e.tag=g.tag,e.anchor!==null&&(e.anchorMap[e.anchor]=e.result);break}}else if(e.tag!=="!"){if(H.call(e.typeMap[e.kind||"fallback"],e.tag))g=e.typeMap[e.kind||"fallback"][e.tag];else for(g=null,h=e.typeMap.multi[e.kind||"fallback"],u=0,p=h.length;u<p;u+=1)if(e.tag.slice(0,h[u].tag.length)===h[u].tag){g=h[u];break}g||f(e,"unknown tag !<"+e.tag+">"),e.result!==null&&g.kind!==e.kind&&f(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+g.kind+'", not "'+e.kind+'"'),g.resolve(e.result,e.tag)?(e.result=g.construct(e.result,e.tag),e.anchor!==null&&(e.anchorMap[e.anchor]=e.result)):f(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")}return e.listener!==null&&e.listener("close",e),e.tag!==null||e.anchor!==null||d}function Rn(e){var n=e.position,t,r,i,a=!1,o;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap=Object.create(null),e.anchorMap=Object.create(null);(o=e.input.charCodeAt(e.position))!==0&&(y(e,!0,-1),o=e.input.charCodeAt(e.position),!(e.lineIndent>0||o!==37));){for(a=!0,o=e.input.charCodeAt(++e.position),t=e.position;o!==0&&!_(o);)o=e.input.charCodeAt(++e.position);for(r=e.input.slice(t,e.position),i=[],r.length<1&&f(e,"directive name must not be less than one character in length");o!==0;){for(;O(o);)o=e.input.charCodeAt(++e.position);if(o===35){do o=e.input.charCodeAt(++e.position);while(o!==0&&!D(o));break}if(D(o))break;for(t=e.position;o!==0&&!_(o);)o=e.input.charCodeAt(++e.position);i.push(e.input.slice(t,e.position))}o!==0&&lt(e),H.call(Pt,r)?Pt[r](e,r,i):Ne(e,'unknown document directive "'+r+'"')}if(y(e,!0,-1),e.lineIndent===0&&e.input.charCodeAt(e.position)===45&&e.input.charCodeAt(e.position+1)===45&&e.input.charCodeAt(e.position+2)===45?(e.position+=3,y(e,!0,-1)):a&&f(e,"directives end mark is expected"),Q(e,e.lineIndent-1,Ge,!1,!0),y(e,!0,-1),e.checkLineBreaks&&vn.test(e.input.slice(n,e.position))&&Ne(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&Fe(e)){e.input.charCodeAt(e.position)===46&&(e.position+=3,y(e,!0,-1));return}if(e.position<e.length-1)f(e,"end of the stream or a document separator is expected");else return}function yr(e,n){e=String(e),n=n||{},e.length!==0&&(e.charCodeAt(e.length-1)!==10&&e.charCodeAt(e.length-1)!==13&&(e+=`
1845
+ `),e.charCodeAt(0)===65279&&(e=e.slice(1)));var t=new Sn(e,n),r=e.indexOf("\0");for(r!==-1&&(t.position=r,f(t,"null byte is not allowed in input")),t.input+="\0";t.input.charCodeAt(t.position)===32;)t.lineIndent+=1,t.position+=1;for(;t.position<t.length-1;)Rn(t);return t.documents}function Pn(e,n,t){n!==null&&typeof n=="object"&&typeof t>"u"&&(t=n,n=null);var r=yr(e,t);if(typeof n!="function")return r;for(var i=0,a=r.length;i<a;i+=1)n(r[i])}function qn(e,n){var t=yr(e,n);if(t.length!==0){if(t.length===1)return t[0];throw new A("expected a single document in the stream, but found more")}}var Bn=Pn,zn=qn,Er={loadAll:Bn,load:zn},Cr=Object.prototype.toString,Sr=Object.prototype.hasOwnProperty,dt=65279,Hn=9,me=10,Gn=13,Nn=32,On=33,Vn=34,rt=35,Fn=37,jn=38,Un=39,Yn=42,kr=44,Kn=45,Oe=58,Wn=61,Qn=62,Xn=63,Zn=64,Tr=91,$r=93,Jn=96,Ar=123,ea=124,_r=125,$={};$[0]="\\0";$[7]="\\a";$[8]="\\b";$[9]="\\t";$[10]="\\n";$[11]="\\v";$[12]="\\f";$[13]="\\r";$[27]="\\e";$[34]='\\"';$[92]="\\\\";$[133]="\\N";$[160]="\\_";$[8232]="\\L";$[8233]="\\P";var ta=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],ra=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;function ia(e,n){var t,r,i,a,o,s,l;if(n===null)return{};for(t={},r=Object.keys(n),i=0,a=r.length;i<a;i+=1)o=r[i],s=String(n[o]),o.slice(0,2)==="!!"&&(o="tag:yaml.org,2002:"+o.slice(2)),l=e.compiledTypeMap.fallback[o],l&&Sr.call(l.styleAliases,s)&&(s=l.styleAliases[s]),t[o]=s;return t}function na(e){var n,t,r;if(n=e.toString(16).toUpperCase(),e<=255)t="x",r=2;else if(e<=65535)t="u",r=4;else if(e<=4294967295)t="U",r=8;else throw new A("code point within a string may not be greater than 0xFFFFFFFF");return"\\"+t+C.repeat("0",r-n.length)+n}var aa=1,fe=2;function oa(e){this.schema=e.schema||st,this.indent=Math.max(1,e.indent||2),this.noArrayIndent=e.noArrayIndent||!1,this.skipInvalid=e.skipInvalid||!1,this.flowLevel=C.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=ia(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.condenseFlow=e.condenseFlow||!1,this.quotingType=e.quotingType==='"'?fe:aa,this.forceQuotes=e.forceQuotes||!1,this.replacer=typeof e.replacer=="function"?e.replacer:null,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function zt(e,n){for(var t=C.repeat(" ",n),r=0,i=-1,a="",o,s=e.length;r<s;)i=e.indexOf(`
1846
+ `,r),i===-1?(o=e.slice(r),r=s):(o=e.slice(r,i+1),r=i+1),o.length&&o!==`
1847
+ `&&(a+=t),a+=o;return a}function it(e,n){return`
1848
+ `+C.repeat(" ",e.indent*n)}function sa(e,n){var t,r,i;for(t=0,r=e.implicitTypes.length;t<r;t+=1)if(i=e.implicitTypes[t],i.resolve(n))return!0;return!1}function Ve(e){return e===Nn||e===Hn}function be(e){return 32<=e&&e<=126||161<=e&&e<=55295&&e!==8232&&e!==8233||57344<=e&&e<=65533&&e!==dt||65536<=e&&e<=1114111}function Ht(e){return be(e)&&e!==dt&&e!==Gn&&e!==me}function Gt(e,n,t){var r=Ht(e),i=r&&!Ve(e);return(t?r:r&&e!==kr&&e!==Tr&&e!==$r&&e!==Ar&&e!==_r)&&e!==rt&&!(n===Oe&&!i)||Ht(n)&&!Ve(n)&&e===rt||n===Oe&&i}function la(e){return be(e)&&e!==dt&&!Ve(e)&&e!==Kn&&e!==Xn&&e!==Oe&&e!==kr&&e!==Tr&&e!==$r&&e!==Ar&&e!==_r&&e!==rt&&e!==jn&&e!==Yn&&e!==On&&e!==ea&&e!==Wn&&e!==Qn&&e!==Un&&e!==Vn&&e!==Fn&&e!==Zn&&e!==Jn}function ca(e){return!Ve(e)&&e!==Oe}function he(e,n){var t=e.charCodeAt(n),r;return t>=55296&&t<=56319&&n+1<e.length&&(r=e.charCodeAt(n+1),r>=56320&&r<=57343)?(t-55296)*1024+r-56320+65536:t}function Ir(e){var n=/^\n* /;return n.test(e)}var Mr=1,nt=2,Lr=3,Dr=4,Y=5;function da(e,n,t,r,i,a,o,s){var l,c=0,d=null,u=!1,p=!1,h=r!==-1,g=-1,m=la(he(e,0))&&ca(he(e,e.length-1));if(n||o)for(l=0;l<e.length;c>=65536?l+=2:l++){if(c=he(e,l),!be(c))return Y;m=m&&Gt(c,d,s),d=c}else{for(l=0;l<e.length;c>=65536?l+=2:l++){if(c=he(e,l),c===me)u=!0,h&&(p=p||l-g-1>r&&e[g+1]!==" ",g=l);else if(!be(c))return Y;m=m&&Gt(c,d,s),d=c}p=p||h&&l-g-1>r&&e[g+1]!==" "}return!u&&!p?m&&!o&&!i(e)?Mr:a===fe?Y:nt:t>9&&Ir(e)?Y:o?a===fe?Y:nt:p?Dr:Lr}function ua(e,n,t,r,i){e.dump=function(){if(n.length===0)return e.quotingType===fe?'""':"''";if(!e.noCompatMode&&(ta.indexOf(n)!==-1||ra.test(n)))return e.quotingType===fe?'"'+n+'"':"'"+n+"'";var a=e.indent*Math.max(1,t),o=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-a),s=r||e.flowLevel>-1&&t>=e.flowLevel;function l(c){return sa(e,c)}switch(da(n,s,e.indent,o,l,e.quotingType,e.forceQuotes&&!r,i)){case Mr:return n;case nt:return"'"+n.replace(/'/g,"''")+"'";case Lr:return"|"+Nt(n,e.indent)+Ot(zt(n,a));case Dr:return">"+Nt(n,e.indent)+Ot(zt(pa(n,o),a));case Y:return'"'+ha(n)+'"';default:throw new A("impossible error: invalid scalar style")}}()}function Nt(e,n){var t=Ir(e)?String(n):"",r=e[e.length-1]===`
1849
+ `,i=r&&(e[e.length-2]===`
1850
+ `||e===`
1851
+ `),a=i?"+":r?"":"-";return t+a+`
1852
+ `}function Ot(e){return e[e.length-1]===`
1853
+ `?e.slice(0,-1):e}function pa(e,n){for(var t=/(\n+)([^\n]*)/g,r=function(){var c=e.indexOf(`
1854
+ `);return c=c!==-1?c:e.length,t.lastIndex=c,Vt(e.slice(0,c),n)}(),i=e[0]===`
1855
+ `||e[0]===" ",a,o;o=t.exec(e);){var s=o[1],l=o[2];a=l[0]===" ",r+=s+(!i&&!a&&l!==""?`
1856
+ `:"")+Vt(l,n),i=a}return r}function Vt(e,n){if(e===""||e[0]===" ")return e;for(var t=/ [^ ]/g,r,i=0,a,o=0,s=0,l="";r=t.exec(e);)s=r.index,s-i>n&&(a=o>i?o:s,l+=`
1857
+ `+e.slice(i,a),i=a+1),o=s;return l+=`
1858
+ `,e.length-i>n&&o>i?l+=e.slice(i,o)+`
1859
+ `+e.slice(o+1):l+=e.slice(i),l.slice(1)}function ha(e){for(var n="",t=0,r,i=0;i<e.length;t>=65536?i+=2:i++)t=he(e,i),r=$[t],!r&&be(t)?(n+=e[i],t>=65536&&(n+=e[i+1])):n+=r||na(t);return n}function ga(e,n,t){var r="",i=e.tag,a,o,s;for(a=0,o=t.length;a<o;a+=1)s=t[a],e.replacer&&(s=e.replacer.call(t,String(a),s)),(q(e,n,s,!1,!1)||typeof s>"u"&&q(e,n,null,!1,!1))&&(r!==""&&(r+=","+(e.condenseFlow?"":" ")),r+=e.dump);e.tag=i,e.dump="["+r+"]"}function Ft(e,n,t,r){var i="",a=e.tag,o,s,l;for(o=0,s=t.length;o<s;o+=1)l=t[o],e.replacer&&(l=e.replacer.call(t,String(o),l)),(q(e,n+1,l,!0,!0,!1,!0)||typeof l>"u"&&q(e,n+1,null,!0,!0,!1,!0))&&((!r||i!=="")&&(i+=it(e,n)),e.dump&&me===e.dump.charCodeAt(0)?i+="-":i+="- ",i+=e.dump);e.tag=a,e.dump=i||"[]"}function ma(e,n,t){var r="",i=e.tag,a=Object.keys(t),o,s,l,c,d;for(o=0,s=a.length;o<s;o+=1)d="",r!==""&&(d+=", "),e.condenseFlow&&(d+='"'),l=a[o],c=t[l],e.replacer&&(c=e.replacer.call(t,l,c)),q(e,n,l,!1,!1)&&(e.dump.length>1024&&(d+="? "),d+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),q(e,n,c,!1,!1)&&(d+=e.dump,r+=d));e.tag=i,e.dump="{"+r+"}"}function fa(e,n,t,r){var i="",a=e.tag,o=Object.keys(t),s,l,c,d,u,p;if(e.sortKeys===!0)o.sort();else if(typeof e.sortKeys=="function")o.sort(e.sortKeys);else if(e.sortKeys)throw new A("sortKeys must be a boolean or a function");for(s=0,l=o.length;s<l;s+=1)p="",(!r||i!=="")&&(p+=it(e,n)),c=o[s],d=t[c],e.replacer&&(d=e.replacer.call(t,c,d)),q(e,n+1,c,!0,!0,!0)&&(u=e.tag!==null&&e.tag!=="?"||e.dump&&e.dump.length>1024,u&&(e.dump&&me===e.dump.charCodeAt(0)?p+="?":p+="? "),p+=e.dump,u&&(p+=it(e,n)),q(e,n+1,d,!0,u)&&(e.dump&&me===e.dump.charCodeAt(0)?p+=":":p+=": ",p+=e.dump,i+=p));e.tag=a,e.dump=i||"{}"}function jt(e,n,t){var r,i,a,o,s,l;for(i=t?e.explicitTypes:e.implicitTypes,a=0,o=i.length;a<o;a+=1)if(s=i[a],(s.instanceOf||s.predicate)&&(!s.instanceOf||typeof n=="object"&&n instanceof s.instanceOf)&&(!s.predicate||s.predicate(n))){if(t?s.multi&&s.representName?e.tag=s.representName(n):e.tag=s.tag:e.tag="?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,Cr.call(s.represent)==="[object Function]")r=s.represent(n,l);else if(Sr.call(s.represent,l))r=s.represent[l](n,l);else throw new A("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');e.dump=r}return!0}return!1}function q(e,n,t,r,i,a,o){e.tag=null,e.dump=t,jt(e,t,!1)||jt(e,t,!0);var s=Cr.call(e.dump),l=r,c;r&&(r=e.flowLevel<0||e.flowLevel>n);var d=s==="[object Object]"||s==="[object Array]",u,p;if(d&&(u=e.duplicates.indexOf(t),p=u!==-1),(e.tag!==null&&e.tag!=="?"||p||e.indent!==2&&n>0)&&(i=!1),p&&e.usedDuplicates[u])e.dump="*ref_"+u;else{if(d&&p&&!e.usedDuplicates[u]&&(e.usedDuplicates[u]=!0),s==="[object Object]")r&&Object.keys(e.dump).length!==0?(fa(e,n,e.dump,i),p&&(e.dump="&ref_"+u+e.dump)):(ma(e,n,e.dump),p&&(e.dump="&ref_"+u+" "+e.dump));else if(s==="[object Array]")r&&e.dump.length!==0?(e.noArrayIndent&&!o&&n>0?Ft(e,n-1,e.dump,i):Ft(e,n,e.dump,i),p&&(e.dump="&ref_"+u+e.dump)):(ga(e,n,e.dump),p&&(e.dump="&ref_"+u+" "+e.dump));else if(s==="[object String]")e.tag!=="?"&&ua(e,e.dump,n,a,l);else{if(s==="[object Undefined]")return!1;if(e.skipInvalid)return!1;throw new A("unacceptable kind of an object to dump "+s)}e.tag!==null&&e.tag!=="?"&&(c=encodeURI(e.tag[0]==="!"?e.tag.slice(1):e.tag).replace(/!/g,"%21"),e.tag[0]==="!"?c="!"+c:c.slice(0,18)==="tag:yaml.org,2002:"?c="!!"+c.slice(18):c="!<"+c+">",e.dump=c+" "+e.dump)}return!0}function ba(e,n){var t=[],r=[],i,a;for(at(e,t,r),i=0,a=r.length;i<a;i+=1)n.duplicates.push(t[r[i]]);n.usedDuplicates=new Array(a)}function at(e,n,t){var r,i,a;if(e!==null&&typeof e=="object")if(i=n.indexOf(e),i!==-1)t.indexOf(i)===-1&&t.push(i);else if(n.push(e),Array.isArray(e))for(i=0,a=e.length;i<a;i+=1)at(e[i],n,t);else for(r=Object.keys(e),i=0,a=r.length;i<a;i+=1)at(e[r[i]],n,t)}function va(e,n){n=n||{};var t=new oa(n);t.noRefs||ba(e,t);var r=e;return t.replacer&&(r=t.replacer.call({"":r},"",r)),q(t,0,r,!0,!0)?t.dump+`
1860
+ `:""}var xa=va,wa={dump:xa};function ut(e,n){return function(){throw new Error("Function yaml."+e+" is removed in js-yaml 4. Use yaml."+n+" instead, which is now safe by default.")}}var ya=T,Ea=Kt,Ca=Zt,Sa=ir,ka=nr,Ta=st,$a=Er.load,Aa=Er.loadAll,_a=wa.dump,Ia=A,Ma={binary:cr,float:rr,map:Xt,null:Jt,pairs:ur,set:pr,timestamp:sr,bool:er,int:tr,merge:lr,omap:dr,seq:Qt,str:Wt},La=ut("safeLoad","load"),Da=ut("safeLoadAll","loadAll"),Ra=ut("safeDump","dump"),Rr={Type:ya,Schema:Ea,FAILSAFE_SCHEMA:Ca,JSON_SCHEMA:Sa,CORE_SCHEMA:ka,DEFAULT_SCHEMA:Ta,load:$a,loadAll:Aa,dump:_a,YAMLException:Ia,types:Ma,safeLoad:La,safeLoadAll:Da,safeDump:Ra};var V=["#10b981","#f59e0b","#06b6d4","#ec4899","#8b5cf6","#3b82f6","#f43f5e","#84cc16","#a855f7","#6366f1"];function S(e){let n=e.length,t;for(;n!==0;)t=Math.floor(Math.random()*n),n--,[e[n],e[t]]=[e[t],e[n]];return e}var R=(e,n=0)=>{let t=3735928559^n,r=1103547991^n;for(let i=0,a;i<e.length;i++)a=e.charCodeAt(i),t=Math.imul(t^a,265443561),r=Math.imul(r^a,159334677);return t=Math.imul(t^r>>>16,2246822507)^Math.imul(r^r>>>13,3266489909),r=Math.imul(r^r>>>16,2246822507)^Math.imul(t^t>>>13,3266489909),(4294967296*(2009751&r)+(t>>>0)).toString()};function E(e){return e.replace(/[&<>"']/g,n=>n==="&"?"&amp;":n==="<"?"&lt;":n===">"?"&gt;":n==='"'?"&quot;":"&#39;")}function is(e){try{return Rr.load(e)}catch(n){throw new Error(`Invalid YAML assets:
1861
+ ${n instanceof Error?n.message:String(n)}`)}}function I(e){return typeof e=="string"}function pt(e){return typeof e=="number"}function ht(e){return/^(\d{1,2}:)?\d{1,2}:\d{2}$/.test(e)}function Pr(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function je(e){return typeof e=="object"&&e!==null&&(Object.getPrototypeOf(e)===Object.prototype||Object.getPrototypeOf(e)===null)}function F(e){return e.split("|").map(n=>n.trim()).filter(Boolean)}var X=e=>[...new Set(e)];function ns(e,n){return n.includes(e)}function Z(e){return E(e)}var Ue=class extends HTMLElement{constructor(){super();this._state={};this._mounted=!1;this.onChange=t=>{let r=t.target,i=r.getAttribute?.("data-r"),a=r.getAttribute?.("data-c");if(!i||!a||!this._config)return;let o=this._config.cellKind,s=null;r instanceof HTMLInputElement&&(o==="checkbox"||o==="radio"?s=r.checked:o==="text"?s=r.value:o==="number"&&(s=r.value===""?null:Number(r.value))),r instanceof HTMLSelectElement&&(s=r.value===""?null:r.value),this.applyCellValue(i,a,s),this.emitChange(i,a,s)};this.onInput=t=>{};this.attachShadow({mode:"open"});let t=document.createElement("section");t.className="wrap",this.shadowRoot.append(t),this.$wrapEl=t}static get observedAttributes(){return["variant"]}connectedCallback(){this._mounted=!0,this.shadowRoot?.addEventListener("change",this.onChange),this.shadowRoot?.addEventListener("input",this.onInput),this.render()}disconnectedCallback(){this._mounted=!1}set config(t){this._config=t,this._state=this.initState(t),t.variant&&this.setAttribute("variant",t.variant),this.render()}get config(){if(!this._config)throw new Error("<edu-table>: spec not set");return this._config}get value(){return this._state}set value(t){this._state=t,this.render()}getValue(){return this._state}setValue(t){this._state=t,this.render()}getState(){let t=this._config;if(!t)return{};let r={};for(let i of t.rows){let a=this._state[i]??{},o=[];for(let s of t.cols){let l=a[s]??null;(t.cellKind==="checkbox"||t.cellKind==="radio")&&l===!0&&o.push(s)}r[i]={selectedCols:o,values:{...a}}}return r}attributeChangedCallback(t,r,i){r!==i&&t==="variant"&&(this.setAttribute("variant",i),this.$wrapEl.querySelectorAll("edu-input").forEach(a=>{a.setAttribute("variant",i)}))}initState(t){let r={};for(let i of t.rows){r[i]={};for(let a of t.cols)switch(t.cellKind){case"checkbox":case"radio":r[i][a]=!1;break;case"select":case"text":case"number":r[i][a]=null;break}}return r}render(){if(!this._mounted||!this.shadowRoot)return;if(!this._config){this.$wrapEl.innerHTML="<style>:host{display:block}</style><div></div>";return}let t=this._config,r=t.shuffle?S(t.cols):t.cols,i=`
1862
+ <tr>
1863
+ <th></th>
1864
+ ${r.map(s=>`<th scope="col">${E(s)}</th>`).join("")}
1865
+ </tr>
1866
+ `,o=(t.shuffle?S(t.rows):t.rows).map(s=>{let l=r.map(c=>this.renderCell(t,s,c)).join("");return`<tr><th scope="row">${E(s)}</th>${l}</tr>`}).join("");this.$wrapEl.innerHTML=`
1867
+ <style>${It}</style>
1868
+ <table part="table">
1869
+ <thead>${i}</thead>
1870
+ <tbody>${o}</tbody>
1871
+ </table>
1872
+ `}renderCell(t,r,i){if(t.disabled?.(r,i)??!1)return'<td aria-disabled="true" class="disabled-cell"></td>';let o=`cell-${R(r)}-${R(i)}`,s=this._state[r]?.[i]??null,l=t.gradingState?.[r]?.[i],c=l?`cell-${l}`:"",d=p=>`<td class="${c}">${p}</td>`,u=`id="${o}" data-r="${Z(r)}" data-c="${Z(i)}"
1873
+ aria-label="${Z(`${r} / ${i}`)}" variant="${this.getAttribute("variant")}" `;switch(t.cellKind){case"checkbox":return d(`<input ${u} type="checkbox" ${s===!0?"checked":""}/>`);case"radio":{let p=s===!0?"checked":"";return d(`<input ${u} type="radio" name="row-${R(r)}" ${p}/>`)}case"text":{let p=s==null?"":String(s);return d(`<edu-input ${u} type="text" value="${Z(p)}"/>`)}case"number":{let p=s==null?"":String(s);return d(`<edu-input ${u} type="number" value="${Z(p)}"/>`)}case"select":{let p=t.allowed?.(r,i)??[],h=s==null?"":String(s),g=['<option value=""></option>',...p.map(m=>{let b=String(m),w=b===h?"selected":"";return`<option value="${Z(b)}" ${w}>${E(b)}</option>`})].join("");return d(`<edu-input as="select" ${u}>${g}</select>`)}}}reset(){this._config&&(this._state=this.initState(this._config),this.render(),this.dispatchEvent(new CustomEvent("reset",{bubbles:!0,composed:!0})))}setGradingState(t){this._config&&(this._config.gradingState=t,this.render())}clearGradingState(){this._config&&(this._config.gradingState=void 0,this.render())}applyCellValue(t,r,i){let a=this._config;if(a&&!a.disabled?.(t,r)){if(a.cellKind==="select"){let o=a.allowed?.(t,r);if(o&&i!==null&&!o.some(s=>String(s)===String(i)))return}if(this._state[t]??={},this._config.cellKind==="radio"&&i===!0){for(let o of this._config.cols)this._state[t][o]=!1;this._state[t][r]=!0;return}this._state[t][r]=i}}emitChange(t,r,i){let a={row:t,col:r,value:i,state:this.getValue(),selection:this.getState()};this.dispatchEvent(new CustomEvent("change",{detail:a,bubbles:!0,composed:!0}))}};customElements.get("edu-table")||customElements.define("edu-table",Ue);var Pa=/\[([^\]]+)\]/g,qa=/^\s*(-?\d+)\s*(\.\.)\s*(-?\d+)\s*$/,Ba=/^\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])$/,za=/^([01]\d|2[0-3]):[0-5]\d$/,qr=e=>{let n=F(e);if(n.length===0||n.some(a=>!a))return{ok:!1,data:null,errors:{"@tx":"provide at least one non-empty answer."}};let t=X(n),r=`text-${R(e)}`,i=`<edu-input type="text" id="${r}" variant="outline" autocomplete="off"></edu-input>`;return{ok:!0,data:{type:"text",id:r,value:t,html:i},errors:null}},Br=e=>{let t=[...e.matchAll(Pa)].flatMap(c=>F(c[1])),r=e.replace(/\[|\]/g,""),i=[" ",...S(X(F(r)))];if(i.length===0)return{ok:!1,data:null,errors:{"@sl":"provide at least one option for the select."}};if(t.length===0)return{ok:!1,data:null,errors:{"@sl":"Mark at least one correct option inside of square brackets."}};let a=[...i],o=`select-${R(e)}-${Math.random().toString(36).slice(2)}`,s=a.map(c=>`<option>${c}</option>`).join(""),l=`<edu-input as="select" id="${o}" variant="outline">${s}</edu-input>`;return{ok:!0,data:{type:"select",id:o,correctOptions:t,options:i,html:l},errors:null}},zr=e=>{let n=F(e);if(n.length===0||n.some(o=>!o.trim()))return{ok:!1,data:null,errors:{"@nm":"provide at least one non-empty option."}};let t=[],r=[];for(let o of n){let s=o.match(qa);if(s){let l=parseInt(s[1],10),c=parseInt(s[3],10);if(Number.isNaN(l)||Number.isNaN(c)||l>c)return{ok:!1,data:null,errors:{"@nm":"Invalid range ${t}"}};r.push({from:l,to:c})}else{let l=Number(o.trim());if(!Number.isInteger(l))return{ok:!1,data:null,errors:{"@nm":"${t} is not an integer."}};t.push(l)}}let i=`number-${R(e)}-${Math.random().toString(36).slice(2)}`,a=`<edu-input type="number" variant="outline" id="${i}"></edu-input>`;return{ok:!0,data:{type:"number",id:i,targets:X(t),ranges:r,html:a},errors:null}},Hr=e=>{let n=F(e);if(n.length===0||n.some(o=>!o.trim()))return{ok:!1,data:null,errors:{"@dt":"provide at least one non-empty date option."}};let t=[];for(let o of n){let s=o.trim();if(!Ba.test(s))return{ok:!1,data:null,errors:{"@dt":`"${s}" is not a valid date. Expected format: YYYY/MM/DD`}};t.push(s)}let r=X(t),i=`date-${R(e)}`,a=`<edu-input type="date" id="${i}" variant="outline"></edu-input>`;return{ok:!0,data:{type:"date",id:i,value:r[0],html:a},errors:null}},Gr=e=>{let n=F(e);if(n.length===0||n.some(o=>!o.trim()))return{ok:!1,data:null,errors:{"@tm":"provide at least one non-empty time option."}};let t=[];for(let o of n){let s=o.trim();if(!za.test(s))return{ok:!1,data:null,errors:{"@tm":`"${s}" is not a valid time. Expected format: HH:MM (24-hour)`}};t.push(s)}let r=X(t),i=`time-${R(e)}`,a=`<edu-input type="time" id="${i}" variant="outline"></edu-input>`;return{ok:!0,data:{type:"time",id:i,value:r[0],html:a},errors:null}};function Nr(e){return e.trim().split(";;")}var Or=["tx","nm","sl","dt","tm"],Ha={tx:qr,nm:zr,sl:Br,dt:Hr,tm:Gr},Vr=e=>{let n=[],t=[],r={},i,a=/^\s*=\s*\[([^\]]+)\]\s*;/m,o=e.match(a);o&&(i=o[1].split("|").map(h=>h.trim().replace(/^["']|["']$/g,"")).filter(Boolean),e=e.replace(a,""));let s="",l=!1,c=null,d=0;for(;d<e.length;){let p=e[d];if(d+1<e.length&&p==="["&&e[d+1]==="["){s+="[",d+=2;continue}if(p==="["){s.trim().length>0&&(n.push(s.trim()),s=""),l=!0,c={words:[],startPos:n.length,endPos:n.length},d++;continue}if(p==="]"){if(!l){r[`at:${d}`]="Unexpected closing bracket ']' without matching opening bracket.",d++;continue}if(s.trim().length>0){let h=s.trim();c.words.push(h),n.push(h),s=""}c.words.length===0?r[`at:${d}`]="Empty brackets [] are not allowed as targets.":(c.endPos=n.length-1,t.push(c)),c=null,l=!1,d++;continue}if(p===" "||p===`
1874
+ `||p===" "||p==="\r"){if(s.trim().length>0){let h=s.trim();l&&c.words.push(h),n.push(h),s=""}d++;continue}s+=p,d++}if(s.trim().length>0){let p=s.trim();l&&(c.words.push(p),c.endPos=n.length,t.push(c)),n.push(p)}l&&(r.unclosed="Unclosed opening bracket '['. Expected ']'.");let u=Object.keys(r).length>0;return{ok:!u,data:{type:"base",parts:n,targets:t,...i&&{distractors:i}},errors:u?r:null}},Fr=e=>{let n={},t=[],r=[],i="",a=0;for(;a<e.length;){let s=e[a];if(a+1<e.length&&s==="@"&&e[a+1]==="@"){i+="@",a+=2;continue}if(s!=="@"){if(s===" "||s===`
1875
+ `||s===" "||s==="\r"){i.trim().length>0&&(t.push(i.trim()),i=""),a++;continue}i+=s,a++;continue}i.trim().length>0&&(t.push(i.trim()),i="");let l=a;a++;let c="";for(;a<e.length&&/[a-z]/i.test(e[a]);)c+=e[a++];if(!c||!Or.includes(c)){n[`at:${l}`]=`Invalid element reference "@${c}". Expected one of: ${Or.join(", ")}.`;continue}if(a>=e.length||e[a]!=="("){n[`at:${l}`]=`Expected '(' after @${c} at position ${a}.`;continue}a++;let d="",u=!1;for(;a<e.length;){if(e[a]===")"){u=!0,a++;break}d+=e[a++]}if(!u){n[`at:${l}`]=`Unclosed parenthesis for @${c}. Expected ')'.`;continue}let p=Ha[c];if(!p){n[`at:${l}`]=`No parser found for @${c}.`;continue}let h=p(d);if(!h.ok){n[`at:${l}`]=h.errors?JSON.stringify(h.errors):`Failed to parse @${c}(${d})`;continue}t.push(h.data.html);let g={id:h.data.id,expectedValue:h.data};r.push(g)}i.trim().length>0&&t.push(i.trim());let o=Object.keys(n).length>0;return{ok:!o,data:{type:"blanks",parts:t,targets:r},errors:o?n:null}},jr=e=>{let n=[],t={},r=new Map,i="",a=0;for(;a<e.length;){let l=e[a];if(a+1<e.length&&l==="@"&&e[a+1]==="@"){i+="@",a+=2;continue}if(l!=="@"){if(l===" "||l===`
1876
+ `||l===" "||l==="\r"){i.trim().length>0&&(n.push(i.trim()),i=""),a++;continue}i+=l,a++;continue}i.trim().length>0&&(n.push(i.trim()),i="");let c=a;a++;let d="";for(;a<e.length&&/[a-z]/i.test(e[a]);)d+=e[a++];if(d!=="ct"){t[`at:${c}`]=`Invalid reference "@${d}". Expected "@ct" for classification.`;continue}if(a>=e.length||e[a]!=="("){t[`at:${c}`]=`Expected '(' after @ct at position ${a}.`;continue}a++;let u="",p=!1;for(;a<e.length;){if(e[a]===")"){p=!0,a++;break}u+=e[a++]}if(!p){t[`at:${c}`]="Unclosed parenthesis for @ct. Expected ')'.";continue}let h=u.split(",").map(U=>U.trim());if(h.length!==2){t[`at:${c}`]=`Invalid @ct syntax. Expected: @ct(category, word). Got: @ct(${u})`;continue}let[g,m]=h;if(!g||!m){t[`at:${c}`]=`Category and word cannot be empty in @ct(${u}).`;continue}let b=m.split(/\s+/).filter(Boolean),w=n.length;for(let U of b)n.push(U);let v=n.length-1,P={words:b,startPos:w,endPos:v};r.has(g)||r.set(g,[]),r.get(g).push(P)}i.trim().length>0&&n.push(i.trim());let o=[];for(let[l,c]of r.entries())o.push({category:l,targets:c});let s=Object.keys(t).length>0;return{ok:!s,data:{type:"classification",parts:n,targets:o},errors:s?t:null}},Ga={base:Vr,blanks:Fr,classification:jr};function Na(e,n){let t=Nr(e),r=Ga[n],i=[],a=[];for(let o of t){let s=r(o);if(!s.ok){s.errors&&(Array.isArray(s.errors)?a.push(...s.errors):a.push(s.errors));continue}i.push(s.data)}return a.length>0?{ok:!1,data:null,errors:a}:{ok:!0,data:i,errors:null}}function Ur(e){let n={};if((!e.parts||e.parts.length===0)&&(n["parts.empty"]="No parts found. Text must contain at least one word."),(!e.targets||e.targets.length===0)&&(n["targets.empty"]="No targets found. Text must contain at least one [target] to interact with."),e.targets&&e.targets.length>0&&e.parts&&e.parts.length>0)for(let t=0;t<e.targets.length;t++){let r=e.targets[t],i=`targets[${t}]`;if(!r.words||r.words.length===0){n[`${i}.words.empty`]=`Target ${t} has no words. Each target must contain at least one word.`;continue}if(r.startPos<0&&(n[`${i}.startPos.negative`]=`Target ${t} has negative startPos (${r.startPos}).`),r.endPos<0&&(n[`${i}.endPos.negative`]=`Target ${t} has negative endPos (${r.endPos}).`),r.startPos>r.endPos&&(n[`${i}.position.invalid`]=`Target ${t} has startPos (${r.startPos}) greater than endPos (${r.endPos}).`),r.startPos>=e.parts.length&&(n[`${i}.startPos.outOfBounds`]=`Target ${t} startPos (${r.startPos}) is out of bounds (parts length: ${e.parts.length}).`),r.endPos>=e.parts.length&&(n[`${i}.endPos.outOfBounds`]=`Target ${t} endPos (${r.endPos}) is out of bounds (parts length: ${e.parts.length}).`),r.startPos<e.parts.length&&r.endPos<e.parts.length){let a=r.endPos-r.startPos+1;r.words.length!==a&&(n[`${i}.words.countMismatch`]=`Target ${t} has ${r.words.length} words but position range indicates ${a} words.`);for(let o=0;o<r.words.length;o++){let s=r.startPos+o;if(s<e.parts.length){let l=e.parts[s],c=r.words[o];l!==c&&(n[`${i}.words[${o}].mismatch`]=`Target ${t} word "${c}" doesn't match part at position ${s}: "${l}".`)}}}}if(e.distractors)if(!Array.isArray(e.distractors))n["distractors.notArray"]="Distractors must be an array.";else{e.distractors.length===0&&(n["distractors.empty"]="Distractors array is empty. Remove distractors field or add at least one distractor.");let t=new Set;for(let r=0;r<e.distractors.length;r++){let i=e.distractors[r];t.has(i)&&(n[`distractors[${r}].duplicate`]=`Duplicate distractor found: "${i}".`),t.add(i),(!i||i.trim().length===0)&&(n[`distractors[${r}].empty`]=`Distractor at index ${r} is empty.`)}}return Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0,errors:null}}function Yr(e){let n={};(!e.parts||e.parts.length===0)&&(n["parts.empty"]="No parts found. Text must contain at least one part."),(!e.targets||e.targets.length===0)&&(n["targets.empty"]="No targets found. Text must contain at least one input element (@tx, @nm, @sl, @dt, @tm).");let t=new Set;if(e.targets&&e.targets.length>0)for(let r=0;r<e.targets.length;r++){let i=e.targets[r],a=`targets[${r}]`;if(!i.id||i.id.trim().length===0?n[`${a}.id.empty`]=`Target ${r} has no ID. Each input element must have a unique ID.`:(t.has(i.id)&&(n[`${a}.id.duplicate`]=`Duplicate ID found: "${i.id}". Each input element must have a unique ID.`),t.add(i.id)),!i.expectedValue){n[`${a}.expectedValue.missing`]=`Target ${r} has no expectedValue. Each input element must define expected answer data.`;continue}let o=i.expectedValue;o.type||(n[`${a}.expectedValue.type.missing`]=`Target ${r} expectedValue has no type field.`),o.id||(n[`${a}.expectedValue.id.missing`]=`Target ${r} expectedValue has no id field.`),o.html||(n[`${a}.expectedValue.html.missing`]=`Target ${r} expectedValue has no html field.`);let s=o.type;if(s)switch(s){case"text":(!("value"in o)||!Array.isArray(o.value))&&(n[`${a}.expectedValue.text.value`]=`Target ${r} is type 'text' but has no valid 'value' array.`);break;case"number":"targets"in o||(n[`${a}.expectedValue.number.targets`]=`Target ${r} is type 'number' but has no 'targets' field.`);break;case"select":(!("correctOptions"in o)||!("options"in o))&&(n[`${a}.expectedValue.select.options`]=`Target ${r} is type 'select' but is missing 'correctOptions' or 'options' fields.`);break;case"date":case"time":"value"in o||(n[`${a}.expectedValue.${s}.value`]=`Target ${r} is type '${s}' but has no 'value' field.`);break}}return Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0,errors:null}}function Kr(e){let n={};(!e.parts||e.parts.length===0)&&(n["parts.empty"]="No parts found. Text must contain at least one word."),(!e.targets||e.targets.length===0)&&(n["targets.empty"]="No categories found. Text must contain at least one @ct(category, word) reference.");let t=new Set;if(e.targets&&e.targets.length>0)for(let r=0;r<e.targets.length;r++){let i=e.targets[r],a=`targets[${r}]`;if(!i.category||i.category.trim().length===0?n[`${a}.category.empty`]=`Category ${r} has no name.`:(t.has(i.category)&&(n[`${a}.category.duplicate`]=`Duplicate category found: "${i.category}". Each category must have a unique name.`),t.add(i.category)),!i.targets||i.targets.length===0){n[`${a}.targets.empty`]=`Category "${i.category}" has no targets. Each category must contain at least one word.`;continue}for(let o=0;o<i.targets.length;o++){let s=i.targets[o],l=`${a}.targets[${o}]`;if(!s.words||s.words.length===0){n[`${l}.words.empty`]=`Category "${i.category}" target ${o} has no words.`;continue}if(s.startPos<0&&(n[`${l}.startPos.negative`]=`Category "${i.category}" target ${o} has negative startPos.`),s.endPos<0&&(n[`${l}.endPos.negative`]=`Category "${i.category}" target ${o} has negative endPos.`),s.startPos>s.endPos&&(n[`${l}.position.invalid`]=`Category "${i.category}" target ${o} has startPos greater than endPos.`),e.parts&&e.parts.length>0&&(s.startPos>=e.parts.length&&(n[`${l}.startPos.outOfBounds`]=`Category "${i.category}" target ${o} startPos is out of bounds.`),s.endPos>=e.parts.length&&(n[`${l}.endPos.outOfBounds`]=`Category "${i.category}" target ${o} endPos is out of bounds.`),s.startPos<e.parts.length&&s.endPos<e.parts.length)){let c=s.endPos-s.startPos+1;s.words.length!==c&&(n[`${l}.words.countMismatch`]=`Category "${i.category}" target ${o} word count mismatch.`)}}}return Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0,errors:null}}function Oa(e){switch(e.type){case"base":return Ur(e);case"blanks":return Yr(e);case"classification":return Kr(e);default:return{ok:!1,errors:{"type.invalid":`Unknown text engine type: ${e.type}`}}}}function ve(e,n){let t=new Set(n.selectedIndices??[]),r=new Set;for(let p of e.targets)for(let h=p.startPos;h<=p.endPos;h++)r.add(h);let i=0,a=0,o=0;for(let p=0;p<e.parts.length;p++){let h=r.has(p),g=t.has(p);h&&g?i++:h&&!g?o++:!h&&g&&a++}let s=r.size,l=i+a>0?i/(i+a):0,c=i+o>0?i/(i+o):0,d=l+c>0?2*l*c/(l+c):0;return{score:Math.round(d*100),correct:i,total:s}}function Va(e,n){let t=new Set,r=n.dndPlacements??{};for(let l of e.targets)for(let c=l.startPos;c<=l.endPos;c++)t.add(c);let i=0;if(Object.keys(r).length>0)for(let l of t){let c=e.parts[l],d=r[l];d&&Ye(d)===Ye(c)&&i++}else{let l=new Set(n.placedIndices??[]);for(let c of l)t.has(c)&&i++}let o=t.size;return{score:o>0?Math.round(i/o*100):0,correct:i,total:o}}function Fa(e,n){let t={},r=n.dndPlacements??{};for(let i of e.targets)for(let a=i.startPos;a<=i.endPos;a++){let o=e.parts[a],s=r[a];s?Ye(s)===Ye(o)?t[a]="correct":t[a]="wrong":t[a]="missed"}return t}function xe(e,n,t){let r=n.transformations??{},i=0,a=0;for(let s=0;s<e.targets.length;s++){let l=t[s],c=r[s];l&&(a++,c&&l.length===c.length&&l.every((u,p)=>u.toLowerCase().trim()===(c[p]||"").toLowerCase().trim())&&i++)}return{score:a>0?Math.round(i/a*100):0,correct:i,total:a}}function gt(e,n,t){let r=n.transformations??{},i={};for(let a=0;a<e.targets.length;a++){let o=t[a],s=r[a];if(!o){i[a]="missed";continue}if(!s||s.length===0){i[a]="missed";continue}if(o.length===s.length){let l=o.every((c,d)=>c.toLowerCase().trim()===(s[d]||"").toLowerCase().trim());i[a]=l?"correct":"wrong"}else i[a]="wrong"}return i}function we(e,n){let t=new Set(n.selectedIndices??[]),r=new Set,i={};for(let a of e.targets)for(let o=a.startPos;o<=a.endPos;o++)r.add(o);for(let a=0;a<e.parts.length;a++){let o=r.has(a),s=t.has(a);o&&s?i[a]="correct":o&&!s?i[a]="missed":!o&&s&&(i[a]="wrong")}return i}function ye(e,n){let t=0,r=e.targets.length;for(let a of e.targets){let o=n.inputValues[a.id],s=a.expectedValue;Xr(s,o)&&t++}return{score:r>0?Math.round(t/r*100):0,correct:t,total:r}}function Ee(e,n){let t={};for(let r of e.targets){let i=n.inputValues[r.id],a=r.expectedValue;i==null||i===""?t[r.id]="missed":Xr(a,i)?t[r.id]="correct":t[r.id]="wrong"}return t}function Xr(e,n){if(n==null||n==="")return!1;switch(e.type){case"text":{let t=String(n).toLowerCase().trim();return e.value.some(r=>r.toLowerCase().trim()===t)}case"number":{let t=Number(n);return isNaN(t)?!1:e.targets.includes(t)?!0:e.ranges?e.ranges.some(r=>t>=r.from&&t<=r.to):!1}case"select":{let t=String(n).trim();return e.correctOptions.some(r=>String(r).trim()===t)}case"date":{let t=Wr(String(e.value)),r=Wr(String(n));return t.length>0&&t===r}case"time":{let t=Qr(String(e.value)),r=Qr(String(n));return t.length>0&&t===r}default:return!1}}function Ye(e){return String(e).trim().toLowerCase()}function Wr(e){return String(e).trim().replace(/\//g,"-")}function Qr(e){let n=String(e).trim(),t=n.match(/^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/);return t?`${t[1]}:${t[2]}`:n}function Ce(e,n){let t=0,r=0,i=new Map;for(let o of e.targets)for(let s of o.targets)for(let l=s.startPos;l<=s.endPos;l++)i.set(l,o.category),r++;for(let[o,s]of Object.entries(n.wordCategories)){let l=Number(o),c=i.get(l);c&&s===c&&t++}return{score:r>0?Math.round(t/r*100):0,correct:t,total:r}}function Se(e,n){let t={},r=new Map;for(let i of e.targets)for(let a of i.targets)for(let o=a.startPos;o<=a.endPos;o++)r.set(o,i.category);for(let[i,a]of r){let o=n.wordCategories[i];o?o===a?t[i]="correct":t[i]="wrong":t[i]="missed"}return t}var Zr=`/* ==================== BASE STYLES ==================== */
1877
+
1878
+ * { box-sizing: border-box; }
1879
+
1880
+ :host {
1881
+ display: block;
1882
+ height: 100%;
1883
+ font-family: system-ui, -apple-system, sans-serif;
1884
+ font-size: clamp(0.92rem, 0.3vw + 0.88rem, 1.05rem);
1885
+ line-height: 2.7;
1886
+ --text-accent: rgb(var(--edu-first-accent));
1887
+ }
1888
+
1889
+ .wrap {
1890
+ padding: clamp(0.6rem, 1.6vw, var(--edu-pad));
1891
+ height: 100%;
1892
+ }
1893
+
1894
+ .text-content {
1895
+ display: block;
1896
+ height: 100%;
1897
+ user-select: none;
1898
+ }
1899
+
1900
+ /* ==================== WORD STYLES ==================== */
1901
+
1902
+ .word {
1903
+ display: inline;
1904
+ margin: 0 0.15rem;
1905
+ padding: 0.15rem 0.25rem;
1906
+ border-radius: var(--edu-radius);
1907
+ transition: all 0.2s ease;
1908
+ overflow-wrap: anywhere;
1909
+ color: rgb(var(--edu-ink));
1910
+ font-weight: 500;
1911
+ }
1912
+
1913
+ /* Selectable words (highlight mode) */
1914
+ .word-selectable {
1915
+ cursor: pointer;
1916
+ background: rgba(var(--edu-muted), 0.5);
1917
+ border: 2px solid rgb(var(--edu-border));
1918
+ color: rgb(var(--edu-ink));
1919
+ }
1920
+
1921
+ .word-selectable:hover {
1922
+ background: rgba(var(--edu-first-accent), 0.15);
1923
+ border-color: rgba(var(--edu-first-accent), 0.5);
1924
+ transform: translateY(-1px);
1925
+ }
1926
+
1927
+ .word-selected {
1928
+ background: rgba(var(--edu-first-accent), 0.25);
1929
+ border-color: var(--text-accent);
1930
+ border-width: 2px;
1931
+ font-weight: 500;
1932
+ color: var(--text-accent);
1933
+ box-shadow: 0 2px 4px rgba(var(--edu-shadow-color), 0.1);
1934
+ }
1935
+
1936
+ /* Editable words (transformation mode) */
1937
+ .word-editable {
1938
+ cursor: text;
1939
+ background: rgb(var(--edu-card));
1940
+ border: 1px solid rgb(var(--edu-border));
1941
+ padding: 0.25rem 0.5rem;
1942
+ min-width: 3ch;
1943
+ outline: none;
1944
+ color: rgb(var(--edu-ink));
1945
+ }
1946
+
1947
+ .word-editable:hover {
1948
+ border-color: rgb(var(--edu-second-ink));
1949
+ }
1950
+
1951
+ .word-editable:focus {
1952
+ border-color: var(--text-accent);
1953
+ background: rgb(var(--edu-card));
1954
+ }
1955
+
1956
+ /* Classifiable words */
1957
+ .word-classifiable {
1958
+ cursor: pointer;
1959
+ position: relative;
1960
+ background: rgb(var(--edu-muted));
1961
+ border: 1px solid rgb(var(--edu-border));
1962
+ color: rgb(var(--edu-ink));
1963
+ }
1964
+
1965
+ .word-classifiable:hover {
1966
+ background: rgb(var(--edu-border));
1967
+ border-color: rgb(var(--edu-second-ink));
1968
+ }
1969
+
1970
+ .word-assigned {
1971
+ background: rgba(var(--category-color), 0.2);
1972
+ border-color: rgb(var(--category-color));
1973
+ font-weight: 600;
1974
+ color: rgb(var(--category-color));
1975
+ }
1976
+
1977
+ /* ==================== GRADING STATES ==================== */
1978
+
1979
+ .word-correct {
1980
+ background: rgba(var(--edu-success), 0.2) !important;
1981
+ border-color: rgb(var(--edu-success)) !important;
1982
+ color: rgb(var(--edu-success));
1983
+ }
1984
+
1985
+ .word-wrong {
1986
+ background: rgba(var(--edu-error), 0.2) !important;
1987
+ border-color: rgb(var(--edu-error)) !important;
1988
+ color: rgb(var(--edu-error));
1989
+ }
1990
+
1991
+ .word-missed {
1992
+ background: rgba(var(--edu-warning), 0.2) !important;
1993
+ border-color: rgb(var(--edu-warning)) !important;
1994
+ color: rgb(var(--edu-second-ink));
1995
+ }
1996
+
1997
+ .input-correct {
1998
+ border-color: rgb(var(--edu-success)) !important;
1999
+ background: rgba(var(--edu-success), 0.1) !important;
2000
+ }
2001
+
2002
+ .input-wrong {
2003
+ border-color: rgb(var(--edu-error)) !important;
2004
+ background: rgba(var(--edu-error), 0.1) !important;
2005
+ }
2006
+
2007
+ .input-missed {
2008
+ border-color: rgb(var(--edu-warning)) !important;
2009
+ background: rgba(var(--edu-warning), 0.1) !important;
2010
+ }
2011
+
2012
+ /* ==================== CLASSIFICATION MODE ==================== */
2013
+
2014
+ .categories {
2015
+ display: flex;
2016
+ gap: 0.5rem;
2017
+ flex-wrap: wrap;
2018
+ justify-content: center;
2019
+ align-items: stretch;
2020
+ padding-top: 1rem;
2021
+ margin-top: auto;
2022
+ }
2023
+
2024
+ .category-btn {
2025
+ min-width: 110px;
2026
+ flex: 0 1 auto;
2027
+ cursor: pointer;
2028
+ }
2029
+
2030
+ .category-btn::part(block) {
2031
+ padding: 0.45rem 0.8rem;
2032
+ min-height: 40px;
2033
+ border-width: 2px;
2034
+ border-color: rgb(var(--edu-border));
2035
+ background: rgb(var(--edu-card));
2036
+ color: rgb(var(--edu-ink));
2037
+ transition: all 0.2s ease;
2038
+ }
2039
+
2040
+ .category-btn:hover {
2041
+ transform: translateY(-1px);
2042
+ }
2043
+
2044
+ .category-btn.category-active::part(block) {
2045
+ border-color: var(--category-color);
2046
+ background: color-mix(in srgb, var(--category-color) 18%, rgb(var(--edu-card)));
2047
+ color: var(--category-color);
2048
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--category-color) 28%, transparent);
2049
+ }
2050
+
2051
+ .category-btn[data-active="true"]::part(block) {
2052
+ border-color: var(--category-color);
2053
+ background: color-mix(in srgb, var(--category-color) 18%, rgb(var(--edu-card)));
2054
+ color: var(--category-color);
2055
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--category-color) 28%, transparent);
2056
+ }
2057
+
2058
+ .words {
2059
+ display: block;
2060
+ line-height: 2.2;
2061
+ flex: 1;
2062
+ overflow-y: auto;
2063
+ min-height: 0;
2064
+ }
2065
+
2066
+ .classification-layout {
2067
+ display: flex;
2068
+ flex-direction: column;
2069
+ min-height: 100%;
2070
+ height: 100%;
2071
+ }
2072
+
2073
+ /* ==================== DND MODE ==================== */
2074
+
2075
+ .dnd-container {
2076
+ display: flex;
2077
+ flex-direction: column;
2078
+ gap: 2rem;
2079
+ }
2080
+
2081
+ .dnd-text {
2082
+ line-height: 2.2;
2083
+ }
2084
+
2085
+ .dropzone {
2086
+ display: inline-block;
2087
+ min-width: clamp(4ch, 5vw, 7ch);
2088
+ min-height: 2rem;
2089
+ padding: 0.25rem 0.75rem;
2090
+ margin: 0 0.25rem;
2091
+ border: 2px dashed rgb(var(--edu-border));
2092
+ border-radius: var(--edu-radius);
2093
+ background: rgb(var(--edu-muted));
2094
+ text-align: center;
2095
+ vertical-align: middle;
2096
+ transition: all 0.2s ease;
2097
+ color: rgb(var(--edu-ink));
2098
+ }
2099
+
2100
+ .dropzone:hover {
2101
+ border-color: rgba(var(--edu-first-accent), 0.5);
2102
+ background: rgba(var(--edu-first-accent), 0.05);
2103
+ }
2104
+
2105
+ .dropzone-filled {
2106
+ border-style: solid;
2107
+ border-color: rgba(var(--edu-first-accent), 0.5);
2108
+ background: rgba(var(--edu-first-accent), 0.1);
2109
+ font-weight: 500;
2110
+ }
2111
+
2112
+ .dropzone-correct {
2113
+ border-color: rgb(var(--edu-success)) !important;
2114
+ background: rgba(var(--edu-success), 0.1) !important;
2115
+ }
2116
+
2117
+ .dropzone-wrong {
2118
+ border-color: rgb(var(--edu-error)) !important;
2119
+ background: rgba(var(--edu-error), 0.1) !important;
2120
+ }
2121
+
2122
+ .dropzone-missed {
2123
+ border-color: rgb(var(--edu-warning)) !important;
2124
+ background: rgba(var(--edu-warning), 0.1) !important;
2125
+ }
2126
+
2127
+ .dnd-chips {
2128
+ display: flex;
2129
+ flex-wrap: wrap;
2130
+ gap: 0.5rem;
2131
+ padding: 1rem;
2132
+ border: 2px solid rgb(var(--edu-border));
2133
+ border-radius: var(--edu-radius);
2134
+ background: rgb(var(--edu-muted));
2135
+ min-height: 4rem;
2136
+ max-height: 11rem;
2137
+ overflow: auto;
2138
+ }
2139
+
2140
+ .chip {
2141
+ padding: 0.5rem 1rem;
2142
+ border: 1px solid rgb(var(--edu-border));
2143
+ background: rgb(var(--edu-card));
2144
+ border-radius: var(--edu-radius);
2145
+ cursor: grab;
2146
+ font-size: 0.875rem;
2147
+ font-weight: 500;
2148
+ transition: all 0.2s ease;
2149
+ user-select: none;
2150
+ color: rgb(var(--edu-ink));
2151
+ }
2152
+
2153
+ .chip:hover {
2154
+ border-color: rgba(var(--edu-first-accent), 0.5);
2155
+ background: rgba(var(--edu-first-accent), 0.05);
2156
+ transform: translateY(-2px);
2157
+ box-shadow: 0 4px 6px rgb(var(--edu-shadow-color) / 0.1);
2158
+ }
2159
+
2160
+ .chip:active {
2161
+ cursor: grabbing;
2162
+ }
2163
+
2164
+ /* ==================== VARIANT: ELEGANT ==================== */
2165
+
2166
+ :host([variant="elegant"]) .word-selectable {
2167
+ background: rgb(var(--edu-card));
2168
+ border: 1px solid rgb(var(--edu-border));
2169
+ box-shadow: 0 1px 2px rgba(var(--edu-shadow-color), 0.05);
2170
+ }
2171
+
2172
+ :host([variant="elegant"]) .word-selectable:hover {
2173
+ border-color: rgba(var(--edu-first-accent), 0.5);
2174
+ box-shadow: 0 4px 8px rgba(var(--edu-shadow-color), 0.12);
2175
+ transform: translateY(-2px);
2176
+ }
2177
+
2178
+ :host([variant="elegant"]) .word-selected {
2179
+ background: linear-gradient(135deg, rgba(var(--edu-first-accent), 0.15), rgba(var(--edu-first-accent), 0.25));
2180
+ border-color: var(--text-accent);
2181
+ border-width: 1px;
2182
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.2);
2183
+ font-weight: 500;
2184
+ color: var(--text-accent);
2185
+ }
2186
+
2187
+ /* ==================== VARIANT: PLAYFUL ==================== */
2188
+
2189
+ :host([variant="playful"]) .word {
2190
+ border-radius: 16px;
2191
+ font-weight: 500;
2192
+ }
2193
+
2194
+ :host([variant="playful"]) .word-selectable {
2195
+ background: linear-gradient(145deg, rgb(var(--edu-card)), rgb(var(--edu-muted)));
2196
+ border: 3px solid rgb(var(--edu-border));
2197
+ box-shadow: 2px 2px 4px rgba(var(--edu-shadow-color), 0.08);
2198
+ }
2199
+
2200
+ :host([variant="playful"]) .word-selectable:hover {
2201
+ transform: scale(1.1) rotate(-2deg);
2202
+ border-color: rgba(var(--edu-first-accent), 0.7);
2203
+ box-shadow: 3px 3px 8px rgba(var(--edu-shadow-color), 0.15);
2204
+ }
2205
+
2206
+ :host([variant="playful"]) .word-selected {
2207
+ background: linear-gradient(135deg, var(--text-accent), rgba(var(--edu-first-accent), 0.8));
2208
+ border-color: var(--text-accent);
2209
+ border-width: 3px;
2210
+ color: rgb(var(--edu-inverted-ink));
2211
+ transform: scale(1.15) rotate(2deg);
2212
+ box-shadow: 4px 4px 12px rgba(var(--edu-shadow-color), 0.25);
2213
+ font-weight: 700;
2214
+ }
2215
+
2216
+ :host([variant="playful"]) .category-btn {
2217
+ border-radius: 24px;
2218
+ }
2219
+
2220
+ /* ==================== VARIANT: OUTLINE ==================== */
2221
+
2222
+ :host([variant="outline"]) .word-selectable {
2223
+ border: 2px solid rgb(var(--edu-border));
2224
+ background: transparent;
2225
+ }
2226
+
2227
+ :host([variant="outline"]) .word-selectable:hover {
2228
+ border-color: rgba(var(--edu-first-accent), 0.7);
2229
+ background: rgba(var(--edu-first-accent), 0.05);
2230
+ border-width: 2px;
2231
+ }
2232
+
2233
+ :host([variant="outline"]) .word-selected {
2234
+ border-color: var(--text-accent);
2235
+ background: rgba(var(--edu-first-accent), 0.12);
2236
+ border-width: 2px;
2237
+ font-weight: 500;
2238
+ color: var(--text-accent);
2239
+ }
2240
+
2241
+ /* ==================== VARIANT: MINIMAL ==================== */
2242
+
2243
+ :host([variant="minimal"]) .word {
2244
+ border: none;
2245
+ border-radius: 0;
2246
+ padding: 0.2rem 0.3rem;
2247
+ margin: 0 0.1rem;
2248
+ }
2249
+
2250
+ :host([variant="minimal"]) .word-selectable {
2251
+ background: transparent;
2252
+ border-bottom: 2px solid transparent;
2253
+ transition: all 0.2s ease;
2254
+ }
2255
+
2256
+ :host([variant="minimal"]) .word-selectable:hover {
2257
+ background: rgba(var(--edu-first-accent), 0.1);
2258
+ border-bottom-color: rgba(var(--edu-first-accent), 0.4);
2259
+ }
2260
+
2261
+ :host([variant="minimal"]) .word-selected {
2262
+ background: linear-gradient(to right, rgba(var(--edu-first-accent), 0.4) 0%, rgba(var(--edu-first-accent), 0.4) 100%);
2263
+ background-size: 100% 60%;
2264
+ background-position: 0 100%;
2265
+ background-repeat: no-repeat;
2266
+ border: none;
2267
+ border-bottom: 3px solid var(--text-accent);
2268
+ font-weight: 500;
2269
+ color: var(--text-accent);
2270
+ }
2271
+
2272
+ /* ==================== VARIANT: LETTER ==================== */
2273
+
2274
+ :host([variant="letter"]) .word {
2275
+ border-radius: 2px;
2276
+ }
2277
+
2278
+ :host([variant="letter"]) .word-selectable {
2279
+ background: rgb(var(--edu-card));
2280
+ border: 1px solid rgb(var(--edu-border));
2281
+ font-family: 'Courier New', monospace;
2282
+ }
2283
+
2284
+ :host([variant="letter"]) .word-selected {
2285
+ background: rgba(var(--edu-first-accent), 0.15);
2286
+ border-color: var(--text-accent);
2287
+ }
2288
+
2289
+ /* ==================== VARIANT: SIGN ==================== */
2290
+
2291
+ :host([variant="sign"]) .word {
2292
+ border-radius: 4px;
2293
+ font-weight: 700;
2294
+ text-transform: uppercase;
2295
+ font-size: 0.95em;
2296
+ letter-spacing: 0.5px;
2297
+ }
2298
+
2299
+ :host([variant="sign"]) .word-selectable {
2300
+ background: linear-gradient(180deg, rgb(var(--edu-card)), rgb(var(--edu-muted)));
2301
+ border: 4px solid rgb(var(--edu-border));
2302
+ border-bottom-width: 6px;
2303
+ box-shadow: 0 4px 0 rgba(var(--edu-shadow-color), 0.15);
2304
+ }
2305
+
2306
+ :host([variant="sign"]) .word-selectable:hover {
2307
+ border-color: rgba(var(--edu-first-accent), 0.6);
2308
+ transform: translateY(-2px);
2309
+ box-shadow: 0 6px 0 rgba(var(--edu-shadow-color), 0.2);
2310
+ }
2311
+
2312
+ :host([variant="sign"]) .word-selected {
2313
+ background: linear-gradient(180deg, var(--text-accent), rgba(var(--edu-first-accent), 0.8));
2314
+ border-color: var(--text-accent);
2315
+ border-width: 4px;
2316
+ border-bottom-width: 6px;
2317
+ color: rgb(var(--edu-inverted-ink));
2318
+ transform: translateY(-4px);
2319
+ box-shadow: 0 8px 0 rgba(var(--edu-shadow-color), 0.25);
2320
+ }
2321
+
2322
+ /* ==================== VARIANT: GLASS ==================== */
2323
+
2324
+ :host([variant="glass"]) .word-selectable {
2325
+ background: rgba(var(--edu-card), 0.6);
2326
+ border: 1px solid rgba(var(--edu-border), 0.3);
2327
+ backdrop-filter: blur(12px) saturate(150%);
2328
+ box-shadow: 0 2px 8px rgba(var(--edu-shadow-color), 0.1);
2329
+ }
2330
+
2331
+ :host([variant="glass"]) .word-selectable:hover {
2332
+ background: rgba(var(--edu-first-accent), 0.2);
2333
+ border-color: rgba(var(--edu-first-accent), 0.5);
2334
+ backdrop-filter: blur(16px) saturate(180%);
2335
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.15);
2336
+ }
2337
+
2338
+ :host([variant="glass"]) .word-selected {
2339
+ background: rgba(var(--edu-first-accent), 0.35);
2340
+ border-color: var(--text-accent);
2341
+ border-width: 2px;
2342
+ backdrop-filter: blur(16px) saturate(200%);
2343
+ box-shadow: 0 6px 16px rgba(var(--edu-shadow-color), 0.2);
2344
+ font-weight: 600;
2345
+ color: var(--text-accent);
2346
+ }
2347
+
2348
+ /* ==================== VARIANT: EMPTY ==================== */
2349
+
2350
+ :host([variant="empty"]) .word {
2351
+ border: none;
2352
+ background: transparent;
2353
+ margin: 0;
2354
+ padding: 0.2rem;
2355
+ }
2356
+
2357
+ :host([variant="empty"]) .word-selectable:hover {
2358
+ opacity: 0.7;
2359
+ }
2360
+
2361
+ :host([variant="empty"]) .word-selected {
2362
+ text-decoration: underline;
2363
+ text-decoration-color: var(--text-accent);
2364
+ text-decoration-thickness: 2px;
2365
+ text-underline-offset: 4px;
2366
+ }
2367
+
2368
+ @media (max-width: 720px) {
2369
+ .word {
2370
+ margin: 0 0.08rem;
2371
+ padding: 0.12rem 0.2rem;
2372
+ }
2373
+
2374
+ .categories {
2375
+ gap: 0.35rem;
2376
+ margin-bottom: 0.9rem;
2377
+ }
2378
+
2379
+ .category-btn {
2380
+ padding: 0.38rem 0.7rem;
2381
+ font-size: 0.8rem;
2382
+ }
2383
+
2384
+ .dnd-container {
2385
+ gap: 1.1rem;
2386
+ }
2387
+ }
2388
+ `;var Ke=class extends HTMLElement{constructor(){super();this._state={};this._mounted=!1;this.onClick=t=>{let r=t.target;if(r.classList.contains("word-selectable")){let i=parseInt(r.getAttribute("data-index")??"");isNaN(i)||this.toggleWordSelection(i)}if(r.classList.contains("category-btn")){let i=r.getAttribute("data-category");i&&this.setActiveCategory(i)}if(r.classList.contains("word-classifiable")){let i=parseInt(r.getAttribute("data-index")??"");!isNaN(i)&&this._activeCategory&&this.assignWordToCategory(i,this._activeCategory)}if(r.classList.contains("dropzone-filled")){let i=parseInt(r.getAttribute("data-index")??"");isNaN(i)||this.clearDropzone(i)}};this.onChange=t=>{let r=t.target;if(r.tagName==="EDU-INPUT"||r.tagName==="INPUT"){let i=r.getAttribute("id");if(i){let a=r.value;this.updateInputValue(i,a)}}};this.onInput=t=>{let r=t.target;if(r.tagName==="EDU-INPUT"||r.tagName==="INPUT"){let i=r.getAttribute("id");if(i){let a=r.value;this.updateInputValue(i,a)}}if(r.hasAttribute("contenteditable")&&r.getAttribute("contenteditable")==="true"){let i=parseInt(r.getAttribute("data-target-index")??"");if(!isNaN(i)){let a=r.textContent??"";this.updateTransformation(i,a)}}};this.onDragStart=t=>{let r=t,i=r.target;if(!r.dataTransfer||!i.classList.contains("chip"))return;let a=i.getAttribute("data-word")||i.textContent||"";a&&(r.dataTransfer.setData("text/plain",a),r.dataTransfer.effectAllowed="move")};this.onDragOver=t=>{let r=t;r.target.classList.contains("dropzone")&&(r.preventDefault(),r.dataTransfer.dropEffect="move")};this.onDrop=t=>{let r=t,i=r.target;if(!i.classList.contains("dropzone")||(r.preventDefault(),!r.dataTransfer))return;let a=parseInt(i.getAttribute("data-index")??"");if(isNaN(a))return;let o=r.dataTransfer.getData("text/plain");o&&this.placeWordInDropzone(a,o)};this._activeCategory=null;this.attachShadow({mode:"open"});let t=document.createElement("section");t.className="wrap",this.shadowRoot.append(t),this.$wrapEl=t}static get observedAttributes(){return["variant"]}connectedCallback(){this._mounted=!0,this.shadowRoot?.addEventListener("click",this.onClick),this.shadowRoot?.addEventListener("change",this.onChange),this.shadowRoot?.addEventListener("input",this.onInput),this.shadowRoot?.addEventListener("dragstart",this.onDragStart),this.shadowRoot?.addEventListener("dragover",this.onDragOver),this.shadowRoot?.addEventListener("drop",this.onDrop),this.render()}disconnectedCallback(){this._mounted=!1,this.shadowRoot?.removeEventListener("click",this.onClick),this.shadowRoot?.removeEventListener("change",this.onChange),this.shadowRoot?.removeEventListener("input",this.onInput),this.shadowRoot?.removeEventListener("dragstart",this.onDragStart),this.shadowRoot?.removeEventListener("dragover",this.onDragOver),this.shadowRoot?.removeEventListener("drop",this.onDrop)}set config(t){this._config=t,this._state=this.initState(t),t.variant&&this.setAttribute("variant",t.variant),this.render()}get config(){if(!this._config)throw new Error("<edu-text>: config not set");return this._config}getValue(){switch(this._config.data.type){case"base":if(this._config.mode==="highlight")return{selectedIndices:Array.from(this._state.selectedIndices??[])};if(this._config.mode==="dnd"){let r=this._state.dndPlacements??{};return{placedIndices:Object.keys(r).map(i=>Number(i)),dndPlacements:{...r}}}else if(this._config.mode==="transformation")return{transformations:this._state.transformations??{}};break;case"blanks":return{inputValues:this._state.inputValues??{}};case"classification":return{wordCategories:this._state.wordCategories??{}}}return{}}getState(){return{...this._state}}setState(t){t&&(this._state={...this._state,...t.selectedIndices?{selectedIndices:new Set(t.selectedIndices)}:{},...t.dndPlacements?{dndPlacements:{...t.dndPlacements}}:{},...t.inputValues?{inputValues:{...t.inputValues}}:{},...t.wordCategories?{wordCategories:{...t.wordCategories}}:{},...t.transformations?{transformations:{...t.transformations}}:{}},this.render())}reset(){this._config&&(this._state=this.initState(this._config),this.render(),this.dispatchEvent(new CustomEvent("reset",{bubbles:!0,composed:!0})))}setGradingState(t){this._config&&(this._config.gradingState=t,this.render())}clearGradingState(){this._config&&(this._config.gradingState=void 0,this.render())}attributeChangedCallback(t,r,i){r!==i&&t==="variant"&&(this.setAttribute("variant",i),this.shadowRoot?.querySelectorAll("edu-input").forEach(a=>{let o=a;o.variant!==void 0&&(o.variant=i)}),this.shadowRoot?.querySelectorAll("edu-block").forEach(a=>{let o=a;o.variant!==void 0&&(o.variant=i)}),this.render())}upsertHtmlAttribute(t,r,i){let a=new RegExp(`${r}="[^"]*"`,"i");return a.test(t)?t.replace(a,`${r}="${i}"`):t.replace(/<([a-z0-9-]+)/i,`<$1 ${r}="${i}"`)}removeHtmlAttribute(t,r){let i=new RegExp(`\\s${r}="[^"]*"`,"ig");return t.replace(i,"")}upsertHtmlClass(t,r){let i=/class="([^"]*)"/i;return i.test(t)?t.replace(i,(a,o)=>{let s=String(o||"").split(/\s+/).filter(Boolean);return s.includes(r)||s.push(r),`class="${s.join(" ")}"`}):t.replace(/<([a-z0-9-]+)/i,`<$1 class="${r}"`)}removeHtmlClassPrefix(t,r){let i=/class="([^"]*)"/i;return i.test(t)?t.replace(i,(a,o)=>{let s=String(o||"").split(/\s+/).filter(Boolean).filter(l=>!l.startsWith(r));return s.length>0?`class="${s.join(" ")}"`:""}):t}initState(t){let r={};switch(t.data.type){case"base":t.mode==="highlight"||t.mode==="dnd"?(r.selectedIndices=new Set,t.mode==="dnd"&&(r.dndPlacements={})):t.mode==="transformation"&&(r.transformations={});break;case"blanks":r.inputValues={};break;case"classification":r.wordCategories={};break}return r}render(){if(!this._mounted||!this.shadowRoot)return;if(!this._config){this.$wrapEl.innerHTML="<style>:host{display:block}</style><div></div>";return}let t=this._config,r=t.data,i="";switch(t.mode){case"highlight":i=this.renderHighlight(r);break;case"blanks":i=this.renderBlanks(r);break;case"classification":i=this.renderClassification(r);break;case"dnd":i=this.renderDND(r);break;case"transformation":i=this.renderTransformation(r);break}this.$wrapEl.innerHTML=`
2389
+ <style>${Zr}</style>
2390
+ <div class="text-content" part="content">
2391
+ ${i}
2392
+ </div>
2393
+ `}renderHighlight(t){let r=t.parts,i=this._state.selectedIndices??new Set,a=this._config.gradingState??{};return r.map((o,s)=>{let l=i.has(s),c=a[s],d=["word","word-selectable"];return l&&d.push("word-selected"),c&&d.push(`word-${c}`),`<span class="${d.join(" ")}" data-index="${s}">${E(o)}</span>`}).join(" ")}renderBlanks(t){let r=this._config.gradingState??{},i=this.getAttribute("variant")??this._config.variant??"outline";return t.parts.map((a,o)=>{if(a.startsWith("<")){let s=t.targets.find(l=>l.expectedValue.html===a);if(s){let l=r[s.id],c=l?`input-${l}`:"",d=this._state.inputValues?.[s.id]??"",u=a;if(/<edu-input\b/i.test(u)&&(u=this.upsertHtmlAttribute(u,"variant",i)),u=this.removeHtmlClassPrefix(u,"input-"),u=this.removeHtmlAttribute(u,"state"),l&&(/<edu-input\b/i.test(u)?u=this.upsertHtmlAttribute(u,"state",l):c&&(u=this.upsertHtmlClass(u,c))),d!==""){let p=E(String(d));u.includes("<edu-input")?/value="[^"]*"/.test(u)?u=u.replace(/value="[^"]*"/,`value="${p}"`):u=u.replace("<edu-input",`<edu-input value="${p}"`):u.includes("<input")&&(/value="[^"]*"/.test(u)?u=u.replace(/value="[^"]*"/,`value="${p}"`):u=u.replace("<input",`<input value="${p}"`))}return u}return a}else return`<span class="word">${E(a)}</span>`}).join(" ")}renderClassification(t){let r=t.parts,i=this._state.wordCategories??{},a=this._config.gradingState??{},o=this.getAttribute("variant")??"outline",s=t.targets.map(p=>p.category),l={},c=["--edu-first-accent","--edu-second-accent","--edu-third-accent","--edu-neutral"];s.forEach((p,h)=>{l[p]=c[h%c.length]});let d=r.map((p,h)=>{let g=i[h],m=a[h],b=["word","word-classifiable"];g&&b.push("word-assigned"),m&&b.push(`word-${m}`);let w=g?`style="--category-color: var(${l[g]})"`:"";return`
2394
+ <span class="${b.join(" ")}" data-index="${h}" ${w}>
2395
+ ${E(p)}
2396
+ </span>
2397
+ `}).join(" "),u=`
2398
+ <div class="categories" part="categories">
2399
+ ${s.map(p=>`
2400
+ <edu-block class="category-btn"
2401
+ ${this._activeCategory===p?'data-active="true"':""}
2402
+ data-category="${E(p)}"
2403
+ variant="${E(o)}"
2404
+ style="--category-color: var(${l[p]})">
2405
+ ${E(p)}
2406
+ </edu-block>
2407
+ `).join("")}
2408
+ </div>
2409
+ `;return`
2410
+ <div class="classification-layout" part="classification-layout">
2411
+ <div class="words" part="words">${d}</div>
2412
+ ${u}
2413
+ </div>
2414
+ `}renderDND(t){let r=t.parts,i=this._state.dndPlacements??{},a=this._config.gradingState??{},o=new Set;for(let h of t.targets)for(let g=h.startPos;g<=h.endPos;g++)o.add(g);let s=r.map((h,g)=>{if(o.has(g)){let m=i[g],b=!!m,w=a[g],v=["dropzone"];b&&v.push("dropzone-filled"),w&&v.push(`dropzone-${w}`);let P=b?E(m):"";return`<span class="${v.join(" ")}" data-index="${g}">${P}</span>`}else return`<span class="word">${E(h)}</span>`}).join(" "),l=[...t.targets.flatMap(h=>h.words)];t.distractors&&l.push(...t.distractors);let c=Object.values(i),d=[...l];for(let h of c){let g=d.findIndex(m=>Jr(m)===Jr(h));g!==-1&&d.splice(g,1)}let p=S(d).map(h=>`<div class="chip" draggable="true" data-word="${E(h)}">${E(h)}</div>`).join("");return`
2415
+ <div class="dnd-container">
2416
+ <div class="dnd-text">${s}</div>
2417
+ <div class="dnd-chips">${p}</div>
2418
+ </div>
2419
+ `}renderTransformation(t){let r=t.parts,i=this._state.transformations??{},a=this._config.gradingState??{},o=new Map;for(let s=0;s<t.targets.length;s++){let l=t.targets[s];for(let c=l.startPos;c<=l.endPos;c++)o.set(c,s)}return r.map((s,l)=>{let c=o.get(l);if(c!==void 0){let d=a[c],u=i[c],p=u?u.join(" "):t.targets[c].words.join(" "),h=["word","word-editable"];return d&&h.push(`word-${d}`),`
2420
+ <span class="${h.join(" ")}"
2421
+ contenteditable="true"
2422
+ data-target-index="${c}"
2423
+ data-original="${E(s)}">${E(p)}</span>
2424
+ `}else return`<span class="word">${E(s)}</span>`}).join(" ")}toggleWordSelection(t){this._state.selectedIndices||(this._state.selectedIndices=new Set),this._state.selectedIndices.has(t)?this._state.selectedIndices.delete(t):this._state.selectedIndices.add(t),this.render(),this.emitChange()}setActiveCategory(t){this._activeCategory=t,this.shadowRoot?.querySelectorAll(".category-btn").forEach(r=>{r.getAttribute("data-category")===t?(r.classList.add("category-active"),r.setAttribute("data-active","true")):(r.classList.remove("category-active"),r.removeAttribute("data-active")),r instanceof G&&(r.variant=this.getAttribute("variant")??"outline")})}assignWordToCategory(t,r){this._state.wordCategories||(this._state.wordCategories={}),this._state.wordCategories[t]===r?delete this._state.wordCategories[t]:this._state.wordCategories[t]=r,this.render(),this.emitChange()}updateInputValue(t,r){this._state.inputValues||(this._state.inputValues={}),this._state.inputValues[t]=r,this.emitChange()}updateTransformation(t,r){this._state.transformations||(this._state.transformations={});let i=r.split(/\s+/).filter(Boolean);this._state.transformations[t]=i,this.emitChange()}placeWordInDropzone(t,r){this._state.dndPlacements||(this._state.dndPlacements={}),this._state.dndPlacements[t]=r,this.render(),this.emitChange()}clearDropzone(t){this._state.dndPlacements&&t in this._state.dndPlacements&&(delete this._state.dndPlacements[t],this.render(),this.emitChange())}emitChange(){let t={userState:this.getValue(),dataType:this._config.data.type};this.dispatchEvent(new CustomEvent("change",{detail:t,bubbles:!0,composed:!0}))}};function Jr(e){return e.trim().toLowerCase()}customElements.get("edu-text")||customElements.define("edu-text",Ke);var j=new Map,k=e=>{let n=j.get(e.id);if(n){if(n.ctor===e.ctor)return;throw new Error(`Duplicate interaction id: "${e.id}"`)}j.set(e.id,e)},qs=e=>j.delete(e),Bs=()=>{j.clear()},zs=()=>j,Hs=()=>Array.from(j.values()),Ua=e=>j.get(e)??null,Gs=(e,...n)=>{let t=Ua(e);if(!t)throw new Error(`Unknown interaction "${e}"`);return new t.ctor(...n)};var We=class extends Error{constructor(n){super(`Asset validation failed:n- ${n.join(`
2425
+ - `)}`),this.name="AssetValidationError",this.issues=n}};function Vs(e){let n=[];if(!je(e))throw new We(["Top-level assets must be an object/map like { mango: {...}, trend: {...} }"]);let t=e,r={};for(let[a,o]of Object.entries(t)){if(!a||typeof a!="string"){n.push(`Asset key must be a non-empty string (got: ${String(a)})`);continue}if(/^[a-zA-Z0-9._-]+$/.test(a)||n.push(`Asset id "${a}" has invalid chars; use letters/numbers/._-`),!je(o)){n.push(`Asset "${a}" must be an object (got: ${Pr(o)})`);continue}let s=o,l=s.type,c=!!s.dialog;if(!I(l)){n.push(`Asset "${a}" missing string field "type"`);continue}if(!Ya(l)){n.push(`Asset "${a}" has unsupported type "${l}" (use image|video|audio|html)`);continue}switch(l){case"image":{let d=s.url;I(d)||n.push(`Asset "${a}" (image) missing "url"`);let u=s.size;u!==void 0&&!I(u)&&n.push(`Asset "${a}" (image) field "size" must be a string`),I(d)&&(r[a]={id:a,type:l,dialog:c,url:d,...I(u)?{size:u}:{}});break}case"video":{let d=s.url;I(d)||n.push(`Asset "${a}" (video) missing "url"`);let u=s.span,p;if(u!==void 0)if(!je(u))n.push(`Asset "${a}" (video) field "span" must be an object`);else{let h=u.from,g=u.to;!I(h)||!I(g)?n.push(`Asset "${a}" (video) span requires string "from" and "to"`):((!ht(h)||!ht(g))&&n.push(`Asset "${a}" (video) span times should look like "02:15" or "01:02:45"`),p={from:h,to:g})}I(d)&&(r[a]={id:a,type:l,dialog:c,url:d,...p?{span:p}:{}});break}case"audio":{let d=s.url;I(d)||n.push(`Asset "${a}" (audio) missing "url"`);let u=s.volume;u!==void 0&&(!pt(u)||!Number.isFinite(u)?n.push(`Asset "${a}" (audio) field "volume" must be a number`):(u<0||u>100)&&n.push(`Asset "${a}" (audio) field "volume" must be between 0 and 100`)),I(d)&&(r[a]={id:a,type:l,dialog:c,url:d,...pt(u)?{volume:u}:{}});break}case"html":{let d=s.content;if(!I(d)){n.push(`Asset "${a}" (html) missing string field "content"`);break}r[a]={id:a,type:l,dialog:c,content:d};break}case"tts":{let d=s.content;if(!I(d)){n.push(`Asset "${a}" (tts) missing string field "content"`);break}r[a]={id:a,type:l,dialog:c,content:d};break}}}if(n.length)throw new We(n);let i=Object.keys(r).sort((a,o)=>a.localeCompare(o)).map(a=>r[a]);return{assetsById:r,assetsList:i}}function Ya(e){return e==="image"||e==="video"||e==="audio"||e==="html"}function ke(e,n,t){let r=0,i=0;return e.forEach(o=>{o.items.forEach(s=>{i++;let l=n.get(s),c=t.querySelector(`[data-label="${s}"]`);l===o.label?(r++,c.chipState="correct"):c.chipState="wrong"})}),{score:i>0?Math.round(r/i*100):0,correct:r,total:i}}var Te=class extends x{constructor(t,r,i){super(t,r,i);this.interactionMechanic="static";this.categories=["none"];this.allItems=[];this.categoryColors=["#94a3b8","#3b82f6","#10b981","#f59e0b","#ef4444","#8b5cf6","#ec4899","#14b8a6","#f97316","#6366f1"];this.currentColor=this.categoryColors[0];this.data.categories.forEach(({label:a,items:o})=>{this.categories.push(a),this.allItems.push(...o)}),this.currentCategory=this.categories[0],this.data.distractors&&this.allItems.push(...this.data.distractors),this.allItems=S(this.allItems),this.categorized=new Map,this.initializeProgress(this.allItems.length)}initialize(){}cleanup(){}onVariantChange(t){this.querySelectorAll("edu-chip, edu-block").forEach(r=>{r.variant!==void 0&&(r.variant=t)})}render(){this.innerHTML=`
2426
+ <style>
2427
+ open-classification {
2428
+ --current-color: #94a3b8;
2429
+ display: flex;
2430
+ width: 100%;
2431
+ height: 100%;
2432
+ box-sizing: border-box;
2433
+ container-type: size;
2434
+ container-name: open-classification;
2435
+ }
2436
+
2437
+ .container {
2438
+ display: flex;
2439
+ flex-direction: column;
2440
+ width: 100%;
2441
+ height: 100%;
2442
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2443
+ padding: clamp(0.75rem, min(2cqw, 2cqh), 1.5rem);
2444
+ box-sizing: border-box;
2445
+ overflow: hidden;
2446
+ }
2447
+
2448
+ @container open-classification (max-width: 768px) {
2449
+ .container {
2450
+ padding: clamp(0.75rem, min(1.6cqw, 1.6cqh), 1rem);
2451
+ }
2452
+ }
2453
+
2454
+ .items-section {
2455
+ flex: 1;
2456
+ display: flex;
2457
+ flex-direction: column;
2458
+ gap: clamp(0.25rem, min(1cqw, 1cqh), 0.5rem);
2459
+ min-height: 0;
2460
+ overflow: hidden;
2461
+ }
2462
+
2463
+ .items-label {
2464
+ font-size: clamp(0.8rem, 1.8cqh, 1rem);
2465
+ font-weight: 600;
2466
+ color: rgb(var(--edu-second-ink));
2467
+ flex-shrink: 0;
2468
+ }
2469
+
2470
+ .items-container {
2471
+ display: grid;
2472
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
2473
+ grid-auto-rows: minmax(44px, 1fr);
2474
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2475
+ padding: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1.25rem);
2476
+ background: rgb(var(--edu-muted));
2477
+ border-radius: clamp(6px, 1.6cqw, 8px);
2478
+ flex: 1;
2479
+ overflow-y: auto;
2480
+ overflow-x: hidden;
2481
+ align-content: stretch;
2482
+ min-height: 0;
2483
+ }
2484
+
2485
+ .items-container edu-chip {
2486
+ width: 100%;
2487
+ height: 100%;
2488
+ cursor: pointer;
2489
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
2490
+ }
2491
+
2492
+ .items-container edu-chip:hover {
2493
+ transform: translateY(-3px);
2494
+ box-shadow: 0 6px 16px rgba(var(--edu-shadow-color), 0.15);
2495
+ }
2496
+
2497
+ .items-container edu-chip::part(block) {
2498
+ width: 100%;
2499
+ height: 100%;
2500
+ display: flex;
2501
+ align-items: center;
2502
+ justify-content: center;
2503
+ }
2504
+
2505
+ @container open-classification (max-width: 1024px) {
2506
+ .items-container {
2507
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));
2508
+ gap: clamp(0.5rem, min(1.4cqw, 1.4cqh), 0.875rem);
2509
+ }
2510
+ }
2511
+
2512
+ @container open-classification (max-width: 768px) {
2513
+ .items-container {
2514
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 120px), 1fr));
2515
+ padding: clamp(0.5rem, min(1.2cqw, 1.2cqh), 1rem);
2516
+ gap: clamp(0.5rem, min(1.2cqw, 1.2cqh), 0.75rem);
2517
+ }
2518
+ }
2519
+
2520
+ @container open-classification (max-width: 560px) {
2521
+ .items-container {
2522
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 110px), 1fr));
2523
+ }
2524
+ }
2525
+
2526
+ .divider {
2527
+ border: none;
2528
+ border-top: 1px solid rgb(var(--edu-border));
2529
+ margin: 0;
2530
+ flex-shrink: 0;
2531
+ }
2532
+
2533
+ .swatch-section {
2534
+ flex-shrink: 0;
2535
+ display: flex;
2536
+ flex-direction: column;
2537
+ gap: clamp(0.25rem, min(1cqw, 1cqh), 0.5rem);
2538
+ }
2539
+
2540
+ .swatch-label {
2541
+ font-size: clamp(0.8rem, 1.8cqh, 1rem);
2542
+ font-weight: 600;
2543
+ color: rgb(var(--edu-second-ink));
2544
+ flex-shrink: 0;
2545
+ }
2546
+
2547
+ .categories-bar {
2548
+ display: grid;
2549
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 110px), 1fr));
2550
+ gap: clamp(0.4rem, min(1.2cqw, 1.2cqh), 0.75rem);
2551
+ }
2552
+
2553
+ #categories-bar edu-block::part(block) {
2554
+ padding: clamp(0.35rem, min(1cqw, 1cqh), 0.6rem);
2555
+ font-size: clamp(0.75rem, 1.6cqh, 0.95rem);
2556
+ min-height: clamp(44px, 8cqh, 64px);
2557
+ }
2558
+
2559
+ #categories-bar edu-block.active::part(block) {
2560
+ background: var(--category-color);
2561
+ border-color: var(--category-color);
2562
+ color: rgb(var(--edu-inverted-ink));
2563
+ box-shadow: 0 0 0 3px rgb(var(--edu-first-accent) / 0.2);
2564
+ }
2565
+ </style>
2566
+
2567
+ <div class="container">
2568
+ <div class="items-section">
2569
+ <!--Sacrificing label for space-->
2570
+ <div class="items-container"></div>
2571
+ </div>
2572
+
2573
+ <hr class="divider">
2574
+
2575
+ <div class="swatch-section">
2576
+ <div class="swatch-label">Categories</div>
2577
+ </div>
2578
+
2579
+ <div class="categories-bar" id="categories-bar">
2580
+ <!-- Categories populated dynamically -->
2581
+ </div>
2582
+ </div>
2583
+ `,this.style.setProperty("--current-color",this.currentColor),this.$categoriesBar=this.querySelector("#categories-bar"),this.setCategories(this.$categoriesBar);let t=this.querySelector(".items-container");this.setItems(t)}setItems(t){this.allItems.forEach((r,i)=>{let a=document.createElement("edu-chip");a.variant=this.config.variant,a.dataset.label=r,L(r,a,this.assets?.assetsById),a.addEventListener("click",o=>{let s=o.currentTarget,l=s.dataset.label;if(this.categorized.get(l)===this.currentCategory){this.categorized.delete(l),s.colored=!1,this.decrementProgress(),this.emitStateChange();return}this.categorized.has(l)||this.incrementProgress(),this.categorized.set(l,this.currentCategory),s.color=this.currentColor,s.colored=!0,this.emitStateChange()}),t.append(a)})}setCategories(t){this.categories.forEach((r,i)=>{let a=new G;a.variant=this.config.variant;let o=this.categoryColors[i%this.categoryColors.length];a.dataset.category=r,a.dataset.color=o,a.style.setProperty("--category-color",o),a.innerHTML=`
2584
+ <div class="category-label">${r}</div>
2585
+ `,a.addEventListener("click",s=>{let l=s.currentTarget;this.currentCategory=l.dataset.category,this.currentColor=l.dataset.color,this.style.setProperty("--current-color",this.currentColor),t.querySelectorAll("edu-block").forEach(c=>c.classList.remove("active")),a.classList.add("active")}),r===this.currentCategory&&a.classList.add("active"),t.append(a)})}getCurrentState(){return{categorized:Object.fromEntries(this.categorized),progress:this.progressTracker.current}}isInteractionComplete(){if(this.categorized.size!==this.allItems.length)return!1;for(let t of this.categorized.values())if(t==null)return!1;return!0}onHint(){let t=this.allItems.filter(i=>!this.categorized.has(i));if(t.length===0){alert('All items are categorized! Click "Check" to submit.'),this.emitHintShown("All items categorized");return}let r=t[0];alert(`Hint: You haven't categorized "${r}" yet. Which category does it belong to?`),this.emitHintShown(`Uncategorized item: ${r}`)}submit(){super.submit();let t=ke(this.data.categories,this.categorized,this);console.log(`Classification Score: ${t.score.toFixed(1)}% (${t.correct}/${t.total} correct)`),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0})),this.setAttribute("inert","")}reset(){super.reset(),this.categorized.clear(),this.querySelectorAll("edu-chip").forEach(t=>{t.classList.remove("colorized"),t.style.setProperty("--current-color","")})}};customElements.get("open-classification")||customElements.define("open-classification",Te);var $e=class extends x{constructor(t,r,i){super(t,r,i);this.interactionMechanic="automatic-sequencing";this.categories=[];this.allItems=[];this.categorized=new Map;this.zones=[];this.chips=[];this.activeChip=null;this.currentZone=null;this.isDragging=!1;this.startX=0;this.startY=0;this.offsetX=0;this.offsetY=0;this.data.categories.forEach(({label:a,items:o})=>{this.categories.push(a),this.allItems.push(...o)}),this.data.distractors&&console.warn("Found a distractor in a Sequential Classification interaction, those are not useful and will be ignored"),this.allItems=this.config.shuffle?S(this.allItems):this.allItems,this.initializeProgress(this.allItems.length),this.boundPointerMove=this.handlePointerMove.bind(this),this.boundPointerUp=this.handlePointerUp.bind(this),this.variant=this.config.variant}initialize(){window.addEventListener("pointermove",this.boundPointerMove),window.addEventListener("pointerup",this.boundPointerUp)}cleanup(){window.removeEventListener("pointermove",this.boundPointerMove),window.removeEventListener("pointerup",this.boundPointerUp)}onVariantChange(t){this.querySelectorAll("edu-chip, edu-block").forEach(r=>{r.variant!==void 0&&(r.variant=t)}),this.variant=t}render(){let t=Math.min(this.categories.length,4);this.innerHTML=`
2586
+ <style>
2587
+ sequential-classification {
2588
+ display: flex;
2589
+ width: 100%;
2590
+ height: 100%;
2591
+ box-sizing: border-box;
2592
+ container-type: size;
2593
+ container-name: sequential-classification;
2594
+ }
2595
+
2596
+ #container {
2597
+ position: relative;
2598
+ display: flex;
2599
+ flex-direction: column;
2600
+ width: 100%;
2601
+ height: 100%;
2602
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2603
+ padding: clamp(0.75rem, min(2cqw, 2cqh), 1.5rem);
2604
+ background: rgb(var(--edu-bg));
2605
+ border-radius: clamp(8px, 2cqw, 12px);
2606
+ overflow: hidden;
2607
+ box-sizing: border-box;
2608
+ }
2609
+
2610
+ .center-zone-container {
2611
+ flex-shrink: 0;
2612
+ display: flex;
2613
+ flex-direction: column;
2614
+ gap: clamp(0.25rem, min(1cqw, 1cqh), 0.5rem);
2615
+ }
2616
+
2617
+ .center-zone-label {
2618
+ font-size: clamp(0.8rem, 1.8cqh, 1rem);
2619
+ font-weight: 600;
2620
+ color: rgb(var(--edu-second-ink));
2621
+ }
2622
+
2623
+ #center-zone {
2624
+ min-height: clamp(70px, 12cqh, 120px);
2625
+ height: clamp(70px, 12cqh, 120px);
2626
+ display: flex;
2627
+ align-items: center;
2628
+ justify-content: center;
2629
+ background: rgba(var(--edu-muted), 0.5);
2630
+ border-radius: clamp(8px, 2cqw, 12px);
2631
+ border: 2px dashed rgb(var(--edu-border));
2632
+ position: relative;
2633
+ }
2634
+
2635
+ #center-zone.empty::before {
2636
+ content: 'All items categorized!';
2637
+ color: rgb(var(--edu-third-ink));
2638
+ font-size: 0.9rem;
2639
+ opacity: 0.6;
2640
+ }
2641
+
2642
+ .zones-container {
2643
+ flex: 1;
2644
+ display: flex;
2645
+ flex-direction: column;
2646
+ gap: clamp(0.25rem, min(1cqw, 1cqh), 0.5rem);
2647
+ min-height: 0;
2648
+ overflow: hidden;
2649
+ }
2650
+
2651
+ .zones-label {
2652
+ font-size: clamp(0.8rem, 1.8cqh, 1rem);
2653
+ font-weight: 600;
2654
+ color: rgb(var(--edu-second-ink));
2655
+ flex-shrink: 0;
2656
+ }
2657
+
2658
+ #zones-grid {
2659
+ position: relative;
2660
+ flex: 1;
2661
+ display: grid;
2662
+ grid-template-columns: repeat(${t}, minmax(0, 1fr));
2663
+ grid-auto-rows: minmax(44px, 1fr);
2664
+ gap: clamp(0.5rem, min(1.5cqw, 1.5cqh), 1rem);
2665
+ overflow-y: auto;
2666
+ overflow-x: hidden;
2667
+ align-content: stretch;
2668
+ padding: clamp(0.25rem, min(1cqw, 1cqh), 0.5rem);
2669
+ min-height: 0;
2670
+ }
2671
+
2672
+ .zone {
2673
+ border-radius: 8px;
2674
+ box-shadow: 0 4px 6px -1px rgb(var(--edu-shadow-color) / 0.1);
2675
+ transition: all 0.3s ease;
2676
+ font-weight: 700;
2677
+ font-size: clamp(1rem, 3cqh, 1.6rem);
2678
+ text-align: center;
2679
+ border: 3px solid transparent;
2680
+ opacity: 0.8;
2681
+ display: flex;
2682
+ align-items: center;
2683
+ justify-content: center;
2684
+ position: relative;
2685
+ height: 100%;
2686
+ }
2687
+
2688
+ .zone.highlight {
2689
+ transform: scale(1.02);
2690
+ opacity: 1;
2691
+ box-shadow: 0 8px 16px rgba(var(--edu-first-accent), 0.3);
2692
+ }
2693
+
2694
+ .zone.empty::after {
2695
+ content: 'Drop here';
2696
+ position: absolute;
2697
+ bottom: 0.5rem;
2698
+ font-size: clamp(0.7rem, 1.8cqh, 0.9rem);
2699
+ font-weight: 500;
2700
+ opacity: 0.4;
2701
+ color: rgb(var(--edu-ink));
2702
+ }
2703
+
2704
+ edu-block::part(block) {
2705
+ height: 100%;
2706
+ }
2707
+
2708
+ edu-chip {
2709
+ position: absolute;
2710
+ user-select: none;
2711
+ touch-action: none;
2712
+ transition: transform 0.2s ease;
2713
+ }
2714
+
2715
+ edu-chip:hover {
2716
+ transform: scale(1.05);
2717
+ }
2718
+
2719
+ edu-chip.dragging {
2720
+ }
2721
+
2722
+ @container sequential-classification (max-width: 920px) {
2723
+ #zones-grid {
2724
+ grid-template-columns: repeat(${Math.min(t,2)}, 1fr);
2725
+ }
2726
+ }
2727
+
2728
+ @container sequential-classification (max-width: 620px) {
2729
+ #zones-grid {
2730
+ grid-template-columns: 1fr;
2731
+ }
2732
+ }
2733
+ </style>
2734
+ <div id="container">
2735
+ <div class="center-zone-container">
2736
+ <div class="center-zone-label">Current Item</div>
2737
+ <div id="center-zone"></div>
2738
+ </div>
2739
+ <div class="zones-container">
2740
+ <div class="zones-label">Categories (Drag item to classify)</div>
2741
+ <div id="zones-grid"></div>
2742
+ </div>
2743
+ </div>
2744
+ `,this.container=this.querySelector("#container"),this.centerZone=this.querySelector("#center-zone"),this.zonesGrid=this.querySelector("#zones-grid"),this.createDropZones(),this.showNextChip()}createDropZones(){let t=this.querySelector("#zones-grid");this.categories.forEach((r,i)=>{let a=document.createElement("edu-block");a.variant=this.variant,a.setAccentColor(V[i%V.length]),a.classList.add("zone","empty"),a.textContent=`${r}: 0`,a.dataset.label=r,t.appendChild(a),this.zones.push(a)})}showNextChip(){let t=this.allItems.find(i=>!this.categorized.has(i));if(!t){this.centerZone.classList.add("empty");return}let r=document.createElement("edu-chip");r.variant=this.variant,L(t,r,this.assets?.assetsById),r.prefix=(this.allItems.indexOf(t)+1).toString(),r.draggable=!0,r.dataset.label=t,r.addEventListener("pointerdown",i=>this.handlePointerDown(i,r)),this.container.appendChild(r),this.chips.push(r),requestAnimationFrame(()=>{let i=this.centerZone.getBoundingClientRect(),a=this.container.getBoundingClientRect(),o=r.getBoundingClientRect(),s=i.left-a.left+(i.width-o.width)/2,l=i.top-a.top+(i.height-o.height)/2;r.style.left=`${s}px`,r.style.top=`${l}px`})}reparentChip(t,r){if(t.parentElement===r)return;let i=t.getBoundingClientRect(),a=r.getBoundingClientRect(),o=i.left-a.left,s=i.top-a.top;r===this.zonesGrid&&(o+=this.zonesGrid.scrollLeft,s+=this.zonesGrid.scrollTop),t.style.left=`${o}px`,t.style.top=`${s}px`,r.appendChild(t)}handlePointerDown(t,r){t.preventDefault(),this.reparentChip(r,this.container),this.activeChip=r,this.isDragging=!0,r.classList.add("dragging");let i=r.getBoundingClientRect(),a=this.container.getBoundingClientRect();this.offsetX=t.clientX-i.left,this.offsetY=t.clientY-i.top,this.chips.forEach(o=>{o!==r&&(o.style.opacity="0.3")}),this.handlePointerMove(t)}handlePointerMove(t){if(!this.isDragging||!this.activeChip)return;let r=this.container.getBoundingClientRect(),i=t.clientX-r.left-this.offsetX,a=t.clientY-r.top-this.offsetY,o=this.activeChip.getBoundingClientRect();i=Math.max(0,Math.min(i,r.width-o.width)),a=Math.max(0,Math.min(a,r.height-o.height)),this.activeChip.style.left=`${i}px`,this.activeChip.style.top=`${a}px`,this.checkZoneOverlap(t.clientX,t.clientY)}handlePointerUp(t){if(!this.isDragging||!this.activeChip)return;this.isDragging=!1,this.chips.forEach(i=>i.style.opacity="1"),this.activeChip.classList.remove("dragging");let r=this.activeChip.dataset.label;if(this.currentZone){let i=this.currentZone.dataset.label,a=this.categorized.get(r);a!==i&&(this.categorized.set(r,i),this.emitStateChange(),a===void 0&&(this.incrementProgress(),this.showNextChip()),a===null&&this.incrementProgress()),this.reparentChip(this.activeChip,this.zonesGrid)}else this.categorized.get(r)&&(this.categorized.set(r,null),this.decrementProgress()),this.reparentChip(this.activeChip,this.container);this.zones.forEach(i=>{i.classList.remove("highlight");let a=Array.from(this.categorized.values()).filter(o=>o===i.dataset.label).length;i.textContent=`${i.dataset.label}: ${a}`,a>0?i.classList.remove("empty"):i.classList.add("empty")}),this.activeChip=null,this.currentZone=null}checkZoneOverlap(t,r){this.currentZone=null;for(let i of this.zones){let a=i.getBoundingClientRect();t>=a.left&&t<=a.right&&r>=a.top&&r<=a.bottom?(i.classList.add("highlight"),this.currentZone=i):i.classList.remove("highlight")}}getCurrentState(){return{categorized:Object.fromEntries(this.categorized),progress:this.progressTracker.current}}isInteractionComplete(){return this.categorized.size===this.allItems.length}onHint(){let t=this.allItems.filter(a=>!this.categorized.has(a));if(t.length===0){alert('All items are categorized! Click "Check" to submit.'),this.emitHintShown("All items categorized");return}let r=t[0],i=this.data.categories.find(a=>a.items.includes(r))?.label;i&&(alert(`Hint: "${r}" belongs to "${i}".`),this.emitHintShown(`Item: ${r} \u2192 Category: ${i}`))}submit(){super.submit();let t=ke(this.data.categories,this.categorized,this);console.log(`Classification Score: ${t.score.toFixed(1)}% (${t.correct}/${t.total} correct)`),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this.categorized.clear(),this.chips.forEach(t=>t.remove()),this.chips=[],this.centerZone.classList.remove("empty"),this.activeChip=null,this.currentZone=null,this.isDragging=!1,this.zonesGrid&&(this.zonesGrid.scrollTop=0),this.showNextChip()}};customElements.get("sequential-classification")||customElements.define("sequential-classification",$e);function ei(e,n){let t=0,r=e.data.length;e.data.forEach(o=>{let s=new Set(o.correctOptions),l=new Set(n[o.question]||[]),c=0,d=0,u=0;l.forEach(m=>{s.has(m)?c++:d++}),s.forEach(m=>{l.has(m)||u++});let p=s.size,h=c-d-u,g=Math.max(0,h/p*100);t+=g});let i=Math.round(t/r),a=0;return e.data.forEach(o=>{let s=new Set(o.correctOptions),l=new Set(n[o.question]||[]);s.size===l.size&&[...s].every(c=>l.has(c))&&a++}),{score:i,correct:a,total:r}}var J=class extends x{constructor(t,r,i){super(t,r,i);this.interactionMechanic="sequential";this.currentQuestionIndex=0;this.userAnswers={};this.shuffledOptions=new Map;this.isGraded=!1;this.data.data.forEach(a=>{this.userAnswers[a.question]=[],this.config.shuffle?this.shuffledOptions.set(a.question,S([...a.options])):this.shuffledOptions.set(a.question,[...a.options])}),this.variant=this.config.variant,this.initializeProgress(this.data.data.length)}get slidesCount(){return this.data.data.length}initialize(){}cleanup(){}onVariantChange(t){this.querySelectorAll("edu-chip, edu-block").forEach(r=>{r.variant!==void 0&&(r.variant=t)}),this.variant=t}setSteps(t){let r=t-1;r>=0&&r<this.data.data.length&&(this.currentQuestionIndex=r,this.renderCurrentQuestion())}render(){this.innerHTML=`
2745
+ <style>
2746
+ mcq-interaction {
2747
+ display: flex;
2748
+ width: 100%;
2749
+ height: 100%;
2750
+ box-sizing: border-box;
2751
+ container-type: size;
2752
+ container-name: mcq;
2753
+ }
2754
+
2755
+ .container {
2756
+ display: flex;
2757
+ flex-direction: column;
2758
+ width: 100%;
2759
+ height: 100%;
2760
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2761
+ padding: clamp(0.75rem, min(2cqw, 2cqh), 1.5rem);
2762
+ box-sizing: border-box;
2763
+ overflow: hidden;
2764
+ }
2765
+
2766
+ .mode-label {
2767
+ align-self: flex-start;
2768
+ font-size: 0.75rem;
2769
+ font-weight: 600;
2770
+ color: rgb(var(--edu-third-ink));
2771
+ text-transform: uppercase;
2772
+ letter-spacing: 0.5px;
2773
+ opacity: 0.7;
2774
+ margin-bottom: clamp(0.25rem, 1cqh, 0.5rem);
2775
+ }
2776
+
2777
+ .question-section {
2778
+ flex-shrink: 0;
2779
+ display: flex;
2780
+ flex-direction: column;
2781
+ min-height: clamp(64px, 10cqh, 120px);
2782
+ max-height: clamp(120px, 30cqh, 260px);
2783
+ overflow: hidden;
2784
+ }
2785
+
2786
+ .question-text {
2787
+ padding: 0;
2788
+ font-size: clamp(0.95rem, 2.4cqh, 1.2rem);
2789
+ font-weight: 600;
2790
+ color: rgb(var(--edu-ink));
2791
+ line-height: 1.4;
2792
+ }
2793
+
2794
+ .divider {
2795
+ border: none;
2796
+ border-top: 1px solid rgb(var(--edu-border));
2797
+ margin: 0;
2798
+ flex-shrink: 0;
2799
+ }
2800
+
2801
+ .options-section {
2802
+ flex: 1;
2803
+ display: flex;
2804
+ flex-direction: column;
2805
+ gap: clamp(0.25rem, min(1cqw, 1cqh), 0.5rem);
2806
+ min-height: 0;
2807
+ overflow: hidden;
2808
+ }
2809
+
2810
+ .options-label {
2811
+ font-size: clamp(0.8rem, 1.8cqh, 1rem);
2812
+ font-weight: 600;
2813
+ color: rgb(var(--edu-second-ink));
2814
+ flex-shrink: 0;
2815
+ }
2816
+
2817
+ .options-container {
2818
+ flex: 1;
2819
+ display: grid;
2820
+ grid-template-columns: 1fr;
2821
+ grid-auto-rows: minmax(44px, 1fr);
2822
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 0.9rem);
2823
+ padding: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2824
+ background: rgb(var(--edu-muted));
2825
+ border-radius: clamp(6px, 1.6cqw, 8px);
2826
+ overflow-y: auto;
2827
+ overflow-x: hidden;
2828
+ min-height: 0;
2829
+ align-content: stretch;
2830
+ align-items: stretch;
2831
+ }
2832
+
2833
+ edu-chip {
2834
+ cursor: pointer;
2835
+ transition: all 0.2s ease;
2836
+ }
2837
+
2838
+ edu-chip::part(block) {
2839
+ width: 100%;
2840
+ height: 100%;
2841
+ }
2842
+
2843
+ edu-chip:hover {
2844
+ transform: translateY(-2px);
2845
+ }
2846
+
2847
+ edu-chip.selected {
2848
+ transform: translateY(-2px);
2849
+ }
2850
+
2851
+ #question-block edu-block::part(block) {
2852
+ border: none;
2853
+ padding: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2854
+ height: 100%;
2855
+ max-height: clamp(120px, 30cqh, 260px);
2856
+ overflow: auto;
2857
+ align-items: center;
2858
+ justify-content: flex-start;
2859
+ }
2860
+
2861
+ #question-block edu-block::part(block) > * {
2862
+ width: 100%;
2863
+ }
2864
+
2865
+ #question-block .question-text {
2866
+ text-align: left;
2867
+ }
2868
+
2869
+ @container mcq (min-width: 920px) {
2870
+ .options-container {
2871
+ grid-template-columns: repeat(2, minmax(min(100%, 220px), 1fr));
2872
+ }
2873
+ }
2874
+
2875
+ @container mcq (max-width: 620px) {
2876
+ .options-container {
2877
+ grid-template-columns: 1fr;
2878
+ padding: clamp(0.5rem, min(1.2cqw, 1.2cqh), 0.75rem);
2879
+ }
2880
+ }
2881
+ </style>
2882
+
2883
+ <div class="container">
2884
+ <div class="question-section">
2885
+ <div class="mode-label"></div>
2886
+ <div id="question-block"></div>
2887
+ </div>
2888
+
2889
+ <hr class="divider">
2890
+
2891
+ <div class="options-section">
2892
+ <div class="options-label">Options</div>
2893
+ <div class="options-container"></div>
2894
+ </div>
2895
+ </div>
2896
+ `,this.$modeLabel=this.querySelector(".mode-label"),this.$optionsContainer=this.querySelector(".options-container");let t=this.querySelector("#question-block");this.$questionBlock=document.createElement("edu-block"),this.$questionBlock.variant=this.config.variant,this.$questionBlock.innerHTML='<div class="question-text"></div>',t.appendChild(this.$questionBlock),this.$questionText=this.$questionBlock.querySelector(".question-text"),this.renderCurrentQuestion()}renderCurrentQuestion(){let t=this.data.data[this.currentQuestionIndex];if(!t)return;let r=t.correctOptions.length===1;this.$modeLabel.textContent=r?"Multiple Choice":"Multiple Response",wt(t.question,this.$questionText,this.assets?.assetsById);let i=this.shuffledOptions.get(t.question)||t.options;this.$optionsContainer.innerHTML="",i.forEach((a,o)=>{let s=document.createElement("edu-chip");s.variant=this.variant,s.prefix=`${o+1}:`,s.dataset.option=a,L(a,s,this.assets?.assetsById);let l=this.userAnswers[t.question]?.includes(a);if(l&&(s.selected=!0,s.classList.add("selected")),this.isGraded){let c=t.correctOptions.includes(a);l&&c?s.chipState="correct":l&&!c?s.chipState="wrong":!l&&c&&(s.chipState="missed")}this.isGraded||s.addEventListener("click",()=>{this.handleOptionClick(a,s,r)}),this.$optionsContainer.appendChild(s)})}handleOptionClick(t,r,i){let a=this.data.data[this.currentQuestionIndex],o=this.userAnswers[a.question];if(i){let s=o.includes(t);this.$optionsContainer.querySelectorAll("edu-chip").forEach(l=>{l.selected=!1,l.classList.remove("selected")}),this.userAnswers[a.question]=[],s||(r.selected=!0,r.classList.add("selected"),this.userAnswers[a.question]=[t])}else{let s=o.indexOf(t);s>-1?(o.splice(s,1),r.selected=!1,r.classList.remove("selected")):(o.push(t),r.selected=!0,r.classList.add("selected"))}this.updateProgress(),this.emitStateChange()}updateProgress(){let t=0;this.data.data.forEach(r=>{this.userAnswers[r.question]?.length>0&&t++}),this.setProgress(t)}getCurrentState(){return{...this.userAnswers}}isInteractionComplete(){return this.data.data.every(t=>this.userAnswers[t.question]?.length>0)}onHint(){let t=this.data.data[this.currentQuestionIndex];this.userAnswers[t.question]?.length>0?(alert("Hint: You've selected an answer. Review your choice and make sure it's correct before submitting."),this.emitHintShown(`Answer exists for question ${this.currentQuestionIndex+1}`)):(alert("Hint: This question requires at least one selection. Read the question carefully and choose the best answer(s)."),this.emitHintShown(`No answer selected for question ${this.currentQuestionIndex+1}`))}submit(){super.submit();let t=ei(this.data,this.userAnswers);console.log(`Recognition Score: ${t.score}% (${t.correct}/${t.total} questions fully correct)`),this.isGraded=!0,this.renderCurrentQuestion(),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0})),this.setAttribute("inert","")}reset(){super.reset(),this.data.data.forEach(t=>{this.userAnswers[t.question]=[]}),this.isGraded=!1,this.currentQuestionIndex=0,this.renderCurrentQuestion()}};customElements.get("mcq-interaction")||customElements.define("mcq-interaction",J);function yl(e){let n=[],t={},r=e.split(`
2897
+ `).map(s=>s.trim()).filter(Boolean),i=null,a=0;for(let s=0;s<r.length;s++){let l=r[s];if(l.startsWith("#")){i=l.substring(1).trim(),a++;continue}if(l.endsWith(";")){if(!i){t[`parse.noQuestion.line${s+1}`]=`Line ${s+1}: Found options without a preceding question (# question).`;continue}let c=l.slice(0,-1).trim(),d=c.match(/\[([^\]]+)\]/),u=[],p=c;d&&(u=d[1].split("|").map(w=>w.trim()).filter(Boolean),p=c.replace(/\[([^\]]+)\]/,"").trim());let h=p.split("|").map(b=>b.trim()).filter(Boolean),g=[...u,...h],m=new Set;for(let b of g){if(m.has(b)){t[`parse.duplicate.q${a}`]=`Question ${a}: Duplicate option "${b}" found.`;break}m.add(b)}n.push({question:i,correctOptions:u,options:g}),i=null}else t[`parse.missingSemicolon.line${s+1}`]=`Line ${s+1}: Options line must end with ';'.`}i&&(t["parse.danglingQuestion"]=`Question "${i}" has no options defined.`);let o={type:"recognition",data:n};return Object.keys(t).length>0?{data:o,errors:t}:{data:o}}function Cl(e){let n={};return!e.data||e.data.length===0?(n["validation.noQuestions"]="No questions found. Expected at least one question with format: # question\\n[correct] | incorrect;",{ok:!1,errors:n}):(e.data.forEach((t,r)=>{let i=r+1;if((!t.question||t.question.trim()==="")&&(n[`validation.emptyQuestion.q${i}`]=`Question ${i}: Question text cannot be empty.`),(!t.correctOptions||t.correctOptions.length===0)&&(n[`validation.noCorrectOptions.q${i}`]=`Question ${i}: Must have at least one correct answer. Use [correct] syntax.`),(!t.options||t.options.length<2)&&(n[`validation.insufficientOptions.q${i}`]=`Question ${i}: Must have at least 2 options (correct and incorrect).`),t.options&&t.options.forEach((a,o)=>{(!a||a.trim()==="")&&(n[`validation.emptyOption.q${i}.opt${o+1}`]=`Question ${i}, Option ${o+1}: Option text cannot be empty.`)}),t.correctOptions&&t.options&&t.correctOptions.forEach(a=>{t.options.includes(a)||(n[`validation.missingCorrectOption.q${i}`]=`Question ${i}: Correct option "${a}" not found in options array.`)}),t.options){let a=new Set;t.options.forEach(o=>{a.has(o)&&(n[`validation.duplicateOption.q${i}`]=`Question ${i}: Duplicate option "${o}" found.`),a.add(o)})}}),Object.keys(n).length>0?{ok:!1,errors:n}:{ok:!0})}function ti(e,n,t){let r=0;for(let[o,s]of n.entries()){let l=t.querySelector(`[data-val="${o}"]`),c=e.find(d=>d.left===o);c&&c.right===s?(l.chipState="correct",r++):l.chipState="wrong"}let i=e.length,a=i>0?r/i*100:0;return console.log(`Association Score: ${a.toFixed(1)}% (${r}/${i} correct)`),{score:a,correct:r,total:i,answerKey:e,userResponse:n}}var Ae=class extends x{constructor(t,r,i,a){super(t,r,i);this.interactionMechanic="static";this.leftItems=[];this.rightItems=[];this.matched=new Map;this.matchColors=new Map;this.data.pairs.forEach(({left:o,right:s})=>{this.leftItems.push(o),this.rightItems.push(s)}),this.data.distractors&&this.rightItems.push(...this.data.distractors),this.config.shuffle&&(this.leftItems=S(this.leftItems),this.rightItems=S(this.rightItems)),this.initializeProgress(this.leftItems.length),this.currentColor=V[0]}initialize(){}cleanup(){}onVariantChange(t){this.querySelectorAll("edu-chip").forEach(r=>{r.variant!==void 0&&(r.variant=t)})}render(){this.innerHTML=`
2898
+ <style>
2899
+ simultaneous-association {
2900
+ --current-color: #3b82f6;
2901
+ display: flex;
2902
+ width: 100%;
2903
+ height: 100%;
2904
+ box-sizing: border-box;
2905
+ container-type: size;
2906
+ container-name: association;
2907
+ }
2908
+
2909
+ .container {
2910
+ display: grid;
2911
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2912
+ gap: clamp(0.75rem, min(2.5cqw, 2.5cqh), 2rem);
2913
+ padding: clamp(0.75rem, min(2.5cqw, 2.5cqh), 2rem);
2914
+ width: 100%;
2915
+ height: 100%;
2916
+ align-content: stretch;
2917
+ box-sizing: border-box;
2918
+ }
2919
+
2920
+ .column {
2921
+ display: grid;
2922
+ grid-template-rows: auto 1fr;
2923
+ gap: clamp(0.25rem, min(1.2cqw, 1.2cqh), 0.75rem);
2924
+ width: 100%;
2925
+ min-width: 0;
2926
+ min-height: 0;
2927
+ }
2928
+
2929
+ .column-label {
2930
+ font-size: clamp(0.8rem, 1.8cqh, 1rem);
2931
+ font-weight: 600;
2932
+ color: rgb(var(--edu-second-ink));
2933
+ margin-bottom: 0.25rem;
2934
+ flex-shrink: 0;
2935
+ }
2936
+
2937
+ .items-list {
2938
+ display: grid;
2939
+ grid-template-columns: 1fr;
2940
+ grid-auto-rows: minmax(44px, 1fr);
2941
+ gap: clamp(0.35rem, min(1.2cqw, 1.2cqh), 0.75rem);
2942
+ min-height: 0;
2943
+ height: 100%;
2944
+ align-content: stretch;
2945
+ align-items: stretch;
2946
+ }
2947
+
2948
+ edu-chip:hover {
2949
+ transform: translateY(-2px);
2950
+ }
2951
+
2952
+ edu-chip {
2953
+ width: 100%;
2954
+ height: 100%;
2955
+ }
2956
+
2957
+ edu-chip::part(content-zone) {
2958
+ width: 100%;
2959
+ height: 100%;
2960
+ }
2961
+
2962
+ @container association (max-width: 640px) {
2963
+ .container {
2964
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2965
+ padding: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
2966
+ }
2967
+ }
2968
+
2969
+ @container association (max-height: 420px) {
2970
+ .items-list[data-compact="true"] {
2971
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2972
+ }
2973
+ }
2974
+
2975
+ @container association (max-width: 520px) {
2976
+ .items-list[data-compact="true"] {
2977
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2978
+ }
2979
+ }
2980
+ </style>
2981
+
2982
+ <div class="container" id="columns-container">
2983
+ <div class="column">
2984
+ <div class="column-label">Left Items</div>
2985
+ <div class="items-list" id="left-col" data-compact="${this.leftItems.length>=7}"></div>
2986
+ </div>
2987
+ <div class="column">
2988
+ <div class="column-label">Right Items</div>
2989
+ <div class="items-list" id="right-col" data-compact="${this.rightItems.length>=7}"></div>
2990
+ </div>
2991
+ </div>
2992
+ `,this.$leftCol=this.querySelector("#left-col"),this.$rightCol=this.querySelector("#right-col"),this.renderItems()}renderItems(){this.leftItems.forEach((t,r)=>{let i=document.createElement("edu-chip");i.variant=this.config.variant,L(t,i,this.assets?.assetsById),i.dataset.val=t,i.addEventListener("click",a=>{let o=a.currentTarget,s=o.dataset.val;if(this.currentSelected===s){o.selected=!1,this.currentSelected="",this.currentEl=null;return}if(this.matched.get(s)){let l=this.matched.get(s),c=this.querySelector(`[data-val="${l}"]`);o.color="",o.colored=!1,c.colored=!1,c.color="",this.matched.delete(s),this.matchColors.delete(s),this.decrementProgress(),this.emitStateChange();return}this.currentSelected&&(this.currentEl.selected=!1),this.currentSelected=s,this.currentEl=o,o.selected=!0}),this.$leftCol.append(i)}),this.rightItems.forEach((t,r)=>{let i=document.createElement("edu-chip");i.variant=this.config.variant,L(t,i,this.assets?.assetsById),i.dataset.val=t,i.dataset.colorIndex=`${r+1}`,i.addEventListener("click",a=>{let o=a.currentTarget,s=o.dataset.val;if(this.currentSelected===s){this.currentSelected="",this.currentEl=null,o.selected=!1;return}if(![...this.matched.values()].includes(s)){if(this.currentSelected)if(this.leftItems.includes(this.currentSelected)&&this.rightItems.includes(s)){let c=Number(o.dataset.colorIndex)%V.length,d=V[c];this.matched.set(this.currentSelected,s),this.matchColors.set(this.currentSelected,d),o.selected=!1,this.currentEl.selected=!1,o.color=d,o.colored=!0,this.currentEl.color=d,this.currentEl.colored=!0,this.incrementProgress(),this.emitStateChange(),this.currentSelected="",this.currentEl=null;return}else this.currentEl.selected=!1;this.currentSelected=s,this.currentEl=o,o.selected=!0}}),this.$rightCol.append(i)})}getCurrentState(){return{matched:Object.fromEntries(this.matched),progress:this.progressTracker.current}}isInteractionComplete(){return this.matched.size===this.leftItems.length}onHint(){let t=this.leftItems.filter(i=>!this.matched.has(i));if(t.length===0){alert('All items are matched! Click "Check" to submit.'),this.emitHintShown("All items matched");return}let r=t[0];alert(`Hint: You haven't matched "${r}" yet. Select it from the left, then select its match from the right.`),this.emitHintShown(`Unmatched: ${r}`)}submit(){super.submit();let t=ti(this.data.pairs,this.matched,this);this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this.matched.clear(),this.matchColors.clear(),this.currentSelected="",this.currentEl=null,this.querySelectorAll("edu-chip").forEach(t=>{t.classList.remove("colorized","selected"),t.style.setProperty("--current-color","")})}};customElements.get("simultaneous-association")||customElements.define("simultaneous-association",Ae);var ee=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";this._recalledItems=new Set;this.initializeProgress(t.items.length)}initialize(){}cleanup(){}onVariantChange(t){this._$textInput&&(this._$textInput.variant=t),this._$addButton&&(this._$addButton.variant=t),this._$chipsContainer?.querySelectorAll("edu-chip").forEach(r=>{r.variant=t})}render(){this.innerHTML=`
2993
+ <style>
2994
+ list-recall {
2995
+ display: flex;
2996
+ flex-direction: column;
2997
+ width: 100%;
2998
+ height: 100%;
2999
+ padding: clamp(0.75rem, min(2cqw, 2cqh), 1.5rem);
3000
+ gap: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
3001
+ box-sizing: border-box;
3002
+ container-type: size;
3003
+ }
3004
+
3005
+ .chips-container {
3006
+ flex: 1;
3007
+ display: grid;
3008
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
3009
+ grid-auto-rows: minmax(44px, auto);
3010
+ gap: clamp(0.4rem, min(1.4cqw, 1.4cqh), 0.75rem);
3011
+ padding: clamp(0.5rem, min(1.6cqw, 1.6cqh), 1rem);
3012
+ border: 2px dashed rgb(var(--edu-border));
3013
+ border-radius: clamp(6px, 1.6cqw, 8px);
3014
+ background: rgb(var(--edu-bg));
3015
+ overflow-y: auto;
3016
+ align-content: start;
3017
+ min-height: 0;
3018
+ }
3019
+
3020
+ .chips-container:empty::before {
3021
+ content: 'Your recalled items will appear here...';
3022
+ color: rgb(var(--edu-second-ink));
3023
+ font-size: 0.95rem;
3024
+ opacity: 0.6;
3025
+ font-style: italic;
3026
+ }
3027
+
3028
+ hr {
3029
+ width: 100%;
3030
+ border: none;
3031
+ border-top: 1px solid rgb(var(--edu-border));
3032
+ margin: 0;
3033
+ }
3034
+
3035
+ .input-row {
3036
+ display: flex;
3037
+ gap: clamp(0.4rem, min(1.4cqw, 1.4cqh), 0.75rem);
3038
+ align-items: center;
3039
+ flex-shrink: 0;
3040
+ }
3041
+
3042
+ .input-row edu-input[type="text"] {
3043
+ flex: 1;
3044
+ }
3045
+
3046
+ .input-row edu-input[type="button"] {
3047
+ flex-shrink: 0;
3048
+ }
3049
+
3050
+ edu-chip {
3051
+ cursor: pointer;
3052
+ transition: opacity 0.2s ease;
3053
+ }
3054
+
3055
+ edu-chip:hover {
3056
+ opacity: 0.7;
3057
+ }
3058
+
3059
+ @container (max-width: 640px) {
3060
+ .chips-container {
3061
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 120px), 1fr));
3062
+ }
3063
+ }
3064
+ </style>
3065
+
3066
+ <div class="chips-container"></div>
3067
+ <hr>
3068
+ <div class="input-row">
3069
+ <edu-input type="text" placeholder="Enter an item..."></edu-input>
3070
+ <edu-input as="button">Add</edu-input>
3071
+ </div>
3072
+ `,this._$chipsContainer=this.querySelector(".chips-container"),this._$textInput=this.querySelector('edu-input[type="text"]'),this._$addButton=this.querySelector('edu-input[as="button"]'),this._$textInput.variant=this.config.variant,this._$addButton.variant=this.config.variant,this._$addButton.addEventListener("click",()=>this.handleAddItem()),this._$textInput.addEventListener("keydown",t=>{t.key==="Enter"&&(t.preventDefault(),this.handleAddItem())})}handleAddItem(){let t=this._$textInput.value.trim();if(!t)return;let r=t.toLowerCase();if(this._recalledItems.has(r)){alert("You have already added this item."),this._$textInput.value="";return}if(this._recalledItems.size>=this.data.items.length){alert(`You can only add up to ${this.data.items.length} items.`),this._$textInput.value="";return}this._recalledItems.add(r),this.addChip(t),this._$textInput.value="",this.setProgress(this._recalledItems.size),this.emitStateChange()}addChip(t){let r=document.createElement("edu-chip");r.textContent=t,r.variant=this.config.variant,r.value=t.toLowerCase(),r.addEventListener("click",()=>{let i=r.value;this._recalledItems.delete(i),r.remove(),this.setProgress(this._recalledItems.size),this.emitStateChange()}),this._$chipsContainer.appendChild(r)}getCurrentState(){return Array.from(this._recalledItems)}isInteractionComplete(){return this._recalledItems.size===this.data.items.length}onHint(){let t=this._recalledItems.size,r=this.data.items.length;t===0?(alert(`Hint: Try to recall all ${r} items from memory.`),this.emitHintShown("No items recalled yet")):t<r?(alert(`Hint: You've recalled ${t} out of ${r} items. Keep going!`),this.emitHintShown(`${t}/${r} items recalled`)):(alert(`Great! You've recalled all items. Click "Check" to submit.`),this.emitHintShown("All items recalled"))}submit(){super.submit();let t=this.gradeRecall();console.log(`List Recall Score: ${t.score.toFixed(1)}% (${t.correct}/${t.total} correct)`),this.applyGradingFeedback(t),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}gradeRecall(){let t=this.data.items.map(s=>s.toLowerCase()),r=Array.from(this._recalledItems),i=0;for(let s of r)t.includes(s)&&i++;let a=this.data.items.length;return{score:a>0?Math.round(i/a*100):0,correct:i,total:a,answerKey:this.data.items,userResponse:r}}applyGradingFeedback(t){let r=this.data.items.map(a=>a.toLowerCase());this._$chipsContainer.querySelectorAll("edu-chip").forEach(a=>{let o=a.value;r.includes(o)?a.chipState="correct":a.chipState="wrong"})}reset(){super.reset(),this._recalledItems.clear(),this._$chipsContainer.innerHTML="";let t=this._$textInput.querySelector(".control");t&&(t.value=""),this.setProgress(0)}};customElements.get("list-recall")||customElements.define("list-recall",ee);var _e=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";let i=ue(t.answerKey),a=ze(i);this._tableConfig={rows:t.rows,cols:t.cols,answerKey:t.answerKey,cellKind:a,preset:"lookup",disabled:(s,l)=>t.answerKey[s]?.[l]===null,allowed:a==="select"?()=>Be(t.answerKey):void 0,variant:r.variant??"outline",shuffle:r.shuffle??!1};let o=0;for(let s of t.rows)for(let l of t.cols)t.answerKey[s]?.[l]!==null&&o++;this.initializeProgress(o)}initialize(){}cleanup(){}onVariantChange(t){this._tableConfig.variant=t,this._$table&&this._$table.setAttribute("variant",t)}render(){this._tableConfig.variant=this.config.variant,this._$table=document.createElement("edu-table"),this._$table.config=this._tableConfig,this._$table.addEventListener("change",()=>{this.updateProgressBasedOnCompletion(),this.emitStateChange()}),this.innerHTML=`
3073
+ <style>
3074
+ :host {
3075
+ display: flex;
3076
+ width: 100%;
3077
+ height: 100%;
3078
+ box-sizing: border-box;
3079
+ }
3080
+
3081
+ .table-container {
3082
+ display: flex;
3083
+ flex-direction: column;
3084
+ width: 100%;
3085
+ height: 100%;
3086
+ overflow: hidden;
3087
+ box-sizing: border-box;
3088
+ }
3089
+
3090
+ .table-wrapper {
3091
+ flex: 1;
3092
+ overflow-y: auto;
3093
+ overflow-x: auto;
3094
+ min-height: 0;
3095
+ padding: 1rem;
3096
+ }
3097
+ </style>
3098
+ <div class="table-container">
3099
+ <div class="table-wrapper"></div>
3100
+ </div>
3101
+ `,this.querySelector(".table-wrapper").appendChild(this._$table)}updateProgressBasedOnCompletion(){let t=this._$table.getState(),r=0;for(let i of this.data.rows)for(let a of this.data.cols){if(this.data.answerKey[i]?.[a]===null)continue;let o=t[i]?.values[a];o!=null&&o!==""&&r++}this.setProgress(r)}getCurrentState(){return this._$table.getState()}isInteractionComplete(){let t=this._$table.getState();for(let r of this.data.rows)for(let i of this.data.cols){if(this.data.answerKey[r]?.[i]===null)continue;let a=t[r]?.values[i];if(a==null||a==="")return!1}return!0}onHint(){let t=this._$table.getState();for(let r of this.data.rows)for(let i of this.data.cols){if(this.data.answerKey[r]?.[i]===null)continue;let a=t[r]?.values[i];if(a==null||a===""){alert(`Hint: You haven't filled the cell for "${r}" / "${i}" yet.`),this.emitHintShown(`Empty cell: ${r} / ${i}`);return}}alert('All cells are complete! Click "Check" to submit.'),this.emitHintShown("All cells complete")}submit(){super.submit();let t=this.getCurrentState(),r=Ct(this.data.answerKey,t,this.data.rows,this.data.cols),i=$t(this.data.answerKey,t,this.data.rows,this.data.cols);this._$table.setGradingState(i),console.log(`Lookup Table Score: ${r.score.toFixed(1)}% (${r.correct}/${r.total} correct)`),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:r},bubbles:!0,composed:!0}))}reset(){super.reset(),this._$table&&(this._$table.reset(),this._$table.clearGradingState())}};customElements.get("lookup-table")||customElements.define("lookup-table",_e);var Ie=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";this._tableConfig={rows:t.rows,cols:t.cols,answerKey:t.answerKey,cellKind:"checkbox",preset:"classification",variant:r.variant??"outline",shuffle:r.shuffle},this.initializeProgress(t.rows.length)}initialize(){}cleanup(){}onVariantChange(t){this._tableConfig.variant=t,this._$table&&this._$table.setAttribute("variant",t)}render(){this._tableConfig.variant=this.config.variant,this._$table=document.createElement("edu-table"),this._$table.config=this._tableConfig,this._$table.addEventListener("change",()=>{this.updateProgressBasedOnCompletion(),this.emitStateChange()}),this.innerHTML="",this.appendChild(this._$table)}updateProgressBasedOnCompletion(){let t=this._$table.getState(),r=0;for(let i of this.data.rows)t[i]?.selectedCols.length>0&&r++;this.setProgress(r)}getCurrentState(){return this._$table.getState()}isInteractionComplete(){let t=this._$table.getState();return this.data.rows.every(r=>t[r]?.selectedCols.length>0)}onHint(){let t=this._$table.getState(),r=this.data.rows.filter(a=>!t[a]||t[a].selectedCols.length===0);if(r.length===0){alert('All rows are complete! Click "Check" to submit.'),this.emitHintShown("All rows complete");return}let i=r[0];alert(`Hint: You haven't classified "${i}" yet. Which categories does it belong to?`),this.emitHintShown(`Incomplete row: ${i}`)}submit(){super.submit();let t=this.getCurrentState(),r=St(this.data.answerKey,t,this.data.rows,this.data.cols),i=At(this.data.answerKey,t,this.data.rows,this.data.cols);this._$table.setGradingState(i),console.log(`Classification Score: ${r.score.toFixed(1)}% (${r.correct}/${r.total} correct)`),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:r},bubbles:!0,composed:!0}))}reset(){super.reset(),this._$table&&(this._$table.reset(),this._$table.clearGradingState())}};customElements.get("classification-matrix")||customElements.define("classification-matrix",Ie);var Me=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";this._tableConfig={rows:t.rows,cols:t.cols,answerKey:t.answerKey,cellKind:"radio",preset:"n-ary",variant:r.variant??"outline",shuffle:!0},this.initializeProgress(t.rows.length)}initialize(){}cleanup(){}onVariantChange(t){this._tableConfig.variant=t,this._$table&&this._$table.setAttribute("variant",t)}render(){this._tableConfig.variant=this.config.variant,this._$table=document.createElement("edu-table"),this._$table.config=this._tableConfig,this._$table.addEventListener("change",()=>{this.updateProgressBasedOnCompletion(),this.emitStateChange()}),this.innerHTML=`
3102
+ <style>
3103
+ nary-choice-table {
3104
+ display: flex;
3105
+ width: 100%;
3106
+ height: 100%;
3107
+ box-sizing: border-box;
3108
+ }
3109
+
3110
+ .table-container {
3111
+ display: flex;
3112
+ flex-direction: column;
3113
+ width: 100%;
3114
+ height: 100%;
3115
+ overflow: hidden;
3116
+ box-sizing: border-box;
3117
+ }
3118
+
3119
+ .table-wrapper {
3120
+ flex: 1;
3121
+ overflow-y: auto;
3122
+ overflow-x: auto;
3123
+ min-height: 0;
3124
+ padding: 1rem;
3125
+ }
3126
+ </style>
3127
+ <div class="table-container">
3128
+ <div class="table-wrapper"></div>
3129
+ </div>
3130
+ `,this.querySelector(".table-wrapper").appendChild(this._$table)}updateProgressBasedOnCompletion(){let t=this._$table.getState(),r=0;for(let i of this.data.rows)t[i]?.selectedCols.length===1&&r++;this.setProgress(r)}getCurrentState(){return this._$table.getState()}isInteractionComplete(){let t=this._$table.getState();return this.data.rows.every(r=>t[r]?.selectedCols.length===1)}onHint(){let t=this._$table.getState(),r=this.data.rows.filter(a=>!t[a]||t[a].selectedCols.length!==1);if(r.length===0){alert('All rows are complete! Click "Check" to submit.'),this.emitHintShown("All rows complete");return}let i=r[0];alert(`Hint: You haven't selected a category for "${i}" yet. Which one does it belong to?`),this.emitHintShown(`Incomplete row: ${i}`)}submit(){super.submit();let t=this.getCurrentState(),r=Et(this.data.answerKey,t,this.data.rows),i=_t(this.data.answerKey,t,this.data.rows);this._$table.setGradingState(i),console.log(`N-ary Choice Score: ${r.score.toFixed(1)}% (${r.correct}/${r.total} correct)`),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:r},bubbles:!0,composed:!0}))}reset(){super.reset(),this._$table&&(this._$table.reset(),this._$table.clearGradingState())}};customElements.get("nary-choice-table")||customElements.define("nary-choice-table",Me);var Le=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";let i=ue(t.answerKey),a=ze(i);this._tableConfig={rows:t.rows,cols:t.cols,answerKey:t.answerKey,cellKind:a,preset:"adjacency",disabled:(s,l)=>s===l,allowed:a==="select"?()=>Be(t.answerKey):void 0,variant:r.variant??"outline",shuffle:r.shuffle??!1};let o=t.rows.length*(t.rows.length-1);this.initializeProgress(o)}initialize(){}cleanup(){}onVariantChange(t){this._tableConfig.variant=t,this._$table&&this._$table.setAttribute("variant",t)}render(){this._tableConfig.variant=this.config.variant,this._$table=document.createElement("edu-table"),this._$table.config=this._tableConfig,this._$table.addEventListener("change",()=>{this.updateProgressBasedOnCompletion(),this.emitStateChange()}),this.innerHTML=`
3131
+ <style>
3132
+ :host {
3133
+ display: flex;
3134
+ width: 100%;
3135
+ height: 100%;
3136
+ box-sizing: border-box;
3137
+ }
3138
+
3139
+ .table-container {
3140
+ display: flex;
3141
+ flex-direction: column;
3142
+ width: 100%;
3143
+ height: 100%;
3144
+ overflow: hidden;
3145
+ box-sizing: border-box;
3146
+ }
3147
+
3148
+ .table-wrapper {
3149
+ flex: 1;
3150
+ overflow-y: auto;
3151
+ overflow-x: auto;
3152
+ min-height: 0;
3153
+ padding: 1rem;
3154
+ }
3155
+ </style>
3156
+ <div class="table-container">
3157
+ <div class="table-wrapper"></div>
3158
+ </div>
3159
+ `,this.querySelector(".table-wrapper").appendChild(this._$table)}updateProgressBasedOnCompletion(){let t=this._$table.getState(),r=0;for(let i of this.data.rows)for(let a of this.data.cols){if(i===a)continue;let o=t[i]?.values[a];o!=null&&o!==""&&r++}this.setProgress(r)}getCurrentState(){return this._$table.getState()}isInteractionComplete(){let t=this._$table.getState();for(let r of this.data.rows)for(let i of this.data.cols){if(r===i)continue;let a=t[r]?.values[i];if(a==null||a==="")return!1}return!0}onHint(){let t=this._$table.getState();for(let r of this.data.rows)for(let i of this.data.cols){if(r===i)continue;let a=t[r]?.values[i];if(a==null||a===""){alert(`Hint: You haven't filled the cell for "${r}" \u2192 "${i}" yet.`),this.emitHintShown(`Empty cell: ${r} \u2192 ${i}`);return}}alert('All cells are complete! Click "Check" to submit.'),this.emitHintShown("All cells complete")}submit(){super.submit();let t=this.getCurrentState(),r=kt(this.data.answerKey,t,this.data.rows),i=Tt(this.data.answerKey,t,this.data.rows);this._$table.setGradingState(i),console.log(`Adjacency Table Score: ${r.score.toFixed(1)}% (${r.correct}/${r.total} correct)`),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:r},bubbles:!0,composed:!0}))}reset(){super.reset(),this._$table&&(this._$table.reset(),this._$table.clearGradingState())}};customElements.get("adjacency-table")||customElements.define("adjacency-table",Le);var te=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";this._textConfig={data:t,mode:"highlight",variant:r.variant??"outline"},this.implementsProgress=!1}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}render(){this._textConfig.variant=this.config.variant,this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig,this._$text.addEventListener("change",()=>{this.emitStateChange()}),this.innerHTML=`
3160
+ <style>
3161
+ mark-the-words {
3162
+ display: flex;
3163
+ width: 100%;
3164
+ height: 100%;
3165
+ box-sizing: border-box;
3166
+ }
3167
+
3168
+ .text-container {
3169
+ display: flex;
3170
+ flex-direction: column;
3171
+ width: 100%;
3172
+ height: 100%;
3173
+ overflow: hidden;
3174
+ box-sizing: border-box;
3175
+ }
3176
+
3177
+ .text-wrapper {
3178
+ flex: 1;
3179
+ overflow-y: auto;
3180
+ overflow-x: auto;
3181
+ min-height: 0;
3182
+ padding: 1rem;
3183
+ }
3184
+ </style>
3185
+ <div class="text-container">
3186
+ <div class="text-wrapper"></div>
3187
+ </div>
3188
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getCurrentState(){return this._$text?this._$text.getValue():{selectedIndices:[]}}isInteractionComplete(){let t=this.getCurrentState(),r=new Set(t.selectedIndices??[]);for(let i of this.data.targets)for(let a=i.startPos;a<=i.endPos;a++)if(!r.has(a))return!1;return!0}onHint(){let t=this.getCurrentState(),r=new Set(t.selectedIndices??[]),i=[];for(let a of this.data.targets)for(let o=a.startPos;o<=a.endPos;o++)r.has(o)||i.push(o);if(i.length>0){let a=i[Math.floor(Math.random()*i.length)],o=this.data.parts[a];this.emitHintShown(`Try selecting: "${o}"`)}else this.emitHintShown("All target words have been selected!")}getUserData(){return this.getCurrentState()}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}grade(){let t=this.getUserData(),r=ve(this.data,t),i=we(this.data,t);return this._$text&&this._$text.setGradingState(i),r}reset(){super.reset(),this._$text&&(this._$text.reset(),this._$text.clearGradingState())}};customElements.get("mark-the-words")||customElements.define("mark-the-words",te);var re=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="sequential";this._slides=[];this._currentStep=0;this._responses={};this._gradingByStep={};this._isGraded=!1;if(this._slides=(Array.isArray(t)?t:[]).filter(i=>i.type==="base"),this._slides.length===0){this.isValid=!1,this.errors="SequentialMarkTheWords requires at least one base slide.";return}this._textConfig={data:this._slides[0],mode:"highlight",variant:r.variant??"outline"},this.initializeProgress(this.getTotalTargetCount())}get slidesCount(){return this._slides.length}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}setSteps(t){this.saveCurrentStepResponse();let r=Math.max(0,Math.min(this._slides.length-1,t-1));r!==this._currentStep&&(this._currentStep=r,this.render())}render(){if(this._slides.length===0)return;this._textConfig={data:this._slides[this._currentStep],mode:"highlight",variant:this.config.variant},this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig;let t=this._responses[this._currentStep];t?.selectedIndices&&this._$text.setState({selectedIndices:new Set(t.selectedIndices)});let r=this._gradingByStep[this._currentStep];this._isGraded&&r&&this._$text.setGradingState(r),this._$text.addEventListener("change",()=>{this.saveCurrentStepResponse(),this.updateProgressAcrossSteps(),this._isGraded&&(delete this._gradingByStep[this._currentStep],this._$text.clearGradingState()),this.emitStateChange()}),this.innerHTML=`
3189
+ <style>
3190
+ sequential-mark-the-words {
3191
+ display: flex;
3192
+ width: 100%;
3193
+ height: 100%;
3194
+ box-sizing: border-box;
3195
+ }
3196
+
3197
+ .text-container {
3198
+ display: flex;
3199
+ flex-direction: column;
3200
+ width: 100%;
3201
+ height: 100%;
3202
+ overflow: hidden;
3203
+ box-sizing: border-box;
3204
+ }
3205
+
3206
+ .text-wrapper {
3207
+ flex: 1;
3208
+ overflow-y: auto;
3209
+ overflow-x: auto;
3210
+ min-height: 0;
3211
+ padding: 1rem;
3212
+ }
3213
+ </style>
3214
+ <div class="text-container">
3215
+ <div class="text-wrapper"></div>
3216
+ </div>
3217
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getTargetCountForSlide(t){let r=0;for(let i of t.targets)r+=i.endPos-i.startPos+1;return r}getTotalTargetCount(){return this._slides.reduce((t,r)=>t+this.getTargetCountForSlide(r),0)}saveCurrentStepResponse(){this._$text&&(this._responses[this._currentStep]=this._$text.getValue())}getResponseForStep(t){return this._responses[t]??{selectedIndices:[]}}getTargetIndices(t){let r=new Set;for(let i of t.targets)for(let a=i.startPos;a<=i.endPos;a++)r.add(a);return r}updateProgressAcrossSteps(){let t=0;for(let r=0;r<this._slides.length;r++){let i=this._slides[r],a=this.getResponseForStep(r),o=new Set(a.selectedIndices??[]),s=this.getTargetIndices(i);for(let l of s)o.has(l)&&t++}this.setProgress(t)}getCurrentState(){return this.saveCurrentStepResponse(),{step:this._currentStep,responses:this._responses}}isInteractionComplete(){return this.getProgress().current===this.getProgress().total}onHint(){this.saveCurrentStepResponse();let t=this._slides[this._currentStep],r=this.getResponseForStep(this._currentStep),i=new Set(r.selectedIndices??[]),a=[];for(let o of t.targets)for(let s=o.startPos;s<=o.endPos;s++)i.has(s)||a.push(s);if(a.length>0){let o=a[Math.floor(Math.random()*a.length)];this.emitHintShown(`Try selecting: "${t.parts[o]}"`);return}this.emitHintShown("This step is complete. Move to another step or submit.")}grade(){this.saveCurrentStepResponse();let t=0,r=0,i={};for(let s=0;s<this._slides.length;s++){let l=this._slides[s],c=this.getResponseForStep(s),d=ve(l,c);t+=d.correct,r+=d.total,i[s]=we(l,c)}this._gradingByStep=i,this._isGraded=!0;let a=this._gradingByStep[this._currentStep];return a&&this._$text.setGradingState(a),{score:r>0?Math.round(t/r*100):0,correct:t,total:r}}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this._responses={},this._gradingByStep={},this._isGraded=!1,this._currentStep=0,this._$text&&(this._$text.reset(),this._$text.clearGradingState()),this.setProgress(0),this.render()}};customElements.get("sequential-mark-the-words")||customElements.define("sequential-mark-the-words",re);var ie=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";this._textConfig={data:t,mode:"classification",variant:r.variant??"outline"},this.implementsProgress=!1}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}render(){this._textConfig.variant=this.config.variant,this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig,this._$text.addEventListener("change",()=>{this.emitStateChange()}),this.innerHTML=`
3218
+ <style>
3219
+ categorize-the-words {
3220
+ display: flex;
3221
+ width: 100%;
3222
+ height: 100%;
3223
+ box-sizing: border-box;
3224
+ }
3225
+
3226
+ .text-container {
3227
+ display: flex;
3228
+ flex-direction: column;
3229
+ width: 100%;
3230
+ height: 100%;
3231
+ overflow: hidden;
3232
+ box-sizing: border-box;
3233
+ }
3234
+
3235
+ .text-wrapper {
3236
+ flex: 1;
3237
+ overflow-y: auto;
3238
+ overflow-x: auto;
3239
+ min-height: 0;
3240
+ padding: 1rem;
3241
+ }
3242
+ </style>
3243
+ <div class="text-container">
3244
+ <div class="text-wrapper"></div>
3245
+ </div>
3246
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getTargetIndices(){let t=new Set;for(let r of this.data.targets)for(let i of r.targets)for(let a=i.startPos;a<=i.endPos;a++)t.add(a);return t}getCurrentState(){return this._$text?this._$text.getValue():{wordCategories:{}}}isInteractionComplete(){let t=this.getCurrentState(),r=this.getTargetIndices();for(let i of r)if(!t.wordCategories[i])return!1;return!0}onHint(){let t=this.getCurrentState();for(let r of this.data.targets)for(let i of r.targets)for(let a=i.startPos;a<=i.endPos;a++)if(!t.wordCategories[a]){this.emitHintShown(`Try categorizing "${this.data.parts[a]}"`);return}this.emitHintShown("All target words are categorized.")}grade(){let t=this.getCurrentState(),r=Ce(this.data,t),i=Se(this.data,t);return this._$text&&this._$text.setGradingState(i),r}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this._$text&&(this._$text.reset(),this._$text.clearGradingState())}};customElements.get("categorize-the-words")||customElements.define("categorize-the-words",ie);var ne=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="sequential";this._slides=[];this._currentStep=0;this._responses={};this._gradingByStep={};this._isGraded=!1;if(this._slides=(Array.isArray(t)?t:[]).filter(i=>i.type==="classification"),this._slides.length===0){this.isValid=!1,this.errors="SequentialCategorizeTheWords requires at least one classification slide.";return}this._textConfig={data:this._slides[0],mode:"classification",variant:r.variant??"outline"},this.initializeProgress(this.getTotalTargetCount())}get slidesCount(){return this._slides.length}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}setSteps(t){this.saveCurrentStepResponse();let r=Math.max(0,Math.min(this._slides.length-1,t-1));r!==this._currentStep&&(this._currentStep=r,this.render())}render(){if(this._slides.length===0)return;this._textConfig={data:this._slides[this._currentStep],mode:"classification",variant:this.config.variant},this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig;let t=this._responses[this._currentStep];t?.wordCategories&&this._$text.setState({wordCategories:t.wordCategories});let r=this._gradingByStep[this._currentStep];this._isGraded&&r&&this._$text.setGradingState(r),this._$text.addEventListener("change",()=>{this.saveCurrentStepResponse(),this.updateProgressAcrossSteps(),this._isGraded&&(delete this._gradingByStep[this._currentStep],this._$text.clearGradingState()),this.emitStateChange()}),this.innerHTML=`
3247
+ <style>
3248
+ sequential-categorize-the-words {
3249
+ display: flex;
3250
+ width: 100%;
3251
+ height: 100%;
3252
+ box-sizing: border-box;
3253
+ }
3254
+
3255
+ .text-container {
3256
+ display: flex;
3257
+ flex-direction: column;
3258
+ width: 100%;
3259
+ height: 100%;
3260
+ overflow: hidden;
3261
+ box-sizing: border-box;
3262
+ }
3263
+
3264
+ .text-wrapper {
3265
+ flex: 1;
3266
+ overflow-y: auto;
3267
+ overflow-x: auto;
3268
+ min-height: 0;
3269
+ padding: 1rem;
3270
+ }
3271
+ </style>
3272
+ <div class="text-container">
3273
+ <div class="text-wrapper"></div>
3274
+ </div>
3275
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getTargetIndices(t){let r=new Set;for(let i of t.targets)for(let a of i.targets)for(let o=a.startPos;o<=a.endPos;o++)r.add(o);return r}getTotalTargetCount(){return this._slides.reduce((t,r)=>t+this.getTargetIndices(r).size,0)}saveCurrentStepResponse(){this._$text&&(this._responses[this._currentStep]=this._$text.getValue())}getResponseForStep(t){return this._responses[t]??{wordCategories:{}}}updateProgressAcrossSteps(){let t=0;for(let r=0;r<this._slides.length;r++){let i=this._slides[r],a=this.getResponseForStep(r),o=this.getTargetIndices(i);for(let s of o)a.wordCategories[s]&&t++}this.setProgress(t)}getCurrentState(){return this.saveCurrentStepResponse(),{step:this._currentStep,responses:this._responses}}isInteractionComplete(){return this.getProgress().current===this.getProgress().total}onHint(){this.saveCurrentStepResponse();let t=this._slides[this._currentStep],r=this.getResponseForStep(this._currentStep),i=this.getTargetIndices(t);for(let a of i)if(!r.wordCategories[a]){this.emitHintShown(`Try categorizing "${t.parts[a]}"`);return}this.emitHintShown("This step is complete. Move to another step or submit.")}grade(){this.saveCurrentStepResponse();let t=0,r=0,i={};for(let s=0;s<this._slides.length;s++){let l=this._slides[s],c=this.getResponseForStep(s),d=Ce(l,c);t+=d.correct,r+=d.total,i[s]=Se(l,c)}this._gradingByStep=i,this._isGraded=!0;let a=this._gradingByStep[this._currentStep];return a&&this._$text.setGradingState(a),{score:r>0?Math.round(t/r*100):0,correct:t,total:r}}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this._responses={},this._gradingByStep={},this._isGraded=!1,this._currentStep=0,this._$text&&(this._$text.reset(),this._$text.clearGradingState()),this.setProgress(0),this.render()}};customElements.get("sequential-categorize-the-words")||customElements.define("sequential-categorize-the-words",ne);var ae=class extends x{constructor(t,r,i){super(t,r);this.interactionMechanic="static";this._expectedTransformations=i??{},Object.keys(this._expectedTransformations).length===0&&t.targets.forEach((a,o)=>{this._expectedTransformations[o]=a.words}),this._textConfig={data:t,mode:"transformation",variant:r.variant??"outline"},this.implementsProgress=!1}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}render(){this._textConfig.variant=this.config.variant,this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig,this._$text.addEventListener("change",()=>{this.emitStateChange()}),this.innerHTML=`
3276
+ <style>
3277
+ edu-text {
3278
+ display: flex;
3279
+ width: 100%;
3280
+ height: 100%;
3281
+ box-sizing: border-box;
3282
+ }
3283
+
3284
+ .text-container {
3285
+ display: flex;
3286
+ flex-direction: column;
3287
+ width: 100%;
3288
+ height: 100%;
3289
+ overflow: hidden;
3290
+ box-sizing: border-box;
3291
+ }
3292
+
3293
+ .text-wrapper {
3294
+ flex: 1;
3295
+ overflow-y: auto;
3296
+ overflow-x: auto;
3297
+ min-height: 0;
3298
+ padding: 1rem;
3299
+ }
3300
+ </style>
3301
+ <div class="text-container">
3302
+ <div class="text-wrapper"></div>
3303
+ </div>
3304
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getCurrentState(){return this._$text?this._$text.getValue():{transformations:{}}}isInteractionComplete(){let r=this.getCurrentState().transformations??{};for(let i=0;i<this.data.targets.length;i++){let a=r[i];if(!a||a.length===0)return!1}return!0}onHint(){let r=this.getCurrentState().transformations??{};for(let i=0;i<this.data.targets.length;i++)if(!r[i]||r[i].length===0){let o=this.data.targets[i].words.join(" "),s=this._expectedTransformations[i]?.join(" ")||o;this.emitHintShown(`Transform "${o}" to "${s}"`);return}this.emitHintShown("All transformations have been attempted!")}getUserData(){return this.getCurrentState()}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}grade(){let t=this.getUserData(),r=xe(this.data,t,this._expectedTransformations),i={};for(let a=0;a<this.data.targets.length;a++){let o=this._expectedTransformations[a],s=t.transformations?.[a];if(!s)i[a]="missed";else if(o&&o.length===s.length){let l=o.every((c,d)=>c.toLowerCase().trim()===(s[d]||"").toLowerCase().trim());i[a]=l?"correct":"wrong"}else i[a]="wrong"}return this._$text&&this._$text.setGradingState(i),r}reset(){super.reset(),this._$text&&(this._$text.reset(),this._$text.clearGradingState())}setExpectedTransformations(t){this._expectedTransformations=t}};customElements.get("text-transformation")||customElements.define("text-transformation",ae);var oe=class extends x{constructor(t,r,i){super(t,r);this.interactionMechanic="sequential";this._slides=[];this._currentStep=0;this._responses={};this._gradingByStep={};this._isGraded=!1;this._expectedByStep={};if(this._slides=(Array.isArray(t)?t:[]).filter(a=>a.type==="base"),this._slides.length===0){this.isValid=!1,this.errors="SequentialTextTransformation requires at least one base slide.";return}this._textConfig={data:this._slides[0],mode:"transformation",variant:r.variant??"outline"},this._expectedByStep=i??this.buildDefaultExpectations(),this.initializeProgress(this.getTotalTargetCount())}get slidesCount(){return this._slides.length}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}setSteps(t){this.saveCurrentStepResponse();let r=Math.max(0,Math.min(this._slides.length-1,t-1));r!==this._currentStep&&(this._currentStep=r,this.render())}render(){if(this._slides.length===0)return;this._textConfig={data:this._slides[this._currentStep],mode:"transformation",variant:this.config.variant},this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig;let t=this._responses[this._currentStep];t?.transformations&&this._$text.setState({transformations:t.transformations});let r=this._gradingByStep[this._currentStep];this._isGraded&&r&&this._$text.setGradingState(r),this._$text.addEventListener("change",()=>{this.saveCurrentStepResponse(),this.updateProgressAcrossSteps(),this._isGraded&&(delete this._gradingByStep[this._currentStep],this._$text.clearGradingState()),this.emitStateChange()}),this.innerHTML=`
3305
+ <style>
3306
+ sequential-text-transformation {
3307
+ display: flex;
3308
+ width: 100%;
3309
+ height: 100%;
3310
+ box-sizing: border-box;
3311
+ }
3312
+
3313
+ .text-container {
3314
+ display: flex;
3315
+ flex-direction: column;
3316
+ width: 100%;
3317
+ height: 100%;
3318
+ overflow: hidden;
3319
+ box-sizing: border-box;
3320
+ }
3321
+
3322
+ .text-wrapper {
3323
+ flex: 1;
3324
+ overflow-y: auto;
3325
+ overflow-x: auto;
3326
+ min-height: 0;
3327
+ padding: 1rem;
3328
+ }
3329
+ </style>
3330
+ <div class="text-container">
3331
+ <div class="text-wrapper"></div>
3332
+ </div>
3333
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getTotalTargetCount(){return this._slides.reduce((t,r)=>t+r.targets.length,0)}buildDefaultExpectations(){let t={};for(let r=0;r<this._slides.length;r++){let i=this._slides[r];t[r]={};for(let a=0;a<i.targets.length;a++)t[r][a]=i.targets[a].words}return t}getExpectedForStep(t){return this._expectedByStep[t]??{}}saveCurrentStepResponse(){this._$text&&(this._responses[this._currentStep]=this._$text.getValue())}getResponseForStep(t){return this._responses[t]??{transformations:{}}}updateProgressAcrossSteps(){let t=0;for(let r=0;r<this._slides.length;r++){let i=this._slides[r],o=this.getResponseForStep(r).transformations??{};t+=i.targets.filter((s,l)=>{let c=o[l];return Array.isArray(c)&&c.length>0}).length}this.setProgress(t)}getCurrentState(){return this.saveCurrentStepResponse(),{step:this._currentStep,responses:this._responses}}isInteractionComplete(){return this.getProgress().current===this.getProgress().total}onHint(){this.saveCurrentStepResponse();let t=this._slides[this._currentStep],i=this.getResponseForStep(this._currentStep).transformations??{},a=this.getExpectedForStep(this._currentStep);for(let o=0;o<t.targets.length;o++)if(!i[o]||i[o].length===0){let s=t.targets[o].words.join(" "),l=a[o]?.join(" ")||s;this.emitHintShown(`Transform "${s}" to "${l}"`);return}this.emitHintShown("This step is complete. Move to another step or submit.")}grade(){this.saveCurrentStepResponse();let t=0,r=0,i={};for(let s=0;s<this._slides.length;s++){let l=this._slides[s],c=this.getResponseForStep(s),d=this.getExpectedForStep(s),u=xe(l,c,d);t+=u.correct,r+=u.total,i[s]=gt(l,c,d)}this._gradingByStep=i,this._isGraded=!0;let a=this._gradingByStep[this._currentStep];return a&&this._$text.setGradingState(a),{score:r>0?Math.round(t/r*100):0,correct:t,total:r}}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this._responses={},this._gradingByStep={},this._isGraded=!1,this._currentStep=0,this._$text&&(this._$text.reset(),this._$text.clearGradingState()),this.setProgress(0),this.render()}setExpectedTransformationsByStep(t){this._expectedByStep=t}};customElements.get("sequential-text-transformation")||customElements.define("sequential-text-transformation",oe);var se=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="static";this._textConfig={data:t,mode:"blanks",variant:r.variant??"outline"},this.initializeProgress(t.targets.length)}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}render(){this._textConfig.variant=this.config.variant,this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig,this._$text.addEventListener("change",()=>{this.updateProgressBasedOnInputs(),this.emitStateChange()}),this.innerHTML=`
3334
+ <style>
3335
+ fill-blanks {
3336
+ display: flex;
3337
+ width: 100%;
3338
+ height: 100%;
3339
+ box-sizing: border-box;
3340
+ }
3341
+
3342
+ .text-container {
3343
+ display: flex;
3344
+ flex-direction: column;
3345
+ width: 100%;
3346
+ height: 100%;
3347
+ overflow: hidden;
3348
+ box-sizing: border-box;
3349
+ }
3350
+
3351
+ .text-wrapper {
3352
+ flex: 1;
3353
+ overflow-y: auto;
3354
+ overflow-x: auto;
3355
+ min-height: 0;
3356
+ padding: 1rem;
3357
+ }
3358
+ </style>
3359
+ <div class="text-container">
3360
+ <div class="text-wrapper"></div>
3361
+ </div>
3362
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getCurrentState(){return this._$text?this._$text.getValue():{inputValues:{}}}updateProgressBasedOnInputs(){let r=this.getCurrentState().inputValues??{},i=this.data.targets.filter(a=>{let o=r[a.id];return o!=null&&String(o).trim()!==""}).length;this.setProgress(i)}isInteractionComplete(){return this.getProgress().current===this.getProgress().total}onHint(){let r=this.getCurrentState().inputValues??{},i=this.data.targets.find(a=>{let o=r[a.id];return o==null||String(o).trim()===""});if(!i){this.emitHintShown("All blanks are filled. Submit to check answers.");return}this.emitHintShown(this.getHintText(i))}getHintText(t){switch(t.expectedValue.type){case"text":return"Fill the missing text blank.";case"number":return"Fill the numeric blank.";case"select":return"Choose the right option in the select blank.";case"date":return"Fill the date blank in the expected format.";case"time":return"Fill the time blank in the expected format.";default:return"Complete the next blank."}}grade(){let t=this.getCurrentState(),r=ye(this.data,t),i=Ee(this.data,t);return this._$text&&this._$text.setGradingState(i),r}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this._$text&&(this._$text.reset(),this._$text.clearGradingState())}};customElements.get("fill-blanks")||customElements.define("fill-blanks",se);var le=class extends x{constructor(t,r){super(t,r);this.interactionMechanic="sequential";this._slides=[];this._currentStep=0;this._responses={};this._gradingByStep={};this._isGraded=!1;if(this._slides=(Array.isArray(t)?t:[]).filter(i=>i.type==="blanks"),this._slides.length===0){this.isValid=!1,this.errors="SequentialFillBlanks requires at least one blanks slide.";return}this._textConfig={data:this._slides[0],mode:"blanks",variant:r.variant??"outline"},this.initializeProgress(this.getTotalTargetCount())}get slidesCount(){return this._slides.length}initialize(){}cleanup(){}onVariantChange(t){this.config.variant=t,this._textConfig.variant=t,this._$text&&this._$text.setAttribute("variant",t)}setSteps(t){this.saveCurrentStepResponse();let r=Math.max(0,Math.min(this._slides.length-1,t-1));r!==this._currentStep&&(this._currentStep=r,this.render())}render(){if(this._slides.length===0)return;this._textConfig={data:this._slides[this._currentStep],mode:"blanks",variant:this.config.variant},this._$text=document.createElement("edu-text"),this._$text.config=this._textConfig;let t=this._responses[this._currentStep];t?.inputValues&&this._$text.setState({inputValues:t.inputValues});let r=this._gradingByStep[this._currentStep];this._isGraded&&r&&this._$text.setGradingState(r),this._$text.addEventListener("change",()=>{this.saveCurrentStepResponse(),this.updateProgressAcrossSteps(),this._isGraded&&(delete this._gradingByStep[this._currentStep],this._$text.clearGradingState()),this.emitStateChange()}),this.innerHTML=`
3363
+ <style>
3364
+ sequential-fill-blanks {
3365
+ display: flex;
3366
+ width: 100%;
3367
+ height: 100%;
3368
+ box-sizing: border-box;
3369
+ }
3370
+
3371
+ .text-container {
3372
+ display: flex;
3373
+ flex-direction: column;
3374
+ width: 100%;
3375
+ height: 100%;
3376
+ overflow: hidden;
3377
+ box-sizing: border-box;
3378
+ }
3379
+
3380
+ .step-label {
3381
+ padding: 0.5rem 1rem;
3382
+ border-bottom: 1px solid rgb(var(--edu-border));
3383
+ color: rgb(var(--edu-second-ink));
3384
+ font-size: 0.85rem;
3385
+ }
3386
+
3387
+ .text-wrapper {
3388
+ flex: 1;
3389
+ overflow-y: auto;
3390
+ overflow-x: auto;
3391
+ min-height: 0;
3392
+ padding: 1rem;
3393
+ }
3394
+ </style>
3395
+ <div class="text-container">
3396
+ <div class="text-wrapper"></div>
3397
+ </div>
3398
+ `,this.querySelector(".text-wrapper").appendChild(this._$text)}getTotalTargetCount(){return this._slides.reduce((t,r)=>t+r.targets.length,0)}saveCurrentStepResponse(){this._$text&&(this._responses[this._currentStep]=this._$text.getValue())}getResponseForStep(t){return this._responses[t]??{inputValues:{}}}updateProgressAcrossSteps(){let t=0;for(let r=0;r<this._slides.length;r++){let i=this._slides[r],o=this.getResponseForStep(r).inputValues??{};t+=i.targets.filter(s=>{let l=o[s.id];return l!=null&&String(l).trim()!==""}).length}this.setProgress(t)}getCurrentState(){return this.saveCurrentStepResponse(),{step:this._currentStep,responses:this._responses}}isInteractionComplete(){return this.getProgress().current===this.getProgress().total}onHint(){this.saveCurrentStepResponse();let t=this._slides[this._currentStep],i=this.getResponseForStep(this._currentStep).inputValues??{},a=t.targets.find(o=>{let s=i[o.id];return s==null||String(s).trim()===""});if(!a){this.emitHintShown("This step is complete. Move to another step or submit.");return}this.emitHintShown(`Complete the ${a.expectedValue.type} input on this step.`)}grade(){this.saveCurrentStepResponse();let t=0,r=0,i={};for(let s=0;s<this._slides.length;s++){let l=this._slides[s],c=this.getResponseForStep(s),d=ye(l,c);t+=d.correct,r+=d.total,i[s]=Ee(l,c)}this._gradingByStep=i,this._isGraded=!0;let a=this._gradingByStep[this._currentStep];return a&&this._$text.setGradingState(a),{score:r>0?Math.round(t/r*100):0,correct:t,total:r}}submit(){super.submit();let t=this.grade();this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0}))}reset(){super.reset(),this._responses={},this._gradingByStep={},this._isGraded=!1,this._currentStep=0,this._$text&&(this._$text.reset(),this._$text.clearGradingState()),this.setProgress(0),this.render()}};customElements.get("sequential-fill-blanks")||customElements.define("sequential-fill-blanks",le);function Ka(e){let n={};if(!e)return n.data="Data is required",{ok:!1,errors:n};if(e.type!=="seriation"&&(n.type='Data type must be "seriation"'),!Array.isArray(e.items))return n.items="Items must be an array",{ok:!1,errors:n};e.items.length<2&&(n.items="At least 2 items are required for seriation"),e.items.some(i=>typeof i!="string"||i.trim()==="")&&(n.items="All items must be non-empty strings"),new Set(e.items).size!==e.items.length&&(n.items="All items must be unique (duplicates found)");let r=Object.keys(n).length===0;return{ok:r,errors:r?null:n}}function mt(e,n,t){let r=0,i=0,a=e.length;e.forEach((s,l)=>{let c=n.indexOf(s),d=t.querySelector(`[data-item="${s}"]`);if(c===-1){d&&(d.chipState="wrong");return}let u=Math.abs(c-l);u===0?(r+=100,i++,d&&(d.chipState="correct")):u===1?(r+=50,d&&(d.chipState="missed")):d&&(d.chipState="wrong")});let o=a>0?r/a:0;return console.log(`Seriation Score: ${o.toFixed(1)}% (${i}/${a} in correct position)`),{score:o,correct:i,total:a,answerKey:e,userResponse:n}}function Wa(e){try{if(!e||typeof e!="string")return{ok:!1,errors:{input:"Input must be a non-empty string"}};let n=e.trim();if(n.length===0)return{ok:!1,errors:{input:"Input cannot be empty"}};let t=[];return n.includes("|")?t=n.split("|").map(i=>i.trim()).filter(i=>i.length>0):t=n.split(`
3399
+ `).map(i=>i.replace(/^\s*[\d\w]+[\.\)]\s*/,"").trim()).filter(i=>i.length>0),t.length<2?{ok:!1,errors:{items:"At least 2 items are required for seriation"}}:{ok:!0,data:{type:"seriation",items:t}}}catch(n){return{ok:!1,errors:{"Parse Error":`${n instanceof Error?n.message:String(n)}`}}}}var ce=class extends x{constructor(t,r,i){super(t,r,i);this.interactionMechanic="static";this.currentOrder=[];this.isGraded=!1;this.draggedRowIndex=null;this.dragOverRowIndex=null;this.isDragging=!1;this.draggedRow=null;this.dragOffsetY=0;this.MAX_ITEMS=10;this.MIN_ITEM_HEIGHT=44;if(!this.isValid||!this.data||!this.config)return;let a=this.data.items;this.data.items=a,this.config.shuffle?this.currentOrder=S([...this.data.items]):this.currentOrder=[...this.data.items],this.implementsProgress=!1,this.variant=this.config.variant}initialize(){this.boundPointerMove=this.handlePointerMove.bind(this),this.boundPointerUp=this.handlePointerUp.bind(this),window.addEventListener("pointermove",this.boundPointerMove),window.addEventListener("pointerup",this.boundPointerUp)}cleanup(){window.removeEventListener("pointermove",this.boundPointerMove),window.removeEventListener("pointerup",this.boundPointerUp)}onVariantChange(t){this.querySelectorAll("edu-chip").forEach(r=>{r.variant!==void 0&&(r.variant=t)}),this.variant=t}render(){this.innerHTML=`
3400
+ <style>
3401
+ rank-order {
3402
+ display: flex;
3403
+ width: 100%;
3404
+ height: 100%;
3405
+ box-sizing: border-box;
3406
+
3407
+ /* Enable container queries for aspect-ratio detection */
3408
+ container-type: size;
3409
+ container-name: rank-order;
3410
+ }
3411
+
3412
+ .container {
3413
+ display: flex;
3414
+ flex-direction: column;
3415
+ width: 100%;
3416
+ height: 100%;
3417
+ padding: 0;
3418
+ box-sizing: border-box;
3419
+ overflow: hidden;
3420
+
3421
+ /* Height Guardrail - prevents Extreme Y stretch */
3422
+ max-height: 100%;
3423
+
3424
+ /* Vertical centering (Letterboxing) */
3425
+ margin: auto;
3426
+ }
3427
+
3428
+ .rows-container {
3429
+ flex: 1;
3430
+ display: grid;
3431
+
3432
+ /* The Grid Formula - auto-reflow based on container width */
3433
+ /* Single column by default */
3434
+ grid-template-columns: 1fr;
3435
+
3436
+ /* Rows can grow but never below the interaction floor */
3437
+ grid-template-rows: repeat(${this.data.items.length}, minmax(${this.MIN_ITEM_HEIGHT}px, 1fr));
3438
+
3439
+ gap: clamp(2px, min(0.6cqw, 0.6cqh), 6px);
3440
+ row-gap: clamp(2px, min(0.6cqw, 0.6cqh), 6px);
3441
+ column-gap: clamp(4px, min(1.2cqw, 1.2cqh), 10px);
3442
+
3443
+ align-content: stretch;
3444
+ align-items: stretch;
3445
+
3446
+ overflow-y: auto;
3447
+ overflow-x: hidden;
3448
+ min-height: 0;
3449
+ padding: clamp(6px, min(1.4cqw, 1.4cqh), 14px);
3450
+
3451
+ /* Prevent excessive width */
3452
+ max-width: 100%;
3453
+ max-height: 100dvh;
3454
+ margin: auto;
3455
+ width: 100%;
3456
+
3457
+ outline: 0 !important;
3458
+
3459
+ overflow-y: scroll;
3460
+ text-size-adjust: 100%;
3461
+ box-sizing: border-box;
3462
+ }
3463
+
3464
+ /* Height-driven reflow: only split columns when height is tight */
3465
+ @container rank-order (max-height: 220px) {
3466
+ .rows-container {
3467
+ grid-template-columns: repeat(2, 1fr);
3468
+ grid-template-rows: repeat(${Math.ceil(this.data.items.length/2)}, minmax(${this.MIN_ITEM_HEIGHT}px, 1fr));
3469
+ column-gap: clamp(0.5rem, 2cqw, 1rem);
3470
+ }
3471
+ }
3472
+
3473
+ @container rank-order (max-height: 140px) {
3474
+ .rows-container {
3475
+ grid-template-columns: repeat(3, 1fr);
3476
+ grid-template-rows: repeat(${Math.ceil(this.data.items.length/3)}, minmax(${this.MIN_ITEM_HEIGHT}px, 1fr));
3477
+ column-gap: clamp(0.5rem, 2cqw, 1rem);
3478
+ }
3479
+ }
3480
+
3481
+ .row {
3482
+ display: flex;
3483
+ align-items: stretch;
3484
+ background: transparent;
3485
+ border: 2px solid transparent;
3486
+ border-radius: clamp(4px, 1cqw, 6px);
3487
+ transition: all 0.2s ease;
3488
+ cursor: grab;
3489
+ gap: clamp(0.25rem, 1cqw, 0.5rem);
3490
+ position: relative;
3491
+
3492
+ min-height: ${this.MIN_ITEM_HEIGHT}px;
3493
+ height: 100%;
3494
+
3495
+ /* Fill the grid cell completely */
3496
+ width: 100%;
3497
+ box-sizing: border-box;
3498
+ }
3499
+
3500
+ .row:hover:not(.dragging) {
3501
+ background: rgba(var(--edu-first-accent), 0.03);
3502
+ border-color: rgba(var(--edu-first-accent), 0.2);
3503
+ }
3504
+
3505
+ .row:active {
3506
+ cursor: grabbing;
3507
+ }
3508
+
3509
+ .row.drag-over {
3510
+ border-color: rgb(var(--edu-first-accent));
3511
+ background: rgba(var(--edu-first-accent), 0.15);
3512
+ transform: scale(1.02);
3513
+ box-shadow: 0 0 0 3px rgba(var(--edu-first-accent), 0.2);
3514
+ }
3515
+
3516
+ .row.dragging {
3517
+ opacity: 0.6;
3518
+ transform: scale(0.95);
3519
+ cursor: grabbing;
3520
+ background: rgba(var(--edu-second-ink), 0.1);
3521
+ border-color: rgb(var(--edu-second-ink));
3522
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.2);
3523
+ }
3524
+
3525
+ .chip-wrapper {
3526
+ flex: 1;
3527
+ min-width: 0;
3528
+ height: 100%;
3529
+ display: flex;
3530
+ }
3531
+
3532
+ edu-chip {
3533
+ width: 100%;
3534
+ height: 100%;
3535
+ flex: 1;
3536
+ }
3537
+
3538
+ .controls {
3539
+ position: absolute;
3540
+ top: clamp(-14px, -2cqh, -10px);
3541
+ right: clamp(-14px, -2cqw, -10px);
3542
+ display: flex;
3543
+ align-items: center;
3544
+ justify-content: center;
3545
+ z-index: 10;
3546
+ opacity: 0;
3547
+ transition: opacity 0.2s ease;
3548
+ pointer-events: none;
3549
+ }
3550
+
3551
+ .row:hover .controls,
3552
+ .row.dragging .controls {
3553
+ opacity: 1;
3554
+ pointer-events: auto;
3555
+ }
3556
+
3557
+ .btn {
3558
+ display: flex;
3559
+ align-items: center;
3560
+ justify-content: center;
3561
+ background: rgb(var(--edu-card));
3562
+ border: 2px solid rgb(var(--edu-first-accent));
3563
+ cursor: pointer;
3564
+ transition: all 0.2s ease;
3565
+ box-shadow: 0 2px 6px rgba(var(--edu-shadow-color), 0.15);
3566
+
3567
+ /* Compact circular buttons */
3568
+ width: clamp(28px, min(5cqw, 5cqh), 42px);
3569
+ height: clamp(28px, min(5cqw, 5cqh), 42px);
3570
+ min-width: 28px;
3571
+ min-height: 28px;
3572
+ flex-shrink: 0;
3573
+ border-radius: 50%;
3574
+ padding: 0;
3575
+ margin: 0;
3576
+ }
3577
+
3578
+ .btn:hover:not(:disabled) {
3579
+ background: rgb(var(--edu-first-accent));
3580
+ border-color: rgb(var(--edu-first-accent));
3581
+ transform: scale(1.1);
3582
+ box-shadow: 0 4px 12px rgba(var(--edu-first-accent), 0.4);
3583
+ }
3584
+
3585
+ .btn:hover:not(:disabled) img {
3586
+ filter: brightness(0) invert(1);
3587
+ }
3588
+
3589
+ .btn:active:not(:disabled) {
3590
+ transform: scale(0.9);
3591
+ }
3592
+
3593
+ .btn:disabled {
3594
+ opacity: 0.2;
3595
+ cursor: not-allowed;
3596
+ border-color: rgb(var(--edu-border));
3597
+ }
3598
+
3599
+ .btn img {
3600
+ width: 60%;
3601
+ height: 60%;
3602
+ object-fit: contain;
3603
+ transition: filter 0.2s ease;
3604
+ }
3605
+
3606
+ /* Mobile optimizations - ensure tight layout */
3607
+ @media (max-width: 640px) {
3608
+ .row {
3609
+ gap: 0.125rem;
3610
+ }
3611
+ }
3612
+
3613
+ </style>
3614
+
3615
+ <div class="container">
3616
+ <div class="rows-container"></div>
3617
+ </div>
3618
+ `,this.$container=this.querySelector(".container"),this.$rowsContainer=this.querySelector(".rows-container"),this.renderRows()}renderRows(){this.$rowsContainer.innerHTML="",this.currentOrder.forEach((t,r)=>{let i=document.createElement("div");i.className="row",i.dataset.index=String(r);let a=document.createElement("div");a.className="chip-wrapper";let o=document.createElement("edu-chip");o.variant=this.variant,o.dataset.item=t,o.prefix=String(r+1),o.draggable=!0,L(t,o,this.assets?.assetsById),this.isGraded&&(this.data.items.indexOf(t)===r?o.chipState="correct":o.chipState="wrong"),a.appendChild(o);let s=document.createElement("div");s.className="controls";let l=this.createButton("up",r);s.appendChild(l),i.appendChild(a),i.appendChild(s),this.isGraded||i.addEventListener("pointerdown",c=>this.handlePointerDown(c,r)),this.$rowsContainer.appendChild(i)})}createButton(t,r){let i=document.createElement("button");i.className="btn",i.dataset.direction=t,i.dataset.index=String(r),i.setAttribute("aria-label",t==="up"?"Move up":"Move down"),t==="up"&&r===0&&(i.disabled=!0),t==="down"&&r===this.currentOrder.length-1&&(i.disabled=!0),this.isGraded&&(i.disabled=!0);let a=t==="up"?'<img src="assets/icons/up.svg" alt="^" />':'<img src="assets/icons/down.svg" alt="v" />';return i.innerHTML=a,i.addEventListener("click",()=>{t==="up"&&r>0?this.swapItems(r,r-1):t==="down"&&r<this.currentOrder.length-1&&this.swapItems(r,r+1)}),i}swapItems(t,r){let i=this.currentOrder[t];this.currentOrder[t]=this.currentOrder[r],this.currentOrder[r]=i,this.renderRows(),this.emitStateChange()}handlePointerDown(t,r){if(t.target.closest(".btn, .controls"))return;t.preventDefault(),t.stopPropagation(),this.isDragging=!0,this.draggedRow=t.currentTarget,this.draggedRowIndex=r;let i=this.draggedRow.getBoundingClientRect();this.dragOffsetY=t.clientY-i.top;try{this.draggedRow.setPointerCapture(t.pointerId)}catch(a){console.warn("Failed to capture pointer:",a)}this.draggedRow.classList.add("dragging"),this.$rowsContainer.style.userSelect="none"}handlePointerMove(t){if(!this.isDragging||!this.draggedRow)return;let r=this.getRowIndexAtY(t.clientY);if(this.$rowsContainer.querySelectorAll(".row").forEach(i=>{i.classList.remove("drag-over")}),r!==-1&&r!==this.draggedRowIndex){let i=Array.from(this.$rowsContainer.children);i[r]&&i[r].classList.add("drag-over")}}handlePointerUp(t){if(!this.isDragging||!this.draggedRow)return;try{this.draggedRow.releasePointerCapture(t.pointerId)}catch{}let r=this.getRowIndexAtY(t.clientY);r!==-1&&r!==this.draggedRowIndex&&this.swapItems(this.draggedRowIndex,r),this.$rowsContainer.querySelectorAll(".row").forEach(i=>{i.classList.remove("dragging","drag-over")}),this.$rowsContainer.style.userSelect="",this.isDragging=!1,this.draggedRow=null,this.draggedRowIndex=null,this.dragOverRowIndex=null}getRowIndexAtY(t){let r=Array.from(this.$rowsContainer.children);for(let i=0;i<r.length;i++){let a=r[i].getBoundingClientRect();if(t>=a.top&&t<=a.bottom)return i}return-1}getCurrentState(){return{currentOrder:[...this.currentOrder],correctOrder:[...this.data.items]}}isInteractionComplete(){return!0}onHint(){let t=0;this.currentOrder.forEach((r,i)=>{this.data.items[i]===r&&t++}),t===this.currentOrder.length?(alert('All items are in the correct order! Click "Check" to submit.'),this.emitHintShown("All items correctly ordered")):(alert(`Hint: ${t} out of ${this.currentOrder.length} items are in the correct position. Keep reordering!`),this.emitHintShown(`${t}/${this.currentOrder.length} correct`))}submit(){super.submit();let t=mt(this.data.items,this.currentOrder,this);console.log(`Rank Order Score: ${t.score.toFixed(1)}% (${t.correct}/${t.total} correct)`),this.isGraded=!0,this.renderRows(),this.dispatchEvent(new CustomEvent("interaction:graded",{detail:{result:t},bubbles:!0,composed:!0})),this.setAttribute("inert","")}reset(){super.reset(),this.config.shuffle?this.currentOrder=S([...this.data.items]):this.currentOrder=[...this.data.items],this.isGraded=!1,this.renderRows()}};customElements.get("rank-order")||customElements.define("rank-order",ce);var ri=!1,Qa=()=>{ri||(ri=!0,k({id:"open-classification",label:"Open Classification",elementTag:"open-classification",cognitiveOp:"classification",mechanic:"static",engine:"direct",ctor:Te,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!0,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"sequential-classification",label:"Sequential Classification",elementTag:"sequential-classification",cognitiveOp:"classification",mechanic:"automatic-sequencing",engine:"direct",ctor:$e,capabilities:{isSequential:!0,implementsProgress:!0,usesAssets:!0,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"mcq",label:"Multiple Choice / Multiple Response",elementTag:"mcq-interaction",cognitiveOp:"recognition",mechanic:"sequential",engine:"direct",ctor:J,capabilities:{isSequential:!0,implementsProgress:!0,usesAssets:!0,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"simultaneous-association",label:"Simultaneous Association",elementTag:"simultaneous-association",cognitiveOp:"association",mechanic:"static",engine:"direct",ctor:Ae,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!0,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"list-recall",label:"List Recall",elementTag:"list-recall",cognitiveOp:"freerecall",mechanic:"static",engine:"direct",ctor:ee,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"lookup-table",label:"Lookup Table",elementTag:"lookup-table",cognitiveOp:"production",mechanic:"static",engine:"tables",ctor:_e,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"classification-matrix",label:"Classification Matrix",elementTag:"classification-matrix",cognitiveOp:"classification",mechanic:"static",engine:"tables",ctor:Ie,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"nary-choice-table",label:"N-ary Choice Table",elementTag:"nary-choice-table",cognitiveOp:"discrimination",mechanic:"static",engine:"tables",ctor:Me,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"adjacency-table",label:"Adjacency Table",elementTag:"adjacency-table",cognitiveOp:"association",mechanic:"static",engine:"tables",ctor:Le,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!0,hasValidator:!0,hasGrader:!0}}),k({id:"mark-the-words",label:"Mark The Words",elementTag:"mark-the-words",cognitiveOp:"recognition",mechanic:"static",engine:"text",ctor:te,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"sequential-mark-the-words",label:"Sequential Mark The Words",elementTag:"sequential-mark-the-words",cognitiveOp:"recognition",mechanic:"sequential",engine:"text",ctor:re,capabilities:{isSequential:!0,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"categorize-the-words",label:"Categorize The Words",elementTag:"categorize-the-words",cognitiveOp:"classification",mechanic:"static",engine:"text",ctor:ie,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"sequential-categorize-the-words",label:"Sequential Categorize The Words",elementTag:"sequential-categorize-the-words",cognitiveOp:"classification",mechanic:"sequential",engine:"text",ctor:ne,capabilities:{isSequential:!0,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"text-transformation",label:"Text Transformation",elementTag:"text-transformation",cognitiveOp:"transformation",mechanic:"static",engine:"text",ctor:ae,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"sequential-text-transformation",label:"Sequential Text Transformation",elementTag:"sequential-text-transformation",cognitiveOp:"transformation",mechanic:"sequential",engine:"text",ctor:oe,capabilities:{isSequential:!0,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"fill-blanks",label:"Fill Blanks",elementTag:"fill-blanks",cognitiveOp:"cuedrecall",mechanic:"static",engine:"text",ctor:se,capabilities:{isSequential:!1,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"sequential-fill-blanks",label:"Sequential Fill Blanks",elementTag:"sequential-fill-blanks",cognitiveOp:"cuedrecall",mechanic:"sequential",engine:"text",ctor:le,capabilities:{isSequential:!0,implementsProgress:!0,usesAssets:!1,hasParser:!1,hasValidator:!0,hasGrader:!0}}),k({id:"rank-order",label:"Rank Order",elementTag:"rank-order",cognitiveOp:"seriation",mechanic:"static",engine:"direct",ctor:ce,capabilities:{isSequential:!1,implementsProgress:!1,usesAssets:!0,hasParser:!0,hasValidator:!0,hasGrader:!0}}))};Qa();var ii=`<header part='header'>
3619
+ <div class="prompt-container">
3620
+ <button class="prompt-btn btn" title="See Prompt Data" part="see-prompt">
3621
+ <img src="assets/icons/data.svg" alt="See Prompt" width="20" height="20"/>
3622
+ </button>
3623
+ <div class='title' part='title'></div>
3624
+ </div>
3625
+ <div class='timer' part='timer'></div>
3626
+ </header>
3627
+
3628
+ <div class='content' part='content'>
3629
+ <!-- Screen 1: Interaction (default) -->
3630
+ <div class="screen" data-screen="interaction">
3631
+ <slot></slot>
3632
+ </div>
3633
+
3634
+ <!-- Screen 2: Error -->
3635
+ <div class="screen" data-screen="error" style="display:none">
3636
+ <div class="error-content"></div>
3637
+ </div>
3638
+
3639
+ <!-- Screen 3: Correct Solution (provided by interaction) -->
3640
+ <div class="screen" data-screen="solution" style="display:none">
3641
+ <slot name="solution">
3642
+ <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 200px; padding: 2rem; text-align: center; color: rgb(var(--edu-second-ink)); font-style: italic;">
3643
+ Solution screen not implemented for this interaction yet
3644
+ </div>
3645
+ </slot>
3646
+ </div>
3647
+
3648
+ <!-- Screen 4: Remaining Attempts -->
3649
+ <div class="screen" data-screen="attempts" style="display:none">
3650
+ <div class="attempts-message"></div>
3651
+ </div>
3652
+
3653
+ <!-- Screen 5: Score -->
3654
+ <div class="screen" data-screen="score" style="display:none">
3655
+ <div class="score-display"></div>
3656
+ </div>
3657
+
3658
+ <div class="screen" data-screen="time" style="display:none">
3659
+ <div class="timer-display"></div>
3660
+ </div>
3661
+ </div>
3662
+
3663
+ <footer id='footer' part='footer'>
3664
+ <div class="progress-container">
3665
+ <progress class="progress-bar" part="progress" value="0" max="100"></progress>
3666
+ <div class="progress-icon-wrapper">
3667
+ <img src="assets/icons/star.svg" class="progress-icon" alt="Progress" />
3668
+ </div>
3669
+ <span class="progress-counter">0/0</span>
3670
+ </div>
3671
+ <div class="radio-nav" part="radio-nav"></div>
3672
+ <div class="action-buttons">
3673
+ <button class="check-btn" type="button" part="check">Check</button>
3674
+
3675
+ <button class="see-answers-btn btn" title="See answers" part="see-answers">
3676
+ <img src="assets/icons/eye.svg" alt="See answers" width="20" height="20"/>
3677
+ </button>
3678
+ <button class="retry-btn btn" title="Retry" part="retry">
3679
+ <img src="assets/icons/repeat.svg" alt="Retry" width="20" height="20"/>
3680
+ </button>
3681
+ <button class="scores-btn btn" title="Retry" part="retry">
3682
+ <img src="assets/icons/data.svg" alt="Retry" width="20" height="20"/>
3683
+ </button>
3684
+
3685
+ </div>
3686
+ </footer>
3687
+ `;var ni=`:host {
3688
+ display: flex;
3689
+ width: 100%;
3690
+ height: 100%;
3691
+ box-sizing: border-box;
3692
+ container-type: size;
3693
+ }
3694
+
3695
+ .edu-hidden { display: none !important; }
3696
+
3697
+ .wrap {
3698
+ display: flex;
3699
+ flex-direction: column;
3700
+ width: 100%;
3701
+ height: 100%;
3702
+ color: rgb(var(--edu-ink));
3703
+ background: rgb(var(--edu-bg));
3704
+ overflow: hidden;
3705
+ box-sizing: border-box;
3706
+ }
3707
+
3708
+ header {
3709
+ display: flex;
3710
+ justify-content: space-between;
3711
+ align-items: center;
3712
+ padding: clamp(0.2rem, 0.7cqh, 0.4rem);
3713
+ border-bottom: 1px solid rgb(var(--edu-border));
3714
+ flex-shrink: 0;
3715
+ gap: clamp(0.25rem, 1cqw, 0.5rem);
3716
+ height: clamp(38px, 7cqh, 46px);
3717
+ min-height: clamp(38px, 7cqh, 46px);
3718
+ }
3719
+
3720
+ .prompt-container {
3721
+ display: flex;
3722
+ min-width: 0;
3723
+ gap: clamp(0.25rem, 1cqw, 0.5rem);
3724
+ align-items: center;
3725
+ flex: 1;
3726
+ }
3727
+
3728
+ .title {
3729
+ flex: 1;
3730
+ min-width: 0;
3731
+ padding: 0;
3732
+ font-size: clamp(0.85rem, 2cqh, 1.05rem);
3733
+ font-weight: 700;
3734
+ line-height: 1.2;
3735
+ white-space: nowrap;
3736
+ overflow: hidden;
3737
+ text-overflow: ellipsis;
3738
+ }
3739
+
3740
+ .timer {
3741
+ padding: 0;
3742
+ font-size: clamp(0.75rem, 1.6cqh, 0.9rem);
3743
+ font-weight: 600;
3744
+ color: rgb(var(--edu-second-ink));
3745
+ font-variant-numeric: tabular-nums;
3746
+ cursor: pointer;
3747
+ }
3748
+
3749
+ .timer[data-warning="true"] {
3750
+ color: rgb(var(--edu-warning));
3751
+ }
3752
+
3753
+ .timer[data-danger="true"] {
3754
+ color: rgb(var(--edu-error));
3755
+ }
3756
+
3757
+ .content {
3758
+ flex: 1;
3759
+ overflow: hidden;
3760
+ min-height: 0;
3761
+ padding: clamp(0.5rem, min(2cqw, 2cqh), 1rem);
3762
+ box-sizing: border-box;
3763
+ position: relative;
3764
+ display: flex;
3765
+ }
3766
+
3767
+ .screen {
3768
+ display: flex;
3769
+ width: 100%;
3770
+ height: 100%;
3771
+ box-sizing: border-box;
3772
+ animation: fadeIn 1s ease;
3773
+ flex: 1;
3774
+ min-height: 0;
3775
+ }
3776
+
3777
+ .screen[data-screen="interaction"] {
3778
+ justify-content: stretch;
3779
+ align-items: stretch;
3780
+ }
3781
+
3782
+ .screen:not([data-screen="interaction"]) {
3783
+ justify-content: center;
3784
+ align-items: center;
3785
+ }
3786
+
3787
+ .screen[data-screen="interaction"] ::slotted(*) {
3788
+ width: 100%;
3789
+ height: 100%;
3790
+ min-height: 0;
3791
+ display: block;
3792
+ }
3793
+
3794
+ @keyframes fadeIn {
3795
+ from {
3796
+ opacity: 0;
3797
+ transform: translateY(10px);
3798
+ }
3799
+ to {
3800
+ opacity: 1;
3801
+ transform: translateY(0);
3802
+ }
3803
+ }
3804
+
3805
+ .error-content,
3806
+ .attempts-message,
3807
+ .score-display,
3808
+ .timer-display {
3809
+ display: flex;
3810
+ flex-direction: column;
3811
+ align-items: center;
3812
+ justify-content: center;
3813
+ text-align: center;
3814
+ height: 100%;
3815
+ color: rgb(var(--edu-ink));
3816
+ }
3817
+
3818
+ .timer-display .timer {
3819
+ font-size: 10rem !important;
3820
+ color: rgb(var(--edu-ink)) !important;
3821
+ }
3822
+
3823
+ .error-content {
3824
+ color: rgb(var(--edu-error));
3825
+ }
3826
+
3827
+ .attempts-message {
3828
+ font-weight: 600;
3829
+ font-size: 1.25rem;
3830
+ }
3831
+
3832
+ footer {
3833
+ position: relative;
3834
+ display: flex;
3835
+ flex-direction: column;
3836
+ justify-content: center;
3837
+ align-items: center;
3838
+ /* padding: clamp(0.3rem, 0.8cqh, 0.6rem);*/
3839
+ gap: clamp(0.25rem, 0.8cqh, 0.5rem);
3840
+ flex-shrink: 0;
3841
+ height: clamp(20px, 9cqh, 62px);
3842
+ min-height: clamp(50px, 9cqh, 62px);
3843
+ }
3844
+
3845
+ .progress-container {
3846
+ position: relative;
3847
+ display: flex;
3848
+ align-items: center;
3849
+ justify-content: space-between;
3850
+ gap: clamp(0.25rem, 1cqw, 0.6rem);
3851
+ width: 100%;
3852
+ }
3853
+
3854
+ .progress-bar {
3855
+ flex: 1;
3856
+ height: clamp(8px, 1.6cqh, 12px);
3857
+ appearance: none;
3858
+ -webkit-appearance: none;
3859
+ border: none;
3860
+ }
3861
+
3862
+ .progress-bar::-webkit-progress-bar {
3863
+ background-color: rgb(var(--edu-muted));
3864
+ border-radius: 10px;
3865
+ }
3866
+
3867
+ .progress-bar::-webkit-progress-value {
3868
+ background: rgb(var(--edu-first-accent));
3869
+ border-radius: 10px;
3870
+ transition: width 0.3s ease, background 0.3s ease;
3871
+ }
3872
+
3873
+ .progress-bar::-moz-progress-bar {
3874
+ background: rgb(var(--edu-first-accent));
3875
+ border-radius: 10px;
3876
+ transition: width 0.3s ease, background 0.3s ease;
3877
+ }
3878
+
3879
+ /* Score-based progress bar coloring */
3880
+ .progress-bar.score-fail::-webkit-progress-value {
3881
+ background: rgb(var(--edu-error)) !important;
3882
+ }
3883
+
3884
+ .progress-bar.score-fail::-moz-progress-bar {
3885
+ background: rgb(var(--edu-error)) !important;
3886
+ }
3887
+
3888
+ .progress-bar.score-low::-webkit-progress-value {
3889
+ background: rgb(var(--edu-warning)) !important;
3890
+ }
3891
+
3892
+ .progress-bar.score-low::-moz-progress-bar {
3893
+ background: rgb(var(--edu-warning)) !important;
3894
+ }
3895
+
3896
+ .progress-bar.score-mid::-webkit-progress-value {
3897
+ background: rgb(139, 195, 74) !important; /* Light green */
3898
+ }
3899
+
3900
+ .progress-bar.score-mid::-moz-progress-bar {
3901
+ background: rgb(139, 195, 74) !important;
3902
+ }
3903
+
3904
+ .progress-bar.score-high::-webkit-progress-value {
3905
+ background: rgb(var(--edu-success)) !important;
3906
+ }
3907
+
3908
+ .progress-bar.score-high::-moz-progress-bar {
3909
+ background: rgb(var(--edu-success)) !important;
3910
+ }
3911
+
3912
+ .progress-icon-wrapper {
3913
+ display: flex;
3914
+ align-items: center;
3915
+ justify-content: center;
3916
+ max-width: 24px;
3917
+ max-height: 24px;
3918
+ position: absolute;
3919
+ left: 0;
3920
+ top: 50%;
3921
+ transform: translateY(-50%);
3922
+ pointer-events: none;
3923
+ transition: left 0.3s ease, background-color 0.3s ease, box-shadow 0.3s ease;
3924
+ background-color: rgb(var(--edu-first-accent));
3925
+ border-radius: 50px;
3926
+ box-shadow: 0 0 10px 5px rgb(var(--edu-first-accent));
3927
+ padding: 0;
3928
+ }
3929
+
3930
+ /* Score-based icon coloring */
3931
+ .progress-icon-wrapper.score-fail {
3932
+ background-color: rgb(var(--edu-error));
3933
+ box-shadow: 0 0 10px 5px rgb(var(--edu-error));
3934
+ }
3935
+
3936
+ .progress-icon-wrapper.score-low {
3937
+ background-color: rgb(var(--edu-warning));
3938
+ box-shadow: 0 0 10px 5px rgb(var(--edu-warning));
3939
+ }
3940
+
3941
+ .progress-icon-wrapper.score-mid {
3942
+ background-color: rgba(139, 195, 74, 0.8);
3943
+ box-shadow: 0 0 10px 5px rgba(139, 195, 74, 0.8);
3944
+ }
3945
+
3946
+ .progress-icon-wrapper.score-high {
3947
+ background-color: rgb(var(--edu-success));
3948
+ box-shadow: 0 0 10px 5px rgb(var(--edu-success));
3949
+ }
3950
+
3951
+ .progress-icon {
3952
+ width: clamp(20px, 3.2cqh, 30px);
3953
+ height: clamp(20px, 3.2cqh, 30px);
3954
+ }
3955
+
3956
+ .progress-counter {
3957
+ font-size: clamp(0.7rem, 1.4cqh, 0.85rem);
3958
+ font-weight: 600;
3959
+ color: rgb(var(--edu-second-ink));
3960
+ min-width: 3rem;
3961
+ text-align: right;
3962
+ flex-shrink: 0;
3963
+ }
3964
+
3965
+ .action-buttons {
3966
+ display: flex;
3967
+ gap: 0.5rem;
3968
+ align-items: center;
3969
+ justify-content: center;
3970
+ flex-wrap: wrap;
3971
+ }
3972
+
3973
+ .check-btn {
3974
+ padding: clamp(0.35rem, 1cqh, 0.6rem) clamp(1rem, 2.6cqw, 1.6rem);
3975
+ font-size: clamp(0.8rem, 1.6cqh, 0.95rem);
3976
+ font-weight: 600;
3977
+ cursor: pointer;
3978
+ border: none;
3979
+ border-radius: var(--edu-radius);
3980
+ background: rgb(var(--edu-first-accent));
3981
+ color: rgb(var(--edu-inverted-ink));
3982
+ transition: all 0.2s ease;
3983
+ }
3984
+
3985
+ .check-btn:hover:not(:disabled) {
3986
+ background: rgb(var(--edu-first-accent) / 0.9);
3987
+ transform: translateY(-2px) scale(1.02);
3988
+ box-shadow: 0 4px 12px rgb(var(--edu-first-accent) / 0.3);
3989
+ }
3990
+
3991
+ .check-btn:active:not(:disabled) {
3992
+ transform: translateY(0) scale(0.98);
3993
+ box-shadow: 0 2px 4px rgb(var(--edu-first-accent) / 0.2);
3994
+ }
3995
+
3996
+ .check-btn:disabled {
3997
+ opacity: 0.5;
3998
+ cursor: not-allowed;
3999
+ }
4000
+
4001
+ .btn {
4002
+ padding: clamp(0.25rem, 0.8cqh, 0.4rem);
4003
+ background: transparent;
4004
+ border: 2px solid rgb(var(--edu-border));
4005
+ border-radius: var(--edu-radius);
4006
+ cursor: pointer;
4007
+ display: flex;
4008
+ align-items: center;
4009
+ justify-content: center;
4010
+ transition: all 0.2s ease;
4011
+ }
4012
+
4013
+ .btn:hover {
4014
+ background: rgb(var(--edu-muted));
4015
+ border-color: rgb(var(--edu-first-accent));
4016
+ transform: translateY(-2px) scale(1.05);
4017
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
4018
+ }
4019
+
4020
+ .btn:active {
4021
+ transform: translateY(0) scale(0.95);
4022
+ box-shadow: none;
4023
+ }
4024
+
4025
+ .radio-nav {
4026
+ display: none;
4027
+ flex-wrap: wrap;
4028
+ gap: 0.5rem;
4029
+ align-items: center;
4030
+ justify-content: center;
4031
+ }
4032
+
4033
+ .radio-nav[data-active="true"] {
4034
+ display: flex;
4035
+ }
4036
+
4037
+ @media (max-width: 640px) {
4038
+ .radio-nav {
4039
+ gap: 0.35rem;
4040
+ }
4041
+
4042
+ .radio-nav label {
4043
+ padding: 0.4rem 0.75rem;
4044
+ font-size: 0.875rem;
4045
+ }
4046
+ }
4047
+
4048
+ .radio-nav input { display: none; }
4049
+
4050
+ .radio-nav label {
4051
+ cursor: pointer;
4052
+ transition: all 0.3s ease;
4053
+ padding: 0.5rem 1rem;
4054
+ border-radius: var(--edu-radius);
4055
+ border: 1px solid rgb(var(--edu-border));
4056
+ background: rgb(var(--edu-card));
4057
+ color: rgb(var(--edu-ink));
4058
+ font-weight: 500;
4059
+ }
4060
+
4061
+ .radio-nav label:hover {
4062
+ border-color: rgb(var(--edu-first-accent));
4063
+ }
4064
+
4065
+ .radio-nav input:checked + label {
4066
+ background: rgb(var(--edu-first-accent));
4067
+ color: rgb(var(--edu-inverted-ink));
4068
+ border-color: rgb(var(--edu-first-accent));
4069
+ }
4070
+
4071
+ .actions {
4072
+ display: flex;
4073
+ gap: 0.5rem;
4074
+ }
4075
+
4076
+ .utils-container {
4077
+ display: flex;
4078
+ justify-content: space-between;
4079
+ }
4080
+
4081
+ :host([variant="empty"]) {
4082
+ & .wrap { background: transparent; border: none; }
4083
+ & header { border-bottom: none; }
4084
+
4085
+ & .title {
4086
+ padding-bottom: 5px;
4087
+ max-width: fit-content;
4088
+ border-bottom: 5px solid rgb(var(--edu-ink));
4089
+ }
4090
+
4091
+ & .timer { }
4092
+
4093
+ & .check-btn {
4094
+ background: transparent;
4095
+ color: rgb(var(--edu-ink));
4096
+ border: 2px solid rgb(var(--edu-ink));
4097
+ border-radius: 0;
4098
+ }
4099
+
4100
+ & .check-btn:hover:not(:disabled) {
4101
+ color: rgb(var(--edu-inverted-ink));
4102
+ background: rgb(var(--edu-ink));
4103
+ border-color: rgb(var(--edu-ink));
4104
+ }
4105
+
4106
+ & .progress-bar::-webkit-progress-bar {background: transparent}
4107
+ & .progress-bar::-webkit-progress-value {background: rgb(var(--edu-ink))}
4108
+
4109
+ & .radio-nav label {
4110
+ background: transparent;
4111
+ border: 2px solid rgb(var(--edu-ink));
4112
+ border-radius: 0;
4113
+ }
4114
+
4115
+ & .radio-nav input:checked + label {
4116
+ background: rgb(var(--edu-ink));
4117
+ color: rgb(var(--edu-inverted-ink));
4118
+ }
4119
+
4120
+ & .radio-nav label:hover { background-color: rgb(var(--edu-first-accent)) }
4121
+ }
4122
+
4123
+ :host([variant="minimal"]) {
4124
+ & .wrap {
4125
+ border: 1px solid rgb(var(--edu-border));
4126
+ border-radius: 6px;
4127
+ }
4128
+
4129
+ & .timer {
4130
+ font-size: 0.95rem;
4131
+ }
4132
+
4133
+ & .check-btn {
4134
+ border-radius: 4px;
4135
+ }
4136
+
4137
+ & footer {
4138
+ border-top: 1px solid rgb(var(--edu-border));
4139
+ }
4140
+
4141
+ & .progress-bar {
4142
+ height: 1px;
4143
+ }
4144
+
4145
+ & .progress-bar::-webkit-progress-bar {
4146
+ background-color: rgb(var(--edu-muted));
4147
+ }
4148
+
4149
+ & .progress-bar::-webkit-progress-value {
4150
+ background-color: rgb(var(--edu-ink));
4151
+ }
4152
+
4153
+ & .radio-nav label {
4154
+ border-radius: 4px;
4155
+ }
4156
+ }
4157
+
4158
+ :host([variant="elegant"]) {
4159
+ & .wrap {
4160
+ border-radius: 10px;
4161
+ box-shadow: 0 10px 30px rgba(var(--edu-shadow-color), 0.15);
4162
+ }
4163
+
4164
+ & .timer {
4165
+ font-family: georgia, serif;
4166
+ font-style: italic;
4167
+ font-size: 1.1rem;
4168
+ }
4169
+
4170
+ & .check-btn {
4171
+ border-radius: 8px;
4172
+ font-size: 1rem;
4173
+ }
4174
+
4175
+ & footer {
4176
+ border-top: 1px solid rgb(var(--edu-border) / 0.5);
4177
+ padding: 1.25rem;
4178
+ }
4179
+
4180
+ & .progress-bar {
4181
+ height: 4px;
4182
+ }
4183
+
4184
+ & .progress-bar::-webkit-progress-value {
4185
+ background: linear-gradient(90deg, rgb(var(--edu-first-accent)), rgb(var(--edu-first-accent) / 0.6));
4186
+ }
4187
+
4188
+ & .radio-nav label {
4189
+ font-family: georgia, serif;
4190
+ border: none;
4191
+ border-bottom: 2px solid transparent;
4192
+ background: transparent;
4193
+ padding: 0.5rem 1rem;
4194
+ }
4195
+
4196
+ & .radio-nav input:checked + label {
4197
+ color: rgb(var(--edu-first-accent));
4198
+ border-bottom: 2px solid rgb(var(--edu-first-accent));
4199
+ background: transparent;
4200
+ font-style: italic;
4201
+ }
4202
+
4203
+ & label {
4204
+ font-family: georgia, serif;
4205
+ padding: 0.5rem 1rem;
4206
+ }
4207
+ }
4208
+
4209
+ :host([variant="playful"]) {
4210
+ & .wrap {
4211
+ color: rgb(var(--edu-first-accent));
4212
+ border-radius: 14px;
4213
+ border: 2px dashed rgb(var(--edu-border));
4214
+ }
4215
+
4216
+ & .timer {
4217
+ font-weight: 700;
4218
+ font-size: 1.2rem;
4219
+ }
4220
+
4221
+ & .check-btn {
4222
+ border-radius: 12px;
4223
+ font-weight: 700;
4224
+ text-transform: uppercase;
4225
+ letter-spacing: 0.5px;
4226
+ }
4227
+
4228
+ & .check-btn:hover:not(:disabled) {
4229
+ transform: translateY(-2px) rotate(-1deg);
4230
+ }
4231
+
4232
+ & footer {
4233
+ border-top: 2px dashed rgb(var(--edu-border));
4234
+ }
4235
+
4236
+ & .progress-bar {
4237
+ height: 20px;
4238
+ }
4239
+
4240
+ & .progress-bar::-webkit-progress-bar {
4241
+ background-color: rgb(var(--edu-warning) / 0.3);
4242
+ border-radius: 20px;
4243
+ }
4244
+
4245
+ & .progress-bar::-webkit-progress-value {
4246
+ background: rgb(var(--edu-first-accent));
4247
+ border-radius: 20px;
4248
+ border: 3px solid rgb(var(--edu-warning) / 0.3);
4249
+ }
4250
+
4251
+ & .radio-nav label {
4252
+ background: rgb(var(--edu-muted));
4253
+ border-radius: 50px;
4254
+ font-weight: 700;
4255
+ }
4256
+
4257
+ & .radio-nav label:hover {
4258
+ transform: scale(1.1) rotate(-2deg);
4259
+ }
4260
+
4261
+ & .radio-nav input:checked + label {
4262
+ background: rgb(var(--edu-first-accent));
4263
+ color: rgb(var(--edu-inverted-ink));
4264
+ box-shadow: 0 5px 15px rgb(var(--edu-first-accent) / 0.4);
4265
+ }
4266
+ }
4267
+
4268
+ :host([variant="glass"]) {
4269
+ & .wrap {
4270
+ background: rgba(var(--edu-card), 0.7);
4271
+ backdrop-filter: blur(10px);
4272
+ border: 1px solid rgba(var(--edu-border), 0.35);
4273
+ border-radius: 12px;
4274
+ }
4275
+
4276
+ & .check-btn {
4277
+ background: rgba(var(--edu-first-accent), 0.9);
4278
+ backdrop-filter: blur(5px);
4279
+ border-radius: 10px;
4280
+ }
4281
+
4282
+ & .check-btn:hover:not(:disabled) {
4283
+ background: rgba(var(--edu-first-accent), 1);
4284
+ }
4285
+
4286
+ & footer {
4287
+ border-top: 1px solid rgba(var(--edu-border), 0.35);
4288
+ }
4289
+
4290
+ & .progress-bar::-webkit-progress-bar {
4291
+ background: rgba(var(--edu-card), 0.3);
4292
+ backdrop-filter: blur(5px);
4293
+ }
4294
+
4295
+ & .progress-bar::-webkit-progress-value {
4296
+ background: rgba(var(--edu-first-accent), 0.7);
4297
+ }
4298
+
4299
+ & .radio-nav label {
4300
+ background: rgba(var(--edu-card), 0.5);
4301
+ backdrop-filter: blur(5px);
4302
+ border: 1px solid rgba(var(--edu-border), 0.35);
4303
+ }
4304
+
4305
+ & .radio-nav input:checked + label {
4306
+ background: rgba(var(--edu-first-accent), 0.8);
4307
+ border-color: rgb(var(--edu-first-accent));
4308
+ }
4309
+ }
4310
+
4311
+ :host([variant="letter"]) {
4312
+ & .wrap {
4313
+ border: 1px solid rgb(var(--edu-border));
4314
+ font-family: georgia, serif;
4315
+ box-shadow: inset 0 0 0 1px rgba(var(--edu-shadow-color), 0.1);
4316
+ border-radius: 4px;
4317
+ }
4318
+
4319
+ & .timer {
4320
+ font-family: georgia, serif;
4321
+ letter-spacing: 0.5px;
4322
+ }
4323
+
4324
+ & .check-btn {
4325
+ font-family: georgia, serif;
4326
+ border-radius: 2px;
4327
+ font-size: 0.95rem;
4328
+ letter-spacing: 0.5px;
4329
+ }
4330
+
4331
+ & footer {
4332
+ border-top: 1px solid rgb(var(--edu-border));
4333
+ padding: 1rem 1.5rem;
4334
+ }
4335
+
4336
+ & .progress-bar::-webkit-progress-bar {
4337
+ background-color: rgb(var(--edu-muted));
4338
+ box-shadow: inset 0 0 0 1px rgba(var(--edu-shadow-color), 0.05);
4339
+ }
4340
+
4341
+ & .radio-nav label {
4342
+ width: 40px;
4343
+ height: 40px;
4344
+ display: flex;
4345
+ align-items: center;
4346
+ justify-content: center;
4347
+ padding: 0;
4348
+ background: rgb(var(--edu-third-ink));
4349
+ color: rgb(var(--edu-inverted-ink));
4350
+ font-weight: 900;
4351
+ border-radius: 4px;
4352
+ }
4353
+
4354
+ & .radio-nav input:checked + label {
4355
+ background: rgb(var(--edu-first-accent));
4356
+ transform: translateY(-4px);
4357
+ }
4358
+ }
4359
+
4360
+ :host([variant="sign"]) {
4361
+ & .wrap {
4362
+ border-radius: 6px;
4363
+ text-transform: uppercase;
4364
+ letter-spacing: 1px;
4365
+ border: 2px solid rgb(var(--edu-border));
4366
+ }
4367
+
4368
+ & .timer {
4369
+ text-transform: uppercase;
4370
+ letter-spacing: 1.5px;
4371
+ font-weight: 800;
4372
+ font-size: 0.9rem;
4373
+ }
4374
+
4375
+ & .check-btn {
4376
+ text-transform: uppercase;
4377
+ letter-spacing: 1.5px;
4378
+ font-weight: 800;
4379
+ font-size: 0.9rem;
4380
+ border-radius: 4px;
4381
+ margin: 0.85rem 2.5rem;
4382
+ }
4383
+
4384
+ & footer {
4385
+ border-top: 2px solid rgb(var(--edu-border));
4386
+ }
4387
+
4388
+ & .title {
4389
+ text-transform: uppercase;
4390
+ }
4391
+
4392
+ & .progress-bar {
4393
+ height: 24px;
4394
+ }
4395
+
4396
+ & .progress-bar::-webkit-progress-bar {
4397
+ background: rgb(var(--edu-third-ink));
4398
+ border: 2px solid rgb(var(--edu-third-ink));
4399
+ }
4400
+
4401
+ & .progress-bar::-webkit-progress-value {
4402
+ background: rgb(var(--edu-second-accent));
4403
+ }
4404
+
4405
+ & .radio-nav label {
4406
+ background: rgb(var(--edu-third-ink));
4407
+ color: rgb(var(--edu-second-accent));
4408
+ border-left: 4px solid rgb(var(--edu-second-accent));
4409
+ text-transform: uppercase;
4410
+ font-size: 0.8rem;
4411
+ font-weight: 700;
4412
+ }
4413
+
4414
+ & .radio-nav input:checked + label {
4415
+ background: rgb(var(--edu-second-accent));
4416
+ color: rgb(var(--edu-third-ink));
4417
+ border-left-color: rgb(var(--edu-third-ink));
4418
+ }
4419
+ }
4420
+
4421
+ :host([variant="outline"]) {
4422
+ & .wrap {
4423
+ color: rgb(var(--edu-inverted-ink));
4424
+ background: transparent;
4425
+ border-width: 0 1px 2px 1px;
4426
+ border-style: solid;
4427
+ border-color: rgb(var(--edu-first-accent));
4428
+ background: rgb(var(--edu-bg) / 0.1);
4429
+ }
4430
+
4431
+ & header { background: rgb(var(--edu-first-accent)); color: rgb(var(--edu-inverted-ink)) }
4432
+ & .timer { color: rgb(var(--edu-inverted-ink)) }
4433
+
4434
+ & footer {
4435
+ border-top: none;
4436
+ padding: 0;
4437
+ padding-left: 0.5rem;
4438
+ padding-right: 0.5rem;
4439
+ }
4440
+
4441
+ & .check-btn {
4442
+ font-size: 100%;
4443
+ font-weight: 700;
4444
+ border: none;
4445
+ border-radius: 0;
4446
+ border-top-left-radius: 10px;
4447
+ border-top-right-radius: 10px;
4448
+ color: rgb(var(--edu-inverted-ink));
4449
+ background: rgb(var(--edu-first-accent));
4450
+ margin: 0;
4451
+ padding: 1rem;
4452
+ text-transform: uppercase;
4453
+ }
4454
+
4455
+ & .check-btn:hover:not(:disabled) {
4456
+ background: rgb(var(--edu-first-accent) / 0.9);
4457
+ box-shadow: 0 4px 12px rgb(var(--edu-first-accent) / 0.3);
4458
+ transform: none;
4459
+ }
4460
+
4461
+ & .radio-nav label {
4462
+ border: 2px solid rgb(var(--edu-first-accent));
4463
+ border-radius: 0;
4464
+ background: transparent;
4465
+ color: rgb(var(--edu-ink));
4466
+ }
4467
+
4468
+ & .radio-nav label:hover {
4469
+ background: rgb(var(--edu-first-accent));
4470
+ color: rgb(var(--edu-inverted-ink));
4471
+ }
4472
+
4473
+ & .radio-nav input:checked + label {
4474
+ background: rgb(var(--edu-first-accent));
4475
+ color: rgb(var(--edu-inverted-ink));
4476
+ }
4477
+ }
4478
+
4479
+ :host([variant="card"]) {
4480
+ & .wrap {
4481
+ border-radius: 8px;
4482
+ box-shadow: 0 4px 12px rgba(var(--edu-shadow-color), 0.1), 0 2px 4px rgba(var(--edu-shadow-color), 0.05);
4483
+ }
4484
+
4485
+ & .check-btn {
4486
+ border-radius: 6px;
4487
+ box-shadow: 0 2px 4px rgba(var(--edu-shadow-color), 0.1);
4488
+ }
4489
+
4490
+ & .check-btn:hover:not(:disabled) {
4491
+ box-shadow: 0 4px 8px rgba(var(--edu-first-accent), 0.2);
4492
+ }
4493
+
4494
+ & footer {
4495
+ border-top: 1px solid rgb(var(--edu-border));
4496
+ }
4497
+
4498
+ & .radio-nav label {
4499
+ border-radius: 6px;
4500
+ box-shadow: 0 2px 4px rgba(var(--edu-shadow-color), 0.1);
4501
+ }
4502
+
4503
+ & .radio-nav input:checked + label {
4504
+ box-shadow: 0 4px 8px rgba(var(--edu-first-accent), 0.2);
4505
+ }
4506
+ }
4507
+ `;var De=class extends HTMLElement{constructor(){super();this.soundManager=new B;this.animationsManager=new M;this.timerInterval=null;this.remainingSeconds=0;this.interactionComplete=!1;this.attemptCount=0;this.attemptLimit=null;this.currentScreen="interaction";this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=ni,this.shadowRoot.append(t);let r=document.createElement("section");r.className="wrap",r.innerHTML=ii,this.shadowRoot.append(r),M.injectKeyframes(this.shadowRoot),this.$headerEl=r.querySelector("header"),this.$footerEl=r.querySelector("footer"),this.$titleEl=r.querySelector(".title"),this.$promptBtn=r.querySelector(".prompt-btn"),this.$timerEl=r.querySelector(".timer"),this.$checkBtn=r.querySelector(".check-btn"),this.$scoresBtn=r.querySelector(".scores-btn"),this.$seeAnswersBtn=r.querySelector(".see-answers-btn"),this.$retryBtn=r.querySelector(".retry-btn"),this.$radioNav=r.querySelector(".radio-nav"),this.$progressContainer=r.querySelector(".progress-container"),this.$progressBar=r.querySelector(".progress-bar"),this.$progressIcon=r.querySelector(".progress-icon-wrapper"),this.$progressCounter=r.querySelector(".progress-counter"),this.$contentEl=r.querySelector('[part="content"]'),this.animationsManager.isEnabled=!0,this.$interactionScreen=r.querySelector('[data-screen="interaction"]'),this.$errorContent=r.querySelector(".error-content"),this.$attemptsMessage=r.querySelector(".attempts-message"),this.$scoreDisplay=r.querySelector(".score-display"),this.$timerDisplay=r.querySelector(".timer-display"),this.setupShellListeners()}static get observedAttributes(){return["show-header","show-footer"]}connectedCallback(){this.hasAttribute("show-header")||this.setAttribute("show-header","true"),this.hasAttribute("show-footer")||this.setAttribute("show-footer","true"),this.updateVisibility(),this.animationsManager.animate(this.$progressIcon,"heartbeat"),this.animationsManager.animate(this.$promptBtn,"wobble")}disconnectedCallback(){this.stopTimer(),this.removeInteractionListeners()}attributeChangedCallback(t,r,i){r!==i&&this.updateVisibility()}setInteraction(t){if(this.stopTimer(),!t.isValid){this.$errorContent.textContent=t.errors??"Error loading the interaction.",this.switchScreen("error");return}this.soundManager.playSound("start"),this.interaction&&(this.removeInteractionListeners(),this.$interactionScreen.innerHTML=""),this.interaction=t,this.interactionComplete=!1;let r=this.interaction.config;this.reset(),this.switchScreen("interaction");let i=r.variant??"elegant";this.setAttribute("variant",i),this.interaction.onVariantChange(i),this.$titleEl.textContent=r.prompt||"",r.promptData&&r.promptModality?(this.$titleEl.style.cursor="pointer",this.$titleEl.title="Click to view prompt details",this.$promptBtn.addEventListener("click",()=>this.openPromptDialog()),this.$titleEl.addEventListener("click",()=>this.openPromptDialog())):(this.$titleEl.style.cursor="",this.$titleEl.style.textDecoration="",this.$titleEl.title=""),r.timer!==null&&r.timer>30?(this.remainingSeconds=r.timer,this.$timerEl.classList.remove("edu-hidden"),this.updateTimerDisplay(),this.startTimer()):this.$timerEl.classList.add("edu-hidden"),this.attemptLimit=r.attemptLimit,this.attemptCount=0,this.interaction.interactionMechanic==="sequential"?(this.$radioNav.dataset.active="true",this.renderRadioNav()):this.$radioNav.dataset.active="false",this.interaction.implementsProgress?(this.$checkBtn.classList.add("edu-hidden"),this.$progressContainer.classList.remove("edu-hidden"),this.$progressCounter.textContent=`0/${this.interaction.progressTracker.total}`):(this.$progressContainer.classList.add("edu-hidden"),this.$checkBtn.classList.remove("edu-hidden")),this.setupInteractionListeners(),this.$interactionScreen.innerHTML="",this.$interactionScreen.appendChild(t)}removeInteraction(){this.interaction&&(this.removeInteractionListeners(),this.$interactionScreen.innerHTML="",this.interaction=void 0,this.interactionComplete=!1)}setupShellListeners(){this.$checkBtn.addEventListener("click",()=>{this.soundManager.playSound("pop");try{this.interaction.submit()}catch(t){console.error("Submit failed:",t)}}),this.$seeAnswersBtn.addEventListener("click",()=>{this.soundManager.playSound("pop"),this.currentScreen==="solution"?this.switchScreen("interaction"):this.switchScreen("solution")}),this.$scoresBtn.addEventListener("click",()=>{this.soundManager.playSound("pop"),this.currentScreen==="score"?this.switchScreen("interaction"):this.switchScreen("score")}),this.$timerEl.addEventListener("click",()=>{this.soundManager.playSound("pop"),this.$timerDisplay.append(this.$timerEl),this.currentScreen==="time"?(this.switchScreen("interaction"),this.$headerEl.append(this.$timerEl)):this.switchScreen("time")}),this.$retryBtn.addEventListener("click",()=>this.handleRetry()),this.$radioNav.addEventListener("change",t=>{let r=t.target;if(r.type==="radio"){let i=parseInt(r.id.replace("step-",""),10);this.interaction&&this.interaction.setSteps(i),this.dispatchEvent(new CustomEvent("navigation-change",{detail:{step:i},bubbles:!0,composed:!0}))}})}setupInteractionListeners(){this.interaction.addEventListener("interaction:ready",t=>{console.log("[Shell] Interaction ready:",t.detail.id)}),this.interaction.addEventListener("interaction:progress",t=>{let{current:r,total:i,percentage:a}=t.detail;this.updateProgress(r,i),r===i&&i>0?(this.interactionComplete=!0,this.$checkBtn.classList.remove("edu-hidden")):(this.interactionComplete=!1,this.interaction.implementsProgress&&this.$checkBtn.classList.add("edu-hidden"))}),this.interaction.addEventListener("interaction:complete",t=>{console.log("[Shell] Interaction complete:",t.detail),this.stopTimer(),this.handleCompletion(t.detail.state)}),this.interaction.addEventListener("interaction:graded",t=>{t.detail.result.score===100?(this.soundManager.playSound("success"),this.animationsManager.animate(this.$progressIcon,"spin-pulse")):(this.soundManager.playSound("failure"),this.animationsManager.animate(this.$progressIcon,"shake")),this.handleGraded(t.detail.result)}),this.interaction.addEventListener("interaction:hint-shown",t=>{console.log("[Shell] Hint shown:",t.detail.message)}),this.interaction.addEventListener("interaction:error",t=>{console.error("[Shell] Interaction error:",t.detail),alert(t.detail.message)})}removeInteractionListeners(){}updateProgress(t,r){this.$progressBar.max=r,this.$progressBar.value=t??0,this.$progressCounter.textContent=`${t}/${r}`;let i=r>0?t/r*100:0,o=this.$progressBar.offsetWidth*i/100-12;this.$progressIcon.style.left=`${Math.max(0,o)}px`}handleCompletion(t){this.dispatchEvent(new CustomEvent("shell:interaction-complete",{detail:{state:t},bubbles:!0,composed:!0})),console.log("[Shell] Interaction submitted with state:",t)}handleGraded(t){this.$checkBtn.classList.add("edu-hidden"),this.$seeAnswersBtn.classList.remove("edu-hidden"),this.$scoresBtn.classList.remove("edu-hidden"),this.$retryBtn.classList.remove("edu-hidden"),this.attemptLimit&&this.attemptCount>this.attemptLimit&&this.$retryBtn.classList.add("edu-hidden");let r=t.score;this.$scoreDisplay.innerHTML=`
4508
+ <div style="font-size: 4rem; font-weight: 700; color: ${r>=75?"rgb(var(--edu-success))":r>=50?"rgba(139, 195, 74)":r>=25?"rgb(var(--edu-warning))":"rgb(var(--edu-error))"}">${r}%</div>
4509
+ <div style="font-size: 1.5rem; margin-top: 1rem; color: rgb(var(--edu-second-ink));">
4510
+ ${r===100?"Perfect Score! \u{1F389}":r>=75?"Great Job!":r>=50?"Good Effort!":r>=25?"Keep Trying!":"Try Again!"}
4511
+ </div>
4512
+ `,this.$progressIcon.classList.remove("score-fail","score-low","score-mid","score-high"),this.$progressBar.classList.remove("score-fail","score-low","score-mid","score-high");let i="";r<=25?i="score-fail":r<=50?i="score-low":r<=75?i="score-mid":i="score-high",this.$progressIcon.classList.add(i),this.$progressBar.classList.add(i)}reset(){this.resetTimer(),this.interaction.implementsProgress||this.$checkBtn.classList.remove("edu-hidden"),this.$seeAnswersBtn.classList.add("edu-hidden"),this.$scoresBtn.classList.add("edu-hidden"),this.$retryBtn.classList.add("edu-hidden"),this.$progressIcon.classList.remove("score-fail","score-low","score-mid","score-high"),this.$progressBar.classList.remove("score-fail","score-low","score-mid","score-high"),this.animationsManager.animate(this.$progressIcon,"heartbeat"),this.$progressBar.value=0,this.updateProgress(0,this.interaction.progressTracker.total),this.interaction.interactionMechanic==="sequential"&&this.renderRadioNav()}handleRetry(){if(this.$retryBtn.classList.add("edu-hidden"),this.soundManager.playSound("pop"),this.attemptCount++,this.attemptLimit&&this.attemptLimit>0){let t=this.attemptLimit-this.attemptCount+1;this.$attemptsMessage.textContent=`${t} attempt${t!==1?"s":""} remaining`,this.switchScreen("attempts"),setTimeout(()=>{this.switchScreen("interaction"),this.reset(),this.resumeTimer(),this.interaction?.reset(),this.soundManager.playSound("flip")},2e3)}else this.switchScreen("interaction"),this.interaction?.reset()}openPromptDialog(){let t=this.interaction?.config;if(!t)return;this.soundManager.playSound("pop");let r=document.querySelector("edu-dialog#prompt-dialog");r||(r=document.createElement("edu-dialog"),r.id="prompt-dialog",document.body.appendChild(r)),r.title=t.construct||this.interaction?.config.promptModality||"Prompt";let i=document.createElement("edu-media");i.setAttribute("type",t.promptModality),i.setAttribute("data",t.promptData),t.promptDataSpec&&i.setAttribute("spec",t.promptDataSpec),r.innerHTML="",r.appendChild(i),r.open()}switchScreen(t){this.shadowRoot.querySelectorAll(".screen").forEach(r=>{let i=r.getAttribute("data-screen");r.style.display=i===t?"block":"none"}),this.currentScreen=t,console.log(`[Shell] Switched to screen: ${t}`)}startTimer(){this.timerInterval=window.setInterval(()=>{this.remainingSeconds--,this.updateTimerDisplay(),this.remainingSeconds<=0&&(this.stopTimer(),this.handleTimerComplete())},1e3)}stopTimer(){this.timerInterval!==null&&(clearInterval(this.timerInterval),this.timerInterval=null)}getFormattedTime(t){let r=Math.floor(t/60),i=t%60;return`${r}:${i.toString().padStart(2,"0")}`}updateTimerDisplay(){this.$timerEl.textContent=this.getFormattedTime(this.remainingSeconds),this.remainingSeconds===30&&(this.soundManager.playSound("low-time"),this.animationsManager.animate(this.$timerEl,"shake")),delete this.$timerEl.dataset.warning,delete this.$timerEl.dataset.danger,this.remainingSeconds<=10?this.$timerEl.dataset.danger="true":this.remainingSeconds<=30&&(this.$timerEl.dataset.warning="true")}handleTimerComplete(){console.log("[Shell] Timer complete");try{this.interaction.submit()}catch(t){console.error("Auto-submit on timer failed:",t)}this.dispatchEvent(new CustomEvent("shell:timer-complete",{bubbles:!0,composed:!0}))}pauseTimer(){this.stopTimer()}resumeTimer(){this.remainingSeconds>0&&this.timerInterval===null&&this.startTimer()}resetTimer(){this.stopTimer(),this.remainingSeconds=this.interaction.config.timer,this.updateTimerDisplay()}updateVisibility(){let t=this.getAttribute("show-header")!=="false",r=this.getAttribute("show-footer")!=="false";this.$headerEl.style.display=t?"":"none",this.$footerEl.style.display=r?"":"none"}renderRadioNav(){let t=this.interaction&&"slidesCount"in this.interaction?this.interaction.slidesCount:1;this.$radioNav.innerHTML="";for(let r=1;r<=t;r++){let i=document.createElement("input");i.type="radio",i.name="step-nav",i.id=`step-${r}`,r===1&&(i.checked=!0);let a=document.createElement("label");a.htmlFor=`step-${r}`,a.textContent=String(r),this.$radioNav.appendChild(i),this.$radioNav.appendChild(a)}}getContentArea(){return this.$contentEl}};customElements.get("edu-window")||customElements.define("edu-window",De);export{Le as AdjacencyTable,M as AnimationsManager,We as AssetValidationError,x as BaseInteraction,ie as CategorizeTheWords,Ie as ClassificationMatrix,G as EduBlock,Qe as EduChip,de as EduDialog,qe as EduInput,Xe as EduMedia,Ue as EduTable,Ke as EduText,se as FillBlanks,De as InteractionsBaseShell,ee as ListRecall,_e as LookupTable,J as MCQ,te as MarkTheWords,Me as NaryChoiceTable,Te as OpenClassification,ce as RankOrder,ne as SequentialCategorizeTheWords,$e as SequentialClassification,le as SequentialFillBlanks,re as SequentialMarkTheWords,oe as SequentialTextTransformation,Ae as SimultaneousAssociation,B as SoundManager,ae as TextTransformation,Ho as adjacencyTableDataParser,Vo as adjacencyTableDataValidator,kt as adjacencyTableGrader,zo as basicTableDataParser,Oo as basicTableDataValidator,St as classificationTableGrader,Bs as clearInteractionRegistry,pe as compareValues,Gs as createInteraction,X as dedupe,ze as detectCellKind,E as escapeHtml,Tt as getAdjacencyCellGrading,Be as getAllUniqueValues,ue as getAllValues,Ee as getBlanksGradingState,At as getClassificationCellGrading,Se as getClassificationGradingState,Fa as getDNDGradingState,we as getHighlightGradingState,Ua as getInteraction,zs as getInteractionRegistry,$t as getLookupCellGrading,_t as getNaryCellGrading,gt as getTransformationGradingState,R as hash,pt as isNumber,ns as isOneOf,je as isPlainObject,I as isString,Hs as listInteractions,ht as looksLikeTime,Go as lookupTableDataParser,Fo as lookupTableDataValidator,Ct as lookupTableGrader,Et as naryTableGrader,Na as parseTextEngineSequential,is as parseYamlAssets,V as randomHexColorsList,ei as recognitionGrader,yl as recognitionParser,Cl as recognitionValidator,Qa as registerBuiltInInteractions,k as registerInteraction,mt as seriationGrader,Wa as seriationParser,Ka as seriationValidator,L as setUpChipData,wt as setUpQuestionData,S as shuffle,F as splitByPipes,Ur as textEngineBaseDataValidator,Vr as textEngineBaseGrammarParser,Yr as textEngineBlanksDataValidator,ye as textEngineBlanksGrader,Fr as textEngineBlanksGrammarParser,Kr as textEngineClassificationDataValidator,Ce as textEngineClassificationGrader,jr as textEngineClassificationGrammarParser,Va as textEngineDNDGrader,Oa as textEngineDataValidator,ve as textEngineHighlightGrader,xe as textEngineTransformationGrader,Pr as typeOf,qs as unregisterInteraction,Vs as validateAndNormalizeAssets};
4513
+ /*! Bundled license information:
4514
+
4515
+ js-yaml/dist/js-yaml.mjs:
4516
+ (*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT *)
4517
+ */
4518
+ //# sourceMappingURL=index.js.map