@intellectif/lk-core 0.14.1 → 0.16.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 (47) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +1 -0
  3. package/dist/{activity-BVkg9VDo.d.cts → activity-DcxtpX7Z.d.cts} +39 -2
  4. package/dist/{activity-BVkg9VDo.d.ts → activity-DcxtpX7Z.d.ts} +39 -2
  5. package/dist/{chunk-J5OIRIOW.cjs → chunk-6P6XK2LI.cjs} +31 -31
  6. package/dist/{chunk-J5OIRIOW.cjs.map → chunk-6P6XK2LI.cjs.map} +1 -1
  7. package/dist/{chunk-VCXIPLEW.cjs → chunk-F7UOLKWV.cjs} +95 -25
  8. package/dist/chunk-F7UOLKWV.cjs.map +1 -0
  9. package/dist/chunk-FJJ2GVBA.cjs +420 -0
  10. package/dist/chunk-FJJ2GVBA.cjs.map +1 -0
  11. package/dist/{chunk-NBADQ3JU.js → chunk-GOZGBVJP.js} +203 -10
  12. package/dist/chunk-GOZGBVJP.js.map +1 -0
  13. package/dist/{chunk-6RND47QE.js → chunk-IRUD73IQ.js} +95 -25
  14. package/dist/chunk-IRUD73IQ.js.map +1 -0
  15. package/dist/{chunk-KTDOZR7Y.js → chunk-OXF7VT7S.js} +2 -2
  16. package/dist/{chunk-RTIR6R2U.js → chunk-S63IOKFP.js} +2 -2
  17. package/dist/{chunk-E7LPIZXI.cjs → chunk-VFTVZJO5.cjs} +4 -4
  18. package/dist/{chunk-E7LPIZXI.cjs.map → chunk-VFTVZJO5.cjs.map} +1 -1
  19. package/dist/{index-v2_-Fyn3.d.ts → index-BWpwZRQw.d.cts} +367 -2
  20. package/dist/{index-BE1bM2Wi.d.cts → index-DRJqwO2y.d.ts} +367 -2
  21. package/dist/index.cjs +399 -97
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +116 -7
  24. package/dist/index.d.ts +116 -7
  25. package/dist/index.js +314 -12
  26. package/dist/index.js.map +1 -1
  27. package/dist/schemas.cjs +11 -3
  28. package/dist/schemas.cjs.map +1 -1
  29. package/dist/schemas.d.cts +2 -2
  30. package/dist/schemas.d.ts +2 -2
  31. package/dist/schemas.js +10 -2
  32. package/dist/scoring.cjs +3 -3
  33. package/dist/scoring.d.cts +2 -2
  34. package/dist/scoring.d.ts +2 -2
  35. package/dist/scoring.js +2 -2
  36. package/dist/xapi.cjs +3 -3
  37. package/dist/xapi.d.cts +1 -1
  38. package/dist/xapi.d.ts +1 -1
  39. package/dist/xapi.js +2 -2
  40. package/package.json +1 -1
  41. package/dist/chunk-2NIALQEH.cjs +0 -227
  42. package/dist/chunk-2NIALQEH.cjs.map +0 -1
  43. package/dist/chunk-6RND47QE.js.map +0 -1
  44. package/dist/chunk-NBADQ3JU.js.map +0 -1
  45. package/dist/chunk-VCXIPLEW.cjs.map +0 -1
  46. /package/dist/{chunk-KTDOZR7Y.js.map → chunk-OXF7VT7S.js.map} +0 -0
  47. /package/dist/{chunk-RTIR6R2U.js.map → chunk-S63IOKFP.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -16,14 +16,14 @@
16
16
 
17
17
 
18
18
 
19
- var _chunkJ5OIRIOWcjs = require('./chunk-J5OIRIOW.cjs');
19
+ var _chunk6P6XK2LIcjs = require('./chunk-6P6XK2LI.cjs');
20
20
 
21
21
 
22
22
 
23
23
 
24
24
 
25
25
 
26
- var _chunkE7LPIZXIcjs = require('./chunk-E7LPIZXI.cjs');
26
+ var _chunkVFTVZJO5cjs = require('./chunk-VFTVZJO5.cjs');
27
27
 
28
28
 
29
29
 
@@ -40,7 +40,6 @@ var _chunkE7LPIZXIcjs = require('./chunk-E7LPIZXI.cjs');
40
40
 
41
41
 
42
42
 
43
- var _chunk2NIALQEHcjs = require('./chunk-2NIALQEH.cjs');
44
43
 
45
44
 
46
45
 
@@ -50,6 +49,7 @@ var _chunk2NIALQEHcjs = require('./chunk-2NIALQEH.cjs');
50
49
 
51
50
 
52
51
 
52
+ var _chunkFJJ2GVBAcjs = require('./chunk-FJJ2GVBA.cjs');
53
53
 
54
54
 
55
55
 
@@ -124,7 +124,17 @@ var _chunk2NIALQEHcjs = require('./chunk-2NIALQEH.cjs');
124
124
 
125
125
 
126
126
 
127
- var _chunkVCXIPLEWcjs = require('./chunk-VCXIPLEW.cjs');
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+ var _chunkF7UOLKWVcjs = require('./chunk-F7UOLKWV.cjs');
128
138
 
129
139
  // src/content-hash.ts
130
140
  function canonicalJson(value, seen = /* @__PURE__ */ new Set()) {
@@ -226,6 +236,20 @@ function keyOf(entry) {
226
236
  }
227
237
  return key;
228
238
  }
239
+ function inQuizOrder(items, timeline) {
240
+ const placement = /* @__PURE__ */ new Map();
241
+ timeline.cues.forEach((cue, cueIndex) => {
242
+ cue.itemIds.forEach((itemId, position) => {
243
+ if (!placement.has(itemId)) {
244
+ placement.set(itemId, { at: cue.at, cue: cueIndex, position });
245
+ }
246
+ });
247
+ });
248
+ const unplaced = { at: Number.POSITIVE_INFINITY, cue: Number.POSITIVE_INFINITY, position: 0 };
249
+ return items.map((entry) => ({ entry, place: _nullishCoalesce(placement.get(entry.item.id), () => ( unplaced)) })).sort(
250
+ (a, b) => a.place.at - b.place.at || a.place.cue - b.place.cue || a.place.position - b.place.position || a.entry.itemIndex - b.entry.itemIndex
251
+ ).map(({ entry }) => entry);
252
+ }
229
253
  function flattenSequence(entries, options = {}) {
230
254
  const shuffleEntries = options.shuffleEntries === true;
231
255
  const needsSeed = shuffleEntries || entries.some((entry) => isItemGroup(entry) && entry.shuffle === "within-group");
@@ -249,11 +273,20 @@ function flattenSequence(entries, options = {}) {
249
273
  `flattenSequence: item group "${entry.id}" has no items. An empty group would silently remove its stimulus and its questions from the presented sequence.`
250
274
  );
251
275
  }
276
+ const timeline = entry.timeline;
277
+ if (timeline !== void 0 && entry.shuffle === "within-group") {
278
+ throw new Error(
279
+ `flattenSequence: item group "${entry.id}" has a timeline and shuffle: "within-group". An interactive video presents its questions in the order its quizzes open.`
280
+ );
281
+ }
252
282
  const items = entry.items.map((item, itemIndex) => ({ item, itemIndex }));
253
- const presented = entry.shuffle === "within-group" ? seededShuffle(items, `${seed}:group:${entry.id}`) : items;
283
+ const presented = timeline !== void 0 ? inQuizOrder(items, timeline) : entry.shuffle === "within-group" ? seededShuffle(items, `${seed}:group:${entry.id}`) : items;
254
284
  const size = presented.length;
255
285
  presented.forEach(({ item, itemIndex }, position) => {
286
+ const cue = _optionalChain([timeline, 'optionalAccess', _ => _.cues, 'access', _2 => _2.find, 'call', _3 => _3((candidate) => candidate.itemIds.includes(item.id))]);
256
287
  slots.push({
288
+ // Slot ids stay AUTHORED — the item's index or its key — whatever the
289
+ // presented order: moving a quiz must never re-map a stored answer.
257
290
  slotId: `${entryKey}.${_nullishCoalesce(keyOf(item), () => ( String(itemIndex)))}`,
258
291
  index: slots.length,
259
292
  activity: item,
@@ -262,7 +295,9 @@ function flattenSequence(entries, options = {}) {
262
295
  ...entry.title !== void 0 ? { title: entry.title } : {},
263
296
  stimulus: entry.stimulus,
264
297
  position,
265
- size
298
+ size,
299
+ ...timeline !== void 0 ? { timeline } : {},
300
+ ...cue !== void 0 ? { cue } : {}
266
301
  }
267
302
  });
268
303
  });
@@ -302,16 +337,16 @@ function stimulusMediaKey(slotId) {
302
337
  }
303
338
  function resolvePlaybackPolicy(media) {
304
339
  const p = media.playback;
305
- const budgeted = typeof _optionalChain([p, 'optionalAccess', _ => _.maxPlays]) === "number";
306
- const seek = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _2 => _2.seek]), () => ( (budgeted ? "none" : "allow")));
307
- const rate = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _3 => _3.rate]), () => ( "allow"));
308
- const controls = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _4 => _4.controls]), () => ( (budgeted || seek === "none" || rate === "fixed" ? "minimal" : "native")));
340
+ const budgeted = typeof _optionalChain([p, 'optionalAccess', _4 => _4.maxPlays]) === "number";
341
+ const seek = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _5 => _5.seek]), () => ( (budgeted ? "none" : "allow")));
342
+ const rate = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _6 => _6.rate]), () => ( "allow"));
343
+ const controls = _nullishCoalesce(_optionalChain([p, 'optionalAccess', _7 => _7.controls]), () => ( (budgeted || seek === "none" || rate === "fixed" ? "minimal" : "native")));
309
344
  return {
310
345
  controls,
311
- maxPlays: budgeted ? _optionalChain([p, 'optionalAccess', _5 => _5.maxPlays]) : null,
346
+ maxPlays: budgeted ? _optionalChain([p, 'optionalAccess', _8 => _8.maxPlays]) : null,
312
347
  seek,
313
348
  rate,
314
- nativeControlHints: _nullishCoalesce(_optionalChain([p, 'optionalAccess', _6 => _6.nativeControlHints]), () => ( []))
349
+ nativeControlHints: _nullishCoalesce(_optionalChain([p, 'optionalAccess', _9 => _9.nativeControlHints]), () => ( []))
315
350
  };
316
351
  }
317
352
  function planMediaBudgets(plan) {
@@ -326,7 +361,7 @@ function planMediaBudgets(plan) {
326
361
  function assertEntry(key, entry) {
327
362
  if (entry === null || typeof entry !== "object" || !Number.isInteger(entry.plays) || entry.plays < 0) {
328
363
  throw new Error(
329
- `serializeMediaPlayLedger: play count for ${JSON.stringify(key)} is ${JSON.stringify(_optionalChain([entry, 'optionalAccess', _7 => _7.plays]))}. A count must be a non-negative integer; Number(a NULL column) is the usual cause.`
364
+ `serializeMediaPlayLedger: play count for ${JSON.stringify(key)} is ${JSON.stringify(_optionalChain([entry, 'optionalAccess', _10 => _10.plays]))}. A count must be a non-negative integer; Number(a NULL column) is the usual cause.`
330
365
  );
331
366
  }
332
367
  if (entry.at !== void 0 && (!Number.isFinite(entry.at) || entry.at < 0)) {
@@ -399,7 +434,7 @@ function mediaBudgetsOf(slot) {
399
434
  budgets.push({ key: slotMediaKey(slot.slotId), maxPlays });
400
435
  }
401
436
  }
402
- const stimulusMedia = _optionalChain([slot, 'access', _8 => _8.group, 'optionalAccess', _9 => _9.stimulus, 'access', _10 => _10.media]);
437
+ const stimulusMedia = _optionalChain([slot, 'access', _11 => _11.group, 'optionalAccess', _12 => _12.stimulus, 'access', _13 => _13.media]);
403
438
  if (stimulusMedia !== void 0) {
404
439
  const maxPlays = resolvePlaybackPolicy(stimulusMedia).maxPlays;
405
440
  if (maxPlays !== null) {
@@ -445,7 +480,14 @@ function planSlot(slot, points) {
445
480
  group: {
446
481
  id: slot.group.id,
447
482
  ...slot.group.title !== void 0 ? { title: slot.group.title } : {},
448
- stimulusHash: contentHash(slot.group.stimulus)
483
+ stimulusHash: contentHash(slot.group.stimulus),
484
+ ...slot.group.cue !== void 0 ? {
485
+ cue: {
486
+ id: slot.group.cue.id,
487
+ at: slot.group.cue.at,
488
+ ...slot.group.cue.required !== void 0 ? { required: slot.group.cue.required } : {}
489
+ }
490
+ } : {}
449
491
  }
450
492
  } : {},
451
493
  ...mediaBudgets !== void 0 ? { mediaBudgets } : {}
@@ -458,7 +500,7 @@ function planAttempt(entries, options = {}) {
458
500
  ...seed !== void 0 ? { seed } : {}
459
501
  });
460
502
  assertNoSplitBudgets(slots);
461
- const planned = slots.map((slot) => planSlot(slot, _nullishCoalesce(_optionalChain([points, 'optionalCall', _11 => _11(slot)]), () => ( 1))));
503
+ const planned = slots.map((slot) => planSlot(slot, _nullishCoalesce(_optionalChain([points, 'optionalCall', _14 => _14(slot)]), () => ( 1))));
462
504
  const totalPoints = planned.reduce((sum, slot) => sum + slot.points, 0);
463
505
  return {
464
506
  planVersion: "1.0",
@@ -479,6 +521,7 @@ function verifyAttemptPlan(plan, current) {
479
521
  const addedSlotIds = current.slots.filter((s) => !before.has(s.slotId)).map((s) => s.slotId);
480
522
  const changedSlotIds = [];
481
523
  const changedStimulusSlotIds = [];
524
+ const changedCueSlotIds = [];
482
525
  const changedPointsSlotIds = [];
483
526
  const reorderedSlotIds = [];
484
527
  for (const slot of plan.slots) {
@@ -489,9 +532,12 @@ function verifyAttemptPlan(plan, current) {
489
532
  if (now.contentHash !== slot.contentHash) {
490
533
  changedSlotIds.push(slot.slotId);
491
534
  }
492
- if (_optionalChain([now, 'access', _12 => _12.group, 'optionalAccess', _13 => _13.stimulusHash]) !== _optionalChain([slot, 'access', _14 => _14.group, 'optionalAccess', _15 => _15.stimulusHash])) {
535
+ if (_optionalChain([now, 'access', _15 => _15.group, 'optionalAccess', _16 => _16.stimulusHash]) !== _optionalChain([slot, 'access', _17 => _17.group, 'optionalAccess', _18 => _18.stimulusHash])) {
493
536
  changedStimulusSlotIds.push(slot.slotId);
494
537
  }
538
+ if (contentHash(_nullishCoalesce(_optionalChain([now, 'access', _19 => _19.group, 'optionalAccess', _20 => _20.cue]), () => ( null))) !== contentHash(_nullishCoalesce(_optionalChain([slot, 'access', _21 => _21.group, 'optionalAccess', _22 => _22.cue]), () => ( null)))) {
539
+ changedCueSlotIds.push(slot.slotId);
540
+ }
495
541
  if (now.points !== slot.points) {
496
542
  changedPointsSlotIds.push(slot.slotId);
497
543
  }
@@ -500,11 +546,12 @@ function verifyAttemptPlan(plan, current) {
500
546
  }
501
547
  }
502
548
  return {
503
- matches: missingSlotIds.length === 0 && addedSlotIds.length === 0 && changedSlotIds.length === 0 && changedStimulusSlotIds.length === 0 && changedPointsSlotIds.length === 0 && reorderedSlotIds.length === 0,
549
+ matches: missingSlotIds.length === 0 && addedSlotIds.length === 0 && changedSlotIds.length === 0 && changedStimulusSlotIds.length === 0 && changedCueSlotIds.length === 0 && changedPointsSlotIds.length === 0 && reorderedSlotIds.length === 0,
504
550
  missingSlotIds,
505
551
  addedSlotIds,
506
552
  changedSlotIds,
507
553
  changedStimulusSlotIds,
554
+ changedCueSlotIds,
508
555
  changedPointsSlotIds,
509
556
  reorderedSlotIds
510
557
  };
@@ -652,23 +699,31 @@ function createItemGroupDraft(context) {
652
699
  items: []
653
700
  };
654
701
  }
702
+ function createInteractiveVideoDraft(context) {
703
+ const draft = createItemGroupDraft(context);
704
+ return {
705
+ ...draft,
706
+ stimulus: { id: draft.stimulus.id, kind: "video", media: { type: "video", url: "" } },
707
+ timeline: { cues: [] }
708
+ };
709
+ }
655
710
  function validateItemGroupDraft(draft) {
656
- return _chunkVCXIPLEWcjs.withValidationScope.call(void 0, () => validateItemGroupDraftInScope(draft));
711
+ return _chunkF7UOLKWVcjs.withValidationScope.call(void 0, () => validateItemGroupDraftInScope(draft));
657
712
  }
658
713
  function validateItemGroupDraftInScope(draft) {
659
714
  const issues = [];
660
- if (!_chunkVCXIPLEWcjs.isRecord.call(void 0, draft)) {
715
+ if (!_chunkF7UOLKWVcjs.isRecord.call(void 0, draft)) {
661
716
  issues.push(
662
- _chunkVCXIPLEWcjs.issue.call(void 0, "ig_not_an_object", [], "A group must be an object with a stimulus and its items.")
717
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_not_an_object", [], "A group must be an object with a stimulus and its items.")
663
718
  );
664
719
  return { status: "invalid", issues };
665
720
  }
666
721
  issues.push(...checkGroupIdentity(draft));
667
- if (_chunkVCXIPLEWcjs.isRecord.call(void 0, draft.stimulus)) {
722
+ if (_chunkF7UOLKWVcjs.isRecord.call(void 0, draft.stimulus)) {
668
723
  issues.push(...checkStimulus(draft.stimulus));
669
- } else if (_chunkVCXIPLEWcjs.isUnset.call(void 0, draft.stimulus)) {
724
+ } else if (_chunkF7UOLKWVcjs.isUnset.call(void 0, draft.stimulus)) {
670
725
  issues.push(
671
- _chunkVCXIPLEWcjs.issue.call(void 0,
726
+ _chunkF7UOLKWVcjs.issue.call(void 0,
672
727
  "ig_stimulus_required",
673
728
  ["stimulus"],
674
729
  "Add the passage, recording or image the questions are about."
@@ -676,25 +731,29 @@ function validateItemGroupDraftInScope(draft) {
676
731
  );
677
732
  }
678
733
  issues.push(...checkItems(draft));
679
- if (_chunkVCXIPLEWcjs.groupCaptionsRevealDictation.call(void 0, draft, (captionsUrl) => !_chunkVCXIPLEWcjs.isUnwritten.call(void 0, captionsUrl))) {
734
+ if (draft.timeline !== void 0 && draft.timeline !== null) {
735
+ issues.push(...checkTimeline(draft));
736
+ }
737
+ const captions = _chunkF7UOLKWVcjs.groupCaptionsField.call(void 0, draft, (captionsUrl) => !_chunkF7UOLKWVcjs.isUnwritten.call(void 0, captionsUrl));
738
+ if (captions !== void 0) {
680
739
  issues.push(
681
- _chunkVCXIPLEWcjs.issue.call(void 0,
740
+ _chunkF7UOLKWVcjs.issue.call(void 0,
682
741
  "dc_captions_not_allowed",
683
- ["stimulus", "media", "captionsUrl"],
684
- _chunkVCXIPLEWcjs.GROUP_CAPTIONS_REVEAL_DICTATION
742
+ ["stimulus", "media", captions],
743
+ _chunkF7UOLKWVcjs.GROUP_CAPTIONS_REVEAL_DICTATION
685
744
  )
686
745
  );
687
746
  }
688
- const parsed = _chunk2NIALQEHcjs.ItemGroupSchema.safeParse(draft, { reportInput: true });
747
+ const parsed = _chunkFJJ2GVBAcjs.ItemGroupSchema.safeParse(draft, { reportInput: true });
689
748
  if (!parsed.success) {
690
749
  for (const schemaIssue of parsed.error.issues) {
691
750
  const path = schemaIssue.path.map(String);
692
- if (issues.some((known) => _chunkVCXIPLEWcjs.covers.call(void 0, known.path, path))) {
751
+ if (issues.some((known) => _chunkF7UOLKWVcjs.covers.call(void 0, known.path, path))) {
693
752
  continue;
694
753
  }
695
- if (path.length > 0 && _chunkVCXIPLEWcjs.refusesEmpty.call(void 0, draft, schemaIssue)) {
754
+ if (path.length > 0 && _chunkF7UOLKWVcjs.refusesEmpty.call(void 0, draft, schemaIssue)) {
696
755
  issues.push(
697
- _chunkVCXIPLEWcjs.issue.call(void 0,
756
+ _chunkF7UOLKWVcjs.issue.call(void 0,
698
757
  "null_not_allowed",
699
758
  path,
700
759
  "This field cannot be null. Leave it out if it is optional, or give it a value."
@@ -710,7 +769,7 @@ function validateItemGroupDraftInScope(draft) {
710
769
  });
711
770
  }
712
771
  }
713
- const stored = _chunk2NIALQEHcjs.validateItemGroup.call(void 0, draft);
772
+ const stored = _chunkFJJ2GVBAcjs.validateItemGroup.call(void 0, draft);
714
773
  if (issues.length === 0 && stored.success) {
715
774
  return { status: "complete", data: stored.data, issues };
716
775
  }
@@ -722,11 +781,188 @@ function validateItemGroupDraftInScope(draft) {
722
781
  const invalid = issues.some((found) => found.severity !== "incomplete");
723
782
  return { status: invalid ? "invalid" : "incomplete", issues };
724
783
  }
784
+ function checkTimeline(draft) {
785
+ const issues = [];
786
+ const timeline = draft.timeline;
787
+ if (!_chunkF7UOLKWVcjs.isRecord.call(void 0, timeline)) {
788
+ return issues;
789
+ }
790
+ const stimulus = _chunkF7UOLKWVcjs.isRecord.call(void 0, draft.stimulus) ? draft.stimulus : void 0;
791
+ if (stimulus !== void 0 && !_chunkF7UOLKWVcjs.isUnwritten.call(void 0, stimulus.kind) && stimulus.kind !== "video") {
792
+ issues.push(
793
+ _chunkF7UOLKWVcjs.issue.call(void 0,
794
+ "ig_timeline_stimulus_kind",
795
+ ["stimulus", "kind"],
796
+ "An interactive video needs a video: quizzes open at moments of it."
797
+ )
798
+ );
799
+ } else if (stimulus !== void 0 && _chunkF7UOLKWVcjs.isRecord.call(void 0, stimulus.media) && !_chunkF7UOLKWVcjs.isUnwritten.call(void 0, stimulus.media.type) && stimulus.media.type !== "video") {
800
+ issues.push(
801
+ _chunkF7UOLKWVcjs.issue.call(void 0,
802
+ "ig_timeline_stimulus_kind",
803
+ ["stimulus", "media", "type"],
804
+ "Upload a video file. An embedded player from another site cannot be paused when a quiz opens."
805
+ )
806
+ );
807
+ }
808
+ if (draft.shuffle === "within-group") {
809
+ issues.push(
810
+ _chunkF7UOLKWVcjs.issue.call(void 0,
811
+ "ig_timeline_shuffle",
812
+ ["shuffle"],
813
+ "The questions of an interactive video appear in the order their quizzes open, so they cannot be shuffled."
814
+ )
815
+ );
816
+ }
817
+ const items = Array.isArray(draft.items) ? draft.items : [];
818
+ const itemIndexById = /* @__PURE__ */ new Map();
819
+ items.forEach((item, index) => {
820
+ if (!_chunkF7UOLKWVcjs.isRecord.call(void 0, item)) {
821
+ return;
822
+ }
823
+ if (typeof item.id === "string" && item.id !== "") {
824
+ itemIndexById.set(item.id, index);
825
+ }
826
+ const type = item.type;
827
+ if (typeof type === "string" && type !== "" && type !== "item-group" && !_chunkFJJ2GVBAcjs.isInteractiveVideoItemType.call(void 0, type) && _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, type) !== void 0) {
828
+ issues.push(
829
+ _chunkF7UOLKWVcjs.issue.call(void 0,
830
+ "ig_timeline_item_type",
831
+ ["items", index, "type"],
832
+ `An interactive video can hold ${_chunkFJJ2GVBAcjs.INTERACTIVE_VIDEO_ITEM_TYPES.join(", ")} questions only.`
833
+ )
834
+ );
835
+ }
836
+ if (type === "dictation" && _chunkF7UOLKWVcjs.isUnset.call(void 0, item.media)) {
837
+ issues.push(
838
+ _chunkF7UOLKWVcjs.issue.call(void 0,
839
+ "ig_timeline_dictation_media",
840
+ ["items", index, "media"],
841
+ "Add the recording this dictation plays: inside a video it cannot play the video."
842
+ )
843
+ );
844
+ }
845
+ });
846
+ const cues = Array.isArray(timeline.cues) ? timeline.cues : [];
847
+ const quizIds = /* @__PURE__ */ new Set();
848
+ const placed = /* @__PURE__ */ new Set();
849
+ cues.forEach((cue, cueIndex) => {
850
+ if (!_chunkF7UOLKWVcjs.isRecord.call(void 0, cue)) {
851
+ return;
852
+ }
853
+ const at = (field, ...rest) => [
854
+ "timeline",
855
+ "cues",
856
+ cueIndex,
857
+ field,
858
+ ...rest
859
+ ];
860
+ if (_chunkF7UOLKWVcjs.isMissingId.call(void 0, cue.id)) {
861
+ issues.push(_chunkF7UOLKWVcjs.issue.call(void 0, "ig_timeline_quiz_id_required", at("id"), "This quiz has no id."));
862
+ } else if (typeof cue.id === "string") {
863
+ if (quizIds.has(cue.id)) {
864
+ issues.push(
865
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_timeline_quiz_id_duplicate", at("id"), `Two quizzes share the id "${cue.id}".`)
866
+ );
867
+ }
868
+ quizIds.add(cue.id);
869
+ }
870
+ if (_chunkF7UOLKWVcjs.isUnset.call(void 0, cue.at)) {
871
+ issues.push(
872
+ _chunkF7UOLKWVcjs.issue.call(void 0,
873
+ "ig_timeline_quiz_time_required",
874
+ at("at"),
875
+ "Choose when in the video this quiz opens."
876
+ )
877
+ );
878
+ } else if (typeof cue.at !== "number" || !Number.isFinite(cue.at) || cue.at < 0) {
879
+ issues.push(
880
+ _chunkF7UOLKWVcjs.issue.call(void 0,
881
+ "ig_timeline_quiz_time_invalid",
882
+ at("at"),
883
+ "A quiz opens at a number of seconds, 0 or more."
884
+ )
885
+ );
886
+ }
887
+ if (_chunkF7UOLKWVcjs.isUnset.call(void 0, cue.itemIds) || Array.isArray(cue.itemIds) && cue.itemIds.length === 0) {
888
+ issues.push(
889
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_timeline_quiz_empty", at("itemIds"), "Add at least one question to this quiz.")
890
+ );
891
+ return;
892
+ }
893
+ if (!Array.isArray(cue.itemIds)) {
894
+ return;
895
+ }
896
+ cue.itemIds.forEach((itemId, position) => {
897
+ if (typeof itemId !== "string") {
898
+ return;
899
+ }
900
+ if (!itemIndexById.has(itemId)) {
901
+ issues.push(
902
+ _chunkF7UOLKWVcjs.issue.call(void 0,
903
+ "ig_timeline_quiz_unknown_item",
904
+ at("itemIds", position),
905
+ `This quiz names a question that is not in the video ("${itemId}").`
906
+ )
907
+ );
908
+ } else if (placed.has(itemId)) {
909
+ issues.push(
910
+ _chunkF7UOLKWVcjs.issue.call(void 0,
911
+ "ig_timeline_item_duplicate",
912
+ at("itemIds", position),
913
+ "This question is already in a quiz: each question belongs to one quiz."
914
+ )
915
+ );
916
+ }
917
+ placed.add(itemId);
918
+ });
919
+ });
920
+ for (const [itemId, index] of itemIndexById) {
921
+ if (!placed.has(itemId)) {
922
+ issues.push(
923
+ _chunkF7UOLKWVcjs.issue.call(void 0,
924
+ "ig_timeline_item_unplaced",
925
+ ["items", index],
926
+ "Add this question to a quiz, or the video never shows it."
927
+ )
928
+ );
929
+ }
930
+ }
931
+ const chapters = Array.isArray(timeline.chapters) ? timeline.chapters : [];
932
+ let previousAt;
933
+ chapters.forEach((chapter, index) => {
934
+ if (!_chunkF7UOLKWVcjs.isRecord.call(void 0, chapter)) {
935
+ return;
936
+ }
937
+ if (_chunkF7UOLKWVcjs.isUnwritten.call(void 0, chapter.title)) {
938
+ issues.push(
939
+ _chunkF7UOLKWVcjs.issue.call(void 0,
940
+ "ig_timeline_chapter_title",
941
+ ["timeline", "chapters", index, "title"],
942
+ "Give this chapter a title."
943
+ )
944
+ );
945
+ }
946
+ if (typeof chapter.at === "number" && Number.isFinite(chapter.at)) {
947
+ if (previousAt !== void 0 && chapter.at <= previousAt) {
948
+ issues.push(
949
+ _chunkF7UOLKWVcjs.issue.call(void 0,
950
+ "ig_timeline_chapter_order",
951
+ ["timeline", "chapters", index, "at"],
952
+ "Chapters must start in order, each after the one before it."
953
+ )
954
+ );
955
+ }
956
+ previousAt = chapter.at;
957
+ }
958
+ });
959
+ return issues;
960
+ }
725
961
  function checkGroupIdentity(draft) {
726
962
  const issues = [];
727
963
  if (draft.schemaVersion !== "1.0") {
728
964
  issues.push(
729
- _chunkVCXIPLEWcjs.issue.call(void 0,
965
+ _chunkF7UOLKWVcjs.issue.call(void 0,
730
966
  "schema_version_invalid",
731
967
  ["schemaVersion"],
732
968
  'The draft must have schemaVersion "1.0". A draft from createItemGroupDraft has it.'
@@ -734,14 +970,14 @@ function checkGroupIdentity(draft) {
734
970
  );
735
971
  }
736
972
  if (draft.type !== "item-group") {
737
- issues.push(_chunkVCXIPLEWcjs.issue.call(void 0, "type_mismatch", ["type"], `The draft's type must be "item-group".`));
973
+ issues.push(_chunkF7UOLKWVcjs.issue.call(void 0, "type_mismatch", ["type"], `The draft's type must be "item-group".`));
738
974
  }
739
- if (_chunkVCXIPLEWcjs.isMissingId.call(void 0, draft.id)) {
740
- issues.push(_chunkVCXIPLEWcjs.issue.call(void 0, "id_required", ["id"], "The group has no id."));
975
+ if (_chunkF7UOLKWVcjs.isMissingId.call(void 0, draft.id)) {
976
+ issues.push(_chunkF7UOLKWVcjs.issue.call(void 0, "id_required", ["id"], "The group has no id."));
741
977
  }
742
- if (!_chunkVCXIPLEWcjs.isUnset.call(void 0, draft.shuffle) && draft.shuffle !== "none" && draft.shuffle !== "within-group") {
978
+ if (!_chunkF7UOLKWVcjs.isUnset.call(void 0, draft.shuffle) && draft.shuffle !== "none" && draft.shuffle !== "within-group") {
743
979
  issues.push(
744
- _chunkVCXIPLEWcjs.issue.call(void 0,
980
+ _chunkF7UOLKWVcjs.issue.call(void 0,
745
981
  "ig_shuffle_invalid",
746
982
  ["shuffle"],
747
983
  'Shuffling is either "none" or "within-group". Leave it out to keep the authored order.'
@@ -760,13 +996,13 @@ var MEDIA_FOR_KIND = {
760
996
  function checkStimulus(stimulus) {
761
997
  const issues = [];
762
998
  const at = (...rest) => ["stimulus", ...rest];
763
- if (_chunkVCXIPLEWcjs.isMissingId.call(void 0, stimulus.id)) {
764
- issues.push(_chunkVCXIPLEWcjs.issue.call(void 0, "ig_stimulus_id_required", at("id"), "The stimulus has no id."));
999
+ if (_chunkF7UOLKWVcjs.isMissingId.call(void 0, stimulus.id)) {
1000
+ issues.push(_chunkF7UOLKWVcjs.issue.call(void 0, "ig_stimulus_id_required", at("id"), "The stimulus has no id."));
765
1001
  }
766
1002
  const kind = stimulus.kind;
767
- if (_chunkVCXIPLEWcjs.isUnwritten.call(void 0, kind)) {
1003
+ if (_chunkF7UOLKWVcjs.isUnwritten.call(void 0, kind)) {
768
1004
  issues.push(
769
- _chunkVCXIPLEWcjs.issue.call(void 0,
1005
+ _chunkF7UOLKWVcjs.issue.call(void 0,
770
1006
  "ig_stimulus_kind_required",
771
1007
  at("kind"),
772
1008
  "Choose what the questions are about: a text, a recording, a video, an image, or a mix."
@@ -775,71 +1011,71 @@ function checkStimulus(stimulus) {
775
1011
  } else if (typeof kind !== "string" || !KINDS.has(kind)) {
776
1012
  if (typeof kind === "string") {
777
1013
  issues.push(
778
- _chunkVCXIPLEWcjs.issue.call(void 0,
1014
+ _chunkF7UOLKWVcjs.issue.call(void 0,
779
1015
  "ig_stimulus_kind_invalid",
780
1016
  at("kind"),
781
1017
  `"${kind}" is not a stimulus kind. Use text, audio, video, image or mixed.`
782
1018
  )
783
1019
  );
784
1020
  }
785
- if (_chunkVCXIPLEWcjs.isRecord.call(void 0, stimulus.media)) {
786
- issues.push(..._chunkVCXIPLEWcjs.checkMedia.call(void 0, stimulus.media, at("media")));
1021
+ if (_chunkF7UOLKWVcjs.isRecord.call(void 0, stimulus.media)) {
1022
+ issues.push(..._chunkF7UOLKWVcjs.checkMedia.call(void 0, stimulus.media, at("media")));
787
1023
  }
788
1024
  return issues;
789
1025
  }
790
1026
  const hasBody = typeof stimulus.body === "string" && stimulus.body.trim() !== "";
791
- const htmlPresent = !_chunkVCXIPLEWcjs.isUnset.call(void 0, stimulus.bodyHtml);
1027
+ const htmlPresent = !_chunkF7UOLKWVcjs.isUnset.call(void 0, stimulus.bodyHtml);
792
1028
  if (!hasBody && (kind === "text" || kind === "mixed" || htmlPresent)) {
793
1029
  issues.push(
794
- _chunkVCXIPLEWcjs.issue.call(void 0,
1030
+ _chunkF7UOLKWVcjs.issue.call(void 0,
795
1031
  "ig_stimulus_body_required",
796
1032
  at("body"),
797
- _chunkVCXIPLEWcjs.isUnwritten.call(void 0, stimulus.bodyHtml) ? "Write the passage." : "Write the passage as plain text too. The rich-text version is shown only where a sanitiser is supplied."
1033
+ _chunkF7UOLKWVcjs.isUnwritten.call(void 0, stimulus.bodyHtml) ? "Write the passage." : "Write the passage as plain text too. The rich-text version is shown only where a sanitiser is supplied."
798
1034
  )
799
1035
  );
800
1036
  }
801
- if (kind !== "text" && _chunkVCXIPLEWcjs.isUnset.call(void 0, stimulus.media)) {
1037
+ if (kind !== "text" && _chunkF7UOLKWVcjs.isUnset.call(void 0, stimulus.media)) {
802
1038
  issues.push(
803
- _chunkVCXIPLEWcjs.issue.call(void 0, "ig_stimulus_media_required", at("media"), "Add the recording, video or image.")
1039
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_stimulus_media_required", at("media"), "Add the recording, video or image.")
804
1040
  );
805
- } else if (_chunkVCXIPLEWcjs.isRecord.call(void 0, stimulus.media)) {
1041
+ } else if (_chunkF7UOLKWVcjs.isRecord.call(void 0, stimulus.media)) {
806
1042
  const allowed = MEDIA_FOR_KIND[kind];
807
1043
  const mediaType = stimulus.media.type;
808
1044
  if (allowed !== void 0 && typeof mediaType === "string" && !allowed.includes(mediaType)) {
809
1045
  issues.push(
810
- _chunkVCXIPLEWcjs.issue.call(void 0,
1046
+ _chunkF7UOLKWVcjs.issue.call(void 0,
811
1047
  "ig_stimulus_media_kind",
812
1048
  at("media", "type"),
813
1049
  `A "${kind}" stimulus cannot carry ${mediaType} media. Use ${allowed.join(" or ")}.`
814
1050
  )
815
1051
  );
816
1052
  }
817
- issues.push(..._chunkVCXIPLEWcjs.checkMedia.call(void 0, stimulus.media, at("media")));
1053
+ issues.push(..._chunkF7UOLKWVcjs.checkMedia.call(void 0, stimulus.media, at("media")));
818
1054
  }
819
1055
  return issues;
820
1056
  }
821
1057
  function checkItems(draft) {
822
1058
  const issues = [];
823
- const items = _chunkVCXIPLEWcjs.isUnset.call(void 0, draft.items) ? [] : draft.items;
1059
+ const items = _chunkF7UOLKWVcjs.isUnset.call(void 0, draft.items) ? [] : draft.items;
824
1060
  if (!Array.isArray(items)) {
825
1061
  return issues;
826
1062
  }
827
1063
  if (items.length === 0) {
828
1064
  issues.push(
829
- _chunkVCXIPLEWcjs.issue.call(void 0, "ig_items_required", ["items"], "Add at least one question about this material.")
1065
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_items_required", ["items"], "Add at least one question about this material.")
830
1066
  );
831
1067
  return issues;
832
1068
  }
833
1069
  const seen = /* @__PURE__ */ new Set();
834
1070
  const repeated = /* @__PURE__ */ new Set();
835
1071
  for (const [index, item] of items.entries()) {
836
- if (!_chunkVCXIPLEWcjs.isRecord.call(void 0, item)) {
1072
+ if (!_chunkF7UOLKWVcjs.isRecord.call(void 0, item)) {
837
1073
  continue;
838
1074
  }
839
1075
  const ordinal = index + 1;
840
- if (_chunkVCXIPLEWcjs.isMissingId.call(void 0, item.id)) {
1076
+ if (_chunkF7UOLKWVcjs.isMissingId.call(void 0, item.id)) {
841
1077
  issues.push(
842
- _chunkVCXIPLEWcjs.issue.call(void 0, "ig_item_id_required", ["items", index, "id"], `Question ${ordinal} has no id.`)
1078
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_item_id_required", ["items", index, "id"], `Question ${ordinal} has no id.`)
843
1079
  );
844
1080
  } else if (typeof item.id === "string") {
845
1081
  if (seen.has(item.id)) {
@@ -849,7 +1085,7 @@ function checkItems(draft) {
849
1085
  }
850
1086
  if (item.type === "item-group") {
851
1087
  issues.push(
852
- _chunkVCXIPLEWcjs.issue.call(void 0,
1088
+ _chunkF7UOLKWVcjs.issue.call(void 0,
853
1089
  "ig_item_nested_group",
854
1090
  ["items", index, "type"],
855
1091
  "Groups do not nest: every item must be an activity."
@@ -857,9 +1093,9 @@ function checkItems(draft) {
857
1093
  );
858
1094
  continue;
859
1095
  }
860
- if (_chunkVCXIPLEWcjs.isUnwritten.call(void 0, item.type)) {
1096
+ if (_chunkF7UOLKWVcjs.isUnwritten.call(void 0, item.type)) {
861
1097
  issues.push(
862
- _chunkVCXIPLEWcjs.issue.call(void 0,
1098
+ _chunkF7UOLKWVcjs.issue.call(void 0,
863
1099
  "ig_item_type_required",
864
1100
  ["items", index, "type"],
865
1101
  `Choose what kind of question ${ordinal} is.`
@@ -874,11 +1110,11 @@ function checkItems(draft) {
874
1110
  try {
875
1111
  result = validateDraft(item.type, item);
876
1112
  } catch (error) {
877
- if (!(error instanceof _chunkVCXIPLEWcjs.UnknownActivityTypeError) || error.activityType !== item.type) {
1113
+ if (!(error instanceof _chunkF7UOLKWVcjs.UnknownActivityTypeError) || error.activityType !== item.type) {
878
1114
  throw error;
879
1115
  }
880
1116
  issues.push(
881
- _chunkVCXIPLEWcjs.issue.call(void 0,
1117
+ _chunkF7UOLKWVcjs.issue.call(void 0,
882
1118
  "ig_item_type_unknown",
883
1119
  ["items", index, "type"],
884
1120
  `"${item.type}" is not a registered activity type.`
@@ -892,7 +1128,7 @@ function checkItems(draft) {
892
1128
  }
893
1129
  for (const id of repeated) {
894
1130
  issues.push(
895
- _chunkVCXIPLEWcjs.issue.call(void 0, "ig_item_id_duplicate", ["items"], `More than one question has the id "${id}".`)
1131
+ _chunkF7UOLKWVcjs.issue.call(void 0, "ig_item_id_duplicate", ["items"], `More than one question has the id "${id}".`)
896
1132
  );
897
1133
  }
898
1134
  return issues;
@@ -900,30 +1136,30 @@ function checkItems(draft) {
900
1136
 
901
1137
  // src/authoring/index.ts
902
1138
  function validateDraft(type, draft) {
903
- return _chunkVCXIPLEWcjs.withValidationScope.call(void 0, () => validateDraftInScope(type, draft));
1139
+ return _chunkF7UOLKWVcjs.withValidationScope.call(void 0, () => validateDraftInScope(type, draft));
904
1140
  }
905
1141
  function validateDraftInScope(type, draft) {
906
- const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, type);
1142
+ const descriptor = _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, type);
907
1143
  if (descriptor === void 0) {
908
- throw new (0, _chunkVCXIPLEWcjs.UnknownActivityTypeError)(String(type));
1144
+ throw new (0, _chunkF7UOLKWVcjs.UnknownActivityTypeError)(String(type));
909
1145
  }
910
- const reported = _chunkVCXIPLEWcjs.isRecord.call(void 0, draft) && _optionalChain([descriptor, 'access', _16 => _16.authoring, 'optionalAccess', _17 => _17.checkDraft]) !== void 0 ? descriptor.authoring.checkDraft(draft).map(normalise) : [];
1146
+ const reported = _chunkF7UOLKWVcjs.isRecord.call(void 0, draft) && _optionalChain([descriptor, 'access', _23 => _23.authoring, 'optionalAccess', _24 => _24.checkDraft]) !== void 0 ? descriptor.authoring.checkDraft(draft).map(normalise) : [];
911
1147
  const issues = [...reported];
912
1148
  const parsed = descriptor.schema.safeParse(draft, { reportInput: true });
913
1149
  if (!parsed.success) {
914
- const covered = _chunkVCXIPLEWcjs.coveredPathsOf.call(void 0, reported);
1150
+ const covered = _chunkF7UOLKWVcjs.coveredPathsOf.call(void 0, reported);
915
1151
  const reportedEmpty = /* @__PURE__ */ new Set();
916
1152
  for (const schemaIssue of parsed.error.issues) {
917
1153
  const path = schemaIssue.path.map(String);
918
- if (covered.has(_chunkVCXIPLEWcjs.pathKey.call(void 0, path))) {
1154
+ if (covered.has(_chunkF7UOLKWVcjs.pathKey.call(void 0, path))) {
919
1155
  continue;
920
1156
  }
921
- if (path.length > 0 && _chunkVCXIPLEWcjs.refusesEmpty.call(void 0, draft, schemaIssue)) {
1157
+ if (path.length > 0 && _chunkF7UOLKWVcjs.refusesEmpty.call(void 0, draft, schemaIssue)) {
922
1158
  const key = JSON.stringify(path);
923
1159
  if (!reportedEmpty.has(key)) {
924
1160
  reportedEmpty.add(key);
925
1161
  issues.push(
926
- _chunkVCXIPLEWcjs.issue.call(void 0,
1162
+ _chunkF7UOLKWVcjs.issue.call(void 0,
927
1163
  "null_not_allowed",
928
1164
  path,
929
1165
  typeof schemaIssue.path.at(-1) === "number" ? "This entry has no value. Remove it, or fill it in." : "This field cannot be null. Leave it out if it is optional, or give it a value."
@@ -947,11 +1183,11 @@ function validateDraftInScope(type, draft) {
947
1183
  return { status: invalid ? "invalid" : "incomplete", issues };
948
1184
  }
949
1185
  function createDraft(type, context) {
950
- const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, type);
1186
+ const descriptor = _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, type);
951
1187
  if (descriptor === void 0) {
952
- throw new (0, _chunkVCXIPLEWcjs.UnknownActivityTypeError)(String(type));
1188
+ throw new (0, _chunkF7UOLKWVcjs.UnknownActivityTypeError)(String(type));
953
1189
  }
954
- const create = _optionalChain([descriptor, 'access', _18 => _18.authoring, 'optionalAccess', _19 => _19.createDraft]);
1190
+ const create = _optionalChain([descriptor, 'access', _25 => _25.authoring, 'optionalAccess', _26 => _26.createDraft]);
955
1191
  if (create === void 0) {
956
1192
  throw new Error(
957
1193
  `Activity type "${String(type)}" declares no authoring.createDraft, so there is no empty draft to create. Build the draft yourself; validateDraft works for every registered type.`
@@ -974,7 +1210,7 @@ function createDraft(type, context) {
974
1210
  return create({ newId });
975
1211
  }
976
1212
  function normalise(found) {
977
- const documented = Object.hasOwn(_chunkVCXIPLEWcjs.DRAFT_ISSUE_SEVERITY, found.code) ? _chunkVCXIPLEWcjs.DRAFT_ISSUE_SEVERITY[found.code] : void 0;
1213
+ const documented = Object.hasOwn(_chunkF7UOLKWVcjs.DRAFT_ISSUE_SEVERITY, found.code) ? _chunkF7UOLKWVcjs.DRAFT_ISSUE_SEVERITY[found.code] : void 0;
978
1214
  return {
979
1215
  ...found,
980
1216
  path: found.path.map(String),
@@ -1038,9 +1274,9 @@ function redactValue(value, policy, reveal) {
1038
1274
  }
1039
1275
  function redact(data, options = {}) {
1040
1276
  const reveal = _nullishCoalesce(options.reveal, () => ( "none"));
1041
- const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, data.type);
1277
+ const descriptor = _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, data.type);
1042
1278
  if (descriptor === void 0) {
1043
- throw new (0, _chunkVCXIPLEWcjs.UnknownActivityTypeError)(String(data.type));
1279
+ throw new (0, _chunkF7UOLKWVcjs.UnknownActivityTypeError)(String(data.type));
1044
1280
  }
1045
1281
  if (descriptor.fieldPolicy === void 0) {
1046
1282
  throw new Error(
@@ -1053,7 +1289,7 @@ function redact(data, options = {}) {
1053
1289
  if (reveal === "none" && descriptor.redactedSchema !== void 0) {
1054
1290
  const parsed = descriptor.redactedSchema.safeParse(result);
1055
1291
  if (!parsed.success) {
1056
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(
1292
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(
1057
1293
  descriptor.type,
1058
1294
  parsed.error.issues.map((issue2) => ({
1059
1295
  path: issue2.path.map(String),
@@ -1067,13 +1303,13 @@ function redact(data, options = {}) {
1067
1303
  }
1068
1304
  function assertRedacted(data) {
1069
1305
  if (typeof data !== "object" || data === null) {
1070
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)("unknown", [
1306
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)("unknown", [
1071
1307
  { path: [], message: "Redacted activity data must be an object.", code: "invalid_type" }
1072
1308
  ]);
1073
1309
  }
1074
1310
  const candidate = data;
1075
1311
  if (candidate.redacted !== true) {
1076
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(String(_nullishCoalesce(candidate.type, () => ( "unknown"))), [
1312
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(String(_nullishCoalesce(candidate.type, () => ( "unknown"))), [
1077
1313
  {
1078
1314
  path: ["redacted"],
1079
1315
  message: "Missing redacted marker \u2014 this payload is not a redact() projection.",
@@ -1082,12 +1318,12 @@ function assertRedacted(data) {
1082
1318
  ]);
1083
1319
  }
1084
1320
  const type = typeof candidate.type === "string" ? candidate.type : "";
1085
- const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, type);
1321
+ const descriptor = _chunkF7UOLKWVcjs.getActivityTypeDescriptor.call(void 0, type);
1086
1322
  if (descriptor === void 0) {
1087
- throw new (0, _chunkVCXIPLEWcjs.UnknownActivityTypeError)(type);
1323
+ throw new (0, _chunkF7UOLKWVcjs.UnknownActivityTypeError)(type);
1088
1324
  }
1089
1325
  if (descriptor.redactedSchema === void 0) {
1090
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(descriptor.type, [
1326
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(descriptor.type, [
1091
1327
  {
1092
1328
  path: [],
1093
1329
  message: `Activity type "${descriptor.type}" registers no redactedSchema; assertRedacted cannot prove this payload is learner-safe.`,
@@ -1097,7 +1333,7 @@ function assertRedacted(data) {
1097
1333
  }
1098
1334
  const parsed = descriptor.redactedSchema.safeParse(candidate);
1099
1335
  if (!parsed.success) {
1100
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(
1336
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(
1101
1337
  descriptor.type,
1102
1338
  parsed.error.issues.map((issue2) => ({
1103
1339
  path: issue2.path.map(String),
@@ -1113,7 +1349,7 @@ var STIMULUS_FIELD_POLICY = {
1113
1349
  title: "public",
1114
1350
  body: "public",
1115
1351
  bodyHtml: "public",
1116
- media: _chunkVCXIPLEWcjs.MEDIA_FIELD_POLICY,
1352
+ media: _chunkF7UOLKWVcjs.MEDIA_FIELD_POLICY,
1117
1353
  locale: "public",
1118
1354
  attribution: "public",
1119
1355
  transcript: "author-only"
@@ -1127,7 +1363,25 @@ var ITEM_GROUP_FIELD_POLICY = {
1127
1363
  // and identity has to cross the redaction boundary intact.
1128
1364
  slotKey: "public",
1129
1365
  shuffle: "public",
1130
- stimulus: STIMULUS_FIELD_POLICY
1366
+ stimulus: STIMULUS_FIELD_POLICY,
1367
+ // Public, and classified key by key rather than as one leaf: the learner's
1368
+ // player needs every part of it, none of it is a key — and a leaf would hand
1369
+ // over the author's object by reference, with whatever else was parked in it.
1370
+ timeline: {
1371
+ // Applies to every element of the array.
1372
+ cues: {
1373
+ id: "public",
1374
+ at: "public",
1375
+ itemIds: "public",
1376
+ title: "public",
1377
+ required: "public"
1378
+ },
1379
+ chapters: {
1380
+ at: "public",
1381
+ title: "public"
1382
+ },
1383
+ navigation: "public"
1384
+ }
1131
1385
  };
1132
1386
  function redactItemGroup(group, options = {}) {
1133
1387
  const reveal = _nullishCoalesce(options.reveal, () => ( "none"));
@@ -1139,9 +1393,9 @@ function redactItemGroup(group, options = {}) {
1139
1393
  redacted: true
1140
1394
  };
1141
1395
  if (reveal === "none") {
1142
- const parsed = _chunk2NIALQEHcjs.RedactedItemGroupSchema.safeParse(result);
1396
+ const parsed = _chunkFJJ2GVBAcjs.RedactedItemGroupSchema.safeParse(result);
1143
1397
  if (!parsed.success) {
1144
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(
1398
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(
1145
1399
  "item-group",
1146
1400
  parsed.error.issues.map((issue2) => ({
1147
1401
  path: issue2.path.map(String),
@@ -1155,13 +1409,13 @@ function redactItemGroup(group, options = {}) {
1155
1409
  }
1156
1410
  function assertRedactedItemGroup(data) {
1157
1411
  if (typeof data !== "object" || data === null) {
1158
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)("item-group", [
1412
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)("item-group", [
1159
1413
  { path: [], message: "Redacted item group must be an object.", code: "invalid_type" }
1160
1414
  ]);
1161
1415
  }
1162
1416
  const candidate = data;
1163
1417
  if (candidate.redacted !== true) {
1164
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)("item-group", [
1418
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)("item-group", [
1165
1419
  {
1166
1420
  path: ["redacted"],
1167
1421
  message: "Missing redacted marker \u2014 this payload is not a redactItemGroup() projection.",
@@ -1169,9 +1423,9 @@ function assertRedactedItemGroup(data) {
1169
1423
  }
1170
1424
  ]);
1171
1425
  }
1172
- const parsed = _chunk2NIALQEHcjs.RedactedItemGroupSchema.safeParse(candidate);
1426
+ const parsed = _chunkFJJ2GVBAcjs.RedactedItemGroupSchema.safeParse(candidate);
1173
1427
  if (!parsed.success) {
1174
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(
1428
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(
1175
1429
  "item-group",
1176
1430
  parsed.error.issues.map((issue2) => ({
1177
1431
  path: issue2.path.map(String),
@@ -1184,8 +1438,8 @@ function assertRedactedItemGroup(data) {
1184
1438
  try {
1185
1439
  assertRedacted(item);
1186
1440
  } catch (error) {
1187
- if (error instanceof _chunkVCXIPLEWcjs.ActivitySchemaError) {
1188
- throw new (0, _chunkVCXIPLEWcjs.ActivitySchemaError)(
1441
+ if (error instanceof _chunkF7UOLKWVcjs.ActivitySchemaError) {
1442
+ throw new (0, _chunkF7UOLKWVcjs.ActivitySchemaError)(
1189
1443
  "item-group",
1190
1444
  error.errors.map((issue2) => ({
1191
1445
  ...issue2,
@@ -1198,6 +1452,54 @@ function assertRedactedItemGroup(data) {
1198
1452
  });
1199
1453
  }
1200
1454
 
1455
+ // src/timeline.ts
1456
+ function readMediaProgress(value, duration) {
1457
+ let version;
1458
+ let at;
1459
+ let furthest;
1460
+ try {
1461
+ if (typeof value !== "object" || value === null) {
1462
+ return null;
1463
+ }
1464
+ ({ progressVersion: version, at, furthest } = value);
1465
+ } catch (e) {
1466
+ return null;
1467
+ }
1468
+ if (version !== "1.0" || typeof at !== "number" || !Number.isFinite(at)) {
1469
+ return null;
1470
+ }
1471
+ const end = typeof duration === "number" && Number.isFinite(duration) && duration >= 0 ? duration : Number.POSITIVE_INFINITY;
1472
+ const clampedAt = Math.min(Math.max(0, at), end);
1473
+ const reached = typeof furthest === "number" && Number.isFinite(furthest) ? furthest : clampedAt;
1474
+ return {
1475
+ progressVersion: "1.0",
1476
+ at: clampedAt,
1477
+ furthest: Math.min(Math.max(clampedAt, reached), end)
1478
+ };
1479
+ }
1480
+ function composeTimelineScore(entryKey, items, policy) {
1481
+ const own = items.filter((item) => entryKeyOf(item.slotId) === entryKey);
1482
+ if (own.length === 0) {
1483
+ throw new Error(
1484
+ `composeTimelineScore: no scored item belongs to entry "${entryKey}". Pass the video's slotKey (or its position in the sequence), and the items of the attempt that holds it.`
1485
+ );
1486
+ }
1487
+ return _chunk6P6XK2LIcjs.composeAssessmentScore.call(void 0, [{ id: entryKey, weight: 1, items: own }], policy);
1488
+ }
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1201
1503
 
1202
1504
 
1203
1505
 
@@ -1330,5 +1632,5 @@ function assertRedactedItemGroup(data) {
1330
1632
 
1331
1633
 
1332
1634
 
1333
- exports.ActivitySchemaError = _chunkVCXIPLEWcjs.ActivitySchemaError; exports.BlankConfigSchema = _chunkVCXIPLEWcjs.BlankConfigSchema; exports.DEFAULT_PASS_THRESHOLD = _chunkJ5OIRIOWcjs.DEFAULT_PASS_THRESHOLD; exports.DICTATION_MAX_ACCEPTED_TRANSCRIPTS = _chunkVCXIPLEWcjs.DICTATION_MAX_ACCEPTED_TRANSCRIPTS; exports.DICTATION_MAX_EQUIVALENCES = _chunkVCXIPLEWcjs.DICTATION_MAX_EQUIVALENCES; exports.DICTATION_MAX_EQUIVALENCE_LENGTH = _chunkVCXIPLEWcjs.DICTATION_MAX_EQUIVALENCE_LENGTH; exports.DICTATION_MAX_TEXT_LENGTH = _chunkVCXIPLEWcjs.DICTATION_MAX_TEXT_LENGTH; exports.DICTATION_MAX_TRANSCRIPT_LENGTH = _chunkVCXIPLEWcjs.DICTATION_MAX_TRANSCRIPT_LENGTH; exports.DeferredScoringError = _chunkVCXIPLEWcjs.DeferredScoringError; exports.DictationDataSchema = _chunkVCXIPLEWcjs.DictationDataSchema; exports.DictationEquivalenceSchema = _chunkVCXIPLEWcjs.DictationEquivalenceSchema; exports.DictationSlowMediaSchema = _chunkVCXIPLEWcjs.DictationSlowMediaSchema; exports.DictationToleranceSchema = _chunkVCXIPLEWcjs.DictationToleranceSchema; exports.FeedbackSchema = _chunkVCXIPLEWcjs.FeedbackSchema; exports.FillInTheBlanksDataSchema = _chunkVCXIPLEWcjs.FillInTheBlanksDataSchema; exports.GapSelectBankSchema = _chunkVCXIPLEWcjs.GapSelectBankSchema; exports.GapSelectChoiceSchema = _chunkVCXIPLEWcjs.GapSelectChoiceSchema; exports.GapSelectDataSchema = _chunkVCXIPLEWcjs.GapSelectDataSchema; exports.GapSelectGapSchema = _chunkVCXIPLEWcjs.GapSelectGapSchema; exports.ItemGroupSchema = _chunk2NIALQEHcjs.ItemGroupSchema; exports.MediaPlaybackSchema = _chunkVCXIPLEWcjs.MediaPlaybackSchema; exports.MediaSchema = _chunkVCXIPLEWcjs.MediaSchema; exports.MediaUrlSchema = _chunkVCXIPLEWcjs.MediaUrlSchema; exports.MultipleChoiceDataSchema = _chunkVCXIPLEWcjs.MultipleChoiceDataSchema; exports.MultipleChoiceOptionMediaSchema = _chunkVCXIPLEWcjs.MultipleChoiceOptionMediaSchema; exports.MultipleChoiceOptionSchema = _chunkVCXIPLEWcjs.MultipleChoiceOptionSchema; exports.NativeControlHintSchema = _chunkVCXIPLEWcjs.NativeControlHintSchema; exports.READ_ALOUD_MAX_DIMENSION_WEIGHT = _chunkVCXIPLEWcjs.READ_ALOUD_MAX_DIMENSION_WEIGHT; exports.READ_ALOUD_MAX_REFERENCE_LENGTH = _chunkVCXIPLEWcjs.READ_ALOUD_MAX_REFERENCE_LENGTH; exports.READ_ALOUD_MAX_SECONDS = _chunkVCXIPLEWcjs.READ_ALOUD_MAX_SECONDS; exports.READ_ALOUD_MAX_TAKES = _chunkVCXIPLEWcjs.READ_ALOUD_MAX_TAKES; exports.ReadAloudDataSchema = _chunkVCXIPLEWcjs.ReadAloudDataSchema; exports.ReadAloudSlowMediaSchema = _chunkVCXIPLEWcjs.ReadAloudSlowMediaSchema; exports.RedactedBlankConfigSchema = _chunkVCXIPLEWcjs.RedactedBlankConfigSchema; exports.RedactedDictationDataSchema = _chunkVCXIPLEWcjs.RedactedDictationDataSchema; exports.RedactedDictationSlowMediaSchema = _chunkVCXIPLEWcjs.RedactedDictationSlowMediaSchema; exports.RedactedFillInTheBlanksDataSchema = _chunkVCXIPLEWcjs.RedactedFillInTheBlanksDataSchema; exports.RedactedGapSelectBankSchema = _chunkVCXIPLEWcjs.RedactedGapSelectBankSchema; exports.RedactedGapSelectChoiceSchema = _chunkVCXIPLEWcjs.RedactedGapSelectChoiceSchema; exports.RedactedGapSelectDataSchema = _chunkVCXIPLEWcjs.RedactedGapSelectDataSchema; exports.RedactedGapSelectGapSchema = _chunkVCXIPLEWcjs.RedactedGapSelectGapSchema; exports.RedactedItemGroupSchema = _chunk2NIALQEHcjs.RedactedItemGroupSchema; exports.RedactedMediaSchema = _chunkVCXIPLEWcjs.RedactedMediaSchema; exports.RedactedMultipleChoiceDataSchema = _chunkVCXIPLEWcjs.RedactedMultipleChoiceDataSchema; exports.RedactedMultipleChoiceOptionMediaSchema = _chunkVCXIPLEWcjs.RedactedMultipleChoiceOptionMediaSchema; exports.RedactedMultipleChoiceOptionSchema = _chunkVCXIPLEWcjs.RedactedMultipleChoiceOptionSchema; exports.RedactedReadAloudDataSchema = _chunkVCXIPLEWcjs.RedactedReadAloudDataSchema; exports.RedactedScoringError = _chunkVCXIPLEWcjs.RedactedScoringError; exports.RedactedStimulusSchema = _chunk2NIALQEHcjs.RedactedStimulusSchema; exports.RedactedWrittenResponseDataSchema = _chunkVCXIPLEWcjs.RedactedWrittenResponseDataSchema; exports.SPEECH_ASSESSMENT_MAX_WORDS = _chunkVCXIPLEWcjs.SPEECH_ASSESSMENT_MAX_WORDS; exports.StimulusSchema = _chunk2NIALQEHcjs.StimulusSchema; exports.TextMatchPolicySchema = _chunkVCXIPLEWcjs.TextMatchPolicySchema; exports.UnknownActivityTypeError = _chunkVCXIPLEWcjs.UnknownActivityTypeError; exports.WrittenResponseDataSchema = _chunkVCXIPLEWcjs.WrittenResponseDataSchema; exports.WrittenResponseRubricCriterionSchema = _chunkVCXIPLEWcjs.WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = _chunkVCXIPLEWcjs.WrittenResponseRubricSchema; exports.XAPIVerb = _chunkE7LPIZXIcjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunkE7LPIZXIcjs.XAPI_VERB_DISPLAY; exports.alignDictation = _chunkVCXIPLEWcjs.alignDictation; exports.alignReadAloud = _chunkJ5OIRIOWcjs.alignReadAloud; exports.assertRedacted = assertRedacted; exports.assertRedactedItemGroup = assertRedactedItemGroup; exports.canonicalJson = canonicalJson; exports.classifyBand = _chunkJ5OIRIOWcjs.classifyBand; exports.composeAssessmentScore = _chunkJ5OIRIOWcjs.composeAssessmentScore; exports.computePassThreshold = _chunkJ5OIRIOWcjs.computePassThreshold; exports.contentHash = contentHash; exports.countWords = _chunkVCXIPLEWcjs.countWords; exports.createDraft = createDraft; exports.createItemGroupDraft = createItemGroupDraft; exports.defineActivityType = _chunkVCXIPLEWcjs.defineActivityType; exports.dictationJsonSchema = _chunk2NIALQEHcjs.dictationJsonSchema; exports.dictationReferenceWords = _chunkVCXIPLEWcjs.dictationReferenceWords; exports.dictationType = _chunkVCXIPLEWcjs.dictationType; exports.diffDictationChars = _chunkJ5OIRIOWcjs.diffDictationChars; exports.diffResponses = diffResponses; exports.entryKeyOf = entryKeyOf; exports.evaluate = _chunkJ5OIRIOWcjs.evaluate; exports.fillInTheBlanksJsonSchema = _chunk2NIALQEHcjs.fillInTheBlanksJsonSchema; exports.fillInTheBlanksType = _chunkVCXIPLEWcjs.fillInTheBlanksType; exports.fingerprint = fingerprint; exports.flattenSequence = flattenSequence; exports.gapSelectJsonSchema = _chunk2NIALQEHcjs.gapSelectJsonSchema; exports.gapSelectType = _chunkVCXIPLEWcjs.gapSelectType; exports.getActivityTypeDescriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor; exports.gradeFromRubric = _chunkJ5OIRIOWcjs.gradeFromRubric; exports.gradeReadAloud = _chunkJ5OIRIOWcjs.gradeReadAloud; exports.gte = _chunkJ5OIRIOWcjs.gte; exports.hasGrade = _chunkJ5OIRIOWcjs.hasGrade; exports.hashSeed = hashSeed; exports.inspectWav = _chunkJ5OIRIOWcjs.inspectWav; exports.isItemGroup = isItemGroup; exports.itemGroupJsonSchema = _chunk2NIALQEHcjs.itemGroupJsonSchema; exports.jsonSchemaFor = _chunk2NIALQEHcjs.jsonSchemaFor; exports.levenshteinDistance = _chunkVCXIPLEWcjs.levenshteinDistance; exports.matchText = _chunkVCXIPLEWcjs.matchText; exports.multipleChoiceJsonSchema = _chunk2NIALQEHcjs.multipleChoiceJsonSchema; exports.multipleChoiceType = _chunkVCXIPLEWcjs.multipleChoiceType; exports.outcomeFromGrade = _chunkJ5OIRIOWcjs.outcomeFromGrade; exports.outcomeFromUnscorable = _chunkJ5OIRIOWcjs.outcomeFromUnscorable; exports.planAttempt = planAttempt; exports.planMediaBudgets = planMediaBudgets; exports.readAloudJsonSchema = _chunk2NIALQEHcjs.readAloudJsonSchema; exports.readAloudType = _chunkVCXIPLEWcjs.readAloudType; exports.redact = redact; exports.redactItemGroup = redactItemGroup; exports.registerActivityType = _chunkVCXIPLEWcjs.registerActivityType; exports.registeredActivityTypes = _chunkVCXIPLEWcjs.registeredActivityTypes; exports.resolvePlaybackPolicy = resolvePlaybackPolicy; exports.restoreAttemptState = restoreAttemptState; exports.restoreMediaPlayLedger = restoreMediaPlayLedger; exports.roundGrade = _chunkJ5OIRIOWcjs.roundGrade; exports.score = _chunkJ5OIRIOWcjs.score; exports.scoredItemsFromPlan = scoredItemsFromPlan; exports.seededShuffle = seededShuffle; exports.serializeAttemptState = serializeAttemptState; exports.serializeMediaPlayLedger = serializeMediaPlayLedger; exports.slotMediaKey = slotMediaKey; exports.stimulusJsonSchema = _chunk2NIALQEHcjs.stimulusJsonSchema; exports.stimulusMediaKey = stimulusMediaKey; exports.validateActivity = _chunk2NIALQEHcjs.validateActivity; exports.validateDraft = validateDraft; exports.validateItemGroup = _chunk2NIALQEHcjs.validateItemGroup; exports.validateItemGroupDraft = validateItemGroupDraft; exports.validateSpeechAssessment = _chunkJ5OIRIOWcjs.validateSpeechAssessment; exports.validateXAPIStatement = _chunkE7LPIZXIcjs.validateXAPIStatement; exports.verifyAttemptPlan = verifyAttemptPlan; exports.writtenResponseJsonSchema = _chunk2NIALQEHcjs.writtenResponseJsonSchema; exports.writtenResponseType = _chunkVCXIPLEWcjs.writtenResponseType; exports.xAPIBuilder = _chunkE7LPIZXIcjs.xAPIBuilder; exports.xapiDefinitionFor = _chunkE7LPIZXIcjs.xapiDefinitionFor;
1635
+ exports.ActivitySchemaError = _chunkF7UOLKWVcjs.ActivitySchemaError; exports.BlankConfigSchema = _chunkF7UOLKWVcjs.BlankConfigSchema; exports.DEFAULT_PASS_THRESHOLD = _chunk6P6XK2LIcjs.DEFAULT_PASS_THRESHOLD; exports.DICTATION_MAX_ACCEPTED_TRANSCRIPTS = _chunkF7UOLKWVcjs.DICTATION_MAX_ACCEPTED_TRANSCRIPTS; exports.DICTATION_MAX_EQUIVALENCES = _chunkF7UOLKWVcjs.DICTATION_MAX_EQUIVALENCES; exports.DICTATION_MAX_EQUIVALENCE_LENGTH = _chunkF7UOLKWVcjs.DICTATION_MAX_EQUIVALENCE_LENGTH; exports.DICTATION_MAX_TEXT_LENGTH = _chunkF7UOLKWVcjs.DICTATION_MAX_TEXT_LENGTH; exports.DICTATION_MAX_TRANSCRIPT_LENGTH = _chunkF7UOLKWVcjs.DICTATION_MAX_TRANSCRIPT_LENGTH; exports.DeferredScoringError = _chunkF7UOLKWVcjs.DeferredScoringError; exports.DictationDataSchema = _chunkF7UOLKWVcjs.DictationDataSchema; exports.DictationEquivalenceSchema = _chunkF7UOLKWVcjs.DictationEquivalenceSchema; exports.DictationSlowMediaSchema = _chunkF7UOLKWVcjs.DictationSlowMediaSchema; exports.DictationToleranceSchema = _chunkF7UOLKWVcjs.DictationToleranceSchema; exports.FeedbackSchema = _chunkF7UOLKWVcjs.FeedbackSchema; exports.FillInTheBlanksDataSchema = _chunkF7UOLKWVcjs.FillInTheBlanksDataSchema; exports.GapSelectBankSchema = _chunkF7UOLKWVcjs.GapSelectBankSchema; exports.GapSelectChoiceSchema = _chunkF7UOLKWVcjs.GapSelectChoiceSchema; exports.GapSelectDataSchema = _chunkF7UOLKWVcjs.GapSelectDataSchema; exports.GapSelectGapSchema = _chunkF7UOLKWVcjs.GapSelectGapSchema; exports.INTERACTIVE_VIDEO_ITEM_TYPES = _chunkFJJ2GVBAcjs.INTERACTIVE_VIDEO_ITEM_TYPES; exports.ItemGroupSchema = _chunkFJJ2GVBAcjs.ItemGroupSchema; exports.MediaPlaybackSchema = _chunkF7UOLKWVcjs.MediaPlaybackSchema; exports.MediaSchema = _chunkF7UOLKWVcjs.MediaSchema; exports.MediaTimelineSchema = _chunkFJJ2GVBAcjs.MediaTimelineSchema; exports.MediaTrackSchema = _chunkF7UOLKWVcjs.MediaTrackSchema; exports.MediaUrlSchema = _chunkF7UOLKWVcjs.MediaUrlSchema; exports.MultipleChoiceDataSchema = _chunkF7UOLKWVcjs.MultipleChoiceDataSchema; exports.MultipleChoiceOptionMediaSchema = _chunkF7UOLKWVcjs.MultipleChoiceOptionMediaSchema; exports.MultipleChoiceOptionSchema = _chunkF7UOLKWVcjs.MultipleChoiceOptionSchema; exports.NativeControlHintSchema = _chunkF7UOLKWVcjs.NativeControlHintSchema; exports.READ_ALOUD_MAX_DIMENSION_WEIGHT = _chunkF7UOLKWVcjs.READ_ALOUD_MAX_DIMENSION_WEIGHT; exports.READ_ALOUD_MAX_REFERENCE_LENGTH = _chunkF7UOLKWVcjs.READ_ALOUD_MAX_REFERENCE_LENGTH; exports.READ_ALOUD_MAX_SECONDS = _chunkF7UOLKWVcjs.READ_ALOUD_MAX_SECONDS; exports.READ_ALOUD_MAX_TAKES = _chunkF7UOLKWVcjs.READ_ALOUD_MAX_TAKES; exports.ReadAloudDataSchema = _chunkF7UOLKWVcjs.ReadAloudDataSchema; exports.ReadAloudSlowMediaSchema = _chunkF7UOLKWVcjs.ReadAloudSlowMediaSchema; exports.RedactedBlankConfigSchema = _chunkF7UOLKWVcjs.RedactedBlankConfigSchema; exports.RedactedDictationDataSchema = _chunkF7UOLKWVcjs.RedactedDictationDataSchema; exports.RedactedDictationSlowMediaSchema = _chunkF7UOLKWVcjs.RedactedDictationSlowMediaSchema; exports.RedactedFillInTheBlanksDataSchema = _chunkF7UOLKWVcjs.RedactedFillInTheBlanksDataSchema; exports.RedactedGapSelectBankSchema = _chunkF7UOLKWVcjs.RedactedGapSelectBankSchema; exports.RedactedGapSelectChoiceSchema = _chunkF7UOLKWVcjs.RedactedGapSelectChoiceSchema; exports.RedactedGapSelectDataSchema = _chunkF7UOLKWVcjs.RedactedGapSelectDataSchema; exports.RedactedGapSelectGapSchema = _chunkF7UOLKWVcjs.RedactedGapSelectGapSchema; exports.RedactedItemGroupSchema = _chunkFJJ2GVBAcjs.RedactedItemGroupSchema; exports.RedactedMediaSchema = _chunkF7UOLKWVcjs.RedactedMediaSchema; exports.RedactedMultipleChoiceDataSchema = _chunkF7UOLKWVcjs.RedactedMultipleChoiceDataSchema; exports.RedactedMultipleChoiceOptionMediaSchema = _chunkF7UOLKWVcjs.RedactedMultipleChoiceOptionMediaSchema; exports.RedactedMultipleChoiceOptionSchema = _chunkF7UOLKWVcjs.RedactedMultipleChoiceOptionSchema; exports.RedactedReadAloudDataSchema = _chunkF7UOLKWVcjs.RedactedReadAloudDataSchema; exports.RedactedScoringError = _chunkF7UOLKWVcjs.RedactedScoringError; exports.RedactedStimulusSchema = _chunkFJJ2GVBAcjs.RedactedStimulusSchema; exports.RedactedWrittenResponseDataSchema = _chunkF7UOLKWVcjs.RedactedWrittenResponseDataSchema; exports.SPEECH_ASSESSMENT_MAX_WORDS = _chunkF7UOLKWVcjs.SPEECH_ASSESSMENT_MAX_WORDS; exports.StimulusSchema = _chunkFJJ2GVBAcjs.StimulusSchema; exports.TIMELINE_MAX_CHAPTERS = _chunkFJJ2GVBAcjs.TIMELINE_MAX_CHAPTERS; exports.TIMELINE_MAX_ITEMS = _chunkFJJ2GVBAcjs.TIMELINE_MAX_ITEMS; exports.TIMELINE_MAX_QUIZZES = _chunkFJJ2GVBAcjs.TIMELINE_MAX_QUIZZES; exports.TIMELINE_MAX_TITLE_LENGTH = _chunkFJJ2GVBAcjs.TIMELINE_MAX_TITLE_LENGTH; exports.TextMatchPolicySchema = _chunkF7UOLKWVcjs.TextMatchPolicySchema; exports.TimelineChapterSchema = _chunkFJJ2GVBAcjs.TimelineChapterSchema; exports.TimelineCueSchema = _chunkFJJ2GVBAcjs.TimelineCueSchema; exports.UnknownActivityTypeError = _chunkF7UOLKWVcjs.UnknownActivityTypeError; exports.WrittenResponseDataSchema = _chunkF7UOLKWVcjs.WrittenResponseDataSchema; exports.WrittenResponseRubricCriterionSchema = _chunkF7UOLKWVcjs.WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = _chunkF7UOLKWVcjs.WrittenResponseRubricSchema; exports.XAPIVerb = _chunkVFTVZJO5cjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunkVFTVZJO5cjs.XAPI_VERB_DISPLAY; exports.alignDictation = _chunkF7UOLKWVcjs.alignDictation; exports.alignReadAloud = _chunk6P6XK2LIcjs.alignReadAloud; exports.assertRedacted = assertRedacted; exports.assertRedactedItemGroup = assertRedactedItemGroup; exports.canonicalJson = canonicalJson; exports.classifyBand = _chunk6P6XK2LIcjs.classifyBand; exports.composeAssessmentScore = _chunk6P6XK2LIcjs.composeAssessmentScore; exports.composeTimelineScore = composeTimelineScore; exports.computePassThreshold = _chunk6P6XK2LIcjs.computePassThreshold; exports.contentHash = contentHash; exports.countWords = _chunkF7UOLKWVcjs.countWords; exports.createDraft = createDraft; exports.createInteractiveVideoDraft = createInteractiveVideoDraft; exports.createItemGroupDraft = createItemGroupDraft; exports.defineActivityType = _chunkF7UOLKWVcjs.defineActivityType; exports.dictationJsonSchema = _chunkFJJ2GVBAcjs.dictationJsonSchema; exports.dictationReferenceWords = _chunkF7UOLKWVcjs.dictationReferenceWords; exports.dictationType = _chunkF7UOLKWVcjs.dictationType; exports.diffDictationChars = _chunk6P6XK2LIcjs.diffDictationChars; exports.diffResponses = diffResponses; exports.entryKeyOf = entryKeyOf; exports.evaluate = _chunk6P6XK2LIcjs.evaluate; exports.fillInTheBlanksJsonSchema = _chunkFJJ2GVBAcjs.fillInTheBlanksJsonSchema; exports.fillInTheBlanksType = _chunkF7UOLKWVcjs.fillInTheBlanksType; exports.fingerprint = fingerprint; exports.flattenSequence = flattenSequence; exports.gapSelectJsonSchema = _chunkFJJ2GVBAcjs.gapSelectJsonSchema; exports.gapSelectType = _chunkF7UOLKWVcjs.gapSelectType; exports.getActivityTypeDescriptor = _chunkF7UOLKWVcjs.getActivityTypeDescriptor; exports.gradeFromRubric = _chunk6P6XK2LIcjs.gradeFromRubric; exports.gradeReadAloud = _chunk6P6XK2LIcjs.gradeReadAloud; exports.gte = _chunk6P6XK2LIcjs.gte; exports.hasGrade = _chunk6P6XK2LIcjs.hasGrade; exports.hashSeed = hashSeed; exports.inspectWav = _chunk6P6XK2LIcjs.inspectWav; exports.isInteractiveVideoItemType = _chunkFJJ2GVBAcjs.isInteractiveVideoItemType; exports.isItemGroup = isItemGroup; exports.itemGroupJsonSchema = _chunkFJJ2GVBAcjs.itemGroupJsonSchema; exports.jsonSchemaFor = _chunkFJJ2GVBAcjs.jsonSchemaFor; exports.levenshteinDistance = _chunkF7UOLKWVcjs.levenshteinDistance; exports.matchText = _chunkF7UOLKWVcjs.matchText; exports.multipleChoiceJsonSchema = _chunkFJJ2GVBAcjs.multipleChoiceJsonSchema; exports.multipleChoiceType = _chunkF7UOLKWVcjs.multipleChoiceType; exports.outcomeFromGrade = _chunk6P6XK2LIcjs.outcomeFromGrade; exports.outcomeFromUnscorable = _chunk6P6XK2LIcjs.outcomeFromUnscorable; exports.planAttempt = planAttempt; exports.planMediaBudgets = planMediaBudgets; exports.readAloudJsonSchema = _chunkFJJ2GVBAcjs.readAloudJsonSchema; exports.readAloudType = _chunkF7UOLKWVcjs.readAloudType; exports.readMediaProgress = readMediaProgress; exports.redact = redact; exports.redactItemGroup = redactItemGroup; exports.registerActivityType = _chunkF7UOLKWVcjs.registerActivityType; exports.registeredActivityTypes = _chunkF7UOLKWVcjs.registeredActivityTypes; exports.resolvePlaybackPolicy = resolvePlaybackPolicy; exports.restoreAttemptState = restoreAttemptState; exports.restoreMediaPlayLedger = restoreMediaPlayLedger; exports.roundGrade = _chunk6P6XK2LIcjs.roundGrade; exports.score = _chunk6P6XK2LIcjs.score; exports.scoredItemsFromPlan = scoredItemsFromPlan; exports.seededShuffle = seededShuffle; exports.serializeAttemptState = serializeAttemptState; exports.serializeMediaPlayLedger = serializeMediaPlayLedger; exports.slotMediaKey = slotMediaKey; exports.stimulusJsonSchema = _chunkFJJ2GVBAcjs.stimulusJsonSchema; exports.stimulusMediaKey = stimulusMediaKey; exports.validateActivity = _chunkFJJ2GVBAcjs.validateActivity; exports.validateDraft = validateDraft; exports.validateItemGroup = _chunkFJJ2GVBAcjs.validateItemGroup; exports.validateItemGroupDraft = validateItemGroupDraft; exports.validateSpeechAssessment = _chunk6P6XK2LIcjs.validateSpeechAssessment; exports.validateXAPIStatement = _chunkVFTVZJO5cjs.validateXAPIStatement; exports.verifyAttemptPlan = verifyAttemptPlan; exports.writtenResponseJsonSchema = _chunkFJJ2GVBAcjs.writtenResponseJsonSchema; exports.writtenResponseType = _chunkF7UOLKWVcjs.writtenResponseType; exports.xAPIBuilder = _chunkVFTVZJO5cjs.xAPIBuilder; exports.xapiDefinitionFor = _chunkVFTVZJO5cjs.xapiDefinitionFor;
1334
1636
  //# sourceMappingURL=index.cjs.map