@longsightgroup/qti3-core 0.9.2 → 0.9.4
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/README.md +108 -11
- package/dist/adaptive-turn-materializer.d.ts +2 -0
- package/dist/adaptive-turn-materializer.d.ts.map +1 -1
- package/dist/adaptive-turn-materializer.js +25 -19
- package/dist/adaptive-turn-materializer.js.map +1 -1
- package/dist/adaptive-turn.d.ts +8 -1
- package/dist/adaptive-turn.d.ts.map +1 -1
- package/dist/adaptive-turn.js +15 -5
- package/dist/adaptive-turn.js.map +1 -1
- package/dist/assert-never.d.ts +3 -0
- package/dist/assert-never.d.ts.map +1 -0
- package/dist/assert-never.js +5 -0
- package/dist/assert-never.js.map +1 -0
- package/dist/attempt-state-constants.d.ts +6 -0
- package/dist/attempt-state-constants.d.ts.map +1 -0
- package/dist/attempt-state-constants.js +6 -0
- package/dist/attempt-state-constants.js.map +1 -0
- package/dist/attempt-state.d.ts +5 -0
- package/dist/attempt-state.d.ts.map +1 -0
- package/dist/attempt-state.js +190 -0
- package/dist/attempt-state.js.map +1 -0
- package/dist/catalog.js +1 -1
- package/dist/catalog.js.map +1 -1
- package/dist/content-text.d.ts.map +1 -1
- package/dist/content-text.js +3 -0
- package/dist/content-text.js.map +1 -1
- package/dist/custom-operators.d.ts +13 -0
- package/dist/custom-operators.d.ts.map +1 -0
- package/dist/custom-operators.js +2 -0
- package/dist/custom-operators.js.map +1 -0
- package/dist/delivery-preparation.d.ts +20 -0
- package/dist/delivery-preparation.d.ts.map +1 -0
- package/dist/delivery-preparation.js +71 -0
- package/dist/delivery-preparation.js.map +1 -0
- package/dist/delivery-redaction.d.ts +5 -0
- package/dist/delivery-redaction.d.ts.map +1 -1
- package/dist/delivery-redaction.js +27 -6
- package/dist/delivery-redaction.js.map +1 -1
- package/dist/delivery-security.js +2 -2
- package/dist/delivery-security.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/item-scoring-expectation.d.ts +4 -0
- package/dist/item-scoring-expectation.d.ts.map +1 -0
- package/dist/item-scoring-expectation.js +6 -0
- package/dist/item-scoring-expectation.js.map +1 -0
- package/dist/item-submission-materialization.d.ts +25 -0
- package/dist/item-submission-materialization.d.ts.map +1 -0
- package/dist/item-submission-materialization.js +68 -0
- package/dist/item-submission-materialization.js.map +1 -0
- package/dist/parser-custom-interactions.js +1 -1
- package/dist/parser-custom-interactions.js.map +1 -1
- package/dist/parser-declarations.d.ts.map +1 -1
- package/dist/parser-declarations.js +4 -4
- package/dist/parser-declarations.js.map +1 -1
- package/dist/parser-item-metadata.d.ts.map +1 -1
- package/dist/parser-item-metadata.js +8 -7
- package/dist/parser-item-metadata.js.map +1 -1
- package/dist/parser-processing.js +2 -2
- package/dist/parser-processing.js.map +1 -1
- package/dist/parser-values.d.ts +5 -1
- package/dist/parser-values.d.ts.map +1 -1
- package/dist/parser-values.js +33 -0
- package/dist/parser-values.js.map +1 -1
- package/dist/processing-evaluator-boolean.d.ts +8 -0
- package/dist/processing-evaluator-boolean.d.ts.map +1 -0
- package/dist/processing-evaluator-boolean.js +47 -0
- package/dist/processing-evaluator-boolean.js.map +1 -0
- package/dist/processing-evaluator-collection.d.ts +12 -0
- package/dist/processing-evaluator-collection.d.ts.map +1 -0
- package/dist/processing-evaluator-collection.js +35 -0
- package/dist/processing-evaluator-collection.js.map +1 -0
- package/dist/processing-evaluator-comparison.d.ts +8 -0
- package/dist/processing-evaluator-comparison.d.ts.map +1 -0
- package/dist/processing-evaluator-comparison.js +88 -0
- package/dist/processing-evaluator-comparison.js.map +1 -0
- package/dist/processing-evaluator-custom.d.ts +8 -0
- package/dist/processing-evaluator-custom.d.ts.map +1 -0
- package/dist/processing-evaluator-custom.js +14 -0
- package/dist/processing-evaluator-custom.js.map +1 -0
- package/dist/processing-evaluator-geometry.d.ts +8 -0
- package/dist/processing-evaluator-geometry.d.ts.map +1 -0
- package/dist/processing-evaluator-geometry.js +21 -0
- package/dist/processing-evaluator-geometry.js.map +1 -0
- package/dist/processing-evaluator-numeric.d.ts +8 -0
- package/dist/processing-evaluator-numeric.d.ts.map +1 -0
- package/dist/processing-evaluator-numeric.js +112 -0
- package/dist/processing-evaluator-numeric.js.map +1 -0
- package/dist/processing-evaluator-string.d.ts +8 -0
- package/dist/processing-evaluator-string.d.ts.map +1 -0
- package/dist/processing-evaluator-string.js +33 -0
- package/dist/processing-evaluator-string.js.map +1 -0
- package/dist/processing-evaluator-variable.d.ts +8 -0
- package/dist/processing-evaluator-variable.d.ts.map +1 -0
- package/dist/processing-evaluator-variable.js +39 -0
- package/dist/processing-evaluator-variable.js.map +1 -0
- package/dist/processing-evaluator.d.ts +22 -0
- package/dist/processing-evaluator.d.ts.map +1 -0
- package/dist/processing-evaluator.js +137 -0
- package/dist/processing-evaluator.js.map +1 -0
- package/dist/processing-expression-children.d.ts +3 -0
- package/dist/processing-expression-children.d.ts.map +1 -0
- package/dist/processing-expression-children.js +68 -0
- package/dist/processing-expression-children.js.map +1 -0
- package/dist/processing-mapping.d.ts +13 -0
- package/dist/processing-mapping.d.ts.map +1 -0
- package/dist/processing-mapping.js +120 -0
- package/dist/processing-mapping.js.map +1 -0
- package/dist/processing-operators.d.ts +11 -0
- package/dist/processing-operators.d.ts.map +1 -0
- package/dist/processing-operators.js +178 -0
- package/dist/processing-operators.js.map +1 -0
- package/dist/processing-random.d.ts +2 -0
- package/dist/processing-random.d.ts.map +1 -0
- package/dist/processing-random.js +16 -0
- package/dist/processing-random.js.map +1 -0
- package/dist/processing-state.d.ts +8 -0
- package/dist/processing-state.d.ts.map +1 -0
- package/dist/processing-state.js +44 -0
- package/dist/processing-state.js.map +1 -0
- package/dist/processing-templates.d.ts +3 -0
- package/dist/processing-templates.d.ts.map +1 -0
- package/dist/processing-templates.js +12 -0
- package/dist/processing-templates.js.map +1 -0
- package/dist/processing-values.d.ts +15 -0
- package/dist/processing-values.d.ts.map +1 -0
- package/dist/processing-values.js +150 -0
- package/dist/processing-values.js.map +1 -0
- package/dist/processing-variables.d.ts +7 -0
- package/dist/processing-variables.d.ts.map +1 -0
- package/dist/processing-variables.js +40 -0
- package/dist/processing-variables.js.map +1 -0
- package/dist/qti-package-assets.d.ts +8 -0
- package/dist/qti-package-assets.d.ts.map +1 -0
- package/dist/qti-package-assets.js +173 -0
- package/dist/qti-package-assets.js.map +1 -0
- package/dist/qti-package-items.d.ts +14 -0
- package/dist/qti-package-items.d.ts.map +1 -0
- package/dist/qti-package-items.js +138 -0
- package/dist/qti-package-items.js.map +1 -0
- package/dist/qti-package-manifest.d.ts +13 -0
- package/dist/qti-package-manifest.d.ts.map +1 -0
- package/dist/qti-package-manifest.js +109 -0
- package/dist/qti-package-manifest.js.map +1 -0
- package/dist/qti-package-metadata.d.ts +8 -0
- package/dist/qti-package-metadata.d.ts.map +1 -0
- package/dist/qti-package-metadata.js +115 -0
- package/dist/qti-package-metadata.js.map +1 -0
- package/dist/qti-package-paths.d.ts +6 -0
- package/dist/qti-package-paths.d.ts.map +1 -0
- package/dist/qti-package-paths.js +32 -0
- package/dist/qti-package-paths.js.map +1 -0
- package/dist/qti-package-types.d.ts +98 -0
- package/dist/qti-package-types.d.ts.map +1 -0
- package/dist/qti-package-types.js +2 -0
- package/dist/qti-package-types.js.map +1 -0
- package/dist/qti-package-xml.d.ts +21 -0
- package/dist/qti-package-xml.d.ts.map +1 -0
- package/dist/qti-package-xml.js +68 -0
- package/dist/qti-package-xml.js.map +1 -0
- package/dist/qti-package-zip.d.ts +24 -0
- package/dist/qti-package-zip.d.ts.map +1 -0
- package/dist/qti-package-zip.js +185 -0
- package/dist/qti-package-zip.js.map +1 -0
- package/dist/qti-package.d.ts +7 -0
- package/dist/qti-package.d.ts.map +1 -0
- package/dist/qti-package.js +76 -0
- package/dist/qti-package.js.map +1 -0
- package/dist/response-input.d.ts +9 -0
- package/dist/response-input.d.ts.map +1 -0
- package/dist/response-input.js +9 -0
- package/dist/response-input.js.map +1 -0
- package/dist/response-validation-policy.d.ts +31 -0
- package/dist/response-validation-policy.d.ts.map +1 -0
- package/dist/response-validation-policy.js +158 -0
- package/dist/response-validation-policy.js.map +1 -0
- package/dist/response-validation.d.ts +23 -0
- package/dist/response-validation.d.ts.map +1 -0
- package/dist/response-validation.js +157 -0
- package/dist/response-validation.js.map +1 -0
- package/dist/scoring-disposition-policy.d.ts +8 -0
- package/dist/scoring-disposition-policy.d.ts.map +1 -0
- package/dist/scoring-disposition-policy.js +24 -0
- package/dist/scoring-disposition-policy.js.map +1 -0
- package/dist/serializer-processing-expressions.d.ts.map +1 -1
- package/dist/serializer-processing-expressions.js +2 -8
- package/dist/serializer-processing-expressions.js.map +1 -1
- package/dist/serializer-processing-xml.js +2 -2
- package/dist/serializer-processing-xml.js.map +1 -1
- package/dist/serializer-processing.d.ts.map +1 -1
- package/dist/serializer-processing.js +3 -0
- package/dist/serializer-processing.js.map +1 -1
- package/dist/session.d.ts +5 -14
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +76 -1158
- package/dist/session.js.map +1 -1
- package/dist/shared-vocabulary-coverage-policy.js +1 -1
- package/dist/shared-vocabulary-coverage-policy.js.map +1 -1
- package/dist/shared-vocabulary-generated-families.js +1 -1
- package/dist/shared-vocabulary-generated-families.js.map +1 -1
- package/dist/shared-vocabulary-support.js +3 -3
- package/dist/shared-vocabulary-support.js.map +1 -1
- package/dist/shared-vocabulary.d.ts.map +1 -1
- package/dist/shared-vocabulary.js +4 -3
- package/dist/shared-vocabulary.js.map +1 -1
- package/dist/support-evidence.d.ts +22 -0
- package/dist/support-evidence.d.ts.map +1 -0
- package/dist/support-evidence.js +93 -0
- package/dist/support-evidence.js.map +1 -0
- package/dist/support.d.ts.map +1 -1
- package/dist/support.js +30 -43
- package/dist/support.js.map +1 -1
- package/dist/template-presentation-materializer.d.ts +14 -0
- package/dist/template-presentation-materializer.d.ts.map +1 -0
- package/dist/template-presentation-materializer.js +143 -0
- package/dist/template-presentation-materializer.js.map +1 -0
- package/dist/trusted-item-session.d.ts +25 -8
- package/dist/trusted-item-session.d.ts.map +1 -1
- package/dist/trusted-item-session.js +57 -51
- package/dist/trusted-item-session.js.map +1 -1
- package/dist/trusted-session-materialization.d.ts +33 -0
- package/dist/trusted-session-materialization.d.ts.map +1 -0
- package/dist/trusted-session-materialization.js +26 -0
- package/dist/trusted-session-materialization.js.map +1 -0
- package/dist/tts.d.ts.map +1 -1
- package/dist/tts.js +16 -2
- package/dist/tts.js.map +1 -1
- package/dist/validation-geometry.d.ts +8 -0
- package/dist/validation-geometry.d.ts.map +1 -0
- package/dist/validation-geometry.js +187 -0
- package/dist/validation-geometry.js.map +1 -0
- package/dist/validation-interactions.d.ts +3 -0
- package/dist/validation-interactions.d.ts.map +1 -0
- package/dist/validation-interactions.js +644 -0
- package/dist/validation-interactions.js.map +1 -0
- package/dist/validation-primitives.d.ts +12 -0
- package/dist/validation-primitives.d.ts.map +1 -0
- package/dist/validation-primitives.js +53 -0
- package/dist/validation-primitives.js.map +1 -0
- package/dist/validation-processing.d.ts +4 -0
- package/dist/validation-processing.d.ts.map +1 -0
- package/dist/validation-processing.js +569 -0
- package/dist/validation-processing.js.map +1 -0
- package/dist/validation-shared-vocabulary-layout.d.ts +10 -0
- package/dist/validation-shared-vocabulary-layout.d.ts.map +1 -0
- package/dist/validation-shared-vocabulary-layout.js +102 -0
- package/dist/validation-shared-vocabulary-layout.js.map +1 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +27 -1641
- package/dist/validation.js.map +1 -1
- package/dist/variable-snapshot.d.ts +9 -0
- package/dist/variable-snapshot.d.ts.map +1 -0
- package/dist/variable-snapshot.js +9 -0
- package/dist/variable-snapshot.js.map +1 -0
- package/dist/xml.js +1 -1
- package/dist/xml.js.map +1 -1
- package/package.json +1 -1
- package/src/adaptive-turn-materializer.ts +29 -16
- package/src/adaptive-turn.ts +29 -6
- package/src/assert-never.ts +4 -0
- package/src/attempt-state-constants.ts +5 -0
- package/src/attempt-state.ts +245 -0
- package/src/catalog.ts +1 -1
- package/src/content-text.ts +3 -0
- package/src/custom-operators.ts +12 -0
- package/src/delivery-preparation.ts +121 -0
- package/src/delivery-redaction.ts +37 -6
- package/src/delivery-security.ts +2 -2
- package/src/index.ts +67 -0
- package/src/item-scoring-expectation.ts +9 -0
- package/src/item-submission-materialization.ts +120 -0
- package/src/parser-custom-interactions.ts +1 -1
- package/src/parser-declarations.ts +4 -3
- package/src/parser-item-metadata.ts +8 -7
- package/src/parser-processing.ts +2 -2
- package/src/parser-values.ts +36 -0
- package/src/processing-evaluator-boolean.ts +48 -0
- package/src/processing-evaluator-collection.ts +50 -0
- package/src/processing-evaluator-comparison.ts +106 -0
- package/src/processing-evaluator-custom.ts +20 -0
- package/src/processing-evaluator-geometry.ts +26 -0
- package/src/processing-evaluator-numeric.ts +155 -0
- package/src/processing-evaluator-string.ts +60 -0
- package/src/processing-evaluator-variable.ts +81 -0
- package/src/processing-evaluator.ts +173 -0
- package/src/processing-expression-children.ts +69 -0
- package/src/processing-mapping.ts +153 -0
- package/src/processing-operators.ts +184 -0
- package/src/processing-random.ts +16 -0
- package/src/processing-state.ts +69 -0
- package/src/processing-templates.ts +12 -0
- package/src/processing-values.ts +162 -0
- package/src/processing-variables.ts +83 -0
- package/src/qti-package-assets.ts +256 -0
- package/src/qti-package-items.ts +240 -0
- package/src/qti-package-manifest.ts +210 -0
- package/src/qti-package-metadata.ts +143 -0
- package/src/qti-package-paths.ts +56 -0
- package/src/qti-package-types.ts +117 -0
- package/src/qti-package-xml.ts +97 -0
- package/src/qti-package-zip.ts +325 -0
- package/src/qti-package.ts +176 -0
- package/src/response-input.ts +19 -0
- package/src/response-validation-policy.ts +218 -0
- package/src/response-validation.ts +282 -0
- package/src/scoring-disposition-policy.ts +37 -0
- package/src/serializer-processing-expressions.ts +2 -12
- package/src/serializer-processing-xml.ts +2 -2
- package/src/serializer-processing.ts +3 -0
- package/src/session.ts +128 -2006
- package/src/shared-vocabulary-coverage-policy.ts +1 -1
- package/src/shared-vocabulary-generated-families.ts +1 -1
- package/src/shared-vocabulary-support.ts +3 -3
- package/src/shared-vocabulary.ts +3 -2
- package/src/support-evidence.ts +107 -0
- package/src/support.ts +59 -50
- package/src/template-presentation-materializer.ts +219 -0
- package/src/trusted-item-session.ts +86 -78
- package/src/trusted-session-materialization.ts +67 -0
- package/src/tts.ts +29 -15
- package/src/validation-geometry.ts +204 -0
- package/src/validation-interactions.ts +831 -0
- package/src/validation-primitives.ts +68 -0
- package/src/validation-processing.ts +785 -0
- package/src/validation-shared-vocabulary-layout.ts +117 -0
- package/src/validation.ts +44 -2077
- package/src/variable-snapshot.ts +20 -0
- package/src/xml.ts +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { qtiScalarToString, qtiValueToStringList } from "./value-format.js";
|
|
2
|
+
import { isRecordValue, numericValue, valuesEqual } from "./processing-values.js";
|
|
3
|
+
export function lookupOutcomeValue(document, identifier, value) {
|
|
4
|
+
const declaration = document.item.outcomeDeclarations.find((outcome) => outcome.identifier === identifier);
|
|
5
|
+
const lookupTable = declaration?.lookupTable;
|
|
6
|
+
if (!lookupTable)
|
|
7
|
+
return null;
|
|
8
|
+
if (value === null)
|
|
9
|
+
return lookupTable.defaultValue;
|
|
10
|
+
const numeric = numericValue(value);
|
|
11
|
+
if (lookupTable.type === "match") {
|
|
12
|
+
return (lookupTable.entries.find((entry) => entry.sourceValue === numeric)?.targetValue ??
|
|
13
|
+
lookupTable.defaultValue);
|
|
14
|
+
}
|
|
15
|
+
const entry = [...lookupTable.entries]
|
|
16
|
+
.toSorted((left, right) => left.sourceValue - right.sourceValue)
|
|
17
|
+
.find((candidate) => numeric < candidate.sourceValue ||
|
|
18
|
+
(candidate.includeBoundary !== false && numeric === candidate.sourceValue));
|
|
19
|
+
return entry?.targetValue ?? lookupTable.defaultValue;
|
|
20
|
+
}
|
|
21
|
+
export function mapOrMatchResponse(declaration, response, correctResponse) {
|
|
22
|
+
if (declaration.areaMapping)
|
|
23
|
+
return scoreAreaMapping(response, declaration.areaMapping);
|
|
24
|
+
if (declaration.mapping)
|
|
25
|
+
return scoreMapping(response, declaration.mapping);
|
|
26
|
+
return valuesEqual(response, correctResponse, declaration.cardinality === "ordered") ? 1 : 0;
|
|
27
|
+
}
|
|
28
|
+
export function scoreAreaMapping(response, areaMapping) {
|
|
29
|
+
const points = Array.isArray(response)
|
|
30
|
+
? response.map(qtiScalarToString)
|
|
31
|
+
: response === null
|
|
32
|
+
? []
|
|
33
|
+
: qtiValueToStringList(response);
|
|
34
|
+
let score = 0;
|
|
35
|
+
for (const point of points) {
|
|
36
|
+
const parsed = parsePoint(point);
|
|
37
|
+
if (!parsed) {
|
|
38
|
+
score += areaMapping.defaultValue;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const entry = areaMapping.entries.find((candidate) => pointInsideArea(parsed, candidate));
|
|
42
|
+
score += entry?.mappedValue ?? areaMapping.defaultValue;
|
|
43
|
+
}
|
|
44
|
+
return clampMappedScore(score, areaMapping.attributes);
|
|
45
|
+
}
|
|
46
|
+
export function parsePoint(value) {
|
|
47
|
+
const [x, y] = value
|
|
48
|
+
.trim()
|
|
49
|
+
.split(/[,\s]+/)
|
|
50
|
+
.map((part) => Number(part));
|
|
51
|
+
if (x === undefined || y === undefined || !Number.isFinite(x) || !Number.isFinite(y)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return { x, y };
|
|
55
|
+
}
|
|
56
|
+
export function pointInsideArea(point, entry) {
|
|
57
|
+
if (entry.shape === "circle") {
|
|
58
|
+
const [cx, cy, radius] = entry.coords;
|
|
59
|
+
if (cx === undefined || cy === undefined || radius === undefined)
|
|
60
|
+
return false;
|
|
61
|
+
return Math.hypot(point.x - cx, point.y - cy) <= radius;
|
|
62
|
+
}
|
|
63
|
+
if (entry.shape === "rect") {
|
|
64
|
+
const [left, top, right, bottom] = entry.coords;
|
|
65
|
+
if (left === undefined || top === undefined || right === undefined || bottom === undefined) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return point.x >= left && point.x <= right && point.y >= top && point.y <= bottom;
|
|
69
|
+
}
|
|
70
|
+
if (entry.shape === "poly") {
|
|
71
|
+
return pointInsidePolygon(point, entry.coords);
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
function pointInsidePolygon(point, coords) {
|
|
76
|
+
if (coords.length < 6 || coords.length % 2 !== 0)
|
|
77
|
+
return false;
|
|
78
|
+
let inside = false;
|
|
79
|
+
for (let index = 0, previous = coords.length - 2; index < coords.length; index += 2) {
|
|
80
|
+
const xi = coords[index];
|
|
81
|
+
const yi = coords[index + 1];
|
|
82
|
+
const xj = coords[previous];
|
|
83
|
+
const yj = coords[previous + 1];
|
|
84
|
+
const intersects = yi > point.y !== yj > point.y && point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;
|
|
85
|
+
if (intersects)
|
|
86
|
+
inside = !inside;
|
|
87
|
+
previous = index;
|
|
88
|
+
}
|
|
89
|
+
return inside;
|
|
90
|
+
}
|
|
91
|
+
function scoreMapping(response, mapping) {
|
|
92
|
+
const values = Object.fromEntries(mapping.entries
|
|
93
|
+
.filter((entry) => entry.mapKey !== undefined)
|
|
94
|
+
.map((entry) => [entry.mapKey, entry.mappedValue]));
|
|
95
|
+
if (Array.isArray(response)) {
|
|
96
|
+
const score = response.reduce((sum, value) => sum + (values[String(value)] ?? mapping.defaultValue), 0);
|
|
97
|
+
return clampMappedScore(score, mapping.attributes);
|
|
98
|
+
}
|
|
99
|
+
const score = response === null || isRecordValue(response)
|
|
100
|
+
? 0
|
|
101
|
+
: (values[String(response)] ?? mapping.defaultValue);
|
|
102
|
+
return clampMappedScore(score, mapping.attributes);
|
|
103
|
+
}
|
|
104
|
+
function clampMappedScore(score, attributes) {
|
|
105
|
+
const lower = numericBound(attributes["lower-bound"]);
|
|
106
|
+
const upper = numericBound(attributes["upper-bound"]);
|
|
107
|
+
let clamped = score;
|
|
108
|
+
if (lower !== undefined)
|
|
109
|
+
clamped = Math.max(clamped, lower);
|
|
110
|
+
if (upper !== undefined)
|
|
111
|
+
clamped = Math.min(clamped, upper);
|
|
112
|
+
return clamped;
|
|
113
|
+
}
|
|
114
|
+
function numericBound(value) {
|
|
115
|
+
if (value === undefined)
|
|
116
|
+
return undefined;
|
|
117
|
+
const numberValue = Number(value);
|
|
118
|
+
return Number.isFinite(numberValue) ? numberValue : undefined;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=processing-mapping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-mapping.js","sourceRoot":"","sources":["../src/processing-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { QtiValue } from "./types.js";
|
|
2
|
+
export declare const MATH_OPERATOR_NAMES: readonly ["abs", "acos", "acot", "acsc", "asec", "asin", "atan", "atan2", "ceil", "cos", "cosh", "cot", "coth", "csc", "csch", "exp", "floor", "ln", "log", "sec", "sech", "signum", "sin", "sinh", "tan", "tanh", "toDegrees", "toRadians"];
|
|
3
|
+
export declare const STATS_OPERATOR_NAMES: readonly ["mean", "sampleVariance", "sampleSD", "popVariance", "popSD"];
|
|
4
|
+
export declare function roundToDecimalPlaces(value: number, figures: number): number;
|
|
5
|
+
export declare function roundToSignificantFigures(value: number, figures: number): number;
|
|
6
|
+
export declare function roundWithMode(value: number, roundingMode: string, figures: number): number | null;
|
|
7
|
+
export declare function generalizedGcd(values: number[]): number;
|
|
8
|
+
export declare function generalizedLcm(values: number[]): number;
|
|
9
|
+
export declare function mathOperatorValue(name: string, values: number[]): QtiValue;
|
|
10
|
+
export declare function statsOperatorValue(name: string, values: number[]): QtiValue;
|
|
11
|
+
//# sourceMappingURL=processing-operators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-operators.d.ts","sourceRoot":"","sources":["../src/processing-operators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,mBAAmB,8OA6BtB,CAAC;AAEX,eAAO,MAAM,oBAAoB,yEAMvB,CAAC;AAEX,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIhF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKjG;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAMvD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAGvD;AAiBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CA+D1E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAkB3E"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
export const MATH_OPERATOR_NAMES = [
|
|
2
|
+
"abs",
|
|
3
|
+
"acos",
|
|
4
|
+
"acot",
|
|
5
|
+
"acsc",
|
|
6
|
+
"asec",
|
|
7
|
+
"asin",
|
|
8
|
+
"atan",
|
|
9
|
+
"atan2",
|
|
10
|
+
"ceil",
|
|
11
|
+
"cos",
|
|
12
|
+
"cosh",
|
|
13
|
+
"cot",
|
|
14
|
+
"coth",
|
|
15
|
+
"csc",
|
|
16
|
+
"csch",
|
|
17
|
+
"exp",
|
|
18
|
+
"floor",
|
|
19
|
+
"ln",
|
|
20
|
+
"log",
|
|
21
|
+
"sec",
|
|
22
|
+
"sech",
|
|
23
|
+
"signum",
|
|
24
|
+
"sin",
|
|
25
|
+
"sinh",
|
|
26
|
+
"tan",
|
|
27
|
+
"tanh",
|
|
28
|
+
"toDegrees",
|
|
29
|
+
"toRadians",
|
|
30
|
+
];
|
|
31
|
+
export const STATS_OPERATOR_NAMES = [
|
|
32
|
+
"mean",
|
|
33
|
+
"sampleVariance",
|
|
34
|
+
"sampleSD",
|
|
35
|
+
"popVariance",
|
|
36
|
+
"popSD",
|
|
37
|
+
];
|
|
38
|
+
export function roundToDecimalPlaces(value, figures) {
|
|
39
|
+
const factor = 10 ** figures;
|
|
40
|
+
return Math.round(value * factor) / factor;
|
|
41
|
+
}
|
|
42
|
+
export function roundToSignificantFigures(value, figures) {
|
|
43
|
+
if (value === 0 || figures <= 0)
|
|
44
|
+
return 0;
|
|
45
|
+
const factor = 10 ** (figures - 1 - Math.floor(Math.log10(Math.abs(value))));
|
|
46
|
+
return Math.round(value * factor) / factor;
|
|
47
|
+
}
|
|
48
|
+
export function roundWithMode(value, roundingMode, figures) {
|
|
49
|
+
if (!Number.isFinite(value))
|
|
50
|
+
return null;
|
|
51
|
+
if (roundingMode === "decimalPlaces")
|
|
52
|
+
return roundToDecimalPlaces(value, figures);
|
|
53
|
+
if (roundingMode === "significantFigures")
|
|
54
|
+
return roundToSignificantFigures(value, figures);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
export function generalizedGcd(values) {
|
|
58
|
+
let result = 0;
|
|
59
|
+
for (const value of values) {
|
|
60
|
+
result = gcd(result, Math.abs(value));
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
export function generalizedLcm(values) {
|
|
65
|
+
if (values.some((value) => value === 0))
|
|
66
|
+
return 0;
|
|
67
|
+
return values.reduce((result, value) => lcm(result, Math.abs(value)), 1);
|
|
68
|
+
}
|
|
69
|
+
function gcd(left, right) {
|
|
70
|
+
let a = Math.abs(left);
|
|
71
|
+
let b = Math.abs(right);
|
|
72
|
+
while (b !== 0) {
|
|
73
|
+
const next = a % b;
|
|
74
|
+
a = b;
|
|
75
|
+
b = next;
|
|
76
|
+
}
|
|
77
|
+
return a;
|
|
78
|
+
}
|
|
79
|
+
function lcm(left, right) {
|
|
80
|
+
return Math.abs(left * right) / gcd(left, right);
|
|
81
|
+
}
|
|
82
|
+
export function mathOperatorValue(name, values) {
|
|
83
|
+
const [first, second] = values;
|
|
84
|
+
if (first === undefined)
|
|
85
|
+
return null;
|
|
86
|
+
switch (name) {
|
|
87
|
+
case "abs":
|
|
88
|
+
return finiteOrNull(Math.abs(first));
|
|
89
|
+
case "acos":
|
|
90
|
+
return Math.abs(first) > 1 ? null : finiteOrNull(Math.acos(first));
|
|
91
|
+
case "acot":
|
|
92
|
+
return finiteOrNull(Math.PI / 2 - Math.atan(1 / first));
|
|
93
|
+
case "acsc":
|
|
94
|
+
return Math.abs(first) < 1 ? null : finiteOrNull(Math.PI / 2 - Math.asin(1 / first));
|
|
95
|
+
case "asec":
|
|
96
|
+
return Math.abs(first) < 1 ? null : finiteOrNull(Math.PI / 2 - Math.acos(1 / first));
|
|
97
|
+
case "asin":
|
|
98
|
+
return Math.abs(first) > 1 ? null : finiteOrNull(Math.asin(first));
|
|
99
|
+
case "atan":
|
|
100
|
+
return finiteOrNull(Math.atan(first));
|
|
101
|
+
case "atan2":
|
|
102
|
+
return second === undefined ? null : finiteOrNull(Math.atan2(first, second));
|
|
103
|
+
case "ceil":
|
|
104
|
+
return finiteOrNull(Math.ceil(first));
|
|
105
|
+
case "cos":
|
|
106
|
+
return finiteOrNull(Math.cos(first));
|
|
107
|
+
case "cosh":
|
|
108
|
+
return finiteOrNull(Math.cosh(first));
|
|
109
|
+
case "cot":
|
|
110
|
+
return finiteOrNull(1 / Math.tan(first));
|
|
111
|
+
case "coth":
|
|
112
|
+
return finiteOrNull(1 / Math.tanh(first));
|
|
113
|
+
case "csc":
|
|
114
|
+
return finiteOrNull(1 / Math.sin(first));
|
|
115
|
+
case "csch":
|
|
116
|
+
return finiteOrNull(1 / Math.sinh(first));
|
|
117
|
+
case "exp":
|
|
118
|
+
return finiteOrNull(Math.exp(first));
|
|
119
|
+
case "floor":
|
|
120
|
+
return finiteOrNull(Math.floor(first));
|
|
121
|
+
case "ln":
|
|
122
|
+
return first < 0 ? null : finiteOrNull(Math.log(first));
|
|
123
|
+
case "log":
|
|
124
|
+
return first < 0 ? null : finiteOrNull(Math.log10(first));
|
|
125
|
+
case "sec":
|
|
126
|
+
return finiteOrNull(1 / Math.cos(first));
|
|
127
|
+
case "sech":
|
|
128
|
+
return finiteOrNull(1 / Math.cosh(first));
|
|
129
|
+
case "signum":
|
|
130
|
+
return finiteOrNull(Math.sign(first));
|
|
131
|
+
case "sin":
|
|
132
|
+
return finiteOrNull(Math.sin(first));
|
|
133
|
+
case "sinh":
|
|
134
|
+
return finiteOrNull(Math.sinh(first));
|
|
135
|
+
case "tan":
|
|
136
|
+
return finiteOrNull(Math.tan(first));
|
|
137
|
+
case "tanh":
|
|
138
|
+
return finiteOrNull(Math.tanh(first));
|
|
139
|
+
case "toDegrees":
|
|
140
|
+
return finiteOrNull((first * 180) / Math.PI);
|
|
141
|
+
case "toRadians":
|
|
142
|
+
return finiteOrNull((first * Math.PI) / 180);
|
|
143
|
+
default:
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export function statsOperatorValue(name, values) {
|
|
148
|
+
if (values.length === 0)
|
|
149
|
+
return 0;
|
|
150
|
+
const meanValue = mean(values);
|
|
151
|
+
const squareDiffs = values.map((value) => (value - meanValue) ** 2);
|
|
152
|
+
switch (name) {
|
|
153
|
+
case "mean":
|
|
154
|
+
return meanValue;
|
|
155
|
+
case "sampleVariance":
|
|
156
|
+
return meanWithDivisor(squareDiffs, values.length > 1 ? values.length - 1 : 1);
|
|
157
|
+
case "sampleSD":
|
|
158
|
+
return Math.sqrt(meanWithDivisor(squareDiffs, values.length > 1 ? values.length - 1 : 1));
|
|
159
|
+
case "popVariance":
|
|
160
|
+
return mean(squareDiffs);
|
|
161
|
+
case "popSD":
|
|
162
|
+
return Math.sqrt(mean(squareDiffs));
|
|
163
|
+
default:
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function mean(values) {
|
|
168
|
+
return meanWithDivisor(values, values.length);
|
|
169
|
+
}
|
|
170
|
+
function meanWithDivisor(values, divisor) {
|
|
171
|
+
if (values.length === 0)
|
|
172
|
+
return 0;
|
|
173
|
+
return values.reduce((sum, value) => sum + value, 0) / divisor;
|
|
174
|
+
}
|
|
175
|
+
function finiteOrNull(value) {
|
|
176
|
+
return Number.isFinite(value) ? value : null;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=processing-operators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-operators.js","sourceRoot":"","sources":["../src/processing-operators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-random.d.ts","sourceRoot":"","sources":["../src/processing-random.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,MAAM,CAMhE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function seededRandom(seed) {
|
|
2
|
+
let state = typeof seed === "number" ? seed >>> 0 : hashSeed(seed);
|
|
3
|
+
return () => {
|
|
4
|
+
state = (1664525 * state + 1013904223) >>> 0;
|
|
5
|
+
return state / 0x100000000;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function hashSeed(seed) {
|
|
9
|
+
let hash = 2166136261;
|
|
10
|
+
for (let index = 0; index < seed.length; index += 1) {
|
|
11
|
+
hash ^= seed.charCodeAt(index);
|
|
12
|
+
hash = Math.imul(hash, 16777619);
|
|
13
|
+
}
|
|
14
|
+
return hash >>> 0;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=processing-random.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-random.js","sourceRoot":"","sources":["../src/processing-random.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,IAAqB;IAChD,IAAI,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO,GAAG,EAAE;QACV,KAAK,GAAG,CAAC,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,KAAK,GAAG,WAAW,CAAC;IAC7B,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { QtiAttemptStateV1, QtiAttemptStatus, QtiDiagnostic, QtiPortableCustomStateValue, QtiValue } from "./types.js";
|
|
2
|
+
export declare function serialize(itemIdentifier: string, status: QtiAttemptStatus, responses: Record<string, QtiValue>, outcomes: Record<string, QtiValue>, templateValues: Record<string, QtiValue>, interactionStates: Record<string, QtiPortableCustomStateValue>, validationMessages: QtiDiagnostic[]): QtiAttemptStateV1;
|
|
3
|
+
export declare function cloneValueRecord(record: Record<string, QtiValue>): Record<string, QtiValue>;
|
|
4
|
+
export declare function clonePortableCustomStateRecord(record: Record<string, QtiPortableCustomStateValue>): Record<string, QtiPortableCustomStateValue>;
|
|
5
|
+
export declare function cloneValue(value: QtiValue): QtiValue;
|
|
6
|
+
export declare function clonePortableCustomState(value: QtiPortableCustomStateValue): QtiPortableCustomStateValue;
|
|
7
|
+
export declare function cloneDiagnostics(diagnostics: QtiDiagnostic[]): QtiDiagnostic[];
|
|
8
|
+
//# sourceMappingURL=processing-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-state.d.ts","sourceRoot":"","sources":["../src/processing-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,2BAA2B,EAC3B,QAAQ,EACT,MAAM,YAAY,CAAC;AAIpB,wBAAgB,SAAS,CACvB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAClC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACxC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,EAC9D,kBAAkB,EAAE,aAAa,EAAE,GAClC,iBAAiB,CAWnB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAE3F;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,GAClD,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAI7C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAIpD;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,2BAA2B,GACjC,2BAA2B,CAI7B;AAQD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAK9E"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ATTEMPT_STATE_SCHEMA } from "./attempt-state-constants.js";
|
|
2
|
+
import { isRecordValue } from "./processing-values.js";
|
|
3
|
+
export function serialize(itemIdentifier, status, responses, outcomes, templateValues, interactionStates, validationMessages) {
|
|
4
|
+
return {
|
|
5
|
+
schema: ATTEMPT_STATE_SCHEMA,
|
|
6
|
+
itemIdentifier,
|
|
7
|
+
status,
|
|
8
|
+
responses: cloneValueRecord(responses),
|
|
9
|
+
outcomes: cloneValueRecord(outcomes),
|
|
10
|
+
templateValues: cloneValueRecord(templateValues),
|
|
11
|
+
interactionStates: clonePortableCustomStateRecord(interactionStates),
|
|
12
|
+
validationMessages: cloneDiagnostics(validationMessages),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function cloneValueRecord(record) {
|
|
16
|
+
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, cloneValue(value)]));
|
|
17
|
+
}
|
|
18
|
+
export function clonePortableCustomStateRecord(record) {
|
|
19
|
+
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, clonePortableCustomState(value)]));
|
|
20
|
+
}
|
|
21
|
+
export function cloneValue(value) {
|
|
22
|
+
if (Array.isArray(value))
|
|
23
|
+
return [...value];
|
|
24
|
+
if (isRecordValue(value))
|
|
25
|
+
return cloneValueRecord(value);
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
export function clonePortableCustomState(value) {
|
|
29
|
+
if (Array.isArray(value))
|
|
30
|
+
return value.map(clonePortableCustomState);
|
|
31
|
+
if (isPortableCustomStateObject(value))
|
|
32
|
+
return clonePortableCustomStateRecord(value);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function isPortableCustomStateObject(value) {
|
|
36
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37
|
+
}
|
|
38
|
+
export function cloneDiagnostics(diagnostics) {
|
|
39
|
+
return diagnostics.map((diagnostic) => ({
|
|
40
|
+
...diagnostic,
|
|
41
|
+
source: diagnostic.source ? { ...diagnostic.source } : undefined,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=processing-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-state.js","sourceRoot":"","sources":["../src/processing-state.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,UAAU,SAAS,CACvB,cAAsB,EACtB,MAAwB,EACxB,SAAmC,EACnC,QAAkC,EAClC,cAAwC,EACxC,iBAA8D,EAC9D,kBAAmC;IAEnC,OAAO;QACL,MAAM,EAAE,oBAAoB;QAC5B,cAAc;QACd,MAAM;QACN,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC;QACtC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,CAAC;QACpC,cAAc,EAAE,gBAAgB,CAAC,cAAc,CAAC;QAChD,iBAAiB,EAAE,8BAA8B,CAAC,iBAAiB,CAAC;QACpE,kBAAkB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAgC;IAC/D,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,MAAmD;IAEnD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC,CACrF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAe;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IAC5C,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAkC;IAElC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACrE,IAAI,2BAA2B,CAAC,KAAK,CAAC;QAAE,OAAO,8BAA8B,CAAC,KAAK,CAAC,CAAC;IACrF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,2BAA2B,CAClC,KAAkC;IAElC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAA4B;IAC3D,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACtC,GAAG,UAAU;QACb,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;KACjE,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-templates.d.ts","sourceRoot":"","sources":["../src/processing-templates.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,8BAA8B,GAAG,cAAc,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEjG,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,GACf,8BAA8B,GAAG,SAAS,CAO5C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function responseProcessingTemplateKind(template) {
|
|
2
|
+
const path = template.split(/[?#]/, 1)[0] ?? "";
|
|
3
|
+
const name = path.slice(path.lastIndexOf("/") + 1).replace(/\.xml$/i, "");
|
|
4
|
+
if (name === "match_correct")
|
|
5
|
+
return "matchCorrect";
|
|
6
|
+
if (name === "map_response")
|
|
7
|
+
return "mapResponse";
|
|
8
|
+
if (name === "map_response_point")
|
|
9
|
+
return "mapResponsePoint";
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=processing-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-templates.js","sourceRoot":"","sources":["../src/processing-templates.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,8BAA8B,CAC5C,QAAgB;IAEhB,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC1E,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,cAAc,CAAC;IACpD,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,aAAa,CAAC;IAClD,IAAI,IAAI,KAAK,oBAAoB;QAAE,OAAO,kBAAkB,CAAC;IAC7D,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { QtiRecordValue, QtiResponseDeclaration, QtiScalarValue, QtiValue } from "./types.js";
|
|
2
|
+
export declare function isNullResponse(response: QtiValue): boolean;
|
|
3
|
+
export declare function valuesEqual(actual: QtiValue, expected: QtiValue, ordered?: boolean): boolean;
|
|
4
|
+
export declare function qtiMatchValues(actual: QtiValue, expected: QtiValue, ordered?: boolean): boolean | null;
|
|
5
|
+
export declare function normalizeValueForCardinality(value: QtiValue, cardinality: QtiResponseDeclaration["cardinality"]): QtiValue;
|
|
6
|
+
export declare function valueContainer(value: QtiValue): QtiScalarValue[];
|
|
7
|
+
export declare function isRecordValue(value: QtiValue): value is QtiRecordValue;
|
|
8
|
+
export declare function containsValues(collection: QtiScalarValue[], values: QtiScalarValue[]): boolean;
|
|
9
|
+
export declare function numericValue(value: QtiValue): number;
|
|
10
|
+
export declare function numericValueOrNull(value: QtiValue): number | null;
|
|
11
|
+
export declare function durationSeconds(value: QtiValue): number | null;
|
|
12
|
+
export declare function booleanValue(value: QtiValue): boolean;
|
|
13
|
+
export declare function booleanValueOrNull(value: QtiValue): boolean | null;
|
|
14
|
+
export declare function stringMatch(left: QtiValue, right: QtiValue, caseSensitive: boolean, substring: boolean): boolean | null;
|
|
15
|
+
//# sourceMappingURL=processing-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processing-values.d.ts","sourceRoot":"","sources":["../src/processing-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGnG,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAE1D;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAsB1F;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,QAAQ,EAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,UAAQ,GACd,OAAO,GAAG,IAAI,CAGhB;AAkBD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,sBAAsB,CAAC,aAAa,CAAC,GACjD,QAAQ,CAUV;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,cAAc,EAAE,CAIhE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,KAAK,IAAI,cAAc,CAEtE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAQ9F;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAKpD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAQjE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAoB9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAMrD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CAGlE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,QAAQ,EACf,aAAa,EAAE,OAAO,EACtB,SAAS,EAAE,OAAO,GACjB,OAAO,GAAG,IAAI,CAShB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { qtiValueToString } from "./value-format.js";
|
|
2
|
+
export function isNullResponse(response) {
|
|
3
|
+
return response === null || response === "" || (Array.isArray(response) && response.length === 0);
|
|
4
|
+
}
|
|
5
|
+
export function valuesEqual(actual, expected, ordered = false) {
|
|
6
|
+
if (isRecordValue(actual) || isRecordValue(expected)) {
|
|
7
|
+
if (!isRecordValue(actual) || !isRecordValue(expected))
|
|
8
|
+
return false;
|
|
9
|
+
const actualKeys = Object.keys(actual).toSorted();
|
|
10
|
+
const expectedKeys = Object.keys(expected).toSorted();
|
|
11
|
+
return (valuesEqual(actualKeys, expectedKeys, true) &&
|
|
12
|
+
actualKeys.every((key) => valuesEqual(actual[key] ?? null, expected[key] ?? null, ordered)));
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(actual) || Array.isArray(expected)) {
|
|
15
|
+
const actualValues = valueContainer(actual);
|
|
16
|
+
const expectedValues = Array.isArray(expected) ? expected : expected === null ? [] : [expected];
|
|
17
|
+
if (actualValues.length !== expectedValues.length)
|
|
18
|
+
return false;
|
|
19
|
+
if (ordered)
|
|
20
|
+
return actualValues.every((value, index) => scalarValuesEqual(value, expectedValues[index]));
|
|
21
|
+
const sortedExpected = [...expectedValues].toSorted(compareScalarValues);
|
|
22
|
+
return [...actualValues]
|
|
23
|
+
.toSorted(compareScalarValues)
|
|
24
|
+
.every((value, index) => scalarValuesEqual(value, sortedExpected[index]));
|
|
25
|
+
}
|
|
26
|
+
return scalarValuesEqual(actual, expected);
|
|
27
|
+
}
|
|
28
|
+
export function qtiMatchValues(actual, expected, ordered = false) {
|
|
29
|
+
if (actual === null || expected === null)
|
|
30
|
+
return null;
|
|
31
|
+
return valuesEqual(actual, expected, ordered);
|
|
32
|
+
}
|
|
33
|
+
function scalarValuesEqual(actual, expected) {
|
|
34
|
+
if (typeof actual === "boolean" && typeof expected === "string") {
|
|
35
|
+
return String(actual) === expected;
|
|
36
|
+
}
|
|
37
|
+
if (typeof actual === "string" && typeof expected === "boolean") {
|
|
38
|
+
return actual === String(expected);
|
|
39
|
+
}
|
|
40
|
+
if (typeof actual === "number" && typeof expected === "string") {
|
|
41
|
+
return String(actual) === expected;
|
|
42
|
+
}
|
|
43
|
+
if (typeof actual === "string" && typeof expected === "number") {
|
|
44
|
+
return actual === String(expected);
|
|
45
|
+
}
|
|
46
|
+
return actual === expected;
|
|
47
|
+
}
|
|
48
|
+
export function normalizeValueForCardinality(value, cardinality) {
|
|
49
|
+
if ((cardinality === "multiple" || cardinality === "ordered") &&
|
|
50
|
+
value !== null &&
|
|
51
|
+
!Array.isArray(value) &&
|
|
52
|
+
!isRecordValue(value)) {
|
|
53
|
+
return [value];
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
export function valueContainer(value) {
|
|
58
|
+
if (value === null)
|
|
59
|
+
return [];
|
|
60
|
+
if (isRecordValue(value))
|
|
61
|
+
return [];
|
|
62
|
+
return Array.isArray(value) ? value : [value];
|
|
63
|
+
}
|
|
64
|
+
export function isRecordValue(value) {
|
|
65
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
66
|
+
}
|
|
67
|
+
export function containsValues(collection, values) {
|
|
68
|
+
const remaining = [...collection];
|
|
69
|
+
for (const value of values) {
|
|
70
|
+
const index = remaining.findIndex((candidate) => valuesEqual(candidate, value));
|
|
71
|
+
if (index === -1)
|
|
72
|
+
return false;
|
|
73
|
+
remaining.splice(index, 1);
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
function compareScalarValues(left, right) {
|
|
78
|
+
return String(left).localeCompare(String(right));
|
|
79
|
+
}
|
|
80
|
+
export function numericValue(value) {
|
|
81
|
+
if (typeof value === "number")
|
|
82
|
+
return value;
|
|
83
|
+
if (typeof value === "boolean")
|
|
84
|
+
return value ? 1 : 0;
|
|
85
|
+
if (typeof value === "string")
|
|
86
|
+
return Number(value);
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
export function numericValueOrNull(value) {
|
|
90
|
+
if (typeof value === "number")
|
|
91
|
+
return Number.isFinite(value) ? value : null;
|
|
92
|
+
if (typeof value === "boolean")
|
|
93
|
+
return value ? 1 : 0;
|
|
94
|
+
if (typeof value === "string") {
|
|
95
|
+
const parsed = Number(value);
|
|
96
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
export function durationSeconds(value) {
|
|
101
|
+
if (value === null || Array.isArray(value) || isRecordValue(value))
|
|
102
|
+
return null;
|
|
103
|
+
if (typeof value === "number")
|
|
104
|
+
return Number.isFinite(value) ? value : null;
|
|
105
|
+
const raw = String(value).trim();
|
|
106
|
+
if (raw.length === 0)
|
|
107
|
+
return null;
|
|
108
|
+
const numeric = Number(raw);
|
|
109
|
+
if (Number.isFinite(numeric))
|
|
110
|
+
return numeric;
|
|
111
|
+
const match = /^P(?:(\d+(?:\.\d+)?)D)?(?:T(?:(\d+(?:\.\d+)?)H)?(?:(\d+(?:\.\d+)?)M)?(?:(\d+(?:\.\d+)?)S)?)?$/i.exec(raw);
|
|
112
|
+
if (!match)
|
|
113
|
+
return null;
|
|
114
|
+
const [, days, hours, minutes, seconds] = match;
|
|
115
|
+
if (!days && !hours && !minutes && !seconds)
|
|
116
|
+
return null;
|
|
117
|
+
const total = Number(days ?? 0) * 86_400 +
|
|
118
|
+
Number(hours ?? 0) * 3_600 +
|
|
119
|
+
Number(minutes ?? 0) * 60 +
|
|
120
|
+
Number(seconds ?? 0);
|
|
121
|
+
return Number.isFinite(total) ? total : null;
|
|
122
|
+
}
|
|
123
|
+
export function booleanValue(value) {
|
|
124
|
+
if (typeof value === "boolean")
|
|
125
|
+
return value;
|
|
126
|
+
if (typeof value === "number")
|
|
127
|
+
return value !== 0;
|
|
128
|
+
if (typeof value === "string")
|
|
129
|
+
return value.length > 0 && value !== "false";
|
|
130
|
+
if (Array.isArray(value))
|
|
131
|
+
return value.length > 0;
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
export function booleanValueOrNull(value) {
|
|
135
|
+
if (value === null)
|
|
136
|
+
return null;
|
|
137
|
+
return booleanValue(value);
|
|
138
|
+
}
|
|
139
|
+
export function stringMatch(left, right, caseSensitive, substring) {
|
|
140
|
+
if (left === null || right === null)
|
|
141
|
+
return null;
|
|
142
|
+
let actual = qtiValueToString(left);
|
|
143
|
+
let expected = qtiValueToString(right);
|
|
144
|
+
if (!caseSensitive) {
|
|
145
|
+
actual = actual.toLocaleLowerCase();
|
|
146
|
+
expected = expected.toLocaleLowerCase();
|
|
147
|
+
}
|
|
148
|
+
return substring ? actual.includes(expected) : actual === expected;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=processing-values.js.map
|