@qti-components/processing 1.4.1 → 1.6.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.
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +4 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/qti-container-size/qti-container-size.d.ts +2 -0
- package/dist/components/qti-container-size/qti-container-size.js +3 -0
- package/dist/components/qti-container-size/qti-container-size.js.map +1 -1
- package/dist/components/qti-contains/qti-contains.d.ts +24 -3
- package/dist/components/qti-contains/qti-contains.js +82 -30
- package/dist/components/qti-contains/qti-contains.js.map +1 -1
- package/dist/components/qti-default/qti-default.js +0 -1
- package/dist/components/qti-default/qti-default.js.map +1 -1
- package/dist/components/qti-divide/qti-divide.d.ts +3 -0
- package/dist/components/qti-divide/qti-divide.js +4 -0
- package/dist/components/qti-divide/qti-divide.js.map +1 -1
- package/dist/components/qti-equal/qti-equal.d.ts +12 -1
- package/dist/components/qti-equal/qti-equal.js +51 -7
- package/dist/components/qti-equal/qti-equal.js.map +1 -1
- package/dist/components/qti-equal-rounded/qti-equal-rounded.js +9 -1
- package/dist/components/qti-equal-rounded/qti-equal-rounded.js.map +1 -1
- package/dist/components/qti-exit-response/qti-exit-response.d.ts +17 -0
- package/dist/components/qti-exit-response/qti-exit-response.js +16 -0
- package/dist/components/qti-exit-response/qti-exit-response.js.map +1 -0
- package/dist/components/qti-exit-test/qti-exit-test.d.ts +16 -0
- package/dist/components/qti-exit-test/qti-exit-test.js +15 -0
- package/dist/components/qti-exit-test/qti-exit-test.js.map +1 -0
- package/dist/components/qti-field-value/qti-field-value.d.ts +7 -1
- package/dist/components/qti-field-value/qti-field-value.js +15 -12
- package/dist/components/qti-field-value/qti-field-value.js.map +1 -1
- package/dist/components/qti-gte/qti-gte.js +1 -1
- package/dist/components/qti-gte/qti-gte.js.map +1 -1
- package/dist/components/qti-integer-divide/qti-integer-divide.d.ts +2 -0
- package/dist/components/qti-integer-divide/qti-integer-divide.js +3 -0
- package/dist/components/qti-integer-divide/qti-integer-divide.js.map +1 -1
- package/dist/components/qti-integer-modulus/qti-integer-modulus.d.ts +3 -1
- package/dist/components/qti-integer-modulus/qti-integer-modulus.js +9 -2
- package/dist/components/qti-integer-modulus/qti-integer-modulus.js.map +1 -1
- package/dist/components/qti-integer-to-float/qti-integer-to-float.d.ts +2 -0
- package/dist/components/qti-integer-to-float/qti-integer-to-float.js +3 -0
- package/dist/components/qti-integer-to-float/qti-integer-to-float.js.map +1 -1
- package/dist/components/qti-is-null/qti-is-null.js +4 -1
- package/dist/components/qti-is-null/qti-is-null.js.map +1 -1
- package/dist/components/qti-lookup-outcome-value/qti-lookup-outcome-value.d.ts +2 -1
- package/dist/components/qti-lookup-outcome-value/qti-lookup-outcome-value.js +29 -5
- package/dist/components/qti-lookup-outcome-value/qti-lookup-outcome-value.js.map +1 -1
- package/dist/components/qti-lte/qti-lte.js +1 -1
- package/dist/components/qti-lte/qti-lte.js.map +1 -1
- package/dist/components/qti-map-response-point/qti-map-response-point.js +6 -0
- package/dist/components/qti-map-response-point/qti-map-response-point.js.map +1 -1
- package/dist/components/qti-math-constant/qti-math-constant.d.ts +20 -0
- package/dist/components/qti-math-constant/qti-math-constant.js +40 -0
- package/dist/components/qti-math-constant/qti-math-constant.js.map +1 -0
- package/dist/components/qti-math-operator/qti-math-operator.d.ts +6 -0
- package/dist/components/qti-math-operator/qti-math-operator.js +43 -1
- package/dist/components/qti-math-operator/qti-math-operator.js.map +1 -1
- package/dist/components/qti-multiple/qti-multiple.js +0 -2
- package/dist/components/qti-multiple/qti-multiple.js.map +1 -1
- package/dist/components/qti-pattern-match/qti-pattern-match.d.ts +1 -0
- package/dist/components/qti-pattern-match/qti-pattern-match.js +28 -4
- package/dist/components/qti-pattern-match/qti-pattern-match.js.map +1 -1
- package/dist/components/qti-power/qti-power.d.ts +2 -0
- package/dist/components/qti-power/qti-power.js +3 -0
- package/dist/components/qti-power/qti-power.js.map +1 -1
- package/dist/components/qti-printed-variable/printed-variable-format.d.ts +19 -0
- package/dist/components/qti-printed-variable/printed-variable-format.js +113 -0
- package/dist/components/qti-printed-variable/printed-variable-format.js.map +1 -0
- package/dist/components/qti-printed-variable/qti-printed-variable.d.ts +26 -0
- package/dist/components/qti-printed-variable/qti-printed-variable.js +96 -2
- package/dist/components/qti-printed-variable/qti-printed-variable.js.map +1 -1
- package/dist/components/qti-random/qti-random.js +0 -1
- package/dist/components/qti-random/qti-random.js.map +1 -1
- package/dist/components/qti-repeat/qti-repeat.d.ts +0 -8
- package/dist/components/qti-repeat/qti-repeat.js +15 -2
- package/dist/components/qti-repeat/qti-repeat.js.map +1 -1
- package/dist/components/qti-response-processing-fragment/qti-response-processing-fragment.d.ts +19 -0
- package/dist/components/qti-response-processing-fragment/qti-response-processing-fragment.js +19 -0
- package/dist/components/qti-response-processing-fragment/qti-response-processing-fragment.js.map +1 -0
- package/dist/components/qti-round/qti-round.d.ts +2 -0
- package/dist/components/qti-round/qti-round.js +3 -0
- package/dist/components/qti-round/qti-round.js.map +1 -1
- package/dist/components/qti-round-to/qti-round-to.d.ts +2 -0
- package/dist/components/qti-round-to/qti-round-to.js +3 -0
- package/dist/components/qti-round-to/qti-round-to.js.map +1 -1
- package/dist/components/qti-stats-operator/qti-stats-operator.d.ts +3 -1
- package/dist/components/qti-stats-operator/qti-stats-operator.js +29 -7
- package/dist/components/qti-stats-operator/qti-stats-operator.js.map +1 -1
- package/dist/components/qti-truncate/qti-truncate.d.ts +2 -0
- package/dist/components/qti-truncate/qti-truncate.js +3 -0
- package/dist/components/qti-truncate/qti-truncate.js.map +1 -1
- package/dist/elements.d.ts +17 -1
- package/dist/elements.js +9 -1
- package/dist/elements.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-printed-variable.js","sourceRoot":"","sources":["../../../src/components/qti-printed-variable/qti-printed-variable.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"qti-printed-variable.js","sourceRoot":"","sources":["../../../src/components/qti-printed-variable/qti-printed-variable.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { LitElement, html, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { itemContext } from '@qti-components/base';\n\nimport { applyFormat, toExponential } from './printed-variable-format';\n\nimport type { BaseType } from '@qti-components/base';\nimport type { VariableDeclaration } from '@qti-components/base';\nimport type { ItemContext } from '@qti-components/base';\n\n/**\n * @summary Prints the value of an item variable into the item body.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#printedVariable\n *\n * A container variable is printed as its values joined by `delimiter`; a record as\n * `name<mapping-indicator>value` pairs joined by the same delimiter. A NULL variable — absent,\n * null, or an empty container — prints nothing at all.\n *\n * @attr {string} identifier - Required. Identifier of the variable to print.\n * @attr {string} [format] - printf-style conversion string, e.g. `%.2f` or `Score: %d`. Applies\n * to each value printed. Takes precedence over `base` and `power-form`.\n * @attr {number} [base=10] - Number base used when printing an integer variable.\n * @attr {number} [index] - 1-based index selecting a single value of an ordered variable.\n * @attr {boolean} [power-form=false] - Print numeric values in exponential form.\n * @attr {string} [field] - Field of a record variable to print, instead of the whole record.\n * @attr {string} [delimiter=;] - Separator between the values of an ordered/multiple/record variable.\n * @attr {string} [mapping-indicator==] - Separator between a record field's name and its value.\n */\nexport class QtiPrintedVariable extends LitElement {\n @property({ type: String })\n identifier: string;\n\n @property({ type: String })\n format?: string;\n\n @property({ type: Number })\n base = 10;\n\n @property({ type: Number })\n index?: number;\n\n @property({ type: Boolean, attribute: 'power-form' })\n powerForm = false;\n\n @property({ type: String })\n field?: string;\n\n @property({ type: String })\n delimiter = ';';\n\n @property({ type: String, attribute: 'mapping-indicator' })\n mappingIndicator = '=';\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n protected context?: ItemContext;\n\n override render() {\n const variable = this.context?.variables.find(v => v.identifier === this.identifier);\n const printed = variable ? this.#print(variable) : null;\n return printed === null ? nothing : html`${printed}`;\n }\n\n /** Returns `null` for anything QTI treats as NULL, which prints as nothing. */\n #print(variable: VariableDeclaration<unknown>): string | null {\n const value = variable.value;\n if (value === null || value === undefined) return null;\n\n if (Array.isArray(value)) {\n if (value.length === 0) return null;\n if (this.index !== undefined) {\n const selected = value[this.index - 1];\n return selected === null || selected === undefined ? null : this.#printValue(selected, variable.baseType);\n }\n return value.map(entry => this.#printValue(entry, variable.baseType)).join(this.delimiter);\n }\n\n if (typeof value === 'object') {\n const record = value as Record<string, unknown>;\n if (this.field !== undefined) {\n const selected = record[this.field];\n return selected === null || selected === undefined ? null : this.#printValue(selected, variable.baseType);\n }\n const fields = Object.entries(record).filter(([, entry]) => entry !== null && entry !== undefined);\n if (fields.length === 0) return null;\n return fields\n .map(([name, entry]) => `${name}${this.mappingIndicator}${this.#printValue(entry, variable.baseType)}`)\n .join(this.delimiter);\n }\n\n return this.#printValue(value, variable.baseType);\n }\n\n #printValue(value: unknown, baseType?: BaseType): string {\n // A pair/directedPair arrives as its two identifiers; QTI writes them space separated.\n const raw = Array.isArray(value) ? value.join(' ') : String(value);\n\n if (this.format) return applyFormat(this.format, raw);\n\n if (baseType === 'integer' && this.base !== 10) {\n const integer = Number.parseInt(raw, 10);\n if (Number.isFinite(integer)) return integer.toString(this.base);\n }\n\n if (this.powerForm) {\n const numeric = Number(raw);\n if (raw.trim() !== '' && Number.isFinite(numeric)) return toExponential(numeric);\n }\n\n return raw;\n }\n\n public calculate(): VariableDeclaration<string | string[]> {\n const result = this.context.variables.find(v => v.identifier === this.identifier) || null;\n return result;\n }\n}\n"]}
|
|
@@ -2,7 +2,6 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
2
2
|
export class QtiRandom extends QtiExpression {
|
|
3
3
|
getResult() {
|
|
4
4
|
const values = this.getVariables();
|
|
5
|
-
// console.log(values);
|
|
6
5
|
if (values.length === 1) {
|
|
7
6
|
const value = values[0].value;
|
|
8
7
|
if (Array.isArray(value)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-random.js","sourceRoot":"","sources":["../../../src/components/qti-random/qti-random.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,SAAU,SAAQ,aAAqB;IAClC,SAAS;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"qti-random.js","sourceRoot":"","sources":["../../../src/components/qti-random/qti-random.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,SAAU,SAAQ,aAAqB;IAClC,SAAS;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC7D,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC;YAC5B,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nexport class QtiRandom extends QtiExpression<string> {\n public override getResult() {\n const values = this.getVariables();\n\n if (values.length === 1) {\n const value = values[0].value;\n if (Array.isArray(value)) {\n const randomIndex = Math.floor(Math.random() * value.length);\n return value[randomIndex];\n }\n return value;\n }\n console.error('unexpected number of children in match');\n return null;\n }\n}\n"]}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
2
|
import type { ResponseVariable } from '@qti-components/base';
|
|
3
|
-
/**
|
|
4
|
-
* @summary The qti-repeat operator generates a container by repeating an expression.
|
|
5
|
-
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#repeat
|
|
6
|
-
*
|
|
7
|
-
* Attributes 'number-repeats' determines the count of iterations.
|
|
8
|
-
* Returns an ordered container filled with results of the evaluated sub-expressions.
|
|
9
|
-
* Special cases: Returns NULL if number-repeats < 1; ignores evaluated NULL values.
|
|
10
|
-
*/
|
|
11
3
|
export declare class QtiRepeat extends QtiExpression<ResponseVariable[]> {
|
|
12
4
|
#private;
|
|
13
5
|
numberRepeats: string;
|
|
@@ -14,6 +14,12 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
14
14
|
* Returns an ordered container filled with results of the evaluated sub-expressions.
|
|
15
15
|
* Special cases: Returns NULL if number-repeats < 1; ignores evaluated NULL values.
|
|
16
16
|
*/
|
|
17
|
+
/**
|
|
18
|
+
* `number-repeats` may name a variable, so the count is only known at run time
|
|
19
|
+
* and nothing stops an item from asking for millions of iterations. Capped so a
|
|
20
|
+
* bad value costs a warning rather than a hung tab.
|
|
21
|
+
*/
|
|
22
|
+
const MAX_REPEATS = 1000;
|
|
17
23
|
export class QtiRepeat extends QtiExpression {
|
|
18
24
|
constructor() {
|
|
19
25
|
super(...arguments);
|
|
@@ -46,7 +52,7 @@ export class QtiRepeat extends QtiExpression {
|
|
|
46
52
|
}
|
|
47
53
|
const numericCount = parseInt(this.numberRepeats, 10);
|
|
48
54
|
if (!Number.isNaN(numericCount)) {
|
|
49
|
-
return numericCount;
|
|
55
|
+
return this.#cap(numericCount);
|
|
50
56
|
}
|
|
51
57
|
const identifier = this.numberRepeats;
|
|
52
58
|
const variable = this.context?.variables?.find(v => v.identifier === identifier);
|
|
@@ -60,7 +66,14 @@ export class QtiRepeat extends QtiExpression {
|
|
|
60
66
|
console.warn(`qti-repeat: invalid repeat count from "${identifier}"`);
|
|
61
67
|
return 0;
|
|
62
68
|
}
|
|
63
|
-
return resolvedCount;
|
|
69
|
+
return this.#cap(resolvedCount);
|
|
70
|
+
}
|
|
71
|
+
#cap(count) {
|
|
72
|
+
if (count > MAX_REPEATS) {
|
|
73
|
+
console.warn(`qti-repeat: number-repeats ${count} exceeds the ${MAX_REPEATS} limit, truncating`);
|
|
74
|
+
return MAX_REPEATS;
|
|
75
|
+
}
|
|
76
|
+
return count;
|
|
64
77
|
}
|
|
65
78
|
#toResponseVariable(value) {
|
|
66
79
|
if (value === null || value === undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-repeat.js","sourceRoot":"","sources":["../../../src/components/qti-repeat/qti-repeat.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,SAAU,SAAQ,aAAiC;IAAhE;;QAC2D,kBAAa,GAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"qti-repeat.js","sourceRoot":"","sources":["../../../src/components/qti-repeat/qti-repeat.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH;;;;GAIG;AACH,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB,MAAM,OAAO,SAAU,SAAQ,aAAiC;IAAhE;;QAC2D,kBAAa,GAAW,EAAE,CAAC;IA8GtF,CAAC;IA5GiB,SAAS;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAkD,CAAC;QAC3E,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YACrD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAuB,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAC7D,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACjF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,mCAAmC,UAAU,GAAG,CAAC,CAAC;YAC/D,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpF,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAE/D,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,0CAA0C,UAAU,GAAG,CAAC,CAAC;YACtE,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,KAAa;QAChB,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,8BAA8B,KAAK,gBAAgB,WAAW,oBAAoB,CAAC,CAAC;YACjG,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mBAAmB,CAAC,KAAc;QAChC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO;gBACL,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,QAAQ;gBACrB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;gBACvD,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;gBACvB,IAAI,EAAE,UAAU;aACG,CAAC;QACxB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,OAAO;oBACL,UAAU,EAAE,EAAE;oBACd,WAAW,EAAE,QAAQ;oBACrB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;oBAC9D,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;oBACvB,IAAI,EAAE,UAAU;iBACG,CAAC;YACxB,CAAC;QACH,CAAC;QAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAK,KAA0B,EAAE,CAAC;YACjF,MAAM,aAAa,GAAI,KAA0B,CAAC,KAAK,CAAC;YACxD,OAAO;gBACL,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,QAAQ;gBACrB,QAAQ,EAAG,KAA0B,CAAC,QAAQ,IAAI,QAAQ;gBAC1D,KAAK,EAAE,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;gBAC9F,IAAI,EAAE,UAAU;aACG,CAAC;QACxB,CAAC;QAED,OAAO;YACL,UAAU,EAAE,EAAE;YACd,WAAW,EAAE,QAAQ;YACrB,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;YACvB,IAAI,EAAE,UAAU;SACG,CAAC;IACxB,CAAC;CACF;AA9G0D;IAAxD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;gDAA4B","sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { QtiExpression } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-repeat operator generates a container by repeating an expression.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#repeat\n *\n * Attributes 'number-repeats' determines the count of iterations.\n * Returns an ordered container filled with results of the evaluated sub-expressions.\n * Special cases: Returns NULL if number-repeats < 1; ignores evaluated NULL values.\n */\n/**\n * `number-repeats` may name a variable, so the count is only known at run time\n * and nothing stops an item from asking for millions of iterations. Capped so a\n * bad value costs a warning rather than a hung tab.\n */\nconst MAX_REPEATS = 1000;\n\nexport class QtiRepeat extends QtiExpression<ResponseVariable[]> {\n @property({ type: String, attribute: 'number-repeats' }) numberRepeats: string = '';\n\n public override getResult(): ResponseVariable[] {\n const count = this.#resolveRepeatCount();\n if (count <= 0) {\n return [];\n }\n\n const expression = this.firstElementChild as QtiExpression<unknown> | null;\n if (!expression) {\n console.warn('qti-repeat: missing child expression');\n return [];\n }\n\n const results: ResponseVariable[] = [];\n for (let i = 0; i < count; i++) {\n const value = expression.calculate();\n const variable = this.#toResponseVariable(value);\n if (variable) {\n results.push(variable);\n }\n }\n\n return results;\n }\n\n #resolveRepeatCount(): number {\n if (!this.numberRepeats) {\n console.warn('qti-repeat: missing number-repeats attribute');\n return 0;\n }\n\n const numericCount = parseInt(this.numberRepeats, 10);\n if (!Number.isNaN(numericCount)) {\n return this.#cap(numericCount);\n }\n\n const identifier = this.numberRepeats;\n const variable = this.context?.variables?.find(v => v.identifier === identifier);\n if (!variable) {\n console.warn(`qti-repeat: unknown identifier \"${identifier}\"`);\n return 0;\n }\n\n const rawValue = Array.isArray(variable.value) ? variable.value[0] : variable.value;\n const resolvedCount = parseInt(rawValue?.toString() ?? '', 10);\n\n if (Number.isNaN(resolvedCount)) {\n console.warn(`qti-repeat: invalid repeat count from \"${identifier}\"`);\n return 0;\n }\n\n return this.#cap(resolvedCount);\n }\n\n #cap(count: number): number {\n if (count > MAX_REPEATS) {\n console.warn(`qti-repeat: number-repeats ${count} exceeds the ${MAX_REPEATS} limit, truncating`);\n return MAX_REPEATS;\n }\n return count;\n }\n\n #toResponseVariable(value: unknown): ResponseVariable | null {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'number') {\n return {\n identifier: '',\n cardinality: 'single',\n baseType: Number.isInteger(value) ? 'integer' : 'float',\n value: value.toString(),\n type: 'response'\n } as ResponseVariable;\n }\n\n if (typeof value === 'string') {\n const numericValue = parseFloat(value);\n if (!Number.isNaN(numericValue)) {\n return {\n identifier: '',\n cardinality: 'single',\n baseType: Number.isInteger(numericValue) ? 'integer' : 'float',\n value: value.toString(),\n type: 'response'\n } as ResponseVariable;\n }\n }\n\n if (value && typeof value === 'object' && 'value' in (value as ResponseVariable)) {\n const responseValue = (value as ResponseVariable).value;\n return {\n identifier: '',\n cardinality: 'single',\n baseType: (value as ResponseVariable).baseType ?? 'string',\n value: responseValue !== null && responseValue !== undefined ? responseValue.toString() : null,\n type: 'response'\n } as ResponseVariable;\n }\n\n return {\n identifier: '',\n cardinality: 'single',\n baseType: 'string',\n value: value.toString(),\n type: 'response'\n } as ResponseVariable;\n }\n}\n"]}
|
package/dist/components/qti-response-processing-fragment/qti-response-processing-fragment.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { QtiRule } from '../qti-rule/qti-rule';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-response-processing-fragment groups rules for reuse.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.response-processing-fragment
|
|
5
|
+
*
|
|
6
|
+
* A fragment is a transparent container: its rules run in place, in document
|
|
7
|
+
* order, exactly as if they had been written where the fragment sits.
|
|
8
|
+
*
|
|
9
|
+
* A fragment held in a separate file is not pulled in, because `qti-include` is
|
|
10
|
+
* not resolved — only the rules authored inside this element run.
|
|
11
|
+
*/
|
|
12
|
+
export declare class QtiResponseProcessingFragment extends QtiRule {
|
|
13
|
+
process(): void;
|
|
14
|
+
}
|
|
15
|
+
declare global {
|
|
16
|
+
interface HTMLElementTagNameMap {
|
|
17
|
+
'qti-response-processing-fragment': QtiResponseProcessingFragment;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { QtiRule } from '../qti-rule/qti-rule';
|
|
2
|
+
/**
|
|
3
|
+
* @summary The qti-response-processing-fragment groups rules for reuse.
|
|
4
|
+
* @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.response-processing-fragment
|
|
5
|
+
*
|
|
6
|
+
* A fragment is a transparent container: its rules run in place, in document
|
|
7
|
+
* order, exactly as if they had been written where the fragment sits.
|
|
8
|
+
*
|
|
9
|
+
* A fragment held in a separate file is not pulled in, because `qti-include` is
|
|
10
|
+
* not resolved — only the rules authored inside this element run.
|
|
11
|
+
*/
|
|
12
|
+
export class QtiResponseProcessingFragment extends QtiRule {
|
|
13
|
+
process() {
|
|
14
|
+
for (const rule of [...this.children]) {
|
|
15
|
+
rule.process();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=qti-response-processing-fragment.js.map
|
package/dist/components/qti-response-processing-fragment/qti-response-processing-fragment.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qti-response-processing-fragment.js","sourceRoot":"","sources":["../../../src/components/qti-response-processing-fragment/qti-response-processing-fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAI/C;;;;;;;;;GASG;AACH,MAAM,OAAO,6BAA8B,SAAQ,OAAO;IACxC,OAAO;QACrB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAA6B,EAAE,CAAC;YAClE,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;CACF","sourcesContent":["import { QtiRule } from '../qti-rule/qti-rule';\n\nimport type { QtiRuleBase } from '@qti-components/base';\n\n/**\n * @summary The qti-response-processing-fragment groups rules for reuse.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.response-processing-fragment\n *\n * A fragment is a transparent container: its rules run in place, in document\n * order, exactly as if they had been written where the fragment sits.\n *\n * A fragment held in a separate file is not pulled in, because `qti-include` is\n * not resolved — only the rules authored inside this element run.\n */\nexport class QtiResponseProcessingFragment extends QtiRule {\n public override process() {\n for (const rule of [...this.children] as unknown as QtiRuleBase[]) {\n rule.process();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-response-processing-fragment': QtiResponseProcessingFragment;\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
import type { BaseType } from '@qti-components/base';
|
|
2
3
|
/**
|
|
3
4
|
* @summary The qti-round operator rounds a numerical value to the nearest integer.
|
|
4
5
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#round
|
|
@@ -8,5 +9,6 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
8
9
|
* Special cases: Returns NULL if input is NULL or NaN.
|
|
9
10
|
*/
|
|
10
11
|
export declare class QtiRound extends QtiExpression<number | null> {
|
|
12
|
+
get resultBaseType(): BaseType;
|
|
11
13
|
getResult(): number | null;
|
|
12
14
|
}
|
|
@@ -8,6 +8,9 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
8
8
|
* Special cases: Returns NULL if input is NULL or NaN.
|
|
9
9
|
*/
|
|
10
10
|
export class QtiRound extends QtiExpression {
|
|
11
|
+
get resultBaseType() {
|
|
12
|
+
return 'integer';
|
|
13
|
+
}
|
|
11
14
|
getResult() {
|
|
12
15
|
if (this.children.length !== 1) {
|
|
13
16
|
console.error('qti-round must have exactly one child expression');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-round.js","sourceRoot":"","sources":["../../../src/components/qti-round/qti-round.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,QAAS,SAAQ,aAA4B;
|
|
1
|
+
{"version":3,"file":"qti-round.js","sourceRoot":"","sources":["../../../src/components/qti-round/qti-round.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,QAAS,SAAQ,aAA4B;IACxD,IAAoB,cAAc;QAChC,OAAO,SAAS,CAAC;IACnB,CAAC;IAEe,SAAS;QACvB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAwB,CAAC;QAC5D,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAE9B,oBAAoB;QACpB,IAAI,QAAQ,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,qBAAqB;QACrB,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB;QAClB,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrE,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC3E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oBAAoB;QACpB,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAe,CAAC,CAAC;QAE1D,uBAAuB;QACvB,IAAI,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5B,wBAAwB;YACxB,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,IAAI,YAAY,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CAAC,QAAQ,CAAC;YACnB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,sFAAsF;QACtF,iEAAiE;QACjE,wCAAwC;QACxC,4BAA4B;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC;IACxC,CAAC;CACF","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { BaseType, ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-round operator rounds a numerical value to the nearest integer.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#round\n *\n * Takes 1 numerical sub-expression of single cardinality.\n * Returns integer n for input in range [n-0.5, n+0.5).\n * Special cases: Returns NULL if input is NULL or NaN.\n */\nexport class QtiRound extends QtiExpression<number | null> {\n public override get resultBaseType(): BaseType {\n return 'integer';\n }\n\n public override getResult(): number | null {\n if (this.children.length !== 1) {\n console.error('qti-round must have exactly one child expression');\n return null;\n }\n\n const variables = this.getVariables() as ResponseVariable[];\n if (!variables || variables.length === 0) {\n return null;\n }\n\n const variable = variables[0];\n\n // Check cardinality\n if (variable.cardinality !== 'single') {\n console.error('qti-round requires single cardinality');\n return null;\n }\n\n // Check if value is array (shouldn't be for single cardinality)\n if (Array.isArray(variable.value)) {\n console.error('qti-round unexpected array value for single cardinality');\n return null;\n }\n\n // Handle null values\n if (variable.value === null || variable.value === undefined) {\n return null;\n }\n\n // Check base type\n if (variable.baseType !== 'integer' && variable.baseType !== 'float') {\n console.error('qti-round requires numerical base-type (integer or float)');\n return null;\n }\n\n // Convert to number\n const numericValue = parseFloat(variable.value as string);\n\n // Handle special cases\n if (isNaN(numericValue)) {\n console.warn('qti-round: NaN input results in NULL');\n return null;\n }\n\n if (!isFinite(numericValue)) {\n // Handle infinity cases\n if (numericValue === Infinity) {\n return Infinity;\n }\n if (numericValue === -Infinity) {\n return -Infinity;\n }\n return null;\n }\n\n // Apply QTI rounding rule: result is integer n for all input values in [n-0.5, n+0.5)\n // This means we need to find n such that: n-0.5 <= value < n+0.5\n // Rearranging: n <= value + 0.5 < n + 1\n // So n = floor(value + 0.5)\n return Math.floor(numericValue + 0.5);\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
import type { BaseType } from '@qti-components/base';
|
|
2
3
|
/**
|
|
3
4
|
* @summary The qti-round-to operator rounds a numerical value to specified precision.
|
|
4
5
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.round-to
|
|
@@ -11,5 +12,6 @@ export declare class QtiRoundTo extends QtiExpression<number | null> {
|
|
|
11
12
|
#private;
|
|
12
13
|
roundingMode: 'decimalPlaces' | 'significantFigures';
|
|
13
14
|
figures: number;
|
|
15
|
+
get resultBaseType(): BaseType;
|
|
14
16
|
getResult(): number | null;
|
|
15
17
|
}
|
|
@@ -20,6 +20,9 @@ export class QtiRoundTo extends QtiExpression {
|
|
|
20
20
|
this.roundingMode = 'significantFigures';
|
|
21
21
|
this.figures = 3;
|
|
22
22
|
}
|
|
23
|
+
get resultBaseType() {
|
|
24
|
+
return 'float';
|
|
25
|
+
}
|
|
23
26
|
getResult() {
|
|
24
27
|
if (this.children.length !== 1) {
|
|
25
28
|
console.error('qti-round-to must have exactly one child expression');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-round-to.js","sourceRoot":"","sources":["../../../src/components/qti-round-to/qti-round-to.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,UAAW,SAAQ,aAA4B;IAA5D;;QAEE,iBAAY,GAA2C,oBAAoB,CAAC;QAG5E,YAAO,GAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"qti-round-to.js","sourceRoot":"","sources":["../../../src/components/qti-round-to/qti-round-to.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { QtiExpression } from '@qti-components/base';\n\nimport type { BaseType, ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-round-to operator rounds a numerical value to specified precision.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.round-to\n *\n * Takes one sub-expression with single cardinality and numerical base-type.\n * Returns a single float rounded by the specified method to the specified precision.\n * Supports rounding to decimal places or significant figures.\n */\nexport class QtiRoundTo extends QtiExpression<number | null> {\n @property({ type: String, attribute: 'rounding-mode' })\n roundingMode: 'decimalPlaces' | 'significantFigures' = 'significantFigures';\n\n @property({ type: Number })\n figures: number = 3;\n\n public override get resultBaseType(): BaseType {\n return 'float';\n }\n\n public override getResult(): number | null {\n if (this.children.length !== 1) {\n console.error('qti-round-to must have exactly one child expression');\n return null;\n }\n\n const variables = this.getVariables() as ResponseVariable[];\n if (!variables || variables.length === 0) {\n return null;\n }\n\n const variable = variables[0];\n\n // Check cardinality\n if (variable.cardinality !== 'single') {\n console.error('qti-round-to requires single cardinality');\n return null;\n }\n\n // Check if value is array (shouldn't be for single cardinality)\n if (Array.isArray(variable.value)) {\n console.error('qti-round-to unexpected array value for single cardinality');\n return null;\n }\n\n // Handle null values\n if (variable.value === null || variable.value === undefined) {\n return null;\n }\n\n // Check base type\n if (variable.baseType !== 'integer' && variable.baseType !== 'float') {\n console.error('qti-round-to requires numerical base-type');\n return null;\n }\n\n // Convert to number\n const numericValue = parseFloat(variable.value as string);\n\n // Handle special cases\n if (isNaN(numericValue)) {\n return null;\n }\n\n if (!isFinite(numericValue)) {\n // Handle infinity cases\n if (numericValue === Infinity) {\n return Infinity;\n }\n if (numericValue === -Infinity) {\n return -Infinity;\n }\n return null;\n }\n\n // Validate figures\n if (this.figures < 0) {\n console.error('qti-round-to: figures must be non-negative');\n return null;\n }\n\n if (this.roundingMode === 'significantFigures' && this.figures < 1) {\n console.error('qti-round-to: figures must be at least 1 for significantFigures mode');\n return null;\n }\n\n // Perform rounding\n if (this.roundingMode === 'decimalPlaces') {\n return this.#roundToDecimalPlaces(numericValue, this.figures);\n } else {\n return this.#roundToSignificantFigures(numericValue, this.figures);\n }\n }\n\n /**\n * Round to specified number of decimal places\n */\n #roundToDecimalPlaces(value: number, decimalPlaces: number): number {\n if (value === 0) {\n return 0;\n }\n\n const multiplier = Math.pow(10, decimalPlaces);\n return Math.round(value * multiplier) / multiplier;\n }\n\n /**\n * Round to specified number of significant figures\n */\n #roundToSignificantFigures(value: number, significantFigures: number): number {\n if (value === 0) {\n return 0;\n }\n\n // Find the order of magnitude of the first non-zero digit\n const magnitude = Math.floor(Math.log10(Math.abs(value)));\n\n // Calculate the multiplier to shift the decimal point\n const multiplier = Math.pow(10, significantFigures - magnitude - 1);\n\n // Round and shift back\n return Math.round(value * multiplier) / multiplier;\n }\n}\n"]}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
import type { BaseType } from '@qti-components/base';
|
|
2
3
|
/**
|
|
3
4
|
* @summary The qti-stats-operator performs statistical calculations on a container.
|
|
4
5
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#statsOperator
|
|
5
6
|
*
|
|
6
7
|
* Takes 1 container (multiple/ordered) of numerical base-type.
|
|
7
|
-
* 'name' attribute identifies function (mean,
|
|
8
|
+
* 'name' attribute identifies function (mean, median, popVariance, popSD, sampleVariance, sampleSD).
|
|
8
9
|
* Returns result as a single float.
|
|
9
10
|
* Special cases: Returns NULL if any values in container are NULL or non-numerical.
|
|
10
11
|
*/
|
|
11
12
|
export declare class QtiStatsOperator extends QtiExpression<number | null> {
|
|
12
13
|
#private;
|
|
13
14
|
name: string;
|
|
15
|
+
get resultBaseType(): BaseType;
|
|
14
16
|
getResult(): number | null;
|
|
15
17
|
}
|
|
@@ -11,7 +11,7 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
11
11
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#statsOperator
|
|
12
12
|
*
|
|
13
13
|
* Takes 1 container (multiple/ordered) of numerical base-type.
|
|
14
|
-
* 'name' attribute identifies function (mean,
|
|
14
|
+
* 'name' attribute identifies function (mean, median, popVariance, popSD, sampleVariance, sampleSD).
|
|
15
15
|
* Returns result as a single float.
|
|
16
16
|
* Special cases: Returns NULL if any values in container are NULL or non-numerical.
|
|
17
17
|
*/
|
|
@@ -20,6 +20,9 @@ export class QtiStatsOperator extends QtiExpression {
|
|
|
20
20
|
super(...arguments);
|
|
21
21
|
this.name = '';
|
|
22
22
|
}
|
|
23
|
+
get resultBaseType() {
|
|
24
|
+
return 'float';
|
|
25
|
+
}
|
|
23
26
|
getResult() {
|
|
24
27
|
if (!this.name) {
|
|
25
28
|
console.warn('qti-stats-operator: missing name attribute');
|
|
@@ -32,18 +35,37 @@ export class QtiStatsOperator extends QtiExpression {
|
|
|
32
35
|
}
|
|
33
36
|
switch (this.name.toLowerCase()) {
|
|
34
37
|
case 'mean':
|
|
35
|
-
return values
|
|
38
|
+
return this.#mean(values);
|
|
39
|
+
case 'median':
|
|
40
|
+
return this.#median(values);
|
|
41
|
+
case 'popvariance':
|
|
42
|
+
return this.#variance(values, values.length);
|
|
36
43
|
case 'popsd':
|
|
37
|
-
return this.#
|
|
44
|
+
return Math.sqrt(this.#variance(values, values.length));
|
|
45
|
+
case 'samplevariance':
|
|
46
|
+
// A sample variance over a single observation has no denominator.
|
|
47
|
+
return values.length < 2 ? null : this.#variance(values, values.length - 1);
|
|
48
|
+
case 'samplesd':
|
|
49
|
+
return values.length < 2 ? null : Math.sqrt(this.#variance(values, values.length - 1));
|
|
38
50
|
default:
|
|
39
51
|
console.warn(`qti-stats-operator: unsupported operator "${this.name}"`);
|
|
40
52
|
return null;
|
|
41
53
|
}
|
|
42
54
|
}
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
#mean(values) {
|
|
56
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
57
|
+
}
|
|
58
|
+
#median(values) {
|
|
59
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
60
|
+
const middle = Math.floor(sorted.length / 2);
|
|
61
|
+
// An even-sized container has no single middle value, so the two straddling
|
|
62
|
+
// it are averaged.
|
|
63
|
+
return sorted.length % 2 === 0 ? (sorted[middle - 1] + sorted[middle]) / 2 : sorted[middle];
|
|
64
|
+
}
|
|
65
|
+
/** Sum of squared deviations over `denominator` — the population or sample divisor. */
|
|
66
|
+
#variance(values, denominator) {
|
|
67
|
+
const mean = this.#mean(values);
|
|
68
|
+
return values.reduce((sum, value) => sum + Math.pow(value - mean, 2), 0) / denominator;
|
|
47
69
|
}
|
|
48
70
|
#collectNumericValues(variables) {
|
|
49
71
|
const values = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-stats-operator.js","sourceRoot":"","sources":["../../../src/components/qti-stats-operator/qti-stats-operator.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;;GAQG;AACH,MAAM,OAAO,gBAAiB,SAAQ,aAA4B;IAAlE;;QAC8B,SAAI,GAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"qti-stats-operator.js","sourceRoot":"","sources":["../../../src/components/qti-stats-operator/qti-stats-operator.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { QtiExpression } from '@qti-components/base';\n\nimport type { BaseType, ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-stats-operator performs statistical calculations on a container.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#statsOperator\n *\n * Takes 1 container (multiple/ordered) of numerical base-type.\n * 'name' attribute identifies function (mean, median, popVariance, popSD, sampleVariance, sampleSD).\n * Returns result as a single float.\n * Special cases: Returns NULL if any values in container are NULL or non-numerical.\n */\nexport class QtiStatsOperator extends QtiExpression<number | null> {\n @property({ type: String }) name: string = '';\n\n public override get resultBaseType(): BaseType {\n return 'float';\n }\n\n public override getResult(): number | null {\n if (!this.name) {\n console.warn('qti-stats-operator: missing name attribute');\n return null;\n }\n\n const values = this.#collectNumericValues(this.getVariables() as ResponseVariable[]);\n if (values.length === 0) {\n console.warn('qti-stats-operator: no numeric values provided');\n return null;\n }\n\n switch (this.name.toLowerCase()) {\n case 'mean':\n return this.#mean(values);\n case 'median':\n return this.#median(values);\n case 'popvariance':\n return this.#variance(values, values.length);\n case 'popsd':\n return Math.sqrt(this.#variance(values, values.length));\n case 'samplevariance':\n // A sample variance over a single observation has no denominator.\n return values.length < 2 ? null : this.#variance(values, values.length - 1);\n case 'samplesd':\n return values.length < 2 ? null : Math.sqrt(this.#variance(values, values.length - 1));\n default:\n console.warn(`qti-stats-operator: unsupported operator \"${this.name}\"`);\n return null;\n }\n }\n\n #mean(values: number[]): number {\n return values.reduce((sum, value) => sum + value, 0) / values.length;\n }\n\n #median(values: number[]): number {\n const sorted = [...values].sort((a, b) => a - b);\n const middle = Math.floor(sorted.length / 2);\n // An even-sized container has no single middle value, so the two straddling\n // it are averaged.\n return sorted.length % 2 === 0 ? (sorted[middle - 1] + sorted[middle]) / 2 : sorted[middle];\n }\n\n /** Sum of squared deviations over `denominator` — the population or sample divisor. */\n #variance(values: number[], denominator: number): number {\n const mean = this.#mean(values);\n return values.reduce((sum, value) => sum + Math.pow(value - mean, 2), 0) / denominator;\n }\n\n #collectNumericValues(variables: ResponseVariable[]): number[] {\n const values: number[] = [];\n\n for (const variable of variables) {\n if (!variable) {\n continue;\n }\n\n const pushValue = (raw: unknown) => {\n if (raw === null || raw === undefined) {\n return;\n }\n const numValue = parseFloat(raw.toString());\n if (Number.isNaN(numValue)) {\n console.warn('qti-stats-operator: non-numeric value encountered');\n return;\n }\n values.push(numValue);\n };\n\n if (Array.isArray(variable.value)) {\n variable.value.forEach(item => pushValue(item));\n continue;\n }\n\n pushValue(variable.value);\n }\n\n return values;\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { QtiExpression } from '@qti-components/base';
|
|
2
|
+
import type { BaseType } from '@qti-components/base';
|
|
2
3
|
/**
|
|
3
4
|
* @summary The qti-truncate operator removes fractional parts of a number.
|
|
4
5
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#truncate
|
|
@@ -8,5 +9,6 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
8
9
|
* Special cases: Returns NULL if input is NULL or NaN.
|
|
9
10
|
*/
|
|
10
11
|
export declare class QtiTruncate extends QtiExpression<number | null> {
|
|
12
|
+
get resultBaseType(): BaseType;
|
|
11
13
|
getResult(): number | null;
|
|
12
14
|
}
|
|
@@ -8,6 +8,9 @@ import { QtiExpression } from '@qti-components/base';
|
|
|
8
8
|
* Special cases: Returns NULL if input is NULL or NaN.
|
|
9
9
|
*/
|
|
10
10
|
export class QtiTruncate extends QtiExpression {
|
|
11
|
+
get resultBaseType() {
|
|
12
|
+
return 'integer';
|
|
13
|
+
}
|
|
11
14
|
getResult() {
|
|
12
15
|
const variables = this.getVariables();
|
|
13
16
|
if (variables.length !== 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-truncate.js","sourceRoot":"","sources":["../../../src/components/qti-truncate/qti-truncate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,WAAY,SAAQ,aAA4B;
|
|
1
|
+
{"version":3,"file":"qti-truncate.js","sourceRoot":"","sources":["../../../src/components/qti-truncate/qti-truncate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;;;;GAOG;AACH,MAAM,OAAO,WAAY,SAAQ,aAA4B;IAC3D,IAAoB,cAAc;QAChC,OAAO,SAAS,CAAC;IACnB,CAAC;IAEe,SAAS;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAwB,CAAC;QAE5D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,QAAQ,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrE,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC3D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAe,CAAC,CAAC;QAC1D,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF","sourcesContent":["import { QtiExpression } from '@qti-components/base';\n\nimport type { BaseType, ResponseVariable } from '@qti-components/base';\n\n/**\n * @summary The qti-truncate operator removes fractional parts of a number.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/info/index.html#truncate\n *\n * Takes 1 numerical sub-expression of single cardinality.\n * Returns integer formed by truncating value toward zero.\n * Special cases: Returns NULL if input is NULL or NaN.\n */\nexport class QtiTruncate extends QtiExpression<number | null> {\n public override get resultBaseType(): BaseType {\n return 'integer';\n }\n\n public override getResult(): number | null {\n const variables = this.getVariables() as ResponseVariable[];\n\n if (variables.length !== 1) {\n console.error('qti-truncate requires exactly one child expression');\n return null;\n }\n\n const variable = variables[0];\n if (variable.cardinality !== 'single' || Array.isArray(variable.value)) {\n console.error('qti-truncate requires single cardinality');\n return null;\n }\n if (variable.baseType !== 'integer' && variable.baseType !== 'float') {\n console.error('qti-truncate requires numerical base-type');\n return null;\n }\n if (variable.value === null || variable.value === undefined) {\n return null;\n }\n\n const value = Number.parseFloat(variable.value as string);\n if (Number.isNaN(value)) {\n console.error('qti-truncate requires a numerical value');\n return null;\n }\n\n return Math.trunc(value);\n }\n}\n"]}
|
package/dist/elements.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ import { QtiDurationGte } from './components/qti-duration-gte/qti-duration-gte';
|
|
|
11
11
|
import { QtiDurationLt } from './components/qti-duration-lt/qti-duration-lt';
|
|
12
12
|
import { QtiEqualRounded } from './components/qti-equal-rounded/qti-equal-rounded';
|
|
13
13
|
import { QtiEqual } from './components/qti-equal/qti-equal';
|
|
14
|
+
import { QtiExitResponse } from './components/qti-exit-response/qti-exit-response';
|
|
15
|
+
import { QtiExitTest } from './components/qti-exit-test/qti-exit-test';
|
|
14
16
|
import { QtiFieldValue } from './components/qti-field-value/qti-field-value';
|
|
15
17
|
import { QtiGcd } from './components/qti-gcd/qti.gcd';
|
|
16
18
|
import { QtiGt } from './components/qti-gt/qti-gt';
|
|
@@ -28,6 +30,7 @@ import { QtiLte } from './components/qti-lte/qti-lte';
|
|
|
28
30
|
import { QtiMapResponsePoint } from './components/qti-map-response-point/qti-map-response-point';
|
|
29
31
|
import { QtiMapResponse } from './components/qti-map-response/qti-map-response';
|
|
30
32
|
import { QtiMatch } from './components/qti-match/qti-match';
|
|
33
|
+
import { QtiMathConstant } from './components/qti-math-constant/qti-math-constant';
|
|
31
34
|
import { QtiMathOperator } from './components/qti-math-operator/qti-math-operator';
|
|
32
35
|
import { QtiMax } from './components/qti-max/qti-max';
|
|
33
36
|
import { QtiMember } from './components/qti-member/qti-member';
|
|
@@ -52,6 +55,7 @@ import { QtiResponseCondition } from './components/qti-response-condition/qti-re
|
|
|
52
55
|
import { QtiResponseElseIf } from './components/qti-response-else-if/qti-response-else-if';
|
|
53
56
|
import { QtiResponseElse } from './components/qti-response-else/qti-response-else';
|
|
54
57
|
import { QtiResponseIf } from './components/qti-response-if/qti-response-if';
|
|
58
|
+
import { QtiResponseProcessingFragment } from './components/qti-response-processing-fragment/qti-response-processing-fragment';
|
|
55
59
|
import { QtiRoundTo } from './components/qti-round-to/qti-round-to';
|
|
56
60
|
import { QtiRound } from './components/qti-round/qti-round';
|
|
57
61
|
import { QtiRule } from './components/qti-rule/qti-rule';
|
|
@@ -65,7 +69,7 @@ import { QtiSubtract } from './components/qti-subtract/qti-subtract';
|
|
|
65
69
|
import { QtiSum } from './components/qti-sum/qti-sum';
|
|
66
70
|
import { QtiTruncate } from './components/qti-truncate/qti-truncate';
|
|
67
71
|
import { QtiVariable } from './components/qti-variable/qti-variable';
|
|
68
|
-
export { QtiAnd, QtiAnyN, QtiBaseValue, QtiContainerSize, QtiContains, QtiCorrect, QtiDefault, QtiDelete, QtiDivide, QtiDurationGte, QtiDurationLt, QtiEqual, QtiEqualRounded, QtiFieldValue, QtiGcd, QtiGt, QtiGte, QtiIndex, QtiInside, QtiIntegerDivide, QtiIntegerModulus, QtiIntegerToFloat, QtiIsNull, QtiLcm, QtiLookupOutcomeValue, QtiLt, QtiLte, QtiMapResponse, QtiMapResponsePoint, QtiMatch, QtiMathOperator, QtiMax, QtiMember, QtiMin, QtiMultiple, QtiNot, QtiNull, QtiOr, QtiOrdered, QtiOutcomeCondition, QtiOutcomeElse, QtiOutcomeElseIf, QtiOutcomeIf, QtiPatternMatch, QtiPower, QtiPrintedVariable, QtiProduct, QtiRandom, QtiRandomInteger, QtiRepeat, QtiResponseCondition, QtiResponseElse, QtiResponseElseIf, QtiResponseIf, QtiRound, QtiRoundTo, QtiRule, QtiSetCorrectResponse, QtiSetOutcomeValue, QtiSetTemplateValue, QtiStatsOperator, QtiStringMatch, QtiSubstring, QtiSubtract, QtiSum, QtiTruncate, QtiVariable };
|
|
72
|
+
export { QtiAnd, QtiAnyN, QtiBaseValue, QtiContainerSize, QtiContains, QtiCorrect, QtiDefault, QtiDelete, QtiDivide, QtiDurationGte, QtiDurationLt, QtiEqual, QtiEqualRounded, QtiExitResponse, QtiExitTest, QtiFieldValue, QtiGcd, QtiGt, QtiGte, QtiIndex, QtiInside, QtiIntegerDivide, QtiIntegerModulus, QtiIntegerToFloat, QtiIsNull, QtiLcm, QtiLookupOutcomeValue, QtiLt, QtiLte, QtiMapResponse, QtiMapResponsePoint, QtiMatch, QtiMathConstant, QtiMathOperator, QtiMax, QtiMember, QtiMin, QtiMultiple, QtiNot, QtiNull, QtiOr, QtiOrdered, QtiOutcomeCondition, QtiOutcomeElse, QtiOutcomeElseIf, QtiOutcomeIf, QtiPatternMatch, QtiPower, QtiPrintedVariable, QtiProduct, QtiRandom, QtiRandomInteger, QtiRepeat, QtiResponseCondition, QtiResponseElse, QtiResponseElseIf, QtiResponseIf, QtiResponseProcessingFragment, QtiRound, QtiRoundTo, QtiRule, QtiSetCorrectResponse, QtiSetOutcomeValue, QtiSetTemplateValue, QtiStatsOperator, QtiStringMatch, QtiSubstring, QtiSubtract, QtiSum, QtiTruncate, QtiVariable };
|
|
69
73
|
export declare const qtiProcessingElements: readonly [{
|
|
70
74
|
readonly tag: "qti-and";
|
|
71
75
|
readonly ctor: typeof QtiAnd;
|
|
@@ -105,6 +109,12 @@ export declare const qtiProcessingElements: readonly [{
|
|
|
105
109
|
}, {
|
|
106
110
|
readonly tag: "qti-equal-rounded";
|
|
107
111
|
readonly ctor: typeof QtiEqualRounded;
|
|
112
|
+
}, {
|
|
113
|
+
readonly tag: "qti-exit-response";
|
|
114
|
+
readonly ctor: typeof QtiExitResponse;
|
|
115
|
+
}, {
|
|
116
|
+
readonly tag: "qti-exit-test";
|
|
117
|
+
readonly ctor: typeof QtiExitTest;
|
|
108
118
|
}, {
|
|
109
119
|
readonly tag: "qti-field-value";
|
|
110
120
|
readonly ctor: typeof QtiFieldValue;
|
|
@@ -156,6 +166,9 @@ export declare const qtiProcessingElements: readonly [{
|
|
|
156
166
|
}, {
|
|
157
167
|
readonly tag: "qti-match";
|
|
158
168
|
readonly ctor: typeof QtiMatch;
|
|
169
|
+
}, {
|
|
170
|
+
readonly tag: "qti-math-constant";
|
|
171
|
+
readonly ctor: typeof QtiMathConstant;
|
|
159
172
|
}, {
|
|
160
173
|
readonly tag: "qti-math-operator";
|
|
161
174
|
readonly ctor: typeof QtiMathOperator;
|
|
@@ -228,6 +241,9 @@ export declare const qtiProcessingElements: readonly [{
|
|
|
228
241
|
}, {
|
|
229
242
|
readonly tag: "qti-response-if";
|
|
230
243
|
readonly ctor: typeof QtiResponseIf;
|
|
244
|
+
}, {
|
|
245
|
+
readonly tag: "qti-response-processing-fragment";
|
|
246
|
+
readonly ctor: typeof QtiResponseProcessingFragment;
|
|
231
247
|
}, {
|
|
232
248
|
readonly tag: "qti-round";
|
|
233
249
|
readonly ctor: typeof QtiRound;
|
package/dist/elements.js
CHANGED
|
@@ -11,6 +11,8 @@ import { QtiDurationGte } from './components/qti-duration-gte/qti-duration-gte';
|
|
|
11
11
|
import { QtiDurationLt } from './components/qti-duration-lt/qti-duration-lt';
|
|
12
12
|
import { QtiEqualRounded } from './components/qti-equal-rounded/qti-equal-rounded';
|
|
13
13
|
import { QtiEqual } from './components/qti-equal/qti-equal';
|
|
14
|
+
import { QtiExitResponse } from './components/qti-exit-response/qti-exit-response';
|
|
15
|
+
import { QtiExitTest } from './components/qti-exit-test/qti-exit-test';
|
|
14
16
|
import { QtiFieldValue } from './components/qti-field-value/qti-field-value';
|
|
15
17
|
import { QtiGcd } from './components/qti-gcd/qti.gcd';
|
|
16
18
|
import { QtiGt } from './components/qti-gt/qti-gt';
|
|
@@ -28,6 +30,7 @@ import { QtiLte } from './components/qti-lte/qti-lte';
|
|
|
28
30
|
import { QtiMapResponsePoint } from './components/qti-map-response-point/qti-map-response-point';
|
|
29
31
|
import { QtiMapResponse } from './components/qti-map-response/qti-map-response';
|
|
30
32
|
import { QtiMatch } from './components/qti-match/qti-match';
|
|
33
|
+
import { QtiMathConstant } from './components/qti-math-constant/qti-math-constant';
|
|
31
34
|
import { QtiMathOperator } from './components/qti-math-operator/qti-math-operator';
|
|
32
35
|
import { QtiMax } from './components/qti-max/qti-max';
|
|
33
36
|
import { QtiMember } from './components/qti-member/qti-member';
|
|
@@ -52,6 +55,7 @@ import { QtiResponseCondition } from './components/qti-response-condition/qti-re
|
|
|
52
55
|
import { QtiResponseElseIf } from './components/qti-response-else-if/qti-response-else-if';
|
|
53
56
|
import { QtiResponseElse } from './components/qti-response-else/qti-response-else';
|
|
54
57
|
import { QtiResponseIf } from './components/qti-response-if/qti-response-if';
|
|
58
|
+
import { QtiResponseProcessingFragment } from './components/qti-response-processing-fragment/qti-response-processing-fragment';
|
|
55
59
|
import { QtiRoundTo } from './components/qti-round-to/qti-round-to';
|
|
56
60
|
import { QtiRound } from './components/qti-round/qti-round';
|
|
57
61
|
import { QtiRule } from './components/qti-rule/qti-rule';
|
|
@@ -65,7 +69,7 @@ import { QtiSubtract } from './components/qti-subtract/qti-subtract';
|
|
|
65
69
|
import { QtiSum } from './components/qti-sum/qti-sum';
|
|
66
70
|
import { QtiTruncate } from './components/qti-truncate/qti-truncate';
|
|
67
71
|
import { QtiVariable } from './components/qti-variable/qti-variable';
|
|
68
|
-
export { QtiAnd, QtiAnyN, QtiBaseValue, QtiContainerSize, QtiContains, QtiCorrect, QtiDefault, QtiDelete, QtiDivide, QtiDurationGte, QtiDurationLt, QtiEqual, QtiEqualRounded, QtiFieldValue, QtiGcd, QtiGt, QtiGte, QtiIndex, QtiInside, QtiIntegerDivide, QtiIntegerModulus, QtiIntegerToFloat, QtiIsNull, QtiLcm, QtiLookupOutcomeValue, QtiLt, QtiLte, QtiMapResponse, QtiMapResponsePoint, QtiMatch, QtiMathOperator, QtiMax, QtiMember, QtiMin, QtiMultiple, QtiNot, QtiNull, QtiOr, QtiOrdered, QtiOutcomeCondition, QtiOutcomeElse, QtiOutcomeElseIf, QtiOutcomeIf, QtiPatternMatch, QtiPower, QtiPrintedVariable, QtiProduct, QtiRandom, QtiRandomInteger, QtiRepeat, QtiResponseCondition, QtiResponseElse, QtiResponseElseIf, QtiResponseIf, QtiRound, QtiRoundTo, QtiRule, QtiSetCorrectResponse, QtiSetOutcomeValue, QtiSetTemplateValue, QtiStatsOperator, QtiStringMatch, QtiSubstring, QtiSubtract, QtiSum, QtiTruncate, QtiVariable };
|
|
72
|
+
export { QtiAnd, QtiAnyN, QtiBaseValue, QtiContainerSize, QtiContains, QtiCorrect, QtiDefault, QtiDelete, QtiDivide, QtiDurationGte, QtiDurationLt, QtiEqual, QtiEqualRounded, QtiExitResponse, QtiExitTest, QtiFieldValue, QtiGcd, QtiGt, QtiGte, QtiIndex, QtiInside, QtiIntegerDivide, QtiIntegerModulus, QtiIntegerToFloat, QtiIsNull, QtiLcm, QtiLookupOutcomeValue, QtiLt, QtiLte, QtiMapResponse, QtiMapResponsePoint, QtiMatch, QtiMathConstant, QtiMathOperator, QtiMax, QtiMember, QtiMin, QtiMultiple, QtiNot, QtiNull, QtiOr, QtiOrdered, QtiOutcomeCondition, QtiOutcomeElse, QtiOutcomeElseIf, QtiOutcomeIf, QtiPatternMatch, QtiPower, QtiPrintedVariable, QtiProduct, QtiRandom, QtiRandomInteger, QtiRepeat, QtiResponseCondition, QtiResponseElse, QtiResponseElseIf, QtiResponseIf, QtiResponseProcessingFragment, QtiRound, QtiRoundTo, QtiRule, QtiSetCorrectResponse, QtiSetOutcomeValue, QtiSetTemplateValue, QtiStatsOperator, QtiStringMatch, QtiSubstring, QtiSubtract, QtiSum, QtiTruncate, QtiVariable };
|
|
69
73
|
export const qtiProcessingElements = [
|
|
70
74
|
{ tag: 'qti-and', ctor: QtiAnd },
|
|
71
75
|
{ tag: 'qti-any-n', ctor: QtiAnyN },
|
|
@@ -80,6 +84,8 @@ export const qtiProcessingElements = [
|
|
|
80
84
|
{ tag: 'qti-duration-lt', ctor: QtiDurationLt },
|
|
81
85
|
{ tag: 'qti-equal', ctor: QtiEqual },
|
|
82
86
|
{ tag: 'qti-equal-rounded', ctor: QtiEqualRounded },
|
|
87
|
+
{ tag: 'qti-exit-response', ctor: QtiExitResponse },
|
|
88
|
+
{ tag: 'qti-exit-test', ctor: QtiExitTest },
|
|
83
89
|
{ tag: 'qti-field-value', ctor: QtiFieldValue },
|
|
84
90
|
{ tag: 'qti-gcd', ctor: QtiGcd },
|
|
85
91
|
{ tag: 'qti-gt', ctor: QtiGt },
|
|
@@ -97,6 +103,7 @@ export const qtiProcessingElements = [
|
|
|
97
103
|
{ tag: 'qti-map-response', ctor: QtiMapResponse },
|
|
98
104
|
{ tag: 'qti-map-response-point', ctor: QtiMapResponsePoint },
|
|
99
105
|
{ tag: 'qti-match', ctor: QtiMatch },
|
|
106
|
+
{ tag: 'qti-math-constant', ctor: QtiMathConstant },
|
|
100
107
|
{ tag: 'qti-math-operator', ctor: QtiMathOperator },
|
|
101
108
|
{ tag: 'qti-max', ctor: QtiMax },
|
|
102
109
|
{ tag: 'qti-member', ctor: QtiMember },
|
|
@@ -121,6 +128,7 @@ export const qtiProcessingElements = [
|
|
|
121
128
|
{ tag: 'qti-response-else', ctor: QtiResponseElse },
|
|
122
129
|
{ tag: 'qti-response-else-if', ctor: QtiResponseElseIf },
|
|
123
130
|
{ tag: 'qti-response-if', ctor: QtiResponseIf },
|
|
131
|
+
{ tag: 'qti-response-processing-fragment', ctor: QtiResponseProcessingFragment },
|
|
124
132
|
{ tag: 'qti-round', ctor: QtiRound },
|
|
125
133
|
{ tag: 'qti-round-to', ctor: QtiRoundTo },
|
|
126
134
|
{ tag: 'qti-rule', ctor: QtiRule },
|