@intellectif/lk-core 1.5.0 → 1.7.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/CHANGELOG.md +77 -0
- package/dist/{ai-BYryFkF9.d.ts → ai-B1wYrqcB.d.cts} +83 -18
- package/dist/ai-B1wYrqcB.d.cts.map +1 -0
- package/dist/{ai-BYryFkF9.d.cts → ai-B1wYrqcB.d.ts} +83 -18
- package/dist/ai-B1wYrqcB.d.ts.map +1 -0
- package/dist/ai-check.cjs +13 -6
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +1 -5
- package/dist/ai-check.d.cts.map +1 -1
- package/dist/ai-check.d.ts +1 -5
- package/dist/ai-check.d.ts.map +1 -1
- package/dist/ai-check.js +13 -6
- package/dist/ai-check.js.map +1 -1
- package/dist/{ai-writing-D8PdhJJz.js → ai-writing-B7oMCt66.js} +311 -66
- package/dist/ai-writing-B7oMCt66.js.map +1 -0
- package/dist/{ai-writing-Cen7-3qs.cjs → ai-writing-DrPTV3R2.cjs} +313 -50
- package/dist/ai-writing-DrPTV3R2.cjs.map +1 -0
- package/dist/{index-DUaW1Tj5.d.ts → index-BM8LeDWn.d.cts} +2 -42
- package/dist/index-BM8LeDWn.d.cts.map +1 -0
- package/dist/{index-Bg0aeWtM.d.cts → index-BTkMQtws.d.ts} +2 -42
- package/dist/index-BTkMQtws.d.ts.map +1 -0
- package/dist/{index-wMc1E_aM.d.ts → index-BU99GFTl.d.ts} +2 -8
- package/dist/index-BU99GFTl.d.ts.map +1 -0
- package/dist/{index-CxpiWedW.d.ts → index-BdXs4-en.d.ts} +42 -20
- package/dist/index-BdXs4-en.d.ts.map +1 -0
- package/dist/{index-qMbxed1B.d.cts → index-DP9rvyOz.d.cts} +42 -20
- package/dist/index-DP9rvyOz.d.cts.map +1 -0
- package/dist/{index-D7R3Ll8R.d.cts → index-XCCoPoTU.d.cts} +2 -8
- package/dist/index-XCCoPoTU.d.cts.map +1 -0
- package/dist/index.cjs +70 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -69
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +135 -69
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -22
- package/dist/index.js.map +1 -1
- package/dist/{item-group-DEB7nLID.cjs → item-group-8P3WFuUK.cjs} +5 -6
- package/dist/item-group-8P3WFuUK.cjs.map +1 -0
- package/dist/{item-group-DdSUCUjM.js → item-group-CeDk7mfM.js} +5 -6
- package/dist/item-group-CeDk7mfM.js.map +1 -0
- package/dist/{registry-DaZRpqjW.js → registry-D92hz9iA.js} +124 -106
- package/dist/registry-D92hz9iA.js.map +1 -0
- package/dist/{registry-Ce00A_OW.cjs → registry-hzrkTeIT.cjs} +142 -107
- package/dist/registry-hzrkTeIT.cjs.map +1 -0
- package/dist/{schemas-DksueYsu.cjs → schemas-BWeskONy.cjs} +79 -18
- package/dist/schemas-BWeskONy.cjs.map +1 -0
- package/dist/{schemas-BioKFf3F.js → schemas-C7TViWCg.js} +74 -19
- package/dist/schemas-C7TViWCg.js.map +1 -0
- package/dist/schemas.cjs +5 -2
- package/dist/schemas.d.cts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/schemas.js +4 -3
- package/dist/{scoring-lKQVYsxy.cjs → scoring-CtkCFyFT.cjs} +22 -42
- package/dist/{scoring-lKQVYsxy.cjs.map → scoring-CtkCFyFT.cjs.map} +1 -1
- package/dist/{scoring-BKNNTz-s.js → scoring-DD1GHcLI.js} +22 -42
- package/dist/{scoring-BKNNTz-s.js.map → scoring-DD1GHcLI.js.map} +1 -1
- package/dist/scoring.cjs +2 -2
- package/dist/scoring.d.cts +2 -2
- package/dist/scoring.d.ts +2 -2
- package/dist/scoring.js +2 -2
- package/dist/{xapi-NYrTlpID.cjs → xapi-7btSpx6v.cjs} +5 -8
- package/dist/{xapi-NYrTlpID.cjs.map → xapi-7btSpx6v.cjs.map} +1 -1
- package/dist/{xapi-wR6gu4qS.js → xapi-Cgicg-zU.js} +5 -8
- package/dist/{xapi-wR6gu4qS.js.map → xapi-Cgicg-zU.js.map} +1 -1
- package/dist/xapi.cjs +1 -1
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/dist/xapi.js +1 -1
- package/package.json +2 -2
- package/dist/ai-BYryFkF9.d.cts.map +0 -1
- package/dist/ai-BYryFkF9.d.ts.map +0 -1
- package/dist/ai-writing-Cen7-3qs.cjs.map +0 -1
- package/dist/ai-writing-D8PdhJJz.js.map +0 -1
- package/dist/index-Bg0aeWtM.d.cts.map +0 -1
- package/dist/index-CxpiWedW.d.ts.map +0 -1
- package/dist/index-D7R3Ll8R.d.cts.map +0 -1
- package/dist/index-DUaW1Tj5.d.ts.map +0 -1
- package/dist/index-qMbxed1B.d.cts.map +0 -1
- package/dist/index-wMc1E_aM.d.ts.map +0 -1
- package/dist/item-group-DEB7nLID.cjs.map +0 -1
- package/dist/item-group-DdSUCUjM.js.map +0 -1
- package/dist/registry-Ce00A_OW.cjs.map +0 -1
- package/dist/registry-DaZRpqjW.js.map +0 -1
- package/dist/schemas-BioKFf3F.js.map +0 -1
- package/dist/schemas-DksueYsu.cjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const require_registry = require("./registry-
|
|
2
|
-
const require_item_group = require("./item-group-
|
|
1
|
+
const require_registry = require("./registry-hzrkTeIT.cjs");
|
|
2
|
+
const require_item_group = require("./item-group-8P3WFuUK.cjs");
|
|
3
3
|
let zod_v4 = require("zod/v4");
|
|
4
4
|
zod_v4 = require_registry.__toESM(zod_v4, 1);
|
|
5
|
-
|
|
5
|
+
// src/schemas/json-schema.ts
|
|
6
6
|
/**
|
|
7
7
|
* JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the
|
|
8
8
|
* kind/media/body consistency guards are Zod-only.
|
|
@@ -67,32 +67,88 @@ const fillInTheBlanksJsonSchema = zod_v4.toJSONSchema(require_registry.FillInThe
|
|
|
67
67
|
* contract. Structural contract only.
|
|
68
68
|
*/
|
|
69
69
|
const writtenResponseJsonSchema = zod_v4.toJSONSchema(require_registry.WrittenResponseDataSchema, { target: "draft-7" });
|
|
70
|
+
/** What the Standard JSON Schema converter calls each draft. */
|
|
71
|
+
const STANDARD_TARGET = {
|
|
72
|
+
"draft-7": "draft-07",
|
|
73
|
+
"draft-2020-12": "draft-2020-12"
|
|
74
|
+
};
|
|
70
75
|
/**
|
|
71
|
-
* Derives the JSON Schema
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
76
|
+
* Derives the JSON Schema for any REGISTERED activity type — the live,
|
|
77
|
+
* registry-backed replacement for the static per-type exports above, and the
|
|
78
|
+
* building block for AI generation pipelines (R6.1): pass the result as a
|
|
79
|
+
* structured-output schema so a model can only emit valid items.
|
|
75
80
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
81
|
+
* Draft 7 unless `target` says `'draft-2020-12'`. For a type you registered,
|
|
82
|
+
* it is the descriptor's `jsonSchema` when you gave one, in whatever draft you
|
|
83
|
+
* wrote it, or else what the schema produces through the Standard JSON Schema
|
|
84
|
+
* converter (`'~standard'.jsonSchema`) in the draft asked for — a zod 4.6
|
|
85
|
+
* schema has one. A fresh copy every call.
|
|
80
86
|
*
|
|
81
87
|
* @throws UnknownActivityTypeError when `type` has no registered descriptor.
|
|
82
88
|
* @throws Error when a registered type has neither a `jsonSchema` nor a schema
|
|
83
89
|
* that can produce one.
|
|
84
90
|
*/
|
|
85
|
-
function jsonSchemaFor(type) {
|
|
91
|
+
function jsonSchemaFor(type, options = {}) {
|
|
92
|
+
const target = options.target ?? "draft-7";
|
|
86
93
|
const descriptor = require_registry.getActivityTypeDescriptor(type);
|
|
87
94
|
if (descriptor === void 0) throw new require_registry.UnknownActivityTypeError(type);
|
|
88
|
-
if (require_registry.isOwnSchema(descriptor.schema)) return zod_v4.toJSONSchema(descriptor.schema, { target
|
|
95
|
+
if (require_registry.isOwnSchema(descriptor.schema)) return zod_v4.toJSONSchema(descriptor.schema, { target });
|
|
89
96
|
if (descriptor.jsonSchema !== void 0) return structuredClone(descriptor.jsonSchema);
|
|
90
|
-
const generated = require_registry.standardJsonSchemaOf(descriptor.schema);
|
|
97
|
+
const generated = require_registry.standardJsonSchemaOf(descriptor.schema, STANDARD_TARGET[target]);
|
|
91
98
|
if (generated === void 0) throw new Error(`Activity type "${descriptor.type}" has no JSON Schema: its schema implements no Standard JSON Schema converter ('~standard'.jsonSchema). Give its descriptor a \`jsonSchema\`.`);
|
|
92
99
|
return generated;
|
|
93
100
|
}
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
/** A schema without its `$schema`, to sit inside another document. */
|
|
102
|
+
function body(schema) {
|
|
103
|
+
const { $schema: _draft, ...rest } = schema;
|
|
104
|
+
return rest;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* One JSON Schema document for content an outside tool writes: the root is a
|
|
108
|
+
* `SequenceEntry` — an activity of any registered type, or an item group whose
|
|
109
|
+
* items are typed too. Each type, the stimulus and the item group sit under
|
|
110
|
+
* `$defs` (`definitions` in draft 7), so a tool can also point at one of them.
|
|
111
|
+
* Draft 2020-12 unless `target` says `'draft-7'`.
|
|
112
|
+
*
|
|
113
|
+
* Structural, as every exported schema is: rules that span fields (one key in
|
|
114
|
+
* a single-answer question, a blank for each marker, a slow recording that is
|
|
115
|
+
* another file) cannot be written in JSON Schema. On import, `validateDraft`
|
|
116
|
+
* and `validateItemGroupDraft` decide. It includes the author-only fields
|
|
117
|
+
* (`transcript`, `script`), so a tool can write them.
|
|
118
|
+
*
|
|
119
|
+
* ```ts
|
|
120
|
+
* writeFileSync('schema.json', JSON.stringify(contentJsonSchema(), null, 2));
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
function contentJsonSchema(options = {}) {
|
|
124
|
+
const target = options.target ?? "draft-2020-12";
|
|
125
|
+
const definitions = target === "draft-7" ? "definitions" : "$defs";
|
|
126
|
+
const ref = (name) => ({ $ref: `#/${definitions}/${name}` });
|
|
127
|
+
const types = require_registry.registeredActivityTypes();
|
|
128
|
+
const anyActivity = { oneOf: types.map(ref) };
|
|
129
|
+
const group = body(zod_v4.toJSONSchema(require_item_group.ItemGroupSchema, { target }));
|
|
130
|
+
const properties = group.properties;
|
|
131
|
+
group.properties = {
|
|
132
|
+
...properties,
|
|
133
|
+
stimulus: ref("stimulus"),
|
|
134
|
+
items: {
|
|
135
|
+
...properties.items,
|
|
136
|
+
items: { allOf: [properties.items?.items, anyActivity] }
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
return {
|
|
140
|
+
$schema: target === "draft-7" ? "http://json-schema.org/draft-07/schema#" : "https://json-schema.org/draft/2020-12/schema",
|
|
141
|
+
title: "SequenceEntry",
|
|
142
|
+
description: "One entry of a question set or an exam section: an activity, or an item group. Structural only: validateDraft and validateItemGroupDraft decide.",
|
|
143
|
+
oneOf: [...types.map(ref), ref("item-group")],
|
|
144
|
+
[definitions]: {
|
|
145
|
+
...Object.fromEntries(types.map((type) => [type, body(jsonSchemaFor(type, { target }))])),
|
|
146
|
+
stimulus: body(zod_v4.toJSONSchema(require_item_group.StimulusSchema, { target })),
|
|
147
|
+
"item-group": group
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
// src/schemas/index.ts
|
|
96
152
|
/**
|
|
97
153
|
* Checks a piece of activity media — an item's `media`, a stimulus's, a
|
|
98
154
|
* dictation's `slowMedia` — on its own, the way `validateActivity` checks it
|
|
@@ -147,7 +203,12 @@ function validateActivity(type, data) {
|
|
|
147
203
|
if (descriptor === void 0) throw new require_registry.UnknownActivityTypeError(String(type));
|
|
148
204
|
return asValidation(require_registry.readSchema(descriptor.schema, data, `Activity type "${descriptor.type}"`));
|
|
149
205
|
}
|
|
150
|
-
|
|
206
|
+
Object.defineProperty(exports, "contentJsonSchema", {
|
|
207
|
+
enumerable: true,
|
|
208
|
+
get: function() {
|
|
209
|
+
return contentJsonSchema;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
151
212
|
Object.defineProperty(exports, "dictationJsonSchema", {
|
|
152
213
|
enumerable: true,
|
|
153
214
|
get: function() {
|
|
@@ -221,4 +282,4 @@ Object.defineProperty(exports, "writtenResponseJsonSchema", {
|
|
|
221
282
|
}
|
|
222
283
|
});
|
|
223
284
|
|
|
224
|
-
//# sourceMappingURL=schemas-
|
|
285
|
+
//# sourceMappingURL=schemas-BWeskONy.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas-BWeskONy.cjs","names":["z","StimulusSchema","ItemGroupSchema","GapSelectDataSchema","DictationDataSchema","ReadAloudDataSchema","MultipleChoiceDataSchema","FillInTheBlanksDataSchema","WrittenResponseDataSchema","getActivityTypeDescriptor","UnknownActivityTypeError","isOwnSchema","standardJsonSchemaOf","registeredActivityTypes","readSchema","MediaSchema","MultipleChoiceOptionMediaSchema","getActivityTypeDescriptor","UnknownActivityTypeError"],"sources":["../src/schemas/json-schema.ts","../src/schemas/index.ts"],"sourcesContent":["import * as z from 'zod/v4';\nimport { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor, registeredActivityTypes } from '../registry/index.js';\nimport { DictationDataSchema } from './dictation.js';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { GapSelectDataSchema } from './gap-select.js';\nimport { ItemGroupSchema, StimulusSchema } from './item-group.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\nimport { ReadAloudDataSchema } from './read-aloud.js';\nimport { isOwnSchema, standardJsonSchemaOf } from './read-schema.js';\nimport { WrittenResponseDataSchema } from './written-response.js';\n\n/**\n * JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the\n * kind/media/body consistency guards are Zod-only.\n */\nexport const stimulusJsonSchema: Record<string, unknown> = z.toJSONSchema(StimulusSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) for an `ItemGroup` CONTAINER. Items appear as objects\n * with `type` and `id` only; each item's own contract is `jsonSchemaFor(type)`.\n * For an AI generation pipeline, ask for the group and each item separately\n * rather than a single nested schema — that keeps the per-type schema the\n * registry's, not a copy.\n */\nexport const itemGroupJsonSchema: Record<string, unknown> = z.toJSONSchema(ItemGroupSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Multiple Choice activity data\n * contract, generated natively by Zod 4. Draft 7 is mandated by Requirement\n * 2.2 for the widest AI-prompt / OpenAPI tooling compatibility. The semantic\n * `.refine()` guards are not representable in JSON Schema and are\n * intentionally omitted — the export captures the *structural* contract only.\n * Since v0.3 the source schemas are loose, so these no longer emit\n * `additionalProperties: false` — the JSON Schema and `validateActivity` now\n * agree on unknown-key handling.\n */\n/**\n * JSON Schema (Draft 7) representation of the Gap Select activity data\n * contract. Structural contract only: the six semantic guards — the\n * passage/gap bijection, id uniqueness, the one-choice-source rule, and an\n * answer key that names a choice the gap offers — are Zod-only, as they are\n * for the other types.\n */\nexport const gapSelectJsonSchema: Record<string, unknown> = z.toJSONSchema(GapSelectDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Dictation activity data\n * contract. Structural contract, plus the raw length caps JSON Schema can\n * state in code points as zod counts them — `maxLength` 2000 on a transcript\n * and an accepted transcript, 200 on a rule's `from` and `to`. The twelve\n * semantic guards — a transcript that survives normalisation, the caps after\n * equivalences are applied, distinct candidates, audio only, the\n * slow-recording rules, no captions, no transcript in the title — are\n * Zod-only, as they are for the other types.\n */\nexport const dictationJsonSchema: Record<string, unknown> = z.toJSONSchema(DictationDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Read Aloud activity data\n * contract. Structural contract, plus the raw cap JSON Schema can state in code\n * points as zod counts them — `maxLength` 2000 on the reference text — and the\n * canonical locale pattern. The ten semantic guards — the cap after\n * normalisation, a text that survives it, the spaced-script rule, the\n * model-recording rules, unique dimensions, a weight above 0, and the take\n * bounds — are Zod-only, as they are for the other types.\n */\nexport const readAloudJsonSchema: Record<string, unknown> = z.toJSONSchema(ReadAloudDataSchema, {\n target: 'draft-7',\n});\n\nexport const multipleChoiceJsonSchema: Record<string, unknown> = z.toJSONSchema(\n MultipleChoiceDataSchema,\n {\n target: 'draft-7',\n },\n);\n\n/**\n * JSON Schema (Draft 7) representation of the Fill-in-the-Blanks activity data\n * contract, generated natively by Zod 4. Structural contract only (semantic\n * `.refine()` guards are Zod-only and not representable in JSON Schema).\n */\nexport const fillInTheBlanksJsonSchema: Record<string, unknown> = z.toJSONSchema(\n FillInTheBlanksDataSchema,\n {\n target: 'draft-7',\n },\n);\n\n/**\n * JSON Schema (Draft 7) representation of the Written Response activity data\n * contract. Structural contract only.\n */\nexport const writtenResponseJsonSchema: Record<string, unknown> = z.toJSONSchema(\n WrittenResponseDataSchema,\n {\n target: 'draft-7',\n },\n);\n\n/** The JSON Schema drafts the SDK writes. */\nexport type JsonSchemaTarget = 'draft-2020-12' | 'draft-7';\n\n/** What the Standard JSON Schema converter calls each draft. */\nconst STANDARD_TARGET = { 'draft-7': 'draft-07', 'draft-2020-12': 'draft-2020-12' } as const;\n\n/**\n * Derives the JSON Schema for any REGISTERED activity type — the live,\n * registry-backed replacement for the static per-type exports above, and the\n * building block for AI generation pipelines (R6.1): pass the result as a\n * structured-output schema so a model can only emit valid items.\n *\n * Draft 7 unless `target` says `'draft-2020-12'`. For a type you registered,\n * it is the descriptor's `jsonSchema` when you gave one, in whatever draft you\n * wrote it, or else what the schema produces through the Standard JSON Schema\n * converter (`'~standard'.jsonSchema`) in the draft asked for — a zod 4.6\n * schema has one. A fresh copy every call.\n *\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n * @throws Error when a registered type has neither a `jsonSchema` nor a schema\n * that can produce one.\n */\nexport function jsonSchemaFor(\n type: string,\n options: { target?: JsonSchemaTarget } = {},\n): Record<string, unknown> {\n const target = options.target ?? 'draft-7';\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(type);\n }\n if (isOwnSchema(descriptor.schema)) {\n return z.toJSONSchema(descriptor.schema as never, { target }) as Record<string, unknown>;\n }\n if (descriptor.jsonSchema !== undefined) {\n return structuredClone(descriptor.jsonSchema) as Record<string, unknown>;\n }\n const generated = standardJsonSchemaOf(descriptor.schema, STANDARD_TARGET[target]);\n if (generated === undefined) {\n throw new Error(\n `Activity type \"${descriptor.type}\" has no JSON Schema: its schema implements no Standard JSON Schema converter ('~standard'.jsonSchema). Give its descriptor a \\`jsonSchema\\`.`,\n );\n }\n return generated;\n}\n\n/** A schema without its `$schema`, to sit inside another document. */\nfunction body(schema: Record<string, unknown>): Record<string, unknown> {\n const { $schema: _draft, ...rest } = schema;\n return rest;\n}\n\n/**\n * One JSON Schema document for content an outside tool writes: the root is a\n * `SequenceEntry` — an activity of any registered type, or an item group whose\n * items are typed too. Each type, the stimulus and the item group sit under\n * `$defs` (`definitions` in draft 7), so a tool can also point at one of them.\n * Draft 2020-12 unless `target` says `'draft-7'`.\n *\n * Structural, as every exported schema is: rules that span fields (one key in\n * a single-answer question, a blank for each marker, a slow recording that is\n * another file) cannot be written in JSON Schema. On import, `validateDraft`\n * and `validateItemGroupDraft` decide. It includes the author-only fields\n * (`transcript`, `script`), so a tool can write them.\n *\n * ```ts\n * writeFileSync('schema.json', JSON.stringify(contentJsonSchema(), null, 2));\n * ```\n */\nexport function contentJsonSchema(\n options: { target?: JsonSchemaTarget } = {},\n): Record<string, unknown> {\n const target = options.target ?? 'draft-2020-12';\n const definitions = target === 'draft-7' ? 'definitions' : '$defs';\n const ref = (name: string) => ({ $ref: `#/${definitions}/${name}` });\n const types = registeredActivityTypes();\n const anyActivity = { oneOf: types.map(ref) };\n\n const group = body(z.toJSONSchema(ItemGroupSchema, { target }) as Record<string, unknown>);\n const properties = group.properties as Record<string, Record<string, unknown>>;\n group.properties = {\n ...properties,\n stimulus: ref('stimulus'),\n // The container's own rule for an item (a `type`, an `id`, a `slotKey`),\n // and the item's type's whole contract.\n items: { ...properties.items, items: { allOf: [properties.items?.items, anyActivity] } },\n };\n\n return {\n $schema:\n target === 'draft-7'\n ? 'http://json-schema.org/draft-07/schema#'\n : 'https://json-schema.org/draft/2020-12/schema',\n title: 'SequenceEntry',\n description:\n 'One entry of a question set or an exam section: an activity, or an item group. Structural only: validateDraft and validateItemGroupDraft decide.',\n oneOf: [...types.map(ref), ref('item-group')],\n [definitions]: {\n ...Object.fromEntries(types.map((type) => [type, body(jsonSchemaFor(type, { target }))])),\n stimulus: body(z.toJSONSchema(StimulusSchema, { target }) as Record<string, unknown>),\n 'item-group': group,\n },\n };\n}\n","import { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport type {\n ActivityDataMap,\n ActivityMedia,\n ActivityType,\n MultipleChoiceOptionMedia,\n ValidationResult,\n} from '../types/activity.js';\nimport { MediaSchema } from './media.js';\nimport { MultipleChoiceOptionMediaSchema } from './multiple-choice.js';\nimport { readSchema, type SchemaReading } from './read-schema.js';\n\nexport type {\n RedactedActivity,\n RedactedBlankConfig,\n RedactedDictationData,\n RedactedDictationSlowMedia,\n RedactedFillInTheBlanksData,\n RedactedGapSelectBank,\n RedactedGapSelectChoice,\n RedactedGapSelectData,\n RedactedGapSelectGap,\n RedactedMultipleChoiceData,\n RedactedMultipleChoiceOption,\n RedactedMultipleChoiceOptionMedia,\n RedactedReadAloudData,\n RedactedStimulus,\n RedactedWrittenResponseData,\n} from '../types/redacted.js';\nexport { validateItemGroup } from './item-group.js';\nexport {\n contentJsonSchema,\n dictationJsonSchema,\n fillInTheBlanksJsonSchema,\n gapSelectJsonSchema,\n itemGroupJsonSchema,\n type JsonSchemaTarget,\n jsonSchemaFor,\n multipleChoiceJsonSchema,\n readAloudJsonSchema,\n stimulusJsonSchema,\n writtenResponseJsonSchema,\n} from './json-schema.js';\nexport { SCRIPT_MAX_TURNS } from './media.js';\n\n/**\n * Checks a piece of activity media — an item's `media`, a stimulus's, a\n * dictation's `slowMedia` — on its own, the way `validateActivity` checks it\n * inside an item: its kind, an address in the allowed schemes, a playback\n * policy only on audio, captions and tracks only where they can play. For an\n * editor's media picker, which holds the media before the item is whole.\n *\n * @returns `{ success: true, data }`, or `{ success: false, errors }` with the\n * same codes, paths and messages `validateActivity` reports.\n */\nexport function validateMedia(value: unknown): ValidationResult<ActivityMedia> {\n return asValidation(readSchema(MediaSchema as never, value, 'Media'));\n}\n\n/**\n * Checks a multiple-choice option's `media` on its own: a picture or a\n * recording, at an address in the allowed schemes, with no playback policy.\n *\n * @returns `{ success: true, data }`, or `{ success: false, errors }` with the\n * same codes, paths and messages `validateActivity` reports.\n */\nexport function validateOptionMedia(value: unknown): ValidationResult<MultipleChoiceOptionMedia> {\n return asValidation(readSchema(MultipleChoiceOptionMediaSchema as never, value, 'Option media'));\n}\n\nfunction asValidation<T>(reading: SchemaReading<unknown>): ValidationResult<T> {\n if (reading.success) {\n return { success: true, data: reading.data as T };\n }\n return {\n success: false,\n errors: reading.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n };\n}\n\n/**\n * Validates raw activity data against the schema registered for the given\n * activity type (built-in or consumer-registered via `registerActivityType`).\n *\n * Unknown keys are PRESERVED, not stripped: every built-in schema is loose,\n * so consumer sidecar fields and forward-version fields survive validation\n * verbatim in the returned `data`.\n *\n * @returns `{ success: true, data }` with the typed, validated data, or\n * `{ success: false, errors }` with one entry per failed constraint.\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function validateActivity<T extends ActivityType>(\n type: T,\n data: unknown,\n): ValidationResult<ActivityDataMap[T]> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(String(type));\n }\n\n return asValidation(readSchema(descriptor.schema, data, `Activity type \"${descriptor.type}\"`));\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { D as MultipleChoiceOptionMediaSchema, E as MultipleChoiceDataSchema,
|
|
2
|
-
import { r as StimulusSchema, t as ItemGroupSchema } from "./item-group-
|
|
1
|
+
import { Ct as MediaSchema, D as MultipleChoiceOptionMediaSchema, E as MultipleChoiceDataSchema, St as FillInTheBlanksDataSchema, Y as DictationDataSchema, _ as GapSelectDataSchema, a as readSchema, g as WrittenResponseDataSchema, i as isOwnSchema, o as standardJsonSchemaOf, r as registeredActivityTypes, t as getActivityTypeDescriptor, tt as UnknownActivityTypeError, v as ReadAloudDataSchema } from "./registry-D92hz9iA.js";
|
|
2
|
+
import { r as StimulusSchema, t as ItemGroupSchema } from "./item-group-CeDk7mfM.js";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
|
-
|
|
4
|
+
// src/schemas/json-schema.ts
|
|
5
5
|
/**
|
|
6
6
|
* JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the
|
|
7
7
|
* kind/media/body consistency guards are Zod-only.
|
|
@@ -66,32 +66,88 @@ const fillInTheBlanksJsonSchema = z.toJSONSchema(FillInTheBlanksDataSchema, { ta
|
|
|
66
66
|
* contract. Structural contract only.
|
|
67
67
|
*/
|
|
68
68
|
const writtenResponseJsonSchema = z.toJSONSchema(WrittenResponseDataSchema, { target: "draft-7" });
|
|
69
|
+
/** What the Standard JSON Schema converter calls each draft. */
|
|
70
|
+
const STANDARD_TARGET = {
|
|
71
|
+
"draft-7": "draft-07",
|
|
72
|
+
"draft-2020-12": "draft-2020-12"
|
|
73
|
+
};
|
|
69
74
|
/**
|
|
70
|
-
* Derives the JSON Schema
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
75
|
+
* Derives the JSON Schema for any REGISTERED activity type — the live,
|
|
76
|
+
* registry-backed replacement for the static per-type exports above, and the
|
|
77
|
+
* building block for AI generation pipelines (R6.1): pass the result as a
|
|
78
|
+
* structured-output schema so a model can only emit valid items.
|
|
74
79
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
80
|
+
* Draft 7 unless `target` says `'draft-2020-12'`. For a type you registered,
|
|
81
|
+
* it is the descriptor's `jsonSchema` when you gave one, in whatever draft you
|
|
82
|
+
* wrote it, or else what the schema produces through the Standard JSON Schema
|
|
83
|
+
* converter (`'~standard'.jsonSchema`) in the draft asked for — a zod 4.6
|
|
84
|
+
* schema has one. A fresh copy every call.
|
|
79
85
|
*
|
|
80
86
|
* @throws UnknownActivityTypeError when `type` has no registered descriptor.
|
|
81
87
|
* @throws Error when a registered type has neither a `jsonSchema` nor a schema
|
|
82
88
|
* that can produce one.
|
|
83
89
|
*/
|
|
84
|
-
function jsonSchemaFor(type) {
|
|
90
|
+
function jsonSchemaFor(type, options = {}) {
|
|
91
|
+
const target = options.target ?? "draft-7";
|
|
85
92
|
const descriptor = getActivityTypeDescriptor(type);
|
|
86
93
|
if (descriptor === void 0) throw new UnknownActivityTypeError(type);
|
|
87
|
-
if (isOwnSchema(descriptor.schema)) return z.toJSONSchema(descriptor.schema, { target
|
|
94
|
+
if (isOwnSchema(descriptor.schema)) return z.toJSONSchema(descriptor.schema, { target });
|
|
88
95
|
if (descriptor.jsonSchema !== void 0) return structuredClone(descriptor.jsonSchema);
|
|
89
|
-
const generated = standardJsonSchemaOf(descriptor.schema);
|
|
96
|
+
const generated = standardJsonSchemaOf(descriptor.schema, STANDARD_TARGET[target]);
|
|
90
97
|
if (generated === void 0) throw new Error(`Activity type "${descriptor.type}" has no JSON Schema: its schema implements no Standard JSON Schema converter ('~standard'.jsonSchema). Give its descriptor a \`jsonSchema\`.`);
|
|
91
98
|
return generated;
|
|
92
99
|
}
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
/** A schema without its `$schema`, to sit inside another document. */
|
|
101
|
+
function body(schema) {
|
|
102
|
+
const { $schema: _draft, ...rest } = schema;
|
|
103
|
+
return rest;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* One JSON Schema document for content an outside tool writes: the root is a
|
|
107
|
+
* `SequenceEntry` — an activity of any registered type, or an item group whose
|
|
108
|
+
* items are typed too. Each type, the stimulus and the item group sit under
|
|
109
|
+
* `$defs` (`definitions` in draft 7), so a tool can also point at one of them.
|
|
110
|
+
* Draft 2020-12 unless `target` says `'draft-7'`.
|
|
111
|
+
*
|
|
112
|
+
* Structural, as every exported schema is: rules that span fields (one key in
|
|
113
|
+
* a single-answer question, a blank for each marker, a slow recording that is
|
|
114
|
+
* another file) cannot be written in JSON Schema. On import, `validateDraft`
|
|
115
|
+
* and `validateItemGroupDraft` decide. It includes the author-only fields
|
|
116
|
+
* (`transcript`, `script`), so a tool can write them.
|
|
117
|
+
*
|
|
118
|
+
* ```ts
|
|
119
|
+
* writeFileSync('schema.json', JSON.stringify(contentJsonSchema(), null, 2));
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
function contentJsonSchema(options = {}) {
|
|
123
|
+
const target = options.target ?? "draft-2020-12";
|
|
124
|
+
const definitions = target === "draft-7" ? "definitions" : "$defs";
|
|
125
|
+
const ref = (name) => ({ $ref: `#/${definitions}/${name}` });
|
|
126
|
+
const types = registeredActivityTypes();
|
|
127
|
+
const anyActivity = { oneOf: types.map(ref) };
|
|
128
|
+
const group = body(z.toJSONSchema(ItemGroupSchema, { target }));
|
|
129
|
+
const properties = group.properties;
|
|
130
|
+
group.properties = {
|
|
131
|
+
...properties,
|
|
132
|
+
stimulus: ref("stimulus"),
|
|
133
|
+
items: {
|
|
134
|
+
...properties.items,
|
|
135
|
+
items: { allOf: [properties.items?.items, anyActivity] }
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
$schema: target === "draft-7" ? "http://json-schema.org/draft-07/schema#" : "https://json-schema.org/draft/2020-12/schema",
|
|
140
|
+
title: "SequenceEntry",
|
|
141
|
+
description: "One entry of a question set or an exam section: an activity, or an item group. Structural only: validateDraft and validateItemGroupDraft decide.",
|
|
142
|
+
oneOf: [...types.map(ref), ref("item-group")],
|
|
143
|
+
[definitions]: {
|
|
144
|
+
...Object.fromEntries(types.map((type) => [type, body(jsonSchemaFor(type, { target }))])),
|
|
145
|
+
stimulus: body(z.toJSONSchema(StimulusSchema, { target })),
|
|
146
|
+
"item-group": group
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// src/schemas/index.ts
|
|
95
151
|
/**
|
|
96
152
|
* Checks a piece of activity media — an item's `media`, a stimulus's, a
|
|
97
153
|
* dictation's `slowMedia` — on its own, the way `validateActivity` checks it
|
|
@@ -146,7 +202,6 @@ function validateActivity(type, data) {
|
|
|
146
202
|
if (descriptor === void 0) throw new UnknownActivityTypeError(String(type));
|
|
147
203
|
return asValidation(readSchema(descriptor.schema, data, `Activity type "${descriptor.type}"`));
|
|
148
204
|
}
|
|
149
|
-
|
|
150
|
-
export { fillInTheBlanksJsonSchema as a, jsonSchemaFor as c, stimulusJsonSchema as d, writtenResponseJsonSchema as f, dictationJsonSchema as i, multipleChoiceJsonSchema as l, validateMedia as n, gapSelectJsonSchema as o, validateOptionMedia as r, itemGroupJsonSchema as s, validateActivity as t, readAloudJsonSchema as u };
|
|
205
|
+
export { dictationJsonSchema as a, itemGroupJsonSchema as c, readAloudJsonSchema as d, stimulusJsonSchema as f, contentJsonSchema as i, jsonSchemaFor as l, validateMedia as n, fillInTheBlanksJsonSchema as o, writtenResponseJsonSchema as p, validateOptionMedia as r, gapSelectJsonSchema as s, validateActivity as t, multipleChoiceJsonSchema as u };
|
|
151
206
|
|
|
152
|
-
//# sourceMappingURL=schemas-
|
|
207
|
+
//# sourceMappingURL=schemas-C7TViWCg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas-C7TViWCg.js","names":[],"sources":["../src/schemas/json-schema.ts","../src/schemas/index.ts"],"sourcesContent":["import * as z from 'zod/v4';\nimport { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor, registeredActivityTypes } from '../registry/index.js';\nimport { DictationDataSchema } from './dictation.js';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { GapSelectDataSchema } from './gap-select.js';\nimport { ItemGroupSchema, StimulusSchema } from './item-group.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\nimport { ReadAloudDataSchema } from './read-aloud.js';\nimport { isOwnSchema, standardJsonSchemaOf } from './read-schema.js';\nimport { WrittenResponseDataSchema } from './written-response.js';\n\n/**\n * JSON Schema (Draft 7) for a `Stimulus`. Structural contract only — the\n * kind/media/body consistency guards are Zod-only.\n */\nexport const stimulusJsonSchema: Record<string, unknown> = z.toJSONSchema(StimulusSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) for an `ItemGroup` CONTAINER. Items appear as objects\n * with `type` and `id` only; each item's own contract is `jsonSchemaFor(type)`.\n * For an AI generation pipeline, ask for the group and each item separately\n * rather than a single nested schema — that keeps the per-type schema the\n * registry's, not a copy.\n */\nexport const itemGroupJsonSchema: Record<string, unknown> = z.toJSONSchema(ItemGroupSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Multiple Choice activity data\n * contract, generated natively by Zod 4. Draft 7 is mandated by Requirement\n * 2.2 for the widest AI-prompt / OpenAPI tooling compatibility. The semantic\n * `.refine()` guards are not representable in JSON Schema and are\n * intentionally omitted — the export captures the *structural* contract only.\n * Since v0.3 the source schemas are loose, so these no longer emit\n * `additionalProperties: false` — the JSON Schema and `validateActivity` now\n * agree on unknown-key handling.\n */\n/**\n * JSON Schema (Draft 7) representation of the Gap Select activity data\n * contract. Structural contract only: the six semantic guards — the\n * passage/gap bijection, id uniqueness, the one-choice-source rule, and an\n * answer key that names a choice the gap offers — are Zod-only, as they are\n * for the other types.\n */\nexport const gapSelectJsonSchema: Record<string, unknown> = z.toJSONSchema(GapSelectDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Dictation activity data\n * contract. Structural contract, plus the raw length caps JSON Schema can\n * state in code points as zod counts them — `maxLength` 2000 on a transcript\n * and an accepted transcript, 200 on a rule's `from` and `to`. The twelve\n * semantic guards — a transcript that survives normalisation, the caps after\n * equivalences are applied, distinct candidates, audio only, the\n * slow-recording rules, no captions, no transcript in the title — are\n * Zod-only, as they are for the other types.\n */\nexport const dictationJsonSchema: Record<string, unknown> = z.toJSONSchema(DictationDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Read Aloud activity data\n * contract. Structural contract, plus the raw cap JSON Schema can state in code\n * points as zod counts them — `maxLength` 2000 on the reference text — and the\n * canonical locale pattern. The ten semantic guards — the cap after\n * normalisation, a text that survives it, the spaced-script rule, the\n * model-recording rules, unique dimensions, a weight above 0, and the take\n * bounds — are Zod-only, as they are for the other types.\n */\nexport const readAloudJsonSchema: Record<string, unknown> = z.toJSONSchema(ReadAloudDataSchema, {\n target: 'draft-7',\n});\n\nexport const multipleChoiceJsonSchema: Record<string, unknown> = z.toJSONSchema(\n MultipleChoiceDataSchema,\n {\n target: 'draft-7',\n },\n);\n\n/**\n * JSON Schema (Draft 7) representation of the Fill-in-the-Blanks activity data\n * contract, generated natively by Zod 4. Structural contract only (semantic\n * `.refine()` guards are Zod-only and not representable in JSON Schema).\n */\nexport const fillInTheBlanksJsonSchema: Record<string, unknown> = z.toJSONSchema(\n FillInTheBlanksDataSchema,\n {\n target: 'draft-7',\n },\n);\n\n/**\n * JSON Schema (Draft 7) representation of the Written Response activity data\n * contract. Structural contract only.\n */\nexport const writtenResponseJsonSchema: Record<string, unknown> = z.toJSONSchema(\n WrittenResponseDataSchema,\n {\n target: 'draft-7',\n },\n);\n\n/** The JSON Schema drafts the SDK writes. */\nexport type JsonSchemaTarget = 'draft-2020-12' | 'draft-7';\n\n/** What the Standard JSON Schema converter calls each draft. */\nconst STANDARD_TARGET = { 'draft-7': 'draft-07', 'draft-2020-12': 'draft-2020-12' } as const;\n\n/**\n * Derives the JSON Schema for any REGISTERED activity type — the live,\n * registry-backed replacement for the static per-type exports above, and the\n * building block for AI generation pipelines (R6.1): pass the result as a\n * structured-output schema so a model can only emit valid items.\n *\n * Draft 7 unless `target` says `'draft-2020-12'`. For a type you registered,\n * it is the descriptor's `jsonSchema` when you gave one, in whatever draft you\n * wrote it, or else what the schema produces through the Standard JSON Schema\n * converter (`'~standard'.jsonSchema`) in the draft asked for — a zod 4.6\n * schema has one. A fresh copy every call.\n *\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n * @throws Error when a registered type has neither a `jsonSchema` nor a schema\n * that can produce one.\n */\nexport function jsonSchemaFor(\n type: string,\n options: { target?: JsonSchemaTarget } = {},\n): Record<string, unknown> {\n const target = options.target ?? 'draft-7';\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(type);\n }\n if (isOwnSchema(descriptor.schema)) {\n return z.toJSONSchema(descriptor.schema as never, { target }) as Record<string, unknown>;\n }\n if (descriptor.jsonSchema !== undefined) {\n return structuredClone(descriptor.jsonSchema) as Record<string, unknown>;\n }\n const generated = standardJsonSchemaOf(descriptor.schema, STANDARD_TARGET[target]);\n if (generated === undefined) {\n throw new Error(\n `Activity type \"${descriptor.type}\" has no JSON Schema: its schema implements no Standard JSON Schema converter ('~standard'.jsonSchema). Give its descriptor a \\`jsonSchema\\`.`,\n );\n }\n return generated;\n}\n\n/** A schema without its `$schema`, to sit inside another document. */\nfunction body(schema: Record<string, unknown>): Record<string, unknown> {\n const { $schema: _draft, ...rest } = schema;\n return rest;\n}\n\n/**\n * One JSON Schema document for content an outside tool writes: the root is a\n * `SequenceEntry` — an activity of any registered type, or an item group whose\n * items are typed too. Each type, the stimulus and the item group sit under\n * `$defs` (`definitions` in draft 7), so a tool can also point at one of them.\n * Draft 2020-12 unless `target` says `'draft-7'`.\n *\n * Structural, as every exported schema is: rules that span fields (one key in\n * a single-answer question, a blank for each marker, a slow recording that is\n * another file) cannot be written in JSON Schema. On import, `validateDraft`\n * and `validateItemGroupDraft` decide. It includes the author-only fields\n * (`transcript`, `script`), so a tool can write them.\n *\n * ```ts\n * writeFileSync('schema.json', JSON.stringify(contentJsonSchema(), null, 2));\n * ```\n */\nexport function contentJsonSchema(\n options: { target?: JsonSchemaTarget } = {},\n): Record<string, unknown> {\n const target = options.target ?? 'draft-2020-12';\n const definitions = target === 'draft-7' ? 'definitions' : '$defs';\n const ref = (name: string) => ({ $ref: `#/${definitions}/${name}` });\n const types = registeredActivityTypes();\n const anyActivity = { oneOf: types.map(ref) };\n\n const group = body(z.toJSONSchema(ItemGroupSchema, { target }) as Record<string, unknown>);\n const properties = group.properties as Record<string, Record<string, unknown>>;\n group.properties = {\n ...properties,\n stimulus: ref('stimulus'),\n // The container's own rule for an item (a `type`, an `id`, a `slotKey`),\n // and the item's type's whole contract.\n items: { ...properties.items, items: { allOf: [properties.items?.items, anyActivity] } },\n };\n\n return {\n $schema:\n target === 'draft-7'\n ? 'http://json-schema.org/draft-07/schema#'\n : 'https://json-schema.org/draft/2020-12/schema',\n title: 'SequenceEntry',\n description:\n 'One entry of a question set or an exam section: an activity, or an item group. Structural only: validateDraft and validateItemGroupDraft decide.',\n oneOf: [...types.map(ref), ref('item-group')],\n [definitions]: {\n ...Object.fromEntries(types.map((type) => [type, body(jsonSchemaFor(type, { target }))])),\n stimulus: body(z.toJSONSchema(StimulusSchema, { target }) as Record<string, unknown>),\n 'item-group': group,\n },\n };\n}\n","import { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport type {\n ActivityDataMap,\n ActivityMedia,\n ActivityType,\n MultipleChoiceOptionMedia,\n ValidationResult,\n} from '../types/activity.js';\nimport { MediaSchema } from './media.js';\nimport { MultipleChoiceOptionMediaSchema } from './multiple-choice.js';\nimport { readSchema, type SchemaReading } from './read-schema.js';\n\nexport type {\n RedactedActivity,\n RedactedBlankConfig,\n RedactedDictationData,\n RedactedDictationSlowMedia,\n RedactedFillInTheBlanksData,\n RedactedGapSelectBank,\n RedactedGapSelectChoice,\n RedactedGapSelectData,\n RedactedGapSelectGap,\n RedactedMultipleChoiceData,\n RedactedMultipleChoiceOption,\n RedactedMultipleChoiceOptionMedia,\n RedactedReadAloudData,\n RedactedStimulus,\n RedactedWrittenResponseData,\n} from '../types/redacted.js';\nexport { validateItemGroup } from './item-group.js';\nexport {\n contentJsonSchema,\n dictationJsonSchema,\n fillInTheBlanksJsonSchema,\n gapSelectJsonSchema,\n itemGroupJsonSchema,\n type JsonSchemaTarget,\n jsonSchemaFor,\n multipleChoiceJsonSchema,\n readAloudJsonSchema,\n stimulusJsonSchema,\n writtenResponseJsonSchema,\n} from './json-schema.js';\nexport { SCRIPT_MAX_TURNS } from './media.js';\n\n/**\n * Checks a piece of activity media — an item's `media`, a stimulus's, a\n * dictation's `slowMedia` — on its own, the way `validateActivity` checks it\n * inside an item: its kind, an address in the allowed schemes, a playback\n * policy only on audio, captions and tracks only where they can play. For an\n * editor's media picker, which holds the media before the item is whole.\n *\n * @returns `{ success: true, data }`, or `{ success: false, errors }` with the\n * same codes, paths and messages `validateActivity` reports.\n */\nexport function validateMedia(value: unknown): ValidationResult<ActivityMedia> {\n return asValidation(readSchema(MediaSchema as never, value, 'Media'));\n}\n\n/**\n * Checks a multiple-choice option's `media` on its own: a picture or a\n * recording, at an address in the allowed schemes, with no playback policy.\n *\n * @returns `{ success: true, data }`, or `{ success: false, errors }` with the\n * same codes, paths and messages `validateActivity` reports.\n */\nexport function validateOptionMedia(value: unknown): ValidationResult<MultipleChoiceOptionMedia> {\n return asValidation(readSchema(MultipleChoiceOptionMediaSchema as never, value, 'Option media'));\n}\n\nfunction asValidation<T>(reading: SchemaReading<unknown>): ValidationResult<T> {\n if (reading.success) {\n return { success: true, data: reading.data as T };\n }\n return {\n success: false,\n errors: reading.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n };\n}\n\n/**\n * Validates raw activity data against the schema registered for the given\n * activity type (built-in or consumer-registered via `registerActivityType`).\n *\n * Unknown keys are PRESERVED, not stripped: every built-in schema is loose,\n * so consumer sidecar fields and forward-version fields survive validation\n * verbatim in the returned `data`.\n *\n * @returns `{ success: true, data }` with the typed, validated data, or\n * `{ success: false, errors }` with one entry per failed constraint.\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function validateActivity<T extends ActivityType>(\n type: T,\n data: unknown,\n): ValidationResult<ActivityDataMap[T]> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(String(type));\n }\n\n return asValidation(readSchema(descriptor.schema, data, `Activity type \"${descriptor.type}\"`));\n}\n"],"mappings":"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"}
|
package/dist/schemas.cjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
const
|
|
2
|
+
const require_registry = require("./registry-hzrkTeIT.cjs");
|
|
3
|
+
const require_item_group = require("./item-group-8P3WFuUK.cjs");
|
|
4
|
+
const require_schemas = require("./schemas-BWeskONy.cjs");
|
|
5
|
+
exports.SCRIPT_MAX_TURNS = require_registry.SCRIPT_MAX_TURNS;
|
|
6
|
+
exports.contentJsonSchema = require_schemas.contentJsonSchema;
|
|
4
7
|
exports.dictationJsonSchema = require_schemas.dictationJsonSchema;
|
|
5
8
|
exports.fillInTheBlanksJsonSchema = require_schemas.fillInTheBlanksJsonSchema;
|
|
6
9
|
exports.gapSelectJsonSchema = require_schemas.gapSelectJsonSchema;
|
package/dist/schemas.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
export { type RedactedActivity, type RedactedBlankConfig, type RedactedDictationData, type RedactedDictationSlowMedia, type RedactedFillInTheBlanksData, type RedactedGapSelectBank, type RedactedGapSelectChoice, type RedactedGapSelectData, type RedactedGapSelectGap, type RedactedMultipleChoiceData, type RedactedMultipleChoiceOption, type RedactedMultipleChoiceOptionMedia, type RedactedReadAloudData, type RedactedStimulus, type RedactedWrittenResponseData, dictationJsonSchema, fillInTheBlanksJsonSchema, gapSelectJsonSchema, itemGroupJsonSchema, jsonSchemaFor, multipleChoiceJsonSchema, readAloudJsonSchema, stimulusJsonSchema, validateActivity, validateItemGroup, validateMedia, validateOptionMedia, writtenResponseJsonSchema };
|
|
1
|
+
import { A as RedactedStimulus, C as RedactedGapSelectChoice, D as RedactedMultipleChoiceOption, E as RedactedMultipleChoiceData, O as RedactedMultipleChoiceOptionMedia, S as RedactedGapSelectBank, T as RedactedGapSelectGap, _ as RedactedActivity, a as JsonSchemaTarget, b as RedactedDictationSlowMedia, c as fillInTheBlanksJsonSchema, d as jsonSchemaFor, f as multipleChoiceJsonSchema, g as validateItemGroup, h as writtenResponseJsonSchema, i as SCRIPT_MAX_TURNS, j as RedactedWrittenResponseData, k as RedactedReadAloudData, l as gapSelectJsonSchema, m as stimulusJsonSchema, n as validateMedia, o as contentJsonSchema, p as readAloudJsonSchema, r as validateOptionMedia, s as dictationJsonSchema, t as validateActivity, u as itemGroupJsonSchema, v as RedactedBlankConfig, w as RedactedGapSelectData, x as RedactedFillInTheBlanksData, y as RedactedDictationData } from "./index-DP9rvyOz.cjs";
|
|
2
|
+
export { type JsonSchemaTarget, type RedactedActivity, type RedactedBlankConfig, type RedactedDictationData, type RedactedDictationSlowMedia, type RedactedFillInTheBlanksData, type RedactedGapSelectBank, type RedactedGapSelectChoice, type RedactedGapSelectData, type RedactedGapSelectGap, type RedactedMultipleChoiceData, type RedactedMultipleChoiceOption, type RedactedMultipleChoiceOptionMedia, type RedactedReadAloudData, type RedactedStimulus, type RedactedWrittenResponseData, SCRIPT_MAX_TURNS, contentJsonSchema, dictationJsonSchema, fillInTheBlanksJsonSchema, gapSelectJsonSchema, itemGroupJsonSchema, jsonSchemaFor, multipleChoiceJsonSchema, readAloudJsonSchema, stimulusJsonSchema, validateActivity, validateItemGroup, validateMedia, validateOptionMedia, writtenResponseJsonSchema };
|
package/dist/schemas.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
export { type RedactedActivity, type RedactedBlankConfig, type RedactedDictationData, type RedactedDictationSlowMedia, type RedactedFillInTheBlanksData, type RedactedGapSelectBank, type RedactedGapSelectChoice, type RedactedGapSelectData, type RedactedGapSelectGap, type RedactedMultipleChoiceData, type RedactedMultipleChoiceOption, type RedactedMultipleChoiceOptionMedia, type RedactedReadAloudData, type RedactedStimulus, type RedactedWrittenResponseData, dictationJsonSchema, fillInTheBlanksJsonSchema, gapSelectJsonSchema, itemGroupJsonSchema, jsonSchemaFor, multipleChoiceJsonSchema, readAloudJsonSchema, stimulusJsonSchema, validateActivity, validateItemGroup, validateMedia, validateOptionMedia, writtenResponseJsonSchema };
|
|
1
|
+
import { A as RedactedStimulus, C as RedactedGapSelectChoice, D as RedactedMultipleChoiceOption, E as RedactedMultipleChoiceData, O as RedactedMultipleChoiceOptionMedia, S as RedactedGapSelectBank, T as RedactedGapSelectGap, _ as RedactedActivity, a as JsonSchemaTarget, b as RedactedDictationSlowMedia, c as fillInTheBlanksJsonSchema, d as jsonSchemaFor, f as multipleChoiceJsonSchema, g as validateItemGroup, h as writtenResponseJsonSchema, i as SCRIPT_MAX_TURNS, j as RedactedWrittenResponseData, k as RedactedReadAloudData, l as gapSelectJsonSchema, m as stimulusJsonSchema, n as validateMedia, o as contentJsonSchema, p as readAloudJsonSchema, r as validateOptionMedia, s as dictationJsonSchema, t as validateActivity, u as itemGroupJsonSchema, v as RedactedBlankConfig, w as RedactedGapSelectData, x as RedactedFillInTheBlanksData, y as RedactedDictationData } from "./index-BdXs4-en.js";
|
|
2
|
+
export { type JsonSchemaTarget, type RedactedActivity, type RedactedBlankConfig, type RedactedDictationData, type RedactedDictationSlowMedia, type RedactedFillInTheBlanksData, type RedactedGapSelectBank, type RedactedGapSelectChoice, type RedactedGapSelectData, type RedactedGapSelectGap, type RedactedMultipleChoiceData, type RedactedMultipleChoiceOption, type RedactedMultipleChoiceOptionMedia, type RedactedReadAloudData, type RedactedStimulus, type RedactedWrittenResponseData, SCRIPT_MAX_TURNS, contentJsonSchema, dictationJsonSchema, fillInTheBlanksJsonSchema, gapSelectJsonSchema, itemGroupJsonSchema, jsonSchemaFor, multipleChoiceJsonSchema, readAloudJsonSchema, stimulusJsonSchema, validateActivity, validateItemGroup, validateMedia, validateOptionMedia, writtenResponseJsonSchema };
|
package/dist/schemas.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { Tt as SCRIPT_MAX_TURNS } from "./registry-D92hz9iA.js";
|
|
2
|
+
import { i as validateItemGroup } from "./item-group-CeDk7mfM.js";
|
|
3
|
+
import { a as dictationJsonSchema, c as itemGroupJsonSchema, d as readAloudJsonSchema, f as stimulusJsonSchema, i as contentJsonSchema, l as jsonSchemaFor, n as validateMedia, o as fillInTheBlanksJsonSchema, p as writtenResponseJsonSchema, r as validateOptionMedia, s as gapSelectJsonSchema, t as validateActivity, u as multipleChoiceJsonSchema } from "./schemas-C7TViWCg.js";
|
|
4
|
+
export { SCRIPT_MAX_TURNS, contentJsonSchema, dictationJsonSchema, fillInTheBlanksJsonSchema, gapSelectJsonSchema, itemGroupJsonSchema, jsonSchemaFor, multipleChoiceJsonSchema, readAloudJsonSchema, stimulusJsonSchema, validateActivity, validateItemGroup, validateMedia, validateOptionMedia, writtenResponseJsonSchema };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const require_registry = require("./registry-
|
|
1
|
+
const require_registry = require("./registry-hzrkTeIT.cjs");
|
|
2
2
|
let zod_v4 = require("zod/v4");
|
|
3
3
|
zod_v4 = require_registry.__toESM(zod_v4, 1);
|
|
4
|
-
|
|
4
|
+
// src/scoring/grade-numbers.ts
|
|
5
5
|
/**
|
|
6
6
|
* How far past its own maximum a score may sit and still be a grade. A grader
|
|
7
7
|
* that sums weighted parts lands on `1.0000000000000002` for a perfect answer
|
|
@@ -24,8 +24,7 @@ const OVERSHOOT = 1e-9;
|
|
|
24
24
|
function isGradeInRange(score, maxScore) {
|
|
25
25
|
return Number.isFinite(maxScore) && maxScore > 0 && Number.isFinite(score) && score >= 0 && score - maxScore <= maxScore * OVERSHOOT;
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
//#region src/is-redacted.ts
|
|
27
|
+
// src/is-redacted.ts
|
|
29
28
|
/**
|
|
30
29
|
* True when `data` is a `redact()` projection rather than full activity data.
|
|
31
30
|
* Grading a redacted item is always a bug: the answer key is gone by design, so
|
|
@@ -42,8 +41,7 @@ function isGradeInRange(score, maxScore) {
|
|
|
42
41
|
function isRedacted(data) {
|
|
43
42
|
return typeof data === "object" && data !== null && data.redacted === true;
|
|
44
43
|
}
|
|
45
|
-
|
|
46
|
-
//#region src/scoring/item-scoring.ts
|
|
44
|
+
// src/scoring/item-scoring.ts
|
|
47
45
|
/**
|
|
48
46
|
* The policy that changes nothing: one try, nothing costs anything, the first
|
|
49
47
|
* try counts. What an absent policy resolves to, and exactly how questions were
|
|
@@ -214,8 +212,7 @@ function scoreTries(tries, policy) {
|
|
|
214
212
|
tries: scored
|
|
215
213
|
};
|
|
216
214
|
}
|
|
217
|
-
|
|
218
|
-
//#region src/scoring/rounding.ts
|
|
215
|
+
// src/scoring/rounding.ts
|
|
219
216
|
const ROUNDING_MODES = [
|
|
220
217
|
"half-up",
|
|
221
218
|
"half-even",
|
|
@@ -327,8 +324,7 @@ function classifyBand(value, bands) {
|
|
|
327
324
|
for (const band of bands) if (value >= band.min - EPSILON && (best === null || band.min > best.min)) best = band;
|
|
328
325
|
return best;
|
|
329
326
|
}
|
|
330
|
-
|
|
331
|
-
//#region src/scoring/pass-threshold.ts
|
|
327
|
+
// src/scoring/pass-threshold.ts
|
|
332
328
|
/** Default minimum scaled score required to pass when `passThreshold` is absent. */
|
|
333
329
|
const DEFAULT_PASS_THRESHOLD = .7;
|
|
334
330
|
/**
|
|
@@ -358,8 +354,7 @@ function selectFeedback(activityData, passed) {
|
|
|
358
354
|
if (feedback === void 0) return null;
|
|
359
355
|
return (passed ? feedback.correct : feedback.incorrect) ?? null;
|
|
360
356
|
}
|
|
361
|
-
|
|
362
|
-
//#region src/content-hash.ts
|
|
357
|
+
// src/content-hash.ts
|
|
363
358
|
/**
|
|
364
359
|
* Content fingerprinting — "is this the same content the learner was served?"
|
|
365
360
|
*
|
|
@@ -430,8 +425,7 @@ function fingerprint(input) {
|
|
|
430
425
|
function contentHash(value) {
|
|
431
426
|
return fingerprint(canonicalJson(value));
|
|
432
427
|
}
|
|
433
|
-
|
|
434
|
-
//#region src/scoring/assisted/calibration.ts
|
|
428
|
+
// src/scoring/assisted/calibration.ts
|
|
435
429
|
const mean = (values) => values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
436
430
|
/** Population variance. */
|
|
437
431
|
function variance(values) {
|
|
@@ -758,8 +752,7 @@ function calibrationReport(pairs, scope) {
|
|
|
758
752
|
}
|
|
759
753
|
};
|
|
760
754
|
}
|
|
761
|
-
|
|
762
|
-
//#region src/grading.ts
|
|
755
|
+
// src/grading.ts
|
|
763
756
|
/**
|
|
764
757
|
* Computes the weighted total from per-criterion scores — the arithmetic that
|
|
765
758
|
* must NOT be delegated to a language model.
|
|
@@ -885,8 +878,7 @@ function outcomeFromGrade(grade) {
|
|
|
885
878
|
function hasGrade(outcome) {
|
|
886
879
|
return outcome.status === "scored" || outcome.status === "graded";
|
|
887
880
|
}
|
|
888
|
-
|
|
889
|
-
//#region src/scoring/assisted/grade-from-judgement.ts
|
|
881
|
+
// src/scoring/assisted/grade-from-judgement.ts
|
|
890
882
|
/**
|
|
891
883
|
* The grade a checked model judgement gives a written response: the total
|
|
892
884
|
* computed as `gradeFromRubric` computes every grade — never by the model — with
|
|
@@ -952,8 +944,7 @@ function gradeFromJudgement(judgement, data, options = {}) {
|
|
|
952
944
|
...provenance?.generatedAt !== void 0 ? { gradedAt: provenance.generatedAt } : {}
|
|
953
945
|
};
|
|
954
946
|
}
|
|
955
|
-
|
|
956
|
-
//#region src/shuffle.ts
|
|
947
|
+
// src/shuffle.ts
|
|
957
948
|
/**
|
|
958
949
|
* Seeded, deterministic shuffling — the ONE algorithm every presentation-order
|
|
959
950
|
* decision in the SDK goes through: option order in a multiple-choice item,
|
|
@@ -990,8 +981,7 @@ function shuffleWithSeed(items, seed, version) {
|
|
|
990
981
|
function seededShuffle(items, seed, options = {}) {
|
|
991
982
|
return shuffleWithSeed(items, hashSeed(seed), options.version ?? 1);
|
|
992
983
|
}
|
|
993
|
-
|
|
994
|
-
//#region src/scoring/assisted/routing.ts
|
|
984
|
+
// src/scoring/assisted/routing.ts
|
|
995
985
|
/** A threshold the caller configured: a finite number, and a rate within 0 to 1 where it is one. */
|
|
996
986
|
function checkThreshold(name, value, rate) {
|
|
997
987
|
if (value === void 0) return;
|
|
@@ -1139,8 +1129,7 @@ function outcomeFromRoutedGrade(grade, routing) {
|
|
|
1139
1129
|
pendingGrade: routed
|
|
1140
1130
|
};
|
|
1141
1131
|
}
|
|
1142
|
-
|
|
1143
|
-
//#region src/scoring/compose.ts
|
|
1132
|
+
// src/scoring/compose.ts
|
|
1144
1133
|
function earned(item) {
|
|
1145
1134
|
const { outcome } = item;
|
|
1146
1135
|
if (hasGrade(outcome)) {
|
|
@@ -1271,8 +1260,7 @@ function composeAssessmentScore(sections, policy) {
|
|
|
1271
1260
|
unscorableSlotIds: unscorableAll
|
|
1272
1261
|
};
|
|
1273
1262
|
}
|
|
1274
|
-
|
|
1275
|
-
//#region src/scoring/dictation/chars.ts
|
|
1263
|
+
// src/scoring/dictation/chars.ts
|
|
1276
1264
|
/**
|
|
1277
1265
|
* The code-point edit operations between two NORMALISED strings — the
|
|
1278
1266
|
* `reference` and `attempt` of a `DictationAlignment`, or one word pair from
|
|
@@ -1307,8 +1295,7 @@ function diffDictationChars(reference, attempt) {
|
|
|
1307
1295
|
};
|
|
1308
1296
|
});
|
|
1309
1297
|
}
|
|
1310
|
-
|
|
1311
|
-
//#region src/scoring/speech/tokens.ts
|
|
1298
|
+
// src/scoring/speech/tokens.ts
|
|
1312
1299
|
/**
|
|
1313
1300
|
* The normalised tokens of the words that can be marked, each remembering the
|
|
1314
1301
|
* word it came from, up to what {@link SPEECH_ASSESSMENT_MAX_TEXT_LENGTH} code
|
|
@@ -1349,8 +1336,7 @@ function heardTokens(words) {
|
|
|
1349
1336
|
length
|
|
1350
1337
|
};
|
|
1351
1338
|
}
|
|
1352
|
-
|
|
1353
|
-
//#region src/scoring/speech/assessment.ts
|
|
1339
|
+
// src/scoring/speech/assessment.ts
|
|
1354
1340
|
/** A score on the assessment's 0..100 scale. `z.number()` refuses NaN and both infinities. */
|
|
1355
1341
|
const Score = zod_v4.number().min(0).max(100);
|
|
1356
1342
|
/** A confidence, 0..1. */
|
|
@@ -1572,8 +1558,7 @@ function validateSpeechAssessment(value) {
|
|
|
1572
1558
|
errors
|
|
1573
1559
|
};
|
|
1574
1560
|
}
|
|
1575
|
-
|
|
1576
|
-
//#region src/scoring/speech/align.ts
|
|
1561
|
+
// src/scoring/speech/align.ts
|
|
1577
1562
|
/**
|
|
1578
1563
|
* The word's accuracy when it has one. Absent means the assessor did not
|
|
1579
1564
|
* measure the word, which is never the same as measuring it at 0.
|
|
@@ -1712,8 +1697,7 @@ function placeInsertions(assessment, entries) {
|
|
|
1712
1697
|
});
|
|
1713
1698
|
});
|
|
1714
1699
|
}
|
|
1715
|
-
|
|
1716
|
-
//#region src/scoring/speech/grade.ts
|
|
1700
|
+
// src/scoring/speech/grade.ts
|
|
1717
1701
|
/**
|
|
1718
1702
|
* The read-aloud grade: the arithmetic over a pronunciation assessment's
|
|
1719
1703
|
* dimension scores, and the checks that decide whether that evidence may be
|
|
@@ -1904,8 +1888,7 @@ function gradeReadAloud(data, response, assessment, options) {
|
|
|
1904
1888
|
function referenceWordsOf(data) {
|
|
1905
1889
|
return require_registry.dictationReferenceWords({ transcript: data.referenceText })[0];
|
|
1906
1890
|
}
|
|
1907
|
-
|
|
1908
|
-
//#region src/scoring/speech/wav.ts
|
|
1891
|
+
// src/scoring/speech/wav.ts
|
|
1909
1892
|
/** `RIFF` + the file size + `WAVE`, before the first chunk. */
|
|
1910
1893
|
const HEADER_BYTES = 12;
|
|
1911
1894
|
/** A chunk's four-character id and its little-endian size. */
|
|
@@ -2053,8 +2036,7 @@ function inspectWav(bytes, policy) {
|
|
|
2053
2036
|
voicedMs: Math.min(voicedMs, durationMs)
|
|
2054
2037
|
};
|
|
2055
2038
|
}
|
|
2056
|
-
|
|
2057
|
-
//#region src/scoring/unscorable.ts
|
|
2039
|
+
// src/scoring/unscorable.ts
|
|
2058
2040
|
/**
|
|
2059
2041
|
* Lifts a result that cannot be graded — a `SpeechUnscorable` from
|
|
2060
2042
|
* `gradeReadAloud`, or anything else carrying a `code` and a `reason` — into
|
|
@@ -2072,8 +2054,7 @@ function outcomeFromUnscorable(result) {
|
|
|
2072
2054
|
code: result.code
|
|
2073
2055
|
};
|
|
2074
2056
|
}
|
|
2075
|
-
|
|
2076
|
-
//#region src/scoring/index.ts
|
|
2057
|
+
// src/scoring/index.ts
|
|
2077
2058
|
/**
|
|
2078
2059
|
* Scores a learner response against activity data and returns a full
|
|
2079
2060
|
* {@link ScoringResult}.
|
|
@@ -2253,7 +2234,6 @@ function costed(data, opening, graded, rules, rounding) {
|
|
|
2253
2234
|
tries: result.tries
|
|
2254
2235
|
};
|
|
2255
2236
|
}
|
|
2256
|
-
//#endregion
|
|
2257
2237
|
Object.defineProperty(exports, "DEFAULT_ITEM_SCORING_POLICY", {
|
|
2258
2238
|
enumerable: true,
|
|
2259
2239
|
get: function() {
|
|
@@ -2465,4 +2445,4 @@ Object.defineProperty(exports, "validateSpeechAssessment", {
|
|
|
2465
2445
|
}
|
|
2466
2446
|
});
|
|
2467
2447
|
|
|
2468
|
-
//# sourceMappingURL=scoring-
|
|
2448
|
+
//# sourceMappingURL=scoring-CtkCFyFT.cjs.map
|