@qti-components/processing 1.6.1-next.3 → 1.6.1-next.5
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/qti-condition/qti-condition-base.d.ts +5 -1
- package/dist/components/qti-condition/qti-condition-base.js +6 -1
- package/dist/components/qti-condition/qti-condition-base.js.map +1 -1
- package/dist/components/qti-exit-response/qti-exit-response.d.ts +2 -2
- package/dist/components/qti-exit-response/qti-exit-response.js +2 -2
- package/dist/components/qti-exit-response/qti-exit-response.js.map +1 -1
- package/dist/components/qti-map-response-point/qti-map-response-point.js +3 -2
- package/dist/components/qti-map-response-point/qti-map-response-point.js.map +1 -1
- package/package.json +2 -2
|
@@ -35,7 +35,11 @@ export declare abstract class QtiConditionElseBase extends QtiConditionBranchBas
|
|
|
35
35
|
* remaining children are the sub-rules processed when it evaluates to true.
|
|
36
36
|
*/
|
|
37
37
|
export declare abstract class QtiConditionIfBase extends QtiConditionBranchBase {
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Variables and base values hold a boolean as the string `'true'` or `'false'`, and `'false'` is
|
|
40
|
+
* truthy, so the condition applies only to `true` itself; `false` and NULL do not.
|
|
41
|
+
*/
|
|
42
|
+
shouldProcess(): boolean;
|
|
39
43
|
getSubRules(): QtiRule[];
|
|
40
44
|
}
|
|
41
45
|
/**
|
|
@@ -43,9 +43,14 @@ export class QtiConditionElseBase extends QtiConditionBranchBase {
|
|
|
43
43
|
* remaining children are the sub-rules processed when it evaluates to true.
|
|
44
44
|
*/
|
|
45
45
|
export class QtiConditionIfBase extends QtiConditionBranchBase {
|
|
46
|
+
/**
|
|
47
|
+
* Variables and base values hold a boolean as the string `'true'` or `'false'`, and `'false'` is
|
|
48
|
+
* truthy, so the condition applies only to `true` itself; `false` and NULL do not.
|
|
49
|
+
*/
|
|
46
50
|
shouldProcess() {
|
|
47
51
|
const expression = this.firstElementChild;
|
|
48
|
-
|
|
52
|
+
const value = expression.calculate();
|
|
53
|
+
return value === true || value === 'true';
|
|
49
54
|
}
|
|
50
55
|
getSubRules() {
|
|
51
56
|
const result = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-condition-base.js","sourceRoot":"","sources":["../../../src/components/qti-condition/qti-condition-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAI/C;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,OAAgB,sBAAuB,SAAQ,UAAU;IACpD,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;IAQM,OAAO;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAgB,oBAAqB,SAAQ,sBAAsB;IAChE,aAAa;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,WAAW;QAChB,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAc,CAAC;IACzC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAgB,kBAAmB,SAAQ,sBAAsB;
|
|
1
|
+
{"version":3,"file":"qti-condition-base.js","sourceRoot":"","sources":["../../../src/components/qti-condition/qti-condition-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAI/C;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,OAAgB,sBAAuB,SAAQ,UAAU;IACpD,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;IAQM,OAAO;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAgB,oBAAqB,SAAQ,sBAAsB;IAChE,aAAa;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,WAAW;QAChB,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAc,CAAC;IACzC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAgB,kBAAmB,SAAQ,sBAAsB;IACrE;;;OAGG;IACI,aAAa;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAoD,CAAC;QAC7E,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;QACrC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC;IAC5C,CAAC;IAEM,WAAW;QAChB,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAY,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAgB,gBAAiB,SAAQ,OAAO;IAC3C,MAAM;QACb,OAAO,IAAI,CAAA,eAAe,CAAC;IAC7B,CAAC;IAEe,OAAO;QACrB,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAA6B,CAAC;QAEhE,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC9B,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;gBAC3B,MAAM,CAAC,OAAO,EAAE,CAAC;gBAEjB,mEAAmE;gBACnE,uEAAuE;gBACvE,+BAA+B;gBAC/B,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;CACF","sourcesContent":["import { LitElement, html } from 'lit';\n\nimport { QtiRule } from '../qti-rule/qti-rule';\n\nimport type { QtiExpression } from '@qti-components/base';\n\n/**\n * Shared logic for the QTI `responseCondition` / `outcomeCondition` family.\n *\n * Both conditions are structurally identical: a container that walks its\n * branches (if / else-if / else) in order and processes the sub-rules of the\n * first branch whose `shouldProcess()` returns true. The only difference\n * between response- and outcome- variants is the custom element tag name, so\n * the behaviour lives here and the concrete classes are empty subclasses that\n * `elements.ts` maps onto their tags.\n */\n\n/**\n * A single branch of a condition (if / else-if / else). It owns the sub-rule\n * processing; subclasses decide whether the branch applies (`shouldProcess`)\n * and which of its children are sub-rules (`getSubRules`).\n */\nexport abstract class QtiConditionBranchBase extends LitElement {\n override render() {\n return html`<slot></slot>`;\n }\n\n /** Whether this branch's sub-rules should be processed. */\n public abstract shouldProcess(): boolean;\n\n /** The sub-rules to process when this branch applies. */\n public abstract getSubRules(): QtiRule[];\n\n public process() {\n const subRules = this.getSubRules();\n for (let i = 0; i < subRules.length; i++) {\n const subRule = subRules[i];\n subRule.process();\n }\n }\n}\n\n/**\n * The `else` branch: no condition (always applies), every child is a sub-rule.\n */\nexport abstract class QtiConditionElseBase extends QtiConditionBranchBase {\n public shouldProcess() {\n return true;\n }\n\n public getSubRules(): QtiRule[] {\n return [...this.children] as QtiRule[];\n }\n}\n\n/**\n * The `if` / `else-if` branch: first child is the boolean expression, the\n * remaining children are the sub-rules processed when it evaluates to true.\n */\nexport abstract class QtiConditionIfBase extends QtiConditionBranchBase {\n /**\n * Variables and base values hold a boolean as the string `'true'` or `'false'`, and `'false'` is\n * truthy, so the condition applies only to `true` itself; `false` and NULL do not.\n */\n public shouldProcess() {\n const expression = this.firstElementChild as QtiExpression<boolean | string>;\n const value = expression.calculate();\n return value === true || value === 'true';\n }\n\n public getSubRules(): QtiRule[] {\n const result = [];\n for (let i = 1; i < this.children.length; i++) {\n result.push(this.children[i] as QtiRule);\n }\n return result;\n }\n}\n\n/**\n * The condition container: walk branches in order, process the first whose\n * `shouldProcess()` is true, then stop.\n */\nexport abstract class QtiConditionBase extends QtiRule {\n override render() {\n return html`<slot></slot>`;\n }\n\n public override process() {\n const branches = [...this.children] as QtiConditionBranchBase[];\n\n for (const branch of branches) {\n if (branch.shouldProcess()) {\n branch.process();\n\n // The QTI spec evaluates branches as if / else-if / else: only the\n // first branch that applies runs, so once one matches we must skip the\n // remaining branches and stop.\n return;\n }\n }\n }\n}\n"]}
|
|
@@ -4,8 +4,8 @@ import { QtiRule } from '../qti-rule/qti-rule';
|
|
|
4
4
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.exit-response
|
|
5
5
|
*
|
|
6
6
|
* No rule after it runs, at any depth. The outcomes already set are kept: a
|
|
7
|
-
* `qti-set-outcome-value` writes as it is processed,
|
|
8
|
-
*
|
|
7
|
+
* `qti-set-outcome-value` writes to the run's working copy as it is processed,
|
|
8
|
+
* and the item applies that copy once the run ends.
|
|
9
9
|
*/
|
|
10
10
|
export declare class QtiExitResponse extends QtiRule {
|
|
11
11
|
process(): never;
|
|
@@ -5,8 +5,8 @@ import { QtiRule } from '../qti-rule/qti-rule';
|
|
|
5
5
|
* @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.exit-response
|
|
6
6
|
*
|
|
7
7
|
* No rule after it runs, at any depth. The outcomes already set are kept: a
|
|
8
|
-
* `qti-set-outcome-value` writes as it is processed,
|
|
9
|
-
*
|
|
8
|
+
* `qti-set-outcome-value` writes to the run's working copy as it is processed,
|
|
9
|
+
* and the item applies that copy once the run ends.
|
|
10
10
|
*/
|
|
11
11
|
export class QtiExitResponse extends QtiRule {
|
|
12
12
|
process() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-exit-response.js","sourceRoot":"","sources":["../../../src/components/qti-exit-response/qti-exit-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,OAAO,eAAgB,SAAQ,OAAO;IAC1B,OAAO;QACrB,MAAM,IAAI,qBAAqB,EAAE,CAAC;IACpC,CAAC;CACF","sourcesContent":["import { QtiExitResponseSignal } from '@qti-components/base';\n\nimport { QtiRule } from '../qti-rule/qti-rule';\n\n/**\n * @summary The qti-exit-response rule ends the response processing of an attempt.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.exit-response\n *\n * No rule after it runs, at any depth. The outcomes already set are kept: a\n * `qti-set-outcome-value` writes as it is processed
|
|
1
|
+
{"version":3,"file":"qti-exit-response.js","sourceRoot":"","sources":["../../../src/components/qti-exit-response/qti-exit-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,OAAO,eAAgB,SAAQ,OAAO;IAC1B,OAAO;QACrB,MAAM,IAAI,qBAAqB,EAAE,CAAC;IACpC,CAAC;CACF","sourcesContent":["import { QtiExitResponseSignal } from '@qti-components/base';\n\nimport { QtiRule } from '../qti-rule/qti-rule';\n\n/**\n * @summary The qti-exit-response rule ends the response processing of an attempt.\n * @documentation https://www.imsglobal.org/spec/qti/v3p0/impl#h.exit-response\n *\n * No rule after it runs, at any depth. The outcomes already set are kept: a\n * `qti-set-outcome-value` writes to the run's working copy as it is processed,\n * and the item applies that copy once the run ends.\n */\nexport class QtiExitResponse extends QtiRule {\n public override process(): never {\n throw new QtiExitResponseSignal();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-exit-response': QtiExitResponse;\n }\n}\n"]}
|
|
@@ -19,8 +19,9 @@ export class QtiMapResponsePoint extends QtiExpression {
|
|
|
19
19
|
console.warn(`Area mapping not found for response ${this.identifier}`);
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
// An unanswered single response is null, not an empty list: it scores the default, not a crash.
|
|
23
|
+
const candidateResponses = (!Array.isArray(response.value) ? [response.value] : response.value).filter((value) => typeof value === 'string' && value.length > 0);
|
|
24
|
+
if (candidateResponses.length === 0) {
|
|
24
25
|
console.warn(`No candidate responses for response ${this.identifier}`);
|
|
25
26
|
return null;
|
|
26
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-map-response-point.js","sourceRoot":"","sources":["../../../src/components/qti-map-response-point/qti-map-response-point.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAKrD,MAAM,OAAO,mBAAoB,SAAQ,aAAqB;IAG5C,SAAS;QACvB,MAAM,QAAQ,GAAqB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;QACtG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,kBAAkB,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,WAAW,GAAmB,QAAQ,CAAC,WAAW,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,uCAAuC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,kBAAkB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC
|
|
1
|
+
{"version":3,"file":"qti-map-response-point.js","sourceRoot":"","sources":["../../../src/components/qti-map-response-point/qti-map-response-point.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\n\nimport { QtiExpression } from '@qti-components/base';\nimport { ScoringHelper } from '@qti-components/base';\n\nimport type { ResponseVariable } from '@qti-components/base';\nimport type { QtiAreaMapping } from '@qti-components/base';\n\nexport class QtiMapResponsePoint extends QtiExpression<number> {\n @property({ type: String }) identifier: string;\n\n public override getResult(): number {\n const response: ResponseVariable = this.context.variables.find(r => r.identifier === this.identifier);\n if (!response) {\n console.warn(`Response ${this.identifier} cannot be found`);\n return null;\n }\n\n const areaMapping: QtiAreaMapping = response.areaMapping;\n if (!areaMapping) {\n console.warn(`Area mapping not found for response ${this.identifier}`);\n return null;\n }\n\n // An unanswered single response is null, not an empty list: it scores the default, not a crash.\n const candidateResponses = (!Array.isArray(response.value) ? [response.value] : response.value).filter(\n (value): value is string => typeof value === 'string' && value.length > 0\n );\n if (candidateResponses.length === 0) {\n console.warn(`No candidate responses for response ${this.identifier}`);\n return null;\n }\n\n let result = 0;\n\n // Keep track of areas that have already been matched\n const mappedAreas = new Set<string>();\n\n for (const candidateResponse of candidateResponses) {\n for (const entry of areaMapping.areaMapEntries) {\n if (mappedAreas.has(entry.coords)) {\n continue; // Skip areas that have already been mapped\n }\n const isPointInArea = ScoringHelper.isPointInArea(\n candidateResponse,\n `${entry.shape},${entry.coords}`,\n response.baseType\n );\n if (isPointInArea) {\n result += entry.mappedValue ?? 0;\n mappedAreas.add(entry.coords);\n // First match wins: \"each area is tested in turn, with those listed first taking priority\n // in the case where areas overlap and a point falls in the intersection\" (QTI 3.0 §7.4).\n // Without this the point would also score every later area it happens to fall in — which\n // only became reachable once `shape=\"default\"`, an area covering the whole image, started\n // matching (Citolab/qti-components#83).\n break;\n }\n }\n }\n\n // Add default value for unmatched candidate responses\n if (mappedAreas.size < candidateResponses.length) {\n result += areaMapping.defaultValue;\n }\n\n // Apply bounds if defined\n if (areaMapping.lowerBound != null) {\n result = Math.max(areaMapping.lowerBound, result);\n }\n if (areaMapping.upperBound != null) {\n result = Math.min(areaMapping.upperBound, result);\n }\n\n return result;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qti-components/processing",
|
|
3
3
|
"description": "QTI processing utilities",
|
|
4
|
-
"version": "1.6.1-next.
|
|
4
|
+
"version": "1.6.1-next.5",
|
|
5
5
|
"author": "",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@qti-components/base": "^3.0.0-next.
|
|
7
|
+
"@qti-components/base": "^3.0.0-next.6",
|
|
8
8
|
"@qti-components/utilities": "^1.3.3"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|