@citolab/qti-components 8.1.0 → 8.2.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 (56) hide show
  1. package/cdn/index.global.js +1 -1
  2. package/cdn/index.js +274 -168
  3. package/dist/base.d.ts +5 -5
  4. package/dist/base.js +1 -1
  5. package/dist/{chunk-IXPDMYKH.js → chunk-43XBJ47H.js} +3 -3
  6. package/dist/{chunk-EKXZI26R.js → chunk-7D3NKAGZ.js} +54 -3
  7. package/dist/chunk-7D3NKAGZ.js.map +1 -0
  8. package/dist/{chunk-Q52IJELT.js → chunk-CRLXQZFA.js} +594 -259
  9. package/dist/chunk-CRLXQZFA.js.map +1 -0
  10. package/dist/{chunk-TXIB3SKC.js → chunk-LMGJOBJA.js} +3 -3
  11. package/dist/{chunk-6V3A7NQP.js → chunk-M7K5C522.js} +2 -2
  12. package/dist/{chunk-CF3DXJWM.js → chunk-OIUK5BFU.js} +22 -6
  13. package/dist/{chunk-CF3DXJWM.js.map → chunk-OIUK5BFU.js.map} +1 -1
  14. package/dist/{chunk-MK2I3MQB.js → chunk-OVBG223G.js} +4 -5
  15. package/dist/{chunk-MK2I3MQB.js.map → chunk-OVBG223G.js.map} +1 -1
  16. package/dist/{chunk-4XR2JHCP.js → chunk-Q6ZK4LRH.js} +26 -2
  17. package/dist/chunk-Q6ZK4LRH.js.map +1 -0
  18. package/dist/chunk-TLTYXWW7.js +7 -0
  19. package/dist/chunk-TLTYXWW7.js.map +1 -0
  20. package/dist/{chunk-3IACYIU2.js → chunk-U7YCXDYC.js} +2 -2
  21. package/dist/{chunk-NZLW6EX7.js → chunk-UC3T3NI3.js} +2 -2
  22. package/dist/{chunk-6XJUP55A.js → chunk-YLRMOX6C.js} +3 -3
  23. package/dist/chunk-YLRMOX6C.js.map +1 -0
  24. package/dist/{computed.types.d-DpKIYO6e.d.ts → computed.types.d-CJarqC6s.d.ts} +12 -0
  25. package/dist/corrections.d.ts +14 -4
  26. package/dist/corrections.js +7 -7
  27. package/dist/elements.d.ts +1 -1
  28. package/dist/elements.js +3 -3
  29. package/dist/index.d.ts +5 -5
  30. package/dist/index.js +14 -12
  31. package/dist/interactions.js +3 -3
  32. package/dist/item.css +81 -0
  33. package/dist/item.d.ts +1 -1
  34. package/dist/item.js +4 -4
  35. package/dist/loader.d.ts +1 -1
  36. package/dist/processing.d.ts +3 -3
  37. package/dist/processing.js +2 -2
  38. package/dist/qti-components-jsx.d.ts +7704 -7127
  39. package/dist/{qti-condition-expression.d-aMvBvpc6.d.ts → qti-condition-expression.d-CYwXOUb1.d.ts} +1 -1
  40. package/dist/{qti-expression.d-BietT_8b.d.ts → qti-expression.d-B_-m9emA.d.ts} +11 -1
  41. package/dist/{qti-feedback.d-DZbad0RN.d.ts → qti-feedback.d-B1EIF-fU.d.ts} +1 -0
  42. package/dist/{qti-test.d-_YAlhDbt.d.ts → qti-test.d-C6lCEMRB.d.ts} +38 -3
  43. package/dist/test.d.ts +5 -5
  44. package/dist/test.js +7 -5
  45. package/package.json +9 -9
  46. package/dist/chunk-4XR2JHCP.js.map +0 -1
  47. package/dist/chunk-6XJUP55A.js.map +0 -1
  48. package/dist/chunk-EKXZI26R.js.map +0 -1
  49. package/dist/chunk-IYC7LZV6.js +0 -7
  50. package/dist/chunk-IYC7LZV6.js.map +0 -1
  51. package/dist/chunk-Q52IJELT.js.map +0 -1
  52. /package/dist/{chunk-IXPDMYKH.js.map → chunk-43XBJ47H.js.map} +0 -0
  53. /package/dist/{chunk-TXIB3SKC.js.map → chunk-LMGJOBJA.js.map} +0 -0
  54. /package/dist/{chunk-6V3A7NQP.js.map → chunk-M7K5C522.js.map} +0 -0
  55. /package/dist/{chunk-3IACYIU2.js.map → chunk-U7YCXDYC.js.map} +0 -0
  56. /package/dist/{chunk-NZLW6EX7.js.map → chunk-UC3T3NI3.js.map} +0 -0
package/dist/base.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import { C as ComputedItemContext } from './computed-item.types.d-BKZdSLLJ.js';
2
- import { C as ComputedContext } from './computed.types.d-DpKIYO6e.js';
3
- export { a as ComputedItem, I as INITIAL_SESSION_CONTEXT, S as SessionContext, V as View, s as sessionContext } from './computed.types.d-DpKIYO6e.js';
2
+ import { C as ComputedContext } from './computed.types.d-CJarqC6s.js';
3
+ export { a as ComputedItem, I as INITIAL_SESSION_CONTEXT, S as SessionContext, V as View, s as sessionContext } from './computed.types.d-CJarqC6s.js';
4
4
  export { C as ConfigContext, V as ValidationDisplayMode, c as configContext } from './config.context.d-BvU9r-Mg.js';
5
5
  export { C as ChoiceRole, I as Interaction, a as InteractionContext, i as interactionContext } from './interaction.d-CJiMv8H7.js';
6
6
  import { I as ItemContext, B as BaseType } from './item.types.d-QU7LljEK.js';
7
7
  export { C as Calculate, a as Cardinality, M as Multiple, O as Ordered, b as OutcomeVariable, Q as QtiAreaMapEntry, c as QtiAreaMapping, d as QtiMapEntry, e as QtiMapping, R as ResponseInteraction, f as ResponseVariable, T as TemplateVariable, V as VariableDeclaration, g as VariableValue, h as areaShape, i as directedPair, j as float, k as integer, l as itemContextVariables } from './item.types.d-QU7LljEK.js';
8
8
  export { Q as QtiContext, a as QtiContextType, S as Seed, b as asSeed, i as isSeed, q as qtiContext } from './qti.context.d-CejJMlfZ.js';
9
- export { I as INITIAL_TEST_CONTEXT, Q as QtiExpression, a as QtiExpressionBase, T as TestContext, t as testContext } from './qti-expression.d-BietT_8b.js';
9
+ export { I as INITIAL_TEST_CONTEXT, Q as QtiExpression, a as QtiExpressionBase, T as TestContext, t as testContext } from './qti-expression.d-B_-m9emA.js';
10
10
  import * as lit from 'lit';
11
- export { Q as QtiFeedback, a as QtiVariableDeclaration } from './qti-feedback.d-DZbad0RN.js';
12
- export { Q as QtiConditionExpression } from './qti-condition-expression.d-aMvBvpc6.js';
11
+ export { Q as QtiFeedback, a as QtiVariableDeclaration } from './qti-feedback.d-B1EIF-fU.js';
12
+ export { Q as QtiConditionExpression } from './qti-condition-expression.d-CYwXOUb1.js';
13
13
  export { D as DirectedPair, I as Identifier, P as Point, R as ResponseValue, i as iterResponseValues, p as parsePair, a as parsePoint, b as parseResponseAttribute, r as responseAttributeConverter, s as serializePair, c as serializePoint, d as serializeResponseAttribute } from './response.d-_8y4kjGP.js';
14
14
  export { F as FormAssociatedInteraction, I as IInteraction, R as ReadonlyInteraction, a as RegisteredInteraction, b as ResettableInteraction, c as ResponseIdentifiedInteraction, d as ResponseInteractionElement, V as ValidatableInteraction } from './interaction.interface.d-CvjHM2bi.js';
15
15
  export { Q as QtiRuleBase, a as QtiRuleElement } from './qti-rule-base.d-ajOnfGXY.js';
package/dist/base.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  sessionContext,
38
38
  testContext,
39
39
  validationMessage
40
- } from "./chunk-EKXZI26R.js";
40
+ } from "./chunk-7D3NKAGZ.js";
41
41
  export {
42
42
  CustomStateSetShim,
43
43
  INITIAL_SESSION_CONTEXT,
@@ -22,13 +22,13 @@ import {
22
22
  elements7,
23
23
  elements8,
24
24
  elements9
25
- } from "./chunk-4XR2JHCP.js";
25
+ } from "./chunk-Q6ZK4LRH.js";
26
26
  import {
27
27
  Interaction,
28
28
  boxSizing,
29
29
  dropRegion,
30
30
  removeDoubleSlashes
31
- } from "./chunk-EKXZI26R.js";
31
+ } from "./chunk-7D3NKAGZ.js";
32
32
 
33
33
  // ../interactions/core/dist/elements/qti-associable-hotspot/qti-associable-hotspot.js
34
34
  import { LitElement, html } from "lit";
@@ -1417,4 +1417,4 @@ export {
1417
1417
  QtiUploadInteraction,
1418
1418
  qtiInteractionElements
1419
1419
  };
1420
- //# sourceMappingURL=chunk-IXPDMYKH.js.map
1420
+ //# sourceMappingURL=chunk-43XBJ47H.js.map
@@ -460,8 +460,7 @@ var QtiExpression = class extends LitElement3 {
460
460
  type: "context"
461
461
  };
462
462
  }
463
- const variable = this.context.variables.find((v) => v.identifier === identifier) || null;
464
- return variable;
463
+ return this.resolveVariable(identifier);
465
464
  }
466
465
  case "qti-multiple": {
467
466
  const multiple = e;
@@ -545,6 +544,17 @@ var QtiExpression = class extends LitElement3 {
545
544
  getResult() {
546
545
  throw new Error("Not implemented");
547
546
  }
547
+ /**
548
+ * Resolve a declared variable from the closest available scope: item-level
549
+ * first, then the test-level outcome variables. So an expression used in an
550
+ * assessmentTest's outcome processing can reference a test-level outcome
551
+ * (e.g. a total set earlier in the same run) — which the QTI variable
552
+ * expression is specified to do. Returns null when unresolved rather than
553
+ * throwing, so callers degrade gracefully.
554
+ */
555
+ resolveVariable(identifier) {
556
+ return this.context?.variables.find((v) => v.identifier === identifier) ?? this._testContext?.testOutcomeVariables?.find((v) => v.identifier === identifier) ?? null;
557
+ }
548
558
  };
549
559
  __decorate2([
550
560
  state()
@@ -557,6 +567,10 @@ __decorate2([
557
567
  consume2({ context: qtiContext, subscribe: true }),
558
568
  state()
559
569
  ], QtiExpression.prototype, "qtiContext", void 0);
570
+ __decorate2([
571
+ consume2({ context: testContext, subscribe: true }),
572
+ state()
573
+ ], QtiExpression.prototype, "_testContext", void 0);
560
574
 
561
575
  // ../qti-base/dist/abstract/qti-condition-expression.js
562
576
  var QtiConditionExpression = class extends QtiExpression {
@@ -628,8 +642,41 @@ var QtiFeedback = class extends LitElement4 {
628
642
  this.#showFeedback(isFound);
629
643
  }
630
644
  #showFeedback(value) {
645
+ if (!this.#sessionControlAllowsFeedback()) {
646
+ this.showStatus = "off";
647
+ return;
648
+ }
631
649
  this.showStatus = value && this.showHide === "show" || !value && this.showHide === "hide" ? "on" : "off";
632
650
  }
651
+ /**
652
+ * The QTI `show-feedback` constraint governs exactly one state: after the end of
653
+ * the last attempt. Up to that point the spec requires any applicable feedback to
654
+ * be shown — "a value of max-attempts greater than 1, by definition, indicates
655
+ * that any applicable feedback must be shown" — and only "once the maximum number
656
+ * of allowed attempts have been used (or for adaptive items, completionStatus has
657
+ * been set to completed)" does `show-feedback` decide.
658
+ *
659
+ * This only ever forces feedback off, so `show-feedback` being true settles it:
660
+ * there is no state in which the constraint hides feedback. It defaults to
661
+ * false, and an absent value suppresses once the attempts are gone.
662
+ *
663
+ * That leaves one question — is the item out of attempts? — and the two item
664
+ * kinds answer it from different variables, so each reads only its own.
665
+ */
666
+ #sessionControlAllowsFeedback() {
667
+ if (!this._computedContext)
668
+ return true;
669
+ const activeItem = this._computedContext.testParts?.find((tp) => tp.active)?.sections.flatMap((s) => s.items).find((i) => i.active);
670
+ if (!activeItem || activeItem.showFeedback)
671
+ return true;
672
+ if (activeItem.adaptive)
673
+ return activeItem.completionStatus !== "completed";
674
+ const maxAttempts = activeItem.maxAttempts ?? 1;
675
+ if (maxAttempts <= 0)
676
+ return true;
677
+ const numAttempts = Number(this._context?.variables?.find((v) => v.identifier === "numAttempts")?.value) || 0;
678
+ return numAttempts < maxAttempts;
679
+ }
633
680
  };
634
681
  __decorate3([
635
682
  property2({ type: String, attribute: "show-hide" })
@@ -647,6 +694,10 @@ __decorate3([
647
694
  consume3({ context: itemContext, subscribe: true }),
648
695
  state2()
649
696
  ], QtiFeedback.prototype, "_context", void 0);
697
+ __decorate3([
698
+ consume3({ context: computedContext, subscribe: true }),
699
+ state2()
700
+ ], QtiFeedback.prototype, "_computedContext", void 0);
650
701
 
651
702
  // ../qti-base/dist/lib/response.js
652
703
  function parseResponseAttribute(raw) {
@@ -914,4 +965,4 @@ export {
914
965
  QtiRuleElement,
915
966
  ScoringHelper
916
967
  };
917
- //# sourceMappingURL=chunk-EKXZI26R.js.map
968
+ //# sourceMappingURL=chunk-7D3NKAGZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../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/elements.ts","../../qti-base/src/register.ts"],"sourcesContent":["/**\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","/**\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","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"]}