@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,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -19,11 +19,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
19
19
|
value: mod,
|
|
20
20
|
enumerable: true
|
|
21
21
|
}) : target, mod));
|
|
22
|
-
//#endregion
|
|
23
22
|
let zod_v4 = require("zod/v4");
|
|
24
23
|
zod_v4 = __toESM(zod_v4, 1);
|
|
25
24
|
let zod_v4_core = require("zod/v4/core");
|
|
26
|
-
|
|
25
|
+
// src/schemas/ai.ts
|
|
27
26
|
/**
|
|
28
27
|
* What an author allows AI to do for one item: see `ActivityAiPermissions`.
|
|
29
28
|
* Loose like every content schema, so a key a later release adds survives an
|
|
@@ -33,8 +32,7 @@ const AiPermissionsSchema = zod_v4.looseObject({
|
|
|
33
32
|
explanations: zod_v4.boolean().optional(),
|
|
34
33
|
hints: zod_v4.boolean().optional()
|
|
35
34
|
});
|
|
36
|
-
|
|
37
|
-
//#region src/schemas/feedback.ts
|
|
35
|
+
// src/schemas/feedback.ts
|
|
38
36
|
/**
|
|
39
37
|
* Optional authored "overall feedback" shown after submission, selected by
|
|
40
38
|
* whether the learner passed (h5p-style overall feedback). Both fields are
|
|
@@ -44,8 +42,7 @@ const FeedbackSchema = zod_v4.looseObject({
|
|
|
44
42
|
correct: zod_v4.string().min(1).optional(),
|
|
45
43
|
incorrect: zod_v4.string().min(1).optional()
|
|
46
44
|
});
|
|
47
|
-
|
|
48
|
-
//#region src/schemas/text-length.ts
|
|
45
|
+
// src/schemas/text-length.ts
|
|
49
46
|
/**
|
|
50
47
|
* `schema`, refusing a string longer than `max` UTF-16 code units — its
|
|
51
48
|
* JavaScript `length`, the unit these limits have always counted in.
|
|
@@ -68,8 +65,7 @@ function maxUnits(schema, max) {
|
|
|
68
65
|
});
|
|
69
66
|
}).meta({ maxLength: max });
|
|
70
67
|
}
|
|
71
|
-
|
|
72
|
-
//#region src/schemas/media.ts
|
|
68
|
+
// src/schemas/media.ts
|
|
73
69
|
/**
|
|
74
70
|
* Optional media attached to an activity, rendered above the question or
|
|
75
71
|
* passage — e.g. a recording to listen to, or an embedded video to watch
|
|
@@ -157,6 +153,20 @@ const MediaTrackSchema = zod_v4.strictObject({
|
|
|
157
153
|
default: zod_v4.boolean().optional()
|
|
158
154
|
});
|
|
159
155
|
const MAX_TRACKS = 12;
|
|
156
|
+
/** The most turns a recording's `script` may hold. */
|
|
157
|
+
const SCRIPT_MAX_TURNS = 500;
|
|
158
|
+
/**
|
|
159
|
+
* One speaker's turn in an author-only `script`. Loose, as content is: a host
|
|
160
|
+
* may keep its own fields on a turn (the voice it cast, a direction for it).
|
|
161
|
+
* Unlike a track's, both fields are required, so a misspelt one is still
|
|
162
|
+
* caught.
|
|
163
|
+
*/
|
|
164
|
+
const ScriptTurnSchema = zod_v4.looseObject({
|
|
165
|
+
speaker: maxUnits(zod_v4.string(), 60).refine((speaker) => speaker.trim().length > 0, { error: "A script turn needs a speaker." }),
|
|
166
|
+
text: zod_v4.string().refine((text) => text.trim().length > 0, { error: "A script turn needs words." })
|
|
167
|
+
});
|
|
168
|
+
/** An author-only `script`: one turn or more, in the order they are spoken. */
|
|
169
|
+
const ScriptSchema = zod_v4.array(ScriptTurnSchema).min(1).max(500);
|
|
160
170
|
/** `poster` on anything but a video: an image with nothing to stand in for. */
|
|
161
171
|
function posterFits(m) {
|
|
162
172
|
return m.poster === void 0 || m.type === "video";
|
|
@@ -199,7 +209,9 @@ const MediaSchema = zod_v4.looseObject({
|
|
|
199
209
|
captionsUrl: MediaUrlSchema.optional(),
|
|
200
210
|
tracks: zod_v4.array(MediaTrackSchema).min(1).max(MAX_TRACKS).optional(),
|
|
201
211
|
poster: MediaUrlSchema.optional(),
|
|
202
|
-
playback: MediaPlaybackSchema.optional()
|
|
212
|
+
playback: MediaPlaybackSchema.optional(),
|
|
213
|
+
transcript: zod_v4.string().optional(),
|
|
214
|
+
script: ScriptSchema.optional()
|
|
203
215
|
}).refine((m) => m.type !== "image" && m.type !== "embed" || typeof m.alt === "string" && m.alt.length > 0, {
|
|
204
216
|
error: "image and embed media require non-empty alt text (WCAG 1.1.1 / 4.1.2).",
|
|
205
217
|
path: ["alt"]
|
|
@@ -251,8 +263,7 @@ const RedactedMediaSchema = zod_v4.strictObject({
|
|
|
251
263
|
error: "embed media requires an absolute http(s) provider URL. data:, blob:, and relative URLs are not allowed for embeds — the embed iframe runs with allow-scripts, and a data:/same-origin document there is an XSS vector.",
|
|
252
264
|
path: ["url"]
|
|
253
265
|
}).refine(posterFits, POSTER_FITS).refine(tracksFit, TRACKS_FIT).refine(tracksAreDistinct, TRACKS_DISTINCT);
|
|
254
|
-
|
|
255
|
-
//#region src/schemas/fill-in-the-blanks.ts
|
|
266
|
+
// src/schemas/fill-in-the-blanks.ts
|
|
256
267
|
/**
|
|
257
268
|
* Matches `{{ blank_id }}` placeholders in a passage, capturing the trimmed id.
|
|
258
269
|
* Exported for the draft checks in `authoring/`, which must read a passage
|
|
@@ -260,6 +271,12 @@ const RedactedMediaSchema = zod_v4.strictObject({
|
|
|
260
271
|
*/
|
|
261
272
|
const PLACEHOLDER_RE = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
262
273
|
/**
|
|
274
|
+
* The instructions of an item with a passage: plain text, with no `{{id}}`
|
|
275
|
+
* placeholder. Blanks and gaps live in the passage only, and one written here
|
|
276
|
+
* would be shown to the learner as it stands. Shared by Gap Select.
|
|
277
|
+
*/
|
|
278
|
+
const PassageInstructionsSchema = zod_v4.string().refine((text) => text.match(PLACEHOLDER_RE) === null, { error: "The instructions are plain text: a {{id}} placeholder belongs in the passage, where its blank or gap is." });
|
|
279
|
+
/**
|
|
263
280
|
* Zod schema for a `TextMatchPolicy` — the opt-in matching tolerances a blank
|
|
264
281
|
* may declare. Every default reproduces the v1 trim + case-fold semantics.
|
|
265
282
|
*/
|
|
@@ -307,6 +324,7 @@ const FillInTheBlanksDataSchema = zod_v4.looseObject({
|
|
|
307
324
|
type: zod_v4.literal("fill-in-the-blanks"),
|
|
308
325
|
id: zod_v4.string().min(1),
|
|
309
326
|
title: zod_v4.string().min(1),
|
|
327
|
+
instructions: PassageInstructionsSchema.optional(),
|
|
310
328
|
passage: zod_v4.string().min(1),
|
|
311
329
|
passageHtml: zod_v4.string().optional(),
|
|
312
330
|
blanks: zod_v4.array(BlankConfigSchema).min(1),
|
|
@@ -338,8 +356,7 @@ const FillInTheBlanksDataSchema = zod_v4.looseObject({
|
|
|
338
356
|
error: "Each blank id must appear exactly once in blanks[] and have exactly one matching {{id}} placeholder in the passage, and vice versa.",
|
|
339
357
|
path: ["passage"]
|
|
340
358
|
});
|
|
341
|
-
|
|
342
|
-
//#region src/answer-leak.ts
|
|
359
|
+
// src/answer-leak.ts
|
|
343
360
|
/**
|
|
344
361
|
* Whether a text gives an answer away: the rule an AI hint is held to, and the
|
|
345
362
|
* one the item critic holds an author's own hint, title and passage to.
|
|
@@ -426,8 +443,7 @@ function revealsAnswer(text, answer, passage, position) {
|
|
|
426
443
|
if (before === void 0 && after === void 0) return containsWords(words, needle);
|
|
427
444
|
return before !== void 0 && containsWords(words, [before, ...needle]) || after !== void 0 && containsWords(words, [...needle, after]);
|
|
428
445
|
}
|
|
429
|
-
|
|
430
|
-
//#region src/built-in-types.ts
|
|
446
|
+
// src/built-in-types.ts
|
|
431
447
|
/**
|
|
432
448
|
* The activity types the SDK ships, in one closed list.
|
|
433
449
|
*
|
|
@@ -463,8 +479,7 @@ function isBuiltInActivityType(type) {
|
|
|
463
479
|
* @internal
|
|
464
480
|
*/
|
|
465
481
|
function everyBuiltInTypeHandled(_value) {}
|
|
466
|
-
|
|
467
|
-
//#region src/scoring/dictation/edit-distance.ts
|
|
482
|
+
// src/scoring/dictation/edit-distance.ts
|
|
468
483
|
/**
|
|
469
484
|
* The code points of `text`, as numbers. A surrogate pair is one code point; a
|
|
470
485
|
* lone surrogate iterates as one code point too — deterministic, never thrown.
|
|
@@ -516,8 +531,7 @@ function similarity(a, b) {
|
|
|
516
531
|
const max = Math.max(codePoints(a).length, codePoints(b).length);
|
|
517
532
|
return max === 0 ? 0 : (max - editDistance(a, b)) / max;
|
|
518
533
|
}
|
|
519
|
-
|
|
520
|
-
//#region src/validation-scope.ts
|
|
534
|
+
// src/validation-scope.ts
|
|
521
535
|
/**
|
|
522
536
|
* Work shared for the length of one outermost validation call.
|
|
523
537
|
*
|
|
@@ -556,8 +570,7 @@ function scopeCache(key, create) {
|
|
|
556
570
|
}
|
|
557
571
|
return value;
|
|
558
572
|
}
|
|
559
|
-
|
|
560
|
-
//#region src/scoring/dictation/unicode-joining.ts
|
|
573
|
+
// src/scoring/dictation/unicode-joining.ts
|
|
561
574
|
/**
|
|
562
575
|
* Unicode data the dictation normaliser reads when it decides whether a joiner
|
|
563
576
|
* changes how the text is drawn (see `normalize.ts`): the viramas, and which
|
|
@@ -775,8 +788,7 @@ const JOINS_BACKWARD = [
|
|
|
775
788
|
[69577, 69578],
|
|
776
789
|
[125184, 125251]
|
|
777
790
|
];
|
|
778
|
-
|
|
779
|
-
//#region src/scoring/dictation/normalize.ts
|
|
791
|
+
// src/scoring/dictation/normalize.ts
|
|
780
792
|
/**
|
|
781
793
|
* The longest transcript a dictation accepts, in code points, before and after
|
|
782
794
|
* its equivalences are applied — and its rules may not grow it past twice
|
|
@@ -1736,8 +1748,7 @@ function searchReveal(forms, candidate) {
|
|
|
1736
1748
|
return fields.some((field) => containsPhrase(field, phrase));
|
|
1737
1749
|
});
|
|
1738
1750
|
}
|
|
1739
|
-
|
|
1740
|
-
//#region src/scoring/dictation/align.ts
|
|
1751
|
+
// src/scoring/dictation/align.ts
|
|
1741
1752
|
/**
|
|
1742
1753
|
* The words the scorer can emit a detail for, one list per candidate — index 0
|
|
1743
1754
|
* is the transcript, index n is `acceptedTranscripts[n − 1]` — each word in the
|
|
@@ -1936,8 +1947,7 @@ function alignWords(reference, attempt) {
|
|
|
1936
1947
|
}
|
|
1937
1948
|
return words;
|
|
1938
1949
|
}
|
|
1939
|
-
|
|
1940
|
-
//#region src/errors.ts
|
|
1950
|
+
// src/errors.ts
|
|
1941
1951
|
/** Thrown when activity data fails schema validation at a component boundary. */
|
|
1942
1952
|
var ActivitySchemaError = class extends Error {
|
|
1943
1953
|
activityType;
|
|
@@ -1991,8 +2001,7 @@ var DeferredScoringError = class extends Error {
|
|
|
1991
2001
|
this.name = "DeferredScoringError";
|
|
1992
2002
|
}
|
|
1993
2003
|
};
|
|
1994
|
-
|
|
1995
|
-
//#region src/schemas/after-issues.ts
|
|
2004
|
+
// src/schemas/after-issues.ts
|
|
1996
2005
|
/**
|
|
1997
2006
|
* A check zod runs even when another field was refused. An ordinary check is
|
|
1998
2007
|
* skipped once any issue has been reported, so an author fixing a recording's
|
|
@@ -2029,8 +2038,7 @@ function parsedFields(payload) {
|
|
|
2029
2038
|
refused
|
|
2030
2039
|
};
|
|
2031
2040
|
}
|
|
2032
|
-
|
|
2033
|
-
//#region src/schemas/dictation.ts
|
|
2041
|
+
// src/schemas/dictation.ts
|
|
2034
2042
|
/**
|
|
2035
2043
|
* Zod schema for the slower second recording of a dictation. Loose like every
|
|
2036
2044
|
* content schema (a sidecar survives), audio only, and — deliberately — with no
|
|
@@ -2212,8 +2220,7 @@ function groupCaptionsField(group, written) {
|
|
|
2212
2220
|
}
|
|
2213
2221
|
/** The message every validator gives for {@link groupCaptionsRevealDictation}. */
|
|
2214
2222
|
const GROUP_CAPTIONS_REVEAL_DICTATION = "The stimulus recording carries captions, and a dictation in this group plays that recording: the captions are the answer. Remove the captions, or give the dictation its own recording.";
|
|
2215
|
-
|
|
2216
|
-
//#region src/authoring/issues.ts
|
|
2223
|
+
// src/authoring/issues.ts
|
|
2217
2224
|
/**
|
|
2218
2225
|
* Every issue code the SDK's draft checks can report, with its severity.
|
|
2219
2226
|
*
|
|
@@ -2549,8 +2556,7 @@ function coveredPathsOf(reported) {
|
|
|
2549
2556
|
}
|
|
2550
2557
|
return covered;
|
|
2551
2558
|
}
|
|
2552
|
-
|
|
2553
|
-
//#region src/authoring/dictation.ts
|
|
2559
|
+
// src/authoring/dictation.ts
|
|
2554
2560
|
/**
|
|
2555
2561
|
* Draft support for `dictation`.
|
|
2556
2562
|
*
|
|
@@ -2740,8 +2746,7 @@ function checkTolerance(tolerance) {
|
|
|
2740
2746
|
}
|
|
2741
2747
|
return issues;
|
|
2742
2748
|
}
|
|
2743
|
-
|
|
2744
|
-
//#region src/count-words.ts
|
|
2749
|
+
// src/count-words.ts
|
|
2745
2750
|
/**
|
|
2746
2751
|
* Canonical word counter for written-response bounds: tokens are
|
|
2747
2752
|
* maximal runs of non-whitespace (split on `\s+`), so hyphenated forms
|
|
@@ -2846,8 +2851,7 @@ function levelDistribution(values, count, chosen) {
|
|
|
2846
2851
|
const sum = read.reduce((total, p) => total + p, 0);
|
|
2847
2852
|
return Math.abs(sum - 1) <= 1e-6 && read[chosen] === Math.max(...read) ? read : null;
|
|
2848
2853
|
}
|
|
2849
|
-
|
|
2850
|
-
//#region src/scoring/strategies/all-or-nothing.ts
|
|
2854
|
+
// src/scoring/strategies/all-or-nothing.ts
|
|
2851
2855
|
/**
|
|
2852
2856
|
* All-or-nothing scoring: full credit only when every item is correct.
|
|
2853
2857
|
*
|
|
@@ -2857,8 +2861,7 @@ function levelDistribution(values, count, chosen) {
|
|
|
2857
2861
|
function allOrNothingStrategy(correctItems) {
|
|
2858
2862
|
return correctItems.every((isCorrect) => isCorrect) ? 1 : 0;
|
|
2859
2863
|
}
|
|
2860
|
-
|
|
2861
|
-
//#region src/scoring/strategies/partial.ts
|
|
2864
|
+
// src/scoring/strategies/partial.ts
|
|
2862
2865
|
/**
|
|
2863
2866
|
* Partial-credit scoring for Multiple Choice — balanced/symmetric scheme.
|
|
2864
2867
|
*
|
|
@@ -2898,8 +2901,7 @@ function partialStrategy(correctSelected, incorrectSelected, totalCorrect, total
|
|
|
2898
2901
|
function partialBlankStrategy(correctBlanks, totalBlanks) {
|
|
2899
2902
|
return correctBlanks / totalBlanks;
|
|
2900
2903
|
}
|
|
2901
|
-
|
|
2902
|
-
//#region src/scoring/text-match.ts
|
|
2904
|
+
// src/scoring/text-match.ts
|
|
2903
2905
|
/** Combining marks (any script) removed for diacritic folding after NFD decomposition. */
|
|
2904
2906
|
const COMBINING_MARKS_RE = /\p{M}/gu;
|
|
2905
2907
|
/**
|
|
@@ -2992,8 +2994,7 @@ function matchText(input, accepted, policy = {}) {
|
|
|
2992
2994
|
via: "none"
|
|
2993
2995
|
};
|
|
2994
2996
|
}
|
|
2995
|
-
|
|
2996
|
-
//#region src/scoring/activity-scorers/fill-in-the-blanks.ts
|
|
2997
|
+
// src/scoring/activity-scorers/fill-in-the-blanks.ts
|
|
2997
2998
|
/**
|
|
2998
2999
|
* Resolves the effective match policy for a blank. The legacy
|
|
2999
3000
|
* `caseSensitive` / `trimWhitespace` flags map onto the baseline policy
|
|
@@ -3037,8 +3038,7 @@ function scoreFillInTheBlanks(data, response) {
|
|
|
3037
3038
|
details
|
|
3038
3039
|
};
|
|
3039
3040
|
}
|
|
3040
|
-
|
|
3041
|
-
//#region src/authoring/findings.ts
|
|
3041
|
+
// src/authoring/findings.ts
|
|
3042
3042
|
/**
|
|
3043
3043
|
* Every finding code the SDK's item critic can report, with its severity.
|
|
3044
3044
|
*
|
|
@@ -3064,6 +3064,9 @@ const ITEM_FINDING_SEVERITY = {
|
|
|
3064
3064
|
wr_criterion_name_duplicate: "warning",
|
|
3065
3065
|
wr_levels_unreadable: "warning",
|
|
3066
3066
|
ra_text_long_for_time: "warning",
|
|
3067
|
+
media_transcript_unused: "advice",
|
|
3068
|
+
media_script_differs: "warning",
|
|
3069
|
+
media_transcript_differs: "warning",
|
|
3067
3070
|
set_key_position_same: "warning"
|
|
3068
3071
|
};
|
|
3069
3072
|
function finding(code, path, message) {
|
|
@@ -3088,8 +3091,7 @@ function normaliseFinding(found) {
|
|
|
3088
3091
|
severity: documented ?? (found.severity === "advice" ? "advice" : "warning")
|
|
3089
3092
|
};
|
|
3090
3093
|
}
|
|
3091
|
-
|
|
3092
|
-
//#region src/authoring/critique.ts
|
|
3094
|
+
// src/authoring/critique.ts
|
|
3093
3095
|
/**
|
|
3094
3096
|
* The built-in item critic: what an experienced item writer points out on
|
|
3095
3097
|
* review, as far as a rule can see it without a model.
|
|
@@ -3372,8 +3374,7 @@ function keyPositionFinding(items, path) {
|
|
|
3372
3374
|
if (positions.length < KEY_POSITION_MINIMUM || !positions.every((at) => at === positions[0])) return [];
|
|
3373
3375
|
return [finding("set_key_position_same", path, `In all ${positions.length} single-answer questions the right option is option ${ordinal(positions[0])}. Vary its position, or shuffle the options.`)];
|
|
3374
3376
|
}
|
|
3375
|
-
|
|
3376
|
-
//#region src/authoring/fill-in-the-blanks.ts
|
|
3377
|
+
// src/authoring/fill-in-the-blanks.ts
|
|
3377
3378
|
/**
|
|
3378
3379
|
* Draft support for `fill-in-the-blanks`.
|
|
3379
3380
|
*
|
|
@@ -3505,8 +3506,7 @@ function pairsOneToOne$1(placeholders, blanks) {
|
|
|
3505
3506
|
if (placeholders.size !== blankIds.length) return false;
|
|
3506
3507
|
return blankIds.every((id) => typeof id === "string" && placeholders.get(id) === 1);
|
|
3507
3508
|
}
|
|
3508
|
-
|
|
3509
|
-
//#region src/authoring/gap-select.ts
|
|
3509
|
+
// src/authoring/gap-select.ts
|
|
3510
3510
|
/** Mirrors `GapSelectChoiceSchema` arrays: `.min(2)` on both a gap's own list and a bank. */
|
|
3511
3511
|
const MIN_CHOICES = 2;
|
|
3512
3512
|
/**
|
|
@@ -3704,8 +3704,7 @@ function pairsOneToOne(placeholders, gaps) {
|
|
|
3704
3704
|
if (new Set(ids).size !== ids.length || placeholders.size !== ids.length) return false;
|
|
3705
3705
|
return ids.every((id) => typeof id === "string" && placeholders.get(id) === 1);
|
|
3706
3706
|
}
|
|
3707
|
-
|
|
3708
|
-
//#region src/schemas/multiple-choice.ts
|
|
3707
|
+
// src/schemas/multiple-choice.ts
|
|
3709
3708
|
/**
|
|
3710
3709
|
* Zod schema for a single Multiple Choice option. Loose: unknown keys are
|
|
3711
3710
|
* preserved through validation (forward-compat / consumer sidecars — B7).
|
|
@@ -3732,7 +3731,9 @@ const MultipleChoiceOptionMediaSchema = zod_v4.looseObject({
|
|
|
3732
3731
|
type: zod_v4.enum(["image", "audio"]),
|
|
3733
3732
|
url: MediaUrlSchema,
|
|
3734
3733
|
alt: zod_v4.string().min(1).optional(),
|
|
3735
|
-
captionsUrl: MediaUrlSchema.optional()
|
|
3734
|
+
captionsUrl: MediaUrlSchema.optional(),
|
|
3735
|
+
transcript: zod_v4.string().optional(),
|
|
3736
|
+
script: ScriptSchema.optional()
|
|
3736
3737
|
}).refine((media) => media.type !== "image" || media.alt !== void 0 && media.alt !== "", {
|
|
3737
3738
|
error: "An image option requires a non-empty `alt`.",
|
|
3738
3739
|
path: ["alt"]
|
|
@@ -3767,6 +3768,7 @@ const MultipleChoiceDataSchema = zod_v4.looseObject({
|
|
|
3767
3768
|
type: zod_v4.literal("multiple-choice"),
|
|
3768
3769
|
id: zod_v4.string().min(1),
|
|
3769
3770
|
title: zod_v4.string().min(1),
|
|
3771
|
+
instructions: zod_v4.string().optional(),
|
|
3770
3772
|
question: zod_v4.string().min(1),
|
|
3771
3773
|
questionHtml: zod_v4.string().optional(),
|
|
3772
3774
|
mode: zod_v4.enum(["single", "multi"]),
|
|
@@ -3796,8 +3798,7 @@ const MultipleChoiceDataSchema = zod_v4.looseObject({
|
|
|
3796
3798
|
error: "Option ids must be unique within the activity.",
|
|
3797
3799
|
path: ["options"]
|
|
3798
3800
|
});
|
|
3799
|
-
|
|
3800
|
-
//#region src/authoring/multiple-choice.ts
|
|
3801
|
+
// src/authoring/multiple-choice.ts
|
|
3801
3802
|
/** Mirrors `MultipleChoiceDataSchema`: `options` is `.min(2).max(26)`. */
|
|
3802
3803
|
const MIN_OPTIONS = 2;
|
|
3803
3804
|
const MAX_OPTIONS = 26;
|
|
@@ -3900,8 +3901,7 @@ function checkOptionMedia(media, index, ordinal) {
|
|
|
3900
3901
|
if (kind === "video" || kind === "embed") return [issue("mc_option_media_kind", [...path, "type"], `Option ${ordinal} carries ${kind === "embed" ? "an embedded player" : "a video"}, which cannot be an option: its controls swallow the click that selects the answer. Use a picture or a recording.`)];
|
|
3901
3902
|
return checkMedia(media, path, MultipleChoiceOptionMediaSchema);
|
|
3902
3903
|
}
|
|
3903
|
-
|
|
3904
|
-
//#region src/scoring/speech/limits.ts
|
|
3904
|
+
// src/scoring/speech/limits.ts
|
|
3905
3905
|
/**
|
|
3906
3906
|
* The longest reference text a read-aloud item accepts, in code points, before
|
|
3907
3907
|
* and after normalisation. It is the dictation transcript cap on purpose: the
|
|
@@ -3951,8 +3951,7 @@ const SPEECH_ASSESSMENT_MAX_WORDS = 1e3;
|
|
|
3951
3951
|
* read-aloud item comes near it.
|
|
3952
3952
|
*/
|
|
3953
3953
|
const SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH;
|
|
3954
|
-
|
|
3955
|
-
//#region src/scoring/speech/locale.ts
|
|
3954
|
+
// src/scoring/speech/locale.ts
|
|
3956
3955
|
/**
|
|
3957
3956
|
* A BCP 47 tag in the one spelling read-aloud accepts: a lowercase language of
|
|
3958
3957
|
* two or three letters, an optional title-case script, and a region of two
|
|
@@ -3968,8 +3967,7 @@ const SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH;
|
|
|
3968
3967
|
* Internal: the content schema and the assessment validator share it.
|
|
3969
3968
|
*/
|
|
3970
3969
|
const CANONICAL_LOCALE_RE = /^[a-z]{2,3}(?:-[A-Z][a-z]{3})?-(?:[A-Z]{2}|[0-9]{3})$/;
|
|
3971
|
-
|
|
3972
|
-
//#region src/schemas/read-aloud.ts
|
|
3970
|
+
// src/schemas/read-aloud.ts
|
|
3973
3971
|
/** The dimensions a read-aloud grade can be made of, in the order they are documented. */
|
|
3974
3972
|
const READ_ALOUD_DIMENSIONS = [
|
|
3975
3973
|
"accuracy",
|
|
@@ -4122,8 +4120,7 @@ const ReadAloudDataSchema = zod_v4.looseObject({
|
|
|
4122
4120
|
if (minSeconds !== void 0 && minSeconds >= maxSeconds) report(["recording", "minSeconds"], minSeconds, "The shortest take must be shorter than the longest.");
|
|
4123
4121
|
}
|
|
4124
4122
|
}));
|
|
4125
|
-
|
|
4126
|
-
//#region src/authoring/read-aloud.ts
|
|
4123
|
+
// src/authoring/read-aloud.ts
|
|
4127
4124
|
/**
|
|
4128
4125
|
* Draft support for `read-aloud`.
|
|
4129
4126
|
*
|
|
@@ -4286,8 +4283,7 @@ function checkSlowRecording(draft) {
|
|
|
4286
4283
|
if (typeof slow.url === "string" && slow.url !== "" && slow.url === media.url) issues.push(issue("ra_slow_media_same_recording", ["slowMedia", "url"], "The slow model recording is the same file as the recording. Point it at the slower reading."));
|
|
4287
4284
|
return issues;
|
|
4288
4285
|
}
|
|
4289
|
-
|
|
4290
|
-
//#region src/authoring/written-response.ts
|
|
4286
|
+
// src/authoring/written-response.ts
|
|
4291
4287
|
/**
|
|
4292
4288
|
* Draft support for `written-response`.
|
|
4293
4289
|
*
|
|
@@ -4375,8 +4371,7 @@ function checkCriteria(criteria) {
|
|
|
4375
4371
|
else if (totalWeight === Number.POSITIVE_INFINITY) issues.push(issue("wr_rubric_weights_too_large", ["rubric", "criteria"], "The rubric weights add up to more than can be calculated with. Use smaller weights."));
|
|
4376
4372
|
return issues;
|
|
4377
4373
|
}
|
|
4378
|
-
|
|
4379
|
-
//#region src/schemas/gap-select.ts
|
|
4374
|
+
// src/schemas/gap-select.ts
|
|
4380
4375
|
/**
|
|
4381
4376
|
* Zod schema for one selectable choice. Loose, like every other schema here:
|
|
4382
4377
|
* unknown keys are preserved so a consumer sidecar survives validation.
|
|
@@ -4440,6 +4435,7 @@ const GapSelectDataSchema = zod_v4.looseObject({
|
|
|
4440
4435
|
type: zod_v4.literal("gap-select"),
|
|
4441
4436
|
id: zod_v4.string().min(1),
|
|
4442
4437
|
title: zod_v4.string().min(1),
|
|
4438
|
+
instructions: PassageInstructionsSchema.optional(),
|
|
4443
4439
|
passage: zod_v4.string().min(1),
|
|
4444
4440
|
passageHtml: zod_v4.string().optional(),
|
|
4445
4441
|
gaps: zod_v4.array(GapSelectGapSchema).min(1),
|
|
@@ -4500,8 +4496,7 @@ const GapSelectDataSchema = zod_v4.looseObject({
|
|
|
4500
4496
|
error: "Each gap needs unique choice ids and a `correctChoiceId` that is one of the choices it offers.",
|
|
4501
4497
|
path: ["gaps"]
|
|
4502
4498
|
});
|
|
4503
|
-
|
|
4504
|
-
//#region src/schemas/written-response.ts
|
|
4499
|
+
// src/schemas/written-response.ts
|
|
4505
4500
|
/** Zod schema for a single rubric criterion. Loose: unknown keys preserved. */
|
|
4506
4501
|
const WrittenResponseRubricCriterionSchema = zod_v4.looseObject({
|
|
4507
4502
|
name: zod_v4.string().min(1),
|
|
@@ -4572,8 +4567,7 @@ const WrittenResponseDataSchema = zod_v4.looseObject({
|
|
|
4572
4567
|
error: "maxWords must be greater than or equal to minWords.",
|
|
4573
4568
|
path: ["maxWords"]
|
|
4574
4569
|
});
|
|
4575
|
-
|
|
4576
|
-
//#region src/schemas/redacted.ts
|
|
4570
|
+
// src/schemas/redacted.ts
|
|
4577
4571
|
/**
|
|
4578
4572
|
* Schemas for REDACTED activity data — the learner-safe projection `redact()`
|
|
4579
4573
|
* produces (R7). Deliberately STRICT (`z.strictObject`), the opposite of the
|
|
@@ -4637,6 +4631,7 @@ const RedactedMultipleChoiceOptionSchema = zod_v4.strictObject({
|
|
|
4637
4631
|
const RedactedMultipleChoiceDataSchema = zod_v4.strictObject({
|
|
4638
4632
|
...redactedBase,
|
|
4639
4633
|
type: zod_v4.literal("multiple-choice"),
|
|
4634
|
+
instructions: zod_v4.string().optional(),
|
|
4640
4635
|
question: zod_v4.string().min(1),
|
|
4641
4636
|
questionHtml: zod_v4.string().optional(),
|
|
4642
4637
|
mode: zod_v4.enum(["single", "multi"]),
|
|
@@ -4652,6 +4647,7 @@ const RedactedBlankConfigSchema = zod_v4.strictObject({
|
|
|
4652
4647
|
const RedactedFillInTheBlanksDataSchema = zod_v4.strictObject({
|
|
4653
4648
|
...redactedBase,
|
|
4654
4649
|
type: zod_v4.literal("fill-in-the-blanks"),
|
|
4650
|
+
instructions: zod_v4.string().optional(),
|
|
4655
4651
|
passage: zod_v4.string().min(1),
|
|
4656
4652
|
passageHtml: zod_v4.string().optional(),
|
|
4657
4653
|
blanks: zod_v4.array(RedactedBlankConfigSchema).min(1)
|
|
@@ -4690,6 +4686,7 @@ const RedactedGapSelectGapSchema = zod_v4.strictObject({
|
|
|
4690
4686
|
const RedactedGapSelectDataSchema = zod_v4.strictObject({
|
|
4691
4687
|
...redactedBase,
|
|
4692
4688
|
type: zod_v4.literal("gap-select"),
|
|
4689
|
+
instructions: zod_v4.string().optional(),
|
|
4693
4690
|
passage: zod_v4.string().min(1),
|
|
4694
4691
|
passageHtml: zod_v4.string().optional(),
|
|
4695
4692
|
gaps: zod_v4.array(RedactedGapSelectGapSchema).min(1),
|
|
@@ -4815,8 +4812,7 @@ const RedactedReadAloudDataSchema = zod_v4.strictObject({
|
|
|
4815
4812
|
path: ["slowMedia", "url"]
|
|
4816
4813
|
});
|
|
4817
4814
|
});
|
|
4818
|
-
|
|
4819
|
-
//#region src/scoring/activity-scorers/dictation.ts
|
|
4815
|
+
// src/scoring/activity-scorers/dictation.ts
|
|
4820
4816
|
/**
|
|
4821
4817
|
* Scores a Dictation response: the character-level similarity of what the
|
|
4822
4818
|
* learner typed to the transcript, over the whole sentence.
|
|
@@ -4855,8 +4851,7 @@ function scoreDictation(data, response) {
|
|
|
4855
4851
|
details
|
|
4856
4852
|
};
|
|
4857
4853
|
}
|
|
4858
|
-
|
|
4859
|
-
//#region src/scoring/activity-scorers/gap-select.ts
|
|
4854
|
+
// src/scoring/activity-scorers/gap-select.ts
|
|
4860
4855
|
/**
|
|
4861
4856
|
* The choices a gap offers: its own list, or the bank it names.
|
|
4862
4857
|
*
|
|
@@ -4910,8 +4905,7 @@ function scoreGapSelect(data, response) {
|
|
|
4910
4905
|
details
|
|
4911
4906
|
};
|
|
4912
4907
|
}
|
|
4913
|
-
|
|
4914
|
-
//#region src/scoring/activity-scorers/multiple-choice.ts
|
|
4908
|
+
// src/scoring/activity-scorers/multiple-choice.ts
|
|
4915
4909
|
/**
|
|
4916
4910
|
* Scores a Multiple Choice response. Pure; trusts its typed inputs (validation
|
|
4917
4911
|
* is the component boundary's job). Options are looked up by id; an unknown
|
|
@@ -4955,8 +4949,7 @@ function scoreMultipleChoice(data, response) {
|
|
|
4955
4949
|
details
|
|
4956
4950
|
};
|
|
4957
4951
|
}
|
|
4958
|
-
|
|
4959
|
-
//#region src/registry/define.ts
|
|
4952
|
+
// src/registry/define.ts
|
|
4960
4953
|
/**
|
|
4961
4954
|
* Identity helper that gives full type inference when authoring a descriptor:
|
|
4962
4955
|
*
|
|
@@ -4971,8 +4964,7 @@ function scoreMultipleChoice(data, response) {
|
|
|
4971
4964
|
function defineActivityType(descriptor) {
|
|
4972
4965
|
return descriptor;
|
|
4973
4966
|
}
|
|
4974
|
-
|
|
4975
|
-
//#region src/registry/keep-when.ts
|
|
4967
|
+
// src/registry/keep-when.ts
|
|
4976
4968
|
/**
|
|
4977
4969
|
* A nested field policy that keeps its field only when the field's value
|
|
4978
4970
|
* passes a test. Internal: the symbol is never exported, so no host policy can
|
|
@@ -4997,8 +4989,22 @@ function keepWhen(policy, test) {
|
|
|
4997
4989
|
function guardOf(policy) {
|
|
4998
4990
|
return policy[KEEP_WHEN];
|
|
4999
4991
|
}
|
|
5000
|
-
|
|
5001
|
-
|
|
4992
|
+
// src/registry/builtins.ts
|
|
4993
|
+
/**
|
|
4994
|
+
* Where the built-in types keep their files (`mediaSlots`). Every type has its
|
|
4995
|
+
* `media`; dictation and read-aloud add a slower recording; a multiple-choice
|
|
4996
|
+
* option may carry a picture or a recording of its own.
|
|
4997
|
+
*/
|
|
4998
|
+
const MAIN_MEDIA = [{ path: ["media"] }];
|
|
4999
|
+
const MAIN_AND_SLOW_MEDIA = [{ path: ["media"] }, { path: ["slowMedia"] }];
|
|
5000
|
+
function multipleChoiceMediaSlots(data) {
|
|
5001
|
+
const options = Array.isArray(data.options) ? data.options : [];
|
|
5002
|
+
return [...MAIN_MEDIA, ...options.map((_, index) => ({ path: [
|
|
5003
|
+
"options",
|
|
5004
|
+
index,
|
|
5005
|
+
"media"
|
|
5006
|
+
] }))];
|
|
5007
|
+
}
|
|
5002
5008
|
/**
|
|
5003
5009
|
* Field-sensitivity policies for the built-in types (R7). Fail-closed:
|
|
5004
5010
|
* anything not listed here is dropped by `redact()`. `scoringStrategy` is
|
|
@@ -5019,10 +5025,11 @@ function guardOf(policy) {
|
|
|
5019
5025
|
* documents ("a field the policy does not classify is removed") stopped at the
|
|
5020
5026
|
* media boundary. It no longer does.
|
|
5021
5027
|
*
|
|
5022
|
-
*
|
|
5023
|
-
* and enforces the policy, and "1 play remaining" is text the
|
|
5024
|
-
*
|
|
5025
|
-
* `
|
|
5028
|
+
* Public by necessity, except what the recording says: the client is the thing
|
|
5029
|
+
* that renders and enforces the policy, and "1 play remaining" is text the
|
|
5030
|
+
* learner has to read. `transcript` and `script` are the exception, and
|
|
5031
|
+
* `author-only`: what a listening question's recording says is that question's
|
|
5032
|
+
* answer, as `stimulus.transcript` is a listening paper's.
|
|
5026
5033
|
*/
|
|
5027
5034
|
const MEDIA_FIELD_POLICY = {
|
|
5028
5035
|
type: "public",
|
|
@@ -5043,7 +5050,9 @@ const MEDIA_FIELD_POLICY = {
|
|
|
5043
5050
|
seek: "public",
|
|
5044
5051
|
rate: "public",
|
|
5045
5052
|
nativeControlHints: "public"
|
|
5046
|
-
}
|
|
5053
|
+
},
|
|
5054
|
+
transcript: "author-only",
|
|
5055
|
+
script: "author-only"
|
|
5047
5056
|
};
|
|
5048
5057
|
const SHARED_PUBLIC_FIELDS = {
|
|
5049
5058
|
schemaVersion: "public",
|
|
@@ -5098,6 +5107,7 @@ const TEXT_MATCH_FIELD_POLICY = {
|
|
|
5098
5107
|
};
|
|
5099
5108
|
const MULTIPLE_CHOICE_FIELD_POLICY = {
|
|
5100
5109
|
...SHARED_PUBLIC_FIELDS,
|
|
5110
|
+
instructions: "public",
|
|
5101
5111
|
question: "public",
|
|
5102
5112
|
questionHtml: "public",
|
|
5103
5113
|
mode: "public",
|
|
@@ -5113,7 +5123,9 @@ const MULTIPLE_CHOICE_FIELD_POLICY = {
|
|
|
5113
5123
|
type: "public",
|
|
5114
5124
|
url: "public",
|
|
5115
5125
|
alt: "public",
|
|
5116
|
-
captionsUrl: "public"
|
|
5126
|
+
captionsUrl: "public",
|
|
5127
|
+
transcript: "author-only",
|
|
5128
|
+
script: "author-only"
|
|
5117
5129
|
}
|
|
5118
5130
|
}
|
|
5119
5131
|
};
|
|
@@ -5130,6 +5142,7 @@ const MULTIPLE_CHOICE_FIELD_POLICY = {
|
|
|
5130
5142
|
*/
|
|
5131
5143
|
const GAP_SELECT_FIELD_POLICY = {
|
|
5132
5144
|
...SHARED_PUBLIC_FIELDS,
|
|
5145
|
+
instructions: "public",
|
|
5133
5146
|
passage: "public",
|
|
5134
5147
|
passageHtml: "public",
|
|
5135
5148
|
presentation: "public",
|
|
@@ -5156,6 +5169,7 @@ const GAP_SELECT_FIELD_POLICY = {
|
|
|
5156
5169
|
};
|
|
5157
5170
|
const FILL_IN_THE_BLANKS_FIELD_POLICY = {
|
|
5158
5171
|
...SHARED_PUBLIC_FIELDS,
|
|
5172
|
+
instructions: "public",
|
|
5159
5173
|
passage: "public",
|
|
5160
5174
|
passageHtml: "public",
|
|
5161
5175
|
scoringStrategy: "answer-key",
|
|
@@ -5253,7 +5267,8 @@ const multipleChoiceType = defineActivityType({
|
|
|
5253
5267
|
"option-deselected",
|
|
5254
5268
|
"submitted"
|
|
5255
5269
|
],
|
|
5256
|
-
authoring: multipleChoiceAuthoring
|
|
5270
|
+
authoring: multipleChoiceAuthoring,
|
|
5271
|
+
mediaSlots: multipleChoiceMediaSlots
|
|
5257
5272
|
});
|
|
5258
5273
|
/** Built-in Fill-in-the-Blanks descriptor. */
|
|
5259
5274
|
const fillInTheBlanksType = defineActivityType({
|
|
@@ -5276,7 +5291,8 @@ const fillInTheBlanksType = defineActivityType({
|
|
|
5276
5291
|
"hint-requested",
|
|
5277
5292
|
"submitted"
|
|
5278
5293
|
],
|
|
5279
|
-
authoring: fillInTheBlanksAuthoring
|
|
5294
|
+
authoring: fillInTheBlanksAuthoring,
|
|
5295
|
+
mediaSlots: () => MAIN_MEDIA
|
|
5280
5296
|
});
|
|
5281
5297
|
/**
|
|
5282
5298
|
* Built-in Written Response descriptor. Grading is DEFERRED: submissions are
|
|
@@ -5308,7 +5324,8 @@ const writtenResponseType = defineActivityType({
|
|
|
5308
5324
|
correctResponsesPattern: () => []
|
|
5309
5325
|
},
|
|
5310
5326
|
interactions: ["text-changed", "submitted"],
|
|
5311
|
-
authoring: writtenResponseAuthoring
|
|
5327
|
+
authoring: writtenResponseAuthoring,
|
|
5328
|
+
mediaSlots: () => MAIN_MEDIA
|
|
5312
5329
|
});
|
|
5313
5330
|
/** Built-in Gap Select descriptor. */
|
|
5314
5331
|
const gapSelectType = defineActivityType({
|
|
@@ -5327,7 +5344,8 @@ const gapSelectType = defineActivityType({
|
|
|
5327
5344
|
correctResponsesPattern: (data) => [data.gaps.map((gap) => `${gap.id}[.]${gap.correctChoiceId}`).join("[,]")]
|
|
5328
5345
|
},
|
|
5329
5346
|
interactions: ["gap-selected", "submitted"],
|
|
5330
|
-
authoring: gapSelectAuthoring
|
|
5347
|
+
authoring: gapSelectAuthoring,
|
|
5348
|
+
mediaSlots: () => MAIN_MEDIA
|
|
5331
5349
|
});
|
|
5332
5350
|
/**
|
|
5333
5351
|
* Built-in Dictation descriptor. Graded synchronously: the score is the
|
|
@@ -5354,7 +5372,8 @@ const dictationType = defineActivityType({
|
|
|
5354
5372
|
"hint-requested",
|
|
5355
5373
|
"submitted"
|
|
5356
5374
|
],
|
|
5357
|
-
authoring: dictationAuthoring
|
|
5375
|
+
authoring: dictationAuthoring,
|
|
5376
|
+
mediaSlots: () => MAIN_AND_SLOW_MEDIA
|
|
5358
5377
|
});
|
|
5359
5378
|
/**
|
|
5360
5379
|
* Read Aloud, the type with no answer key at all.
|
|
@@ -5435,7 +5454,8 @@ const readAloudType = defineActivityType({
|
|
|
5435
5454
|
"recording-uploaded",
|
|
5436
5455
|
"submitted"
|
|
5437
5456
|
],
|
|
5438
|
-
authoring: readAloudAuthoring
|
|
5457
|
+
authoring: readAloudAuthoring,
|
|
5458
|
+
mediaSlots: () => MAIN_AND_SLOW_MEDIA
|
|
5439
5459
|
});
|
|
5440
5460
|
/**
|
|
5441
5461
|
* The SDK's own types, by type: what the registry is created holding
|
|
@@ -5452,8 +5472,7 @@ const BUILT_IN_DESCRIPTORS = {
|
|
|
5452
5472
|
dictation: dictationType,
|
|
5453
5473
|
"read-aloud": readAloudType
|
|
5454
5474
|
};
|
|
5455
|
-
|
|
5456
|
-
//#region src/schemas/read-schema.ts
|
|
5475
|
+
// src/schemas/read-schema.ts
|
|
5457
5476
|
/**
|
|
5458
5477
|
* How every entry point reads a schema — `validateActivity`, `validateDraft`,
|
|
5459
5478
|
* `validateItemGroup`, `redact`, `assertRedacted` — so a schema is read one way
|
|
@@ -5563,14 +5582,13 @@ function isStandardSchema(value) {
|
|
|
5563
5582
|
* A schema's own JSON Schema, when it implements the Standard JSON Schema
|
|
5564
5583
|
* converter (`'~standard'.jsonSchema`) — zod 4.6 does — or `undefined`.
|
|
5565
5584
|
*/
|
|
5566
|
-
function standardJsonSchemaOf(schema) {
|
|
5585
|
+
function standardJsonSchemaOf(schema, target = "draft-07") {
|
|
5567
5586
|
const converter = schema["~standard"].jsonSchema;
|
|
5568
5587
|
if (typeof converter?.output !== "function") return;
|
|
5569
|
-
const generated = converter.output({ target
|
|
5588
|
+
const generated = converter.output({ target });
|
|
5570
5589
|
return generated !== null && typeof generated === "object" && !Array.isArray(generated) ? generated : void 0;
|
|
5571
5590
|
}
|
|
5572
|
-
|
|
5573
|
-
//#region src/registry/registry.ts
|
|
5591
|
+
// src/registry/registry.ts
|
|
5574
5592
|
/**
|
|
5575
5593
|
* Module-scoped default registry (deliberate — no registry instances until a
|
|
5576
5594
|
* second consumer exists), created holding the SDK's own types.
|
|
@@ -5616,7 +5634,6 @@ function getActivityTypeDescriptor(type) {
|
|
|
5616
5634
|
function registeredActivityTypes() {
|
|
5617
5635
|
return [...registry.keys()];
|
|
5618
5636
|
}
|
|
5619
|
-
//#endregion
|
|
5620
5637
|
Object.defineProperty(exports, "ActivitySchemaError", {
|
|
5621
5638
|
enumerable: true,
|
|
5622
5639
|
get: function() {
|
|
@@ -5773,6 +5790,12 @@ Object.defineProperty(exports, "RedactedScoringError", {
|
|
|
5773
5790
|
return RedactedScoringError;
|
|
5774
5791
|
}
|
|
5775
5792
|
});
|
|
5793
|
+
Object.defineProperty(exports, "SCRIPT_MAX_TURNS", {
|
|
5794
|
+
enumerable: true,
|
|
5795
|
+
get: function() {
|
|
5796
|
+
return SCRIPT_MAX_TURNS;
|
|
5797
|
+
}
|
|
5798
|
+
});
|
|
5776
5799
|
Object.defineProperty(exports, "SPEECH_ASSESSMENT_MAX_TEXT_LENGTH", {
|
|
5777
5800
|
enumerable: true,
|
|
5778
5801
|
get: function() {
|
|
@@ -5791,6 +5814,12 @@ Object.defineProperty(exports, "STEP", {
|
|
|
5791
5814
|
return STEP;
|
|
5792
5815
|
}
|
|
5793
5816
|
});
|
|
5817
|
+
Object.defineProperty(exports, "ScriptSchema", {
|
|
5818
|
+
enumerable: true,
|
|
5819
|
+
get: function() {
|
|
5820
|
+
return ScriptSchema;
|
|
5821
|
+
}
|
|
5822
|
+
});
|
|
5794
5823
|
Object.defineProperty(exports, "UnknownActivityTypeError", {
|
|
5795
5824
|
enumerable: true,
|
|
5796
5825
|
get: function() {
|
|
@@ -5887,6 +5916,12 @@ Object.defineProperty(exports, "fillInTheBlanksType", {
|
|
|
5887
5916
|
return fillInTheBlanksType;
|
|
5888
5917
|
}
|
|
5889
5918
|
});
|
|
5919
|
+
Object.defineProperty(exports, "finding", {
|
|
5920
|
+
enumerable: true,
|
|
5921
|
+
get: function() {
|
|
5922
|
+
return finding;
|
|
5923
|
+
}
|
|
5924
|
+
});
|
|
5890
5925
|
Object.defineProperty(exports, "fold", {
|
|
5891
5926
|
enumerable: true,
|
|
5892
5927
|
get: function() {
|
|
@@ -6092,4 +6127,4 @@ Object.defineProperty(exports, "writtenResponseType", {
|
|
|
6092
6127
|
}
|
|
6093
6128
|
});
|
|
6094
6129
|
|
|
6095
|
-
//# sourceMappingURL=registry-
|
|
6130
|
+
//# sourceMappingURL=registry-hzrkTeIT.cjs.map
|