@intellectif/lk-core 1.4.0 → 1.6.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 (89) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/README.md +2 -0
  3. package/dist/ai-check.cjs +175 -17
  4. package/dist/ai-check.cjs.map +1 -1
  5. package/dist/ai-check.d.cts +13 -5
  6. package/dist/ai-check.d.cts.map +1 -1
  7. package/dist/ai-check.d.ts +13 -5
  8. package/dist/ai-check.d.ts.map +1 -1
  9. package/dist/ai-check.js +175 -17
  10. package/dist/ai-check.js.map +1 -1
  11. package/dist/{ai-CnmLPMzd.d.ts → ai-i3jwXnpX.d.cts} +242 -7
  12. package/dist/ai-i3jwXnpX.d.cts.map +1 -0
  13. package/dist/{ai-CnmLPMzd.d.cts → ai-i3jwXnpX.d.ts} +242 -7
  14. package/dist/ai-i3jwXnpX.d.ts.map +1 -0
  15. package/dist/{ai-writing-G6tnCGzw.cjs → ai-writing-C4YRVrFi.cjs} +683 -72
  16. package/dist/ai-writing-C4YRVrFi.cjs.map +1 -0
  17. package/dist/{ai-writing-CPpH9Qxq.js → ai-writing-OJ5m_1EB.js} +663 -88
  18. package/dist/ai-writing-OJ5m_1EB.js.map +1 -0
  19. package/dist/{index-BqMXWuNC.d.cts → index--U7hHV0s.d.cts} +2 -2
  20. package/dist/{index-BqMXWuNC.d.cts.map → index--U7hHV0s.d.cts.map} +1 -1
  21. package/dist/{index-B54baFUA.d.ts → index-CFRgZLhH.d.cts} +45 -12
  22. package/dist/index-CFRgZLhH.d.cts.map +1 -0
  23. package/dist/{index-CVWvymVb.d.ts → index-DeD8EI1D.d.ts} +327 -3
  24. package/dist/index-DeD8EI1D.d.ts.map +1 -0
  25. package/dist/{index-CcHDTxIZ.d.ts → index-Dj92T76o.d.ts} +2 -2
  26. package/dist/{index-CcHDTxIZ.d.ts.map → index-Dj92T76o.d.ts.map} +1 -1
  27. package/dist/{index-BAfEHCnD.d.cts → index-Uh1u57yq.d.cts} +327 -3
  28. package/dist/index-Uh1u57yq.d.cts.map +1 -0
  29. package/dist/{index-2nigSf4N.d.cts → index-WBHSrIUU.d.ts} +45 -12
  30. package/dist/index-WBHSrIUU.d.ts.map +1 -0
  31. package/dist/index.cjs +88 -131
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +217 -95
  34. package/dist/index.d.cts.map +1 -1
  35. package/dist/index.d.ts +217 -95
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +60 -118
  38. package/dist/index.js.map +1 -1
  39. package/dist/{item-group-DXiR8nOr.js → item-group-BbvvH_Ob.js} +3 -2
  40. package/dist/item-group-BbvvH_Ob.js.map +1 -0
  41. package/dist/{item-group-DroFXgLb.cjs → item-group-CQRbb8Rx.cjs} +3 -2
  42. package/dist/item-group-CQRbb8Rx.cjs.map +1 -0
  43. package/dist/{registry-Dsx9mNsS.js → registry-B23o9UWh.js} +218 -21
  44. package/dist/registry-B23o9UWh.js.map +1 -0
  45. package/dist/{registry-DVi0LR_i.cjs → registry-Ih5n4PVZ.cjs} +265 -20
  46. package/dist/registry-Ih5n4PVZ.cjs.map +1 -0
  47. package/dist/{schemas-DVbAOrtd.cjs → schemas-Q2dyOgc2.cjs} +77 -14
  48. package/dist/schemas-Q2dyOgc2.cjs.map +1 -0
  49. package/dist/{schemas-Bdw0nGPo.js → schemas-yId-bJhD.js} +72 -15
  50. package/dist/schemas-yId-bJhD.js.map +1 -0
  51. package/dist/schemas.cjs +5 -2
  52. package/dist/schemas.d.cts +2 -2
  53. package/dist/schemas.d.ts +2 -2
  54. package/dist/schemas.js +4 -3
  55. package/dist/{scoring-BZqUkuDF.js → scoring-CLMdk8i9.js} +657 -3
  56. package/dist/scoring-CLMdk8i9.js.map +1 -0
  57. package/dist/{scoring-B2_HEhMT.cjs → scoring-CaPS6q8b.cjs} +722 -2
  58. package/dist/scoring-CaPS6q8b.cjs.map +1 -0
  59. package/dist/scoring.cjs +8 -2
  60. package/dist/scoring.d.cts +3 -3
  61. package/dist/scoring.d.ts +3 -3
  62. package/dist/scoring.js +3 -3
  63. package/dist/{xapi-DNzkSJ0S.cjs → xapi-BX0hvRRB.cjs} +2 -2
  64. package/dist/{xapi-DNzkSJ0S.cjs.map → xapi-BX0hvRRB.cjs.map} +1 -1
  65. package/dist/{xapi-CMTph7wG.js → xapi-Cdk9fTvV.js} +2 -2
  66. package/dist/{xapi-CMTph7wG.js.map → xapi-Cdk9fTvV.js.map} +1 -1
  67. package/dist/xapi.cjs +1 -1
  68. package/dist/xapi.d.cts +1 -1
  69. package/dist/xapi.d.ts +1 -1
  70. package/dist/xapi.js +1 -2
  71. package/package.json +2 -2
  72. package/vectors/README.md +24 -1
  73. package/vectors/scoring.json +18182 -1
  74. package/dist/ai-CnmLPMzd.d.cts.map +0 -1
  75. package/dist/ai-CnmLPMzd.d.ts.map +0 -1
  76. package/dist/ai-writing-CPpH9Qxq.js.map +0 -1
  77. package/dist/ai-writing-G6tnCGzw.cjs.map +0 -1
  78. package/dist/index-2nigSf4N.d.cts.map +0 -1
  79. package/dist/index-B54baFUA.d.ts.map +0 -1
  80. package/dist/index-BAfEHCnD.d.cts.map +0 -1
  81. package/dist/index-CVWvymVb.d.ts.map +0 -1
  82. package/dist/item-group-DXiR8nOr.js.map +0 -1
  83. package/dist/item-group-DroFXgLb.cjs.map +0 -1
  84. package/dist/registry-DVi0LR_i.cjs.map +0 -1
  85. package/dist/registry-Dsx9mNsS.js.map +0 -1
  86. package/dist/schemas-Bdw0nGPo.js.map +0 -1
  87. package/dist/schemas-DVbAOrtd.cjs.map +0 -1
  88. package/dist/scoring-B2_HEhMT.cjs.map +0 -1
  89. package/dist/scoring-BZqUkuDF.js.map +0 -1
@@ -157,6 +157,20 @@ const MediaTrackSchema = zod_v4.strictObject({
157
157
  default: zod_v4.boolean().optional()
158
158
  });
159
159
  const MAX_TRACKS = 12;
160
+ /** The most turns a recording's `script` may hold. */
161
+ const SCRIPT_MAX_TURNS = 500;
162
+ /**
163
+ * One speaker's turn in an author-only `script`. Loose, as content is: a host
164
+ * may keep its own fields on a turn (the voice it cast, a direction for it).
165
+ * Unlike a track's, both fields are required, so a misspelt one is still
166
+ * caught.
167
+ */
168
+ const ScriptTurnSchema = zod_v4.looseObject({
169
+ speaker: maxUnits(zod_v4.string(), 60).refine((speaker) => speaker.trim().length > 0, { error: "A script turn needs a speaker." }),
170
+ text: zod_v4.string().refine((text) => text.trim().length > 0, { error: "A script turn needs words." })
171
+ });
172
+ /** An author-only `script`: one turn or more, in the order they are spoken. */
173
+ const ScriptSchema = zod_v4.array(ScriptTurnSchema).min(1).max(500);
160
174
  /** `poster` on anything but a video: an image with nothing to stand in for. */
161
175
  function posterFits(m) {
162
176
  return m.poster === void 0 || m.type === "video";
@@ -199,7 +213,9 @@ const MediaSchema = zod_v4.looseObject({
199
213
  captionsUrl: MediaUrlSchema.optional(),
200
214
  tracks: zod_v4.array(MediaTrackSchema).min(1).max(MAX_TRACKS).optional(),
201
215
  poster: MediaUrlSchema.optional(),
202
- playback: MediaPlaybackSchema.optional()
216
+ playback: MediaPlaybackSchema.optional(),
217
+ transcript: zod_v4.string().optional(),
218
+ script: ScriptSchema.optional()
203
219
  }).refine((m) => m.type !== "image" && m.type !== "embed" || typeof m.alt === "string" && m.alt.length > 0, {
204
220
  error: "image and embed media require non-empty alt text (WCAG 1.1.1 / 4.1.2).",
205
221
  path: ["alt"]
@@ -2755,6 +2771,97 @@ function countWords(text) {
2755
2771
  if (trimmed === "") return 0;
2756
2772
  return trimmed.split(/\s+/).length;
2757
2773
  }
2774
+ /** A label as labels are compared: composed, trimmed, its spacing collapsed, lower-cased. */
2775
+ function levelKey(label) {
2776
+ return label.normalize("NFC").trim().replace(/\s+/gu, " ").toLowerCase();
2777
+ }
2778
+ /**
2779
+ * The levels in `value`, or the first reason they cannot be used. `null` or
2780
+ * absent means the criterion has no levels, which is not a problem: it is
2781
+ * judged on a score.
2782
+ *
2783
+ * Each element and each field is read once, so a getter cannot pass the check
2784
+ * with one value and hand the grader another. The levels come back as written.
2785
+ */
2786
+ function readRubricLevels(value) {
2787
+ if (value === void 0 || value === null) return {
2788
+ ok: true,
2789
+ levels: null
2790
+ };
2791
+ if (!Array.isArray(value)) return {
2792
+ ok: false,
2793
+ problem: "not-a-list"
2794
+ };
2795
+ const count = value.length;
2796
+ if (count < 2) return {
2797
+ ok: false,
2798
+ problem: "too-few"
2799
+ };
2800
+ if (count > 10) return {
2801
+ ok: false,
2802
+ problem: "too-many"
2803
+ };
2804
+ const levels = [];
2805
+ const seen = /* @__PURE__ */ new Set();
2806
+ for (let index = 0; index < count; index += 1) {
2807
+ const entry = value[index];
2808
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return {
2809
+ ok: false,
2810
+ problem: "not-a-level",
2811
+ index
2812
+ };
2813
+ const record = entry;
2814
+ const label = record.label;
2815
+ const description = record.description;
2816
+ if (typeof label !== "string" || label.trim() === "") return {
2817
+ ok: false,
2818
+ problem: "no-label",
2819
+ index
2820
+ };
2821
+ if (description !== void 0 && typeof description !== "string") return {
2822
+ ok: false,
2823
+ problem: "bad-description",
2824
+ index
2825
+ };
2826
+ const key = levelKey(label);
2827
+ if (seen.has(key)) return {
2828
+ ok: false,
2829
+ problem: "duplicate-label",
2830
+ index
2831
+ };
2832
+ seen.add(key);
2833
+ levels.push({
2834
+ label,
2835
+ ...description !== void 0 ? { description } : {}
2836
+ });
2837
+ }
2838
+ return {
2839
+ ok: true,
2840
+ levels
2841
+ };
2842
+ }
2843
+ /**
2844
+ * How far level probabilities may sum from 1 and still be a distribution:
2845
+ * rounding in a grader's output, not a different judgement.
2846
+ */
2847
+ const LEVEL_PROBABILITY_TOLERANCE = 1e-6;
2848
+ /**
2849
+ * `values` as a distribution over `count` levels whose likeliest is level
2850
+ * `chosen`, a tie for likeliest included: each a finite number from 0 to 1,
2851
+ * together 1 within {@link LEVEL_PROBABILITY_TOLERANCE}. `null` when they are
2852
+ * not one.
2853
+ *
2854
+ * The AI check refuses a reply whose probabilities are not a distribution, and
2855
+ * calibration and routing read a grade's the same way, so probabilities the
2856
+ * check let through are never ignored downstream. Each element is read once,
2857
+ * a hole as `undefined`, into the copy returned.
2858
+ */
2859
+ function levelDistribution(values, count, chosen) {
2860
+ const read = Array.from(values);
2861
+ if (read.length !== count || !read.every((p) => typeof p === "number" && p >= 0 && p <= 1)) return null;
2862
+ const sum = read.reduce((total, p) => total + p, 0);
2863
+ return Math.abs(sum - 1) <= 1e-6 && read[chosen] === Math.max(...read) ? read : null;
2864
+ }
2758
2865
  //#endregion
2759
2866
  //#region src/scoring/strategies/all-or-nothing.ts
2760
2867
  /**
@@ -2971,7 +3078,11 @@ const ITEM_FINDING_SEVERITY = {
2971
3078
  gs_bank_no_distractor: "warning",
2972
3079
  gs_answer_in_passage: "warning",
2973
3080
  wr_criterion_name_duplicate: "warning",
3081
+ wr_levels_unreadable: "warning",
2974
3082
  ra_text_long_for_time: "warning",
3083
+ media_transcript_unused: "advice",
3084
+ media_script_differs: "warning",
3085
+ media_transcript_differs: "warning",
2975
3086
  set_key_position_same: "warning"
2976
3087
  };
2977
3088
  function finding(code, path, message) {
@@ -3221,14 +3332,38 @@ function critiqueGapSelect(draft) {
3221
3332
  });
3222
3333
  return findings;
3223
3334
  }
3335
+ /** Why a criterion's levels cannot be graded on, said to the author. */
3336
+ const LEVELS_PROBLEM = {
3337
+ "not-a-list": (criterion) => `Criterion ${criterion}'s levels are not a list`,
3338
+ "too-few": (criterion) => `Criterion ${criterion} has fewer than 2 levels`,
3339
+ "too-many": (criterion) => `Criterion ${criterion} has more than 10 levels`,
3340
+ "not-a-level": (criterion, level) => `Level ${level} of criterion ${criterion} is not a level`,
3341
+ "no-label": (criterion, level) => `Level ${level} of criterion ${criterion} has no label`,
3342
+ "bad-description": (criterion, level) => `Level ${level} of criterion ${criterion} has a description that is not text`,
3343
+ "duplicate-label": (criterion, level) => `Level ${level} of criterion ${criterion} has the label of an earlier level`
3344
+ };
3224
3345
  function critiqueWrittenResponse(draft) {
3225
3346
  const rubric = isRecord(draft.rubric) ? draft.rubric : void 0;
3226
- return duplicates(rubric === void 0 ? [] : listOf(rubric.criteria), (criterion) => isRecord(criterion) ? written(criterion.name) : void 0).map(({ first, second }) => finding("wr_criterion_name_duplicate", [
3347
+ const criteria = rubric === void 0 ? [] : listOf(rubric.criteria);
3348
+ const names = duplicates(criteria, (criterion) => isRecord(criterion) ? written(criterion.name) : void 0).map(({ first, second }) => finding("wr_criterion_name_duplicate", [
3227
3349
  "rubric",
3228
3350
  "criteria",
3229
3351
  second,
3230
3352
  "name"
3231
3353
  ], `Criteria ${ordinal(first)} and ${ordinal(second)} have the same name. Feedback and grades name a criterion, so one of them cannot be told apart.`));
3354
+ const levels = criteria.flatMap((criterion, index) => {
3355
+ if (!isRecord(criterion)) return [];
3356
+ const read = readRubricLevels(criterion.levels);
3357
+ if (read.ok) return [];
3358
+ const level = ordinal(read.index ?? 0);
3359
+ return [finding("wr_levels_unreadable", [
3360
+ "rubric",
3361
+ "criteria",
3362
+ index,
3363
+ "levels"
3364
+ ], `${LEVELS_PROBLEM[read.problem](ordinal(index), level)}, so a grader cannot judge against them.`)];
3365
+ });
3366
+ return [...names, ...levels];
3232
3367
  }
3233
3368
  /** 150 words a minute: a fluent adult reading aloud. A learner is slower. */
3234
3369
  const WORDS_PER_SECOND = 2.5;
@@ -3616,7 +3751,9 @@ const MultipleChoiceOptionMediaSchema = zod_v4.looseObject({
3616
3751
  type: zod_v4.enum(["image", "audio"]),
3617
3752
  url: MediaUrlSchema,
3618
3753
  alt: zod_v4.string().min(1).optional(),
3619
- captionsUrl: MediaUrlSchema.optional()
3754
+ captionsUrl: MediaUrlSchema.optional(),
3755
+ transcript: zod_v4.string().optional(),
3756
+ script: ScriptSchema.optional()
3620
3757
  }).refine((media) => media.type !== "image" || media.alt !== void 0 && media.alt !== "", {
3621
3758
  error: "An image option requires a non-empty `alt`.",
3622
3759
  path: ["alt"]
@@ -4410,7 +4547,11 @@ const WrittenResponseRubricSchema = zod_v4.looseObject({
4410
4547
  const RedactedWrittenResponseRubricCriterionSchema = zod_v4.strictObject({
4411
4548
  name: zod_v4.string().min(1),
4412
4549
  description: zod_v4.string().optional(),
4413
- weight: zod_v4.number().min(0)
4550
+ weight: zod_v4.number().min(0),
4551
+ levels: zod_v4.array(zod_v4.strictObject({
4552
+ label: zod_v4.string().min(1),
4553
+ description: zod_v4.string().optional()
4554
+ })).min(2).max(10).optional()
4414
4555
  });
4415
4556
  const RedactedWrittenResponseRubricSchema = zod_v4.strictObject({
4416
4557
  label: zod_v4.string().optional(),
@@ -4852,8 +4993,49 @@ function defineActivityType(descriptor) {
4852
4993
  return descriptor;
4853
4994
  }
4854
4995
  //#endregion
4996
+ //#region src/registry/keep-when.ts
4997
+ /**
4998
+ * A nested field policy that keeps its field only when the field's value
4999
+ * passes a test. Internal: the symbol is never exported, so no host policy can
5000
+ * carry one, and `FieldPolicy`'s string keys never see it.
5001
+ *
5002
+ * It can only drop a field the policy would otherwise emit, never emit one it
5003
+ * would drop, so redaction stays fail-closed. It exists for a field
5004
+ * `validateActivity` does not check in 1.x — a rubric criterion's `levels` —
5005
+ * whose malformed values would otherwise reach the strict redacted schema and
5006
+ * make `redact()` throw on content it accepted before.
5007
+ */
5008
+ const KEEP_WHEN = Symbol("lk.keepWhen");
5009
+ /** `policy`, kept only for values `test` accepts. */
5010
+ function keepWhen(policy, test) {
5011
+ const guarded = {
5012
+ ...policy,
5013
+ [KEEP_WHEN]: test
5014
+ };
5015
+ return Object.freeze(guarded);
5016
+ }
5017
+ /** The test a nested policy keeps its field by, when it has one. */
5018
+ function guardOf(policy) {
5019
+ return policy[KEEP_WHEN];
5020
+ }
5021
+ //#endregion
4855
5022
  //#region src/registry/builtins.ts
4856
5023
  /**
5024
+ * Where the built-in types keep their files (`mediaSlots`). Every type has its
5025
+ * `media`; dictation and read-aloud add a slower recording; a multiple-choice
5026
+ * option may carry a picture or a recording of its own.
5027
+ */
5028
+ const MAIN_MEDIA = [{ path: ["media"] }];
5029
+ const MAIN_AND_SLOW_MEDIA = [{ path: ["media"] }, { path: ["slowMedia"] }];
5030
+ function multipleChoiceMediaSlots(data) {
5031
+ const options = Array.isArray(data.options) ? data.options : [];
5032
+ return [...MAIN_MEDIA, ...options.map((_, index) => ({ path: [
5033
+ "options",
5034
+ index,
5035
+ "media"
5036
+ ] }))];
5037
+ }
5038
+ /**
4857
5039
  * Field-sensitivity policies for the built-in types (R7). Fail-closed:
4858
5040
  * anything not listed here is dropped by `redact()`. `scoringStrategy` is
4859
5041
  * answer-key everywhere — MC `partial` penalises wrong selections while
@@ -4873,10 +5055,11 @@ function defineActivityType(descriptor) {
4873
5055
  * documents ("a field the policy does not classify is removed") stopped at the
4874
5056
  * media boundary. It no longer does.
4875
5057
  *
4876
- * Everything here is public by necessity: the client is the thing that renders
4877
- * and enforces the policy, and "1 play remaining" is text the learner has to
4878
- * read. None of it is an answer key — a listening paper's answer key is
4879
- * `stimulus.transcript`, which stays `author-only`.
5058
+ * Public by necessity, except what the recording says: the client is the thing
5059
+ * that renders and enforces the policy, and "1 play remaining" is text the
5060
+ * learner has to read. `transcript` and `script` are the exception, and
5061
+ * `author-only`: what a listening question's recording says is that question's
5062
+ * answer, as `stimulus.transcript` is a listening paper's.
4880
5063
  */
4881
5064
  const MEDIA_FIELD_POLICY = {
4882
5065
  type: "public",
@@ -4897,7 +5080,9 @@ const MEDIA_FIELD_POLICY = {
4897
5080
  seek: "public",
4898
5081
  rate: "public",
4899
5082
  nativeControlHints: "public"
4900
- }
5083
+ },
5084
+ transcript: "author-only",
5085
+ script: "author-only"
4901
5086
  };
4902
5087
  const SHARED_PUBLIC_FIELDS = {
4903
5088
  schemaVersion: "public",
@@ -4967,7 +5152,9 @@ const MULTIPLE_CHOICE_FIELD_POLICY = {
4967
5152
  type: "public",
4968
5153
  url: "public",
4969
5154
  alt: "public",
4970
- captionsUrl: "public"
5155
+ captionsUrl: "public",
5156
+ transcript: "author-only",
5157
+ script: "author-only"
4971
5158
  }
4972
5159
  }
4973
5160
  };
@@ -5069,7 +5256,11 @@ const RUBRIC_FIELD_POLICY = {
5069
5256
  criteria: {
5070
5257
  name: "public",
5071
5258
  description: "public",
5072
- weight: "public"
5259
+ weight: "public",
5260
+ levels: keepWhen({
5261
+ label: "public",
5262
+ description: "public"
5263
+ }, (value) => readRubricLevels(value).ok)
5073
5264
  }
5074
5265
  };
5075
5266
  const WRITTEN_RESPONSE_FIELD_POLICY = {
@@ -5103,7 +5294,8 @@ const multipleChoiceType = defineActivityType({
5103
5294
  "option-deselected",
5104
5295
  "submitted"
5105
5296
  ],
5106
- authoring: multipleChoiceAuthoring
5297
+ authoring: multipleChoiceAuthoring,
5298
+ mediaSlots: multipleChoiceMediaSlots
5107
5299
  });
5108
5300
  /** Built-in Fill-in-the-Blanks descriptor. */
5109
5301
  const fillInTheBlanksType = defineActivityType({
@@ -5126,7 +5318,8 @@ const fillInTheBlanksType = defineActivityType({
5126
5318
  "hint-requested",
5127
5319
  "submitted"
5128
5320
  ],
5129
- authoring: fillInTheBlanksAuthoring
5321
+ authoring: fillInTheBlanksAuthoring,
5322
+ mediaSlots: () => MAIN_MEDIA
5130
5323
  });
5131
5324
  /**
5132
5325
  * Built-in Written Response descriptor. Grading is DEFERRED: submissions are
@@ -5158,7 +5351,8 @@ const writtenResponseType = defineActivityType({
5158
5351
  correctResponsesPattern: () => []
5159
5352
  },
5160
5353
  interactions: ["text-changed", "submitted"],
5161
- authoring: writtenResponseAuthoring
5354
+ authoring: writtenResponseAuthoring,
5355
+ mediaSlots: () => MAIN_MEDIA
5162
5356
  });
5163
5357
  /** Built-in Gap Select descriptor. */
5164
5358
  const gapSelectType = defineActivityType({
@@ -5177,7 +5371,8 @@ const gapSelectType = defineActivityType({
5177
5371
  correctResponsesPattern: (data) => [data.gaps.map((gap) => `${gap.id}[.]${gap.correctChoiceId}`).join("[,]")]
5178
5372
  },
5179
5373
  interactions: ["gap-selected", "submitted"],
5180
- authoring: gapSelectAuthoring
5374
+ authoring: gapSelectAuthoring,
5375
+ mediaSlots: () => MAIN_MEDIA
5181
5376
  });
5182
5377
  /**
5183
5378
  * Built-in Dictation descriptor. Graded synchronously: the score is the
@@ -5204,7 +5399,8 @@ const dictationType = defineActivityType({
5204
5399
  "hint-requested",
5205
5400
  "submitted"
5206
5401
  ],
5207
- authoring: dictationAuthoring
5402
+ authoring: dictationAuthoring,
5403
+ mediaSlots: () => MAIN_AND_SLOW_MEDIA
5208
5404
  });
5209
5405
  /**
5210
5406
  * Read Aloud, the type with no answer key at all.
@@ -5285,7 +5481,8 @@ const readAloudType = defineActivityType({
5285
5481
  "recording-uploaded",
5286
5482
  "submitted"
5287
5483
  ],
5288
- authoring: readAloudAuthoring
5484
+ authoring: readAloudAuthoring,
5485
+ mediaSlots: () => MAIN_AND_SLOW_MEDIA
5289
5486
  });
5290
5487
  /**
5291
5488
  * The SDK's own types, by type: what the registry is created holding
@@ -5413,10 +5610,10 @@ function isStandardSchema(value) {
5413
5610
  * A schema's own JSON Schema, when it implements the Standard JSON Schema
5414
5611
  * converter (`'~standard'.jsonSchema`) — zod 4.6 does — or `undefined`.
5415
5612
  */
5416
- function standardJsonSchemaOf(schema) {
5613
+ function standardJsonSchemaOf(schema, target = "draft-07") {
5417
5614
  const converter = schema["~standard"].jsonSchema;
5418
5615
  if (typeof converter?.output !== "function") return;
5419
- const generated = converter.output({ target: "draft-07" });
5616
+ const generated = converter.output({ target });
5420
5617
  return generated !== null && typeof generated === "object" && !Array.isArray(generated) ? generated : void 0;
5421
5618
  }
5422
5619
  //#endregion
@@ -5551,6 +5748,12 @@ Object.defineProperty(exports, "GapSelectDataSchema", {
5551
5748
  return GapSelectDataSchema;
5552
5749
  }
5553
5750
  });
5751
+ Object.defineProperty(exports, "LEVEL_PROBABILITY_TOLERANCE", {
5752
+ enumerable: true,
5753
+ get: function() {
5754
+ return LEVEL_PROBABILITY_TOLERANCE;
5755
+ }
5756
+ });
5554
5757
  Object.defineProperty(exports, "MEDIA_FIELD_POLICY", {
5555
5758
  enumerable: true,
5556
5759
  get: function() {
@@ -5617,6 +5820,12 @@ Object.defineProperty(exports, "RedactedScoringError", {
5617
5820
  return RedactedScoringError;
5618
5821
  }
5619
5822
  });
5823
+ Object.defineProperty(exports, "SCRIPT_MAX_TURNS", {
5824
+ enumerable: true,
5825
+ get: function() {
5826
+ return SCRIPT_MAX_TURNS;
5827
+ }
5828
+ });
5620
5829
  Object.defineProperty(exports, "SPEECH_ASSESSMENT_MAX_TEXT_LENGTH", {
5621
5830
  enumerable: true,
5622
5831
  get: function() {
@@ -5635,6 +5844,12 @@ Object.defineProperty(exports, "STEP", {
5635
5844
  return STEP;
5636
5845
  }
5637
5846
  });
5847
+ Object.defineProperty(exports, "ScriptSchema", {
5848
+ enumerable: true,
5849
+ get: function() {
5850
+ return ScriptSchema;
5851
+ }
5852
+ });
5638
5853
  Object.defineProperty(exports, "UnknownActivityTypeError", {
5639
5854
  enumerable: true,
5640
5855
  get: function() {
@@ -5731,6 +5946,12 @@ Object.defineProperty(exports, "fillInTheBlanksType", {
5731
5946
  return fillInTheBlanksType;
5732
5947
  }
5733
5948
  });
5949
+ Object.defineProperty(exports, "finding", {
5950
+ enumerable: true,
5951
+ get: function() {
5952
+ return finding;
5953
+ }
5954
+ });
5734
5955
  Object.defineProperty(exports, "fold", {
5735
5956
  enumerable: true,
5736
5957
  get: function() {
@@ -5755,6 +5976,12 @@ Object.defineProperty(exports, "groupCaptionsField", {
5755
5976
  return groupCaptionsField;
5756
5977
  }
5757
5978
  });
5979
+ Object.defineProperty(exports, "guardOf", {
5980
+ enumerable: true,
5981
+ get: function() {
5982
+ return guardOf;
5983
+ }
5984
+ });
5758
5985
  Object.defineProperty(exports, "isBuiltInActivityType", {
5759
5986
  enumerable: true,
5760
5987
  get: function() {
@@ -5803,6 +6030,18 @@ Object.defineProperty(exports, "keyPositionFinding", {
5803
6030
  return keyPositionFinding;
5804
6031
  }
5805
6032
  });
6033
+ Object.defineProperty(exports, "levelDistribution", {
6034
+ enumerable: true,
6035
+ get: function() {
6036
+ return levelDistribution;
6037
+ }
6038
+ });
6039
+ Object.defineProperty(exports, "levelKey", {
6040
+ enumerable: true,
6041
+ get: function() {
6042
+ return levelKey;
6043
+ }
6044
+ });
5806
6045
  Object.defineProperty(exports, "levenshteinDistance", {
5807
6046
  enumerable: true,
5808
6047
  get: function() {
@@ -5863,6 +6102,12 @@ Object.defineProperty(exports, "readAloudType", {
5863
6102
  return readAloudType;
5864
6103
  }
5865
6104
  });
6105
+ Object.defineProperty(exports, "readRubricLevels", {
6106
+ enumerable: true,
6107
+ get: function() {
6108
+ return readRubricLevels;
6109
+ }
6110
+ });
5866
6111
  Object.defineProperty(exports, "readSchema", {
5867
6112
  enumerable: true,
5868
6113
  get: function() {
@@ -5912,4 +6157,4 @@ Object.defineProperty(exports, "writtenResponseType", {
5912
6157
  }
5913
6158
  });
5914
6159
 
5915
- //# sourceMappingURL=registry-DVi0LR_i.cjs.map
6160
+ //# sourceMappingURL=registry-Ih5n4PVZ.cjs.map