@citolab/qti-components 8.1.0 → 9.0.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 (63) hide show
  1. package/cdn/index.global.js +1 -1
  2. package/cdn/index.js +288 -182
  3. package/dist/base.d.ts +5 -5
  4. package/dist/base.js +1 -1
  5. package/dist/{chunk-TXIB3SKC.js → chunk-3MQNPN7A.js} +3 -3
  6. package/dist/{chunk-6V3A7NQP.js → chunk-3NPCS4IT.js} +2 -2
  7. package/dist/{chunk-MK2I3MQB.js → chunk-3VQSUWCK.js} +175 -15
  8. package/dist/chunk-3VQSUWCK.js.map +1 -0
  9. package/dist/{chunk-4XR2JHCP.js → chunk-5BXJRO5O.js} +1816 -551
  10. package/dist/chunk-5BXJRO5O.js.map +1 -0
  11. package/dist/{chunk-NZLW6EX7.js → chunk-DXEWBTJB.js} +2 -2
  12. package/dist/{chunk-Q52IJELT.js → chunk-GBDTBHUQ.js} +602 -263
  13. package/dist/chunk-GBDTBHUQ.js.map +1 -0
  14. package/dist/chunk-KCK27QBP.js +11 -0
  15. package/dist/chunk-KCK27QBP.js.map +1 -0
  16. package/dist/chunk-MKZ374OJ.js +179 -0
  17. package/dist/chunk-MKZ374OJ.js.map +1 -0
  18. package/dist/{chunk-3IACYIU2.js → chunk-RT6WZ3P7.js} +2 -2
  19. package/dist/chunk-TLTYXWW7.js +7 -0
  20. package/dist/chunk-TLTYXWW7.js.map +1 -0
  21. package/dist/{chunk-EKXZI26R.js → chunk-WCWJPIUQ.js} +58 -6
  22. package/dist/chunk-WCWJPIUQ.js.map +1 -0
  23. package/dist/{chunk-6XJUP55A.js → chunk-WKWCOV5P.js} +3 -3
  24. package/dist/chunk-WKWCOV5P.js.map +1 -0
  25. package/dist/{chunk-CF3DXJWM.js → chunk-WTV7NQHO.js} +731 -715
  26. package/dist/chunk-WTV7NQHO.js.map +1 -0
  27. package/dist/{computed.types.d-DpKIYO6e.d.ts → computed.types.d-CJarqC6s.d.ts} +12 -0
  28. package/dist/corrections.d.ts +14 -4
  29. package/dist/corrections.js +82 -7
  30. package/dist/corrections.js.map +1 -1
  31. package/dist/elements.d.ts +1 -1
  32. package/dist/elements.js +3 -3
  33. package/dist/index.d.ts +5 -5
  34. package/dist/index.js +26 -24
  35. package/dist/interactions.js +14 -15
  36. package/dist/item.css +81 -0
  37. package/dist/item.d.ts +1 -1
  38. package/dist/item.js +4 -4
  39. package/dist/loader.d.ts +1 -1
  40. package/dist/processing.d.ts +29 -3
  41. package/dist/processing.js +3 -2
  42. package/dist/qti-components-jsx.d.ts +7883 -7250
  43. package/dist/{qti-condition-expression.d-aMvBvpc6.d.ts → qti-condition-expression.d-CYwXOUb1.d.ts} +1 -1
  44. package/dist/{qti-expression.d-BietT_8b.d.ts → qti-expression.d-B_-m9emA.d.ts} +11 -1
  45. package/dist/{qti-feedback.d-DZbad0RN.d.ts → qti-feedback.d-B1EIF-fU.d.ts} +1 -0
  46. package/dist/{qti-test.d-_YAlhDbt.d.ts → qti-test.d-C6lCEMRB.d.ts} +38 -3
  47. package/dist/test.d.ts +5 -5
  48. package/dist/test.js +7 -5
  49. package/package.json +9 -9
  50. package/dist/chunk-4XR2JHCP.js.map +0 -1
  51. package/dist/chunk-6XJUP55A.js.map +0 -1
  52. package/dist/chunk-CF3DXJWM.js.map +0 -1
  53. package/dist/chunk-EKXZI26R.js.map +0 -1
  54. package/dist/chunk-IXPDMYKH.js +0 -1420
  55. package/dist/chunk-IXPDMYKH.js.map +0 -1
  56. package/dist/chunk-IYC7LZV6.js +0 -7
  57. package/dist/chunk-IYC7LZV6.js.map +0 -1
  58. package/dist/chunk-MK2I3MQB.js.map +0 -1
  59. package/dist/chunk-Q52IJELT.js.map +0 -1
  60. /package/dist/{chunk-TXIB3SKC.js.map → chunk-3MQNPN7A.js.map} +0 -0
  61. /package/dist/{chunk-6V3A7NQP.js.map → chunk-3NPCS4IT.js.map} +0 -0
  62. /package/dist/{chunk-NZLW6EX7.js.map → chunk-DXEWBTJB.js.map} +0 -0
  63. /package/dist/{chunk-3IACYIU2.js.map → chunk-RT6WZ3P7.js.map} +0 -0
@@ -14,22 +14,241 @@ import {
14
14
  responseAttributeConverter,
15
15
  serializeResponseAttribute,
16
16
  validationMessage
17
- } from "./chunk-EKXZI26R.js";
17
+ } from "./chunk-WCWJPIUQ.js";
18
18
 
19
- // ../interactions/core/dist/elements/qti-gap-text/qti-gap-text.js
20
- import { html as html2, LitElement } from "lit";
21
- import { property as property2 } from "lit/decorators.js";
22
-
23
- // ../interactions/core/dist/mixins/active-element/active-element.mixin.js
24
- import { html } from "lit";
19
+ // ../interactions/core/dist/elements/qti-associable-hotspot/qti-associable-hotspot.js
20
+ import { LitElement, html } from "lit";
25
21
  import { property, state } from "lit/decorators.js";
22
+ import { repeat } from "lit/directives/repeat.js";
26
23
  import { consume } from "@lit/context";
24
+
25
+ // ../interactions/core/dist/context/drag-drop.context.js
26
+ import { createContext } from "@lit/context";
27
+ var dragDropContext = createContext(/* @__PURE__ */ Symbol("dragDropContext"));
28
+
29
+ // ../interactions/core/dist/elements/qti-associable-hotspot/qti-associable-hotspot.styles.js
30
+ import { css } from "lit";
31
+ var qti_associable_hotspot_styles_default = [
32
+ boxSizing,
33
+ dropRegion,
34
+ css`
35
+ /* A drop target — see qti-gap.styles.ts. The interaction publishes the chip measurements as
36
+ custom properties on its host; the properties themselves live here. */
37
+ :host {
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ user-select: none;
42
+ position: absolute;
43
+ min-height: var(--qti-dropzone-min-height, 0);
44
+ min-width: var(--qti-dropzone-min-width, 0);
45
+ }
46
+
47
+ /* The hotspot's own box comes from its authored coords; the drop region simply fills it. */
48
+ [part~='drop'] {
49
+ width: 100%;
50
+ height: 100%;
51
+ }
52
+ `
53
+ ];
54
+
55
+ // ../interactions/core/dist/elements/qti-associable-hotspot/qti-associable-hotspot.js
27
56
  var __decorate = function(decorators, target, key, desc) {
28
57
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
58
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
30
59
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
31
60
  return c > 3 && r && Object.defineProperty(target, key, r), r;
32
61
  };
62
+ var QtiAssociableHotspot = class extends LitElement {
63
+ constructor() {
64
+ super(...arguments);
65
+ this.internals = this.attachInternals();
66
+ this.acceptsDeclarativeDrops = true;
67
+ }
68
+ static {
69
+ this.styles = qti_associable_hotspot_styles_default;
70
+ }
71
+ /** The chips this hotspot holds. Stable node references, cloned once at drop time. */
72
+ get drags() {
73
+ return this._dragDrop?.nodesByTarget?.[this.identifier] ?? [];
74
+ }
75
+ connectedCallback() {
76
+ super.connectedCallback();
77
+ this.dispatchEvent(new CustomEvent("qti-register-hotspot", {
78
+ bubbles: true,
79
+ composed: true,
80
+ cancelable: false
81
+ }));
82
+ }
83
+ render() {
84
+ return html`<div part="drop">
85
+ ${repeat(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
86
+ </div>`;
87
+ }
88
+ };
89
+ __decorate([
90
+ property({ type: String, reflect: true })
91
+ ], QtiAssociableHotspot.prototype, "identifier", void 0);
92
+ __decorate([
93
+ consume({ context: dragDropContext, subscribe: true }),
94
+ state()
95
+ ], QtiAssociableHotspot.prototype, "_dragDrop", void 0);
96
+
97
+ // ../interactions/core/dist/elements/qti-gap/qti-gap.js
98
+ import { html as html2, LitElement as LitElement2 } from "lit";
99
+ import { property as property2, state as state2 } from "lit/decorators.js";
100
+ import { repeat as repeat2 } from "lit/directives/repeat.js";
101
+ import { consume as consume2 } from "@lit/context";
102
+
103
+ // ../interactions/core/dist/elements/qti-gap/qti-gap.styles.js
104
+ import { css as css2 } from "lit";
105
+ var qti_gap_styles_default = [
106
+ boxSizing,
107
+ dropRegion,
108
+ css2`
109
+ /*
110
+ * A drop target. The interaction measures its chips and publishes the result as custom
111
+ * properties on its own host; the actual CSS properties live here, not in a style attribute.
112
+ *
113
+ * An authored data-choices-container-width takes the width axis: autoSizeDropzoneWidth goes
114
+ * false and the mixin never publishes --qti-dropzone-min-width at all, so the fallback below
115
+ * applies and the authored inline width is free to win. That works only because the token is
116
+ * never declared globally — min-width beats width, so a declared floor would silently outrank
117
+ * the author. See DROP-SIZING.md §2 and tools/stylelint/no-declared-measured-token.js.
118
+ */
119
+ /*
120
+ * A gap sits in a line of prose, so it is inline-flex and rides the text baseline. All four of
121
+ * these were in the theme, set on this host from the document — which also meant the
122
+ * 'display: flex' this file declared never took effect.
123
+ */
124
+ :host {
125
+ display: inline-flex;
126
+ align-items: center;
127
+ justify-content: center;
128
+ vertical-align: middle;
129
+ user-select: none;
130
+ }
131
+
132
+ /*
133
+ * The chip's box is reserved on the slot, not on the host.
134
+ *
135
+ * --qti-dropzone-min-* is the border-box of the widest and tallest chip, so whatever carries
136
+ * that minimum must have no border or padding of its own — otherwise the theme's dashed gap
137
+ * border eats into the reservation, the gap comes up short, and it grows the instant a chip
138
+ * lands in it. That reflows the sentence and drags the neighbouring gaps sideways while the
139
+ * user is still on their way to one.
140
+ *
141
+ * It cannot live on :host. A theme's universal reset matches the host element from the
142
+ * document, and document rules outrank :host — so the host is border-box no matter what this
143
+ * file says. This div is inside the shadow tree, out of the document's reach, and inherits
144
+ * border-box harmlessly since it has no border or padding of its own.
145
+ */
146
+ [part~='drop'] {
147
+ display: flex;
148
+ align-items: center;
149
+ justify-content: center;
150
+ min-height: var(--qti-dropzone-min-height, 0);
151
+ min-width: var(--qti-dropzone-min-width, 0);
152
+ }
153
+ `
154
+ ];
155
+
156
+ // ../interactions/core/dist/elements/qti-gap/qti-gap.js
157
+ var __decorate2 = function(decorators, target, key, desc) {
158
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
159
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
160
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
161
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
162
+ };
163
+ var QtiGap = class extends LitElement2 {
164
+ constructor() {
165
+ super(...arguments);
166
+ this.internals = this.attachInternals();
167
+ this.acceptsDeclarativeDrops = true;
168
+ this.tabindex = 0;
169
+ }
170
+ static {
171
+ this.styles = qti_gap_styles_default;
172
+ }
173
+ /** The chips this gap holds. Stable node references, cloned once at drop time by the interaction. */
174
+ get drags() {
175
+ return this._dragDrop?.nodesByTarget?.[this.identifier] ?? [];
176
+ }
177
+ render() {
178
+ return html2`<div part="drop">
179
+ ${repeat2(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
180
+ </div>`;
181
+ }
182
+ };
183
+ __decorate2([
184
+ property2({ type: Number, reflect: true })
185
+ ], QtiGap.prototype, "tabindex", void 0);
186
+ __decorate2([
187
+ property2({ type: String, reflect: true })
188
+ ], QtiGap.prototype, "identifier", void 0);
189
+ __decorate2([
190
+ consume2({ context: dragDropContext, subscribe: true }),
191
+ state2()
192
+ ], QtiGap.prototype, "_dragDrop", void 0);
193
+
194
+ // ../interactions/core/dist/elements/qti-gap-img/qti-gap-img.js
195
+ import { LitElement as LitElement3 } from "lit";
196
+ import { property as property3 } from "lit/decorators.js";
197
+
198
+ // ../interactions/core/dist/elements/qti-gap-img/qti-gap-img.styles.js
199
+ import { css as css3 } from "lit";
200
+ var qti_gap_img_styles_default = [
201
+ boxSizing,
202
+ css3`
203
+ /* Centred, because a gap-img is a picture inside a drop the same size as it. Was in the theme's
204
+ graphic-gap-match rules, on the host from the document. */
205
+ :host {
206
+ display: flex;
207
+ align-items: center;
208
+ justify-content: center;
209
+ user-select: none;
210
+ }
211
+ `
212
+ ];
213
+
214
+ // ../interactions/core/dist/elements/qti-gap-img/qti-gap-img.js
215
+ var __decorate3 = function(decorators, target, key, desc) {
216
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
217
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
218
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
219
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
220
+ };
221
+ var QtiGapImg = class extends LitElement3 {
222
+ constructor() {
223
+ super(...arguments);
224
+ this.tabindex = 0;
225
+ this.internals = this.attachInternals();
226
+ }
227
+ static {
228
+ this.styles = qti_gap_img_styles_default;
229
+ }
230
+ connectedCallback() {
231
+ this.setAttribute("slot", "drags");
232
+ }
233
+ };
234
+ __decorate3([
235
+ property3({ type: Number, reflect: true })
236
+ ], QtiGapImg.prototype, "tabindex", void 0);
237
+
238
+ // ../interactions/core/dist/elements/qti-gap-text/qti-gap-text.js
239
+ import { html as html4, LitElement as LitElement4 } from "lit";
240
+ import { property as property5 } from "lit/decorators.js";
241
+
242
+ // ../interactions/core/dist/mixins/active-element/active-element.mixin.js
243
+ import { html as html3 } from "lit";
244
+ import { property as property4, state as state3 } from "lit/decorators.js";
245
+ import { consume as consume3 } from "@lit/context";
246
+ var __decorate4 = function(decorators, target, key, desc) {
247
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
248
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
249
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
250
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
251
+ };
33
252
  var ariaBooleanConverter = {
34
253
  toAttribute: (value) => value ? "true" : "false",
35
254
  fromAttribute: (value) => value === "true"
@@ -146,47 +365,47 @@ function ActiveElementMixin(Base, type) {
146
365
  }));
147
366
  }
148
367
  render() {
149
- return html`<slot></slot>`;
368
+ return html3`<slot></slot>`;
150
369
  }
151
370
  }
152
- __decorate([
153
- property({ type: String })
371
+ __decorate4([
372
+ property4({ type: String })
154
373
  ], QtiChoice.prototype, "identifier", void 0);
155
- __decorate([
156
- property({ type: Number, reflect: true, attribute: "tabindex" })
374
+ __decorate4([
375
+ property4({ type: Number, reflect: true, attribute: "tabindex" })
157
376
  ], QtiChoice.prototype, "tabIndex", void 0);
158
- __decorate([
159
- property({
377
+ __decorate4([
378
+ property4({
160
379
  type: Boolean,
161
380
  attribute: "aria-disabled",
162
381
  converter: ariaBooleanConverter
163
382
  })
164
383
  ], QtiChoice.prototype, "disabled", void 0);
165
- __decorate([
166
- property({
384
+ __decorate4([
385
+ property4({
167
386
  type: Boolean,
168
387
  attribute: "aria-readonly",
169
388
  converter: ariaBooleanConverter
170
389
  })
171
390
  ], QtiChoice.prototype, "readonly", void 0);
172
- __decorate([
173
- consume({ context: interactionContext, subscribe: true }),
174
- state()
391
+ __decorate4([
392
+ consume3({ context: interactionContext, subscribe: true }),
393
+ state3()
175
394
  ], QtiChoice.prototype, "_interactionContext", void 0);
176
- __decorate([
395
+ __decorate4([
177
396
  watch("disabled", { waitUntilFirstUpdate: true })
178
397
  ], QtiChoice.prototype, "handleDisabledChange", null);
179
- __decorate([
398
+ __decorate4([
180
399
  watch("readonly", { waitUntilFirstUpdate: true })
181
400
  ], QtiChoice.prototype, "handleReadonlyChange", null);
182
401
  return QtiChoice;
183
402
  }
184
403
 
185
404
  // ../interactions/core/dist/elements/qti-gap-text/qti-gap-text.styles.js
186
- import { css } from "lit";
405
+ import { css as css4 } from "lit";
187
406
  var qti_gap_text_styles_default = [
188
407
  boxSizing,
189
- css`
408
+ css4`
190
409
  /*
191
410
  * A chip's own box. Both drag-drop interactions that use this element laid it out from the
192
411
  * theme — gap-match with 'display: flex !important; align-items: center !important',
@@ -217,17 +436,29 @@ var qti_gap_text_styles_default = [
217
436
  justify-content: var(--qti-drag-justify-content, normal);
218
437
  user-select: none;
219
438
  }
439
+
440
+ /*
441
+ * The control div's only content is the theme's ::before grip glyph. Centering it with
442
+ * 'vertical-align: middle' (the theme's only lever on a pseudo-element it owns) aligns to the
443
+ * line box's baseline metrics, which drift with font/line-height. Flex centering here is
444
+ * geometric and font-independent — the same fix qti-simple-choice already has for its control.
445
+ */
446
+ [part='control'] {
447
+ display: flex;
448
+ align-items: center;
449
+ justify-content: center;
450
+ }
220
451
  `
221
452
  ];
222
453
 
223
454
  // ../interactions/core/dist/elements/qti-gap-text/qti-gap-text.js
224
- var __decorate2 = function(decorators, target, key, desc) {
455
+ var __decorate5 = function(decorators, target, key, desc) {
225
456
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
226
457
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
227
458
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
228
459
  return c > 3 && r && Object.defineProperty(target, key, r), r;
229
460
  };
230
- var QtiGapText = class extends ActiveElementMixin(LitElement, "qti-gap-text") {
461
+ var QtiGapText = class extends ActiveElementMixin(LitElement4, "qti-gap-text") {
231
462
  constructor() {
232
463
  super(...arguments);
233
464
  this.tabindex = 0;
@@ -240,23 +471,23 @@ var QtiGapText = class extends ActiveElementMixin(LitElement, "qti-gap-text") {
240
471
  this.setAttribute("slot", "drags");
241
472
  }
242
473
  render() {
243
- return html2`<div part="control"></div>
474
+ return html4`<div part="control"></div>
244
475
  <slot part="label"></slot>`;
245
476
  }
246
477
  };
247
- __decorate2([
248
- property2({ type: Number, reflect: true })
478
+ __decorate5([
479
+ property5({ type: Number, reflect: true })
249
480
  ], QtiGapText.prototype, "tabindex", void 0);
250
481
 
251
482
  // ../interactions/core/dist/elements/qti-hotspot-choice/qti-hotspot-choice.js
252
- import { LitElement as LitElement2 } from "lit";
253
- import { property as property3 } from "lit/decorators.js";
483
+ import { LitElement as LitElement5 } from "lit";
484
+ import { property as property6 } from "lit/decorators.js";
254
485
 
255
486
  // ../interactions/core/dist/elements/qti-hotspot-choice/qti-hotspot-choice.styles.js
256
- import { css as css2 } from "lit";
487
+ import { css as css5 } from "lit";
257
488
  var qti_hotspot_choice_styles_default = [
258
489
  boxSizing,
259
- css2`
490
+ css5`
260
491
  :host {
261
492
  display: flex;
262
493
  user-select: none;
@@ -280,29 +511,29 @@ var qti_hotspot_choice_styles_default = [
280
511
  ];
281
512
 
282
513
  // ../interactions/core/dist/elements/qti-hotspot-choice/qti-hotspot-choice.js
283
- var __decorate3 = function(decorators, target, key, desc) {
514
+ var __decorate6 = function(decorators, target, key, desc) {
284
515
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
285
516
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
286
517
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
287
518
  return c > 3 && r && Object.defineProperty(target, key, r), r;
288
519
  };
289
- var QtiHotspotChoice = class extends ActiveElementMixin(LitElement2, "qti-hotspot-choice") {
520
+ var QtiHotspotChoice = class extends ActiveElementMixin(LitElement5, "qti-hotspot-choice") {
290
521
  static {
291
522
  this.styles = qti_hotspot_choice_styles_default;
292
523
  }
293
524
  };
294
- __decorate3([
295
- property3({ attribute: "aria-ordervalue", type: Number, reflect: true })
525
+ __decorate6([
526
+ property6({ attribute: "aria-ordervalue", type: Number, reflect: true })
296
527
  ], QtiHotspotChoice.prototype, "order", void 0);
297
528
 
298
529
  // ../interactions/core/dist/elements/qti-hottext/qti-hottext.js
299
- import { html as html3, LitElement as LitElement3 } from "lit";
530
+ import { html as html5, LitElement as LitElement6 } from "lit";
300
531
 
301
532
  // ../interactions/core/dist/elements/qti-hottext/qti-hottext.styles.js
302
- import { css as css3 } from "lit";
533
+ import { css as css6 } from "lit";
303
534
  var qti_hottext_styles_default = [
304
535
  boxSizing,
305
- css3`
536
+ css6`
306
537
  /* 'position: relative' is the containing block for the answer-key tick the theme draws as an
307
538
  absolutely positioned ::before. See CONTRACT.md §7. */
308
539
  :host {
@@ -326,32 +557,126 @@ var qti_hottext_styles_default = [
326
557
  ];
327
558
 
328
559
  // ../interactions/core/dist/elements/qti-hottext/qti-hottext.js
329
- var QtiHottext = class extends ActiveElementMixin(LitElement3, "qti-hottext") {
560
+ var QtiHottext = class extends ActiveElementMixin(LitElement6, "qti-hottext") {
330
561
  static {
331
562
  this.styles = qti_hottext_styles_default;
332
563
  }
333
564
  render() {
334
- return html3`<div part="control"><div part="control-mark"></div></div>
565
+ return html5`<div part="control"><div part="control-mark"></div></div>
335
566
  <slot part="label"></slot>`;
336
567
  }
337
568
  };
338
569
 
339
- // ../interactions/core/dist/elements/qti-simple-associable-choice/qti-simple-associable-choice.js
340
- import { html as html4, LitElement as LitElement4 } from "lit";
341
- import { property as property4, state as state2 } from "lit/decorators.js";
342
- import { repeat } from "lit/directives/repeat.js";
343
- import { consume as consume2 } from "@lit/context";
570
+ // ../interactions/core/dist/elements/qti-inline-choice/qti-inline-choice.js
571
+ import { html as html6, LitElement as LitElement7 } from "lit";
572
+ import { property as property7 } from "lit/decorators.js";
344
573
 
345
- // ../interactions/core/dist/context/drag-drop.context.js
346
- import { createContext } from "@lit/context";
347
- var dragDropContext = createContext(/* @__PURE__ */ Symbol("dragDropContext"));
574
+ // ../interactions/core/dist/elements/qti-inline-choice/qti-inline-choice.styles.js
575
+ import { css as css7 } from "lit";
576
+ var styles = css7`
577
+ /*
578
+ * An option row: one line, clipped, with its text centred against the row's min-height. All four
579
+ * were in the theme, set on this host from the document — which is also why the 'display: block'
580
+ * this file declared never took effect.
581
+ */
582
+ :host {
583
+ display: inline-flex;
584
+ align-items: center;
585
+ white-space: nowrap;
586
+ overflow: hidden;
587
+ box-sizing: border-box;
588
+ }
589
+
590
+ slot {
591
+ display: inline;
592
+ }
593
+ `;
594
+ var qti_inline_choice_styles_default = styles;
595
+
596
+ // ../interactions/core/dist/elements/qti-inline-choice/qti-inline-choice.js
597
+ var __decorate7 = function(decorators, target, key, desc) {
598
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
599
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
600
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
601
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
602
+ };
603
+ var QtiInlineChoice = class extends ActiveElementMixin(LitElement7, "qti-inline-choice") {
604
+ static {
605
+ this.styles = qti_inline_choice_styles_default;
606
+ }
607
+ connectedCallback() {
608
+ super.connectedCallback();
609
+ this.addEventListener("click", this.#onSelectInlineChoice);
610
+ this.dispatchEvent(new CustomEvent("qti-inline-choice-register", {
611
+ bubbles: true,
612
+ composed: true,
613
+ cancelable: false
614
+ }));
615
+ }
616
+ disconnectedCallback() {
617
+ this.removeEventListener("click", this.#onSelectInlineChoice);
618
+ }
619
+ render() {
620
+ return html6` <slot></slot> `;
621
+ }
622
+ #onSelectInlineChoice() {
623
+ this.dispatchEvent(new CustomEvent("qti-inline-choice-select", {
624
+ bubbles: true,
625
+ cancelable: false,
626
+ composed: true,
627
+ detail: { identifier: this.identifier }
628
+ }));
629
+ }
630
+ };
631
+ __decorate7([
632
+ property7({ type: String })
633
+ ], QtiInlineChoice.prototype, "identifier", void 0);
634
+
635
+ // ../interactions/core/dist/elements/qti-prompt/qti-prompt.js
636
+ import { html as html7, LitElement as LitElement8 } from "lit";
637
+
638
+ // ../interactions/core/dist/elements/qti-prompt/qti-prompt.styles.js
639
+ import { css as css8 } from "lit";
640
+ var qti_prompt_styles_default = [
641
+ boxSizing,
642
+ css8`
643
+ :host {
644
+ display: block;
645
+ margin: var(--qti-gap) 0;
646
+ width: 100%;
647
+ }
648
+ `
649
+ ];
650
+
651
+ // ../interactions/core/dist/elements/qti-prompt/qti-prompt.js
652
+ var QtiPrompt = class extends LitElement8 {
653
+ static {
654
+ this.styles = qti_prompt_styles_default;
655
+ }
656
+ render() {
657
+ return html7`<slot></slot>`;
658
+ }
659
+ connectedCallback() {
660
+ super.connectedCallback();
661
+ const inInteraction = this.parentElement?.tagName.endsWith("INTERACTION");
662
+ if (inInteraction) {
663
+ this.setAttribute("slot", "prompt");
664
+ }
665
+ }
666
+ };
667
+
668
+ // ../interactions/core/dist/elements/qti-simple-associable-choice/qti-simple-associable-choice.js
669
+ import { html as html8, LitElement as LitElement9 } from "lit";
670
+ import { property as property8, state as state4 } from "lit/decorators.js";
671
+ import { repeat as repeat3 } from "lit/directives/repeat.js";
672
+ import { consume as consume4 } from "@lit/context";
348
673
 
349
674
  // ../interactions/core/dist/elements/qti-simple-associable-choice/qti-simple-associable-choice.styles.js
350
- import { css as css4 } from "lit";
675
+ import { css as css9 } from "lit";
351
676
  var qti_simple_associable_choice_styles_default = [
352
677
  boxSizing,
353
678
  dropRegion,
354
- css4`
679
+ css9`
355
680
  /*
356
681
  * 'align-items' / 'justify-content' are variables because one caller cannot be reached any other
357
682
  * way. In tabular match this element is a light-DOM *grandchild* of the slotted
@@ -488,17 +813,29 @@ var qti_simple_associable_choice_styles_default = [
488
813
  ::slotted(p) {
489
814
  display: inline;
490
815
  }
816
+
817
+ /*
818
+ * The control div's only content is the theme's ::before grip glyph. Centering it with
819
+ * 'vertical-align: middle' (the theme's only lever on a pseudo-element it owns) aligns to the
820
+ * line box's baseline metrics, which drift with font/line-height. Flex centering here is
821
+ * geometric and font-independent — the same fix qti-simple-choice already has for its control.
822
+ */
823
+ [part='control'] {
824
+ display: flex;
825
+ align-items: center;
826
+ justify-content: center;
827
+ }
491
828
  `
492
829
  ];
493
830
 
494
831
  // ../interactions/core/dist/elements/qti-simple-associable-choice/qti-simple-associable-choice.js
495
- var __decorate4 = function(decorators, target, key, desc) {
832
+ var __decorate8 = function(decorators, target, key, desc) {
496
833
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
497
834
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
498
835
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
499
836
  return c > 3 && r && Object.defineProperty(target, key, r), r;
500
837
  };
501
- var QtiSimpleAssociableChoice = class extends ActiveElementMixin(LitElement4, "qti-simple-associable-choice") {
838
+ var QtiSimpleAssociableChoice = class extends ActiveElementMixin(LitElement9, "qti-simple-associable-choice") {
502
839
  constructor() {
503
840
  super(...arguments);
504
841
  this.matchMin = 0;
@@ -525,29 +862,29 @@ var QtiSimpleAssociableChoice = class extends ActiveElementMixin(LitElement4, "q
525
862
  // So we have a slot for whenever another qti-simple-associable-choice is dropped in here.
526
863
  // And we have slot for content like in this associate interaction
527
864
  render() {
528
- return html4`
865
+ return html8`
529
866
  <div part="control"></div>
530
867
  <slot part="label"></slot>
531
868
  <div part="drop">
532
- ${repeat(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
869
+ ${repeat3(this.drags, (node) => node.getAttribute("identifier"), (node) => node)}
533
870
  </div>
534
871
  `;
535
872
  }
536
873
  };
537
- __decorate4([
538
- property4({
874
+ __decorate8([
875
+ property8({
539
876
  type: Number,
540
877
  attribute: "match-min"
541
878
  })
542
879
  ], QtiSimpleAssociableChoice.prototype, "matchMin", void 0);
543
- __decorate4([
544
- property4({
880
+ __decorate8([
881
+ property8({
545
882
  type: Number,
546
883
  attribute: "match-max"
547
884
  })
548
885
  ], QtiSimpleAssociableChoice.prototype, "matchMax", void 0);
549
- __decorate4([
550
- property4({
886
+ __decorate8([
887
+ property8({
551
888
  type: String,
552
889
  attribute: "fixed",
553
890
  converter: {
@@ -556,20 +893,20 @@ __decorate4([
556
893
  }
557
894
  })
558
895
  ], QtiSimpleAssociableChoice.prototype, "fixed", void 0);
559
- __decorate4([
560
- consume2({ context: dragDropContext, subscribe: true }),
561
- state2()
896
+ __decorate8([
897
+ consume4({ context: dragDropContext, subscribe: true }),
898
+ state4()
562
899
  ], QtiSimpleAssociableChoice.prototype, "_dragDrop", void 0);
563
900
 
564
901
  // ../interactions/core/dist/elements/qti-simple-choice/qti-simple-choice.js
565
- import { html as html5, LitElement as LitElement5, nothing } from "lit";
566
- import { property as property5 } from "lit/decorators.js";
902
+ import { html as html9, LitElement as LitElement10, nothing } from "lit";
903
+ import { property as property9 } from "lit/decorators.js";
567
904
 
568
905
  // ../interactions/core/dist/elements/qti-simple-choice/qti-simple-choice.styles.js
569
- import { css as css5 } from "lit";
906
+ import { css as css10 } from "lit";
570
907
  var qti_simple_choice_styles_default = [
571
908
  boxSizing,
572
- css5`
909
+ css10`
573
910
  /*
574
911
  * 'position: relative' unconditionally, because this element can carry a correction badge and a
575
912
  * badge needs a containing block. The theme draws the badge as an absolutely positioned ::after
@@ -609,13 +946,13 @@ var qti_simple_choice_styles_default = [
609
946
  ];
610
947
 
611
948
  // ../interactions/core/dist/elements/qti-simple-choice/qti-simple-choice.js
612
- var __decorate5 = function(decorators, target, key, desc) {
949
+ var __decorate9 = function(decorators, target, key, desc) {
613
950
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
614
951
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
615
952
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
616
953
  return c > 3 && r && Object.defineProperty(target, key, r), r;
617
954
  };
618
- var QtiSimpleChoice = class extends ActiveElementMixin(LitElement5, "qti-simple-choice") {
955
+ var QtiSimpleChoice = class extends ActiveElementMixin(LitElement10, "qti-simple-choice") {
619
956
  constructor() {
620
957
  super(...arguments);
621
958
  this.templateIdentifier = null;
@@ -627,7 +964,7 @@ var QtiSimpleChoice = class extends ActiveElementMixin(LitElement5, "qti-simple-
627
964
  }
628
965
  static {
629
966
  this.shadowRootOptions = {
630
- ...LitElement5.shadowRootOptions,
967
+ ...LitElement10.shadowRootOptions,
631
968
  delegatesFocus: true
632
969
  };
633
970
  }
@@ -635,19 +972,19 @@ var QtiSimpleChoice = class extends ActiveElementMixin(LitElement5, "qti-simple-
635
972
  return this["internals"].states.has("checked");
636
973
  }
637
974
  render() {
638
- return html5`<div part="control" tabindex="0"><div part="control-mark"></div></div>
639
- ${this.marker ? html5`<div id="label" part="marker">${this.marker}</div>` : nothing}
975
+ return html9`<div part="control" tabindex="0"><div part="control-mark"></div></div>
976
+ ${this.marker ? html9`<div id="label" part="marker">${this.marker}</div>` : nothing}
640
977
  <slot part="label"></slot>`;
641
978
  }
642
979
  };
643
- __decorate5([
644
- property5({ type: String, attribute: "template-identifier" })
980
+ __decorate9([
981
+ property9({ type: String, attribute: "template-identifier" })
645
982
  ], QtiSimpleChoice.prototype, "templateIdentifier", void 0);
646
- __decorate5([
647
- property5({ type: String, attribute: "show-hide" })
983
+ __decorate9([
984
+ property9({ type: String, attribute: "show-hide" })
648
985
  ], QtiSimpleChoice.prototype, "showHide", void 0);
649
- __decorate5([
650
- property5({
986
+ __decorate9([
987
+ property9({
651
988
  type: Boolean,
652
989
  converter: {
653
990
  fromAttribute: (value) => value === "true",
@@ -655,18 +992,18 @@ __decorate5([
655
992
  }
656
993
  })
657
994
  ], QtiSimpleChoice.prototype, "fixed", void 0);
658
- __decorate5([
659
- property5({ type: String, attribute: false })
995
+ __decorate9([
996
+ property9({ type: String, attribute: false })
660
997
  ], QtiSimpleChoice.prototype, "marker", void 0);
661
998
 
662
999
  // ../interactions/associate-interaction/dist/qti-associate-interaction.js
663
- import { html as html6 } from "lit";
664
- import { repeat as repeat2 } from "lit/directives/repeat.js";
665
- import { state as state3 } from "lit/decorators.js";
1000
+ import { html as html10 } from "lit";
1001
+ import { repeat as repeat4 } from "lit/directives/repeat.js";
1002
+ import { state as state5 } from "lit/decorators.js";
666
1003
 
667
1004
  // ../interactions/core/dist/mixins/dropzone-auto-size/dropzone-auto-size.mixin.js
668
- import { property as property6 } from "lit/decorators.js";
669
- var __decorate6 = function(decorators, target, key, desc) {
1005
+ import { property as property10 } from "lit/decorators.js";
1006
+ var __decorate10 = function(decorators, target, key, desc) {
670
1007
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
671
1008
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
672
1009
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -860,8 +1197,8 @@ var DropzoneAutoSizeMixin = (superClass, draggablesSelector, droppablesSelector,
860
1197
  super.disconnectedCallback();
861
1198
  }
862
1199
  }
863
- __decorate6([
864
- property6({ type: Boolean, attribute: "auto-size-dropzones" })
1200
+ __decorate10([
1201
+ property10({ type: Boolean, attribute: "auto-size-dropzones" })
865
1202
  /**
866
1203
  * Size the dropzones from the chips they will hold.
867
1204
  *
@@ -901,22 +1238,22 @@ var [Observable, Subscriber] = (() => {
901
1238
  const AsyncFromSyncIteratorPrototype = {
902
1239
  next(...args) {
903
1240
  const O = this;
904
- const state11 = privateState.get(O);
905
- if (!state11?.syncIteratorRecord)
1241
+ const state14 = privateState.get(O);
1242
+ if (!state14?.syncIteratorRecord)
906
1243
  throw new TypeError(
907
1244
  "AsyncFromSyncIteratorPrototype.next called on invalid object"
908
1245
  );
909
- const { syncIteratorRecord } = state11;
1246
+ const { syncIteratorRecord } = state14;
910
1247
  return pTry(() => syncIteratorRecord.next(...args));
911
1248
  },
912
1249
  return(...args) {
913
1250
  const O = this;
914
- const state11 = privateState.get(O);
915
- if (!state11?.syncIteratorRecord)
1251
+ const state14 = privateState.get(O);
1252
+ if (!state14?.syncIteratorRecord)
916
1253
  throw new TypeError(
917
1254
  "AsyncFromSyncIteratorPrototype.return called on invalid object"
918
1255
  );
919
- const { syncIteratorRecord } = state11;
1256
+ const { syncIteratorRecord } = state14;
920
1257
  return pTry(() => {
921
1258
  if (!syncIteratorRecord.return) return { value: void 0, done: true };
922
1259
  return syncIteratorRecord.return(...args);
@@ -924,12 +1261,12 @@ var [Observable, Subscriber] = (() => {
924
1261
  },
925
1262
  throw(...args) {
926
1263
  const O = this;
927
- const state11 = privateState.get(O);
928
- if (!state11?.syncIteratorRecord)
1264
+ const state14 = privateState.get(O);
1265
+ if (!state14?.syncIteratorRecord)
929
1266
  throw new TypeError(
930
1267
  "AsyncFromSyncIteratorPrototype.throw called on invalid object"
931
1268
  );
932
- const { syncIteratorRecord } = state11;
1269
+ const { syncIteratorRecord } = state14;
933
1270
  return pTry(() => {
934
1271
  if (!syncIteratorRecord.throw) {
935
1272
  syncIteratorRecord.return();
@@ -995,11 +1332,11 @@ var [Observable, Subscriber] = (() => {
995
1332
  }
996
1333
  }
997
1334
  function closeASubscription(subscriber, reason) {
998
- const state11 = privateState.get(subscriber);
999
- if (!state11?.active) return;
1000
- state11.active = false;
1001
- state11.subscriptionController.abort(reason);
1002
- for (const teardown of state11.teardowns.reverse()) {
1335
+ const state14 = privateState.get(subscriber);
1336
+ if (!state14?.active) return;
1337
+ state14.active = false;
1338
+ state14.subscriptionController.abort(reason);
1339
+ for (const teardown of state14.teardowns.reverse()) {
1003
1340
  if (isBrowserContext() && !isDocumentFullyActive(document)) return;
1004
1341
  try {
1005
1342
  teardown();
@@ -1080,10 +1417,10 @@ var [Observable, Subscriber] = (() => {
1080
1417
  if (!(this instanceof Subscriber2))
1081
1418
  throw new TypeError("illegal invocation");
1082
1419
  if (!arguments.length) throw new TypeError("too few arguments");
1083
- const state11 = privateState.get(this);
1084
- if (!state11?.active) return;
1420
+ const state14 = privateState.get(this);
1421
+ if (!state14?.active) return;
1085
1422
  if (isBrowserContext() && !isDocumentFullyActive(document)) return;
1086
- const internalObservers = new Set(state11.observers);
1423
+ const internalObservers = new Set(state14.observers);
1087
1424
  for (const observer of internalObservers) {
1088
1425
  observer.next(value);
1089
1426
  }
@@ -1093,14 +1430,14 @@ var [Observable, Subscriber] = (() => {
1093
1430
  if (!(this instanceof Subscriber2))
1094
1431
  throw new TypeError("illegal invocation");
1095
1432
  if (!arguments.length) throw new TypeError("too few arguments");
1096
- const state11 = privateState.get(this);
1097
- if (!state11?.active) {
1433
+ const state14 = privateState.get(this);
1434
+ if (!state14?.active) {
1098
1435
  reportError(error);
1099
1436
  return;
1100
1437
  }
1101
1438
  if (isBrowserContext() && !isDocumentFullyActive(document)) return;
1102
1439
  closeASubscription(this, error);
1103
- const internalObservers = new Set(state11.observers);
1440
+ const internalObservers = new Set(state14.observers);
1104
1441
  for (const observer of internalObservers) {
1105
1442
  observer.error(error);
1106
1443
  }
@@ -1109,11 +1446,11 @@ var [Observable, Subscriber] = (() => {
1109
1446
  complete() {
1110
1447
  if (!(this instanceof Subscriber2))
1111
1448
  throw new TypeError("illegal invocation");
1112
- const state11 = privateState.get(this);
1113
- if (!state11?.active) return;
1449
+ const state14 = privateState.get(this);
1450
+ if (!state14?.active) return;
1114
1451
  if (isBrowserContext() && !isDocumentFullyActive(document)) return;
1115
1452
  closeASubscription(this);
1116
- const internalObservers = new Set(state11.observers);
1453
+ const internalObservers = new Set(state14.observers);
1117
1454
  for (const observer of internalObservers) {
1118
1455
  observer.complete();
1119
1456
  }
@@ -1126,9 +1463,9 @@ var [Observable, Subscriber] = (() => {
1126
1463
  throw new TypeError(`Parameter 1 is not of type 'Function'`);
1127
1464
  }
1128
1465
  if (isBrowserContext() && !isDocumentFullyActive(document)) return;
1129
- const state11 = privateState.get(this);
1130
- if (state11?.active)
1131
- state11.teardowns.push(teardown);
1466
+ const state14 = privateState.get(this);
1467
+ if (state14?.active)
1468
+ state14.teardowns.push(teardown);
1132
1469
  else teardown();
1133
1470
  }
1134
1471
  get active() {
@@ -2178,6 +2515,10 @@ function closestCornersCollision(dropzones, clientX, clientY, dragElement) {
2178
2515
  }
2179
2516
  return closestZone;
2180
2517
  }
2518
+ function containsPoint(zone, x, y) {
2519
+ const rect = zone.getBoundingClientRect();
2520
+ return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
2521
+ }
2181
2522
  function closestCornersWithInventoryPriorityCollision(dropzones, clientX, clientY, dragElement, dragContainers) {
2182
2523
  const identifiedDragContainers = dragContainers && dragContainers.length > 0 ? dropzones.filter((zone) => dragContainers.includes(zone)) : dropzones.filter((zone) => zone.tagName === "SLOT" && zone.hasAttribute("part") && zone.getAttribute("part")?.includes("drags"));
2183
2524
  const allRegularDroppables = dropzones.filter((zone) => !identifiedDragContainers.includes(zone));
@@ -2248,6 +2589,9 @@ function closestCornersWithInventoryPriorityCollision(dropzones, clientX, client
2248
2589
  return closestDragContainer;
2249
2590
  }
2250
2591
  }
2592
+ if (closestDroppable && containsPoint(closestDroppable, clientX, clientY)) {
2593
+ return closestDroppable;
2594
+ }
2251
2595
  const dragOrigin = dragElement?.getAttribute("data-drag-origin");
2252
2596
  const inventoryPriorityThreshold = dragOrigin === "droppable" ? 0.85 : 1.5;
2253
2597
  if (closestDragContainer && closestDroppable) {
@@ -2305,17 +2649,17 @@ function isDraggableDisabled(target) {
2305
2649
  return internals?.states?.has("disabled") ?? false;
2306
2650
  }
2307
2651
  var internalsOf = (el) => el?.internals;
2308
- function setDragChipState(el, state11, on) {
2652
+ function setDragChipState(el, state14, on) {
2309
2653
  const states = internalsOf(el)?.states;
2310
2654
  if (!states)
2311
2655
  return;
2312
2656
  if (on)
2313
- states.add(state11);
2657
+ states.add(state14);
2314
2658
  else
2315
- states.delete(state11);
2659
+ states.delete(state14);
2316
2660
  }
2317
- function hasDragChipState(el, state11) {
2318
- return internalsOf(el)?.states?.has(state11) ?? false;
2661
+ function hasDragChipState(el, state14) {
2662
+ return internalsOf(el)?.states?.has(state14) ?? false;
2319
2663
  }
2320
2664
  function clearDragChipStates(el) {
2321
2665
  setDragChipState(el, "dragging", false);
@@ -3027,8 +3371,8 @@ var DragDropCoreMixin = (superClass, draggablesSelector, droppablesSelector, dra
3027
3371
  const clone = element.cloneNode(true);
3028
3372
  const computedStyles = window.getComputedStyle(element);
3029
3373
  for (let i = 0; i < computedStyles.length; i++) {
3030
- const property20 = computedStyles[i];
3031
- clone.style.setProperty(property20, computedStyles.getPropertyValue(property20));
3374
+ const property26 = computedStyles[i];
3375
+ clone.style.setProperty(property26, computedStyles.getPropertyValue(property26));
3032
3376
  }
3033
3377
  const host = resolveDragCloneHost(element.isConnected ? element : this, this.dragCloneRoot());
3034
3378
  this.cloneFrame = measureFixedFrame(host);
@@ -3160,14 +3504,14 @@ var DragDropCoreMixin = (superClass, draggablesSelector, droppablesSelector, dra
3160
3504
  returnAnchorItems: []
3161
3505
  };
3162
3506
  }
3163
- setInternalsState(state11, enabled) {
3507
+ setInternalsState(state14, enabled) {
3164
3508
  const internals = this._internals;
3165
3509
  if (!internals?.states)
3166
3510
  return;
3167
3511
  if (enabled) {
3168
- internals.states.add(state11);
3512
+ internals.states.add(state14);
3169
3513
  } else {
3170
- internals.states.delete(state11);
3514
+ internals.states.delete(state14);
3171
3515
  }
3172
3516
  }
3173
3517
  cleanup() {
@@ -3195,7 +3539,7 @@ var DragDropCoreMixin = (superClass, draggablesSelector, droppablesSelector, dra
3195
3539
  };
3196
3540
 
3197
3541
  // ../interactions/core/dist/mixins/drag-drop-observables/drag-drop-slotted.mixin.js
3198
- import { property as property7 } from "lit/decorators.js";
3542
+ import { property as property11 } from "lit/decorators.js";
3199
3543
  import { provide } from "@lit/context";
3200
3544
 
3201
3545
  // ../interactions/core/dist/mixins/drag-drop-observables/utils/flip.utils.js
@@ -3216,9 +3560,9 @@ function captureFlipState(element) {
3216
3560
  function flipStateFromRect(rect) {
3217
3561
  return { left: rect.left, top: rect.top, width: rect.width, height: rect.height };
3218
3562
  }
3219
- function captureMultipleFlipStates(elements17) {
3563
+ function captureMultipleFlipStates(elements32) {
3220
3564
  const states = /* @__PURE__ */ new Map();
3221
- elements17.forEach((element) => {
3565
+ elements32.forEach((element) => {
3222
3566
  states.set(element, captureFlipState(element));
3223
3567
  });
3224
3568
  return states;
@@ -3287,7 +3631,7 @@ function animateMultipleFlips(previousStates, options = {}) {
3287
3631
  }
3288
3632
 
3289
3633
  // ../interactions/core/dist/mixins/drag-drop-observables/drag-drop-slotted.mixin.js
3290
- var __decorate7 = function(decorators, target, key, desc) {
3634
+ var __decorate11 = function(decorators, target, key, desc) {
3291
3635
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3292
3636
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3293
3637
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -3892,20 +4236,20 @@ var DragDropSlottedMixin = (superClass, draggablesSelector, droppablesSelector,
3892
4236
  return super.reportValidity();
3893
4237
  }
3894
4238
  }
3895
- __decorate7([
3896
- property7({ type: Number, reflect: true, attribute: "min-associations" })
4239
+ __decorate11([
4240
+ property11({ type: Number, reflect: true, attribute: "min-associations" })
3897
4241
  ], DragDropSlottedElement.prototype, "minAssociations", void 0);
3898
- __decorate7([
3899
- property7({ type: Number, reflect: true, attribute: "max-associations" })
4242
+ __decorate11([
4243
+ property11({ type: Number, reflect: true, attribute: "max-associations" })
3900
4244
  ], DragDropSlottedElement.prototype, "maxAssociations", null);
3901
- __decorate7([
4245
+ __decorate11([
3902
4246
  provide({ context: dragDropContext })
3903
4247
  ], DragDropSlottedElement.prototype, "_dragDrop", void 0);
3904
- __decorate7([
3905
- property7({ type: Boolean, attribute: "disable-animations" })
4248
+ __decorate11([
4249
+ property11({ type: Boolean, attribute: "disable-animations" })
3906
4250
  ], DragDropSlottedElement.prototype, "disableAnimations", null);
3907
- __decorate7([
3908
- property7({
4251
+ __decorate11([
4252
+ property11({
3909
4253
  attribute: "response",
3910
4254
  reflect: false,
3911
4255
  noAccessor: true,
@@ -3917,8 +4261,8 @@ var DragDropSlottedMixin = (superClass, draggablesSelector, droppablesSelector,
3917
4261
 
3918
4262
  // ../interactions/core/dist/mixins/drag-drop-observables/strategies/sorting.strategy.js
3919
4263
  var VerticalListSortingStrategy = class {
3920
- getInsertPosition(elements17, _activeElement, targetElement, _clientX, clientY) {
3921
- const targetIndex = elements17.indexOf(targetElement);
4264
+ getInsertPosition(elements32, _activeElement, targetElement, _clientX, clientY) {
4265
+ const targetIndex = elements32.indexOf(targetElement);
3922
4266
  if (targetIndex === -1)
3923
4267
  return null;
3924
4268
  const rect = targetElement.getBoundingClientRect();
@@ -4202,12 +4546,12 @@ var DragDropSlottedSortableMixin = (superClass, sortableItemSelector = '[qti-dra
4202
4546
  };
4203
4547
 
4204
4548
  // ../interactions/associate-interaction/dist/qti-associate-interaction.styles.js
4205
- import { css as css6 } from "lit";
4549
+ import { css as css11 } from "lit";
4206
4550
  var qti_associate_interaction_styles_default = [
4207
4551
  boxSizing,
4208
4552
  validationMessage,
4209
4553
  dropRegion,
4210
- css6`
4554
+ css11`
4211
4555
  :host {
4212
4556
  display: block; /* necessary to calculate scaling position */
4213
4557
  }
@@ -4264,7 +4608,7 @@ var qti_associate_interaction_styles_default = [
4264
4608
  ];
4265
4609
 
4266
4610
  // ../interactions/associate-interaction/dist/qti-associate-interaction.js
4267
- var __decorate8 = function(decorators, target, key, desc) {
4611
+ var __decorate12 = function(decorators, target, key, desc) {
4268
4612
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4269
4613
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4270
4614
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -4297,8 +4641,8 @@ var QtiAssociateInteraction = class extends DragDropSlottedSortableMixin(Slotted
4297
4641
  */
4298
4642
  #renderDrop(identifier, name) {
4299
4643
  const drags = this._dragDrop?.nodesByTarget?.[identifier] ?? [];
4300
- return html6`<div name=${name} part="drop" data-declarative-drops identifier=${identifier}>
4301
- ${repeat2(drags, (node) => node.getAttribute("identifier"), (node) => node)}
4644
+ return html10`<div name=${name} part="drop" data-declarative-drops identifier=${identifier}>
4645
+ ${repeat4(drags, (node) => node.getAttribute("identifier"), (node) => node)}
4302
4646
  </div>`;
4303
4647
  }
4304
4648
  /**
@@ -4354,10 +4698,10 @@ var QtiAssociateInteraction = class extends DragDropSlottedSortableMixin(Slotted
4354
4698
  }) ?? [];
4355
4699
  }
4356
4700
  render() {
4357
- return html6` <slot name="prompt"></slot>
4701
+ return html10` <slot name="prompt"></slot>
4358
4702
  <slot part="drags" name="qti-simple-associable-choice"></slot>
4359
4703
  <div part="drops">
4360
- ${this._childrenMap.length > 0 && Array.from({ length: this.#rowCount }, (_, index) => html6`<div part="drop-row">
4704
+ ${this._childrenMap.length > 0 && Array.from({ length: this.#rowCount }, (_, index) => html10`<div part="drop-row">
4361
4705
  ${this.#renderDrop(`droplist${index}_left`, `left${index}`)}
4362
4706
  ${this.#renderDrop(`droplist${index}_right`, `right${index}`)}
4363
4707
  </div>`)}
@@ -4376,17 +4720,17 @@ var QtiAssociateInteraction = class extends DragDropSlottedSortableMixin(Slotted
4376
4720
  this.removeEventListener("register-qti-simple-associable-choice", this._registerChoiceHandler);
4377
4721
  }
4378
4722
  };
4379
- __decorate8([
4380
- state3()
4723
+ __decorate12([
4724
+ state5()
4381
4725
  ], QtiAssociateInteraction.prototype, "_childrenMap", void 0);
4382
4726
 
4383
4727
  // ../interactions/choice-interaction/dist/qti-choice-interaction.js
4384
- import { html as html7 } from "lit";
4385
- import { property as property10 } from "lit/decorators.js";
4728
+ import { html as html11 } from "lit";
4729
+ import { property as property14 } from "lit/decorators.js";
4386
4730
 
4387
4731
  // ../interactions/core/dist/mixins/choices/choices.mixin.js
4388
- import { property as property8, query } from "lit/decorators.js";
4389
- var __decorate9 = function(decorators, target, key, desc) {
4732
+ import { property as property12, query } from "lit/decorators.js";
4733
+ var __decorate13 = function(decorators, target, key, desc) {
4390
4734
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4391
4735
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4392
4736
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -4576,40 +4920,40 @@ var ChoicesMixin = (superClass, selector) => {
4576
4920
  });
4577
4921
  }
4578
4922
  }
4579
- __decorate9([
4923
+ __decorate13([
4580
4924
  query("#validation-message")
4581
4925
  ], ChoicesMixinElement.prototype, "_validationMessageElement", void 0);
4582
- __decorate9([
4583
- property8({ type: Number, attribute: "min-choices" })
4926
+ __decorate13([
4927
+ property12({ type: Number, attribute: "min-choices" })
4584
4928
  ], ChoicesMixinElement.prototype, "minChoices", void 0);
4585
- __decorate9([
4586
- property8({ type: Number, attribute: "max-choices" })
4929
+ __decorate13([
4930
+ property12({ type: Number, attribute: "max-choices" })
4587
4931
  ], ChoicesMixinElement.prototype, "maxChoices", void 0);
4588
- __decorate9([
4932
+ __decorate13([
4589
4933
  watch("maxChoices")
4590
4934
  ], ChoicesMixinElement.prototype, "_handleMaxChoicesChange", null);
4591
- __decorate9([
4935
+ __decorate13([
4592
4936
  watch("disabled", { waitUntilFirstUpdate: true })
4593
4937
  ], ChoicesMixinElement.prototype, "_handleDisabledChange", void 0);
4594
- __decorate9([
4938
+ __decorate13([
4595
4939
  watch("readonly", { waitUntilFirstUpdate: true })
4596
4940
  ], ChoicesMixinElement.prototype, "_handleReadonlyChange", void 0);
4597
- __decorate9([
4598
- property8({
4941
+ __decorate13([
4942
+ property12({
4599
4943
  attribute: "response",
4600
4944
  reflect: false,
4601
4945
  converter: responseAttributeConverter({ emptyAs: "" })
4602
4946
  })
4603
4947
  ], ChoicesMixinElement.prototype, "response", void 0);
4604
- __decorate9([
4948
+ __decorate13([
4605
4949
  watch("response", { waitUntilFirstUpdate: true })
4606
4950
  ], ChoicesMixinElement.prototype, "_handleValueChange", void 0);
4607
4951
  return ChoicesMixinElement;
4608
4952
  };
4609
4953
 
4610
4954
  // ../interactions/core/dist/mixins/vocabulary/vocabulary-mixin.js
4611
- import { property as property9 } from "lit/decorators.js";
4612
- var __decorate10 = function(decorators, target, key, desc) {
4955
+ import { property as property13 } from "lit/decorators.js";
4956
+ var __decorate14 = function(decorators, target, key, desc) {
4613
4957
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4614
4958
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4615
4959
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -4690,174 +5034,749 @@ var VocabularyMixin = (superClass, _selector) => {
4690
5034
  #getActiveLabelType() {
4691
5035
  return this.#classes.filter((c) => this.#allLabels.includes(c)).pop() ?? null;
4692
5036
  }
4693
- #getActiveLabelSuffixType() {
4694
- return this.#classes.filter((c) => this.#allLabelSuffixes.includes(c)).pop() ?? null;
5037
+ #getActiveLabelSuffixType() {
5038
+ return this.#classes.filter((c) => this.#allLabelSuffixes.includes(c)).pop() ?? null;
5039
+ }
5040
+ #getLabel(index, labelType, labelSuffixType) {
5041
+ let effectiveLabelType = labelType;
5042
+ if (!effectiveLabelType && labelSuffixType && labelSuffixType !== "qti-labels-suffix-none") {
5043
+ effectiveLabelType = "qti-labels-upper-alpha";
5044
+ }
5045
+ if (!effectiveLabelType || effectiveLabelType === "qti-labels-none") {
5046
+ return "";
5047
+ }
5048
+ let label = "";
5049
+ switch (effectiveLabelType) {
5050
+ case "qti-labels-decimal":
5051
+ label = `${index}`;
5052
+ break;
5053
+ case "qti-labels-lower-alpha":
5054
+ label = this.#toAlphabetic(index, "lower");
5055
+ break;
5056
+ case "qti-labels-upper-alpha":
5057
+ label = this.#toAlphabetic(index, "upper");
5058
+ break;
5059
+ }
5060
+ if (labelSuffixType === "qti-labels-suffix-period") {
5061
+ return `${label}.`;
5062
+ }
5063
+ if (labelSuffixType === "qti-labels-suffix-parenthesis") {
5064
+ return `${label})`;
5065
+ }
5066
+ return label;
5067
+ }
5068
+ #toAlphabetic(index, casing) {
5069
+ let value = index;
5070
+ let label = "";
5071
+ const charCodeBase = casing === "lower" ? 97 : 65;
5072
+ while (value > 0) {
5073
+ value -= 1;
5074
+ label = String.fromCharCode(charCodeBase + value % 26) + label;
5075
+ value = Math.floor(value / 26);
5076
+ }
5077
+ return label;
5078
+ }
5079
+ }
5080
+ __decorate14([
5081
+ property13({
5082
+ type: String,
5083
+ attribute: "class"
5084
+ })
5085
+ ], VocabularyElement.prototype, "class", null);
5086
+ return VocabularyElement;
5087
+ };
5088
+
5089
+ // ../interactions/choice-interaction/dist/qti-choice-interaction.styles.js
5090
+ import { css as css12 } from "lit";
5091
+ var qti_choice_interaction_styles_default = [
5092
+ boxSizing,
5093
+ validationMessage,
5094
+ css12`
5095
+ :host {
5096
+ display: block;
5097
+ }
5098
+
5099
+ [part='slot'] {
5100
+ display: grid;
5101
+ gap: 10px;
5102
+ }
5103
+
5104
+ /* Define the number of columns dynamically */
5105
+ :host([class*='qti-choices-stacking-']) [part='slot'] {
5106
+ grid-template-columns: repeat(var(--stacking-count, 1), 1fr);
5107
+ }
5108
+
5109
+ /* Apply dynamic stacking count based on class */
5110
+ :host(.qti-choices-stacking-1) {
5111
+ --stacking-count: 1;
5112
+ }
5113
+ :host(.qti-choices-stacking-2) {
5114
+ --stacking-count: 2;
5115
+ }
5116
+ :host(.qti-choices-stacking-3) {
5117
+ --stacking-count: 3;
5118
+ }
5119
+ :host(.qti-choices-stacking-4) {
5120
+ --stacking-count: 4;
5121
+ }
5122
+ :host(.qti-choices-stacking-5) {
5123
+ --stacking-count: 5;
5124
+ }
5125
+
5126
+ /* Default slot item layout */
5127
+ ::slotted(qti-simple-choice) {
5128
+ display: flex;
5129
+ align-items: center;
5130
+ white-space: normal;
5131
+ }
5132
+
5133
+ /* Orientation styles */
5134
+ :host(.qti-orientation-horizontal) [part='slot'] {
5135
+ grid-auto-flow: dense column;
5136
+ grid-auto-columns: 1fr;
5137
+ }
5138
+
5139
+ :host(.qti-orientation-vertical) [part='slot'] {
5140
+ grid-auto-flow: row;
5141
+ }
5142
+
5143
+ /* Vertical and horizontal stacking logic */
5144
+ :host(.qti-orientation-vertical[class*='qti-choices-stacking-']) [part='slot'] {
5145
+ grid-auto-flow: dense column;
5146
+ grid-auto-columns: 1fr;
5147
+ grid-template-columns: repeat(var(--stacking-count), 1fr);
5148
+ grid-template-rows: repeat(calc(var(--item-count) / var(--stacking-count)), 1fr);
5149
+ }
5150
+
5151
+ :host(.qti-orientation-horizontal[class*='qti-choices-stacking-']) [part='slot'] {
5152
+ grid-auto-flow: row;
5153
+ grid-template-columns: repeat(var(--stacking-count), 1fr);
5154
+ grid-template-rows: unset;
5155
+ }
5156
+
5157
+ /* Ensure even distribution in vertical mode */
5158
+ :host(.qti-orientation-vertical) ::slotted(qti-simple-choice:nth-child(even)) {
5159
+ grid-row: auto;
5160
+ }
5161
+ `
5162
+ ];
5163
+
5164
+ // ../interactions/choice-interaction/dist/qti-choice-interaction.js
5165
+ var __decorate15 = function(decorators, target, key, desc) {
5166
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5167
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5168
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5169
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
5170
+ };
5171
+ var QtiChoiceInteraction = class extends VocabularyMixin(ChoicesMixin(Interaction, "qti-simple-choice"), "qti-simple-choice") {
5172
+ constructor() {
5173
+ super(...arguments);
5174
+ this.orientation = "vertical";
5175
+ }
5176
+ static {
5177
+ this.styles = qti_choice_interaction_styles_default;
5178
+ }
5179
+ #handleSlotChange() {
5180
+ const choices = this.querySelectorAll("qti-simple-choice");
5181
+ this.style.setProperty("--item-count", choices.length.toString());
5182
+ }
5183
+ render() {
5184
+ return html11`
5185
+ <slot part="prompt" name="prompt"></slot>
5186
+ <slot part="slot" @slotchange=${this.#handleSlotChange}></slot>
5187
+ <div part="message" role="alert" id="validation-message"></div>
5188
+ `;
5189
+ }
5190
+ };
5191
+ __decorate15([
5192
+ property14({ type: String })
5193
+ ], QtiChoiceInteraction.prototype, "orientation", void 0);
5194
+
5195
+ // ../interactions/custom-interaction/dist/qti-custom-interaction.js
5196
+ import { html as html12 } from "lit";
5197
+ import { property as property15, state as state6 } from "lit/decorators.js";
5198
+
5199
+ // ../interactions/custom-interaction/dist/qti-custom-interaction.styles.js
5200
+ import { css as css13 } from "lit";
5201
+ var qti_custom_interaction_styles_default = [
5202
+ boxSizing,
5203
+ css13`
5204
+ /* The box this element already had. See the note in qti-match-interaction.styles.ts. */
5205
+ :host {
5206
+ display: block;
5207
+ }
5208
+ `
5209
+ ];
5210
+
5211
+ // ../interactions/custom-interaction/dist/qti-custom-interaction.js
5212
+ var __decorate16 = function(decorators, target, key, desc) {
5213
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5214
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5215
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5216
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
5217
+ };
5218
+ var registerCES = `
5219
+ const postToParentWindows = (type, data) => {
5220
+ window.top.postMessage(data ? { type, data } : { type }, '*');
5221
+ let w = window.parent;
5222
+ while (w) {
5223
+ if (w !== window.top) {
5224
+ w.postMessage({ type, data }, '*');
5225
+ }
5226
+ if (w !== w.parent) {
5227
+ w = w.parent;
5228
+ } else {
5229
+ w = null;
5230
+ }
5231
+ }
5232
+ };
5233
+
5234
+ window.CES = {
5235
+ media: null,
5236
+ response: null,
5237
+ load: () => {
5238
+ let resolveCount = 0;
5239
+
5240
+ const handleMessage = (event) => {
5241
+ if (event.data.type === "mediaData") {
5242
+ const media = event.data.data;
5243
+ CES.media = media;
5244
+ resolveCount++;
5245
+ } else if (event.data.type === "responseData") {
5246
+ const response = event.data.data;
5247
+ if (response && Array.isArray(response) && response.length > 0) {
5248
+ // state is stored in the first element of the array
5249
+ CES.response = response[0];
5250
+ // Wait a short moment to ensure CES.response is set
5251
+ setTimeout(() => {
5252
+ // Re-create the Controller instance if it exists
5253
+ if (typeof Controller === 'function') {
5254
+ console.log("Re-creating Controller instance");
5255
+ ctrl = new Controller();
5256
+ }
5257
+ }, 50);
5258
+ } else {
5259
+ CES.response = response;
5260
+ }
5261
+ resolveCount++;
5262
+ }
5263
+ if (resolveCount === 2) {
5264
+ //window.removeEventListener("message", handleMessage);
5265
+ }
5266
+ };
5267
+ window.addEventListener("message", handleMessage);
5268
+ postToParentWindows("getMedia");
5269
+ postToParentWindows("getResponse");
5270
+ },
5271
+ setResponse: (data) => {
5272
+ postToParentWindows("setResponse", data);
5273
+ },
5274
+ getResponse: () => {
5275
+ return CES.response;
5276
+ },
5277
+ getMedia: () => {
5278
+ return CES.media;
5279
+ },
5280
+ setStageHeight: () => {
5281
+ postToParentWindows("setStageHeight");
5282
+ },
5283
+ };
5284
+ CES.load();
5285
+ `;
5286
+ var ciBootstrap = `
5287
+ (function() {
5288
+ var blobUrlReceived = null;
5289
+
5290
+ const createIframe = () => {
5291
+ if (!blobUrlReceived || !document.body) return;
5292
+ var n = document.createElement('iframe');
5293
+ n.frameBorder = '0';
5294
+ n.scrolling = 'no';
5295
+ n.src = blobUrlReceived;
5296
+ n.style.width = '100%';
5297
+ n.style.height = '100%';
5298
+ document.body.appendChild(n);
5299
+ };
5300
+
5301
+ const handleMessage = (event) => {
5302
+ if (event.data.type === 'blobUrl') {
5303
+ blobUrlReceived = event.data.data;
5304
+ window.removeEventListener('message', handleMessage);
5305
+ createIframe();
5306
+ }
5307
+ };
5308
+
5309
+ window.addEventListener('message', handleMessage);
5310
+
5311
+ // Wait for document ready before requesting blobUrl
5312
+ const requestBlobUrl = () => {
5313
+ let w = window.parent;
5314
+ while (w) {
5315
+ w.postMessage({ type: 'getBlobUrl' }, '*');
5316
+ if (w !== w.parent) {
5317
+ w = w.parent;
5318
+ } else {
5319
+ w = null;
5320
+ }
5321
+ }
5322
+ };
5323
+
5324
+ if (document.readyState === 'loading') {
5325
+ document.addEventListener('DOMContentLoaded', requestBlobUrl);
5326
+ } else {
5327
+ requestBlobUrl();
5328
+ }
5329
+ })();
5330
+ `;
5331
+ var QtiCustomInteraction = class extends Interaction {
5332
+ #rawResponse;
5333
+ #manifestUrl;
5334
+ #resourceBaseUrl;
5335
+ static {
5336
+ this.styles = qti_custom_interaction_styles_default;
5337
+ }
5338
+ constructor() {
5339
+ super();
5340
+ this.#rawResponse = "";
5341
+ this.#manifestUrl = null;
5342
+ this.#resourceBaseUrl = null;
5343
+ this._errorMessage = null;
5344
+ this.#contentBlobUrl = null;
5345
+ this.handlePostMessage = this.handlePostMessage.bind(this);
5346
+ }
5347
+ // Pre-created blob URL for the index.html with injected CES proxy
5348
+ #contentBlobUrl;
5349
+ connectedCallback() {
5350
+ super.connectedCallback();
5351
+ let manifestPath = this.data;
5352
+ if (!manifestPath) {
5353
+ const objectEl = this.querySelector("object[data]");
5354
+ if (objectEl) {
5355
+ manifestPath = objectEl.getAttribute("data");
5356
+ const width = objectEl.getAttribute("width");
5357
+ const height = objectEl.getAttribute("height");
5358
+ if (width)
5359
+ this.setAttribute("width", width);
5360
+ if (height)
5361
+ this.setAttribute("height", height);
5362
+ }
5363
+ }
5364
+ if (!manifestPath) {
5365
+ this._errorMessage = "No manifest path found (neither data attribute nor object child)";
5366
+ return;
5367
+ }
5368
+ const uriToManifest = manifestPath.startsWith("http") || manifestPath.startsWith("blob") ? manifestPath : removeDoubleSlashes((this.baseItemUrl || "") + "/" + manifestPath);
5369
+ this.#manifestUrl = new URL(uriToManifest, window.location.href).toString();
5370
+ fetch(uriToManifest).then((response) => {
5371
+ return response.json();
5372
+ }).then((data) => {
5373
+ this.manifest = data;
5374
+ this.setupCES();
5375
+ }).catch((err) => {
5376
+ this._errorMessage = err;
5377
+ });
5378
+ }
5379
+ /**
5380
+ * Sets up the CES custom interaction by creating the iframe structure and
5381
+ * handling the CES API communication via postMessage.
5382
+ *
5383
+ * For interactions that use CES, this method:
5384
+ * 1. Fetches the original bootstrap.js and checks if it uses CES
5385
+ * 2. If CES is used, fetches index.html and injects the registerCES proxy
5386
+ * 3. Creates a blob URL for the modified HTML (stored in _contentBlobUrl)
5387
+ * 4. Replaces bootstrap.js with ciBootstrap that loads the blob URL
5388
+ * 5. Sets up postMessage listeners for CES API calls
5389
+ */
5390
+ async setupCES() {
5391
+ await this.updateComplete;
5392
+ const iframe = this.shadowRoot?.querySelector("#pciContainer");
5393
+ if (!iframe) {
5394
+ this._errorMessage = "pciContainer iframe not found";
5395
+ return;
5396
+ }
5397
+ if (!iframe.getAttribute("src")) {
5398
+ iframe.setAttribute("src", "about:blank");
5399
+ }
5400
+ let iframeDoc = iframe.contentDocument ?? iframe.contentWindow?.document ?? null;
5401
+ if (!iframeDoc) {
5402
+ await new Promise((resolve) => iframe.addEventListener("load", () => resolve(), { once: true }));
5403
+ iframeDoc = iframe.contentDocument ?? iframe.contentWindow?.document ?? null;
5404
+ }
5405
+ if (!iframeDoc) {
5406
+ this._errorMessage = "pciContainer iframe document not available";
5407
+ return;
5408
+ }
5409
+ if (!this.manifest.script || this.manifest.script.length === 0) {
5410
+ this._errorMessage = "No script found in manifest";
5411
+ return;
5412
+ }
5413
+ if (!this.manifest.style || this.manifest.style.length === 0) {
5414
+ this._errorMessage = "No style found in manifest";
5415
+ return;
5416
+ }
5417
+ const cssRef = this.manifest.style[0];
5418
+ const baseCandidates = this.#getBaseCandidates();
5419
+ const cssResolved = await this.#resolveResourceWithFallback(cssRef, baseCandidates);
5420
+ const cssUrl = cssResolved.url;
5421
+ if (cssResolved.baseUrl && !this.#resourceBaseUrl) {
5422
+ this.#resourceBaseUrl = cssResolved.baseUrl;
5423
+ }
5424
+ const usesCES = true;
5425
+ if (usesCES) {
5426
+ let indexUrl = "";
5427
+ if (this.manifest.media && this.manifest.media.length > 0) {
5428
+ const mediaRef = this.manifest.media[0];
5429
+ const indexResolved = await this.#resolveResourceWithFallback(mediaRef, baseCandidates, {
5430
+ returnText: true
5431
+ });
5432
+ indexUrl = indexResolved.url;
5433
+ if (indexResolved.baseUrl && !this.#resourceBaseUrl) {
5434
+ this.#resourceBaseUrl = indexResolved.baseUrl;
5435
+ }
5436
+ if (indexResolved.text) {
5437
+ let html32 = indexResolved.text;
5438
+ const alreadyModified = html32.includes("postToParentWindows") || html32.includes("window.CES");
5439
+ if (!alreadyModified) {
5440
+ const cesScript = "<script>" + registerCES + "</script>";
5441
+ const headIndex = html32.indexOf("<head>");
5442
+ if (headIndex !== -1) {
5443
+ html32 = html32.slice(0, headIndex + 6) + cesScript + html32.slice(headIndex + 6);
5444
+ } else {
5445
+ html32 = cesScript + html32;
5446
+ }
5447
+ }
5448
+ const blob = new Blob([html32], { type: "text/html" });
5449
+ this.#contentBlobUrl = URL.createObjectURL(blob);
5450
+ }
5451
+ } else {
5452
+ const manifestPath = this.data || "manifest.json";
5453
+ const basePath = manifestPath.includes("/") ? manifestPath.substring(0, manifestPath.lastIndexOf("/")) : "";
5454
+ const indexPath = basePath ? `${basePath}/index.html` : "index.html";
5455
+ const indexResolved = await this.#resolveResourceWithFallback(indexPath, baseCandidates, {
5456
+ returnText: true
5457
+ });
5458
+ indexUrl = indexResolved.url;
5459
+ if (indexResolved.baseUrl && !this.#resourceBaseUrl) {
5460
+ this.#resourceBaseUrl = indexResolved.baseUrl;
5461
+ }
5462
+ if (indexResolved.text) {
5463
+ let html32 = indexResolved.text;
5464
+ const alreadyModified = html32.includes("postToParentWindows") || html32.includes("window.CES");
5465
+ if (!alreadyModified) {
5466
+ const cesScript = "<script>" + registerCES + "</script>";
5467
+ const headIndex = html32.indexOf("<head>");
5468
+ if (headIndex !== -1) {
5469
+ html32 = html32.slice(0, headIndex + 6) + cesScript + html32.slice(headIndex + 6);
5470
+ } else {
5471
+ html32 = cesScript + html32;
5472
+ }
5473
+ }
5474
+ const blob = new Blob([html32], { type: "text/html" });
5475
+ this.#contentBlobUrl = URL.createObjectURL(blob);
5476
+ }
5477
+ }
5478
+ if (indexUrl && !this.#contentBlobUrl) {
5479
+ try {
5480
+ const indexResponse = await fetch(indexUrl);
5481
+ if (indexResponse.ok) {
5482
+ let html32 = await indexResponse.text();
5483
+ const alreadyModified = html32.includes("postToParentWindows") || html32.includes("window.CES");
5484
+ if (!alreadyModified) {
5485
+ const cesScript = "<script>" + registerCES + "</script>";
5486
+ const headIndex = html32.indexOf("<head>");
5487
+ if (headIndex !== -1) {
5488
+ html32 = html32.slice(0, headIndex + 6) + cesScript + html32.slice(headIndex + 6);
5489
+ } else {
5490
+ html32 = cesScript + html32;
5491
+ }
5492
+ }
5493
+ const blob = new Blob([html32], { type: "text/html" });
5494
+ this.#contentBlobUrl = URL.createObjectURL(blob);
5495
+ } else {
5496
+ console.error(`Failed to fetch index.html: ${indexResponse.status}`);
5497
+ }
5498
+ } catch (e) {
5499
+ console.error(`Error fetching index.html: ${e}`);
5500
+ }
5501
+ }
5502
+ }
5503
+ const inlineScript = `<script>${ciBootstrap}</script>`;
5504
+ window.addEventListener("message", this.handlePostMessage);
5505
+ const htmlContent = `
5506
+ <!DOCTYPE html>
5507
+ <html>
5508
+ <head>
5509
+ ${cssUrl ? `<link href='${cssUrl}' rel="stylesheet" />` : ""}
5510
+ ${inlineScript}
5511
+ </head>
5512
+ <body></body>
5513
+ </html>
5514
+ `;
5515
+ iframe.srcdoc = htmlContent;
5516
+ }
5517
+ #getIFrames() {
5518
+ const iframesInShadowRoot = this.shadowRoot.querySelectorAll("iframe");
5519
+ const iframe = this.querySelectorAll("iframe");
5520
+ const outerIFrames = [...iframesInShadowRoot, ...iframe];
5521
+ for (const iframe2 of outerIFrames) {
5522
+ const iframeSrc = iframe2.src;
5523
+ const isSameOrigin = new URL(iframeSrc, window.location.href).origin === window.location.origin;
5524
+ if (isSameOrigin) {
5525
+ try {
5526
+ const outerDoc = iframe2.contentDocument || iframe2.contentWindow.document;
5527
+ if (outerDoc) {
5528
+ this.#getInnerIFrames(outerDoc, outerIFrames);
5529
+ }
5530
+ } catch (e) {
5531
+ console.error("Error accessing nested iframe:", e);
5532
+ }
5533
+ }
4695
5534
  }
4696
- #getLabel(index, labelType, labelSuffixType) {
4697
- let effectiveLabelType = labelType;
4698
- if (!effectiveLabelType && labelSuffixType && labelSuffixType !== "qti-labels-suffix-none") {
4699
- effectiveLabelType = "qti-labels-upper-alpha";
5535
+ outerIFrames.forEach((iframe2, index) => {
5536
+ if (outerIFrames.indexOf(iframe2) !== index) {
5537
+ outerIFrames.splice(index, 1);
4700
5538
  }
4701
- if (!effectiveLabelType || effectiveLabelType === "qti-labels-none") {
4702
- return "";
5539
+ });
5540
+ return outerIFrames;
5541
+ }
5542
+ #getInnerIFrames(iframeDocument, iframes = []) {
5543
+ const currentIframes = iframeDocument.querySelectorAll("iframe");
5544
+ currentIframes.forEach((iframe) => {
5545
+ iframes.push(iframe);
5546
+ const iframeSrc = iframe.src;
5547
+ const isSameOrigin = new URL(iframeSrc, window.location.href).origin === window.location.origin;
5548
+ if (isSameOrigin) {
5549
+ try {
5550
+ const nestedDoc = iframe.contentDocument || iframe.contentWindow.document;
5551
+ this.#getInnerIFrames(nestedDoc, iframes);
5552
+ } catch (e) {
5553
+ console.error("Error accessing nested iframe:", e);
5554
+ }
5555
+ } else {
5556
+ console.warn("Skipped cross-origin iframe:", iframeSrc);
4703
5557
  }
4704
- let label = "";
4705
- switch (effectiveLabelType) {
4706
- case "qti-labels-decimal":
4707
- label = `${index}`;
4708
- break;
4709
- case "qti-labels-lower-alpha":
4710
- label = this.#toAlphabetic(index, "lower");
4711
- break;
4712
- case "qti-labels-upper-alpha":
4713
- label = this.#toAlphabetic(index, "upper");
4714
- break;
5558
+ });
5559
+ return iframes;
5560
+ }
5561
+ #postToWindowAndIframes(type, data) {
5562
+ window.postMessage({ type, data }, "*");
5563
+ const iframes = this.#getIFrames();
5564
+ for (const iframe of iframes) {
5565
+ if (iframe.contentWindow) {
5566
+ iframe.contentWindow.postMessage({ type, data }, "*");
4715
5567
  }
4716
- if (labelSuffixType === "qti-labels-suffix-period") {
4717
- return `${label}.`;
5568
+ }
5569
+ }
5570
+ handlePostMessage(event) {
5571
+ const { type, data } = event.data;
5572
+ switch (type) {
5573
+ case "setResponse":
5574
+ if (data === null || !(Array.isArray(data) && data.length === 1 && data[0] === "")) {
5575
+ this.#rawResponse = data;
5576
+ this.saveResponse(data);
5577
+ }
5578
+ break;
5579
+ case "getResponse": {
5580
+ this.#postToWindowAndIframes("responseData", this.#rawResponse);
5581
+ break;
4718
5582
  }
4719
- if (labelSuffixType === "qti-labels-suffix-parenthesis") {
4720
- return `${label})`;
5583
+ case "getBlobUrl": {
5584
+ if (this.#contentBlobUrl) {
5585
+ this.#postToWindowAndIframes("blobUrl", this.#contentBlobUrl);
5586
+ if (event.source && event.source !== window) {
5587
+ event.source.postMessage({ type: "blobUrl", data: this.#contentBlobUrl }, "*");
5588
+ }
5589
+ }
5590
+ break;
4721
5591
  }
4722
- return label;
4723
- }
4724
- #toAlphabetic(index, casing) {
4725
- let value = index;
4726
- let label = "";
4727
- const charCodeBase = casing === "lower" ? 97 : 65;
4728
- while (value > 0) {
4729
- value -= 1;
4730
- label = String.fromCharCode(charCodeBase + value % 26) + label;
4731
- value = Math.floor(value / 26);
5592
+ case "getMedia": {
5593
+ const baseCandidates = this.#getBaseCandidates();
5594
+ const mediaData = this.manifest.media.map((media) => {
5595
+ if (media.startsWith("http") || media.startsWith("blob")) {
5596
+ return media;
5597
+ }
5598
+ const baseUrl = this.#resourceBaseUrl || baseCandidates[0];
5599
+ if (!baseUrl) {
5600
+ return media;
5601
+ }
5602
+ return new URL(media, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).toString();
5603
+ });
5604
+ this.#postToWindowAndIframes("mediaData", mediaData);
5605
+ break;
4732
5606
  }
4733
- return label;
5607
+ case "setStageHeight":
5608
+ console.log("setStageHeight not implemented");
5609
+ break;
4734
5610
  }
4735
5611
  }
4736
- __decorate10([
4737
- property9({
4738
- type: String,
4739
- attribute: "class"
4740
- })
4741
- ], VocabularyElement.prototype, "class", null);
4742
- return VocabularyElement;
4743
- };
4744
-
4745
- // ../interactions/choice-interaction/dist/qti-choice-interaction.styles.js
4746
- import { css as css7 } from "lit";
4747
- var qti_choice_interaction_styles_default = [
4748
- boxSizing,
4749
- validationMessage,
4750
- css7`
4751
- :host {
4752
- display: block;
4753
- }
4754
-
4755
- [part='slot'] {
4756
- display: grid;
4757
- gap: 10px;
4758
- }
4759
-
4760
- /* Define the number of columns dynamically */
4761
- :host([class*='qti-choices-stacking-']) [part='slot'] {
4762
- grid-template-columns: repeat(var(--stacking-count, 1), 1fr);
4763
- }
4764
-
4765
- /* Apply dynamic stacking count based on class */
4766
- :host(.qti-choices-stacking-1) {
4767
- --stacking-count: 1;
4768
- }
4769
- :host(.qti-choices-stacking-2) {
4770
- --stacking-count: 2;
5612
+ validate() {
5613
+ if (!this.#rawResponse) {
5614
+ return false;
4771
5615
  }
4772
- :host(.qti-choices-stacking-3) {
4773
- --stacking-count: 3;
5616
+ if (Array.isArray(this.#rawResponse)) {
5617
+ if (this.#rawResponse.length === 0) {
5618
+ return false;
5619
+ }
5620
+ for (const value of this.#rawResponse) {
5621
+ if (value !== "" && value !== null) {
5622
+ return true;
5623
+ }
5624
+ }
4774
5625
  }
4775
- :host(.qti-choices-stacking-4) {
4776
- --stacking-count: 4;
5626
+ return true;
5627
+ }
5628
+ get response() {
5629
+ return this.#rawResponse || null;
5630
+ }
5631
+ set response(val) {
5632
+ if (typeof val === "string") {
5633
+ this.#rawResponse = val;
5634
+ this.saveResponse(val);
5635
+ } else if (Array.isArray(val)) {
5636
+ this.#rawResponse = val;
5637
+ } else if (!val) {
5638
+ } else {
5639
+ throw new Error("Value must be a string or an array of strings");
4777
5640
  }
4778
- :host(.qti-choices-stacking-5) {
4779
- --stacking-count: 5;
5641
+ }
5642
+ disconnectedCallback() {
5643
+ window.removeEventListener("message", this.handlePostMessage);
5644
+ super.disconnectedCallback();
5645
+ }
5646
+ render() {
5647
+ return html12`<iframe
5648
+ width=${this.getAttribute("width")}
5649
+ height=${this.getAttribute("height")}
5650
+ frameborder="0"
5651
+ title="pciContainer"
5652
+ id="pciContainer"
5653
+ >
5654
+ </iframe>
5655
+ ${this._errorMessage && html12`<div style="color:red">
5656
+ <h1>Error</h1>
5657
+ ${this._errorMessage}
5658
+ </div>`}`;
5659
+ }
5660
+ #getBaseCandidates() {
5661
+ const candidates = [this.#resourceBaseUrl, this.baseRefUrl, this.baseItemUrl, this.#getManifestBaseUrl()];
5662
+ const resolved = candidates.filter(Boolean).map((base) => new URL(base, window.location.href).toString());
5663
+ const manifestParent = this.#getManifestParentBaseUrl();
5664
+ if (manifestParent) {
5665
+ resolved.push(manifestParent);
5666
+ }
5667
+ return [...new Set(resolved)];
5668
+ }
5669
+ #getManifestBaseUrl() {
5670
+ if (!this.#manifestUrl) {
5671
+ return null;
4780
5672
  }
4781
-
4782
- /* Default slot item layout */
4783
- ::slotted(qti-simple-choice) {
4784
- display: flex;
4785
- align-items: center;
4786
- white-space: normal;
5673
+ return new URL(".", this.#manifestUrl).toString();
5674
+ }
5675
+ #getManifestParentBaseUrl() {
5676
+ if (!this.#manifestUrl) {
5677
+ return null;
4787
5678
  }
4788
-
4789
- /* Orientation styles */
4790
- :host(.qti-orientation-horizontal) [part='slot'] {
4791
- grid-auto-flow: dense column;
4792
- grid-auto-columns: 1fr;
5679
+ return new URL("..", this.#manifestUrl).toString();
5680
+ }
5681
+ async #resolveResourceWithFallback(ref, baseCandidates, options = {}) {
5682
+ if (!ref) {
5683
+ return { url: "", baseUrl: null };
4793
5684
  }
4794
-
4795
- :host(.qti-orientation-vertical) [part='slot'] {
4796
- grid-auto-flow: row;
5685
+ if (ref.startsWith("http") || ref.startsWith("blob")) {
5686
+ return { url: ref, baseUrl: null };
4797
5687
  }
4798
-
4799
- /* Vertical and horizontal stacking logic */
4800
- :host(.qti-orientation-vertical[class*='qti-choices-stacking-']) [part='slot'] {
4801
- grid-auto-flow: dense column;
4802
- grid-auto-columns: 1fr;
4803
- grid-template-columns: repeat(var(--stacking-count), 1fr);
4804
- grid-template-rows: repeat(calc(var(--item-count) / var(--stacking-count)), 1fr);
5688
+ for (const base of baseCandidates) {
5689
+ const baseUrl = new URL(base, window.location.href).toString();
5690
+ const url = new URL(ref, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).toString();
5691
+ try {
5692
+ const response = await fetch(url);
5693
+ if (response.ok) {
5694
+ if (options.returnText) {
5695
+ const text = await response.text();
5696
+ return { url, baseUrl, text };
5697
+ }
5698
+ return { url, baseUrl };
5699
+ }
5700
+ } catch (e) {
5701
+ }
4805
5702
  }
5703
+ return { url: "", baseUrl: null };
5704
+ }
5705
+ };
5706
+ __decorate16([
5707
+ property15({ type: String, attribute: "data" })
5708
+ ], QtiCustomInteraction.prototype, "data", void 0);
5709
+ __decorate16([
5710
+ property15({ type: String, attribute: "data-base-item" })
5711
+ ], QtiCustomInteraction.prototype, "baseItemUrl", void 0);
5712
+ __decorate16([
5713
+ property15({ type: String, attribute: "data-base-ref" })
5714
+ ], QtiCustomInteraction.prototype, "baseRefUrl", void 0);
5715
+ __decorate16([
5716
+ property15({ type: String, attribute: "id" })
5717
+ ], QtiCustomInteraction.prototype, "id", void 0);
5718
+ __decorate16([
5719
+ state6()
5720
+ ], QtiCustomInteraction.prototype, "_errorMessage", void 0);
4806
5721
 
4807
- :host(.qti-orientation-horizontal[class*='qti-choices-stacking-']) [part='slot'] {
4808
- grid-auto-flow: row;
4809
- grid-template-columns: repeat(var(--stacking-count), 1fr);
4810
- grid-template-rows: unset;
4811
- }
5722
+ // ../interactions/end-attempt-interaction/dist/qti-end-attempt-interaction.js
5723
+ import { html as html13, LitElement as LitElement11 } from "lit";
5724
+ import { property as property16 } from "lit/decorators.js";
4812
5725
 
4813
- /* Ensure even distribution in vertical mode */
4814
- :host(.qti-orientation-vertical) ::slotted(qti-simple-choice:nth-child(even)) {
4815
- grid-row: auto;
4816
- }
4817
- `
4818
- ];
5726
+ // ../interactions/end-attempt-interaction/dist/qti-end-attempt-interaction.styles.js
5727
+ var qti_end_attempt_interaction_styles_default = [boxSizing];
4819
5728
 
4820
- // ../interactions/choice-interaction/dist/qti-choice-interaction.js
4821
- var __decorate11 = function(decorators, target, key, desc) {
5729
+ // ../interactions/end-attempt-interaction/dist/qti-end-attempt-interaction.js
5730
+ var __decorate17 = function(decorators, target, key, desc) {
4822
5731
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4823
5732
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4824
5733
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4825
5734
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4826
5735
  };
4827
- var QtiChoiceInteraction = class extends VocabularyMixin(ChoicesMixin(Interaction, "qti-simple-choice"), "qti-simple-choice") {
5736
+ var QtiEndAttemptInteraction = class extends LitElement11 {
4828
5737
  constructor() {
4829
5738
  super(...arguments);
4830
- this.orientation = "vertical";
5739
+ this.disabled = false;
5740
+ this.countAttempt = null;
5741
+ this.title = "end attempt";
4831
5742
  }
4832
5743
  static {
4833
- this.styles = qti_choice_interaction_styles_default;
4834
- }
4835
- #handleSlotChange() {
4836
- const choices = this.querySelectorAll("qti-simple-choice");
4837
- this.style.setProperty("--item-count", choices.length.toString());
5744
+ this.styles = qti_end_attempt_interaction_styles_default;
4838
5745
  }
4839
5746
  render() {
4840
- return html7`
4841
- <slot part="prompt" name="prompt"></slot>
4842
- <slot part="slot" @slotchange=${this.#handleSlotChange}></slot>
4843
- <div part="message" role="alert" id="validation-message"></div>
4844
- `;
5747
+ return html13`<button ?disabled=${this.disabled} part="button" @click=${this.endAttempt}>${this.title}</button>`;
5748
+ }
5749
+ endAttempt(_) {
5750
+ this.dispatchEvent(new CustomEvent("end-attempt", {
5751
+ bubbles: true,
5752
+ composed: true,
5753
+ detail: { responseIdentifier: this.responseIdentifier, countAttempt: this.countAttempt === "true" }
5754
+ }));
4845
5755
  }
4846
5756
  };
4847
- __decorate11([
4848
- property10({ type: String })
4849
- ], QtiChoiceInteraction.prototype, "orientation", void 0);
5757
+ __decorate17([
5758
+ property16({ type: String, attribute: "response-identifier" })
5759
+ ], QtiEndAttemptInteraction.prototype, "responseIdentifier", void 0);
5760
+ __decorate17([
5761
+ property16({ reflect: true, type: Boolean })
5762
+ ], QtiEndAttemptInteraction.prototype, "disabled", void 0);
5763
+ __decorate17([
5764
+ property16({ type: String, attribute: "count-attempt" })
5765
+ ], QtiEndAttemptInteraction.prototype, "countAttempt", void 0);
5766
+ __decorate17([
5767
+ property16({ type: String })
5768
+ ], QtiEndAttemptInteraction.prototype, "title", void 0);
4850
5769
 
4851
5770
  // ../interactions/extended-text-interaction/dist/qti-extended-text-interaction.js
4852
- import { html as html8 } from "lit";
5771
+ import { html as html14 } from "lit";
4853
5772
  import { ifDefined } from "lit/directives/if-defined.js";
4854
- import { property as property11, state as state4 } from "lit/decorators.js";
5773
+ import { property as property17, state as state7 } from "lit/decorators.js";
4855
5774
 
4856
5775
  // ../interactions/extended-text-interaction/dist/qti-extended-text-interaction.styles.js
4857
- import { css as css8 } from "lit";
5776
+ import { css as css14 } from "lit";
4858
5777
  var qti_extended_text_interaction_styles_default = [
4859
5778
  boxSizing,
4860
- css8`
5779
+ css14`
4861
5780
  /* PK: display host as block, else design will be collapsed */
4862
5781
  /* 'position: relative' anchors the correction glyph the theme draws over the textarea. */
4863
5782
  :host {
@@ -4874,7 +5793,7 @@ var qti_extended_text_interaction_styles_default = [
4874
5793
  ];
4875
5794
 
4876
5795
  // ../interactions/extended-text-interaction/dist/qti-extended-text-interaction.js
4877
- var __decorate12 = function(decorators, target, key, desc) {
5796
+ var __decorate18 = function(decorators, target, key, desc) {
4878
5797
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4879
5798
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4880
5799
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -4994,11 +5913,11 @@ var QtiExtendedTextInteraction = class extends Interaction {
4994
5913
  */
4995
5914
  /** The prompt, above the field. */
4996
5915
  renderPrompt() {
4997
- return html8`<slot name="prompt"></slot>`;
5916
+ return html14`<slot name="prompt"></slot>`;
4998
5917
  }
4999
5918
  /** The field itself. */
5000
5919
  renderTextarea() {
5001
- return html8`<textarea
5920
+ return html14`<textarea
5002
5921
  part="textarea"
5003
5922
  name="${this.responseIdentifier}"
5004
5923
  spellcheck="false"
@@ -5019,10 +5938,10 @@ var QtiExtendedTextInteraction = class extends Interaction {
5019
5938
  }
5020
5939
  /** Hidden until `Interaction.reportValidity` shows it. */
5021
5940
  renderValidationMessage() {
5022
- return html8`<div id="validation-message" part="message" role="alert" style="display:none;"></div>`;
5941
+ return html14`<div id="validation-message" part="message" role="alert" style="display:none;"></div>`;
5023
5942
  }
5024
5943
  render() {
5025
- return html8`${this.renderPrompt()}${this.renderTextarea()} ${this.renderValidationMessage()}`;
5944
+ return html14`${this.renderPrompt()}${this.renderTextarea()} ${this.renderValidationMessage()}`;
5026
5945
  }
5027
5946
  textChanged(event) {
5028
5947
  if (this.disabled || this.readonly)
@@ -5034,52 +5953,52 @@ var QtiExtendedTextInteraction = class extends Interaction {
5034
5953
  }
5035
5954
  }
5036
5955
  };
5037
- __decorate12([
5038
- state4()
5956
+ __decorate18([
5957
+ state7()
5039
5958
  ], QtiExtendedTextInteraction.prototype, "_rows", void 0);
5040
- __decorate12([
5041
- property11({ type: Number, attribute: "expected-length" })
5959
+ __decorate18([
5960
+ property17({ type: Number, attribute: "expected-length" })
5042
5961
  ], QtiExtendedTextInteraction.prototype, "expectedLength", void 0);
5043
- __decorate12([
5044
- property11({ type: Number, attribute: "expected-lines" })
5962
+ __decorate18([
5963
+ property17({ type: Number, attribute: "expected-lines" })
5045
5964
  ], QtiExtendedTextInteraction.prototype, "expectedLines", void 0);
5046
- __decorate12([
5047
- property11({ type: String, reflect: true })
5965
+ __decorate18([
5966
+ property17({ type: String, reflect: true })
5048
5967
  ], QtiExtendedTextInteraction.prototype, "format", void 0);
5049
- __decorate12([
5968
+ __decorate18([
5050
5969
  watch("format")
5051
5970
  ], QtiExtendedTextInteraction.prototype, "_handleFormatChange", void 0);
5052
- __decorate12([
5053
- property11({ type: String, attribute: "pattern-mask" })
5971
+ __decorate18([
5972
+ property17({ type: String, attribute: "pattern-mask" })
5054
5973
  ], QtiExtendedTextInteraction.prototype, "patternMask", void 0);
5055
- __decorate12([
5056
- property11({ type: String, attribute: "placeholder-text" })
5974
+ __decorate18([
5975
+ property17({ type: String, attribute: "placeholder-text" })
5057
5976
  ], QtiExtendedTextInteraction.prototype, "placeholderText", void 0);
5058
- __decorate12([
5059
- property11({ type: String, attribute: "data-patternmask-message" })
5977
+ __decorate18([
5978
+ property17({ type: String, attribute: "data-patternmask-message" })
5060
5979
  ], QtiExtendedTextInteraction.prototype, "dataPatternmaskMessage", void 0);
5061
- __decorate12([
5062
- property11({ type: String, attribute: "class" })
5980
+ __decorate18([
5981
+ property17({ type: String, attribute: "class" })
5063
5982
  ], QtiExtendedTextInteraction.prototype, "classNames", void 0);
5064
- __decorate12([
5983
+ __decorate18([
5065
5984
  watch(["classNames", "expectedLines", "expectedLength"])
5066
5985
  ], QtiExtendedTextInteraction.prototype, "_handleRowsInputChange", null);
5067
- __decorate12([
5068
- property11({ type: String, attribute: "response", reflect: false })
5986
+ __decorate18([
5987
+ property17({ type: String, attribute: "response", reflect: false })
5069
5988
  ], QtiExtendedTextInteraction.prototype, "response", void 0);
5070
- __decorate12([
5989
+ __decorate18([
5071
5990
  watch("response", { waitUntilFirstUpdate: true })
5072
5991
  ], QtiExtendedTextInteraction.prototype, "_handleResponseChange", void 0);
5073
5992
 
5074
5993
  // ../interactions/gap-match-interaction/dist/qti-gap-match-interaction.js
5075
- import { html as html9 } from "lit";
5994
+ import { html as html15 } from "lit";
5076
5995
 
5077
5996
  // ../interactions/gap-match-interaction/dist/qti-gap-match-interaction.styles.js
5078
- import { css as css9 } from "lit";
5997
+ import { css as css15 } from "lit";
5079
5998
  var qti_gap_match_interaction_styles_default = [
5080
5999
  boxSizing,
5081
6000
  validationMessage,
5082
- css9`
6001
+ css15`
5083
6002
  :host {
5084
6003
  display: flex;
5085
6004
  align-items: flex-start;
@@ -5132,7 +6051,7 @@ var QtiGapMatchInteraction = class extends DragDropSlottedSortableMixin(DragDrop
5132
6051
  this.styles = qti_gap_match_interaction_styles_default;
5133
6052
  }
5134
6053
  render() {
5135
- return html9`<slot name="prompt"> </slot>
6054
+ return html15`<slot name="prompt"> </slot>
5136
6055
  <slot part="drags" name="drags"></slot>
5137
6056
  <slot part="drops"></slot>
5138
6057
  <div role="alert" part="message" id="validation-message"></div>`;
@@ -5140,10 +6059,10 @@ var QtiGapMatchInteraction = class extends DragDropSlottedSortableMixin(DragDrop
5140
6059
  };
5141
6060
 
5142
6061
  // ../interactions/graphic-associate-interaction/dist/qti-graphic-associate-interaction.js
5143
- import { html as html10, nothing as nothing2, svg } from "lit";
5144
- import { property as property12, queryAssignedElements, state as state5 } from "lit/decorators.js";
6062
+ import { html as html16, nothing as nothing2, svg } from "lit";
6063
+ import { property as property18, queryAssignedElements, state as state8 } from "lit/decorators.js";
5145
6064
  import { ifDefined as ifDefined2 } from "lit/directives/if-defined.js";
5146
- import { repeat as repeat3 } from "lit/directives/repeat.js";
6065
+ import { repeat as repeat5 } from "lit/directives/repeat.js";
5147
6066
 
5148
6067
  // ../interactions/core/dist/internal/hotspots/hotspot.js
5149
6068
  function positionShapes(shape, coordsNumber, img, hotspot) {
@@ -5244,11 +6163,11 @@ function positionShapes(shape, coordsNumber, img, hotspot) {
5244
6163
  }
5245
6164
 
5246
6165
  // ../interactions/graphic-associate-interaction/dist/qti-graphic-associate-interaction.styles.js
5247
- import { css as css10 } from "lit";
6166
+ import { css as css16 } from "lit";
5248
6167
  var qti_graphic_associate_interaction_styles_default = [
5249
6168
  boxSizing,
5250
6169
  validationMessage,
5251
- css10`
6170
+ css16`
5252
6171
  /* Containing block for the absolutely positioned hotspots over the image. Was on this host in
5253
6172
  the theme, together with a 'display: block' this component now owns. */
5254
6173
  :host {
@@ -5282,7 +6201,7 @@ var qti_graphic_associate_interaction_styles_default = [
5282
6201
  ];
5283
6202
 
5284
6203
  // ../interactions/graphic-associate-interaction/dist/qti-graphic-associate-interaction.js
5285
- var __decorate13 = function(decorators, target, key, desc) {
6204
+ var __decorate19 = function(decorators, target, key, desc) {
5286
6205
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5287
6206
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5288
6207
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -5327,14 +6246,14 @@ var QtiGraphicAssociateInteraction = class extends Interaction {
5327
6246
  return nothing2;
5328
6247
  }
5329
6248
  render() {
5330
- return html10`<slot name="prompt"></slot>
6249
+ return html16`<slot name="prompt"></slot>
5331
6250
  <line-container>
5332
6251
  <svg
5333
6252
  width=${ifDefined2(this.grImage[0]?.width)}
5334
6253
  height=${ifDefined2(this.grImage[0]?.height)}
5335
6254
  viewbox="0 0 ${this.grImage[0]?.width} ${this.grImage[0]?.height}"
5336
6255
  >
5337
- ${repeat3(this.#getResponseArray(), (line) => line, (line, index) => svg`
6256
+ ${repeat5(this.#getResponseArray(), (line) => line, (line, index) => svg`
5338
6257
  <line
5339
6258
  part="line"
5340
6259
  x1=${parseInt(this.querySelector(`[identifier=${line.split(" ")[0]}]`).style.left)}
@@ -5417,20 +6336,20 @@ var QtiGraphicAssociateInteraction = class extends Interaction {
5417
6336
  this.removeEventListener("qti-register-hotspot", this.#positionHotspotOnRegister);
5418
6337
  }
5419
6338
  };
5420
- __decorate13([
5421
- state5()
6339
+ __decorate19([
6340
+ state8()
5422
6341
  ], QtiGraphicAssociateInteraction.prototype, "startCoord", void 0);
5423
- __decorate13([
5424
- state5()
6342
+ __decorate19([
6343
+ state8()
5425
6344
  ], QtiGraphicAssociateInteraction.prototype, "mouseCoord", void 0);
5426
- __decorate13([
6345
+ __decorate19([
5427
6346
  queryAssignedElements({ selector: "img" })
5428
6347
  ], QtiGraphicAssociateInteraction.prototype, "grImage", void 0);
5429
- __decorate13([
5430
- state5()
6348
+ __decorate19([
6349
+ state8()
5431
6350
  ], QtiGraphicAssociateInteraction.prototype, "_response", void 0);
5432
- __decorate13([
5433
- property12({
6351
+ __decorate19([
6352
+ property18({
5434
6353
  attribute: "response",
5435
6354
  reflect: false,
5436
6355
  noAccessor: true,
@@ -5439,14 +6358,14 @@ __decorate13([
5439
6358
  ], QtiGraphicAssociateInteraction.prototype, "response", null);
5440
6359
 
5441
6360
  // ../interactions/graphic-gap-match-interaction/dist/qti-graphic-gap-match-interaction.js
5442
- import { html as html11 } from "lit";
6361
+ import { html as html17 } from "lit";
5443
6362
 
5444
6363
  // ../interactions/graphic-gap-match-interaction/dist/qti-graphic-gap-match-interaction.styles.js
5445
- import { css as css11 } from "lit";
6364
+ import { css as css17 } from "lit";
5446
6365
  var qti_graphic_gap_match_interaction_styles_default = [
5447
6366
  boxSizing,
5448
6367
  validationMessage,
5449
- css11`
6368
+ css17`
5450
6369
  :host {
5451
6370
  display: flex;
5452
6371
  align-items: flex-start;
@@ -5513,7 +6432,7 @@ var QtiGraphicGapMatchInteraction = class extends DragDropSlottedSortableMixin(S
5513
6432
  this.styles = qti_graphic_gap_match_interaction_styles_default;
5514
6433
  }
5515
6434
  render() {
5516
- return html11` <slot name="prompt"></slot>
6435
+ return html17` <slot name="prompt"></slot>
5517
6436
  <slot part="image"></slot>
5518
6437
  <slot part="drags" name="drags" class="hover-border"></slot>
5519
6438
  <div role="alert" part="message" id="validation-message"></div>`;
@@ -5559,14 +6478,14 @@ var QtiGraphicGapMatchInteraction = class extends DragDropSlottedSortableMixin(S
5559
6478
  };
5560
6479
 
5561
6480
  // ../interactions/graphic-order-interaction/dist/qti-graphic-order-interaction.js
5562
- import { html as html12 } from "lit";
6481
+ import { html as html18 } from "lit";
5563
6482
 
5564
6483
  // ../interactions/graphic-order-interaction/dist/qti-graphic-order-interaction.styles.js
5565
- import { css as css12 } from "lit";
6484
+ import { css as css18 } from "lit";
5566
6485
  var qti_graphic_order_interaction_styles_default = [
5567
6486
  boxSizing,
5568
6487
  validationMessage,
5569
- css12`
6488
+ css18`
5570
6489
  /* The order pins are anchored outside their hotspot's box. */
5571
6490
  :host {
5572
6491
  /* The box this element already had. See the note in qti-match-interaction.styles.ts. */
@@ -5618,7 +6537,7 @@ var QtiGraphicOrderInteraction = class _QtiGraphicOrderInteraction extends Choic
5618
6537
  }
5619
6538
  static #LOCATOR_CLASS = "cito-graphic-order-marker";
5620
6539
  render() {
5621
- return html12`
6540
+ return html18`
5622
6541
  <slot name="prompt"></slot>
5623
6542
  <slot></slot>
5624
6543
  <div role="alert" part="message" id="validation-message"></div>
@@ -5705,14 +6624,14 @@ var QtiGraphicOrderInteraction = class _QtiGraphicOrderInteraction extends Choic
5705
6624
  };
5706
6625
 
5707
6626
  // ../interactions/hotspot-interaction/dist/qti-hotspot-interaction.js
5708
- import { html as html13 } from "lit";
6627
+ import { html as html19 } from "lit";
5709
6628
 
5710
6629
  // ../interactions/hotspot-interaction/dist/qti-hotspot-interaction.styles.js
5711
- import { css as css13 } from "lit";
6630
+ import { css as css19 } from "lit";
5712
6631
  var qti_hotspot_interaction_styles_default = [
5713
6632
  boxSizing,
5714
6633
  validationMessage,
5715
- css13`
6634
+ css19`
5716
6635
  :host {
5717
6636
  display: block;
5718
6637
  }
@@ -5770,7 +6689,7 @@ var QtiHotspotInteraction = class extends ChoicesMixin(Interaction, "qti-hotspot
5770
6689
  this.styles = qti_hotspot_interaction_styles_default;
5771
6690
  }
5772
6691
  render() {
5773
- return html13`
6692
+ return html19`
5774
6693
  <slot name="prompt"></slot>
5775
6694
  <slot></slot>
5776
6695
  <div part="message" role="alert" id="validation-message"></div>
@@ -5813,14 +6732,14 @@ var QtiHotspotInteraction = class extends ChoicesMixin(Interaction, "qti-hotspot
5813
6732
  };
5814
6733
 
5815
6734
  // ../interactions/hottext-interaction/dist/qti-hottext-interaction.js
5816
- import { html as html14 } from "lit";
6735
+ import { html as html20 } from "lit";
5817
6736
 
5818
6737
  // ../interactions/hottext-interaction/dist/qti-hottext-interaction.styles.js
5819
- import { css as css14 } from "lit";
6738
+ import { css as css20 } from "lit";
5820
6739
  var qti_hottext_interaction_styles_default = [
5821
6740
  boxSizing,
5822
6741
  validationMessage,
5823
- css14`
6742
+ css20`
5824
6743
  /* The box this element already had. See the note in qti-match-interaction.styles.ts. */
5825
6744
  :host {
5826
6745
  display: block;
@@ -5832,7 +6751,7 @@ var qti_hottext_interaction_styles_default = [
5832
6751
  var QtiHottextInteraction = class extends ChoicesMixin(Interaction, "qti-hottext") {
5833
6752
  constructor() {
5834
6753
  super(...arguments);
5835
- this.render = () => html14`<slot></slot>
6754
+ this.render = () => html20`<slot></slot>
5836
6755
  <div part="message" role="alert" id="validation-message"></div>`;
5837
6756
  }
5838
6757
  static {
@@ -5841,9 +6760,9 @@ var QtiHottextInteraction = class extends ChoicesMixin(Interaction, "qti-hottext
5841
6760
  };
5842
6761
 
5843
6762
  // ../interactions/inline-choice-interaction/dist/qti-inline-choice-interaction.js
5844
- import { html as html15 } from "lit";
5845
- import { property as property13, state as state6 } from "lit/decorators.js";
5846
- import { consume as consume3 } from "@lit/context";
6763
+ import { html as html21 } from "lit";
6764
+ import { property as property19, state as state9 } from "lit/decorators.js";
6765
+ import { consume as consume5 } from "@lit/context";
5847
6766
 
5848
6767
  // ../interactions/core/dist/mixins/menu-auto-size/menu-auto-size.mixin.js
5849
6768
  var MenuAutoSizeMixin = (superClass, menuSelector = "[part='menu']", triggerSelector = "[part='trigger']", customProperty = "--qti-inline-choice-width") => {
@@ -6030,8 +6949,8 @@ var MenuAutoSizeMixin = (superClass, menuSelector = "[part='menu']", triggerSele
6030
6949
  };
6031
6950
 
6032
6951
  // ../interactions/inline-choice-interaction/dist/qti-inline-choice-interaction.styles.js
6033
- import { css as css15 } from "lit";
6034
- var own = css15`
6952
+ import { css as css21 } from "lit";
6953
+ var own = css21`
6035
6954
  /* ── Host ──────────────────────────────────────────────────────────────────
6036
6955
  Inline-block so the element flows with surrounding text.
6037
6956
  --qti-inline-choice-width is the single width control surface:
@@ -6213,11 +7132,11 @@ var own = css15`
6213
7132
  white-space: nowrap;
6214
7133
  }
6215
7134
  `;
6216
- var styles = own;
6217
- var qti_inline_choice_interaction_styles_default = styles;
7135
+ var styles2 = own;
7136
+ var qti_inline_choice_interaction_styles_default = styles2;
6218
7137
 
6219
7138
  // ../interactions/inline-choice-interaction/dist/qti-inline-choice-interaction.js
6220
- var __decorate14 = function(decorators, target, key, desc) {
7139
+ var __decorate20 = function(decorators, target, key, desc) {
6221
7140
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6222
7141
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
6223
7142
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -6325,7 +7244,7 @@ var QtiInlineChoiceInteraction = class extends MenuAutoSizeMixin(Interaction) {
6325
7244
  /** The closed combobox — the box showing the chosen option. */
6326
7245
  renderTrigger() {
6327
7246
  const selected = this.#selectedOption();
6328
- return html15`
7247
+ return html21`
6329
7248
  <button
6330
7249
  part="trigger"
6331
7250
  type="button"
@@ -6349,7 +7268,7 @@ var QtiInlineChoiceInteraction = class extends MenuAutoSizeMixin(Interaction) {
6349
7268
  }
6350
7269
  /** The popover listbox. */
6351
7270
  renderMenu() {
6352
- return html15`
7271
+ return html21`
6353
7272
  <div
6354
7273
  id="${this._menuId}"
6355
7274
  part="menu"
@@ -6373,10 +7292,10 @@ var QtiInlineChoiceInteraction = class extends MenuAutoSizeMixin(Interaction) {
6373
7292
  }
6374
7293
  /** Hidden until `Interaction.reportValidity` shows it. */
6375
7294
  renderValidationMessage() {
6376
- return html15`<div id="validation-message" part="message" role="alert" style="display:none;"></div>`;
7295
+ return html21`<div id="validation-message" part="message" role="alert" style="display:none;"></div>`;
6377
7296
  }
6378
7297
  render() {
6379
- return html15` ${this.renderTrigger()} ${this.renderMenu()} ${this.renderValidationMessage()} `;
7298
+ return html21` ${this.renderTrigger()} ${this.renderMenu()} ${this.renderValidationMessage()} `;
6380
7299
  }
6381
7300
  async connectedCallback() {
6382
7301
  super.connectedCallback();
@@ -6587,24 +7506,24 @@ var QtiInlineChoiceInteraction = class extends MenuAutoSizeMixin(Interaction) {
6587
7506
  return [...promptOption ? [promptOption] : [], ...slottedChoices];
6588
7507
  }
6589
7508
  };
6590
- __decorate14([
6591
- state6()
7509
+ __decorate20([
7510
+ state9()
6592
7511
  ], QtiInlineChoiceInteraction.prototype, "options", void 0);
6593
- __decorate14([
6594
- state6()
7512
+ __decorate20([
7513
+ state9()
6595
7514
  ], QtiInlineChoiceInteraction.prototype, "_dropdownOpen", void 0);
6596
- __decorate14([
6597
- consume3({ context: configContext, subscribe: true }),
6598
- property13({ attribute: false })
7515
+ __decorate20([
7516
+ consume5({ context: configContext, subscribe: true }),
7517
+ property19({ attribute: false })
6599
7518
  ], QtiInlineChoiceInteraction.prototype, "configContext", void 0);
6600
- __decorate14([
6601
- property13({ type: String, attribute: "data-prompt" })
7519
+ __decorate20([
7520
+ property19({ type: String, attribute: "data-prompt" })
6602
7521
  ], QtiInlineChoiceInteraction.prototype, "dataPrompt", void 0);
6603
- __decorate14([
7522
+ __decorate20([
6604
7523
  watch("dataPrompt", { waitUntilFirstUpdate: true })
6605
7524
  ], QtiInlineChoiceInteraction.prototype, "_handleDataPromptChange", void 0);
6606
- __decorate14([
6607
- property13({
7525
+ __decorate20([
7526
+ property19({
6608
7527
  type: Boolean,
6609
7528
  reflect: true,
6610
7529
  converter: {
@@ -6614,26 +7533,26 @@ __decorate14([
6614
7533
  }
6615
7534
  })
6616
7535
  ], QtiInlineChoiceInteraction.prototype, "required", void 0);
6617
- __decorate14([
6618
- property13({ type: Number, attribute: "min-choices" })
7536
+ __decorate20([
7537
+ property19({ type: Number, attribute: "min-choices" })
6619
7538
  ], QtiInlineChoiceInteraction.prototype, "minChoices", void 0);
6620
- __decorate14([
7539
+ __decorate20([
6621
7540
  watch(["required", "minChoices"], { waitUntilFirstUpdate: true })
6622
7541
  ], QtiInlineChoiceInteraction.prototype, "_handleRequiredChange", void 0);
6623
- __decorate14([
6624
- property13({ attribute: "response", reflect: false, noAccessor: true })
7542
+ __decorate20([
7543
+ property19({ attribute: "response", reflect: false, noAccessor: true })
6625
7544
  ], QtiInlineChoiceInteraction.prototype, "response", null);
6626
7545
 
6627
7546
  // ../interactions/match-interaction/dist/qti-match-interaction.js
6628
- import { html as html16, nothing as nothing3 } from "lit";
6629
- import { property as property14, state as state7 } from "lit/decorators.js";
7547
+ import { html as html22, nothing as nothing3 } from "lit";
7548
+ import { property as property20, state as state10 } from "lit/decorators.js";
6630
7549
 
6631
7550
  // ../interactions/match-interaction/dist/qti-match-interaction.styles.js
6632
- import { css as css16 } from "lit";
7551
+ import { css as css22 } from "lit";
6633
7552
  var qti_match_interaction_styles_default = [
6634
7553
  boxSizing,
6635
7554
  validationMessage,
6636
- css16`
7555
+ css22`
6637
7556
  /*
6638
7557
  * A custom element is inline unless it says otherwise, and this one never did. Its shadow content
6639
7558
  * is block-level, so block-in-inline generated the anonymous block boxes and it looked correct —
@@ -6743,10 +7662,10 @@ var qti_match_interaction_styles_default = [
6743
7662
  ];
6744
7663
 
6745
7664
  // ../interactions/match-interaction/dist/qti-match-interaction-tabular.styles.js
6746
- import { css as css17 } from "lit";
7665
+ import { css as css23 } from "lit";
6747
7666
  var qti_match_interaction_tabular_styles_default = [
6748
7667
  boxSizing,
6749
- css17`
7668
+ css23`
6750
7669
  :host(.qti-match-tabular) slot:not([hidden]) {
6751
7670
  display: contents;
6752
7671
  }
@@ -6806,7 +7725,7 @@ var qti_match_interaction_tabular_styles_default = [
6806
7725
  ];
6807
7726
 
6808
7727
  // ../interactions/match-interaction/dist/qti-match-interaction.js
6809
- var __decorate15 = function(decorators, target, key, desc) {
7728
+ var __decorate21 = function(decorators, target, key, desc) {
6810
7729
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6811
7730
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
6812
7731
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -6949,11 +7868,11 @@ var QtiMatchInteraction = class extends DragDropSlottedSortableMixin(DragDropSlo
6949
7868
  }
6950
7869
  render() {
6951
7870
  const isTabular = this.class.split(" ").includes("qti-match-tabular");
6952
- return html16`
7871
+ return html22`
6953
7872
  <slot name="prompt"></slot>
6954
7873
  <slot ?hidden=${isTabular}></slot>
6955
7874
 
6956
- ${isTabular ? html16`
7875
+ ${isTabular ? html22`
6957
7876
  <div
6958
7877
  part="grid"
6959
7878
  role="grid"
@@ -6963,7 +7882,7 @@ var QtiMatchInteraction = class extends DragDropSlottedSortableMixin(DragDropSlo
6963
7882
  <div part="cols-wrap" role="row"><slot name="match-cols" part="c-header"></slot></div>
6964
7883
  <div part="rows-wrap"><slot name="match-rows" part="r-header"></slot></div>
6965
7884
  <div part="checkbox-grid">
6966
- ${this.sourceChoices.map((row, r) => html16`
7885
+ ${this.sourceChoices.map((row, r) => html22`
6967
7886
  <div role="row" style="display: contents;">
6968
7887
  ${this.targetChoices.map((col, c) => {
6969
7888
  const rowId = row.getAttribute("identifier");
@@ -6977,7 +7896,7 @@ var QtiMatchInteraction = class extends DragDropSlottedSortableMixin(DragDropSlo
6977
7896
  const controlPart = `control ${type} ${checkedMarker} ${stateVariant}`.trim();
6978
7897
  const controlMarkPart = `control-mark ${type} ${checkedMarker} ${stateVariant}`.trim();
6979
7898
  const disable = row.matchMax === 1 ? false : row.matchMax !== 0 && selectedInRowCount >= row.matchMax && !checked;
6980
- return html16`
7899
+ return html22`
6981
7900
  <label
6982
7901
  part="input-cell"
6983
7902
  role="gridcell"
@@ -7009,28 +7928,99 @@ var QtiMatchInteraction = class extends DragDropSlottedSortableMixin(DragDropSlo
7009
7928
  `;
7010
7929
  }
7011
7930
  };
7012
- __decorate15([
7013
- property14({ type: String })
7931
+ __decorate21([
7932
+ property20({ type: String })
7014
7933
  ], QtiMatchInteraction.prototype, "class", void 0);
7015
- __decorate15([
7016
- state7()
7934
+ __decorate21([
7935
+ state10()
7017
7936
  ], QtiMatchInteraction.prototype, "_response", void 0);
7018
- __decorate15([
7019
- property14({ type: String, attribute: "response-identifier" })
7937
+ __decorate21([
7938
+ property20({ type: String, attribute: "response-identifier" })
7020
7939
  ], QtiMatchInteraction.prototype, "responseIdentifier", void 0);
7021
7940
 
7941
+ // ../interactions/media-interaction/dist/qti-media-interaction.js
7942
+ import { html as html23 } from "lit";
7943
+
7944
+ // ../interactions/media-interaction/dist/qti-media-interaction.styles.js
7945
+ import { css as css24 } from "lit";
7946
+ var qti_media_interaction_styles_default = [
7947
+ boxSizing,
7948
+ css24`
7949
+ /* The box this element already had. See the note in qti-match-interaction.styles.ts. */
7950
+ :host {
7951
+ display: block;
7952
+ }
7953
+ `
7954
+ ];
7955
+
7956
+ // ../interactions/media-interaction/dist/qti-media-interaction.js
7957
+ var QtiMediaInteraction = class extends Interaction {
7958
+ static {
7959
+ this.styles = qti_media_interaction_styles_default;
7960
+ }
7961
+ #value = null;
7962
+ reset() {
7963
+ this.#value = null;
7964
+ }
7965
+ validate() {
7966
+ return true;
7967
+ }
7968
+ get response() {
7969
+ return this.#value ? this.#value.toString() : null;
7970
+ }
7971
+ set response(val) {
7972
+ if (val) {
7973
+ const isNumber = !isNaN(parseInt(val?.toString()));
7974
+ if (isNumber) {
7975
+ this.#value = parseInt(val.toString());
7976
+ } else {
7977
+ throw new Error(`Value must be a number ${val}`);
7978
+ }
7979
+ }
7980
+ }
7981
+ static get properties() {
7982
+ return {
7983
+ ...Interaction.properties,
7984
+ ...{
7985
+ step: {
7986
+ type: Number,
7987
+ attribute: "step",
7988
+ default: 10
7989
+ }
7990
+ }
7991
+ };
7992
+ }
7993
+ render() {
7994
+ return html23` <slot name="prompt"></slot>
7995
+ <slot></slot>`;
7996
+ }
7997
+ constructor() {
7998
+ super();
7999
+ }
8000
+ connectedCallback() {
8001
+ super.connectedCallback();
8002
+ const mediaObject = this.querySelector("audio") || this.querySelector("video") || this.querySelector("object");
8003
+ if (mediaObject) {
8004
+ mediaObject.addEventListener("ended", () => {
8005
+ this.#value++;
8006
+ this.saveResponse(this.value);
8007
+ });
8008
+ }
8009
+ }
8010
+ };
8011
+
7022
8012
  // ../interactions/order-interaction/dist/qti-order-interaction.js
7023
- import { html as html17 } from "lit";
7024
- import { repeat as repeat4 } from "lit/directives/repeat.js";
7025
- import { property as property15, state as state8 } from "lit/decorators.js";
8013
+ import { html as html24 } from "lit";
8014
+ import { repeat as repeat6 } from "lit/directives/repeat.js";
8015
+ import { property as property21, state as state11 } from "lit/decorators.js";
7026
8016
 
7027
8017
  // ../interactions/order-interaction/dist/qti-order-interaction.styles.js
7028
- import { css as css18 } from "lit";
8018
+ import { css as css25 } from "lit";
7029
8019
  var qti_order_interaction_styles_default = [
7030
8020
  boxSizing,
7031
8021
  validationMessage,
7032
8022
  dropRegion,
7033
- css18`
8023
+ css25`
7034
8024
  /* The box this element already had. See the note in qti-match-interaction.styles.ts. */
7035
8025
  :host {
7036
8026
  display: block;
@@ -7244,7 +8234,7 @@ var qti_order_interaction_styles_default = [
7244
8234
  ];
7245
8235
 
7246
8236
  // ../interactions/order-interaction/dist/qti-order-interaction.js
7247
- var __decorate16 = function(decorators, target, key, desc) {
8237
+ var __decorate22 = function(decorators, target, key, desc) {
7248
8238
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7249
8239
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
7250
8240
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -7264,15 +8254,15 @@ var QtiOrderInteraction = class extends DragDropSlottedSortableMixin(SlottedBase
7264
8254
  if (this.nrChoices < choices.length) {
7265
8255
  this.nrChoices = choices.length;
7266
8256
  }
7267
- return html17` <slot name="prompt"> </slot>
8257
+ return html24` <slot name="prompt"> </slot>
7268
8258
  <div part="container">
7269
8259
  <slot part="drags"> </slot>
7270
8260
  <div part="drops">
7271
8261
  ${[...Array(this.nrChoices)].map((_, i) => {
7272
8262
  const identifier = `droplist${i}`;
7273
8263
  const drags = this._dragDrop?.nodesByTarget?.[identifier] ?? [];
7274
- return html17`<div role="region" part="drop" data-declarative-drops identifier=${identifier}>
7275
- ${repeat4(drags, (node) => node.getAttribute("identifier"), (node) => node)}
8264
+ return html24`<div role="region" part="drop" data-declarative-drops identifier=${identifier}>
8265
+ ${repeat6(drags, (node) => node.getAttribute("identifier"), (node) => node)}
7276
8266
  </div>`;
7277
8267
  })}
7278
8268
  </div>
@@ -7303,23 +8293,23 @@ var QtiOrderInteraction = class extends DragDropSlottedSortableMixin(SlottedBase
7303
8293
  this.childrenMap = Array.from(this.querySelectorAll("qti-simple-choice"));
7304
8294
  }
7305
8295
  };
7306
- __decorate16([
7307
- state8()
8296
+ __decorate22([
8297
+ state11()
7308
8298
  ], QtiOrderInteraction.prototype, "nrChoices", void 0);
7309
- __decorate16([
7310
- property15({ type: String })
8299
+ __decorate22([
8300
+ property21({ type: String })
7311
8301
  ], QtiOrderInteraction.prototype, "orientation", void 0);
7312
8302
 
7313
8303
  // ../interactions/portable-custom-interaction/dist/qti-portable-custom-interaction.js
7314
- import { css as css20, html as html18 } from "lit";
7315
- import { property as property16, state as state9 } from "lit/decorators.js";
7316
- import { consume as consume4 } from "@lit/context";
8304
+ import { css as css27, html as html25 } from "lit";
8305
+ import { property as property22, state as state12 } from "lit/decorators.js";
8306
+ import { consume as consume6 } from "@lit/context";
7317
8307
 
7318
8308
  // ../interactions/portable-custom-interaction/dist/qti-portable-custom-interaction.styles.js
7319
- import { css as css19 } from "lit";
8309
+ import { css as css26 } from "lit";
7320
8310
  var qti_portable_custom_interaction_styles_default = [
7321
8311
  boxSizing,
7322
- css19`
8312
+ css26`
7323
8313
  :host {
7324
8314
  display: block;
7325
8315
  width: 100%;
@@ -7333,7 +8323,7 @@ var qti_portable_custom_interaction_styles_default = [
7333
8323
  ];
7334
8324
 
7335
8325
  // ../interactions/portable-custom-interaction/dist/qti-portable-custom-interaction.js
7336
- var __decorate17 = function(decorators, target, key, desc) {
8326
+ var __decorate23 = function(decorators, target, key, desc) {
7337
8327
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7338
8328
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
7339
8329
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -7420,30 +8410,30 @@ var QtiPortableCustomInteraction = class extends Interaction {
7420
8410
  this.#pciCustomValidityMessage = pciCustomValidity;
7421
8411
  }
7422
8412
  const stateRaw = data?.params?.state;
7423
- let state11;
8413
+ let state14;
7424
8414
  if (stateRaw === void 0) {
7425
- state11 = void 0;
8415
+ state14 = void 0;
7426
8416
  } else if (stateRaw === null) {
7427
- state11 = null;
8417
+ state14 = null;
7428
8418
  } else if (typeof stateRaw === "string") {
7429
- state11 = stateRaw;
8419
+ state14 = stateRaw;
7430
8420
  } else {
7431
8421
  try {
7432
- state11 = `__qti_json__::${JSON.stringify(stateRaw)}`;
8422
+ state14 = `__qti_json__::${JSON.stringify(stateRaw)}`;
7433
8423
  } catch {
7434
- state11 = null;
8424
+ state14 = null;
7435
8425
  }
7436
8426
  }
7437
8427
  if (converted === null) {
7438
8428
  const emptyResponse = this.responseVariable?.cardinality === "single" ? "" : [];
7439
8429
  this.response = emptyResponse;
7440
8430
  this.validate();
7441
- this.saveResponse(emptyResponse, state11);
8431
+ this.saveResponse(emptyResponse, state14);
7442
8432
  break;
7443
8433
  }
7444
8434
  this.response = converted;
7445
8435
  this.validate();
7446
- this.saveResponse(converted, state11);
8436
+ this.saveResponse(converted, state14);
7447
8437
  break;
7448
8438
  }
7449
8439
  case "error":
@@ -7458,7 +8448,7 @@ var QtiPortableCustomInteraction = class extends Interaction {
7458
8448
  static {
7459
8449
  this.styles = [
7460
8450
  qti_portable_custom_interaction_styles_default,
7461
- css20`
8451
+ css27`
7462
8452
  :host {
7463
8453
  display: block;
7464
8454
  width: 100%;
@@ -9022,65 +10012,156 @@ var QtiPortableCustomInteraction = class extends Interaction {
9022
10012
  // Add this property to store the previous state
9023
10013
  #previousState;
9024
10014
  render() {
9025
- return html18`
10015
+ return html25`
9026
10016
  <slot></slot>
9027
- ${this._errorMessage ? html18`<div style="color:red">
10017
+ ${this._errorMessage ? html25`<div style="color:red">
9028
10018
  <h1>Error</h1>
9029
10019
  ${this._errorMessage}
9030
10020
  </div>` : ""}
9031
10021
  `;
9032
10022
  }
9033
10023
  };
9034
- __decorate17([
9035
- property16({ type: String, attribute: "module" })
10024
+ __decorate23([
10025
+ property22({ type: String, attribute: "module" })
9036
10026
  ], QtiPortableCustomInteraction.prototype, "module", void 0);
9037
- __decorate17([
9038
- property16({ type: String, attribute: "custom-interaction-type-identifier" })
10027
+ __decorate23([
10028
+ property22({ type: String, attribute: "custom-interaction-type-identifier" })
9039
10029
  ], QtiPortableCustomInteraction.prototype, "customInteractionTypeIdentifier", void 0);
9040
- __decorate17([
9041
- property16({ type: String, attribute: "data-require-paths" })
10030
+ __decorate23([
10031
+ property22({ type: String, attribute: "data-require-paths" })
9042
10032
  ], QtiPortableCustomInteraction.prototype, "requirePathsJson", void 0);
9043
- __decorate17([
9044
- property16({ type: String, attribute: "data-require-shim" })
10033
+ __decorate23([
10034
+ property22({ type: String, attribute: "data-require-shim" })
9045
10035
  ], QtiPortableCustomInteraction.prototype, "requireShimJson", void 0);
9046
- __decorate17([
9047
- property16({ type: String, attribute: "data-require-js-url" })
10036
+ __decorate23([
10037
+ property22({ type: String, attribute: "data-require-js-url" })
9048
10038
  ], QtiPortableCustomInteraction.prototype, "requireJsUrl", void 0);
9049
- __decorate17([
9050
- property16({ type: String, attribute: "data-base-url" })
10039
+ __decorate23([
10040
+ property22({ type: String, attribute: "data-base-url" })
9051
10041
  ], QtiPortableCustomInteraction.prototype, "baseUrl", void 0);
9052
- __decorate17([
9053
- property16({ type: Boolean, attribute: "data-use-default-paths" })
10042
+ __decorate23([
10043
+ property22({ type: Boolean, attribute: "data-use-default-paths" })
9054
10044
  ], QtiPortableCustomInteraction.prototype, "useDefaultPaths", void 0);
9055
- __decorate17([
9056
- property16({ type: String, attribute: "data-status" })
10045
+ __decorate23([
10046
+ property22({ type: String, attribute: "data-status" })
9057
10047
  ], QtiPortableCustomInteraction.prototype, "status", void 0);
9058
- __decorate17([
9059
- state9()
10048
+ __decorate23([
10049
+ state12()
9060
10050
  ], QtiPortableCustomInteraction.prototype, "_errorMessage", void 0);
9061
- __decorate17([
9062
- consume4({ context: itemContext, subscribe: true }),
9063
- state9()
10051
+ __decorate23([
10052
+ consume6({ context: itemContext, subscribe: true }),
10053
+ state12()
9064
10054
  ], QtiPortableCustomInteraction.prototype, "context", void 0);
9065
- __decorate17([
9066
- consume4({ context: qtiContext, subscribe: true }),
9067
- state9()
10055
+ __decorate23([
10056
+ consume6({ context: qtiContext, subscribe: true }),
10057
+ state12()
9068
10058
  ], QtiPortableCustomInteraction.prototype, "qtiContext", void 0);
9069
- __decorate17([
9070
- property16({ attribute: "response", reflect: false, converter: responseAttributeConverter({ emptyAs: null }) })
10059
+ __decorate23([
10060
+ property22({ attribute: "response", reflect: false, converter: responseAttributeConverter({ emptyAs: null }) })
9071
10061
  ], QtiPortableCustomInteraction.prototype, "response", void 0);
9072
10062
 
10063
+ // ../interactions/position-object-interaction/dist/qti-position-object-interaction.js
10064
+ import { LitElement as LitElement12, html as html26 } from "lit";
10065
+
10066
+ // ../interactions/position-object-interaction/dist/qti-position-object-interaction.styles.js
10067
+ import { css as css28 } from "lit";
10068
+ var qti_position_object_interaction_styles_default = [
10069
+ boxSizing,
10070
+ css28`
10071
+ :host {
10072
+ display: block;
10073
+ }
10074
+ ::slotted(img) {
10075
+ position: absolute;
10076
+ cursor: move;
10077
+ user-select: none;
10078
+ left: 50%;
10079
+ transform: translateX(-50%);
10080
+ }
10081
+ `
10082
+ ];
10083
+
10084
+ // ../interactions/position-object-interaction/dist/qti-position-object-interaction.js
10085
+ var QtiPositionObjectInteraction = class extends LitElement12 {
10086
+ static {
10087
+ this.styles = qti_position_object_interaction_styles_default;
10088
+ }
10089
+ render() {
10090
+ return html26`<slot></slot>`;
10091
+ }
10092
+ };
10093
+
10094
+ // ../interactions/position-object-interaction/dist/qti-position-object-stage.js
10095
+ import { LitElement as LitElement13, html as html27 } from "lit";
10096
+
10097
+ // ../interactions/position-object-interaction/dist/qti-position-object-stage.styles.js
10098
+ import { css as css29 } from "lit";
10099
+ var qti_position_object_stage_styles_default = [
10100
+ boxSizing,
10101
+ css29`
10102
+ :host {
10103
+ display: inline-block;
10104
+ position: relative;
10105
+ }
10106
+ `
10107
+ ];
10108
+
10109
+ // ../interactions/position-object-interaction/dist/qti-position-object-stage.js
10110
+ var QtiPositionObjectStage = class extends LitElement13 {
10111
+ static {
10112
+ this.styles = qti_position_object_stage_styles_default;
10113
+ }
10114
+ render() {
10115
+ return html27`<slot></slot>`;
10116
+ }
10117
+ constructor() {
10118
+ super();
10119
+ this.removeMoveListener = this.removeMoveListener.bind(this);
10120
+ this.dragElementHandler = this.dragElementHandler.bind(this);
10121
+ }
10122
+ // Define a function to handle the mousemove event on the draggable element
10123
+ dragElementHandler(event) {
10124
+ event.preventDefault();
10125
+ const deltaX = event.clientX - this.startX;
10126
+ const deltaY = event.clientY - this.startY;
10127
+ this.dragElement.style.left = this.dragElement.offsetLeft + deltaX + "px";
10128
+ this.dragElement.style.top = this.dragElement.offsetTop + deltaY + "px";
10129
+ this.startX = event.clientX;
10130
+ this.startY = event.clientY;
10131
+ }
10132
+ firstUpdated(a) {
10133
+ super.firstUpdated(a);
10134
+ this.dragElement = this.querySelector("qti-position-object-interaction>img");
10135
+ this.startX = 0;
10136
+ this.startY = 0;
10137
+ this.dragElement.addEventListener("mousedown", (event) => {
10138
+ this.startX = event.clientX;
10139
+ this.startY = event.clientY;
10140
+ document.addEventListener("mousemove", this.dragElementHandler, true);
10141
+ });
10142
+ document.addEventListener("mouseup", this.removeMoveListener);
10143
+ }
10144
+ removeMoveListener() {
10145
+ document.removeEventListener("mousemove", this.dragElementHandler, true);
10146
+ }
10147
+ disconnectedCallback() {
10148
+ super.disconnectedCallback();
10149
+ document.removeEventListener("mousemove", this.dragElementHandler);
10150
+ document.removeEventListener("mouseup", this.removeMoveListener);
10151
+ }
10152
+ };
10153
+
9073
10154
  // ../interactions/select-point-interaction/dist/qti-select-point-interaction.js
9074
- import { html as html19, nothing as nothing4 } from "lit";
9075
- import { property as property17, state as state10 } from "lit/decorators.js";
9076
- import { repeat as repeat5 } from "lit/directives/repeat.js";
10155
+ import { html as html28, nothing as nothing4 } from "lit";
10156
+ import { property as property23, state as state13 } from "lit/decorators.js";
10157
+ import { repeat as repeat7 } from "lit/directives/repeat.js";
9077
10158
  import { styleMap } from "lit/directives/style-map.js";
9078
10159
 
9079
10160
  // ../interactions/select-point-interaction/dist/qti-select-point-interaction.styles.js
9080
- import { css as css21 } from "lit";
10161
+ import { css as css30 } from "lit";
9081
10162
  var qti_select_point_interaction_styles_default = [
9082
10163
  boxSizing,
9083
- css21`
10164
+ css30`
9084
10165
  :host {
9085
10166
  display: block;
9086
10167
  --qti-select-point-marker-size: 1.5rem;
@@ -9119,7 +10200,7 @@ var qti_select_point_interaction_styles_default = [
9119
10200
  ];
9120
10201
 
9121
10202
  // ../interactions/select-point-interaction/dist/qti-select-point-interaction.js
9122
- var __decorate18 = function(decorators, target, key, desc) {
10203
+ var __decorate24 = function(decorators, target, key, desc) {
9123
10204
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9124
10205
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9125
10206
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -9224,12 +10305,12 @@ var QtiSelectPointInteraction = class extends Interaction {
9224
10305
  return nothing4;
9225
10306
  }
9226
10307
  /** Positions overlay elements that carry `data-coord` and `data-shape`. */
9227
- positionOverlayElements(elements17) {
10308
+ positionOverlayElements(elements32) {
9228
10309
  const img = this.#imgElement;
9229
10310
  if (!img)
9230
10311
  return;
9231
10312
  this.#calculateScale();
9232
- for (const element of elements17) {
10313
+ for (const element of elements32) {
9233
10314
  const coords = element.dataset.coord;
9234
10315
  const shape = element.dataset.shape;
9235
10316
  if (!coords || !shape)
@@ -9240,13 +10321,13 @@ var QtiSelectPointInteraction = class extends Interaction {
9240
10321
  render() {
9241
10322
  const rawResponse = this.response;
9242
10323
  const responseList = Array.isArray(rawResponse) ? rawResponse : rawResponse ? [rawResponse] : [];
9243
- return html19` <slot name="prompt"></slot>
10324
+ return html28` <slot name="prompt"></slot>
9244
10325
  <point-container>
9245
- ${repeat5(responseList.filter((point) => point), (point) => point, (point, index) => {
10326
+ ${repeat7(responseList.filter((point) => point), (point) => point, (point, index) => {
9246
10327
  const [x, y] = point.split(" ").map(Number);
9247
10328
  const leftPercentage = x / (this.#imageWidthOriginal || 1) * 100;
9248
10329
  const topPercentage = y / (this.#imageHeightOriginal || 1) * 100;
9249
- return html19`
10330
+ return html28`
9250
10331
  <button
9251
10332
  part=${this.pointPart(point, index)}
9252
10333
  style=${styleMap({
@@ -9313,20 +10394,20 @@ var QtiSelectPointInteraction = class extends Interaction {
9313
10394
  }
9314
10395
  }
9315
10396
  };
9316
- __decorate18([
9317
- property17({
10397
+ __decorate24([
10398
+ property23({
9318
10399
  type: Number,
9319
10400
  attribute: "max-choices"
9320
10401
  })
9321
10402
  ], QtiSelectPointInteraction.prototype, "maxChoices", void 0);
9322
- __decorate18([
9323
- property17({
10403
+ __decorate24([
10404
+ property23({
9324
10405
  type: Number,
9325
10406
  attribute: "min-choices"
9326
10407
  })
9327
10408
  ], QtiSelectPointInteraction.prototype, "minChoices", void 0);
9328
- __decorate18([
9329
- property17({
10409
+ __decorate24([
10410
+ property23({
9330
10411
  attribute: "response",
9331
10412
  reflect: false,
9332
10413
  converter: {
@@ -9342,25 +10423,25 @@ __decorate18([
9342
10423
  }
9343
10424
  })
9344
10425
  ], QtiSelectPointInteraction.prototype, "response", void 0);
9345
- __decorate18([
9346
- property17({ attribute: "area-mappings" })
10426
+ __decorate24([
10427
+ property23({ attribute: "area-mappings" })
9347
10428
  ], QtiSelectPointInteraction.prototype, "areaMappings", void 0);
9348
- __decorate18([
9349
- state10()
10429
+ __decorate24([
10430
+ state13()
9350
10431
  ], QtiSelectPointInteraction.prototype, "_areaEntries", void 0);
9351
- __decorate18([
10432
+ __decorate24([
9352
10433
  watch("areaMappings")
9353
10434
  ], QtiSelectPointInteraction.prototype, "_handleAreaMappingsChange", void 0);
9354
10435
 
9355
10436
  // ../interactions/slider-interaction/dist/qti-slider-interaction.js
9356
- import { html as html20, nothing as nothing5 } from "lit";
9357
- import { property as property18, query as query2 } from "lit/decorators.js";
10437
+ import { html as html29, nothing as nothing5 } from "lit";
10438
+ import { property as property24, query as query2 } from "lit/decorators.js";
9358
10439
 
9359
10440
  // ../interactions/slider-interaction/dist/qti-slider-interaction.styles.js
9360
- import { css as css22 } from "lit";
10441
+ import { css as css31 } from "lit";
9361
10442
  var qti_slider_interaction_styles_default = [
9362
10443
  boxSizing,
9363
- css22`
10444
+ css31`
9364
10445
  :host {
9365
10446
  display: block;
9366
10447
  --show-bounds: true;
@@ -9432,7 +10513,7 @@ var qti_slider_interaction_styles_default = [
9432
10513
  ];
9433
10514
 
9434
10515
  // ../interactions/slider-interaction/dist/qti-slider-interaction.js
9435
- var __decorate19 = function(decorators, target, key, desc) {
10516
+ var __decorate25 = function(decorators, target, key, desc) {
9436
10517
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9437
10518
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9438
10519
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -9489,7 +10570,7 @@ var QtiSliderInteraction = class extends Interaction {
9489
10570
  this.requestUpdate();
9490
10571
  }
9491
10572
  render() {
9492
- return html20`
10573
+ return html29`
9493
10574
  <slot name="prompt"></slot>
9494
10575
  <div id="slider" part="slider">
9495
10576
  <div id="bounds" part="bounds">
@@ -9545,33 +10626,33 @@ var QtiSliderInteraction = class extends Interaction {
9545
10626
  this.dispatchEvent(new Event("change", { bubbles: true }));
9546
10627
  }
9547
10628
  };
9548
- __decorate19([
10629
+ __decorate25([
9549
10630
  query2("#rail")
9550
10631
  ], QtiSliderInteraction.prototype, "_rail", void 0);
9551
- __decorate19([
9552
- property18({ type: Number, attribute: "lower-bound" })
10632
+ __decorate25([
10633
+ property24({ type: Number, attribute: "lower-bound" })
9553
10634
  ], QtiSliderInteraction.prototype, "min", void 0);
9554
- __decorate19([
9555
- property18({ type: Number, attribute: "upper-bound" })
10635
+ __decorate25([
10636
+ property24({ type: Number, attribute: "upper-bound" })
9556
10637
  ], QtiSliderInteraction.prototype, "max", void 0);
9557
- __decorate19([
9558
- property18({ type: Number, attribute: "step" })
10638
+ __decorate25([
10639
+ property24({ type: Number, attribute: "step" })
9559
10640
  ], QtiSliderInteraction.prototype, "step", void 0);
9560
- __decorate19([
9561
- property18({ attribute: "response", reflect: false, noAccessor: true })
10641
+ __decorate25([
10642
+ property24({ attribute: "response", reflect: false, noAccessor: true })
9562
10643
  ], QtiSliderInteraction.prototype, "response", null);
9563
10644
 
9564
10645
  // ../interactions/text-entry-interaction/dist/qti-text-entry-interaction.js
9565
- import { html as html21 } from "lit";
9566
- import { property as property19, query as query3 } from "lit/decorators.js";
10646
+ import { html as html30 } from "lit";
10647
+ import { property as property25, query as query3 } from "lit/decorators.js";
9567
10648
  import { ifDefined as ifDefined3 } from "lit/directives/if-defined.js";
9568
10649
  import { createRef } from "lit/directives/ref.js";
9569
10650
 
9570
10651
  // ../interactions/text-entry-interaction/dist/qti-text-entry-interaction.styles.js
9571
- import { css as css23 } from "lit";
10652
+ import { css as css32 } from "lit";
9572
10653
  var qti_text_entry_interaction_styles_default = [
9573
10654
  boxSizing,
9574
- css23`
10655
+ css32`
9575
10656
  :host {
9576
10657
  display: inline-flex;
9577
10658
  align-items: center;
@@ -9664,7 +10745,7 @@ var qti_text_entry_interaction_styles_default = [
9664
10745
  ];
9665
10746
 
9666
10747
  // ../interactions/text-entry-interaction/dist/qti-text-entry-interaction.js
9667
- var __decorate20 = function(decorators, target, key, desc) {
10748
+ var __decorate26 = function(decorators, target, key, desc) {
9668
10749
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9669
10750
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9670
10751
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -9723,11 +10804,11 @@ var QtiTextEntryInteraction = class extends Interaction {
9723
10804
  */
9724
10805
  /** The answer-key line, revealed above the field when the correct response is shown. */
9725
10806
  renderAnswer() {
9726
- return html21`<div part="answer" aria-hidden="true"></div>`;
10807
+ return html30`<div part="answer" aria-hidden="true"></div>`;
9727
10808
  }
9728
10809
  /** The field itself. */
9729
10810
  renderInput() {
9730
- return html21`<input
10811
+ return html30`<input
9731
10812
  part="input"
9732
10813
  name="${this.responseIdentifier}"
9733
10814
  spellcheck="false"
@@ -9749,10 +10830,10 @@ var QtiTextEntryInteraction = class extends Interaction {
9749
10830
  }
9750
10831
  /** Hidden until `Interaction.reportValidity` shows it. */
9751
10832
  renderValidationMessage() {
9752
- return html21`<div id="validation-message" part="message" role="alert" style="display:none;"></div>`;
10833
+ return html30`<div id="validation-message" part="message" role="alert" style="display:none;"></div>`;
9753
10834
  }
9754
10835
  render() {
9755
- return html21` ${this.renderAnswer()} ${this.renderInput()} ${this.renderValidationMessage()} `;
10836
+ return html30` ${this.renderAnswer()} ${this.renderInput()} ${this.renderValidationMessage()} `;
9756
10837
  }
9757
10838
  textChanged(event) {
9758
10839
  if (this.disabled || this.readonly)
@@ -9771,63 +10852,197 @@ var QtiTextEntryInteraction = class extends Interaction {
9771
10852
  this.response = "";
9772
10853
  }
9773
10854
  };
9774
- __decorate20([
9775
- property19({ type: Number, attribute: "expected-length" })
10855
+ __decorate26([
10856
+ property25({ type: Number, attribute: "expected-length" })
9776
10857
  ], QtiTextEntryInteraction.prototype, "expectedLength", void 0);
9777
- __decorate20([
9778
- property19({ type: String, attribute: "pattern-mask" })
10858
+ __decorate26([
10859
+ property25({ type: String, attribute: "pattern-mask" })
9779
10860
  ], QtiTextEntryInteraction.prototype, "patternMask", void 0);
9780
- __decorate20([
9781
- property19({ type: String, attribute: "placeholder-text" })
10861
+ __decorate26([
10862
+ property25({ type: String, attribute: "placeholder-text" })
9782
10863
  ], QtiTextEntryInteraction.prototype, "placeholderText", void 0);
9783
- __decorate20([
9784
- property19({ type: String, attribute: "data-patternmask-message" })
10864
+ __decorate26([
10865
+ property25({ type: String, attribute: "data-patternmask-message" })
9785
10866
  ], QtiTextEntryInteraction.prototype, "dataPatternmaskMessage", void 0);
9786
- __decorate20([
9787
- property19({ type: String, attribute: "response", reflect: false })
10867
+ __decorate26([
10868
+ property25({ type: String, attribute: "response", reflect: false })
9788
10869
  ], QtiTextEntryInteraction.prototype, "response", void 0);
9789
- __decorate20([
10870
+ __decorate26([
9790
10871
  query3("input")
9791
10872
  ], QtiTextEntryInteraction.prototype, "_input", void 0);
9792
- __decorate20([
10873
+ __decorate26([
9793
10874
  watch("response", { waitUntilFirstUpdate: true })
9794
10875
  ], QtiTextEntryInteraction.prototype, "_handleValueChange", void 0);
9795
10876
 
10877
+ // ../interactions/upload-interaction/dist/qti-upload-interaction.js
10878
+ import { html as html31 } from "lit";
10879
+
10880
+ // ../interactions/upload-interaction/dist/qti-upload-interaction.styles.js
10881
+ import { css as css33 } from "lit";
10882
+ var qti_upload_interaction_styles_default = [
10883
+ boxSizing,
10884
+ css33`
10885
+ :host {
10886
+ display: block;
10887
+ margin: 1em 0;
10888
+ }
10889
+ input[type='file'] {
10890
+ display: block;
10891
+ margin-top: 0.5em;
10892
+ }
10893
+ `
10894
+ ];
10895
+
10896
+ // ../interactions/upload-interaction/dist/qti-upload-interaction.js
10897
+ var QtiUploadInteraction = class extends Interaction {
10898
+ static {
10899
+ this.styles = qti_upload_interaction_styles_default;
10900
+ }
10901
+ #file = null;
10902
+ #base64 = null;
10903
+ reset() {
10904
+ this.#file = null;
10905
+ this.#base64 = null;
10906
+ this.saveResponse(null);
10907
+ }
10908
+ validate() {
10909
+ return this.#base64 !== null;
10910
+ }
10911
+ get response() {
10912
+ return this.#base64;
10913
+ }
10914
+ set response(base64) {
10915
+ if (typeof base64 === "string") {
10916
+ this.#base64 = base64;
10917
+ this.saveResponse(base64);
10918
+ } else if (base64 === null) {
10919
+ this.reset();
10920
+ } else {
10921
+ throw new Error("Value must be a Base64-encoded string or null");
10922
+ }
10923
+ }
10924
+ static get properties() {
10925
+ return {
10926
+ ...Interaction.properties
10927
+ };
10928
+ }
10929
+ render() {
10930
+ return html31`
10931
+ <div>
10932
+ <slot name="prompt"></slot>
10933
+ <input type="file" @change="${this.#onFileChange}" ?disabled="${this.disabled}" ?readonly="${this.readonly}" />
10934
+ </div>
10935
+ `;
10936
+ }
10937
+ async #onFileChange(event) {
10938
+ const input = event.target;
10939
+ if (input.files && input.files.length > 0) {
10940
+ this.#file = input.files[0];
10941
+ this.#base64 = await this.#convertToBase64(this.#file);
10942
+ this.saveResponse(this.#base64);
10943
+ this.dispatchEvent(new CustomEvent("qti-interaction-response", {
10944
+ detail: { response: this.#base64 }
10945
+ }));
10946
+ }
10947
+ }
10948
+ #convertToBase64(file) {
10949
+ return new Promise((resolve, reject) => {
10950
+ const reader = new FileReader();
10951
+ reader.onload = () => resolve(reader.result);
10952
+ reader.onerror = () => reject(reader.error);
10953
+ reader.readAsDataURL(file);
10954
+ });
10955
+ }
10956
+ };
10957
+
10958
+ // ../interactions/core/dist/elements/qti-associable-hotspot/elements.js
10959
+ var elements = [{ tag: "qti-associable-hotspot", ctor: QtiAssociableHotspot }];
10960
+
10961
+ // ../interactions/core/dist/elements/qti-gap/elements.js
10962
+ var elements2 = [{ tag: "qti-gap", ctor: QtiGap }];
10963
+
10964
+ // ../interactions/core/dist/elements/qti-gap-img/elements.js
10965
+ var elements3 = [{ tag: "qti-gap-img", ctor: QtiGapImg }];
10966
+
10967
+ // ../interactions/core/dist/elements/qti-gap-text/elements.js
10968
+ var elements4 = [{ tag: "qti-gap-text", ctor: QtiGapText }];
10969
+
10970
+ // ../interactions/core/dist/elements/qti-hotspot-choice/elements.js
10971
+ var elements5 = [{ tag: "qti-hotspot-choice", ctor: QtiHotspotChoice }];
10972
+
10973
+ // ../interactions/core/dist/elements/qti-hottext/elements.js
10974
+ var elements6 = [{ tag: "qti-hottext", ctor: QtiHottext }];
10975
+
10976
+ // ../interactions/core/dist/elements/qti-inline-choice/elements.js
10977
+ var elements7 = [{ tag: "qti-inline-choice", ctor: QtiInlineChoice }];
10978
+
10979
+ // ../interactions/core/dist/elements/qti-prompt/elements.js
10980
+ var elements8 = [{ tag: "qti-prompt", ctor: QtiPrompt }];
10981
+
10982
+ // ../interactions/core/dist/elements/qti-simple-associable-choice/elements.js
10983
+ var elements9 = [{ tag: "qti-simple-associable-choice", ctor: QtiSimpleAssociableChoice }];
10984
+
10985
+ // ../interactions/core/dist/elements/qti-simple-choice/elements.js
10986
+ var elements10 = [{ tag: "qti-simple-choice", ctor: QtiSimpleChoice }];
10987
+
10988
+ // ../interactions/core/dist/elements.js
10989
+ var qtiInteractionCoreElements = [
10990
+ ...elements,
10991
+ ...elements2,
10992
+ ...elements3,
10993
+ ...elements4,
10994
+ ...elements5,
10995
+ ...elements6,
10996
+ ...elements7,
10997
+ ...elements8,
10998
+ ...elements9,
10999
+ ...elements10
11000
+ ];
11001
+
9796
11002
  // ../interactions/associate-interaction/dist/elements.js
9797
- var elements = [{ tag: "qti-associate-interaction", ctor: QtiAssociateInteraction }];
11003
+ var elements11 = [{ tag: "qti-associate-interaction", ctor: QtiAssociateInteraction }];
9798
11004
 
9799
11005
  // ../interactions/choice-interaction/dist/elements.js
9800
- var elements2 = [{ tag: "qti-choice-interaction", ctor: QtiChoiceInteraction }];
11006
+ var elements12 = [{ tag: "qti-choice-interaction", ctor: QtiChoiceInteraction }];
11007
+
11008
+ // ../interactions/custom-interaction/dist/elements.js
11009
+ var elements13 = [{ tag: "qti-custom-interaction", ctor: QtiCustomInteraction }];
11010
+
11011
+ // ../interactions/end-attempt-interaction/dist/elements.js
11012
+ var elements14 = [{ tag: "qti-end-attempt-interaction", ctor: QtiEndAttemptInteraction }];
9801
11013
 
9802
11014
  // ../interactions/extended-text-interaction/dist/elements.js
9803
- var elements3 = [{ tag: "qti-extended-text-interaction", ctor: QtiExtendedTextInteraction }];
11015
+ var elements15 = [{ tag: "qti-extended-text-interaction", ctor: QtiExtendedTextInteraction }];
9804
11016
 
9805
11017
  // ../interactions/gap-match-interaction/dist/elements.js
9806
- var elements4 = [{ tag: "qti-gap-match-interaction", ctor: QtiGapMatchInteraction }];
11018
+ var elements16 = [{ tag: "qti-gap-match-interaction", ctor: QtiGapMatchInteraction }];
9807
11019
 
9808
11020
  // ../interactions/graphic-associate-interaction/dist/elements.js
9809
- var elements5 = [{ tag: "qti-graphic-associate-interaction", ctor: QtiGraphicAssociateInteraction }];
11021
+ var elements17 = [{ tag: "qti-graphic-associate-interaction", ctor: QtiGraphicAssociateInteraction }];
9810
11022
 
9811
11023
  // ../interactions/graphic-gap-match-interaction/dist/elements.js
9812
- var elements6 = [{ tag: "qti-graphic-gap-match-interaction", ctor: QtiGraphicGapMatchInteraction }];
11024
+ var elements18 = [{ tag: "qti-graphic-gap-match-interaction", ctor: QtiGraphicGapMatchInteraction }];
9813
11025
 
9814
11026
  // ../interactions/graphic-order-interaction/dist/elements.js
9815
- var elements7 = [{ tag: "qti-graphic-order-interaction", ctor: QtiGraphicOrderInteraction }];
11027
+ var elements19 = [{ tag: "qti-graphic-order-interaction", ctor: QtiGraphicOrderInteraction }];
9816
11028
 
9817
11029
  // ../interactions/hotspot-interaction/dist/elements.js
9818
- var elements8 = [{ tag: "qti-hotspot-interaction", ctor: QtiHotspotInteraction }];
11030
+ var elements20 = [{ tag: "qti-hotspot-interaction", ctor: QtiHotspotInteraction }];
9819
11031
 
9820
11032
  // ../interactions/hottext-interaction/dist/elements.js
9821
- var elements9 = [{ tag: "qti-hottext-interaction", ctor: QtiHottextInteraction }];
11033
+ var elements21 = [{ tag: "qti-hottext-interaction", ctor: QtiHottextInteraction }];
9822
11034
 
9823
11035
  // ../interactions/inline-choice-interaction/dist/elements.js
9824
- var elements10 = [{ tag: "qti-inline-choice-interaction", ctor: QtiInlineChoiceInteraction }];
11036
+ var elements22 = [{ tag: "qti-inline-choice-interaction", ctor: QtiInlineChoiceInteraction }];
9825
11037
 
9826
11038
  // ../interactions/match-interaction/dist/elements.js
9827
- var elements11 = [{ tag: "qti-match-interaction", ctor: QtiMatchInteraction }];
11039
+ var elements23 = [{ tag: "qti-match-interaction", ctor: QtiMatchInteraction }];
11040
+
11041
+ // ../interactions/media-interaction/dist/elements.js
11042
+ var elements24 = [{ tag: "qti-media-interaction", ctor: QtiMediaInteraction }];
9828
11043
 
9829
11044
  // ../interactions/order-interaction/dist/elements.js
9830
- var elements12 = [{ tag: "qti-order-interaction", ctor: QtiOrderInteraction }];
11045
+ var elements25 = [{ tag: "qti-order-interaction", ctor: QtiOrderInteraction }];
9831
11046
 
9832
11047
  // ../interactions/portable-custom-interaction/dist/qti-portable-custom-test-interaction.js
9833
11048
  var QtiPortableCustomInteractionTest = class extends QtiPortableCustomInteraction {
@@ -10274,59 +11489,109 @@ var QtiPortableCustomInteractionTest = class extends QtiPortableCustomInteractio
10274
11489
  };
10275
11490
 
10276
11491
  // ../interactions/portable-custom-interaction/dist/elements.js
10277
- var elements13 = [
11492
+ var elements26 = [
10278
11493
  { tag: "qti-portable-custom-interaction", ctor: QtiPortableCustomInteraction },
10279
11494
  { tag: "qti-portable-custom-interaction-test", ctor: QtiPortableCustomInteractionTest }
10280
11495
  ];
10281
11496
 
11497
+ // ../interactions/position-object-interaction/dist/elements.js
11498
+ var elements27 = [
11499
+ { tag: "qti-position-object-interaction", ctor: QtiPositionObjectInteraction },
11500
+ { tag: "qti-position-object-stage", ctor: QtiPositionObjectStage }
11501
+ ];
11502
+
10282
11503
  // ../interactions/select-point-interaction/dist/elements.js
10283
- var elements14 = [{ tag: "qti-select-point-interaction", ctor: QtiSelectPointInteraction }];
11504
+ var elements28 = [{ tag: "qti-select-point-interaction", ctor: QtiSelectPointInteraction }];
10284
11505
 
10285
11506
  // ../interactions/slider-interaction/dist/elements.js
10286
- var elements15 = [{ tag: "qti-slider-interaction", ctor: QtiSliderInteraction }];
11507
+ var elements29 = [{ tag: "qti-slider-interaction", ctor: QtiSliderInteraction }];
10287
11508
 
10288
11509
  // ../interactions/text-entry-interaction/dist/elements.js
10289
- var elements16 = [{ tag: "qti-text-entry-interaction", ctor: QtiTextEntryInteraction }];
11510
+ var elements30 = [{ tag: "qti-text-entry-interaction", ctor: QtiTextEntryInteraction }];
11511
+
11512
+ // ../interactions/upload-interaction/dist/elements.js
11513
+ var elements31 = [{ tag: "qti-upload-interaction", ctor: QtiUploadInteraction }];
11514
+
11515
+ // ../qti-interactions/dist/elements.js
11516
+ var qtiInteractionElements = [
11517
+ ...qtiInteractionCoreElements,
11518
+ ...elements11,
11519
+ ...elements12,
11520
+ ...elements13,
11521
+ ...elements14,
11522
+ ...elements15,
11523
+ ...elements16,
11524
+ ...elements17,
11525
+ ...elements18,
11526
+ ...elements19,
11527
+ ...elements20,
11528
+ ...elements21,
11529
+ ...elements22,
11530
+ ...elements23,
11531
+ ...elements24,
11532
+ ...elements25,
11533
+ ...elements26,
11534
+ ...elements27,
11535
+ ...elements28,
11536
+ ...elements29,
11537
+ ...elements30,
11538
+ ...elements31
11539
+ ];
10290
11540
 
10291
11541
  export {
10292
- ActiveElementMixin,
11542
+ QtiAssociableHotspot,
11543
+ QtiGap,
11544
+ QtiGapImg,
10293
11545
  QtiGapText,
10294
11546
  QtiHotspotChoice,
10295
11547
  QtiHottext,
10296
- dragDropContext,
11548
+ QtiInlineChoice,
11549
+ QtiPrompt,
10297
11550
  QtiSimpleAssociableChoice,
10298
11551
  QtiSimpleChoice,
10299
11552
  QtiAssociateInteraction,
10300
- elements,
11553
+ elements11 as elements,
10301
11554
  QtiChoiceInteraction,
10302
- elements2,
11555
+ elements12 as elements2,
11556
+ QtiCustomInteraction,
11557
+ elements13 as elements3,
11558
+ QtiEndAttemptInteraction,
11559
+ elements14 as elements4,
10303
11560
  QtiExtendedTextInteraction,
10304
- elements3,
11561
+ elements15 as elements5,
10305
11562
  QtiGapMatchInteraction,
10306
- elements4,
11563
+ elements16 as elements6,
10307
11564
  QtiGraphicAssociateInteraction,
10308
- elements5,
11565
+ elements17 as elements7,
10309
11566
  QtiGraphicGapMatchInteraction,
10310
- elements6,
11567
+ elements18 as elements8,
10311
11568
  QtiGraphicOrderInteraction,
10312
- elements7,
11569
+ elements19 as elements9,
10313
11570
  QtiHotspotInteraction,
10314
- elements8,
11571
+ elements20 as elements10,
10315
11572
  QtiHottextInteraction,
10316
- elements9,
11573
+ elements21 as elements11,
10317
11574
  QtiInlineChoiceInteraction,
10318
- elements10,
11575
+ elements22 as elements12,
10319
11576
  QtiMatchInteraction,
10320
- elements11,
11577
+ elements23 as elements13,
11578
+ QtiMediaInteraction,
11579
+ elements24 as elements14,
10321
11580
  QtiOrderInteraction,
10322
- elements12,
11581
+ elements25 as elements15,
10323
11582
  QtiPortableCustomInteraction,
10324
- elements13,
11583
+ elements26 as elements16,
11584
+ QtiPositionObjectInteraction,
11585
+ QtiPositionObjectStage,
11586
+ elements27 as elements17,
10325
11587
  QtiSelectPointInteraction,
10326
- elements14,
11588
+ elements28 as elements18,
10327
11589
  QtiSliderInteraction,
10328
- elements15,
11590
+ elements29 as elements19,
10329
11591
  QtiTextEntryInteraction,
10330
- elements16
11592
+ elements30 as elements20,
11593
+ QtiUploadInteraction,
11594
+ elements31 as elements21,
11595
+ qtiInteractionElements
10331
11596
  };
10332
- //# sourceMappingURL=chunk-4XR2JHCP.js.map
11597
+ //# sourceMappingURL=chunk-5BXJRO5O.js.map