@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
@@ -1,3 +1,6 @@
1
+ // ../qti-base/dist/elements.js
2
+ var qtiBaseElements = [];
3
+
1
4
  // ../qti-base/dist/utils/custom-state-set.js
2
5
  var CustomStateSetShim = class extends Set {
3
6
  #host;
@@ -460,8 +463,7 @@ var QtiExpression = class extends LitElement3 {
460
463
  type: "context"
461
464
  };
462
465
  }
463
- const variable = this.context.variables.find((v) => v.identifier === identifier) || null;
464
- return variable;
466
+ return this.resolveVariable(identifier);
465
467
  }
466
468
  case "qti-multiple": {
467
469
  const multiple = e;
@@ -545,6 +547,17 @@ var QtiExpression = class extends LitElement3 {
545
547
  getResult() {
546
548
  throw new Error("Not implemented");
547
549
  }
550
+ /**
551
+ * Resolve a declared variable from the closest available scope: item-level
552
+ * first, then the test-level outcome variables. So an expression used in an
553
+ * assessmentTest's outcome processing can reference a test-level outcome
554
+ * (e.g. a total set earlier in the same run) — which the QTI variable
555
+ * expression is specified to do. Returns null when unresolved rather than
556
+ * throwing, so callers degrade gracefully.
557
+ */
558
+ resolveVariable(identifier) {
559
+ return this.context?.variables.find((v) => v.identifier === identifier) ?? this._testContext?.testOutcomeVariables?.find((v) => v.identifier === identifier) ?? null;
560
+ }
548
561
  };
549
562
  __decorate2([
550
563
  state()
@@ -557,6 +570,10 @@ __decorate2([
557
570
  consume2({ context: qtiContext, subscribe: true }),
558
571
  state()
559
572
  ], QtiExpression.prototype, "qtiContext", void 0);
573
+ __decorate2([
574
+ consume2({ context: testContext, subscribe: true }),
575
+ state()
576
+ ], QtiExpression.prototype, "_testContext", void 0);
560
577
 
561
578
  // ../qti-base/dist/abstract/qti-condition-expression.js
562
579
  var QtiConditionExpression = class extends QtiExpression {
@@ -628,8 +645,41 @@ var QtiFeedback = class extends LitElement4 {
628
645
  this.#showFeedback(isFound);
629
646
  }
630
647
  #showFeedback(value) {
648
+ if (!this.#sessionControlAllowsFeedback()) {
649
+ this.showStatus = "off";
650
+ return;
651
+ }
631
652
  this.showStatus = value && this.showHide === "show" || !value && this.showHide === "hide" ? "on" : "off";
632
653
  }
654
+ /**
655
+ * The QTI `show-feedback` constraint governs exactly one state: after the end of
656
+ * the last attempt. Up to that point the spec requires any applicable feedback to
657
+ * be shown — "a value of max-attempts greater than 1, by definition, indicates
658
+ * that any applicable feedback must be shown" — and only "once the maximum number
659
+ * of allowed attempts have been used (or for adaptive items, completionStatus has
660
+ * been set to completed)" does `show-feedback` decide.
661
+ *
662
+ * This only ever forces feedback off, so `show-feedback` being true settles it:
663
+ * there is no state in which the constraint hides feedback. It defaults to
664
+ * false, and an absent value suppresses once the attempts are gone.
665
+ *
666
+ * That leaves one question — is the item out of attempts? — and the two item
667
+ * kinds answer it from different variables, so each reads only its own.
668
+ */
669
+ #sessionControlAllowsFeedback() {
670
+ if (!this._computedContext)
671
+ return true;
672
+ const activeItem = this._computedContext.testParts?.find((tp) => tp.active)?.sections.flatMap((s) => s.items).find((i) => i.active);
673
+ if (!activeItem || activeItem.showFeedback)
674
+ return true;
675
+ if (activeItem.adaptive)
676
+ return activeItem.completionStatus !== "completed";
677
+ const maxAttempts = activeItem.maxAttempts ?? 1;
678
+ if (maxAttempts <= 0)
679
+ return true;
680
+ const numAttempts = Number(this._context?.variables?.find((v) => v.identifier === "numAttempts")?.value) || 0;
681
+ return numAttempts < maxAttempts;
682
+ }
633
683
  };
634
684
  __decorate3([
635
685
  property2({ type: String, attribute: "show-hide" })
@@ -647,6 +697,10 @@ __decorate3([
647
697
  consume3({ context: itemContext, subscribe: true }),
648
698
  state2()
649
699
  ], QtiFeedback.prototype, "_context", void 0);
700
+ __decorate3([
701
+ consume3({ context: computedContext, subscribe: true }),
702
+ state2()
703
+ ], QtiFeedback.prototype, "_computedContext", void 0);
650
704
 
651
705
  // ../qti-base/dist/lib/response.js
652
706
  function parseResponseAttribute(raw) {
@@ -863,9 +917,6 @@ var ScoringHelper = class {
863
917
  }
864
918
  };
865
919
 
866
- // ../qti-base/dist/elements.js
867
- var qtiBaseElements = [];
868
-
869
920
  // ../qti-base/dist/register.js
870
921
  installCustomStateSetFallback();
871
922
  for (const { tag, ctor } of qtiBaseElements) {
@@ -875,6 +926,7 @@ for (const { tag, ctor } of qtiBaseElements) {
875
926
  }
876
927
 
877
928
  export {
929
+ qtiBaseElements,
878
930
  CustomStateSetShim,
879
931
  classifyCustomStateSupport,
880
932
  installCustomStateSetFallback,
@@ -914,4 +966,4 @@ export {
914
966
  QtiRuleElement,
915
967
  ScoringHelper
916
968
  };
917
- //# sourceMappingURL=chunk-EKXZI26R.js.map
969
+ //# sourceMappingURL=chunk-WCWJPIUQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../qti-base/src/elements.ts","../../qti-base/src/utils/custom-state-set.ts","../../qti-base/src/context/computed-item.context.ts","../../qti-base/src/context/computed.context.ts","../../qti-base/src/context/config.context.ts","../../qti-base/src/context/interaction.context.ts","../../qti-base/src/context/item.context.ts","../../qti-base/src/context/types/item.types.ts","../../qti-base/src/context/qti.context.ts","../../qti-base/src/context/session.context.ts","../../qti-base/src/context/test.context.ts","../../qti-base/src/styles/box-sizing.styles.ts","../../qti-base/src/styles/drop-region.styles.ts","../../qti-base/src/styles/validation-message.styles.ts","../../qti-base/src/abstract/interaction.ts","../../qti-base/src/abstract/qti-variable-declaration.ts","../../qti-base/src/abstract/qti-expression.ts","../../qti-base/src/abstract/qti-condition-expression.ts","../../qti-base/src/utils/utils.ts","../../qti-base/src/abstract/qti-feedback.ts","../../qti-base/src/lib/response.ts","../../qti-base/src/lib/qti-rule-base.ts","../../qti-base/src/utils/scoring-helper.ts","../../qti-base/src/register.ts"],"sourcesContent":["/**\n * Custom elements this package registers into an application's registry.\n *\n * Empty, deliberately. `qti-base` is abstractions and context — it contributes no elements to a\n * delivery application.\n *\n * The one entry that used to be here, `qti-config-test-provider`, is gone entirely. It was a\n * TEST-ONLY wrapper that every consumer of `import '@qti-components/base'` registered transitively,\n * and it carried `@customElement(...)` on top of this list — an UNGUARDED `customElements.define()`\n * at module-evaluation time. A module graph holding two copies of this package (a workspace build\n * alongside a published dist, which is what the editor resolves) evaluated it twice and the second\n * threw `NotSupportedError: ... already been used with this registry`, aborting module evaluation\n * and taking down every test file that imported it — 34 suites in the editor, none of which used\n * the element. `register.ts` had the guard right all along; the decorator bypassed it.\n *\n * Config for a single interaction is a property binding now — see config.context.ts.\n *\n * The array and `register.ts` stay so the elements + guarded-register convention the other 30\n * packages follow is already in place the day this package does own an element.\n */\nexport const qtiBaseElements: readonly { tag: string; ctor: CustomElementConstructor }[] = [];\n","/**\n * Custom-state support shim for browsers this library cannot use natively.\n *\n * Interactions track selection and correct/incorrect marking through\n * `internals.states`, with bare state names (`checked`, `radio`,\n * `correct-response`, …). Two browser profiles cannot service that:\n *\n * - Safari 16.4–17.3 implement `ElementInternals` but not `CustomStateSet`, so\n * `internals.states` is `undefined` and reading it throws — \"undefined is not\n * an object (evaluating 'internals.states.has')\".\n * - Chrome and Edge before the CSS custom-state spec change expose `states` but\n * reject names that do not start with `--`, so `states.add('radio')` throws\n * \"The specified value 'radio' must start with '--'\".\n *\n * On both, picking a choice throws rather than registering. `attachInternals`\n * itself is unguarded throughout the interaction base classes, which puts the\n * hard support floor at Safari 16.4 — inside the range that breaks.\n *\n * The shim replaces `states` with a permissive `Set` and mirrors its contents to\n * a space-separated `data-state` attribute on the host, because these browsers'\n * CSS parsers also drop any selector list containing `:state()`. The theme's\n * built stylesheets pair every `:state(x)` with a `[data-state~='x']` arm (see\n * `tools/postcss/custom-state-fallback.mjs`), so styling survives too.\n *\n * Support is classified by behaviour rather than by browser version, and the\n * shim is not installed at all where `states` works.\n */\n\n/** A permissive `CustomStateSet` that mirrors its contents to `data-state`. */\nexport class CustomStateSetShim extends Set<string> {\n readonly #host: HTMLElement;\n\n constructor(host: HTMLElement) {\n super();\n this.#host = host;\n }\n\n override add(state: string): this {\n super.add(state);\n this.#reflect();\n return this;\n }\n\n override delete(state: string): boolean {\n const deleted = super.delete(state);\n this.#reflect();\n return deleted;\n }\n\n override clear(): void {\n super.clear();\n this.#reflect();\n }\n\n #reflect(): void {\n // A custom element must not gain attributes while it is upgrading, so defer\n // the write until the element is connected.\n if (this.#host.isConnected) this.#write();\n else queueMicrotask(() => this.#write());\n }\n\n #write(): void {\n if (this.size === 0) this.#host.removeAttribute('data-state');\n else this.#host.setAttribute('data-state', Array.from(this).join(' '));\n }\n}\n\nexport type CustomStateSupport = 'missing' | 'legacy' | 'modern';\n\nconst PROBE_TAG = 'custom-state-support-probe';\n\n/**\n * Classify native custom-state support by behaviour:\n *\n * - `missing`: `ElementInternals` carries no `states` at all.\n * - `legacy`: `states` exists but rejects a bare name.\n * - `modern`: `states` exists and accepts a bare name — no shim wanted.\n *\n * `attachInternals` only works on a custom element, so the probe registers a\n * throwaway one. That happens solely when `states` is present, so the `missing`\n * path never defines anything.\n */\nexport function classifyCustomStateSupport(\n attachInternals: (this: HTMLElement) => ElementInternals\n): CustomStateSupport {\n if (!('states' in ElementInternals.prototype)) return 'missing';\n if (typeof customElements === 'undefined') return 'modern';\n\n try {\n if (!customElements.get(PROBE_TAG)) customElements.define(PROBE_TAG, class extends HTMLElement {});\n const states = attachInternals.call(document.createElement(PROBE_TAG)).states;\n if (!states) return 'missing';\n // A bare name throws SyntaxError under the legacy spec and never does under\n // the current one, so classify on the throw alone — not on whether the value\n // sticks, which some environments do not honour on a detached element.\n states.add('probe');\n states.delete('probe');\n return 'modern';\n } catch {\n return 'legacy';\n }\n}\n\nlet installed = false;\n\n/**\n * Patch `HTMLElement.prototype.attachInternals` so every element's `states` is\n * the shim, on the two profiles that need it. Idempotent, and a no-op where\n * native support is usable.\n *\n * Returns the classification that was acted on, which is what the tests assert.\n */\nexport function installCustomStateSetFallback(): CustomStateSupport | 'already-installed' {\n if (installed) return 'already-installed';\n if (typeof HTMLElement === 'undefined' || typeof ElementInternals === 'undefined') return 'modern';\n\n const native = HTMLElement.prototype.attachInternals;\n if (!native) return 'modern';\n\n const support = classifyCustomStateSupport(native);\n if (support === 'modern') return support;\n\n installed = true;\n HTMLElement.prototype.attachInternals = function attachInternals(this: HTMLElement): ElementInternals {\n const internals = native.call(this);\n Object.defineProperty(internals, 'states', {\n configurable: true,\n enumerable: true,\n value: new CustomStateSetShim(this)\n });\n return internals;\n };\n\n return support;\n}\n","import { createContext } from '@lit/context';\n\nimport type { ComputedItemContext } from './types/computed-item.types';\n\nexport const computedItemContext = createContext<Readonly<ComputedItemContext>>(Symbol('computedItemContext'));\n","import { createContext } from '@lit/context';\n\nimport type { ComputedContext } from './types/computed.types';\n\nexport const computedContext = createContext<Readonly<ComputedContext>>(Symbol('computedContext'));\n","import { createContext } from '@lit/context';\n\nexport type ValidationDisplayMode = 'inline' | 'native' | 'both' | 'none';\n\n/**\n * Configuration context for QTI components. Provides runtime options for assessment item and\n * interaction behavior.\n *\n * ── Three ways to set it, in the order you should reach for them ─────────────────────────────\n *\n * 1. **On a provider**, for real delivery. `qti-test` and `qti-item` both provide it, so setting\n * `item.configContext = {…}` configures every interaction inside.\n *\n * 2. **On one interaction, directly** — the development-time route, and the reason\n * `Interaction.configContext` is public:\n *\n * orderInteraction.configContext = { allowReorder: false };\n *\n * or, in a lit-html template, as a property binding — which lands before `connectedCallback`:\n *\n * html`<qti-order-interaction .configContext=${{ allowReorder: false }}>…`\n *\n * An interaction has to work standalone, so in a story or a spec there is usually no provider\n * above it, and then nothing ever overwrites what you set. Where a provider DOES exist it wins on\n * its next emit, because `@consume` writes that same field.\n *\n * A `qti-config-test-provider` element used to exist for scoping config to a subtree. It is gone:\n * it was test-only yet registered itself into every consumer's element registry via an unguarded\n * `@customElement`, which threw whenever two copies of this package ended up in one module graph.\n * Bind the property on each interaction instead, or provide from `qti-item`.\n *\n * There is no merging at any level: @lit/context resolves to the nearest provider and that object\n * replaces the ancestor's wholesale. A deeper provider therefore has to restate anything from above\n * that it still wants.\n *\n * Note what is NOT here. Options an item author chooses per question are attributes on the\n * interaction (`auto-size-dropzones`, `max-associations`, `disable-animations`); options only a\n * developer chooses are mixin factory arguments or method overrides. This context is for what a\n * delivery environment decides across items. `interactionContext` and `dragDropContext` are neither\n * — they publish derived state (what a choice IS, what a drop HOLDS), never configuration.\n */\nexport interface ConfigContext {\n /**\n * Optional category label for info items, used for reporting or display purposes.\n * Example: \"General Information\", \"Instructions\".\n */\n infoItemCategory?: string;\n\n /**\n * If true, calls reportValidity() on interactions after scoring to show validation feedback.\n * Used to trigger UI validation after a scoring event.\n */\n reportValidityAfterScoring?: boolean;\n\n /**\n * Controls how validation feedback is displayed by interactions:\n * - 'inline': render message in #validation-message (default behavior)\n * - 'native': use browser-native reportValidity popup behavior\n * - 'both': show both inline and native feedback\n * - 'none': keep validity state only, without visual feedback\n */\n validationDisplayMode?: ValidationDisplayMode;\n\n /**\n * If true, disables further user actions when an interaction reaches its configured maximum.\n * Applies to both choice-based and drag/drop interactions.\n */\n disableAfterMaxReached?: boolean;\n\n /**\n * If false, chips already placed in a drop target cannot be reordered or moved between targets in\n * drag/drop sortable interactions (order, match, gap-match). Defaults to true. A per-interaction\n * `allowReorder` property overrides this.\n */\n allowReorder?: boolean;\n\n /**\n * If true, disables further selection in choice interactions after the maximum number of choices is reached.\n * @deprecated Legacy alias for choice interactions. Prefer disableAfterMaxReached.\n */\n disableAfterIfMaxChoicesReached?: boolean;\n\n /**\n * Optional prompt text to display in inline choice interactions when no option is selected.\n * Example: \"Select an answer...\"\n */\n inlineChoicePrompt?: string;\n\n /**\n * If true, the inline choice interaction automatically measures the widest option and sizes the\n * trigger button to match. Defaults to false.\n * When a `qti-input-width-*` class is present on the interaction, that class width always takes\n * precedence and autosizing is skipped regardless of this setting.\n */\n inlineChoiceAutosize?: boolean;\n}\n\nexport const configContext = createContext<Readonly<ConfigContext>>(Symbol('configContext'));\n","import { createContext } from '@lit/context';\n\n/**\n * What a choice element should render and behave as. The same element — `qti-simple-choice`,\n * `qti-hottext` — is a radio in one interaction and a checkbox in another. It cannot know this\n * by itself.\n *\n * Note \"drag\" is deliberately *not* a choiceRole. In `qti-match-interaction` the same element\n * type is a drag in one match-set and a drop target in the other, so draggability is positional,\n * not a property of the interaction. It is derived from `draggablesSelector` instead. It is also\n * not a valid ARIA role, so it may only ever be a custom state.\n */\nexport type ChoiceRole = 'radio' | 'checkbox';\n\n/**\n * State an interaction publishes to the choice elements inside it.\n *\n * Provided by the `qti-*-interaction`, never by `qti-assessment-item`: interactions must work\n * standalone — in a plain form, in a story, in a vendor's app — with no QTI ancestor. Consumers\n * must therefore tolerate its absence and fall back to a sensible default:\n *\n * const role = this.interactionContext?.choiceRole ?? null;\n */\nexport interface InteractionContext {\n /** `null` when the interaction assigns no particular role to its choices. */\n choiceRole: ChoiceRole | null;\n\n /**\n * The selector this interaction uses to recognise its draggable chips. An element tests\n * itself with `this.matches(draggablesSelector)` and takes `:state(chip)` if it matches.\n *\n * Published rather than pushed because draggability can be positional: match-interaction's\n * selector distinguishes the source match-set from the target one, so two elements of the\n * same tag get different answers.\n */\n draggablesSelector: string | null;\n}\n\nexport const interactionContext = createContext<Readonly<InteractionContext>>(Symbol('interactionContext'));\n","import { createContext } from '@lit/context';\n\nimport type { ItemContext } from './types/item.types';\n\nexport const itemContext = createContext<ItemContext>(Symbol('item'));\n","import type { VariableDeclaration } from '../../lib/variables';\n\nexport interface ItemContext {\n identifier?: string;\n href?: string;\n variables?: ReadonlyArray<VariableDeclaration<string | string[] | null>>;\n /**\n * Optional per-interaction opaque state, keyed by responseIdentifier.\n * Used for interactions that support state save/restore (e.g. PCI).\n */\n state?: Record<string, string | null>;\n}\n\nexport const itemContextVariables = [\n {\n identifier: 'completionStatus',\n cardinality: 'single',\n baseType: 'string',\n value: 'unknown',\n type: 'outcome'\n },\n {\n identifier: 'numAttempts',\n cardinality: 'single',\n baseType: 'integer',\n value: '0',\n type: 'response'\n }\n] as VariableDeclaration<string | string[]>[];\n","import { createContext } from '@lit/context';\n\n/**\n * A validated deterministic shuffle seed.\n *\n * Branded so that only values verified through {@link isSeed} (or constructed via\n * {@link asSeed}) can be assigned where a seed is expected. This prevents arbitrary\n * strings from silently being used as a seed.\n *\n * A usable seed is a non-empty string of letters, digits and hyphens (e.g. a GUID\n * \"N\" format like `8f14e45fceea167a5a36dedd4bea2543`, or a readable label like\n * `delivery-2026-06-05`). Whitespace and other characters are rejected.\n */\nexport type Seed = string & { readonly __seedBrand: 'Seed' };\n\n/** Format a value must match to be usable as a {@link Seed}. */\nconst SEED_PATTERN = /^[A-Za-z0-9-]+$/;\n\n/**\n * Runtime type guard that narrows an unknown value to a {@link Seed}.\n * Use this at boundaries (e.g. values coming from XML, a host application or a\n * backend) before treating a string as a seed.\n */\nexport const isSeed = (value: unknown): value is Seed => typeof value === 'string' && SEED_PATTERN.test(value);\n\n/**\n * Validates and brands a value as a {@link Seed}, returning `undefined` when the\n * value is missing or not in a usable seed format.\n */\nexport const asSeed = (value: unknown): Seed | undefined => (isSeed(value) ? value : undefined);\n\nexport type QtiContextType = {\n testIdentifier: string;\n candidateIdentifier: string;\n environmentIdentifier: string;\n /**\n * Optional deterministic seed for shuffling.\n *\n * When set, it is used to reproduce a stable shuffle order across reloads/restarts:\n * - test ordering in `test-container` (`<qti-ordering shuffle=\"true\">`),\n * - seeded item interaction shuffling in `item-container` and during test navigation.\n *\n * Typically generated once per session by the host/backend and passed in via\n * `QTI_CONTEXT`. When omitted, each item falls back to its own URI-derived seed.\n */\n seed?: Seed;\n [key: string]: string | string[]; // Allow for additional context variables\n};\n\nexport interface QtiContext {\n QTI_CONTEXT: QtiContextType;\n}\n\nexport const qtiContext = createContext<Readonly<QtiContext>>(Symbol('qtiContext'));\n","import { createContext } from '@lit/context';\n\nexport type View = 'author' | 'candidate' | 'proctor' | 'scorer' | 'testConstructor' | 'tutor' | '';\n\nexport interface SessionContext {\n navPartId?: string | null;\n navSectionId?: string | null;\n navItemRefId?: string | null;\n navItemLoading?: boolean;\n navTestLoading?: boolean;\n view?: View;\n}\n\nexport const INITIAL_SESSION_CONTEXT: Readonly<SessionContext> = { view: 'candidate' };\n\nexport const sessionContext = createContext<Readonly<SessionContext>>(Symbol('testContext'));\n","import { createContext } from '@lit/context';\n\nimport type { ItemContext } from './types/item.types';\nimport type { VariableDeclaration } from '../lib/variables';\n\nexport interface TestContext {\n items: (ItemContext & { category?: string })[];\n testOutcomeVariables?: VariableDeclaration<string | string[] | null>[];\n}\n\nexport const INITIAL_TEST_CONTEXT: Readonly<TestContext> = { items: [], testOutcomeVariables: [] };\n\nexport const testContext = createContext<Readonly<TestContext>>(Symbol('testContext'));\n","import { css } from 'lit';\n\n/**\n * The border-box reset, for shadow trees.\n *\n * `modern-normalize` applies `*, ::before, ::after { box-sizing: border-box }` to the document,\n * but a universal selector never crosses a shadow boundary: every shadow root starts over at\n * the UA default, `content-box`. So each component has to opt in, and until now 15 of them did\n * so ad hoc — one of them with `content-box`, one with `!important`.\n *\n * Why this matters beyond tidiness: under `content-box`, padding and border are *size*. A rule\n * that only means to repaint a chip — `:state(dragging) { border: none }` — silently shrinks it\n * by two pixels per axis, the drag bank rewraps, and a drop target slides out from under the\n * user's pointer mid-drag. Border-box is what makes \"a state may repaint but never re-lay-out\"\n * a rule the CSS can actually keep.\n *\n * `:host` is set explicitly and descendants inherit, so a component that genuinely needs\n * `content-box` for a subtree (an image map, say) can opt out at one node and have it hold for\n * everything below it.\n */\nexport const boxSizing = css`\n :host {\n box-sizing: border-box;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: inherit;\n }\n`;\n","import { css } from 'lit';\n\n/**\n * The `drop` region of every drop target.\n *\n * One rule: **a drop container hosts a chip, it never sizes one.** No `flex: 1`, no stretch, no\n * centring. The chip's box is decided by the chip — in the drag bank, mid-flight as a clone, and\n * once dropped — and a container that centres or stretches it makes the drop the one place where\n * that stops being true. That is felt as the chip jumping the instant it lands.\n *\n * `flex: 0 1 auto` on the children says \"intrinsic size, no growing, shrink if you must\".\n * `align-items: flex-start` stops the cross axis stretching them, which is the flex default and\n * the reason a chip in a tall dropzone used to grow to fill it.\n *\n * The shrink half used to be 0 as well, on the reading that a drop must not resize a chip. It does\n * not say that. `flex-shrink: 0` does not preserve the chip's size, it preserves the chip's\n * UNCONSTRAINED max-content size — and those are the same number only while the bank is wide enough\n * to give the chip its full width. Once the bank is narrower, the bank chip (`flex: 0 1 auto`, like\n * any flex item) shrinks and wraps, the placed chip does not, and the two disagree.\n *\n * Measured on the order fixture, bank vs placed: 209x36 / 209x36 at a 480px interaction, but\n * 204x55 / 209x36 at 440px and 154x55 / 209x36 at 340px — the placed chip a fixed 209px wide,\n * overflowing a drop that had correctly reserved 156px for it. It reached CI as a font difference:\n * the same label measures ~227px under the Linux fonts, which puts 480px on the wrong side of the\n * boundary too.\n *\n * Shrinking cannot make a placed chip smaller than the reservation, because the reservation IS the\n * measured chip (`--qti-dropzone-min-*`, applied to this region's content box). So the floor a\n * shrink stops at is the chip's own size, which is the rule above, not an exception to it.\n * `flex-grow: 0` is what actually prevents the stretch this block cares about, and it is untouched.\n *\n * A container that wants a *minimum* size still declares one (see `--qti-dropzone-min-*`). That\n * sizes the container, never its contents.\n *\n * Verified by drag-drop.invariance.spec.ts: \"a chip is the same chip wherever it lives\" — including\n * the narrow-bank order fixture, which is there because the wide one passes either way.\n */\nexport const dropRegion = css`\n [part~='drop'] {\n /*\n * The one deliberate opt-out from the border-box reset.\n *\n * --qti-dropzone-min-* is the border-box of the largest chip, and what has to hold that chip is\n * this region's *content* area. Under border-box a theme's dashed drop border is subtracted\n * from the chip's own size, the content comes up short, and the drop grows the moment a chip\n * lands in it. Order's drop did exactly that: 64px empty, 66px full, for a 1px border.\n */\n box-sizing: content-box;\n\n /*\n * No padding, and no token for one.\n *\n * A drop reserves --qti-dropzone-min-*, which is the chip's BORDER-box, as this region's CONTENT\n * area — so the chip already fits exactly, with nothing to spare and nothing squeezed. An inset\n * on top would only make the drop bigger than the thing it holds.\n *\n * There was a 1px one, to make the drop read as a frame a hair outside the chip. It never painted:\n * an EMPTY slot has nothing inside the inset to separate from, and a FILLED one hides its edge\n * (DROP-SIZING.md §4), so both states spent 2px on an invisible ring. The one drop that genuinely\n * wants breathing room — match's category card — declares padding on its own rule, which a\n * theme reaches with ::part(drop). A token in between bought nothing.\n */\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: flex-start;\n /* No gap either: 0 is the flex initial value, so the declaration only existed to host a token.\n A drop that wants space between chips sets gap on its own rule. */\n /* Containing block for anything a theme draws over the drop. Was 'position: relative' in the\n theme's 'drop' mixin, which put a document stylesheet in charge of a shadow node's position. */\n position: relative;\n }\n\n [part~='drop'] > * {\n flex: 0 1 auto;\n align-self: flex-start;\n }\n`;\n","import { css } from 'lit';\n\n/**\n * The `#validation-message` region every interaction renders, hidden until there is a message.\n *\n * `Interaction` owns showing and hiding it: `reportValidity` sets\n * `display: block !important` inline when `_internals.validationMessage` is non-empty, and clears the\n * text and sets `display: none` inline again when it is not (see interaction.ts). An inline\n * `!important` beats this rule, so the JS still wins whenever it speaks.\n *\n * What it did not own was the *initial* state. Before first validation the div has no inline style,\n * so it needs a stylesheet to start hidden — otherwise it paints as an empty box with the theme's\n * warning border and padding. That hide used to be a `display: none` inside the theme's\n * `validation-message` mixin, which made a document stylesheet responsible for a shadow node's box.\n * Two components had already noticed and worked around it with `style=\"display:none\"` in their\n * template; the other five relied on the theme.\n *\n * The theme still paints the message — colour, border, padding, radius — via `::part(message)`.\n */\nexport const validationMessage = css`\n [part~='message'] {\n display: none;\n }\n`;\n","import { consume, provide } from '@lit/context';\nimport { LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { configContext } from '../context/config.context';\nimport { interactionContext } from '../context/interaction.context';\nimport { itemContext } from '../context/item.context';\n\nimport type { PropertyValues } from 'lit';\nimport type { InteractionContext } from '../context/interaction.context';\nimport type { ConfigContext, ValidationDisplayMode } from '../context/config.context';\nimport type { ItemContext } from '../context/types/item.types';\nimport type { ValidatableInteraction } from '../lib/interaction.interface';\nimport type { ResponseVariable } from '../lib/variables';\n\n/**\n * Shared QTI interaction base. Formative correction behavior is supplied by the\n * `@qti-components/corrections` package.\n */\nexport abstract class Interaction extends LitElement implements ValidatableInteraction {\n @consume({ context: itemContext, subscribe: true })\n private _context: ItemContext;\n\n /**\n * Delivery configuration, from the nearest provider — `qti-test` or `qti-item`.\n *\n * **Public so it can be assigned directly, which is the development-time route.** An interaction\n * has to work standalone, and in a story or a spec there is usually no provider above it — so\n * setting the field is all that is needed:\n *\n * orderInteraction.configContext = { allowReorder: false, validationDisplayMode: 'none' };\n *\n * With no provider, nothing ever overwrites it. That is the whole contract, and its limit: where a\n * provider DOES exist it re-emits on its next update and wins, because `@consume` writes this same\n * field. There is no merging — set the value on the provider in that case.\n *\n * In a lit-html template, bind it as a property rather than assigning after the fact:\n *\n * html`<qti-order-interaction .configContext=${{ allowReorder: false }}>…`\n *\n * The binding is committed on the detached template clone, before the fragment is inserted, so it\n * is in place by `connectedCallback` — which matters for anything that reads config on connect.\n *\n * It was `protected`, which fooled nobody: every caller reached it anyway through an\n * `as any` / `as { configContext?: … }` cast. Public says what was already true and removes the\n * casts, rather than pretending at an encapsulation the type system was the only thing enforcing.\n */\n @consume({ context: configContext, subscribe: true })\n public configContext: ConfigContext;\n\n #didLogDisableAfterIfMaxChoicesReachedDeprecation = false;\n\n /*\n * Published to the choice elements inside this interaction — their role, and how to tell\n * whether they are draggable. Provided here on the base rather than in a mixin so that\n * ChoicesMixin and the drag-drop mixins can each contribute without two providers of the same\n * context competing on one element.\n *\n * Reassign, never mutate: an in-place change does not notify consumers.\n */\n @provide({ context: interactionContext })\n protected _interactionContext: Readonly<InteractionContext> = { choiceRole: null, draggablesSelector: null };\n\n static formAssociated = true;\n protected _internals: ElementInternals;\n\n get internals(): ElementInternals {\n return this._internals;\n }\n\n @property({ type: String, attribute: 'response-identifier' }) responseIdentifier: string;\n\n @property({ reflect: true, type: Boolean }) disabled = false;\n\n @property({ reflect: true, type: Boolean }) readonly = false;\n\n @property({ type: String }) name;\n\n /** Extension point used by wrappers that should not register as candidate inputs. */\n protected get registersWithItem(): boolean {\n return true;\n }\n\n get isInline(): boolean {\n return false;\n }\n\n get responseVariable(): ResponseVariable | undefined {\n if (!this._context?.variables) {\n return undefined;\n }\n const responseVariables = this._context.variables.filter(v => v.type === 'response') as ResponseVariable[];\n const responseIdentifier = this.getAttribute('response-identifier');\n return responseVariables.find(v => v.identifier === responseIdentifier);\n }\n\n abstract validate(): boolean;\n\n get value(): string | null {\n return JSON.stringify(this.response);\n }\n\n set value(val: string | null) {\n this.response = val ? JSON.parse(val) : null;\n }\n\n abstract get response(): string | string[] | null;\n abstract set response(val: string | string[] | null);\n\n public reportValidity(): boolean {\n const isValid = this._internals.validity.valid;\n const mode = this.validationDisplayMode;\n\n if (mode === 'native' || mode === 'both') {\n this._internals.reportValidity();\n }\n\n if (mode === 'inline' || mode === 'both') {\n this.updateInlineValidationMessage();\n } else {\n this.clearInlineValidationMessage();\n }\n\n if (mode === 'none') {\n this.clearInlineValidationMessage();\n }\n\n return isValid;\n }\n\n protected get validationDisplayMode(): ValidationDisplayMode {\n return this.configContext?.validationDisplayMode ?? 'inline';\n }\n\n protected resolveAllowReorder(options?: { defaultWhenUnset?: boolean }): boolean {\n const defaultWhenUnset = options?.defaultWhenUnset ?? true;\n const config = this.configContext;\n if (!config) {\n return defaultWhenUnset;\n }\n if (config.allowReorder !== undefined) {\n return config.allowReorder;\n }\n return defaultWhenUnset;\n }\n\n protected resolveDisableAfterMaxReached(options?: { defaultWhenUnset?: boolean }): boolean {\n const defaultWhenUnset = options?.defaultWhenUnset ?? false;\n const config = this.configContext;\n\n if (!config) {\n return defaultWhenUnset;\n }\n\n if (config.disableAfterMaxReached !== undefined) {\n return config.disableAfterMaxReached;\n }\n\n if (config.disableAfterIfMaxChoicesReached !== undefined) {\n if (!this.#didLogDisableAfterIfMaxChoicesReachedDeprecation) {\n this.#didLogDisableAfterIfMaxChoicesReachedDeprecation = true;\n console.log(\n '[QTI Config] `disableAfterIfMaxChoicesReached` is deprecated. Use `disableAfterMaxReached` instead.'\n );\n }\n return config.disableAfterIfMaxChoicesReached;\n }\n\n return defaultWhenUnset;\n }\n\n protected setInteractionValidity(\n isValid: boolean,\n validityMessage = '',\n anchor?: HTMLElement | null,\n options?: { suppressInline?: boolean }\n ): void {\n const validityAnchor = anchor ?? this;\n this._internals.setValidity(isValid ? {} : { customError: true }, validityMessage, validityAnchor);\n\n if (\n options?.suppressInline !== true &&\n (this.validationDisplayMode === 'inline' || this.validationDisplayMode === 'both')\n ) {\n this.updateInlineValidationMessage();\n }\n }\n\n protected updateInlineValidationMessage(): void {\n const validationMessageElement = this.getValidationMessageElement();\n if (!validationMessageElement) {\n return;\n }\n\n if (!this._internals.validity.valid) {\n validationMessageElement.textContent = this._internals.validationMessage;\n validationMessageElement.style.setProperty('display', 'block', 'important');\n return;\n }\n\n validationMessageElement.textContent = '';\n validationMessageElement.style.display = 'none';\n }\n\n protected clearInlineValidationMessage(): void {\n const validationMessageElement = this.getValidationMessageElement();\n if (!validationMessageElement) {\n return;\n }\n\n validationMessageElement.textContent = '';\n validationMessageElement.style.display = 'none';\n }\n\n protected getValidationMessageElement(): HTMLElement | null {\n return this.shadowRoot?.querySelector('#validation-message') as HTMLElement | null;\n }\n\n public reset(): void {\n this.response = null;\n }\n\n public formResetCallback(): void {\n this.reset();\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n\n if (!this.registersWithItem) {\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent('qti-register-interaction', {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: {\n interactionElement: this,\n responseIdentifier: this.responseIdentifier\n }\n })\n );\n }\n\n public saveResponse(value: string | string[], state?: string | null): void {\n this.dispatchEvent(\n new CustomEvent('qti-interaction-response', {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: {\n responseIdentifier: this.responseIdentifier,\n response: Array.isArray(value) ? [...value] : value,\n ...(state !== undefined ? { state } : {})\n }\n })\n );\n }\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n /**\n * Optional lifecycle bridge for interaction subclasses that do not need changed-property data.\n *\n * The parameter is `PropertyValues`, matching LitElement, and NOT `PropertyValues<this>`.\n * The polymorphic `this` narrowed the parameter per subclass, which made every interaction\n * class structurally incompatible with `LitElement` — so `Constructor<LitElement>`, the\n * standard constraint for a Lit mixin, rejected all of them and consumers could not wrap an\n * interaction in a mixin without casting. `this` buys nothing in a parameter position and\n * costs contravariant compatibility with the base class.\n *\n * Still optional, so subclasses that ignore the argument can override with `firstUpdated()`.\n */\n protected override firstUpdated(_changedProperties?: PropertyValues): void {}\n}\n","import { html, LitElement } from 'lit';\n\nimport type { Cardinality } from '../lib/expression-result';\n\nexport abstract class QtiVariableDeclaration extends LitElement {\n override render() {\n return html`<slot></slot>`;\n }\n\n protected defaultValues(cardinality: Cardinality) {\n const htmlValues = Array.from(this.querySelectorAll('qti-default-value > qti-value'));\n\n if (htmlValues.length === 0) {\n return null;\n }\n\n const defaultValues = htmlValues.map(n => n.innerHTML.trim());\n if (defaultValues.length > 1 || cardinality === 'multiple' || cardinality === 'ordered') {\n return defaultValues;\n }\n return defaultValues[0];\n }\n}\n","import { consume } from '@lit/context';\nimport { css, html, LitElement } from 'lit';\nimport { state } from 'lit/decorators.js';\n\nimport { itemContext } from '../context/item.context';\nimport { qtiContext } from '../context/qti.context';\nimport { testContext } from '../context/test.context';\n\nimport type { ItemContext } from '../context/types/item.types';\nimport type { QtiContext, QtiContextType } from '../context/qti.context';\nimport type { ResponseVariable, VariableDeclaration } from '../lib/variables';\nimport type { TestContext } from '../context/test.context';\n\nexport interface QtiExpressionBase<T> {\n // get assessmentItem(): QtiAssessmentItem;\n\n // getVariables(): VariableDeclaration<number | string | (number | string)[] | null>[];\n calculate(): Readonly<T>;\n}\n\nexport abstract class QtiExpression<T> extends LitElement implements QtiExpressionBase<T> {\n @state()\n protected result: any;\n\n /*\n * Written here rather than imported from a .css file, and that is a packaging constraint rather\n * than a style preference.\n *\n * The rule used to live in qti-expression.css, imported with Vite's inline-stylesheet query so\n * DevTools could show source-file provenance. That query is a VITE specifier, and tsc copies it\n * verbatim into dist — so the published package shipped an import only a Vite-based consumer\n * could resolve. Every other consumer broke on it: plain Node, tsx, any non-Vite bundler. It was\n * the single such specifier reachable from this package, and it took down QTI-Editor's schema\n * check, which loads the components under tsx to build the real ProseMirror schema\n * (ERR_UNKNOWN_FILE_EXTENSION on a file that has nothing to do with schemas).\n *\n * A `build:assets` step used to copy the .css into dist beside it. That went too — it existed\n * only to give the unresolvable import something to point at.\n *\n * Two lines of CSS are not worth a dist that only one bundler can consume. If this ever grows\n * into a real stylesheet, give it a `.styles.ts` exporting a `css` template — the house pattern\n * everywhere else in this repo — rather than reintroducing a bundler-specific import.\n *\n * The element renders a debug <pre> of its computed result plus a <slot>; hiding the slot is all\n * the styling it has ever had.\n */\n static override styles = css`\n slot {\n display: none;\n }\n `;\n\n override render() {\n return html`<pre>${JSON.stringify(this.result, null, 2)}</pre>\n <slot></slot>`;\n }\n\n public calculate(): Readonly<T> {\n this.result = this.getResult();\n return this.result;\n }\n\n protected getResult(): Readonly<T> {\n throw new Error('Not implemented');\n }\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n protected context?: ItemContext;\n\n @consume({ context: qtiContext, subscribe: true })\n @state()\n protected qtiContext?: QtiContext;\n\n @consume({ context: testContext, subscribe: true })\n @state()\n protected _testContext?: TestContext;\n\n /**\n * Resolve a declared variable from the closest available scope: item-level\n * first, then the test-level outcome variables. So an expression used in an\n * assessmentTest's outcome processing can reference a test-level outcome\n * (e.g. a total set earlier in the same run) — which the QTI variable\n * expression is specified to do. Returns null when unresolved rather than\n * throwing, so callers degrade gracefully.\n */\n protected resolveVariable(identifier: string): VariableDeclaration<string | string[] | null> | null {\n return (\n this.context?.variables.find(v => v.identifier === identifier) ??\n this._testContext?.testOutcomeVariables?.find(v => v.identifier === identifier) ??\n null\n );\n }\n\n getVariables = (): (ResponseVariable | VariableDeclaration<QtiContextType>)[] =>\n // FIXME: if this itself is multiple, this will never enter the qti-multiple switch\n // See this example here: https://github.com/1EdTech/qti-examples/blob/master/qtiv3-examples/packaging/items/Example05-feedbackBlock-adaptive.xml\n\n Array.from(this.children)\n .map((e: Element) => {\n console.debug('getVariables', e.tagName.toLowerCase());\n switch (e.tagName.toLowerCase()) {\n case 'qti-base-value': {\n return {\n baseType: e.getAttribute('base-type'),\n value: e.textContent.trim(),\n cardinality: 'single'\n } as ResponseVariable;\n }\n case 'qti-variable': {\n const identifier = e.getAttribute('identifier') || '';\n\n // Special handling for QTI_CONTEXT\n if (identifier === 'QTI_CONTEXT') {\n if (!this.qtiContext?.QTI_CONTEXT) {\n console.warn('QTI_CONTEXT not available');\n return {\n identifier: 'QTI_CONTEXT',\n baseType: 'record',\n value: this.qtiContext.QTI_CONTEXT,\n cardinality: 'record',\n type: 'context'\n } as VariableDeclaration<QtiContextType>;\n }\n return {\n identifier: 'QTI_CONTEXT',\n baseType: 'record',\n value: this.qtiContext.QTI_CONTEXT,\n cardinality: 'record',\n type: 'context'\n } as VariableDeclaration<QtiContextType>;\n }\n\n return this.resolveVariable(identifier);\n }\n case 'qti-multiple': {\n const multiple = e as QtiExpression<ResponseVariable[]>;\n\n const values = multiple.getResult();\n console.debug('values', values);\n if (values?.length > 0) {\n return {\n identifier: '',\n baseType: values[0].baseType,\n value: values.map(v => v.value),\n cardinality: 'multiple',\n type: 'response'\n } as ResponseVariable;\n }\n return null;\n }\n case 'qti-ordered': {\n const multiple = e as QtiExpression<ResponseVariable[]>;\n const values = multiple.getResult();\n if (values?.length > 0) {\n return {\n identifier: '',\n baseType: values[0].baseType,\n value: values.map(v => v.value),\n cardinality: 'ordered',\n type: 'response'\n } as ResponseVariable;\n }\n return null;\n }\n case 'qti-repeat': {\n const repeat = e as QtiExpression<ResponseVariable[]>;\n const values = repeat.getResult();\n if (values?.length > 0) {\n return values;\n }\n return null;\n }\n case 'qti-correct': {\n const identifier = e.getAttribute('identifier') || '';\n const responseVariable: ResponseVariable =\n this.context?.variables?.find(v => v.identifier === identifier) || null;\n return {\n baseType: responseVariable.baseType,\n value: responseVariable.correctResponse,\n cardinality: responseVariable.cardinality\n } as ResponseVariable;\n }\n default: {\n // added for use of qti-equal-rounded\n try {\n const expression = e as QtiExpression<number>;\n const value = expression.getResult();\n return {\n baseType: 'integer',\n value: value?.toString() || null,\n cardinality: 'single'\n } as ResponseVariable;\n } catch (error) {\n console.warn('default not sufficient');\n }\n return null;\n }\n }\n })\n .flatMap(v => (Array.isArray(v) ? v : [v]))\n .filter(v => v !== null);\n}\n","import { QtiExpression } from './qti-expression';\n\nexport abstract class QtiConditionExpression extends QtiExpression<boolean> {\n public override calculate(): Readonly<boolean> {\n this.result = this.getResult();\n return this.result;\n }\n\n public override getResult(): Readonly<boolean> {\n throw new Error('Not implemented');\n }\n}\n","export const decimalSeparator = () => {\n return new Intl.NumberFormat().format(0.1).replace(/\\d/g, '');\n};\n\nexport const convertNumberToUniversalFormat = (number: number | string) => {\n // check if type is string\n if (typeof number === 'string') {\n return number;\n }\n const dSep = decimalSeparator();\n if (dSep === '.') {\n return number.toLocaleString();\n } else {\n return number.toString().replace('.', '').replace(dSep, '.');\n }\n};\n\nexport function IsNullOrUndefined(value: unknown) {\n return value === null || value === undefined;\n}\n\nexport function removeDoubleSlashes(str: string) {\n const singleForwardSlashes = str\n .replace(/([^:]\\/)\\/+/g, '$1')\n .replace(/\\/\\//g, '/')\n .replace('http:/', 'http://')\n .replace('https:/', 'https://');\n return singleForwardSlashes;\n}\n","import { consume } from '@lit/context';\nimport { LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { computedContext } from '../context/computed.context';\nimport { itemContext } from '../context/item.context';\nimport { IsNullOrUndefined } from '../utils/utils';\n\nimport type { ComputedContext } from '../context/types/computed.types';\nimport type { ItemContext } from '../context/types/item.types';\n\nexport abstract class QtiFeedback extends LitElement {\n @property({ type: String, attribute: 'show-hide' })\n protected showHide: 'show' | 'hide' = 'show';\n\n @property({ type: String, attribute: 'outcome-identifier' })\n public outcomeIdentifier: string;\n\n @property({ type: String })\n protected identifier: string;\n\n @property({ type: String, attribute: false })\n public showStatus: string;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n private _context?: ItemContext;\n\n @consume({ context: computedContext, subscribe: true })\n @state()\n private _computedContext?: ComputedContext;\n\n public override connectedCallback() {\n super.connectedCallback();\n this.dispatchEvent(\n new CustomEvent<QtiFeedback>('qti-register-feedback', {\n bubbles: true,\n composed: true,\n detail: this\n })\n );\n }\n\n public checkShowFeedback(outcomeIdentifier: string) {\n const outcomeVariable = this._context.variables.find(v => v.identifier === outcomeIdentifier) || null;\n if (this.outcomeIdentifier !== outcomeIdentifier || !outcomeVariable) return;\n let isFound = false;\n if (Array.isArray(outcomeVariable.value)) {\n isFound = outcomeVariable.value.includes(this.identifier);\n } else {\n isFound =\n (!IsNullOrUndefined(this.identifier) &&\n !IsNullOrUndefined(outcomeVariable?.value) &&\n this.identifier === outcomeVariable.value) ||\n false;\n }\n\n this.#showFeedback(isFound);\n }\n\n #showFeedback(value: boolean) {\n if (!this.#sessionControlAllowsFeedback()) {\n this.showStatus = 'off';\n return;\n }\n this.showStatus = (value && this.showHide === 'show') || (!value && this.showHide === 'hide') ? 'on' : 'off';\n }\n\n /**\n * The QTI `show-feedback` constraint governs exactly one state: after the end of\n * the last attempt. Up to that point the spec requires any applicable feedback to\n * be shown — \"a value of max-attempts greater than 1, by definition, indicates\n * that any applicable feedback must be shown\" — and only \"once the maximum number\n * of allowed attempts have been used (or for adaptive items, completionStatus has\n * been set to completed)\" does `show-feedback` decide.\n *\n * This only ever forces feedback off, so `show-feedback` being true settles it:\n * there is no state in which the constraint hides feedback. It defaults to\n * false, and an absent value suppresses once the attempts are gone.\n *\n * That leaves one question — is the item out of attempts? — and the two item\n * kinds answer it from different variables, so each reads only its own.\n */\n #sessionControlAllowsFeedback(): boolean {\n if (!this._computedContext) return true;\n const activeItem = this._computedContext.testParts\n ?.find(tp => tp.active)\n ?.sections.flatMap(s => s.items)\n .find(i => i.active);\n if (!activeItem || activeItem.showFeedback) return true;\n\n // Adaptive items ignore max-attempts: \"the number of attempts is limited by\n // the value of the completionStatus built-in outcome variable\".\n if (activeItem.adaptive) return activeItem.completionStatus !== 'completed';\n\n // `max-attempts=\"0\"` is \"no limit\", so the last attempt never arrives.\n const maxAttempts = activeItem.maxAttempts ?? 1;\n if (maxAttempts <= 0) return true;\n\n const numAttempts = Number(this._context?.variables?.find(v => v.identifier === 'numAttempts')?.value) || 0;\n return numAttempts < maxAttempts;\n }\n}\n","/**\n * Canonical `response=\"...\"` / `correct-response=\"...\"` attribute codec.\n *\n * Authors put a single string on an interaction element. This module is the\n * single source of truth for how that string parses into the runtime's\n * internal value AND how an editor serializes the internal value back to the\n * attribute. Both `@qti-components/*` interactions and `@citolab/prose-qti`\n * (the editor) import from here — no per-codebase parsers, no drift.\n *\n * The two attributes share the same grammar; the codec is agnostic about\n * which of them is being parsed.\n *\n * ---\n *\n * Format reference (per interaction):\n *\n * | Interaction | base-type | cardinality | attribute value |\n * |----------------------|---------------|----------------------|---------------------------|\n * | choice | identifier | single / multiple | \"A\" / \"A,B,C\" |\n * | inline-choice | identifier | single | \"Y\" |\n * | hottext | identifier | single / multiple | \"h1\" / \"h1,h2\" |\n * | hotspot | identifier | single / multiple | \"spot1\" / \"spot1,spot2\" |\n * | order | identifier | ordered | \"a,b,c\" (order matters) |\n * | graphic-order | identifier | ordered | \"spot1,spot2,spot3\" |\n * | match | directedPair | multiple | \"src1 tgt1,src2 tgt2\" |\n * | associate | directedPair | multiple | \"A B,C D\" |\n * | gap-match | directedPair | multiple | \"gtext1 gap1,...\" |\n * | graphic-associate | directedPair | multiple | \"spot1 spot2,...\" |\n * | graphic-gap-match | directedPair | multiple | \"gimg1 spot1,...\" |\n * | select-point | point | single / multiple | \"100 150\" / \"100 150,…\" |\n * | slider | integer | single | \"50\" |\n * | text-entry | string | single | \"paris\" |\n *\n * Rules:\n * - Comma `,` separates VALUES (different identifiers / pairs / points).\n * - Space ` ` separates PARTS within one value (pair members or point coords).\n * - Each value is trimmed on parse.\n * - No escape mechanism. Identifiers that contain commas cannot round-trip.\n */\n\n// ─── parsed shape ────────────────────────────────────────────────────────────\n\n/** Canonical parsed value of a `response` / `correct-response` attribute. */\nexport type ResponseValue = string | string[] | null;\n\n// ─── per-shape branded types (advisory at compile time) ──────────────────────\n\n/** Identifier literal — opaque QTI identifier (e.g. `\"choice1\"`). */\nexport type Identifier = string;\n\n/** Directed pair literal — `\"sourceId targetId\"`. Used by match / associate / gap-match. */\nexport type DirectedPair = `${string} ${string}`;\n\n/** Point literal — `\"x y\"` integer coordinates. Used by select-point / graphic-*. */\nexport type Point = `${number} ${number}`;\n\n// ─── attribute-level parser / serializer ─────────────────────────────────────\n\n/**\n * Parse a raw `response` / `correct-response` attribute string into the\n * canonical value.\n *\n * - `null` / `undefined` / empty → `null`\n * - no comma → trimmed string\n * - one or more commas → trimmed array (single-element collapses to a string)\n */\nexport function parseResponseAttribute(raw: string | null | undefined): ResponseValue {\n if (raw == null) return null;\n if (!raw.includes(',')) {\n const trimmed = raw.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n const tokens = raw\n .split(',')\n .map(token => token.trim())\n .filter(token => token.length > 0);\n if (tokens.length === 0) return null;\n if (tokens.length === 1) return tokens[0];\n return tokens;\n}\n\n/**\n * Serialize a canonical value back to the attribute string. Returns `null` for\n * empty inputs so a Lit `@property({ reflect: true })` drops the attribute.\n */\nexport function serializeResponseAttribute(value: ResponseValue): string | null {\n if (value == null) return null;\n if (Array.isArray(value)) {\n const tokens = value.map(token => token.trim()).filter(token => token.length > 0);\n return tokens.length > 0 ? tokens.join(',') : null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\n// ─── value-shape helpers (per interaction type) ──────────────────────────────\n\n/**\n * Iterate over the comma-separated entries in a response value, regardless of\n * whether the caller has the raw string, the parsed string, or a string[].\n * Yields trimmed non-empty entries.\n */\nexport function* iterResponseValues(raw: ResponseValue): Generator<string> {\n if (raw == null) return;\n if (Array.isArray(raw)) {\n for (const v of raw) {\n const t = v.trim();\n if (t) yield t;\n }\n return;\n }\n if (!raw.includes(',')) {\n const t = raw.trim();\n if (t) yield t;\n return;\n }\n for (const v of raw.split(',')) {\n const t = v.trim();\n if (t) yield t;\n }\n}\n\n/** Parse a directed-pair value into `{ source, target }`. Throws on malformed input. */\nexport function parsePair(value: string): { source: string; target: string } {\n const [source, target, ...rest] = value.trim().split(/\\s+/);\n if (!source || !target || rest.length > 0) {\n throw new Error(`malformed directed-pair value: \"${value}\" (expected \"source target\")`);\n }\n return { source, target };\n}\n\n/** Serialize a directed pair to canonical `\"source target\"` form. */\nexport function serializePair(source: string, target: string): DirectedPair {\n return `${source} ${target}`;\n}\n\n/** Parse a point value into `{ x, y }`. Throws on malformed input. */\nexport function parsePoint(value: string): { x: number; y: number } {\n const [xStr, yStr, ...rest] = value.trim().split(/\\s+/);\n const x = Number(xStr);\n const y = Number(yStr);\n if (!Number.isFinite(x) || !Number.isFinite(y) || rest.length > 0) {\n throw new Error(`malformed point value: \"${value}\" (expected \"x y\" numeric coords)`);\n }\n return { x, y };\n}\n\n/** Serialize a point to canonical `\"x y\"` form. */\nexport function serializePoint(x: number, y: number): Point {\n return `${x} ${y}`;\n}\n\n// ─── Lit converter factory ───────────────────────────────────────────────────\n\n/**\n * Ready-to-use Lit `converter` for `response` / `correct-response` attributes.\n * Assign to the `converter` option:\n *\n * @property({ attribute: 'response', converter: responseAttributeConverter({ emptyAs: [] }) })\n *\n * `emptyAs` picks the sentinel returned when the attribute is absent / blank.\n * Three sentinels exist across the codebase — match the one your call site\n * already uses. Future work may normalize to a single sentinel.\n *\n * - '' (empty string) — ChoicesMixin convention\n * - [] — DragDropSlottedMixin / graphic-associate convention\n * - null — base interaction / select-point convention\n *\n * On the serialize side, the `emptyAs` value roundtrips back to `null` so a\n * `reflect: true` property drops the attribute rather than emitting `\"\"`.\n */\nexport function responseAttributeConverter<E extends '' | null | readonly unknown[]>(opts: {\n emptyAs: E;\n}): {\n fromAttribute: (value: string | null) => ResponseValue | E;\n toAttribute: (value: ResponseValue | E) => string | null;\n} {\n const { emptyAs } = opts;\n const isEmptySentinel = (value: unknown): boolean =>\n value === emptyAs || value == null || value === '' || (Array.isArray(value) && value.length === 0);\n\n return {\n fromAttribute: (value: string | null): ResponseValue | E => {\n const parsed = parseResponseAttribute(value);\n return parsed === null ? emptyAs : parsed;\n },\n toAttribute: (value: ResponseValue | E): string | null => {\n if (isEmptySentinel(value)) return null;\n return serializeResponseAttribute(value as ResponseValue);\n }\n };\n}\n","import { LitElement } from 'lit';\n\n/**\n * Interface for any object that can process QTI rules\n */\nexport interface QtiRuleBase {\n process(): any;\n}\n\n/**\n * Abstract base class for QTI rule DOM elements\n */\nexport abstract class QtiRuleElement extends LitElement implements QtiRuleBase {\n abstract process(): any;\n}\n","import type { BaseType } from '../lib/expression-result';\n\nexport class ScoringHelper {\n /**\n * Checks if a given point is within a specified area.\n * @param point The point to test, represented as a string \"x y\" (e.g., \"102 113\").\n * @param areaKey The area definition, including shape and coordinates (e.g., \"circle,102,113,16\").\n * @param baseType The base type of the response, must be \"point\" for this method to proceed.\n * @returns True if the point is within the area; false otherwise.\n */\n public static isPointInArea(point: string, areaKey: string, baseType: string): boolean {\n if (baseType !== 'point') {\n console.warn(`Base type ${baseType} is not supported for point area mapping.`);\n return false;\n }\n\n // Parse the point as x and y coordinates\n const [px, py] = point.split(' ').map(Number);\n\n // Parse the area definition\n const [shape, ...coords] = areaKey.split(',');\n const coordinates = coords.map(Number);\n\n switch (shape.toLowerCase()) {\n case 'circle':\n case 'default': {\n const [cx, cy, radius] = coordinates;\n if (coordinates.length !== 3) {\n console.warn(`Invalid circle definition: ${areaKey}`);\n return false;\n }\n const distance = Math.sqrt((px - cx) ** 2 + (py - cy) ** 2);\n return distance <= radius;\n }\n\n case 'rect': {\n const [x1, y1, x2, y2] = coordinates;\n if (coordinates.length !== 4) {\n console.warn(`Invalid rectangle definition: ${areaKey}`);\n return false;\n }\n return px >= x1 && px <= x2 && py >= y1 && py <= y2;\n }\n\n case 'ellipse': {\n const [cx, cy, rx, ry] = coordinates;\n if (coordinates.length !== 4) {\n console.warn(`Invalid ellipse definition: ${areaKey}`);\n return false;\n }\n // Ellipse equation: ((px - cx)² / rx²) + ((py - cy)² / ry²) <= 1\n const normalizedX = (px - cx) ** 2 / rx ** 2;\n const normalizedY = (py - cy) ** 2 / ry ** 2;\n return normalizedX + normalizedY <= 1;\n }\n\n case 'poly': {\n if (coordinates.length < 6 || coordinates.length % 2 !== 0) {\n console.warn(`Invalid polygon definition: ${areaKey}`);\n return false;\n }\n const vertices = [];\n for (let i = 0; i < coordinates.length; i += 2) {\n vertices.push({ x: coordinates[i], y: coordinates[i + 1] });\n }\n return this.isPointInPolygon({ x: px, y: py }, vertices);\n }\n\n default:\n console.warn(`Unsupported shape type: ${shape}`);\n return false;\n }\n }\n\n /**\n * Checks if a point is inside a polygon using the ray-casting algorithm.\n * @param point The point to test.\n * @param vertices The vertices of the polygon in order (array of {x, y} objects).\n * @returns True if the point is inside the polygon; false otherwise.\n */\n static isPointInPolygon(point: { x: number; y: number }, vertices: { x: number; y: number }[]): boolean {\n let inside = false;\n for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {\n const xi = vertices[i].x,\n yi = vertices[i].y;\n const xj = vertices[j].x,\n yj = vertices[j].y;\n\n const intersect = yi > point.y !== yj > point.y && point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;\n\n if (intersect) inside = !inside;\n }\n return inside;\n }\n\n public static compareSingleValues(value1: Readonly<string>, value2: Readonly<string>, baseType: BaseType): boolean {\n switch (baseType) {\n case 'identifier':\n case 'string':\n return value1 === value2;\n case 'integer': {\n const int1 = parseInt(value1, 10);\n const int2 = parseInt(value2, 10);\n if (!isNaN(int1) && !isNaN(int2)) {\n return int1 === int2;\n } else {\n console.error(`Cannot convert ${value1} and/or ${value2} to int.`);\n }\n break;\n }\n case 'float': {\n const float1 = parseFloat(value1);\n const float2 = parseFloat(value2);\n if (!isNaN(float1) && !isNaN(float2)) {\n return float1 === float2;\n } else {\n console.error(`couldn't convert ${value1} and/or ${value2} to float.`);\n }\n break;\n }\n case 'pair':\n case 'directedPair': {\n const pair1 = value1.split(' ').sort();\n const pair2 = value2.split(' ').sort();\n if (pair1.length === 2 && pair2.length === 2) {\n if (baseType === 'pair') {\n pair1.sort();\n pair2.sort();\n }\n return pair1.join(' ') === pair2.join(' ');\n } else {\n console.error(`compared two pair but one of the values does not have 2 values: 1: ${value1} 2: ${value2}`);\n }\n break;\n }\n }\n\n return false;\n }\n}\n","import { qtiBaseElements } from './elements';\nimport { installCustomStateSetFallback } from './utils/custom-state-set';\n\n// Before any element is defined, so the patched `attachInternals` is in place by\n// the time the first interaction upgrades. No-op where `states` works natively.\ninstallCustomStateSetFallback();\n\nfor (const { tag, ctor } of qtiBaseElements) {\n if (!customElements.get(tag)) {\n customElements.define(tag, ctor);\n }\n}\n"],"mappings":"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","names":["state","createContext","createContext","createContext","createContext","createContext","createContext","createContext","css","css","state","LitElement","consume","css","html","LitElement","LitElement","css","html","__decorate","consume","consume","LitElement","property","state","LitElement","__decorate","property","consume","state","LitElement"]}
@@ -9,7 +9,7 @@ import {
9
9
  QtiVariableDeclaration,
10
10
  itemContext,
11
11
  itemContextVariables
12
- } from "./chunk-EKXZI26R.js";
12
+ } from "./chunk-WCWJPIUQ.js";
13
13
 
14
14
  // ../qti-elements/dist/components/qti-assessment-item/qti-assessment-item.js
15
15
  import { provide } from "@lit/context";
@@ -269,7 +269,7 @@ var QtiAssessmentItem = class extends LitElement {
269
269
  this.dispatchEvent(new CustomEvent("qti-item-context-updated", {
270
270
  bubbles: true,
271
271
  composed: true,
272
- detail: { itemContext: this._context }
272
+ detail: { itemContext: this._context, responseProcessed: true }
273
273
  }));
274
274
  return canProcess;
275
275
  }
@@ -1541,4 +1541,4 @@ export {
1541
1541
  QtiTemplateProcessing,
1542
1542
  qtiContentElements
1543
1543
  };
1544
- //# sourceMappingURL=chunk-6XJUP55A.js.map
1544
+ //# sourceMappingURL=chunk-WKWCOV5P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../qti-elements/src/components/qti-assessment-item/qti-assessment-item.ts","../../qti-elements/src/components/qti-assessment-stimulus-ref/qti-assessment-stimulus-ref.ts","../../qti-elements/src/components/qti-companion-materials-info/qti-companion-materials-info.ts","../../qti-elements/src/components/qti-content-body/qti-content-body.ts","../../qti-elements/src/components/qti-context-declaration/qti-context-declaration.ts","../../qti-elements/src/components/qti-custom-operator/qti-custom-operator.ts","../../qti-elements/src/components/qti-feedback-block/qti-feedback-block.ts","../../qti-elements/src/components/qti-feedback-inline/qti-feedback-inline.ts","../../qti-elements/src/components/qti-item-body/qti-item-body.ts","../../qti-elements/src/components/qti-item-body/qti-item-body.styles.ts","../../qti-elements/src/components/qti-modal-feedback/qti-modal-feedback.ts","../../qti-elements/src/components/qti-outcome-declaration/qti-outcome-declaration.ts","../../qti-elements/src/components/qti-response-declaration/qti-response-declaration.ts","../../qti-elements/src/components/qti-response-processing/qti-response-processing.ts","../../qti-elements/src/internal/template-strings.ts","../../qti-elements/src/components/qti-rubric-block/qti-rubric-block.ts","../../qti-elements/src/components/qti-stylesheet/qti-stylesheet.ts","../../qti-elements/src/components/qti-template-constraint/qti-template-constraint.ts","../../qti-elements/src/components/qti-template-declaration/qti-template-declaration.ts","../../qti-elements/src/components/qti-template-processing/qti-template-processing.ts","../../qti-elements/src/elements.ts"],"sourcesContent":["import { provide } from '@lit/context';\nimport { LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { itemContext, itemContextVariables } from '@qti-components/base';\nimport { watch } from '@qti-components/utilities';\n\nimport type { QtiTemplateProcessing } from '../qti-template-processing/qti-template-processing.js';\nimport type { InteractionChangedDetails, OutcomeChangedDetails } from '../../internal/event-types.ts';\nimport type { QtiFeedback, ResponseInteraction } from '@qti-components/base';\nimport type { RegisteredInteraction } from '@qti-components/base';\nimport type { VariableDeclaration, VariableValue } from '@qti-components/base';\nimport type { OutcomeVariable, ResponseVariable, TemplateVariable } from '@qti-components/base';\nimport type { QtiResponseProcessing } from '../qti-response-processing/qti-response-processing.ts';\nimport type QtiRegisterVariable from '../../internal/events/qti-register-variable.ts';\nimport type { ItemContext } from '@qti-components/base';\n\n/**\n * @summary The qti-assessment-item element contains all the other QTI 3 item structures.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.dltnnj87l0yj\n *\n * @dependency qti-feedback\n * @dependency qti-responseprocessing\n *\n * @event qti-item-context-updated - Emitted when through a user action the itemContext is updated,\n * typically on interaction with the interactions, or calling response processing.\n */\n\nexport class QtiAssessmentItem extends LitElement {\n #itemTitle: string | undefined;\n #templateProcessing: QtiTemplateProcessing | null = null;\n\n @property({ type: String }) identifier: string = '';\n @property({ type: String }) adaptive: 'true' | 'false' = 'false';\n @property({ type: String }) timeDependent: 'true' | 'false' | null = null;\n\n @property({ type: String })\n override get title(): string {\n return this.#itemTitle;\n }\n override set title(value: string) {\n this.#itemTitle = value;\n this.removeAttribute('title');\n this.setAttribute('data-title', value);\n }\n\n @property({ type: Boolean }) disabled: boolean;\n @watch('disabled', { waitUntilFirstUpdate: true })\n protected _handleDisabledChange = (_: boolean, disabled: boolean) => {\n this.interactionElements.forEach(ch => (ch.disabled = disabled));\n };\n\n @property({ type: Boolean }) readonly: boolean;\n @watch('readonly', { waitUntilFirstUpdate: true })\n protected _handleReadonlyChange = (_: boolean, readonly: boolean) =>\n this.interactionElements.forEach(ch => (ch.readonly = readonly));\n\n @provide({ context: itemContext })\n private _context: ItemContext = {\n variables: itemContextVariables\n };\n\n /**\n * Sets the identifier for the assessment item reference if this item is in a test.\n *\n * @param identifier - The identifier for the assessment item reference.\n */\n public set assessmentItemRefId(identifier: string) {\n this._context = { ...this._context, identifier };\n }\n\n public get assessmentItemRefId(): string {\n return this._context.identifier;\n }\n\n public get variables(): VariableValue<string | string[] | null>[] {\n return this._context.variables.map(v => ({\n identifier: v.identifier,\n value: v.value,\n type: v.type,\n // add externalscored, a fixed prop to the test, so the testcontext can read and decide how to score this item\n ...(v.type === 'outcome' && v.identifier === 'SCORE'\n ? { externalScored: (v as OutcomeVariable).externalScored }\n : {})\n }));\n }\n\n public set variables(value: VariableValue<string | string[] | null>[]) {\n if (!Array.isArray(value) || value.some(v => !('identifier' in v))) {\n console.warn('variables property should be an array of VariableDeclaration');\n return;\n }\n this._context = {\n ...this._context,\n variables: this._context.variables.map(variable => {\n const matchingValue = value.find(v => v.identifier === variable.identifier);\n if (matchingValue) {\n return {\n ...variable,\n ...matchingValue,\n interpolationTable: (variable as OutcomeVariable).interpolationTable\n };\n }\n return variable;\n })\n };\n\n this._context.variables.forEach(variable => {\n if (variable.type === 'response') {\n const interactionElement = this.interactionElements.find(\n (el: RegisteredInteraction) => el.responseIdentifier === variable.identifier\n );\n if (interactionElement) {\n interactionElement.response = variable.value as string | string[];\n }\n }\n });\n\n this.variables.forEach(variable => {\n if (variable.type === 'outcome') {\n this.#feedbackElements.forEach(fe => fe.checkShowFeedback(variable.identifier));\n }\n });\n }\n\n public get state(): ItemContext['state'] {\n return this._context.state;\n }\n\n public set state(value: ItemContext['state']) {\n this._context = {\n ...this._context,\n state: value ? { ...value } : undefined\n };\n }\n\n #initialContext: Readonly<ItemContext> = { ...this._context, variables: this._context.variables };\n #feedbackElements: QtiFeedback[] = [];\n /** Registered candidate-input interactions. Correction packages may extend their presentation behavior. */\n protected interactionElements: RegisteredInteraction[] = [];\n\n /** @deprecated use variables property instead */\n set responses(myResponses: ResponseInteraction[]) {\n if (myResponses) {\n for (const response of myResponses) {\n const responseVariable = this.getResponse(response.responseIdentifier);\n if (responseVariable) {\n this.updateResponseVariable(response.responseIdentifier, response.response);\n }\n\n const interaction: RegisteredInteraction | undefined = this.interactionElements.find(\n i => i.getAttribute('response-identifier') === response.responseIdentifier\n );\n if (interaction) {\n interaction.response = response.response;\n }\n }\n }\n }\n\n override render() {\n return html`<slot></slot>`;\n }\n\n override connectedCallback(): void {\n this.#attachEventListeners();\n super.connectedCallback();\n this.updateComplete.then(() => {\n this.dispatchEvent(\n new CustomEvent<QtiAssessmentItem>('qti-assessment-item-connected', {\n bubbles: true,\n composed: true,\n detail: this\n })\n );\n this.#processTemplates();\n });\n }\n\n override disconnectedCallback(): void {\n this.#removeEventListeners();\n super.disconnectedCallback();\n }\n\n #attachEventListeners() {\n this.addEventListener('qti-register-variable', this.#handleRegisterVariable);\n this.addEventListener('qti-register-feedback', this.#handleRegisterFeedback);\n this.addEventListener('qti-register-interaction', this.#handleRegisterInteraction);\n this.addEventListener('end-attempt', this.#handleEndAttempt);\n this.addEventListener('qti-set-outcome-value', this.#handleSetOutcomeValue);\n this.addEventListener('qti-set-template-value', this.#handleSetTemplateValue);\n this.addEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);\n this.addEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);\n }\n\n #removeEventListeners() {\n this.removeEventListener('qti-register-variable', this.#handleRegisterVariable);\n this.removeEventListener('qti-register-feedback', this.#handleRegisterFeedback);\n this.removeEventListener('qti-register-interaction', this.#handleRegisterInteraction);\n this.removeEventListener('end-attempt', this.#handleEndAttempt);\n this.removeEventListener('qti-set-outcome-value', this.#handleSetOutcomeValue);\n this.removeEventListener('qti-set-template-value', this.#handleSetTemplateValue);\n this.removeEventListener('qti-set-correct-response', this.#handleSetCorrectResponse);\n this.removeEventListener('qti-interaction-response', this.#handleUpdateResponseVariable);\n }\n\n #handleRegisterVariable = (e: QtiRegisterVariable) => {\n e.stopImmediatePropagation();\n this._context = { ...this._context, variables: [...this._context.variables, e.detail.variable] };\n this.#initialContext = this._context;\n e.stopPropagation();\n };\n\n #handleRegisterFeedback = (e: CustomEvent<QtiFeedback>) => {\n e.stopImmediatePropagation();\n const feedbackElement = e.detail;\n this.#feedbackElements.push(feedbackElement);\n const numAttempts = Number(this._context.variables.find(v => v.identifier === 'numAttempts')?.value) || 0;\n if (numAttempts > 0) {\n feedbackElement.checkShowFeedback(feedbackElement.outcomeIdentifier);\n }\n };\n\n #handleRegisterInteraction = (e: CustomEvent<{ interaction: string; interactionElement: RegisteredInteraction }>) => {\n e.stopImmediatePropagation();\n this.interactionElements.push(e.detail.interactionElement);\n };\n\n #handleEndAttempt = (e: CustomEvent<{ responseIdentifier: string; countAttempt: boolean }>) => {\n e.stopImmediatePropagation();\n const { responseIdentifier, countAttempt } = e.detail;\n this.validate();\n this.updateResponseVariable(responseIdentifier, 'true');\n this.processResponse(countAttempt);\n };\n\n #handleSetOutcomeValue = (e: CustomEvent<{ outcomeIdentifier: string; value: string | string[] }>) => {\n e.stopImmediatePropagation();\n const { outcomeIdentifier, value } = e.detail;\n this.updateOutcomeVariable(outcomeIdentifier, value);\n e.stopPropagation();\n };\n\n #handleSetTemplateValue = (e: CustomEvent<{ templateIdentifier: string; value: string | string[] | null }>) => {\n e.stopImmediatePropagation();\n const { templateIdentifier, value } = e.detail;\n this.updateTemplateVariable(templateIdentifier, value ?? undefined);\n e.stopPropagation();\n };\n\n #handleSetCorrectResponse = (e: CustomEvent<{ responseIdentifier: string; value: string | string[] | null }>) => {\n e.stopImmediatePropagation();\n const { responseIdentifier, value } = e.detail;\n this.updateCorrectResponse(responseIdentifier, value ?? undefined);\n e.stopPropagation();\n };\n\n #handleUpdateResponseVariable = (e: CustomEvent<ResponseInteraction>) => {\n e.stopImmediatePropagation();\n\n const { responseIdentifier, response, state } = e.detail;\n this.updateResponseVariable(responseIdentifier, response);\n if (state !== undefined) {\n this._context = {\n ...this._context,\n state: {\n ...(this._context.state || {}),\n [responseIdentifier]: state\n }\n };\n }\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n };\n\n async #processTemplates(): Promise<void> {\n const templateDeclarations = Array.from(this.querySelectorAll<LitElement>('qti-template-declaration'));\n if (templateDeclarations.length > 0) {\n await Promise.all(templateDeclarations.map(declaration => declaration.updateComplete));\n await Promise.resolve();\n }\n\n this.#templateProcessing = this.querySelector<QtiTemplateProcessing>('qti-template-processing');\n if (this.#templateProcessing) {\n // Run template processing before first presentation\n this.#templateProcessing.process();\n this.#initialContext = { ...this._context, variables: this._context.variables };\n }\n }\n\n public processResponse(countNumAttempts = true, reportValidityAfterScoring = true): boolean {\n this.validate(reportValidityAfterScoring);\n\n if (countNumAttempts) {\n this.updateOutcomeVariable(\n 'numAttempts',\n (+this._context.variables.find(v => v.identifier === 'numAttempts')?.value + 1).toString()\n );\n }\n\n if (this.adaptive === 'false') {\n this.#resetOutcomeVariablesBeforeResponseProcessing();\n }\n\n const responseProcessor = this.querySelector<QtiResponseProcessing>('qti-response-processing');\n const canProcess = !!(responseProcessor && typeof responseProcessor.process === 'function');\n if (canProcess) {\n responseProcessor.process();\n }\n if (this.adaptive === 'false') {\n // if adaptive, completionStatus is set by the processing template\n this.updateOutcomeVariable('completionStatus', this.#getCompletionStatus());\n }\n\n // `responseProcessed` marks this as the end of an attempt (vs. a plain\n // selection, which fires the same event without the flag). Lets listeners\n // react only when an attempt actually ends.\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext; responseProcessed: boolean }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context, responseProcessed: true }\n })\n );\n\n return canProcess;\n }\n\n public resetResponses() {\n this._context = this.#initialContext;\n }\n\n protected getResponse(identifier: string): Readonly<ResponseVariable> {\n return this.getVariable(identifier) as ResponseVariable;\n }\n\n public getOutcome(identifier: string): Readonly<OutcomeVariable> {\n return this.getVariable(identifier) as OutcomeVariable;\n }\n\n protected getVariable(identifier: string): Readonly<VariableDeclaration<string | string[] | null>> {\n return this._context.variables.find(v => v.identifier === identifier) || null;\n }\n\n /** Extension point for presentation packages reacting to a candidate response change. */\n protected afterResponseVariableUpdated(): void {}\n\n // saving privates here: ------------------------------------------------------------------------------\n\n /**\n * Updates the response variable with the specified identifier to the given value.\n *\n * @protected\n *\n * This method is intended for internal use within the class and subclasses.\n * It should not be called externally by third parties.\n *\n * @param identifier - The identifier of the response variable to update.\n * @param value - The new value for the response variable.\n */\n public updateResponseVariable(identifier: string, value: string | string[] | undefined) {\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v => (v.identifier !== identifier ? v : { ...v, value: value }))\n };\n\n this.afterResponseVariableUpdated();\n\n this.dispatchEvent(\n new CustomEvent<InteractionChangedDetails>('qti-interaction-changed', {\n bubbles: true,\n composed: true,\n detail: {\n item: this.identifier,\n responseIdentifier: identifier,\n response: Array.isArray(value) ? [...value] : value\n }\n })\n );\n\n if (this.adaptive === 'false') {\n // if adaptive, completionStatus is set by the processing template\n this.updateOutcomeVariable('completionStatus', this.#getCompletionStatus());\n }\n }\n\n /**\n * Updates the template variable with the specified identifier to the given value.\n */\n public updateTemplateVariable(identifier: string, value: string | string[] | undefined) {\n const templateVariable = this._context.variables.find(v => v.identifier === identifier && v.type === 'template') as\n | TemplateVariable\n | undefined;\n\n if (!templateVariable) {\n console.warn(`Can not set qti-template-identifier: ${identifier}, it is not available`);\n return;\n }\n\n const normalizedValue =\n templateVariable.cardinality === 'single'\n ? Array.isArray(value)\n ? value[0]\n : (value ?? null)\n : value === undefined || value === null\n ? null\n : Array.isArray(value)\n ? value\n : [value];\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier !== identifier\n ? v\n : {\n ...v,\n value: normalizedValue\n }\n )\n };\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n /**\n * Updates the correct response for the specified response variable.\n */\n public updateCorrectResponse(identifier: string, value: string | string[] | undefined) {\n const responseVariable = this.getResponse(identifier);\n\n if (!responseVariable) {\n console.warn(`Can not set correct response for identifier: ${identifier}, it is not available`);\n return;\n }\n\n const normalizedValue =\n responseVariable.cardinality === 'single'\n ? Array.isArray(value)\n ? value[0]\n : (value ?? null)\n : value === undefined || value === null\n ? null\n : Array.isArray(value)\n ? value\n : [value];\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v =>\n v.identifier !== identifier\n ? v\n : {\n ...v,\n correctResponse: normalizedValue\n }\n )\n };\n\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n public setOutcomeVariable(identifier: string, value: string | string[] | undefined) {\n this.updateOutcomeVariable(identifier, value);\n this.dispatchEvent(\n new CustomEvent<{ itemContext: ItemContext }>('qti-item-context-updated', {\n bubbles: true,\n composed: true,\n detail: { itemContext: this._context }\n })\n );\n }\n\n /**\n * Updates the outcome variable with the specified identifier to the given value.\n *\n * @protected\n *\n * This method is intended for internal use within the class and subclasses.\n * It should not be called externally by third parties.\n *\n * @param identifier - The identifier of the response variable to update.\n * @param value - The new value for the response variable.\n */\n public updateOutcomeVariable(identifier: string, value: string | string[] | undefined) {\n const outcomeVariable = this.getOutcome(identifier);\n\n if (!outcomeVariable) {\n console.warn(`Can not set qti-outcome-identifier: ${identifier}, it is not available`);\n return;\n }\n\n this._context = {\n ...this._context,\n variables: this._context.variables.map(v => {\n if (v.identifier !== identifier) {\n return v;\n }\n return {\n ...v,\n value: outcomeVariable.cardinality === 'single' ? value : Array.isArray(value) ? value : [value]\n };\n })\n };\n this.#feedbackElements.forEach(fe => fe.checkShowFeedback(identifier));\n\n this.dispatchEvent(\n new CustomEvent<OutcomeChangedDetails>('qti-outcome-changed', {\n bubbles: true,\n composed: true,\n detail: {\n item: this.identifier,\n outcomeIdentifier: identifier,\n value: this._context.variables.find(v => v.identifier === identifier)?.value\n }\n })\n );\n }\n\n public validate(reportValidity = true): boolean {\n const isValid = this.interactionElements.every(interactionElement => interactionElement.validate());\n\n if (reportValidity) {\n this.reportValidity();\n }\n\n return isValid;\n }\n\n public reportValidity() {\n for (const interactionElement of this.interactionElements) {\n interactionElement.reportValidity();\n }\n }\n\n #getCompletionStatus(): 'completed' | 'incomplete' | 'not_attempted' | 'unknown' {\n const valid = this.validate(false);\n if (valid === true) return 'completed';\n if (valid === false) return 'incomplete';\n return 'not_attempted';\n }\n\n #resetOutcomeVariablesBeforeResponseProcessing(): void {\n this._context = {\n ...this._context,\n variables: this._context.variables.map(variable => {\n if (variable.type !== 'outcome') {\n return variable;\n }\n\n const hasDefaultValue = 'defaultValue' in variable;\n const declaredDefault = hasDefaultValue ? variable.defaultValue : null;\n\n let value = declaredDefault ?? null;\n if (\n (value === null || value === undefined) &&\n (variable.baseType === 'integer' || variable.baseType === 'float')\n ) {\n value = '0';\n }\n\n return {\n ...variable,\n value\n };\n })\n };\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-assessment-item': QtiAssessmentItem;\n }\n}\n","import { LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { qtiTransformItem } from '@qti-components/transformers';\n\nimport type { QtiAssessmentItem } from '../qti-assessment-item/qti-assessment-item';\n\nexport class QtiAssessmentStimulusRefConnectedEvent extends Event {\n public static eventName = 'qti-assessment-stimulus-ref-connected';\n constructor(\n public element: QtiAssessmentStimulusRef,\n public item: QtiAssessmentItem\n ) {\n super(QtiAssessmentStimulusRefConnectedEvent.eventName, { bubbles: true, composed: true, cancelable: true });\n }\n}\n\n/**\n * Represents a custom element for referencing an assessment stimulus.\n */\n\nexport class QtiAssessmentStimulusRef extends LitElement {\n @property({ type: String }) identifier = '';\n @property({ type: String }) href = '';\n\n /**\n * Lifecycle method called when the element is connected to the DOM.\n * First checks if there's a data-stimulus-idref element. If found, loads the stimulus directly.\n * If not found, delegates to the delivery platform via an event.\n */\n public override async connectedCallback(): Promise<void> {\n super.connectedCallback();\n // VERY important to wait for updateComplete to ensure that the stimulusRef is connected after item\n // for the test-navigation to correctly process everything in order\n await this.updateComplete;\n\n const item = this.closest<QtiAssessmentItem>('qti-assessment-item');\n\n const event = new QtiAssessmentStimulusRefConnectedEvent(this, item);\n this.dispatchEvent(event);\n\n const stimulusRef = item?.querySelector(`[data-stimulus-idref=\"${this.identifier}\"]`);\n if (!event.defaultPrevented && stimulusRef) {\n await this.updateStimulusRef(stimulusRef);\n }\n }\n\n /**\n * Loads and appends the stimulus to the specified element.\n * @param stimulusRef - The element to which the stimulus will be appended.\n */\n public async updateStimulusRef(stimulusRef: Element) {\n const stimulus = await qtiTransformItem()\n .load(this.href)\n .then(api => api.htmlDoc());\n if (stimulus) {\n const elements = stimulus.querySelectorAll('qti-stimulus-body, qti-stylesheet');\n stimulusRef.innerHTML = '';\n stimulusRef.append(...elements);\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-assessment-stimulus-ref': QtiAssessmentStimulusRef;\n }\n}\n","import { LitElement } from 'lit';\n\nexport class QtiCompanionMaterialsInfo extends LitElement {\n // static override styles = css`\n // slot {\n // display: hidden;\n // }\n // `;\n // override render() {\n // return html` <slot></slot> `;\n // }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-companion-materials-info': QtiCompanionMaterialsInfo;\n }\n}\n","import { consume } from '@lit/context';\nimport { LitElement, html } from 'lit';\nimport { state } from 'lit/decorators.js';\n\nimport { itemContext } from '@qti-components/base';\n\nimport type { ItemContext, TemplateVariable } from '@qti-components/base';\n\nexport class QtiContentBody extends LitElement {\n @consume({ context: itemContext, subscribe: true })\n @state()\n protected context?: ItemContext;\n\n override render() {\n return html`<slot @slotchange=${this.#expandMathVariables}></slot>`;\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.updateComplete.then(() => this.#expandMathVariables());\n }\n\n protected override updated(changedProperties: Map<string | number | symbol, unknown>): void {\n if (changedProperties.has('context')) {\n this.#expandMathVariables();\n }\n }\n\n #expandMathVariables(): void {\n const mathVariables = new Map<string, string>();\n const templateVariables = (this.context?.variables ?? []).filter(variable => variable.type === 'template');\n\n for (const variable of templateVariables) {\n const templateVariable = variable as TemplateVariable;\n if (\n templateVariable.mathVariable !== true ||\n templateVariable.value === null ||\n templateVariable.value === undefined\n ) {\n continue;\n }\n\n mathVariables.set(templateVariable.identifier, this.#stringifyValue(templateVariable.value));\n }\n\n if (mathVariables.size === 0) {\n return;\n }\n\n const mathIdentifiers = Array.from(this.querySelectorAll('*')).filter(\n element => element.localName.toLowerCase() === 'mi' || element.localName.toLowerCase() === 'mn'\n );\n\n for (const element of mathIdentifiers) {\n const identifier = element.getAttribute('data-qti-math-variable-source') ?? element.textContent?.trim() ?? '';\n const value = mathVariables.get(identifier);\n\n if (!value) {\n continue;\n }\n\n if (element.localName.toLowerCase() === 'mn') {\n element.textContent = value;\n element.setAttribute('data-qti-math-variable-source', identifier);\n continue;\n }\n\n const replacement = document.createElement('mn');\n replacement.textContent = value;\n replacement.setAttribute('data-qti-math-variable-source', identifier);\n element.replaceWith(replacement);\n }\n }\n\n #stringifyValue(value: string | readonly string[] | number | boolean | null): string {\n if (Array.isArray(value)) {\n return value.join(' ');\n }\n\n return value?.toString() ?? '';\n }\n}\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-content-body': QtiContentBody;\n }\n}\n","import { css, LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\n/**\n * @summary The qti-context-declaration element declares context variables for an item.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.qti-context-declaration\n */\n\nexport class QtiContextDeclaration extends LitElement {\n @property({ type: String }) identifier: string = '';\n @property({ type: String }) cardinality: 'single' | 'multiple' | 'ordered' | 'record' = 'record';\n\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-context-declaration': QtiContextDeclaration;\n }\n}\n","import { consume } from '@lit/context';\nimport { LitElement, html } from 'lit';\nimport { state } from 'lit/decorators.js';\n\nimport { itemContext } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\nimport type { Calculate } from '@qti-components/base';\nimport type { ItemContext } from '@qti-components/base';\n\n/**\n * https://www.imsglobal.org/spec/qti/v3p0/impl#h.fi29q8dubjgw\n * <qti-custom-operator class=\"js.org\">\n <qti-base-value base-type=\"string\"><![CDATA[\n console.log(context.variables);\n return 'B'\n document.querySelector('qti-end-attempt-interaction').disabled = true;\n ]]></qti-base-value>\n </qti-custom-operator>\n </qti-set-outcome-value>\n */\n\nexport class QtiCustomOperator extends LitElement implements Calculate {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n #operatorFunction: Function;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n private _context?: ItemContext;\n\n override render() {\n return html`<slot @slotchange=${this.handleSlotChange}></slot>`;\n }\n\n handleSlotChange() {\n // expecting <[!CDATA[ ... ]]> is converted into <!-- ... --> with qti-transform: cDataToComment\n const commentNode = Array.from(this.firstElementChild?.childNodes ?? []).find(\n node => node.nodeType === Node.COMMENT_NODE\n );\n try {\n this.#operatorFunction = new Function('context', 'fn', 'item', commentNode?.textContent ?? '');\n } catch (e) {\n console.error('custom-operator contains invalid javascript code', e);\n }\n }\n\n public calculate() {\n const fn = {\n variable: (responseIdentifier: string) =>\n this._context?.variables.find(v => v.identifier === responseIdentifier)?.value ?? '',\n correct: (responseIdentifier: string) =>\n (this._context?.variables.find(v => v.identifier === responseIdentifier) as ResponseVariable)\n ?.correctResponse ?? ''\n };\n const item = {\n getVariable: (variableIdentifier: string) =>\n this._context?.variables.find(v => v.identifier === variableIdentifier),\n updateOutcomeVariable: (outcomeIdentifier: string, value: string | string[]) => {\n this.dispatchEvent(\n new CustomEvent<{ outcomeIdentifier: string; value: string | string[] }>('qti-set-outcome-value', {\n bubbles: true,\n composed: true,\n detail: {\n outcomeIdentifier,\n value\n }\n })\n );\n },\n updateResponseVariable: (responseIdentifier: string, response: string | string[]) => {\n this.dispatchEvent(\n new CustomEvent<{ responseIdentifier: string; response: string | string[] }>('qti-interaction-response', {\n bubbles: true,\n composed: true,\n detail: {\n responseIdentifier,\n response\n }\n })\n );\n }\n };\n\n return this.#operatorFunction(this._context, fn, item);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-custom-operator': QtiCustomOperator;\n }\n}\n","import { css, html } from 'lit';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nexport class QtiFeedbackBlock extends QtiFeedback {\n static override styles = css`\n :host {\n display: block;\n }\n .on {\n display: block;\n }\n .off {\n display: none;\n }\n `;\n\n override render() {\n return html` <slot part=\"feedback\" class=\"feedback ${this.showStatus}\"></slot> `;\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.checkShowFeedback(this.outcomeIdentifier);\n }\n}\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-feedback-block': QtiFeedbackBlock;\n }\n}\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nexport class QtiFeedbackInline extends QtiFeedback {\n static override styles = css`\n .on {\n display: inline-block;\n }\n .off {\n display: none;\n }\n `;\n\n override render = () => html` <slot part=\"feedback\" class=\"${ifDefined(this.showStatus)}\"></slot> `;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.checkShowFeedback(this.outcomeIdentifier);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-feedback-inline': QtiFeedbackInline;\n }\n}\n","import { html, LitElement } from 'lit';\n\nimport styles from './qti-item-body.styles';\n\nimport type { CSSResultGroup } from 'lit';\n\n/**\n * @summary The qti-item-body node contains the text, graphics, media objects and interactions that describe the item's content and information about how it is structured.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.sphpo6lu6zqi\n * @status stable\n * @since 4.0\n *\n * @slot - item body content.\n * @slot qti-rubric-block - the qti rubric block is placed above the item\n * @part qti-rubric-block - the qti rubric block part\n */\n\nexport class QtiItemBody extends LitElement {\n static override styles: CSSResultGroup = styles;\n\n override render() {\n return html`<slot part=\"qti-rubric-blocks\" name=\"qti-rubric-block\"></slot><slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-item-body': QtiItemBody;\n }\n}\n","import { css } from 'lit';\n\nexport default css`\n :host {\n display: block;\n }\n`;\n","import { css, html } from 'lit';\n\nimport { QtiFeedback } from '@qti-components/base';\n\nexport class QtiModalFeedback extends QtiFeedback {\n static override styles = css`\n .cito-dialog {\n background: var(--qti-bg);\n border: var(--qti-border-thickness) var(--qti-border-style) var(--qti-border-color);\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-box);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1000;\n width: auto;\n max-width: 90%;\n }\n\n .button {\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-box);\n background-color: var(--qti-bg-active);\n border: var(--qti-border-active);\n cursor: pointer;\n position: relative;\n display: inline-block;\n }\n\n /* Inlined from --qti-disabled-bg / --qti-disabled-color, which this button was the only reader\n of anywhere in the repo. They were named as a global disabled vocabulary but no interaction\n ever used them: the theme's disabled treatment is cursor only (see the note in qti-mixins.css). */\n .button:disabled {\n background-color: transparent;\n color: var(--qti-fg);\n cursor: not-allowed;\n }\n\n .button:focus {\n outline: var(--qti-focus-border-width) solid var(--qti-focus-color);\n }\n `;\n\n override render() {\n return html`\n <dialog class=\"cito-dialog\" part=\"feedback\" ?open=\"${this.showStatus === 'on'}\">\n <slot></slot>\n <div style=\"margin-top: var(--qti-gap); text-align: center;\">\n <button class=\"button close-button\" @click=\"${this.closeFeedback}\">Close</button>\n </div>\n </dialog>\n `;\n }\n\n openFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && !dialog.open) {\n dialog.showModal();\n }\n }\n\n closeFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && dialog.open) {\n dialog.close();\n this.showStatus = 'off';\n }\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (this.showStatus === 'on') {\n this.openFeedback();\n }\n }\n\n protected override updated(changedProperties: Map<string | number | symbol, unknown>): void {\n if (changedProperties.has('showStatus')) {\n if (this.showStatus === 'on') {\n this.openFeedback();\n } else {\n this.closeFeedback();\n }\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-modal-feedback': QtiModalFeedback;\n }\n}\n","import { consume } from '@lit/context';\nimport { css, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { itemContext } from '@qti-components/base';\nimport { QtiVariableDeclaration } from '@qti-components/base';\n\nimport type { BaseType, Cardinality } from '@qti-components/base';\nimport type { OutcomeVariable } from '@qti-components/base';\nimport type { ItemContext } from '@qti-components/base';\n\nexport class QtiOutcomeDeclaration extends QtiVariableDeclaration {\n @property({ type: String, attribute: 'base-type' }) baseType: BaseType;\n @property({ type: String, attribute: 'external-scored' }) externalScored: 'human' | 'externalMachine' | null = null;\n @property({ type: String }) identifier: string;\n @property({ type: String }) cardinality: Cardinality;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n public itemContext?: ItemContext;\n\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n override render() {\n const value = this.itemContext?.variables.find(v => v.identifier === this.identifier)?.value;\n return html`${JSON.stringify(value, null, 2)}`;\n }\n\n get interpolationTable(): Map<number, number> | null {\n const table = this.querySelector('qti-interpolation-table');\n if (table) {\n const entries = new Map<number, number>();\n for (const entry of table.querySelectorAll('qti-interpolation-table-entry')) {\n if (!entry.getAttribute('source-value') && entry.getAttribute('target-value')) {\n console.error('source-value or target-value is missing in qti-interpolation-table-entry');\n }\n const sourceValue = parseFloat(entry.getAttribute('source-value'));\n const targetValue = parseFloat(entry.getAttribute('target-value'));\n if (isNaN(sourceValue) || isNaN(targetValue)) {\n console.error('source-value or target-value is not a number in qti-interpolation-table-entry');\n }\n entries.set(sourceValue, targetValue);\n }\n return entries;\n }\n return null;\n }\n\n public override connectedCallback() {\n super.connectedCallback();\n\n const defaultValue = this.defaultValues(this.cardinality);\n\n const outcomeVariable: OutcomeVariable = {\n identifier: this.identifier,\n cardinality: this.cardinality,\n baseType: this.baseType,\n defaultValue: defaultValue,\n type: 'outcome',\n value: null,\n interpolationTable: this.interpolationTable,\n externalScored: this.externalScored\n };\n // At runtime, outcome variables are instantiated as part of an item session.\n // Their values may be initialized with a default value and/or set during response processing.\n // If no default value is given in the declaration then the outcome variable is initialized to NULL unless the outcome is of a numeric type (integer or float) in which case it is initialized to 0.\n outcomeVariable.value = defaultValue;\n if (\n (outcomeVariable.value === null || outcomeVariable.value == undefined) &&\n (outcomeVariable.baseType === 'integer' || outcomeVariable.baseType === 'float')\n ) {\n outcomeVariable.value = '0';\n }\n this.dispatchEvent(\n new CustomEvent('qti-register-variable', {\n bubbles: true,\n composed: true,\n detail: { variable: outcomeVariable }\n })\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-outcome-declaration': QtiOutcomeDeclaration;\n }\n}\n","import { consume } from '@lit/context';\nimport { css, html } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { itemContext } from '@qti-components/base';\nimport { QtiVariableDeclaration } from '@qti-components/base';\n\nimport type { QtiAreaMapping } from '@qti-components/base';\nimport type { BaseType, Cardinality } from '@qti-components/base';\nimport type { ResponseVariable } from '@qti-components/base';\nimport type { QtiMapping } from '@qti-components/base';\nimport type { ItemContext } from '@qti-components/base';\n\nexport class QtiResponseDeclaration extends QtiVariableDeclaration {\n @property({ type: String, attribute: 'base-type' }) baseType: BaseType;\n\n @property({ type: String }) identifier: string;\n\n @property({ type: String }) cardinality: Cardinality;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n public itemContext?: ItemContext;\n\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n override render() {\n const value = this.itemContext?.variables.find(v => v.identifier === this.identifier)?.value;\n return html`${JSON.stringify(value, null, 2)}`;\n }\n\n public override connectedCallback() {\n super.connectedCallback();\n const defaultValue = this.defaultValues(this.cardinality);\n\n const responseVariable: ResponseVariable = {\n baseType: this.baseType,\n identifier: this.identifier,\n correctResponse: this.#correctResponse,\n cardinality: this.cardinality || 'single',\n mapping: this.#mapping,\n defaultValue,\n areaMapping: this.#areaMapping,\n value: null,\n type: 'response',\n candidateResponse: null\n };\n responseVariable.value = defaultValue;\n\n this.dispatchEvent(\n new CustomEvent('qti-register-variable', {\n bubbles: true,\n composed: true,\n detail: { variable: responseVariable }\n })\n );\n }\n\n get #correctResponse(): string | string[] {\n let result: string | string[];\n const correctResponse = this.querySelector('qti-correct-response');\n if (correctResponse) {\n const values = correctResponse.querySelectorAll('qti-value');\n if (this.cardinality === 'single' && values.length > 0) {\n result = values[0].textContent.trim();\n values[0].remove();\n } else if (this.cardinality !== 'single') {\n result = [];\n for (let i = 0; i < values.length; i++) {\n result.push(values[i].textContent.trim());\n values[i].remove();\n }\n }\n }\n return result;\n }\n\n get #mapping(): QtiMapping {\n const mappingElement = this.querySelector('qti-mapping');\n const lowerBound = parseFloat(mappingElement?.getAttribute('lower-bound'));\n const uppperBound = parseFloat(mappingElement?.getAttribute('upper-bound'));\n const mappingValue = {\n defaultValue: Number(mappingElement?.getAttribute('default-value')) || 0,\n lowerBound: isNaN(lowerBound) ? null : lowerBound,\n upperBound: isNaN(uppperBound) ? null : uppperBound,\n mapEntries: Array.from(mappingElement?.querySelectorAll('qti-map-entry') || []).map(el => ({\n mapKey: el.getAttribute('map-key') || '',\n mappedValue: Number(el.getAttribute('mapped-value')) || 0,\n caseSensitive: el.hasAttribute('case-sensitive') ? el.getAttribute('case-sensitive') !== 'false' : false\n }))\n };\n return mappingValue;\n }\n\n get #areaMapping(): QtiAreaMapping {\n const areaMappingElement = this.querySelector('qti-area-mapping') as HTMLElement;\n\n const defaultValue = Number(areaMappingElement?.getAttribute('default-value')) || 0;\n const lowerBound = parseFloat(areaMappingElement?.getAttribute('lower-bound'));\n const uppperBound = parseFloat(areaMappingElement?.getAttribute('upper-bound'));\n\n const areaMapEntries = Array.from(areaMappingElement?.querySelectorAll('qti-area-map-entry') || []).map(\n (el: HTMLElement) => ({\n shape: (el.getAttribute('shape') as 'default' | 'circle' | 'rect' | 'ellipse' | 'poly') || 'default',\n coords: el.getAttribute('coords') || '',\n mappedValue: Number(el.getAttribute('mapped-value')) || 0,\n defaultValue: Number(el.getAttribute('default-value')) || 0\n })\n );\n\n return {\n defaultValue,\n lowerBound: isNaN(lowerBound) ? null : lowerBound,\n upperBound: isNaN(uppperBound) ? null : uppperBound,\n areaMapEntries\n };\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-response-declaration': QtiResponseDeclaration;\n }\n}\n","import { css, html, LitElement } from 'lit';\n\nimport { type QtiRuleBase } from '@qti-components/base';\n\nimport { mapResponse, mapResponsePoint, matchCorrect } from '../../internal/template-strings';\n\nimport type { PropertyValueMap } from 'lit';\n\n/** The response processing templates we substitute for, keyed by the file name in `template`. */\nconst responseProcessingTemplates: Record<string, string> = {\n map_response: mapResponse,\n map_response_point: mapResponsePoint,\n match_correct: matchCorrect\n};\n\nexport class QtiResponseProcessing extends LitElement {\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n override render() {\n return html`<slot></slot>`;\n }\n\n public process() {\n const assessmentItem = this.closest('qti-assessment-item');\n if (!assessmentItem) return;\n const rules = [...this.children] as unknown as QtiRuleBase[];\n for (const rule of rules) {\n rule.process();\n }\n }\n\n public override firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {\n const template = this.getAttribute('template');\n if (!template) return;\n\n const templateName = template.split('/').pop()!.replace('.xml', '');\n const rules = responseProcessingTemplates[templateName];\n // Leave an unknown template's authored children alone; there is nothing to substitute.\n if (!rules) return;\n\n // Parsed through this element's own `innerHTML` rather than a fragment created off `document`:\n // the HTML fragment parsing algorithm takes its custom element registry from the context\n // element, so the rules are upgraded with the registry this element lives in. A fragment from\n // `document.createRange()` is parsed against the global registry, which leaves every rule an\n // unupgraded HTMLElement when the item was rendered into a scoped registry.\n this.innerHTML = rules;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-response-processing': QtiResponseProcessing;\n }\n}\n","export const matchCorrect = `<qti-response-condition>\n <qti-response-if>\n <qti-match>\n <qti-variable identifier=\"RESPONSE\"></qti-variable>\n <qti-correct identifier=\"RESPONSE\"></qti-correct>\n </qti-match>\n <qti-set-outcome-value identifier=\"SCORE\">\n <qti-base-value base-type=\"float\">1</qti-base-value>\n </qti-set-outcome-value>\n </qti-response-if>\n <qti-response-else>\n <qti-set-outcome-value identifier=\"SCORE\">\n <qti-base-value base-type=\"float\">0</qti-base-value>\n </qti-set-outcome-value>\n </qti-response-else>\n</qti-response-condition>`;\n\nexport const mapResponse = `<qti-response-condition>\n <qti-response-if>\n <qti-is-null>\n <qti-variable identifier=\"RESPONSE\"></qti-variable>\n </qti-is-null>\n <qti-set-outcome-value identifier=\"SCORE\">\n <qti-base-value base-type=\"float\">0.0</qti-base-value>\n </qti-set-outcome-value>\n </qti-response-if>\n <qti-response-else>\n <qti-set-outcome-value identifier=\"SCORE\">\n <qti-map-response identifier=\"RESPONSE\"> </qti-map-response>\n </qti-set-outcome-value>\n </qti-response-else>\n</qti-response-condition>`;\n\nexport const mapResponsePoint = `<qti-response-condition>\n <qti-response-if>\n <qti-is-null>\n <qti-variable identifier=\"RESPONSE\"></qti-variable>\n </qti-is-null>\n <qti-set-outcome-value identifier=\"SCORE\">\n <qti-base-value base-type=\"float\">0</qti-base-value>\n </qti-set-outcome-value>\n </qti-response-if>\n <qti-response-else>\n <qti-set-outcome-value identifier=\"SCORE\">\n <qti-map-response-point identifier=\"RESPONSE\"></qti-map-response-point>\n </qti-set-outcome-value>\n </qti-response-else>\n</qti-response-condition>`;\n","import { LitElement, css, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { watch } from '@qti-components/utilities';\n\nexport class QtiRubricBlock extends LitElement {\n @property({ type: String }) override id: string; // =\"qtiAspectInhoudRubricBlock\"\n\n @property({ type: String }) use: 'instructions' | 'scoring' | 'navigation'; // = \"scoring\"\n\n @property({ type: String }) view: 'author' | 'candidate' | 'proctor' | 'scorer' | 'testConstructor' | 'tutor';\n\n @property({ type: String, attribute: 'class' }) classNames: string;\n @watch('classNames', { waitUntilFirstUpdate: true })\n handleclassNamesChange() {\n const classNames = this.classNames.split(' ');\n classNames.forEach((className: string) => {\n switch (className) {\n case 'qti-rubric-discretionary-placement':\n {\n const event = new CustomEvent('qti-rubric:discretionary-placement', {\n detail: { className, element: this },\n bubbles: true,\n composed: true,\n cancelable: true\n });\n const notCancelled = this.dispatchEvent(event);\n if (!notCancelled) return;\n this.setAttribute('slot', 'qti-rubric-block');\n }\n break;\n case 'qti-rubric-inline':\n this.setAttribute('slot', '');\n break;\n default:\n break;\n }\n });\n }\n\n static override styles = css`\n :host {\n display: block;\n }\n `;\n\n override render() {\n return html`<slot></slot>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-rubric-block': QtiRubricBlock;\n }\n}\n","import { LitElement } from 'lit';\n\nimport type { PropertyValueMap } from 'lit';\n\nexport class QtiStylesheet extends LitElement {\n #styleElement: HTMLStyleElement | null = null;\n\n protected override firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {\n super.firstUpdated(_changedProperties);\n\n const link = this.getAttribute('href');\n\n if (link !== null) {\n // Fetch the stylesheet content\n fetch(link)\n .then(response => response.text())\n .then(cssContent => {\n // Minify the CSS content by removing whitespace and comments\n const minifiedCss = this.#minifyCss(cssContent);\n\n // Create a <style> element with @scope surrounding the minified CSS\n this.#styleElement = document.createElement('style');\n this.#styleElement.media = 'screen';\n this.#styleElement.textContent = `@scope {${minifiedCss}}`;\n\n // Append the style element to the parent element of this component\n if (this.parentElement) {\n this.parentElement.appendChild(this.#styleElement);\n } else {\n console.warn('No parent element to append the scoped stylesheet to.');\n }\n })\n .catch(error => {\n console.error('Failed to load stylesheet:', error);\n });\n }\n\n if (this.textContent !== null && this.textContent.trim() !== '') {\n // Minify the inline CSS content\n const minifiedCss = this.#minifyCss(this.textContent);\n\n // Directly create a <style> element with the @scope surrounding the minified inline styles\n this.#styleElement = document.createElement('style');\n this.#styleElement.media = 'screen';\n this.#styleElement.textContent = `@scope {${minifiedCss}}`;\n\n // Append the style element to the parent element of this component\n if (this.parentElement) {\n this.parentElement.appendChild(this.#styleElement);\n } else {\n console.warn('No parent element to append the scoped stylesheet to.');\n }\n }\n }\n\n #minifyCss(cssContent: string): string {\n // Remove comments, whitespace, and newline characters\n return cssContent\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Remove comments\n .replace(/\\s+/g, ' ') // Collapse whitespace\n .replace(/\\s*([{}:;])\\s*/g, '$1') // Remove spaces around {}, :, ;\n .trim(); // Trim leading/trailing whitespace\n }\n\n override disconnectedCallback() {\n if (this.#styleElement) {\n try {\n this.#styleElement.remove();\n } catch (error) {\n console.error('Could not remove stylesheet:', error);\n }\n }\n super.disconnectedCallback();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-stylesheet': QtiStylesheet;\n }\n}\n","import { LitElement, html } from 'lit';\n\nimport type { QtiExpression } from '@qti-components/base';\nimport type { QtiRuleBase } from '@qti-components/base';\n\n/**\n * @summary The qti-template-constraint element is a processing rule available only in Template Processing.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.template-constraint\n *\n * It terminates Template Processing and re-runs it from the beginning if the condition\n * specified in the template constraint is not satisfied. This can be used to iterate\n * the Template Processing with different randomly-generated values until a predetermined\n * condition is satisfied.\n */\n\nexport class QtiTemplateConstraint extends LitElement implements QtiRuleBase {\n override render() {\n return html`<slot></slot>`;\n }\n\n /**\n * Evaluates the constraint condition\n * @returns true if constraint is satisfied, false if template processing should restart\n */\n public calculate(): boolean {\n const expressions = [...this.children] as QtiExpression<boolean>[];\n\n if (expressions.length !== 1) {\n console.error('qti-template-constraint must have exactly one child expression');\n return true; // Don't restart on error\n }\n\n try {\n const result = expressions[0].calculate();\n return Boolean(result);\n } catch (error) {\n console.error('Error evaluating template constraint:', error);\n return true; // Don't restart on error\n }\n }\n\n /**\n * Template constraints don't have sub-rules like conditions\n */\n public getSubRules(): QtiRuleBase[] {\n return [];\n }\n\n /**\n * Process the template constraint\n * @returns true if constraint is satisfied, false if template processing should restart\n */\n public process(): boolean {\n const constraintSatisfied = this.calculate();\n\n if (!constraintSatisfied) {\n console.debug('Template constraint not satisfied, restarting template processing');\n }\n\n return constraintSatisfied;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-template-constraint': QtiTemplateConstraint;\n }\n}\n","import { css, LitElement, html } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport type { TemplateVariable } from '@qti-components/base';\nimport type { BaseType } from '@qti-components/base';\n\n/**\n * @summary The qti-template-declaration element declares template variables for item cloning.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.template-declaration\n */\n\nexport class QtiTemplateDeclaration extends LitElement {\n @property({ type: String }) identifier: string = '';\n @property({ type: String }) cardinality: 'single' | 'multiple' | 'ordered' | 'record' = 'single';\n @property({ type: String, attribute: 'base-type' }) baseType: BaseType = 'string';\n @property({ type: Boolean, attribute: 'math-variable' }) mathVariable: boolean = false;\n @property({ type: Boolean, attribute: 'param-variable' }) paramVariable: boolean = false;\n\n #defaultValue: any = null;\n\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n override render() {\n return html`<slot></slot>`;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateComplete.then(() => {\n this.#processDefaultValue();\n this.#registerTemplateVariable();\n });\n }\n\n /**\n * Process qti-default-value to extract the default value\n */\n #processDefaultValue(): void {\n const defaultValueElement = this.querySelector('qti-default-value');\n if (!defaultValueElement) {\n return;\n }\n\n // For now, just get the text content - this could be enhanced to handle expressions\n const textContent = defaultValueElement.textContent?.trim() || '';\n this.#defaultValue = this.#convertValue(textContent);\n }\n\n /**\n * Convert string value based on base-type\n */\n #convertValue(value: string): any {\n if (!value) return null;\n\n switch (this.baseType) {\n case 'integer':\n return parseInt(value, 10);\n case 'float':\n case 'duration':\n return parseFloat(value);\n case 'boolean':\n return value.toLowerCase() === 'true';\n case 'string':\n default:\n return value;\n }\n }\n\n /**\n * Register this template variable with the assessment item\n */\n #registerTemplateVariable(): void {\n const templateVariable: TemplateVariable = {\n identifier: this.identifier,\n cardinality: this.cardinality,\n baseType: this.baseType,\n defaultValue: this.#defaultValue,\n value: this.#defaultValue,\n type: 'template',\n mathVariable: this.mathVariable,\n paramVariable: this.paramVariable\n };\n\n // Dispatch event to register the variable\n\n // value must string or string[]\n const variable = { ...templateVariable, value: this.#defaultValue?.toString() || '' };\n this.dispatchEvent(\n new CustomEvent('qti-register-variable', {\n bubbles: true,\n composed: true,\n detail: { variable }\n })\n );\n }\n\n /**\n * Get the template variable definition\n */\n public getTemplateVariable(): TemplateVariable {\n return {\n identifier: this.identifier,\n cardinality: this.cardinality,\n baseType: this.baseType,\n value: this.#defaultValue,\n type: 'template',\n mathVariable: this.mathVariable,\n paramVariable: this.paramVariable\n };\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-template-declaration': QtiTemplateDeclaration;\n }\n}\n","import { css, html, LitElement } from 'lit';\n\nimport type { QtiRuleBase } from '@qti-components/base';\nimport type { QtiTemplateConstraint } from '../qti-template-constraint/qti-template-constraint';\nimport type { PropertyValueMap } from 'lit';\n\n/**\n * @summary The qti-template-processing element contains template processing rules.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.template-processing\n */\n\nexport class QtiTemplateProcessing extends LitElement {\n static override styles = [\n css`\n :host {\n display: none;\n }\n `\n ];\n\n #maxIterations = 100; // Prevent infinite loops in template constraints\n\n override render() {\n return html`<slot></slot>`;\n }\n\n /**\n * Process template rules to set template variable values\n */\n public process(): void {\n const assessmentItem = this.closest('qti-assessment-item');\n if (!assessmentItem) {\n console.warn('qti-template-processing must be inside qti-assessment-item');\n return;\n }\n\n let iterations = 0;\n let shouldReprocess = false;\n\n do {\n shouldReprocess = false;\n iterations++;\n\n if (iterations > this.#maxIterations) {\n console.error('Template processing exceeded maximum iterations. Possible infinite loop.');\n break;\n }\n\n try {\n const rules = [...this.children] as unknown as (Element & QtiRuleBase)[];\n for (const rule of rules) {\n // Check if this is a template constraint that failed\n if (rule.tagName.toLowerCase() === 'qti-template-constraint') {\n const constraintResult = (rule as QtiTemplateConstraint).calculate();\n if (constraintResult === false) {\n // Template constraint failed, restart processing\n shouldReprocess = true;\n break;\n }\n } else {\n rule.process();\n }\n }\n } catch (error) {\n console.error('Error during template processing:', error);\n break;\n }\n } while (shouldReprocess);\n\n // Dispatch event that template processing is complete\n this.dispatchEvent(\n new CustomEvent('qti-template-processing-complete', {\n bubbles: true,\n composed: true,\n detail: { iterations }\n })\n );\n }\n\n public override firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {\n // Template processing doesn't typically use external templates like response processing\n // But we could add support for common template processing patterns here if needed\n if (this.getAttribute('template')) {\n console.info('Template processing with external template not yet implemented');\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-template-processing': QtiTemplateProcessing;\n }\n}\n","import { QtiAssessmentItem } from './components/qti-assessment-item/qti-assessment-item';\nimport { QtiAssessmentStimulusRef } from './components/qti-assessment-stimulus-ref/qti-assessment-stimulus-ref';\nimport { QtiCompanionMaterialsInfo } from './components/qti-companion-materials-info/qti-companion-materials-info';\nimport { QtiContentBody } from './components/qti-content-body/qti-content-body';\nimport { QtiContextDeclaration } from './components/qti-context-declaration/qti-context-declaration';\nimport { QtiCustomOperator } from './components/qti-custom-operator/qti-custom-operator';\nimport { QtiFeedbackBlock } from './components/qti-feedback-block/qti-feedback-block';\nimport { QtiFeedbackInline } from './components/qti-feedback-inline/qti-feedback-inline';\nimport { QtiItemBody } from './components/qti-item-body/qti-item-body';\nimport { QtiModalFeedback } from './components/qti-modal-feedback/qti-modal-feedback';\nimport { QtiOutcomeDeclaration } from './components/qti-outcome-declaration/qti-outcome-declaration';\nimport { QtiResponseDeclaration } from './components/qti-response-declaration/qti-response-declaration';\nimport { QtiResponseProcessing } from './components/qti-response-processing/qti-response-processing';\nimport { QtiRubricBlock } from './components/qti-rubric-block/qti-rubric-block';\nimport { QtiStylesheet } from './components/qti-stylesheet/qti-stylesheet';\nimport { QtiTemplateConstraint } from './components/qti-template-constraint/qti-template-constraint';\nimport { QtiTemplateDeclaration } from './components/qti-template-declaration/qti-template-declaration';\nimport { QtiTemplateProcessing } from './components/qti-template-processing/qti-template-processing';\n\nexport {\n QtiAssessmentItem,\n QtiAssessmentStimulusRef,\n QtiCompanionMaterialsInfo,\n QtiContentBody,\n QtiContextDeclaration,\n QtiCustomOperator,\n QtiFeedbackBlock,\n QtiFeedbackInline,\n QtiItemBody,\n QtiModalFeedback,\n QtiOutcomeDeclaration,\n QtiResponseDeclaration,\n QtiResponseProcessing,\n QtiRubricBlock,\n QtiStylesheet,\n QtiTemplateConstraint,\n QtiTemplateDeclaration,\n QtiTemplateProcessing\n};\n\nexport const qtiContentElements = [\n { tag: 'qti-assessment-item', ctor: QtiAssessmentItem },\n { tag: 'qti-assessment-stimulus-ref', ctor: QtiAssessmentStimulusRef },\n { tag: 'qti-companion-materials-info', ctor: QtiCompanionMaterialsInfo },\n { tag: 'qti-content-body', ctor: QtiContentBody },\n { tag: 'qti-context-declaration', ctor: QtiContextDeclaration },\n { tag: 'qti-custom-operator', ctor: QtiCustomOperator },\n { tag: 'qti-feedback-block', ctor: QtiFeedbackBlock },\n { tag: 'qti-feedback-inline', ctor: QtiFeedbackInline },\n { tag: 'qti-item-body', ctor: QtiItemBody },\n { tag: 'qti-modal-feedback', ctor: QtiModalFeedback },\n { tag: 'qti-outcome-declaration', ctor: QtiOutcomeDeclaration },\n { tag: 'qti-response-declaration', ctor: QtiResponseDeclaration },\n { tag: 'qti-response-processing', ctor: QtiResponseProcessing },\n { tag: 'qti-rubric-block', ctor: QtiRubricBlock },\n { tag: 'qti-stylesheet', ctor: QtiStylesheet },\n { tag: 'qti-template-constraint', ctor: QtiTemplateConstraint },\n { tag: 'qti-template-declaration', ctor: QtiTemplateDeclaration },\n { tag: 'qti-template-processing', ctor: QtiTemplateProcessing }\n] as const;\n"],"mappings":"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","names":["state","LitElement","property","LitElement","__decorate","property","LitElement","LitElement","html","LitElement","html","__decorate","LitElement","html","property","__decorate","consume","LitElement","html","state","LitElement","html","__decorate","consume","state","css","html","css","html","css","html","html","css","html","LitElement","css","LitElement","html","css","html","css","html","consume","css","html","property","state","css","html","__decorate","property","consume","state","consume","css","html","property","state","css","html","__decorate","property","consume","state","css","html","LitElement","LitElement","css","html","LitElement","css","html","property","LitElement","css","html","__decorate","property","LitElement","LitElement","html","css","LitElement","html","property","__decorate","css","html","LitElement"]}