import { C as ComputedItemContext } from './session.context.d-Cw8GcziG.js'; export { I as INITIAL_SESSION_CONTEXT, S as SessionContext, V as View, s as sessionContext } from './session.context.d-Cw8GcziG.js'; import { C as ComputedContext } from './computed.types.d-SsTm3ieP.js'; export { a as ComputedItem } from './computed.types.d-SsTm3ieP.js'; export { C as ConfigContext, V as ValidationDisplayMode, c as configContext } from './config.context.d-BvU9r-Mg.js'; export { C as ChoiceRole, I as Interaction, a as InteractionContext, R as RecordFieldValues, b as RecordValue, i as inferRecordFieldBaseType, c as interactionContext, d as isRecordValue, r as readRecordFieldValues } from './record.d-wB9uYs-j.js'; import { b as ItemContext, B as BaseType } from './item.types.d-DuVR0ZVK.js'; export { C as Calculate, a as Cardinality, I as InterpolationTableEntry, M as Multiple, O as Ordered, c as OutcomeVariable, Q as QtiAreaMapEntry, d as QtiAreaMapping, e as QtiMapEntry, f as QtiMapping, R as ResponseInteraction, g as ResponseVariable, T as TemplateVariable, V as VariableDeclaration, h as VariableValue, i as areaShape, j as directedPair, k as float, l as integer, m as itemContextVariables } from './item.types.d-DuVR0ZVK.js'; 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'; export { I as INITIAL_TEST_CONTEXT, Q as QtiExpression, a as QtiExpressionBase, T as TestContext, t as testContext } from './qti-expression.d-B-Cfbqlb.js'; import * as lit from 'lit'; export { Q as QtiFeedback, a as QtiVariableDeclaration } from './qti-feedback.d-DbzPSJuK.js'; export { Q as QtiConditionExpression } from './qti-condition-expression.d-B-T1NNl0.js'; 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'; 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'; export { Q as QtiExitResponseSignal, a as QtiExitTestSignal, b as QtiRuleBase, c as QtiRuleElement } from './qti-rule-base.d-Bdzg8eGH.js'; declare const computedItemContext: { __context__: Readonly; }; declare const computedContext: { __context__: Readonly; }; declare const itemContext: { __context__: ItemContext; }; /** * The border-box reset, for shadow trees. * * `modern-normalize` applies `*, ::before, ::after { box-sizing: border-box }` to the document, * but a universal selector never crosses a shadow boundary: every shadow root starts over at * the UA default, `content-box`. So each component has to opt in, and until now 15 of them did * so ad hoc — one of them with `content-box`, one with `!important`. * * Why this matters beyond tidiness: under `content-box`, padding and border are *size*. A rule * that only means to repaint a chip — `:state(dragging) { border: none }` — silently shrinks it * by two pixels per axis, the drag bank rewraps, and a drop target slides out from under the * user's pointer mid-drag. Border-box is what makes "a state may repaint but never re-lay-out" * a rule the CSS can actually keep. * * `:host` is set explicitly and descendants inherit, so a component that genuinely needs * `content-box` for a subtree (an image map, say) can opt out at one node and have it hold for * everything below it. */ declare const boxSizing: lit.CSSResult; /** * The `drop` region of every drop target. * * One rule: **a drop container hosts a chip, it never sizes one.** No `flex: 1`, no stretch, no * centring. The chip's box is decided by the chip — in the drag bank, mid-flight as a clone, and * once dropped — and a container that centres or stretches it makes the drop the one place where * that stops being true. That is felt as the chip jumping the instant it lands. * * `flex: 0 1 auto` on the children says "intrinsic size, no growing, shrink if you must". * `align-items: flex-start` stops the cross axis stretching them, which is the flex default and * the reason a chip in a tall dropzone used to grow to fill it. * * The shrink half used to be 0 as well, on the reading that a drop must not resize a chip. It does * not say that. `flex-shrink: 0` does not preserve the chip's size, it preserves the chip's * UNCONSTRAINED max-content size — and those are the same number only while the bank is wide enough * to give the chip its full width. Once the bank is narrower, the bank chip (`flex: 0 1 auto`, like * any flex item) shrinks and wraps, the placed chip does not, and the two disagree. * * Measured on the order fixture, bank vs placed: 209x36 / 209x36 at a 480px interaction, but * 204x55 / 209x36 at 440px and 154x55 / 209x36 at 340px — the placed chip a fixed 209px wide, * overflowing a drop that had correctly reserved 156px for it. It reached CI as a font difference: * the same label measures ~227px under the Linux fonts, which puts 480px on the wrong side of the * boundary too. * * Shrinking cannot make a placed chip smaller than the reservation, because the reservation IS the * measured chip (`--qti-dropzone-min-*`, applied to this region's content box). So the floor a * shrink stops at is the chip's own size, which is the rule above, not an exception to it. * `flex-grow: 0` is what actually prevents the stretch this block cares about, and it is untouched. * * A container that wants a *minimum* size still declares one (see `--qti-dropzone-min-*`). That * sizes the container, never its contents. * * Verified by drag-drop.invariance.spec.ts: "a chip is the same chip wherever it lives" — including * the narrow-bank order fixture, which is there because the wide one passes either way. */ declare const dropRegion: lit.CSSResult; /** * The `#validation-message` region every interaction renders, hidden until there is a message. * * `Interaction` owns showing and hiding it: `reportValidity` sets * `display: block !important` inline when `_internals.validationMessage` is non-empty, and clears the * text and sets `display: none` inline again when it is not (see interaction.ts). An inline * `!important` beats this rule, so the JS still wins whenever it speaks. * * What it did not own was the *initial* state. Before first validation the div has no inline style, * so it needs a stylesheet to start hidden — otherwise it paints as an empty box with the theme's * warning border and padding. That hide used to be a `display: none` inside the theme's * `validation-message` mixin, which made a document stylesheet responsible for a shadow node's box. * Two components had already noticed and worked around it with `style="display:none"` in their * template; the other five relied on the theme. * * The theme still paints the message — colour, border, padding, radius — via `::part(message)`. */ declare const validationMessage: lit.CSSResult; /** * The registry behind ``. * * A custom operator is by definition outside the QTI vocabulary, so which ones * exist is a property of the delivery engine rather than of an item. An item * names one in its `definition` attribute and the engine supplies it — here, * through this registry. * * This is the second of two mechanisms on `qti-custom-operator`. The other runs * inline JavaScript out of a CDATA section and is selected with * `class="js.org"`; it stays as it is. `definition` is what items authored * against the Citolab scoring engine use, and the two do not interact. */ type CustomOperatorValue = string | string[] | number | boolean | null; /** * Handed the calculated values of the element's child expressions, in document * order, and returns the value of the expression. */ type CustomOperator = (values: CustomOperatorValue[]) => CustomOperatorValue; /** * Make an operator available to every `qti-custom-operator` that names it. * * The key is the `definition` attribute in full, prefix included. Registering a * key a built-in already uses overrides that built-in, which is how a delivery * engine replaces one it disagrees with. */ declare const registerCustomOperator: (definition: string, operator: CustomOperator) => void; /** Undo a {@link registerCustomOperator}, restoring any built-in of that name. */ declare const unregisterCustomOperator: (definition: string) => void; /** The operator for a `definition`, or null when nothing provides it. */ declare const getCustomOperator: (definition: string) => CustomOperator | null; /** * Custom-state support shim for browsers this library cannot use natively. * * Interactions track selection and correct/incorrect marking through * `internals.states`, with bare state names (`checked`, `radio`, * `correct-response`, …). Two browser profiles cannot service that: * * - Safari 16.4–17.3 implement `ElementInternals` but not `CustomStateSet`, so * `internals.states` is `undefined` and reading it throws — "undefined is not * an object (evaluating 'internals.states.has')". * - Chrome and Edge before the CSS custom-state spec change expose `states` but * reject names that do not start with `--`, so `states.add('radio')` throws * "The specified value 'radio' must start with '--'". * * On both, picking a choice throws rather than registering. `attachInternals` * itself is unguarded throughout the interaction base classes, which puts the * hard support floor at Safari 16.4 — inside the range that breaks. * * The shim replaces `states` with a permissive `Set` and mirrors its contents to * a space-separated `data-state` attribute on the host, because these browsers' * CSS parsers also drop any selector list containing `:state()`. The theme's * built stylesheets pair every `:state(x)` with a `[data-state~='x']` arm (see * `tools/postcss/custom-state-fallback.mjs`), so styling survives too. * * Support is classified by behaviour rather than by browser version, and the * shim is not installed at all where `states` works. */ /** A permissive `CustomStateSet` that mirrors its contents to `data-state`. */ declare class CustomStateSetShim extends Set { #private; constructor(host: HTMLElement); add(state: string): this; delete(state: string): boolean; clear(): void; } type CustomStateSupport = 'missing' | 'legacy' | 'modern'; /** * Classify native custom-state support by behaviour: * * - `missing`: `ElementInternals` carries no `states` at all. * - `legacy`: `states` exists but rejects a bare name. * - `modern`: `states` exists and accepts a bare name — no shim wanted. * * `attachInternals` only works on a custom element, so the probe registers a * throwaway one. That happens solely when `states` is present, so the `missing` * path never defines anything. */ declare function classifyCustomStateSupport(attachInternals: (this: HTMLElement) => ElementInternals): CustomStateSupport; /** * Patch `HTMLElement.prototype.attachInternals` so every element's `states` is * the shim, on the two profiles that need it. Idempotent, and a no-op where * native support is usable. * * Returns the classification that was acted on, which is what the tests assert. */ declare function installCustomStateSetFallback(): CustomStateSupport | 'already-installed'; declare class ScoringHelper { /** * Checks if a given point is within a specified area. * @param point The point to test, represented as a string "x y" (e.g., "102 113"). * @param areaKey The area definition, including shape and coordinates (e.g., "circle,102,113,16"). * @param baseType The base type of the response, must be "point" for this method to proceed. * @returns True if the point is within the area; false otherwise. */ static isPointInArea(point: string, areaKey: string, baseType: string): boolean; /** * Checks if a point is inside a polygon using the ray-casting algorithm. * @param point The point to test. * @param vertices The vertices of the polygon in order (array of {x, y} objects). * @returns True if the point is inside the polygon; false otherwise. */ static isPointInPolygon(point: { x: number; y: number; }, vertices: { x: number; y: number; }[]): boolean; static compareSingleValues(value1: Readonly, value2: Readonly, baseType: BaseType): boolean; } declare const decimalSeparator: () => string; /** * Renders a number the way QTI stores one: a plain decimal string with `.` as the separator and no * grouping, whatever the browser's locale is. Strings are already in that form and pass through. * * `Number.prototype.toString()` is exactly that format. The locale-aware versions this used to call * are not: under a comma-decimal locale (nl, de, fr, ...) it ran `.replace('.', '')` over a string * that always uses `.`, so a score of 0.5 was stored as "05" and 1.5 as "15" — an item's SCORE came * out ten times too big for every value with a fraction. Under a dot-decimal locale * `toLocaleString()` grouped thousands instead, turning 1234.5 into "1,234.5". */ declare const convertNumberToUniversalFormat: (number: number | string) => string; declare function IsNullOrUndefined(value: unknown): boolean; declare function removeDoubleSlashes(str: string): string; export { BaseType, ComputedContext, ComputedItemContext, type CustomOperator, type CustomOperatorValue, CustomStateSetShim, type CustomStateSupport, IsNullOrUndefined, ItemContext, ScoringHelper, boxSizing, classifyCustomStateSupport, computedContext, computedItemContext, convertNumberToUniversalFormat, decimalSeparator, dropRegion, getCustomOperator, installCustomStateSetFallback, itemContext, registerCustomOperator, removeDoubleSlashes, unregisterCustomOperator, validationMessage };