@intellectif/lk-core 0.13.0 → 0.14.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +1 -1
  3. package/dist/{activity-DfAmJ1sl.d.cts → activity-BVkg9VDo.d.cts} +153 -4
  4. package/dist/{activity-DfAmJ1sl.d.ts → activity-BVkg9VDo.d.ts} +153 -4
  5. package/dist/{chunk-DQKJUMUW.cjs → chunk-2NIALQEH.cjs} +24 -19
  6. package/dist/chunk-2NIALQEH.cjs.map +1 -0
  7. package/dist/{chunk-XKKKWKRH.js → chunk-6RND47QE.js} +694 -126
  8. package/dist/chunk-6RND47QE.js.map +1 -0
  9. package/dist/{chunk-FT7SAC3X.cjs → chunk-CZRUMHKW.cjs} +4 -4
  10. package/dist/{chunk-FT7SAC3X.cjs.map → chunk-CZRUMHKW.cjs.map} +1 -1
  11. package/dist/chunk-J5OIRIOW.cjs +1034 -0
  12. package/dist/chunk-J5OIRIOW.cjs.map +1 -0
  13. package/dist/{chunk-Y36S3X3L.js → chunk-NBADQ3JU.js} +7 -2
  14. package/dist/chunk-NBADQ3JU.js.map +1 -0
  15. package/dist/{chunk-PYP3HCRQ.js → chunk-R7PV3XIC.js} +2 -2
  16. package/dist/chunk-RTIR6R2U.js +1034 -0
  17. package/dist/chunk-RTIR6R2U.js.map +1 -0
  18. package/dist/{chunk-XONKWL6D.cjs → chunk-VCXIPLEW.cjs} +585 -17
  19. package/dist/chunk-VCXIPLEW.cjs.map +1 -0
  20. package/dist/{index-Bz9wUigA.d.cts → index-BE1bM2Wi.d.cts} +225 -3
  21. package/dist/{index-CJbbVE9o.d.ts → index-v2_-Fyn3.d.ts} +225 -3
  22. package/dist/index.cjs +113 -80
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +50 -17
  25. package/dist/index.d.ts +50 -17
  26. package/dist/index.js +39 -6
  27. package/dist/index.js.map +1 -1
  28. package/dist/schemas.cjs +11 -3
  29. package/dist/schemas.cjs.map +1 -1
  30. package/dist/schemas.d.cts +2 -2
  31. package/dist/schemas.d.ts +2 -2
  32. package/dist/schemas.js +10 -2
  33. package/dist/scoring.cjs +23 -3
  34. package/dist/scoring.cjs.map +1 -1
  35. package/dist/scoring.d.cts +471 -16
  36. package/dist/scoring.d.ts +471 -16
  37. package/dist/scoring.js +24 -4
  38. package/dist/xapi.cjs +3 -3
  39. package/dist/xapi.d.cts +1 -1
  40. package/dist/xapi.d.ts +1 -1
  41. package/dist/xapi.js +2 -2
  42. package/package.json +1 -1
  43. package/vectors/README.md +63 -3
  44. package/vectors/replay.d.mts +7 -2
  45. package/vectors/replay.mjs +83 -1
  46. package/vectors/scoring.json +10875 -2
  47. package/dist/chunk-DQKJUMUW.cjs.map +0 -1
  48. package/dist/chunk-FGN4LLSP.js +0 -387
  49. package/dist/chunk-FGN4LLSP.js.map +0 -1
  50. package/dist/chunk-UHQVIC3P.cjs +0 -387
  51. package/dist/chunk-UHQVIC3P.cjs.map +0 -1
  52. package/dist/chunk-XKKKWKRH.js.map +0 -1
  53. package/dist/chunk-XONKWL6D.cjs.map +0 -1
  54. package/dist/chunk-Y36S3X3L.js.map +0 -1
  55. /package/dist/{chunk-PYP3HCRQ.js.map → chunk-R7PV3XIC.js.map} +0 -0
@@ -20,7 +20,7 @@ var UnknownActivityTypeError = class extends Error {
20
20
  var RedactedScoringError = class extends Error {
21
21
  constructor(activityType) {
22
22
  super(
23
- `Activity data for "${activityType}" carries no answer key (it looks redacted), so it cannot be scored. Score against the full activity data server-side, or use evaluate() which returns { status: "unscorable" }.`
23
+ `Activity data for "${activityType}" carries no answer key (it looks redacted), so it cannot be scored. Score against the full activity data server-side. evaluate() answers this input without throwing, but it never grades it.`
24
24
  );
25
25
  this.activityType = activityType;
26
26
  this.name = "RedactedScoringError";
@@ -220,6 +220,10 @@ var SPACE_BESIDE_UNSPACED_RE = new RegExp(
220
220
  );
221
221
  var WORD_RE = new RegExp(`^[\\p{L}\\p{M}\\p{N}${JOINERS}]$`, "u");
222
222
  var UNSPACED_CHARACTER_RE = new RegExp(`^${UNSPACED_CHARACTER}$`, "u");
223
+ var UNSPACED_LETTER_RE = new RegExp(`(?=\\p{L})${UNSPACED_CHARACTER}`, "u");
224
+ function containsUnspacedScript(text) {
225
+ return UNSPACED_LETTER_RE.test(text);
226
+ }
223
227
  var EXTENDING_RE = new RegExp(`^[\\p{M}${JOINERS}${TAGS}]$`, "u");
224
228
  var WORD = 1;
225
229
  var UNSPACED = 2;
@@ -1341,6 +1345,168 @@ var MultipleChoiceDataSchema = _v4.z.looseObject({
1341
1345
  path: ["options"]
1342
1346
  });
1343
1347
 
1348
+ // src/scoring/speech/limits.ts
1349
+ var READ_ALOUD_MAX_REFERENCE_LENGTH = DICTATION_MAX_TRANSCRIPT_LENGTH;
1350
+ var READ_ALOUD_MAX_SECONDS = 300;
1351
+ var READ_ALOUD_MAX_TAKES = 20;
1352
+ var READ_ALOUD_MAX_DIMENSION_WEIGHT = 1e3;
1353
+ var SPEECH_ASSESSMENT_MAX_WORDS = 1e3;
1354
+ var SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH;
1355
+
1356
+ // src/schemas/read-aloud.ts
1357
+
1358
+
1359
+ // src/scoring/speech/locale.ts
1360
+ var CANONICAL_LOCALE_RE = /^[a-z]{2,3}(?:-[A-Z][a-z]{3})?-(?:[A-Z]{2}|[0-9]{3})$/;
1361
+
1362
+ // src/schemas/read-aloud.ts
1363
+ var READ_ALOUD_DIMENSIONS = ["accuracy", "fluency", "completeness", "prosody"];
1364
+ var READ_ALOUD_MAX_DIMENSIONS = READ_ALOUD_DIMENSIONS.length;
1365
+ var ReadAloudSlowMediaSchema = _v4.z.strictObject({
1366
+ type: _v4.z.literal("audio"),
1367
+ url: MediaUrlSchema,
1368
+ alt: _v4.z.string().min(1).optional()
1369
+ });
1370
+ var ReferenceTextSchema = _v4.z.string().min(1).refine((text) => text.trim() !== "", {
1371
+ error: "The text to read aloud must contain something to read."
1372
+ }).meta({ maxLength: READ_ALOUD_MAX_REFERENCE_LENGTH });
1373
+ var RecordingBoundsSchema = _v4.z.looseObject({
1374
+ maxSeconds: _v4.z.number().gt(0).max(READ_ALOUD_MAX_SECONDS),
1375
+ minSeconds: _v4.z.number().min(0).optional(),
1376
+ maxTakes: _v4.z.number().int().min(1).max(READ_ALOUD_MAX_TAKES).optional()
1377
+ });
1378
+ var ReadAloudDimensionWeightSchema = _v4.z.looseObject({
1379
+ name: _v4.z.enum(READ_ALOUD_DIMENSIONS),
1380
+ weight: _v4.z.number().min(0).max(READ_ALOUD_MAX_DIMENSION_WEIGHT)
1381
+ });
1382
+ var ReadAloudScoringSchema = _v4.z.looseObject({
1383
+ dimensions: _v4.z.array(ReadAloudDimensionWeightSchema).min(1).max(READ_ALOUD_MAX_DIMENSIONS)
1384
+ });
1385
+ function checkEvenAfterIssues2(check) {
1386
+ const guard = new _v4.z.core.$ZodCheck({ check: "custom", when: () => true });
1387
+ guard._zod.check = check;
1388
+ return guard;
1389
+ }
1390
+ var ReadAloudDataShape = _v4.z.looseObject({
1391
+ schemaVersion: _v4.z.literal("1.0"),
1392
+ type: _v4.z.literal("read-aloud"),
1393
+ id: _v4.z.string().min(1),
1394
+ title: _v4.z.string().min(1),
1395
+ instructions: _v4.z.string().optional(),
1396
+ referenceText: ReferenceTextSchema,
1397
+ locale: _v4.z.string().regex(CANONICAL_LOCALE_RE, {
1398
+ error: `The locale must be a BCP 47 tag in canonical form, with a region: "en-US", "es-419", "zh-Hant-TW". Pronunciation is assessed against one locale's speech, and "en" does not say whose.`
1399
+ }),
1400
+ media: MediaSchema.optional(),
1401
+ slowMedia: ReadAloudSlowMediaSchema.optional(),
1402
+ recording: RecordingBoundsSchema,
1403
+ scoring: ReadAloudScoringSchema,
1404
+ passThreshold: _v4.z.number().min(0).max(1).optional(),
1405
+ feedback: FeedbackSchema.optional(),
1406
+ learningObjectives: _v4.z.array(_v4.z.string()).optional(),
1407
+ difficultyLevel: _v4.z.literal([1, 2, 3, 4, 5]).optional()
1408
+ });
1409
+ var ReadAloudDataSchema = ReadAloudDataShape.check(
1410
+ checkEvenAfterIssues2((ctx) => {
1411
+ if (ctx.issues.some((issue2) => (_nullishCoalesce(_optionalChain([issue2, 'access', _53 => _53.path, 'optionalAccess', _54 => _54.length]), () => ( 0))) === 0)) {
1412
+ return;
1413
+ }
1414
+ const data = ctx.value;
1415
+ const refused = new Set(ctx.issues.map((issue2) => String(_optionalChain([issue2, 'access', _55 => _55.path, 'optionalAccess', _56 => _56[0]]))));
1416
+ const report = (path, input, message) => {
1417
+ ctx.issues.push({ code: "custom", input, message, path: [...path] });
1418
+ };
1419
+ if (!refused.has("referenceText")) {
1420
+ const text = data.referenceText;
1421
+ const measured = dictationNormalizer(void 0).measure(text);
1422
+ if (measured.tooLong) {
1423
+ report(
1424
+ ["referenceText"],
1425
+ text,
1426
+ `The text to read aloud is at most ${READ_ALOUD_MAX_REFERENCE_LENGTH} characters, before and after normalisation.`
1427
+ );
1428
+ }
1429
+ if (measured.normalized === "") {
1430
+ report(
1431
+ ["referenceText"],
1432
+ text,
1433
+ "The text to read aloud must contain a word: after ignoring punctuation and spacing nothing is left, so no word would be marked and every reading would align as one insertion after another."
1434
+ );
1435
+ }
1436
+ if (containsUnspacedScript(text)) {
1437
+ report(
1438
+ ["referenceText"],
1439
+ text,
1440
+ "A read-aloud item needs a script written with spaces between its words. The text is compared word by word, and a run of Han, kana, Thai, Lao, Khmer or Myanmar letters is one word however many it holds."
1441
+ );
1442
+ }
1443
+ }
1444
+ const mediaParses = !refused.has("media");
1445
+ const slowParses = !refused.has("slowMedia");
1446
+ if (mediaParses && data.media !== void 0 && data.media.type !== "audio") {
1447
+ report(
1448
+ ["media", "type"],
1449
+ data.media.type,
1450
+ "A read-aloud model is read aloud: its recording must be audio."
1451
+ );
1452
+ }
1453
+ if (mediaParses && slowParses && data.slowMedia !== void 0) {
1454
+ if (data.media === void 0) {
1455
+ report(
1456
+ ["media"],
1457
+ data.media,
1458
+ "A slow model recording accompanies a recording: add `media` first."
1459
+ );
1460
+ }
1461
+ if (_optionalChain([data, 'access', _57 => _57.media, 'optionalAccess', _58 => _58.playback, 'optionalAccess', _59 => _59.maxPlays]) !== void 0) {
1462
+ report(
1463
+ ["slowMedia"],
1464
+ data.slowMedia,
1465
+ "A play budget on `media` cannot coexist with an unbudgeted slow recording of the same content. Drop `slowMedia`, or drop `maxPlays`."
1466
+ );
1467
+ }
1468
+ if (typeof data.slowMedia.url === "string" && typeof _optionalChain([data, 'access', _60 => _60.media, 'optionalAccess', _61 => _61.url]) === "string" && data.slowMedia.url === data.media.url) {
1469
+ report(
1470
+ ["slowMedia", "url"],
1471
+ data.slowMedia.url,
1472
+ "The slow model recording must be a different file from the recording."
1473
+ );
1474
+ }
1475
+ }
1476
+ if (!refused.has("scoring")) {
1477
+ const dimensions = data.scoring.dimensions;
1478
+ const seen = /* @__PURE__ */ new Set();
1479
+ for (const [index, dimension] of dimensions.entries()) {
1480
+ if (seen.has(dimension.name)) {
1481
+ report(
1482
+ ["scoring", "dimensions", index, "name"],
1483
+ dimension.name,
1484
+ `"${dimension.name}" is already weighed: a dimension counted twice hides which weight the grade used.`
1485
+ );
1486
+ }
1487
+ seen.add(dimension.name);
1488
+ }
1489
+ if (dimensions.every((dimension) => dimension.weight === 0)) {
1490
+ report(
1491
+ ["scoring", "dimensions"],
1492
+ dimensions,
1493
+ "At least one dimension must carry a weight above 0: with every weight at 0 there is no weighted total, and every take would be unscorable."
1494
+ );
1495
+ }
1496
+ }
1497
+ if (!refused.has("recording")) {
1498
+ const { minSeconds, maxSeconds } = data.recording;
1499
+ if (minSeconds !== void 0 && minSeconds >= maxSeconds) {
1500
+ report(
1501
+ ["recording", "minSeconds"],
1502
+ minSeconds,
1503
+ "The shortest take must be shorter than the longest."
1504
+ );
1505
+ }
1506
+ }
1507
+ })
1508
+ );
1509
+
1344
1510
  // src/count-words.ts
1345
1511
  function countWords(text) {
1346
1512
  if (typeof text !== "string") {
@@ -1377,7 +1543,7 @@ function resolveChoices(gap, banks) {
1377
1543
  if (gap.bankId === void 0) {
1378
1544
  return void 0;
1379
1545
  }
1380
- return _optionalChain([banks, 'access', _53 => _53.find, 'call', _54 => _54((bank) => bank.id === gap.bankId), 'optionalAccess', _55 => _55.choices]);
1546
+ return _optionalChain([banks, 'access', _62 => _62.find, 'call', _63 => _63((bank) => bank.id === gap.bankId), 'optionalAccess', _64 => _64.choices]);
1381
1547
  }
1382
1548
  function placeholderCounts(passage) {
1383
1549
  const counts = /* @__PURE__ */ new Map();
@@ -1591,7 +1757,7 @@ var RedactedDictationDataSchema = _v4.z.strictObject({
1591
1757
  hints: _v4.z.strictObject({ mode: _v4.z.literal("progressive-words") }).optional()
1592
1758
  }).check((ctx) => {
1593
1759
  const data = ctx.value;
1594
- if (_optionalChain([data, 'access', _56 => _56.media, 'optionalAccess', _57 => _57.captionsUrl]) !== void 0) {
1760
+ if (_optionalChain([data, 'access', _65 => _65.media, 'optionalAccess', _66 => _66.captionsUrl]) !== void 0) {
1595
1761
  ctx.issues.push({
1596
1762
  code: "custom",
1597
1763
  input: data.media.captionsUrl,
@@ -1599,7 +1765,7 @@ var RedactedDictationDataSchema = _v4.z.strictObject({
1599
1765
  path: ["media", "captionsUrl"]
1600
1766
  });
1601
1767
  }
1602
- if (data.slowMedia !== void 0 && _optionalChain([data, 'access', _58 => _58.media, 'optionalAccess', _59 => _59.playback, 'optionalAccess', _60 => _60.maxPlays]) !== void 0) {
1768
+ if (data.slowMedia !== void 0 && _optionalChain([data, 'access', _67 => _67.media, 'optionalAccess', _68 => _68.playback, 'optionalAccess', _69 => _69.maxPlays]) !== void 0) {
1603
1769
  ctx.issues.push({
1604
1770
  code: "custom",
1605
1771
  input: data.slowMedia,
@@ -1616,6 +1782,61 @@ var RedactedDictationDataSchema = _v4.z.strictObject({
1616
1782
  });
1617
1783
  }
1618
1784
  });
1785
+ var RedactedReadAloudDataSchema = _v4.z.strictObject({
1786
+ ...redactedBase,
1787
+ type: _v4.z.literal("read-aloud"),
1788
+ locale: _v4.z.string().regex(CANONICAL_LOCALE_RE),
1789
+ instructions: _v4.z.string().optional(),
1790
+ referenceText: _v4.z.string().min(1),
1791
+ slowMedia: ReadAloudSlowMediaSchema.optional(),
1792
+ recording: _v4.z.strictObject({
1793
+ maxSeconds: _v4.z.number().gt(0).max(READ_ALOUD_MAX_SECONDS),
1794
+ minSeconds: _v4.z.number().min(0).optional(),
1795
+ maxTakes: _v4.z.number().int().min(1).max(READ_ALOUD_MAX_TAKES).optional()
1796
+ }),
1797
+ scoring: _v4.z.strictObject({
1798
+ dimensions: _v4.z.array(
1799
+ _v4.z.strictObject({
1800
+ name: _v4.z.enum(READ_ALOUD_DIMENSIONS),
1801
+ weight: _v4.z.number().min(0).max(READ_ALOUD_MAX_DIMENSION_WEIGHT)
1802
+ })
1803
+ ).min(1).max(READ_ALOUD_DIMENSIONS.length)
1804
+ })
1805
+ }).check((ctx) => {
1806
+ const data = ctx.value;
1807
+ if (data.media !== void 0 && data.media.type !== "audio") {
1808
+ ctx.issues.push({
1809
+ code: "custom",
1810
+ input: data.media.type,
1811
+ message: "A read-aloud model recording must be audio, so this payload is not renderable.",
1812
+ path: ["media", "type"]
1813
+ });
1814
+ }
1815
+ if (data.slowMedia !== void 0 && data.media === void 0) {
1816
+ ctx.issues.push({
1817
+ code: "custom",
1818
+ input: data.slowMedia,
1819
+ message: "A slow model recording accompanies a recording: this payload has no `media`.",
1820
+ path: ["media"]
1821
+ });
1822
+ }
1823
+ if (data.slowMedia !== void 0 && _optionalChain([data, 'access', _70 => _70.media, 'optionalAccess', _71 => _71.playback, 'optionalAccess', _72 => _72.maxPlays]) !== void 0) {
1824
+ ctx.issues.push({
1825
+ code: "custom",
1826
+ input: data.slowMedia,
1827
+ message: "A play budget on `media` cannot coexist with an unbudgeted slow recording of the same content.",
1828
+ path: ["slowMedia"]
1829
+ });
1830
+ }
1831
+ if (data.slowMedia !== void 0 && data.slowMedia.url === _optionalChain([data, 'access', _73 => _73.media, 'optionalAccess', _74 => _74.url])) {
1832
+ ctx.issues.push({
1833
+ code: "custom",
1834
+ input: data.slowMedia.url,
1835
+ message: "The slow model recording must be a different file from the recording.",
1836
+ path: ["slowMedia", "url"]
1837
+ });
1838
+ }
1839
+ });
1619
1840
 
1620
1841
  // src/scoring/dictation/edit-distance.ts
1621
1842
  function codePoints(text) {
@@ -2037,7 +2258,27 @@ var DRAFT_ISSUE_SEVERITY = {
2037
2258
  dc_hints_mode_invalid: "invalid",
2038
2259
  dc_equivalence_from_required: "incomplete",
2039
2260
  dc_equivalence_to_required: "incomplete",
2040
- dc_tolerance_invalid: "invalid"
2261
+ dc_tolerance_invalid: "invalid",
2262
+ // read-aloud
2263
+ ra_reference_text_required: "incomplete",
2264
+ ra_reference_text_too_long: "invalid",
2265
+ ra_reference_text_unreadable: "invalid",
2266
+ ra_reference_text_unspaced_script: "invalid",
2267
+ ra_locale_required: "incomplete",
2268
+ ra_locale_invalid: "invalid",
2269
+ ra_max_seconds_required: "incomplete",
2270
+ ra_max_seconds_out_of_range: "invalid",
2271
+ ra_min_seconds_out_of_range: "invalid",
2272
+ ra_max_takes_out_of_range: "invalid",
2273
+ ra_dimensions_required: "incomplete",
2274
+ ra_dimension_name_invalid: "invalid",
2275
+ ra_dimension_duplicate: "invalid",
2276
+ ra_dimension_weight_invalid: "invalid",
2277
+ ra_dimension_weights_zero: "invalid",
2278
+ ra_media_kind: "invalid",
2279
+ ra_slow_media_without_media: "incomplete",
2280
+ ra_slow_media_same_recording: "invalid",
2281
+ ra_slow_media_beside_play_limit: "invalid"
2041
2282
  };
2042
2283
  function issue(code, path, message) {
2043
2284
  return { path: path.map(String), message, code, severity: DRAFT_ISSUE_SEVERITY[code] };
@@ -3178,6 +3419,283 @@ function checkOptionMedia(media, index, ordinal) {
3178
3419
  return checkMedia(media, path, MultipleChoiceOptionMediaSchema);
3179
3420
  }
3180
3421
 
3422
+ // src/authoring/read-aloud.ts
3423
+ var readAloudAuthoring = {
3424
+ createDraft: ({ newId }) => ({
3425
+ schemaVersion: "1.0",
3426
+ type: "read-aloud",
3427
+ id: newId(),
3428
+ title: "",
3429
+ referenceText: "",
3430
+ locale: "",
3431
+ recording: { maxSeconds: 0 },
3432
+ scoring: { dimensions: [] }
3433
+ }),
3434
+ checkDraft: checkReadAloudDraft
3435
+ };
3436
+ function checkReadAloudDraft(draft) {
3437
+ const issues = checkIdentity(draft, "read-aloud");
3438
+ issues.push(...checkReferenceText(draft.referenceText));
3439
+ issues.push(...checkLocale(draft.locale));
3440
+ issues.push(...checkRecording2(draft.recording));
3441
+ issues.push(...checkDimensions(draft.scoring));
3442
+ issues.push(...checkModelRecording(draft.media));
3443
+ issues.push(...checkSlowRecording2(draft));
3444
+ issues.push(...checkSharedOptional(draft));
3445
+ return issues;
3446
+ }
3447
+ function checkReferenceText(referenceText) {
3448
+ if (isUnwritten(referenceText)) {
3449
+ return [
3450
+ issue("ra_reference_text_required", ["referenceText"], "Write the text to be read aloud.")
3451
+ ];
3452
+ }
3453
+ if (typeof referenceText !== "string") {
3454
+ return [];
3455
+ }
3456
+ const issues = [];
3457
+ const measured = dictationNormalizer(void 0).measure(referenceText);
3458
+ if (measured.tooLong) {
3459
+ issues.push(
3460
+ issue(
3461
+ "ra_reference_text_too_long",
3462
+ ["referenceText"],
3463
+ `The text is longer than ${READ_ALOUD_MAX_REFERENCE_LENGTH} characters, before or after normalisation. A read-aloud item is a sentence or a short paragraph.`
3464
+ )
3465
+ );
3466
+ }
3467
+ if (measured.normalized === "") {
3468
+ issues.push(
3469
+ issue(
3470
+ "ra_reference_text_unreadable",
3471
+ ["referenceText"],
3472
+ "The text has no word to read: once punctuation and spacing are ignored, nothing is left. A reading of it would be marked against no word at all."
3473
+ )
3474
+ );
3475
+ }
3476
+ if (containsUnspacedScript(referenceText)) {
3477
+ issues.push(
3478
+ issue(
3479
+ "ra_reference_text_unspaced_script",
3480
+ ["referenceText"],
3481
+ "The text is written in a script that does not separate its words with spaces. Each word is marked on its own, and a run of Han, kana, Thai, Lao, Khmer or Myanmar letters would be marked as one word."
3482
+ )
3483
+ );
3484
+ }
3485
+ return issues;
3486
+ }
3487
+ function checkLocale(locale) {
3488
+ if (isUnwritten(locale)) {
3489
+ return [
3490
+ issue(
3491
+ "ra_locale_required",
3492
+ ["locale"],
3493
+ 'Choose the language the learner reads in, with its region \u2014 "en-US", not "en".'
3494
+ )
3495
+ ];
3496
+ }
3497
+ if (typeof locale !== "string" || CANONICAL_LOCALE_RE.test(locale)) {
3498
+ return [];
3499
+ }
3500
+ return [
3501
+ issue(
3502
+ "ra_locale_invalid",
3503
+ ["locale"],
3504
+ `The language must be a BCP 47 tag in canonical form, with a region: "en-US", "es-419", "zh-Hant-TW". Pronunciation is assessed against one locale's speech.`
3505
+ )
3506
+ ];
3507
+ }
3508
+ function checkRecording2(recording) {
3509
+ if (isUnset(recording)) {
3510
+ return [maxSecondsRequired()];
3511
+ }
3512
+ if (!isRecord(recording)) {
3513
+ return [];
3514
+ }
3515
+ const issues = [];
3516
+ const max = recording.maxSeconds;
3517
+ if (isUnset(max) || max === 0) {
3518
+ issues.push(maxSecondsRequired());
3519
+ } else if (typeof max === "number" && !(Number.isFinite(max) && max > 0 && max <= READ_ALOUD_MAX_SECONDS)) {
3520
+ issues.push(
3521
+ issue(
3522
+ "ra_max_seconds_out_of_range",
3523
+ ["recording", "maxSeconds"],
3524
+ `A take is at most ${READ_ALOUD_MAX_SECONDS} seconds long.`
3525
+ )
3526
+ );
3527
+ }
3528
+ const min = recording.minSeconds;
3529
+ if (typeof min === "number" && !(Number.isFinite(min) && min >= 0)) {
3530
+ issues.push(minSecondsOutOfRange("The shortest take is a number of seconds, 0 or more."));
3531
+ } else if (typeof min === "number" && typeof max === "number" && max > 0 && min >= max) {
3532
+ issues.push(minSecondsOutOfRange("The shortest take must be shorter than the longest."));
3533
+ }
3534
+ const takes = recording.maxTakes;
3535
+ if (typeof takes === "number" && !(isWholeNumber(takes) && takes >= 1 && takes <= READ_ALOUD_MAX_TAKES)) {
3536
+ issues.push(
3537
+ issue(
3538
+ "ra_max_takes_out_of_range",
3539
+ ["recording", "maxTakes"],
3540
+ `How many takes a learner may record is a whole number from 1 to ${READ_ALOUD_MAX_TAKES}.`
3541
+ )
3542
+ );
3543
+ }
3544
+ return issues;
3545
+ }
3546
+ function maxSecondsRequired() {
3547
+ return issue(
3548
+ "ra_max_seconds_required",
3549
+ ["recording", "maxSeconds"],
3550
+ "Set how long a take may be, in seconds."
3551
+ );
3552
+ }
3553
+ function minSecondsOutOfRange(message) {
3554
+ return issue("ra_min_seconds_out_of_range", ["recording", "minSeconds"], message);
3555
+ }
3556
+ var DIMENSION_NAMES = READ_ALOUD_DIMENSIONS;
3557
+ function checkDimensions(scoring) {
3558
+ if (isUnset(scoring)) {
3559
+ return [dimensionsRequired()];
3560
+ }
3561
+ if (!isRecord(scoring)) {
3562
+ return [];
3563
+ }
3564
+ const dimensions = scoring.dimensions;
3565
+ if (isUnset(dimensions)) {
3566
+ return [dimensionsRequired()];
3567
+ }
3568
+ if (!Array.isArray(dimensions)) {
3569
+ return [];
3570
+ }
3571
+ if (dimensions.length === 0) {
3572
+ return [dimensionsRequired()];
3573
+ }
3574
+ const issues = [];
3575
+ const seen = /* @__PURE__ */ new Set();
3576
+ let everyWeightUsable = true;
3577
+ let totalWeight = 0;
3578
+ for (const [index, dimension] of dimensions.entries()) {
3579
+ if (!isRecord(dimension)) {
3580
+ everyWeightUsable = false;
3581
+ continue;
3582
+ }
3583
+ const path = ["scoring", "dimensions", index];
3584
+ const name = dimension.name;
3585
+ if (!DIMENSION_NAMES.includes(name)) {
3586
+ issues.push(
3587
+ issue(
3588
+ "ra_dimension_name_invalid",
3589
+ [...path, "name"],
3590
+ `Choose what dimension ${index + 1} measures: ${READ_ALOUD_DIMENSIONS.join(", ")}.`
3591
+ )
3592
+ );
3593
+ } else if (seen.has(name)) {
3594
+ issues.push(
3595
+ issue(
3596
+ "ra_dimension_duplicate",
3597
+ [...path, "name"],
3598
+ `"${String(name)}" is already weighed. Remove this one, or measure something else.`
3599
+ )
3600
+ );
3601
+ } else {
3602
+ seen.add(name);
3603
+ }
3604
+ const weight = dimension.weight;
3605
+ if (typeof weight === "number" && Number.isFinite(weight) && weight >= 0 && weight <= READ_ALOUD_MAX_DIMENSION_WEIGHT) {
3606
+ totalWeight += weight;
3607
+ } else {
3608
+ everyWeightUsable = false;
3609
+ issues.push(
3610
+ issue(
3611
+ "ra_dimension_weight_invalid",
3612
+ [...path, "weight"],
3613
+ `Give dimension ${index + 1} a weight: a number from 0 to ${READ_ALOUD_MAX_DIMENSION_WEIGHT}.`
3614
+ )
3615
+ );
3616
+ }
3617
+ }
3618
+ if (everyWeightUsable && totalWeight === 0) {
3619
+ issues.push(
3620
+ issue(
3621
+ "ra_dimension_weights_zero",
3622
+ ["scoring", "dimensions"],
3623
+ "Give at least one dimension a weight above 0. With every weight at 0 there is no weighted total, and every take would be unscorable."
3624
+ )
3625
+ );
3626
+ }
3627
+ return issues;
3628
+ }
3629
+ function dimensionsRequired() {
3630
+ return issue(
3631
+ "ra_dimensions_required",
3632
+ ["scoring", "dimensions"],
3633
+ "Choose what the grade measures: at least one of accuracy, fluency, completeness or prosody, with a weight."
3634
+ );
3635
+ }
3636
+ function checkModelRecording(media) {
3637
+ if (!isRecord(media)) {
3638
+ return [];
3639
+ }
3640
+ const kind = media.type;
3641
+ return isUnwritten(kind) || kind === "audio" ? [] : [
3642
+ issue(
3643
+ "ra_media_kind",
3644
+ ["media", "type"],
3645
+ "A read-aloud model is read aloud: its recording must be audio."
3646
+ )
3647
+ ];
3648
+ }
3649
+ function checkSlowRecording2(draft) {
3650
+ const slow = draft.slowMedia;
3651
+ if (!isRecord(slow)) {
3652
+ return [];
3653
+ }
3654
+ const kind = slow.type;
3655
+ const wrongKind = !isUnwritten(kind) && kind !== "audio";
3656
+ const issues = wrongKind ? [issue("media_invalid", ["slowMedia", "type"], "The slow model recording must be audio.")] : [];
3657
+ issues.push(
3658
+ ...checkMedia(
3659
+ wrongKind ? { ...slow, type: "audio" } : slow,
3660
+ ["slowMedia"],
3661
+ ReadAloudSlowMediaSchema
3662
+ )
3663
+ );
3664
+ const media = draft.media;
3665
+ if (isUnset(media)) {
3666
+ issues.push(
3667
+ issue(
3668
+ "ra_slow_media_without_media",
3669
+ ["media"],
3670
+ "A slow model recording accompanies a recording. Add the recording first."
3671
+ )
3672
+ );
3673
+ return issues;
3674
+ }
3675
+ if (!isRecord(media)) {
3676
+ return issues;
3677
+ }
3678
+ if (isRecord(media.playback) && media.playback.maxPlays !== void 0) {
3679
+ issues.push(
3680
+ issue(
3681
+ "ra_slow_media_beside_play_limit",
3682
+ ["slowMedia"],
3683
+ "A play budget on the recording cannot coexist with a slow recording that has none. Remove the slow recording, or remove the play limit."
3684
+ )
3685
+ );
3686
+ }
3687
+ if (typeof slow.url === "string" && slow.url !== "" && slow.url === media.url) {
3688
+ issues.push(
3689
+ issue(
3690
+ "ra_slow_media_same_recording",
3691
+ ["slowMedia", "url"],
3692
+ "The slow model recording is the same file as the recording. Point it at the slower reading."
3693
+ )
3694
+ );
3695
+ }
3696
+ return issues;
3697
+ }
3698
+
3181
3699
  // src/authoring/written-response.ts
3182
3700
  var writtenResponseAuthoring = {
3183
3701
  createDraft: ({ newId }) => ({
@@ -3321,7 +3839,7 @@ function checkCriteria(criteria) {
3321
3839
 
3322
3840
  // src/scoring/activity-scorers/dictation.ts
3323
3841
  function scoreDictation(data, response) {
3324
- const alignment = alignDictation(data, typeof _optionalChain([response, 'optionalAccess', _61 => _61.text]) === "string" ? response.text : "");
3842
+ const alignment = alignDictation(data, typeof _optionalChain([response, 'optionalAccess', _75 => _75.text]) === "string" ? response.text : "");
3325
3843
  const details = [];
3326
3844
  for (const word of alignment.words) {
3327
3845
  if (word.status === "extra") {
@@ -3390,7 +3908,7 @@ function choicesFor(data, gap) {
3390
3908
  if (gap.choices !== void 0) {
3391
3909
  return gap.choices;
3392
3910
  }
3393
- return _nullishCoalesce(_optionalChain([data, 'access', _62 => _62.banks, 'optionalAccess', _63 => _63.find, 'call', _64 => _64((bank) => bank.id === gap.bankId), 'optionalAccess', _65 => _65.choices]), () => ( []));
3911
+ return _nullishCoalesce(_optionalChain([data, 'access', _76 => _76.banks, 'optionalAccess', _77 => _77.find, 'call', _78 => _78((bank) => bank.id === gap.bankId), 'optionalAccess', _79 => _79.choices]), () => ( []));
3394
3912
  }
3395
3913
  function scoreGapSelect(data, response) {
3396
3914
  const details = [];
@@ -3426,7 +3944,7 @@ function scoreMultipleChoice(data, response) {
3426
3944
  let scoreValue;
3427
3945
  if (data.scoringStrategy === "all-or-nothing") {
3428
3946
  if (data.mode === "single") {
3429
- scoreValue = response.selectedOptionIds.length === 1 && _optionalChain([optionById, 'access', _66 => _66.get, 'call', _67 => _67(response.selectedOptionIds[0]), 'optionalAccess', _68 => _68.isCorrect]) === true ? 1 : 0;
3947
+ scoreValue = response.selectedOptionIds.length === 1 && _optionalChain([optionById, 'access', _80 => _80.get, 'call', _81 => _81(response.selectedOptionIds[0]), 'optionalAccess', _82 => _82.isCorrect]) === true ? 1 : 0;
3430
3948
  } else {
3431
3949
  const correctIds = data.options.filter((o) => o.isCorrect).map((o) => o.id);
3432
3950
  const allCorrectSelected = correctIds.every((id) => selected.has(id));
@@ -3437,7 +3955,7 @@ function scoreMultipleChoice(data, response) {
3437
3955
  let incorrectSelected = 0;
3438
3956
  for (const id of selected) {
3439
3957
  const option = optionById.get(id);
3440
- if (_optionalChain([option, 'optionalAccess', _69 => _69.isCorrect])) {
3958
+ if (_optionalChain([option, 'optionalAccess', _83 => _83.isCorrect])) {
3441
3959
  correctSelected += 1;
3442
3960
  } else {
3443
3961
  incorrectSelected += 1;
@@ -3608,7 +4126,7 @@ var multipleChoiceType = defineActivityType({
3608
4126
  // exact optionals. Structurally identical at runtime — cast is type-level only.
3609
4127
  schema: MultipleChoiceDataSchema,
3610
4128
  scoring: { kind: "sync", score: scoreMultipleChoice },
3611
- isAnswered: (response) => (_nullishCoalesce(_optionalChain([response, 'optionalAccess', _70 => _70.selectedOptionIds, 'access', _71 => _71.length]), () => ( 0))) > 0,
4129
+ isAnswered: (response) => (_nullishCoalesce(_optionalChain([response, 'optionalAccess', _84 => _84.selectedOptionIds, 'access', _85 => _85.length]), () => ( 0))) > 0,
3612
4130
  fieldPolicy: MULTIPLE_CHOICE_FIELD_POLICY,
3613
4131
  redactedSchema: RedactedMultipleChoiceDataSchema,
3614
4132
  interop: {
@@ -3625,7 +4143,7 @@ var fillInTheBlanksType = defineActivityType({
3625
4143
  type: "fill-in-the-blanks",
3626
4144
  schema: FillInTheBlanksDataSchema,
3627
4145
  scoring: { kind: "sync", score: scoreFillInTheBlanks },
3628
- isAnswered: (response) => Object.values(_nullishCoalesce(_optionalChain([response, 'optionalAccess', _72 => _72.answers]), () => ( {}))).some((answer) => answer.trim().length > 0),
4146
+ isAnswered: (response) => Object.values(_nullishCoalesce(_optionalChain([response, 'optionalAccess', _86 => _86.answers]), () => ( {}))).some((answer) => answer.trim().length > 0),
3629
4147
  fieldPolicy: FILL_IN_THE_BLANKS_FIELD_POLICY,
3630
4148
  redactedSchema: RedactedFillInTheBlanksDataSchema,
3631
4149
  interop: {
@@ -3648,14 +4166,14 @@ var writtenResponseType = defineActivityType({
3648
4166
  kind: "deferred",
3649
4167
  reason: "requires_async_grading",
3650
4168
  partial: (data, response) => {
3651
- const wordCount = countWords(_nullishCoalesce(_optionalChain([response, 'optionalAccess', _73 => _73.text]), () => ( "")));
4169
+ const wordCount = countWords(_nullishCoalesce(_optionalChain([response, 'optionalAccess', _87 => _87.text]), () => ( "")));
3652
4170
  return {
3653
4171
  withinWordBounds: response !== void 0 && wordCount >= data.minWords && wordCount <= data.maxWords,
3654
4172
  wordCount
3655
4173
  };
3656
4174
  }
3657
4175
  },
3658
- isAnswered: (response) => (_nullishCoalesce(_optionalChain([response, 'optionalAccess', _74 => _74.text, 'access', _75 => _75.trim, 'call', _76 => _76(), 'access', _77 => _77.length]), () => ( 0))) > 0,
4176
+ isAnswered: (response) => (_nullishCoalesce(_optionalChain([response, 'optionalAccess', _88 => _88.text, 'access', _89 => _89.trim, 'call', _90 => _90(), 'access', _91 => _91.length]), () => ( 0))) > 0,
3659
4177
  fieldPolicy: WRITTEN_RESPONSE_FIELD_POLICY,
3660
4178
  redactedSchema: RedactedWrittenResponseDataSchema,
3661
4179
  interop: {
@@ -3670,7 +4188,7 @@ var gapSelectType = defineActivityType({
3670
4188
  type: "gap-select",
3671
4189
  schema: GapSelectDataSchema,
3672
4190
  scoring: { kind: "sync", score: scoreGapSelect },
3673
- isAnswered: (response) => Object.values(_nullishCoalesce(_optionalChain([response, 'optionalAccess', _78 => _78.selections]), () => ( {}))).some((choiceId) => choiceId !== ""),
4191
+ isAnswered: (response) => Object.values(_nullishCoalesce(_optionalChain([response, 'optionalAccess', _92 => _92.selections]), () => ( {}))).some((choiceId) => choiceId !== ""),
3674
4192
  fieldPolicy: GAP_SELECT_FIELD_POLICY,
3675
4193
  redactedSchema: RedactedGapSelectDataSchema,
3676
4194
  interop: {
@@ -3701,7 +4219,7 @@ var dictationType = defineActivityType({
3701
4219
  // cut where the scorer cuts, so text past the cap never counts as an answer.
3702
4220
  isAnswered: (response) => normalizeDictationText(
3703
4221
  truncateCodePoints(
3704
- typeof _optionalChain([response, 'optionalAccess', _79 => _79.text]) === "string" ? response.text : "",
4222
+ typeof _optionalChain([response, 'optionalAccess', _93 => _93.text]) === "string" ? response.text : "",
3705
4223
  DICTATION_MAX_TEXT_LENGTH
3706
4224
  )
3707
4225
  ) !== "",
@@ -3717,11 +4235,61 @@ var dictationType = defineActivityType({
3717
4235
  interactions: ["text-changed", "hint-requested", "submitted"],
3718
4236
  authoring: dictationAuthoring
3719
4237
  });
4238
+ var READ_ALOUD_FIELD_POLICY = {
4239
+ ...SHARED_PUBLIC_FIELDS,
4240
+ instructions: "public",
4241
+ referenceText: "public",
4242
+ recording: { maxSeconds: "public", minSeconds: "public", maxTakes: "public" },
4243
+ slowMedia: { type: "public", url: "public", alt: "public" },
4244
+ scoring: { dimensions: { name: "public", weight: "public" } },
4245
+ feedback: FEEDBACK_FIELD_POLICY
4246
+ };
4247
+ function hasRecording(response) {
4248
+ const recording = _optionalChain([response, 'optionalAccess', _94 => _94.recording]);
4249
+ return typeof recording === "object" && recording !== null && typeof recording.key === "string" && recording.key !== "";
4250
+ }
4251
+ var readAloudType = defineActivityType({
4252
+ type: "read-aloud",
4253
+ schema: ReadAloudDataSchema,
4254
+ scoring: {
4255
+ kind: "deferred",
4256
+ reason: "requires_async_grading",
4257
+ partial: (_data, response) => ({ hasRecording: hasRecording(response) })
4258
+ },
4259
+ isAnswered: (response) => hasRecording(response),
4260
+ fieldPolicy: READ_ALOUD_FIELD_POLICY,
4261
+ redactedSchema: RedactedReadAloudDataSchema,
4262
+ interop: {
4263
+ xapiActivityTypeIri: "http://adlnet.gov/expapi/activities/cmi.interaction",
4264
+ // `other`, not `performance`: xAPI's performance interaction describes a set
4265
+ // of steps with their own responses, and a reading has one. There is no
4266
+ // pattern to publish either — the "correct response" is a pronunciation, not
4267
+ // a string a statement can carry.
4268
+ xapiInteractionType: "other",
4269
+ correctResponsesPattern: () => []
4270
+ },
4271
+ interactions: ["recording-started", "recording-stopped", "recording-uploaded", "submitted"],
4272
+ authoring: readAloudAuthoring
4273
+ });
3720
4274
  registerActivityType(multipleChoiceType);
3721
4275
  registerActivityType(fillInTheBlanksType);
3722
4276
  registerActivityType(writtenResponseType);
3723
4277
  registerActivityType(gapSelectType);
3724
4278
  registerActivityType(dictationType);
4279
+ registerActivityType(readAloudType);
4280
+
4281
+
4282
+
4283
+
4284
+
4285
+
4286
+
4287
+
4288
+
4289
+
4290
+
4291
+
4292
+
3725
4293
 
3726
4294
 
3727
4295
 
@@ -3799,5 +4367,5 @@ registerActivityType(dictationType);
3799
4367
 
3800
4368
 
3801
4369
 
3802
- exports.ActivitySchemaError = ActivitySchemaError; exports.UnknownActivityTypeError = UnknownActivityTypeError; exports.RedactedScoringError = RedactedScoringError; exports.DeferredScoringError = DeferredScoringError; exports.withValidationScope = withValidationScope; exports.DICTATION_MAX_TRANSCRIPT_LENGTH = DICTATION_MAX_TRANSCRIPT_LENGTH; exports.DICTATION_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH; exports.DICTATION_MAX_EQUIVALENCE_LENGTH = DICTATION_MAX_EQUIVALENCE_LENGTH; exports.DICTATION_MAX_EQUIVALENCES = DICTATION_MAX_EQUIVALENCES; exports.DICTATION_MAX_ACCEPTED_TRANSCRIPTS = DICTATION_MAX_ACCEPTED_TRANSCRIPTS; exports.FeedbackSchema = FeedbackSchema; exports.MediaUrlSchema = MediaUrlSchema; exports.NativeControlHintSchema = NativeControlHintSchema; exports.MediaPlaybackSchema = MediaPlaybackSchema; exports.MediaSchema = MediaSchema; exports.RedactedMediaSchema = RedactedMediaSchema; exports.DictationSlowMediaSchema = DictationSlowMediaSchema; exports.DictationEquivalenceSchema = DictationEquivalenceSchema; exports.DictationToleranceSchema = DictationToleranceSchema; exports.DictationDataSchema = DictationDataSchema; exports.groupCaptionsRevealDictation = groupCaptionsRevealDictation; exports.GROUP_CAPTIONS_REVEAL_DICTATION = GROUP_CAPTIONS_REVEAL_DICTATION; exports.DRAFT_ISSUE_SEVERITY = DRAFT_ISSUE_SEVERITY; exports.issue = issue; exports.isRecord = isRecord; exports.refusesEmpty = refusesEmpty; exports.isUnset = isUnset; exports.isUnwritten = isUnwritten; exports.isMissingId = isMissingId; exports.checkMedia = checkMedia; exports.covers = covers; exports.pathKey = pathKey; exports.coveredPathsOf = coveredPathsOf; exports.TextMatchPolicySchema = TextMatchPolicySchema; exports.BlankConfigSchema = BlankConfigSchema; exports.FillInTheBlanksDataSchema = FillInTheBlanksDataSchema; exports.MultipleChoiceOptionMediaSchema = MultipleChoiceOptionMediaSchema; exports.MultipleChoiceOptionSchema = MultipleChoiceOptionSchema; exports.MultipleChoiceDataSchema = MultipleChoiceDataSchema; exports.countWords = countWords; exports.GapSelectChoiceSchema = GapSelectChoiceSchema; exports.GapSelectBankSchema = GapSelectBankSchema; exports.GapSelectGapSchema = GapSelectGapSchema; exports.GapSelectDataSchema = GapSelectDataSchema; exports.WrittenResponseRubricCriterionSchema = WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = WrittenResponseRubricSchema; exports.WrittenResponseDataSchema = WrittenResponseDataSchema; exports.RedactedMultipleChoiceOptionMediaSchema = RedactedMultipleChoiceOptionMediaSchema; exports.RedactedMultipleChoiceOptionSchema = RedactedMultipleChoiceOptionSchema; exports.RedactedMultipleChoiceDataSchema = RedactedMultipleChoiceDataSchema; exports.RedactedBlankConfigSchema = RedactedBlankConfigSchema; exports.RedactedFillInTheBlanksDataSchema = RedactedFillInTheBlanksDataSchema; exports.RedactedGapSelectChoiceSchema = RedactedGapSelectChoiceSchema; exports.RedactedGapSelectBankSchema = RedactedGapSelectBankSchema; exports.RedactedGapSelectGapSchema = RedactedGapSelectGapSchema; exports.RedactedGapSelectDataSchema = RedactedGapSelectDataSchema; exports.RedactedWrittenResponseDataSchema = RedactedWrittenResponseDataSchema; exports.RedactedDictationSlowMediaSchema = RedactedDictationSlowMediaSchema; exports.RedactedDictationDataSchema = RedactedDictationDataSchema; exports.dictationReferenceWords = dictationReferenceWords; exports.alignDictation = alignDictation; exports.STEP = STEP; exports.alignSequences = alignSequences; exports.levenshteinDistance = levenshteinDistance; exports.matchText = matchText; exports.defineActivityType = defineActivityType; exports.registerActivityType = registerActivityType; exports.getActivityTypeDescriptor = getActivityTypeDescriptor; exports.registeredActivityTypes = registeredActivityTypes; exports.MEDIA_FIELD_POLICY = MEDIA_FIELD_POLICY; exports.multipleChoiceType = multipleChoiceType; exports.fillInTheBlanksType = fillInTheBlanksType; exports.writtenResponseType = writtenResponseType; exports.gapSelectType = gapSelectType; exports.dictationType = dictationType;
3803
- //# sourceMappingURL=chunk-XONKWL6D.cjs.map
4370
+ exports.ActivitySchemaError = ActivitySchemaError; exports.UnknownActivityTypeError = UnknownActivityTypeError; exports.RedactedScoringError = RedactedScoringError; exports.DeferredScoringError = DeferredScoringError; exports.withValidationScope = withValidationScope; exports.DICTATION_MAX_TRANSCRIPT_LENGTH = DICTATION_MAX_TRANSCRIPT_LENGTH; exports.DICTATION_MAX_TEXT_LENGTH = DICTATION_MAX_TEXT_LENGTH; exports.DICTATION_MAX_EQUIVALENCE_LENGTH = DICTATION_MAX_EQUIVALENCE_LENGTH; exports.DICTATION_MAX_EQUIVALENCES = DICTATION_MAX_EQUIVALENCES; exports.DICTATION_MAX_ACCEPTED_TRANSCRIPTS = DICTATION_MAX_ACCEPTED_TRANSCRIPTS; exports.codePointLength = codePointLength; exports.normalizeDictationText = normalizeDictationText; exports.FeedbackSchema = FeedbackSchema; exports.MediaUrlSchema = MediaUrlSchema; exports.NativeControlHintSchema = NativeControlHintSchema; exports.MediaPlaybackSchema = MediaPlaybackSchema; exports.MediaSchema = MediaSchema; exports.RedactedMediaSchema = RedactedMediaSchema; exports.DictationSlowMediaSchema = DictationSlowMediaSchema; exports.DictationEquivalenceSchema = DictationEquivalenceSchema; exports.DictationToleranceSchema = DictationToleranceSchema; exports.DictationDataSchema = DictationDataSchema; exports.groupCaptionsRevealDictation = groupCaptionsRevealDictation; exports.GROUP_CAPTIONS_REVEAL_DICTATION = GROUP_CAPTIONS_REVEAL_DICTATION; exports.DRAFT_ISSUE_SEVERITY = DRAFT_ISSUE_SEVERITY; exports.issue = issue; exports.isRecord = isRecord; exports.refusesEmpty = refusesEmpty; exports.isUnset = isUnset; exports.isUnwritten = isUnwritten; exports.isMissingId = isMissingId; exports.checkMedia = checkMedia; exports.covers = covers; exports.pathKey = pathKey; exports.coveredPathsOf = coveredPathsOf; exports.TextMatchPolicySchema = TextMatchPolicySchema; exports.BlankConfigSchema = BlankConfigSchema; exports.FillInTheBlanksDataSchema = FillInTheBlanksDataSchema; exports.MultipleChoiceOptionMediaSchema = MultipleChoiceOptionMediaSchema; exports.MultipleChoiceOptionSchema = MultipleChoiceOptionSchema; exports.MultipleChoiceDataSchema = MultipleChoiceDataSchema; exports.READ_ALOUD_MAX_REFERENCE_LENGTH = READ_ALOUD_MAX_REFERENCE_LENGTH; exports.READ_ALOUD_MAX_SECONDS = READ_ALOUD_MAX_SECONDS; exports.READ_ALOUD_MAX_TAKES = READ_ALOUD_MAX_TAKES; exports.READ_ALOUD_MAX_DIMENSION_WEIGHT = READ_ALOUD_MAX_DIMENSION_WEIGHT; exports.SPEECH_ASSESSMENT_MAX_WORDS = SPEECH_ASSESSMENT_MAX_WORDS; exports.SPEECH_ASSESSMENT_MAX_TEXT_LENGTH = SPEECH_ASSESSMENT_MAX_TEXT_LENGTH; exports.CANONICAL_LOCALE_RE = CANONICAL_LOCALE_RE; exports.ReadAloudSlowMediaSchema = ReadAloudSlowMediaSchema; exports.ReadAloudDataSchema = ReadAloudDataSchema; exports.countWords = countWords; exports.GapSelectChoiceSchema = GapSelectChoiceSchema; exports.GapSelectBankSchema = GapSelectBankSchema; exports.GapSelectGapSchema = GapSelectGapSchema; exports.GapSelectDataSchema = GapSelectDataSchema; exports.WrittenResponseRubricCriterionSchema = WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = WrittenResponseRubricSchema; exports.WrittenResponseDataSchema = WrittenResponseDataSchema; exports.RedactedMultipleChoiceOptionMediaSchema = RedactedMultipleChoiceOptionMediaSchema; exports.RedactedMultipleChoiceOptionSchema = RedactedMultipleChoiceOptionSchema; exports.RedactedMultipleChoiceDataSchema = RedactedMultipleChoiceDataSchema; exports.RedactedBlankConfigSchema = RedactedBlankConfigSchema; exports.RedactedFillInTheBlanksDataSchema = RedactedFillInTheBlanksDataSchema; exports.RedactedGapSelectChoiceSchema = RedactedGapSelectChoiceSchema; exports.RedactedGapSelectBankSchema = RedactedGapSelectBankSchema; exports.RedactedGapSelectGapSchema = RedactedGapSelectGapSchema; exports.RedactedGapSelectDataSchema = RedactedGapSelectDataSchema; exports.RedactedWrittenResponseDataSchema = RedactedWrittenResponseDataSchema; exports.RedactedDictationSlowMediaSchema = RedactedDictationSlowMediaSchema; exports.RedactedDictationDataSchema = RedactedDictationDataSchema; exports.RedactedReadAloudDataSchema = RedactedReadAloudDataSchema; exports.dictationReferenceWords = dictationReferenceWords; exports.alignDictation = alignDictation; exports.STEP = STEP; exports.alignSequences = alignSequences; exports.levenshteinDistance = levenshteinDistance; exports.matchText = matchText; exports.defineActivityType = defineActivityType; exports.registerActivityType = registerActivityType; exports.getActivityTypeDescriptor = getActivityTypeDescriptor; exports.registeredActivityTypes = registeredActivityTypes; exports.MEDIA_FIELD_POLICY = MEDIA_FIELD_POLICY; exports.multipleChoiceType = multipleChoiceType; exports.fillInTheBlanksType = fillInTheBlanksType; exports.writtenResponseType = writtenResponseType; exports.gapSelectType = gapSelectType; exports.dictationType = dictationType; exports.readAloudType = readAloudType;
4371
+ //# sourceMappingURL=chunk-VCXIPLEW.cjs.map