@intellectif/lk-core 1.2.0 → 1.4.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 (105) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +2 -2
  3. package/dist/ai-CnmLPMzd.d.cts +2417 -0
  4. package/dist/ai-CnmLPMzd.d.cts.map +1 -0
  5. package/dist/ai-CnmLPMzd.d.ts +2417 -0
  6. package/dist/ai-CnmLPMzd.d.ts.map +1 -0
  7. package/dist/ai-check.cjs +845 -620
  8. package/dist/ai-check.cjs.map +1 -1
  9. package/dist/ai-check.d.cts +82 -80
  10. package/dist/ai-check.d.cts.map +1 -0
  11. package/dist/ai-check.d.ts +82 -80
  12. package/dist/ai-check.d.ts.map +1 -0
  13. package/dist/ai-check.js +843 -621
  14. package/dist/ai-check.js.map +1 -1
  15. package/dist/ai-writing-CPpH9Qxq.js +2601 -0
  16. package/dist/ai-writing-CPpH9Qxq.js.map +1 -0
  17. package/dist/ai-writing-G6tnCGzw.cjs +2846 -0
  18. package/dist/ai-writing-G6tnCGzw.cjs.map +1 -0
  19. package/dist/index-2nigSf4N.d.cts +339 -0
  20. package/dist/index-2nigSf4N.d.cts.map +1 -0
  21. package/dist/index-B54baFUA.d.ts +339 -0
  22. package/dist/index-B54baFUA.d.ts.map +1 -0
  23. package/dist/index-BAfEHCnD.d.cts +1071 -0
  24. package/dist/index-BAfEHCnD.d.cts.map +1 -0
  25. package/dist/index-BqMXWuNC.d.cts +153 -0
  26. package/dist/index-BqMXWuNC.d.cts.map +1 -0
  27. package/dist/index-CVWvymVb.d.ts +1071 -0
  28. package/dist/index-CVWvymVb.d.ts.map +1 -0
  29. package/dist/index-CcHDTxIZ.d.ts +153 -0
  30. package/dist/index-CcHDTxIZ.d.ts.map +1 -0
  31. package/dist/index.cjs +1211 -1146
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +941 -861
  34. package/dist/index.d.cts.map +1 -0
  35. package/dist/index.d.ts +941 -861
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +1063 -1147
  38. package/dist/index.js.map +1 -1
  39. package/dist/item-group-DXiR8nOr.js +445 -0
  40. package/dist/item-group-DXiR8nOr.js.map +1 -0
  41. package/dist/item-group-DroFXgLb.cjs +505 -0
  42. package/dist/item-group-DroFXgLb.cjs.map +1 -0
  43. package/dist/registry-DVi0LR_i.cjs +5915 -0
  44. package/dist/registry-DVi0LR_i.cjs.map +1 -0
  45. package/dist/registry-Dsx9mNsS.js +5449 -0
  46. package/dist/registry-Dsx9mNsS.js.map +1 -0
  47. package/dist/schemas-Bdw0nGPo.js +152 -0
  48. package/dist/schemas-Bdw0nGPo.js.map +1 -0
  49. package/dist/schemas-DVbAOrtd.cjs +224 -0
  50. package/dist/schemas-DVbAOrtd.cjs.map +1 -0
  51. package/dist/schemas.cjs +16 -34
  52. package/dist/schemas.d.cts +2 -2
  53. package/dist/schemas.d.ts +2 -2
  54. package/dist/schemas.js +3 -34
  55. package/dist/scoring-B2_HEhMT.cjs +1748 -0
  56. package/dist/scoring-B2_HEhMT.cjs.map +1 -0
  57. package/dist/scoring-BZqUkuDF.js +1604 -0
  58. package/dist/scoring-BZqUkuDF.js.map +1 -0
  59. package/dist/scoring.cjs +37 -75
  60. package/dist/scoring.d.cts +3 -1103
  61. package/dist/scoring.d.ts +3 -1103
  62. package/dist/scoring.js +3 -75
  63. package/dist/xapi-CMTph7wG.js +332 -0
  64. package/dist/xapi-CMTph7wG.js.map +1 -0
  65. package/dist/xapi-DNzkSJ0S.cjs +362 -0
  66. package/dist/xapi-DNzkSJ0S.cjs.map +1 -0
  67. package/dist/xapi.cjs +7 -16
  68. package/dist/xapi.d.cts +2 -150
  69. package/dist/xapi.d.ts +2 -150
  70. package/dist/xapi.js +2 -16
  71. package/package.json +4 -4
  72. package/dist/activity-D705CXng.d.cts +0 -2162
  73. package/dist/activity-D705CXng.d.ts +0 -2162
  74. package/dist/chunk-46BXIGLG.cjs +0 -272
  75. package/dist/chunk-46BXIGLG.cjs.map +0 -1
  76. package/dist/chunk-4YANYTFN.cjs +0 -1256
  77. package/dist/chunk-4YANYTFN.cjs.map +0 -1
  78. package/dist/chunk-7KOWU4RO.js +0 -2207
  79. package/dist/chunk-7KOWU4RO.js.map +0 -1
  80. package/dist/chunk-7THXD7AN.cjs +0 -5057
  81. package/dist/chunk-7THXD7AN.cjs.map +0 -1
  82. package/dist/chunk-CYCTIXUN.cjs +0 -118
  83. package/dist/chunk-CYCTIXUN.cjs.map +0 -1
  84. package/dist/chunk-CYPA5BW5.js +0 -118
  85. package/dist/chunk-CYPA5BW5.js.map +0 -1
  86. package/dist/chunk-JTNDIBZO.js +0 -272
  87. package/dist/chunk-JTNDIBZO.js.map +0 -1
  88. package/dist/chunk-MV2N2WNS.js +0 -352
  89. package/dist/chunk-MV2N2WNS.js.map +0 -1
  90. package/dist/chunk-MXI26H62.cjs +0 -2207
  91. package/dist/chunk-MXI26H62.cjs.map +0 -1
  92. package/dist/chunk-QS7B42ZR.js +0 -5057
  93. package/dist/chunk-QS7B42ZR.js.map +0 -1
  94. package/dist/chunk-QX2ERL72.js +0 -1256
  95. package/dist/chunk-QX2ERL72.js.map +0 -1
  96. package/dist/chunk-ZWXQSKCX.cjs +0 -352
  97. package/dist/chunk-ZWXQSKCX.cjs.map +0 -1
  98. package/dist/index-BChYtrEe.d.ts +0 -548
  99. package/dist/index-VXt_v3YI.d.cts +0 -548
  100. package/dist/schemas.cjs.map +0 -1
  101. package/dist/schemas.js.map +0 -1
  102. package/dist/scoring.cjs.map +0 -1
  103. package/dist/scoring.js.map +0 -1
  104. package/dist/xapi.cjs.map +0 -1
  105. package/dist/xapi.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,26 +1,38 @@
1
- import { W as AiSupportedActivityType, g as AiActivityInput, G as AiFeature, aB as LearnerResponse, aA as ItemOutcome, F as AiExplanationRequest, L as AiGrade, M as AiHintRequest, aR as ScoringDetail, N as AiItemFacts, X as AiTextResult, T as AiRefusal, aq as GradeRecord, j as AiCoachingRequest, i as AiCoaching, f as ActivityType, s as AiCritiqueRequest, n as AiCritique, D as AiDraftsRequest, B as AiDrafts, K as AiGeneratedDraft, z as AiDraftType, y as AiDraftSource, x as AiDraftSettings, E as AiDraftsRun, d as ActivityMedia, Z as AiVideoDraft, a2 as AiWritingFeedbackRequest, a1 as AiWritingFeedback, a as ActivityData, ae as DraftContext, ay as ItemFinding, ai as DraftValidationResult, b as ActivityDataMap, aW as ValidationError, a5 as CriterionScore, aJ as NativeControlHint, af as DraftIssue, aT as ScoringResult, a7 as DeferredScoringPartial, a8 as DictationData, aa as DictationLearnerResponse, aj as FillInTheBlanksData, ak as FillInTheBlanksLearnerResponse, an as GapSelectData, ap as GapSelectLearnerResponse, aF as MultipleChoiceData, aG as MultipleChoiceLearnerResponse, aK as ReadAloudData, aN as ReadAloudLearnerResponse, aY as WrittenResponseData, aZ as WrittenResponseLearnerResponse } from './activity-D705CXng.cjs';
2
- export { A as ActivityAiPermissions, c as ActivityFeedback, e as ActivityResult, h as AiBlankFact, k as AiCoachingResult, l as AiCoachingWord, m as AiCriterionJudgement, o as AiCritiqueField, p as AiCritiqueFinding, q as AiCritiqueFindingResult, r as AiCritiqueKind, t as AiCritiqueResult, u as AiDictationFacts, v as AiDraftCaption, w as AiDraftProblem, C as AiDraftsCall, H as AiFillInTheBlanksFacts, I as AiGapFact, J as AiGapSelectFacts, O as AiMultipleChoiceFacts, P as AiOptionFact, Q as AiProvenance, R as AiReadingFacts, S as AiReadingWordFact, U as AiRubricCriterionFact, V as AiSoundFact, Y as AiVerdict, _ as AiWordFact, $ as AiWritingCorrection, a0 as AiWritingFacts, a3 as AiWritingFeedbackResult, a4 as BlankConfig, a6 as DeferredReason, a9 as DictationEquivalence, ab as DictationSlowMedia, ac as DictationTolerance, ad as DraftComplete, ag as DraftNotComplete, ah as DraftSeverity, al as GapSelectBank, am as GapSelectChoice, ao as GapSelectGap, ar as Grader, as as GraderKind, at as GraderUsage, au as GradingState, av as InlineCorrection, aw as InteractionEvent, ax as InteractionKind, az as ItemFindingSeverity, aC as LearnerResponseMap, aD as MediaPlaybackPolicy, aE as MediaTrack, aH as MultipleChoiceOption, aI as MultipleChoiceOptionMedia, aL as ReadAloudDimension, aM as ReadAloudDimensionWeight, aO as ReadAloudSlowMedia, aP as RecordingBounds, aQ as RecordingRef, aS as ScoringOutcome, aU as TextMatchPolicy, aV as TextMatchResult, aX as ValidationResult, a_ as WrittenResponseRubric, a$ as WrittenResponseRubricCriterion, b0 as XAPIActor, b1 as XAPIConfig, b2 as XAPIContext, b3 as XAPIContextActivities, b4 as XAPIError, b5 as XAPIObject, b6 as XAPIResult, b7 as XAPIScore, b8 as XAPIStatement, b9 as XAPIVerbObject, ba as levenshteinDistance, bb as matchText } from './activity-D705CXng.cjs';
3
- import { SpeechAssessment, ResolvedItemScoringPolicy, ItemScoringPolicy, ScoredItem, RoundingPolicy, CompositionPolicy, AssessmentScore } from './scoring.cjs';
4
- export { AssessmentSectionInput, Band, DEFAULT_ITEM_SCORING_POLICY, DEFAULT_PASS_THRESHOLD, DICTATION_MAX_ACCEPTED_TRANSCRIPTS, DICTATION_MAX_EQUIVALENCES, DICTATION_MAX_EQUIVALENCE_LENGTH, DICTATION_MAX_TEXT_LENGTH, DICTATION_MAX_TRANSCRIPT_LENGTH, DictationAlignment, DictationCharOp, DictationReference, DictationWordAlignment, EvaluateOptions, GradeReadAloudOptions, ITEM_SCORING_MAX_RETRIES, ItemScoringCount, ItemScoringPolicyIssue, ItemTriesOutcome, ItemTriesScore, ItemTry, ItemTryScore, PassFailureReason, READ_ALOUD_MAX_DIMENSION_WEIGHT, READ_ALOUD_MAX_REFERENCE_LENGTH, READ_ALOUD_MAX_SECONDS, READ_ALOUD_MAX_TAKES, ReadAloudWordAlignment, ReadAloudWordState, RoundingMode, SPEECH_ASSESSMENT_MAX_WORDS, ScoringOptions, SectionScore, SpeechMeasurement, SpeechPhoneme, SpeechPhonemeCandidate, SpeechPlausibilityPolicy, SpeechSyllable, SpeechUnscorable, SpeechUnscorableCode, SpeechWord, SpeechWordError, WavInspection, WavInspectionPolicy, alignDictation, alignReadAloud, classifyBand, composeAssessmentScore, computePassThreshold, dictationReferenceWords, diffDictationChars, evaluate, evaluateTries, gradeReadAloud, gte, inspectWav, outcomeFromUnscorable, resolveItemScoringPolicy, roundGrade, score, scoreTries, validateItemScoringPolicy, validateSpeechAssessment } from './scoring.cjs';
5
- import { p as SequenceSlot, S as SequenceEntry, I as ItemGroup, M as MediaProgress } from './index-VXt_v3YI.cjs';
6
- export { a as MediaTimeline, R as RedactedActivity, b as RedactedBlankConfig, c as RedactedDictationData, d as RedactedDictationSlowMedia, e as RedactedFillInTheBlanksData, f as RedactedGapSelectBank, g as RedactedGapSelectChoice, h as RedactedGapSelectData, i as RedactedGapSelectGap, j as RedactedMultipleChoiceData, k as RedactedMultipleChoiceOption, l as RedactedMultipleChoiceOptionMedia, m as RedactedReadAloudData, n as RedactedStimulus, o as RedactedWrittenResponseData, q as SequenceSlotGroup, r as Stimulus, s as StimulusKind, T as TimelineChapter, t as TimelineCue, u as dictationJsonSchema, v as fillInTheBlanksJsonSchema, w as gapSelectJsonSchema, x as itemGroupJsonSchema, y as jsonSchemaFor, z as multipleChoiceJsonSchema, A as readAloudJsonSchema, B as stimulusJsonSchema, C as validateActivity, D as validateItemGroup, E as validateMedia, F as validateOptionMedia, G as writtenResponseJsonSchema } from './index-VXt_v3YI.cjs';
7
- export { AnsweredStatementParams, CompletedStatementParams, SubmittedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder, xapiDefinitionFor } from './xapi.cjs';
8
-
1
+ import { $ as AiWritingFeedbackRequest, $t as ReadAloudDimension, A as AiGapSelectFacts, An as InlineCorrection, At as DictationLearnerResponse, B as AiReadingFacts, Bt as InteractionEvent, C as AiDraftsCall, Cn as XAPIVerbObject, Ct as ActivityResult, D as AiFeature, Dn as GraderKind, Dt as DeferredScoringPartial, E as AiExplanationRequest, En as Grader, Et as DeferredReason, F as AiItemFacts, Ft as GapSelectBank, G as AiSupportedActivityType, Gt as MediaPlaybackPolicy, H as AiRefusal, Ht as ItemOutcome, I as AiMaterialFacts, It as GapSelectChoice, J as AiVideoDraft, Jt as MultipleChoiceLearnerResponse, K as AiTextResult, Kt as MediaTrack, L as AiMultipleChoiceFacts, Lt as GapSelectData, M as AiGrade, Mn as TextMatchResult, Mt as DictationTolerance, N as AiGroupInput, Nn as levenshteinDistance, Nt as FillInTheBlanksData, O as AiFillInTheBlanksFacts, On as GraderUsage, Ot as DictationData, P as AiHintRequest, Pn as matchText, Pt as FillInTheBlanksLearnerResponse, Q as AiWritingFeedback, Qt as ReadAloudData, R as AiOptionFact, Rt as GapSelectGap, S as AiDrafts, Sn as XAPIStatement, St as ActivityMedia, T as AiDraftsRun, Tn as GradeRecord, Tt as BlankConfig, U as AiRubricCriterionFact, Ut as LearnerResponse, V as AiReadingWordFact, Vt as InteractionKind, W as AiSoundFact, Wt as LearnerResponseMap, X as AiWritingCorrection, Xt as MultipleChoiceOptionMedia, Y as AiWordFact, Yt as MultipleChoiceOption, Z as AiWritingFacts, Zt as NativeControlHint, _ as AiDraftCaption, _n as XAPIContextActivities, _t as ItemFinding, a as AiCoachingRequest, an as ScoringDetail, at as SequenceSlot, b as AiDraftSource, bn as XAPIResult, bt as ActivityDataMap, c as AiCriterionJudgement, cn as ValidationError, ct as StimulusKind, d as AiCritiqueFinding, dn as WrittenResponseLearnerResponse, dt as DraftComplete, en as ReadAloudDimensionWeight, et as AiWritingFeedbackResult, f as AiCritiqueFindingResult, fn as WrittenResponseRubric, ft as DraftContext, g as AiDictationFacts, gn as XAPIContext, gt as DraftValidationResult, h as AiCritiqueResult, hn as XAPIConfig, ht as DraftSeverity, i as AiCoaching, in as RecordingRef, it as SequenceEntry, j as AiGeneratedDraft, jn as TextMatchPolicy, jt as DictationSlowMedia, k as AiGapFact, kn as GradingState, kt as DictationEquivalence, l as AiCritique, ln as ValidationResult, lt as TimelineChapter, m as AiCritiqueRequest, mn as XAPIActor, mt as DraftNotComplete, n as AiActivityInput, nn as ReadAloudSlowMedia, nt as MediaProgress, o as AiCoachingResult, on as ScoringOutcome, ot as SequenceSlotGroup, p as AiCritiqueKind, pn as WrittenResponseRubricCriterion, pt as DraftIssue, q as AiVerdict, qt as MultipleChoiceData, r as AiBlankFact, rn as RecordingBounds, rt as MediaTimeline, s as AiCoachingWord, sn as ScoringResult, st as Stimulus, t as ActivityAiPermissions, tn as ReadAloudLearnerResponse, tt as ItemGroup, u as AiCritiqueField, un as WrittenResponseData, ut as TimelineCue, v as AiDraftProblem, vn as XAPIError, vt as ItemFindingSeverity, w as AiDraftsRequest, wn as CriterionScore, wt as ActivityType, x as AiDraftType, xn as XAPIScore, xt as ActivityFeedback, y as AiDraftSettings, yn as XAPIObject, yt as ActivityData, z as AiProvenance, zt as GapSelectLearnerResponse } from "./ai-CnmLPMzd.cjs";
2
+ import { $ as SpeechAssessment, A as diffDictationChars, B as ItemTry, C as validateItemScoringPolicy, D as DICTATION_MAX_TEXT_LENGTH, E as DICTATION_MAX_EQUIVALENCE_LENGTH, F as dictationReferenceWords, G as CompositionPolicy, H as ResolvedItemScoringPolicy, I as ItemScoringCount, J as SectionScore, K as PassFailureReason, L as ItemScoringPolicy, M as DictationReference, N as DictationWordAlignment, O as DICTATION_MAX_TRANSCRIPT_LENGTH, P as alignDictation, Q as ReadAloudWordState, R as ItemScoringPolicyIssue, S as scoreTries, T as DICTATION_MAX_EQUIVALENCES, U as AssessmentScore, V as ItemTryScore, W as AssessmentSectionInput, X as GradeReadAloudOptions, Y as composeAssessmentScore, Z as ReadAloudWordAlignment, _ as DEFAULT_PASS_THRESHOLD, a as evaluateTries, at as SpeechUnscorable, b as ITEM_SCORING_MAX_RETRIES, c as inspectWav, ct as SpeechWordError, d as READ_ALOUD_MAX_SECONDS, dt as Band, et as SpeechMeasurement, f as READ_ALOUD_MAX_TAKES, ft as RoundingMode, g as alignReadAloud, gt as roundGrade, h as validateSpeechAssessment, ht as gte, i as evaluate, it as SpeechSyllable, j as DictationAlignment, k as DictationCharOp, l as READ_ALOUD_MAX_DIMENSION_WEIGHT, lt as WavInspection, m as gradeReadAloud, mt as classifyBand, n as ItemTriesOutcome, nt as SpeechPhonemeCandidate, o as score, ot as SpeechUnscorableCode, p as SPEECH_ASSESSMENT_MAX_WORDS, pt as RoundingPolicy, q as ScoredItem, r as ScoringOptions, rt as SpeechPlausibilityPolicy, s as outcomeFromUnscorable, st as SpeechWord, t as EvaluateOptions, tt as SpeechPhoneme, u as READ_ALOUD_MAX_REFERENCE_LENGTH, ut as WavInspectionPolicy, v as computePassThreshold, w as DICTATION_MAX_ACCEPTED_TRANSCRIPTS, x as resolveItemScoringPolicy, y as DEFAULT_ITEM_SCORING_POLICY, z as ItemTriesScore } from "./index-BAfEHCnD.cjs";
3
+ import { C as RedactedMultipleChoiceData, D as RedactedStimulus, E as RedactedReadAloudData, O as RedactedWrittenResponseData, S as RedactedGapSelectGap, T as RedactedMultipleChoiceOptionMedia, _ as RedactedDictationSlowMedia, a as fillInTheBlanksJsonSchema, b as RedactedGapSelectChoice, c as jsonSchemaFor, d as stimulusJsonSchema, f as writtenResponseJsonSchema, g as RedactedDictationData, h as RedactedBlankConfig, i as dictationJsonSchema, l as multipleChoiceJsonSchema, m as RedactedActivity, n as validateMedia, o as gapSelectJsonSchema, p as validateItemGroup, r as validateOptionMedia, s as itemGroupJsonSchema, t as validateActivity, u as readAloudJsonSchema, v as RedactedFillInTheBlanksData, w as RedactedMultipleChoiceOption, x as RedactedGapSelectData, y as RedactedGapSelectBank } from "./index-2nigSf4N.cjs";
4
+ import { a as XAPIObjectParams, c as xapiDefinitionFor, d as XAPI_VERB_DISPLAY, i as SubmittedStatementParams, l as XAPIVerb, n as AnsweredStatementParams, o as XAPIStatementParams, r as CompletedStatementParams, s as xAPIBuilder, t as validateXAPIStatement, u as XAPIVerbKey } from "./index-BqMXWuNC.cjs";
5
+ //#region src/ai-material.d.ts
6
+ /**
7
+ * What a model is told about the group a question sits in: the material the
8
+ * learner reads and sees beside it.
9
+ *
10
+ * Internal: the request builders in `ai.ts` and `ai-writing.ts` are its public
11
+ * face, through their `group` input.
12
+ */
13
+ /**
14
+ * The longest material text a model is given, in code points. A longer one is
15
+ * cut and marked `truncated`: a long reading passage on an exam paper runs to
16
+ * 4,000–7,000.
17
+ */
18
+ export declare const AI_MATERIAL_MAX_LENGTH = 12000;
19
+ //#endregion
20
+ //#region src/ai.d.ts
9
21
  /**
10
22
  * The activity types the SDK builds facts for, and which of them take hints.
11
23
  * A dictation takes none: its answer is the whole sentence, and it has
12
24
  * word-by-word hints of its own.
13
25
  */
14
- declare const AI_EXPLANATION_TYPES: readonly AiSupportedActivityType[];
15
- declare const AI_HINT_TYPES: readonly AiSupportedActivityType[];
26
+ export declare const AI_EXPLANATION_TYPES: readonly AiSupportedActivityType[];
27
+ export declare const AI_HINT_TYPES: readonly AiSupportedActivityType[];
16
28
  /** The longest AI text shown, in code points. Longer is refused, not cut. */
17
- declare const AI_TEXT_MAX_LENGTH = 2000;
29
+ export declare const AI_TEXT_MAX_LENGTH = 2000;
18
30
  /**
19
31
  * Whether the SDK supports `feature` for this activity type: explanations and
20
32
  * hints for the types it builds facts for, and writing feedback for a written
21
33
  * response, and coaching for a read-aloud. A consumer's own type has none.
22
34
  */
23
- declare function aiSupports(activityType: string, feature: AiFeature): boolean;
35
+ export declare function aiSupports(activityType: string, feature: AiFeature): boolean;
24
36
  /**
25
37
  * Whether the item's author allows `feature`. Only an explicit `false`
26
38
  * switches it off: an author can refuse a feature, never force one on.
@@ -29,12 +41,12 @@ declare function aiSupports(activityType: string, feature: AiFeature): boolean;
29
41
  * model's words about the learner's own answer, and an author who switched one
30
42
  * off has switched off the others.
31
43
  */
32
- declare function aiAllowedByContent(data: AiActivityInput, feature: AiFeature): boolean;
44
+ export declare function aiAllowedByContent(data: AiActivityInput, feature: AiFeature): boolean;
33
45
  /** A grade as an explanation must speak to it: all marks, some, or none. */
34
- declare function aiGradeOf(result: {
35
- score: number;
36
- maxScore: number;
37
- passed: boolean;
46
+ export declare function aiGradeOf(result: {
47
+ score: number;
48
+ maxScore: number;
49
+ passed: boolean;
38
50
  }): AiGrade;
39
51
  /**
40
52
  * The facts a model is given about one item and one answer. `details` are the
@@ -45,7 +57,7 @@ declare function aiGradeOf(result: {
45
57
  *
46
58
  * `null` for a type the SDK builds no facts for.
47
59
  */
48
- declare function buildAiFacts(data: AiActivityInput, response: LearnerResponse | null, details: readonly ScoringDetail[] | null): AiItemFacts | null;
60
+ export declare function buildAiFacts(data: AiActivityInput, response: LearnerResponse | null, details: readonly ScoringDetail[] | null): AiItemFacts | null;
49
61
  /**
50
62
  * The request for an explanation of `response`, or `null` when there is none
51
63
  * to give: an unsupported type, an author who switched explanations off,
@@ -57,12 +69,17 @@ declare function buildAiFacts(data: AiActivityInput, response: LearnerResponse |
57
69
  * positive and finite, `score` finite from 0 to it) gets no explanation at all:
58
70
  * explaining 85 "out of 1" would tell the model a wrong answer was correct, and
59
71
  * grading locally instead would speak to a grade the screen does not show.
72
+ *
73
+ * `group` is the item group the question sits in: its material — the passage,
74
+ * or the instructions the group's questions share — goes with the request as
75
+ * `material`, as the learner sees it.
60
76
  */
61
- declare function aiExplanationRequest(input: {
62
- data: AiActivityInput;
63
- response: LearnerResponse | null;
64
- outcome?: ItemOutcome;
65
- learnerLocale?: string;
77
+ export declare function aiExplanationRequest(input: {
78
+ data: AiActivityInput;
79
+ response: LearnerResponse | null;
80
+ outcome?: ItemOutcome;
81
+ group?: AiGroupInput;
82
+ learnerLocale?: string;
66
83
  }): AiExplanationRequest | null;
67
84
  /**
68
85
  * The request for the next hint on an unsubmitted answer, or `null` when
@@ -71,25 +88,30 @@ declare function aiExplanationRequest(input: {
71
88
  *
72
89
  * The facts carry the key, and which parts the learner has right so far, so a
73
90
  * model can hint where it helps. The learner never sees them; a hint that
74
- * contains an answer is refused by {@link checkAiHint}.
75
- */
76
- declare function aiHintRequest(input: {
77
- data: AiActivityInput;
78
- response: LearnerResponse | null;
79
- previousHints: readonly string[];
80
- learnerLocale?: string;
91
+ * contains an answer is refused by {@link checkAiHint}, whatever it quotes —
92
+ * the group's material included.
93
+ *
94
+ * `group` is the item group the question sits in, as for
95
+ * {@link aiExplanationRequest}.
96
+ */
97
+ export declare function aiHintRequest(input: {
98
+ data: AiActivityInput;
99
+ response: LearnerResponse | null;
100
+ previousHints: readonly string[];
101
+ group?: AiGroupInput;
102
+ learnerLocale?: string;
81
103
  }): AiHintRequest | null;
82
104
  /**
83
105
  * Reads what a port returned. Anything but an object with a string `text` is
84
106
  * `malformed`; text that is empty once cleaned, or longer than
85
107
  * {@link AI_TEXT_MAX_LENGTH}, is refused rather than shown or cut.
86
108
  */
87
- declare function readAiTextResult(raw: unknown): {
88
- ok: true;
89
- result: AiTextResult;
109
+ export declare function readAiTextResult(raw: unknown): {
110
+ ok: true;
111
+ result: AiTextResult;
90
112
  } | {
91
- ok: false;
92
- refusal: AiRefusal;
113
+ ok: false;
114
+ refusal: AiRefusal;
93
115
  };
94
116
  /**
95
117
  * Checks an explanation a port returned for `request`. On top of
@@ -97,24 +119,24 @@ declare function readAiTextResult(raw: unknown): {
97
119
  * the SDK's grade is refused (`contradicts-grade`) — it explains an answer
98
120
  * the learner did not get.
99
121
  */
100
- declare function checkAiExplanation(raw: unknown, request: AiExplanationRequest): {
101
- ok: true;
102
- result: AiTextResult;
122
+ export declare function checkAiExplanation(raw: unknown, request: AiExplanationRequest): {
123
+ ok: true;
124
+ result: AiTextResult;
103
125
  } | {
104
- ok: false;
105
- refusal: AiRefusal;
126
+ ok: false;
127
+ refusal: AiRefusal;
106
128
  };
107
129
  /**
108
130
  * Checks a hint a port returned for `request`. On top of
109
131
  * {@link readAiTextResult}: a hint that contains an answer is refused
110
132
  * (`reveals-answer`) — see {@link hintRevealsAnswer}.
111
133
  */
112
- declare function checkAiHint(raw: unknown, request: AiHintRequest): {
113
- ok: true;
114
- result: AiTextResult;
134
+ export declare function checkAiHint(raw: unknown, request: AiHintRequest): {
135
+ ok: true;
136
+ result: AiTextResult;
115
137
  } | {
116
- ok: false;
117
- refusal: AiRefusal;
138
+ ok: false;
139
+ refusal: AiRefusal;
118
140
  };
119
141
  /**
120
142
  * Whether a hint gives away an answer, judged against the facts it was asked
@@ -126,15 +148,18 @@ declare function checkAiHint(raw: unknown, request: AiHintRequest): {
126
148
  * An answer of one short word ("is", "the") counts only where the hint
127
149
  * writes it beside a neighbour it has in the passage — "name is", "is
128
150
  * Rossi" — so a hint may still use the word on its own.
151
+ * - **Facts of any other kind:** revealing. A hint the check cannot read is
152
+ * withheld, not shown unchecked.
129
153
  *
130
154
  * Case, accents and punctuation are ignored on both sides.
131
155
  */
132
- declare function hintRevealsAnswer(facts: AiItemFacts, hint: string): boolean;
133
-
156
+ export declare function hintRevealsAnswer(facts: AiItemFacts, hint: string): boolean;
157
+ //#endregion
158
+ //#region src/ai-coaching.d.ts
134
159
  /** The most words one coaching may work on. More is refused, not cut. */
135
- declare const AI_COACHING_MAX_WORDS = 20;
160
+ export declare const AI_COACHING_MAX_WORDS = 20;
136
161
  /** The longest tip for one word, in code points. */
137
- declare const AI_COACHING_MAX_TIP_LENGTH = 500;
162
+ export declare const AI_COACHING_MAX_TIP_LENGTH = 500;
138
163
  /**
139
164
  * The request for coaching on a graded reading, or `null` when there is none
140
165
  * to give: not a read-aloud, an author who switched explanations off (coaching
@@ -151,11 +176,11 @@ declare const AI_COACHING_MAX_TIP_LENGTH = 500;
151
176
  * the engine's dimension scores. The marks are the engine's; the model
152
177
  * explains them.
153
178
  */
154
- declare function aiCoachingRequest(input: {
155
- data: AiActivityInput;
156
- assessment?: SpeechAssessment | null;
157
- grade?: GradeRecord | null;
158
- learnerLocale?: string;
179
+ export declare function aiCoachingRequest(input: {
180
+ data: AiActivityInput;
181
+ assessment?: SpeechAssessment | null;
182
+ grade?: GradeRecord | null;
183
+ learnerLocale?: string;
159
184
  }): AiCoachingRequest | null;
160
185
  /**
161
186
  * Checks coaching a port returned for `request`, and turns it into what a
@@ -180,18 +205,19 @@ declare function aiCoachingRequest(input: {
180
205
  * (the SDK's reading of the text, never the model's), and each sound spelt as
181
206
  * the engine spelt it.
182
207
  */
183
- declare function checkAiCoaching(raw: unknown, request: AiCoachingRequest): {
184
- ok: true;
185
- coaching: AiCoaching;
208
+ export declare function checkAiCoaching(raw: unknown, request: AiCoachingRequest): {
209
+ ok: true;
210
+ coaching: AiCoaching;
186
211
  } | {
187
- ok: false;
188
- refusal: AiRefusal;
212
+ ok: false;
213
+ refusal: AiRefusal;
189
214
  };
190
-
215
+ //#endregion
216
+ //#region src/ai-critique.d.ts
191
217
  /** The most findings one critique may carry. More is refused, not cut. */
192
- declare const AI_CRITIQUE_MAX_FINDINGS = 20;
218
+ export declare const AI_CRITIQUE_MAX_FINDINGS = 20;
193
219
  /** The longest message or quote in a finding, in code points. */
194
- declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
220
+ export declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
195
221
  /**
196
222
  * What a model is given to review an item, or `null` when there is nothing to
197
223
  * review: a draft that is not an object, or one with no words in it yet.
@@ -207,11 +233,11 @@ declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
207
233
  *
208
234
  * @throws UnknownActivityTypeError when `type` has no registered descriptor.
209
235
  */
210
- declare function aiCritiqueRequest(input: {
211
- type: ActivityType;
212
- draft: unknown;
213
- level?: string;
214
- authorLocale?: string;
236
+ export declare function aiCritiqueRequest(input: {
237
+ type: ActivityType;
238
+ draft: unknown;
239
+ level?: string;
240
+ authorLocale?: string;
215
241
  }): AiCritiqueRequest | null;
216
242
  /**
217
243
  * Checks a critique a port returned for `request`, and turns it into findings
@@ -230,18 +256,19 @@ declare function aiCritiqueRequest(input: {
230
256
  * {@link AI_CRITIQUE_MAX_FIELD_LENGTH} code points; over them `too-long`. A
231
257
  * kind the SDK does not name, or any other shape, is `malformed`.
232
258
  */
233
- declare function checkAiCritique(raw: unknown, request: AiCritiqueRequest): {
234
- ok: true;
235
- critique: AiCritique;
259
+ export declare function checkAiCritique(raw: unknown, request: AiCritiqueRequest): {
260
+ ok: true;
261
+ critique: AiCritique;
236
262
  } | {
237
- ok: false;
238
- refusal: AiRefusal;
263
+ ok: false;
264
+ refusal: AiRefusal;
239
265
  };
240
-
266
+ //#endregion
267
+ //#region src/ai-drafts.d.ts
241
268
  /** The most drafts one request may ask for, and the most a reply may hold when it names no count. */
242
- declare const AI_DRAFTS_MAX_COUNT = 50;
269
+ export declare const AI_DRAFTS_MAX_COUNT = 50;
243
270
  /** The most repair passes `generateDrafts` makes. */
244
- declare const AI_DRAFTS_MAX_REPAIRS = 3;
271
+ export declare const AI_DRAFTS_MAX_REPAIRS = 3;
245
272
  /**
246
273
  * What a model is given to draft items from a source, or `null` when there is
247
274
  * no source to draft from: an empty text, or no caption with words in it.
@@ -264,14 +291,14 @@ declare const AI_DRAFTS_MAX_REPAIRS = 3;
264
291
  * does not draft, or `count` is not a whole number from 1 to
265
292
  * {@link AI_DRAFTS_MAX_COUNT}.
266
293
  */
267
- declare function aiDraftsRequest(input: {
268
- types: readonly AiDraftType[];
269
- source: AiDraftSource;
270
- count?: number;
271
- locale?: string;
272
- level?: string;
273
- instructions?: string;
274
- settings?: AiDraftSettings;
294
+ export declare function aiDraftsRequest(input: {
295
+ types: readonly AiDraftType[];
296
+ source: AiDraftSource;
297
+ count?: number;
298
+ locale?: string;
299
+ level?: string;
300
+ instructions?: string;
301
+ settings?: AiDraftSettings;
275
302
  }): AiDraftsRequest | null;
276
303
  /**
277
304
  * Reads a model's reply to {@link aiDraftsRequest} into drafts an editor can
@@ -296,14 +323,14 @@ declare function aiDraftsRequest(input: {
296
323
  *
297
324
  * @throws Error when `newId` returns an empty or repeated id.
298
325
  */
299
- declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options: {
300
- newId: () => string;
326
+ export declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options: {
327
+ newId: () => string;
301
328
  }): {
302
- ok: true;
303
- drafts: AiDrafts;
329
+ ok: true;
330
+ drafts: AiDrafts;
304
331
  } | {
305
- ok: false;
306
- refusal: AiRefusal;
332
+ ok: false;
333
+ refusal: AiRefusal;
307
334
  };
308
335
  /**
309
336
  * A second request, for the drafts with something wrong the model can fix —
@@ -314,7 +341,7 @@ declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options:
314
341
  * The reply holds one draft for each, in order; {@link checkAiDrafts} reads it
315
342
  * and gives each the `index` of the draft it replaces.
316
343
  */
317
- declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDrafts | readonly AiGeneratedDraft[]): AiDraftsRequest | null;
344
+ export declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDrafts | readonly AiGeneratedDraft[]): AiDraftsRequest | null;
318
345
  /**
319
346
  * Drafts items from a source, with a bounded repair loop: asks the port with
320
347
  * `request`, reads the reply with {@link checkAiDrafts}, then — up to `repairs`
@@ -340,11 +367,11 @@ declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDraft
340
367
  * {@link AI_DRAFTS_MAX_REPAIRS} (default 1), and Error when `newId` returns an
341
368
  * empty or repeated id.
342
369
  */
343
- declare function generateDrafts(input: {
344
- request: AiDraftsRequest;
345
- port: (request: AiDraftsRequest) => Promise<unknown> | unknown;
346
- newId: () => string;
347
- repairs?: number;
370
+ export declare function generateDrafts(input: {
371
+ request: AiDraftsRequest;
372
+ port: (request: AiDraftsRequest) => Promise<unknown> | unknown;
373
+ newId: () => string;
374
+ repairs?: number;
348
375
  }): Promise<AiDraftsRun>;
349
376
  /**
350
377
  * An interactive video made of drafts: an item group whose stimulus is
@@ -365,19 +392,20 @@ declare function generateDrafts(input: {
365
392
  *
366
393
  * @throws Error when `newId` returns an empty or repeated id.
367
394
  */
368
- declare function interactiveVideoFromDrafts(input: {
369
- request: AiDraftsRequest;
370
- drafts: AiDrafts | AiDraftsRun | readonly AiGeneratedDraft[];
371
- video: ActivityMedia;
372
- durationSeconds?: number;
373
- title?: string;
374
- newId: () => string;
395
+ export declare function interactiveVideoFromDrafts(input: {
396
+ request: AiDraftsRequest;
397
+ drafts: AiDrafts | AiDraftsRun | readonly AiGeneratedDraft[];
398
+ video: ActivityMedia;
399
+ durationSeconds?: number;
400
+ title?: string;
401
+ newId: () => string;
375
402
  }): AiVideoDraft;
376
-
403
+ //#endregion
404
+ //#region src/ai-writing.d.ts
377
405
  /** The most corrections one piece of writing feedback may carry. More is refused, not cut. */
378
- declare const AI_WRITING_MAX_CORRECTIONS = 20;
406
+ export declare const AI_WRITING_MAX_CORRECTIONS = 20;
379
407
  /** The longest quote, correction, explanation or criterion comment, in code points. */
380
- declare const AI_WRITING_MAX_FIELD_LENGTH = 500;
408
+ export declare const AI_WRITING_MAX_FIELD_LENGTH = 500;
381
409
  /**
382
410
  * The request for feedback on a draft, or `null` when there is none to give:
383
411
  * not a written response, an author who switched explanations off (writing
@@ -387,13 +415,16 @@ declare const AI_WRITING_MAX_FIELD_LENGTH = 500;
387
415
  * The facts are the task as the learner saw it, the draft verbatim with its
388
416
  * word count recomputed as the grader will count it, and the rubric the answer
389
417
  * will be graded on. `previousFeedback` is the text of the feedback already
390
- * shown on earlier drafts, so a model can speak to what changed.
391
- */
392
- declare function aiWritingFeedbackRequest(input: {
393
- data: AiActivityInput;
394
- response: LearnerResponse | null;
395
- previousFeedback?: readonly string[];
396
- learnerLocale?: string;
418
+ * shown on earlier drafts, so a model can speak to what changed. `group` is the
419
+ * item group the task sits in: its material, the text a summary is of, goes
420
+ * with the request as `material`.
421
+ */
422
+ export declare function aiWritingFeedbackRequest(input: {
423
+ data: AiActivityInput;
424
+ response: LearnerResponse | null;
425
+ previousFeedback?: readonly string[];
426
+ group?: AiGroupInput;
427
+ learnerLocale?: string;
397
428
  }): AiWritingFeedbackRequest | null;
398
429
  /**
399
430
  * Checks writing feedback a port returned for `request`, and turns it into what
@@ -419,14 +450,15 @@ declare function aiWritingFeedbackRequest(input: {
419
450
  * `gradeFromRubric` computes a grade, when every criterion of the rubric was
420
451
  * judged; `null` otherwise. An indication, never a grade.
421
452
  */
422
- declare function checkAiWritingFeedback(raw: unknown, request: AiWritingFeedbackRequest): {
423
- ok: true;
424
- feedback: AiWritingFeedback;
453
+ export declare function checkAiWritingFeedback(raw: unknown, request: AiWritingFeedbackRequest): {
454
+ ok: true;
455
+ feedback: AiWritingFeedback;
425
456
  } | {
426
- ok: false;
427
- refusal: AiRefusal;
457
+ ok: false;
458
+ refusal: AiRefusal;
428
459
  };
429
-
460
+ //#endregion
461
+ //#region src/types/delivery.d.ts
430
462
  /**
431
463
  * How a paper is delivered: what a learner is shown around the questions, as
432
464
  * the school running it decides — separately from the content, so that one
@@ -439,45 +471,45 @@ declare function checkAiWritingFeedback(raw: unknown, request: AiWritingFeedback
439
471
  * because the client in an exam has no answer key to grade with.
440
472
  */
441
473
  interface DeliveryPolicy {
442
- /**
443
- * Whether a graded answer shows as graded: right and wrong marks, the score,
444
- * and the author's feedback. `false` leaves the learner with "Answer
445
- * submitted." — a homework quiz marked on the client and shown to the
446
- * learner at the end, or a review that shows what was answered and not how
447
- * it was marked. Never on in `exam`.
448
- */
449
- feedback?: boolean | null;
450
- /**
451
- * Whether the right answer is shown beside a wrong one, wherever an activity
452
- * would show it: the correct option of a multiple-choice question, the
453
- * correct answers `showCorrectAnswers` puts in the blanks, a dictation's
454
- * transcript. `false` still marks what the learner answered right or wrong.
455
- * Use it on a paper that will be sat again, or before a retry.
456
- */
457
- solutions?: boolean | null;
458
- /**
459
- * Whether the learner can ask for hints: the author's hints on a
460
- * fill-in-the-blanks blank, a dictation's word hints, and AI hints. `false`
461
- * switches every kind off.
462
- *
463
- * **The author's fill-in-the-blanks hints are on in `exam` unless this says
464
- * otherwise** — they are public content, and were designed to be. Set
465
- * `hints: false` on a paper of record whose hints are not part of the test.
466
- */
474
+ /**
475
+ * Whether a graded answer shows as graded: right and wrong marks, the score,
476
+ * and the author's feedback. `false` leaves the learner with "Answer
477
+ * submitted." — a homework quiz marked on the client and shown to the
478
+ * learner at the end, or a review that shows what was answered and not how
479
+ * it was marked. Never on in `exam`.
480
+ */
481
+ feedback?: boolean | null;
482
+ /**
483
+ * Whether the right answer is shown beside a wrong one, wherever an activity
484
+ * would show it: the correct option of a multiple-choice question, the
485
+ * correct answers `showCorrectAnswers` puts in the blanks, a dictation's
486
+ * transcript. `false` still marks what the learner answered right or wrong.
487
+ * Use it on a paper that will be sat again, or before a retry.
488
+ */
489
+ solutions?: boolean | null;
490
+ /**
491
+ * Whether the learner can ask for hints: the author's hints on a
492
+ * fill-in-the-blanks blank, a dictation's word hints, and AI hints. `false`
493
+ * switches every kind off.
494
+ *
495
+ * **The author's fill-in-the-blanks hints are on in `exam` unless this says
496
+ * otherwise** — they are public content, and were designed to be. Set
497
+ * `hints: false` on a paper of record whose hints are not part of the test.
498
+ */
499
+ hints?: boolean | null;
500
+ /**
501
+ * The deployment's switches for AI help, beside the author's switch on the
502
+ * item and the ports the host supplies: a feature appears only where all
503
+ * three allow it. `false` switches a feature off; nothing here can switch one
504
+ * on, and nothing switches AI help on in an `exam`.
505
+ *
506
+ * `ai: false` switches both off and `ai: true` leaves both as the other
507
+ * settings allow — the same as leaving `ai` out.
508
+ */
509
+ ai?: boolean | {
467
510
  hints?: boolean | null;
468
- /**
469
- * The deployment's switches for AI help, beside the author's switch on the
470
- * item and the ports the host supplies: a feature appears only where all
471
- * three allow it. `false` switches a feature off; nothing here can switch one
472
- * on, and nothing switches AI help on in an `exam`.
473
- *
474
- * `ai: false` switches both off and `ai: true` leaves both as the other
475
- * settings allow — the same as leaving `ai` out.
476
- */
477
- ai?: boolean | {
478
- hints?: boolean | null;
479
- explanations?: boolean | null;
480
- } | null;
511
+ explanations?: boolean | null;
512
+ } | null;
481
513
  }
482
514
  /**
483
515
  * A policy with every setting spelled out: what {@link resolveDeliveryPolicy}
@@ -486,231 +518,220 @@ interface DeliveryPolicy {
486
518
  * change.
487
519
  */
488
520
  interface ResolvedDeliveryPolicy {
489
- feedback: boolean;
490
- solutions: boolean;
521
+ feedback: boolean;
522
+ solutions: boolean;
523
+ hints: boolean;
524
+ ai: {
491
525
  hints: boolean;
492
- ai: {
493
- hints: boolean;
494
- explanations: boolean;
495
- };
526
+ explanations: boolean;
527
+ };
496
528
  }
497
529
  /** One thing {@link validateDeliveryPolicy} found wrong with a policy. */
498
530
  interface DeliveryPolicyIssue {
499
- /** Where, as a dotted path: `hints`, `ai.explanations`, or `''` for the policy itself. */
500
- path: string;
501
- message: string;
531
+ /** Where, as a dotted path: `hints`, `ai.explanations`, or `''` for the policy itself. */
532
+ path: string;
533
+ message: string;
502
534
  }
503
-
504
- /**
505
- * The frozen record of what one attempt was served.
506
- *
507
- * A sequence definition is live content: it gets edited, re-ordered, corrected.
508
- * An attempt is a historical fact. Everything that decides a grade — which
509
- * questions, in what order, each worth how much, against which version of the
510
- * content — has to be pinned at the moment the attempt starts, or a re-grade
511
- * six months later silently answers a different question than the learner was
512
- * asked.
513
- *
514
- * This is the thing you persist next to the responses.
515
- */
516
-
535
+ //#endregion
536
+ //#region src/types/attempt-plan.d.ts
517
537
  /** One planned position: an item, its identity, its worth, and its fingerprint. */
518
538
  interface AttemptPlanSlot {
539
+ /**
540
+ * Slot identity, from `flattenSequence`. Stable under shuffling; stable
541
+ * under editing too when the entries declare `slotKey`. This is the key to
542
+ * store responses and scores against.
543
+ */
544
+ slotId: string;
545
+ /** 0-based PRESENTED position in this attempt. */
546
+ index: number;
547
+ /** The activity that filled the slot. */
548
+ activityId: string;
549
+ /** The activity's `type` discriminator. */
550
+ activityType: string;
551
+ /**
552
+ * What this slot is worth, frozen. Points belong to the PAPER, not the item:
553
+ * the same question can be worth 1 in a quiz and 3 in a final, so they are
554
+ * resolved when the attempt is planned and never read from content again.
555
+ */
556
+ points: number;
557
+ /**
558
+ * Fingerprint of the activity's content as served. Compare it later with
559
+ * {@link verifyAttemptPlan} to find out whether the item has been edited
560
+ * since — the difference between "re-grading this attempt" and "grading a
561
+ * different exam".
562
+ */
563
+ contentHash: string;
564
+ /** Present when the slot came from an item group. */
565
+ group?: {
566
+ id: string;
567
+ title?: string;
568
+ /** Fingerprint of the stimulus as served — a corrected passage changes the question. */
569
+ stimulusHash: string;
519
570
  /**
520
- * Slot identity, from `flattenSequence`. Stable under shuffling; stable
521
- * under editing too when the entries declare `slotKey`. This is the key to
522
- * store responses and scores against.
523
- */
524
- slotId: string;
525
- /** 0-based PRESENTED position in this attempt. */
526
- index: number;
527
- /** The activity that filled the slot. */
528
- activityId: string;
529
- /** The activity's `type` discriminator. */
530
- activityType: string;
531
- /**
532
- * What this slot is worth, frozen. Points belong to the PAPER, not the item:
533
- * the same question can be worth 1 in a quiz and 3 in a final, so they are
534
- * resolved when the attempt is planned and never read from content again.
535
- */
536
- points: number;
537
- /**
538
- * Fingerprint of the activity's content as served. Compare it later with
539
- * {@link verifyAttemptPlan} to find out whether the item has been edited
540
- * since — the difference between "re-grading this attempt" and "grading a
541
- * different exam".
571
+ * The quiz this slot's question sat in, when the group is an interactive
572
+ * video. Frozen because WHEN a question is asked is part of what is asked:
573
+ * moved from before the passage it is about to after it, the same item is
574
+ * a different question.
542
575
  */
543
- contentHash: string;
544
- /** Present when the slot came from an item group. */
545
- group?: {
546
- id: string;
547
- title?: string;
548
- /** Fingerprint of the stimulus as served — a corrected passage changes the question. */
549
- stimulusHash: string;
550
- /**
551
- * The quiz this slot's question sat in, when the group is an interactive
552
- * video. Frozen because WHEN a question is asked is part of what is asked:
553
- * moved from before the passage it is about to after it, the same item is
554
- * a different question.
555
- */
556
- cue?: {
557
- id: string;
558
- at: number;
559
- required?: boolean;
560
- };
576
+ cue?: {
577
+ id: string;
578
+ at: number;
579
+ required?: boolean;
561
580
  };
562
- /**
563
- * Play budgets in force for this slot when the attempt was planned.
564
- *
565
- * Frozen for the same reason `points` is: a budget decides the grade, so an
566
- * author who edits `maxPlays: 2 → 4` mid-window must not be able to change
567
- * what a past learner was held to. A group's stimulus budget repeats on every
568
- * slot of the group, exactly as `group.stimulusHash` already does.
569
- *
570
- * Absent when the slot budgets nothing, which keeps the plan — and therefore
571
- * `planHash` — byte-identical for every paper written before 0.8.0.
572
- */
573
- mediaBudgets?: MediaBudgetRef[];
581
+ };
582
+ /**
583
+ * Play budgets in force for this slot when the attempt was planned.
584
+ *
585
+ * Frozen for the same reason `points` is: a budget decides the grade, so an
586
+ * author who edits `maxPlays: 2 → 4` mid-window must not be able to change
587
+ * what a past learner was held to. A group's stimulus budget repeats on every
588
+ * slot of the group, exactly as `group.stimulusHash` already does.
589
+ *
590
+ * Absent when the slot budgets nothing, which keeps the plan — and therefore
591
+ * `planHash` — byte-identical for every paper written before 0.8.0.
592
+ */
593
+ mediaBudgets?: MediaBudgetRef[];
574
594
  }
575
595
  /** A budgeted recording a slot presents, frozen as served. */
576
596
  interface MediaBudgetRef {
577
- /** `slot:<slotId>` or `stimulus:<entryKey>`. */
578
- key: string;
579
- /** The `maxPlays` in force when the attempt was planned. */
580
- maxPlays: number;
597
+ /** `slot:<slotId>` or `stimulus:<entryKey>`. */
598
+ key: string;
599
+ /** The `maxPlays` in force when the attempt was planned. */
600
+ maxPlays: number;
581
601
  }
582
602
  /** Everything needed to reproduce and re-grade one attempt. */
583
603
  interface AttemptPlan {
584
- /** Version of this envelope, so a stored plan stays readable as it evolves. */
585
- planVersion: '1.0';
586
- /**
587
- * The seed every shuffle in this attempt used, when anything shuffled.
588
- * Absent means nothing was shuffled and the order is the authored one.
589
- */
590
- seed?: string;
591
- /**
592
- * Whether the top-level entries were shuffled. Recorded because
593
- * {@link verifyAttemptPlan} needs to rebuild the SAME presented order: a
594
- * re-plan that omitted this returned authored order, every slot compared as
595
- * re-ordered, and unchanged content reported as drift.
596
- */
597
- shuffleEntries?: boolean;
598
- /**
599
- * Fingerprint of the whole plan's content — every slot's identity, order,
600
- * points and content hash. One value to store against an attempt and compare
601
- * later; the per-slot hashes then say WHICH item moved.
602
- */
603
- planHash: string;
604
- /**
605
- * The delivery policy the attempt was sat under, every setting spelled out:
606
- * whether feedback, solutions and hints showed, and which AI help was on.
607
- * Absent when `planAttempt` was given none. Part of `planHash` when present.
608
- */
609
- delivery?: ResolvedDeliveryPolicy;
610
- /**
611
- * The scoring policy the attempt was sat under, every setting spelled out:
612
- * the tries each question gave, which counted, and what tries and hints
613
- * cost. Absent when `planAttempt` was given none. Part of `planHash` when
614
- * present.
615
- */
616
- scoring?: ResolvedItemScoringPolicy;
617
- slots: AttemptPlanSlot[];
618
- /** Sum of every slot's `points`, frozen. The denominator of the paper. */
619
- totalPoints: number;
604
+ /** Version of this envelope, so a stored plan stays readable as it evolves. */
605
+ planVersion: '1.0';
606
+ /**
607
+ * The seed every shuffle in this attempt used, when anything shuffled.
608
+ * Absent means nothing was shuffled and the order is the authored one.
609
+ */
610
+ seed?: string;
611
+ /**
612
+ * Whether the top-level entries were shuffled. Recorded because
613
+ * {@link verifyAttemptPlan} needs to rebuild the SAME presented order: a
614
+ * re-plan that omitted this returned authored order, every slot compared as
615
+ * re-ordered, and unchanged content reported as drift.
616
+ */
617
+ shuffleEntries?: boolean;
618
+ /**
619
+ * Fingerprint of the whole plan's content — every slot's identity, order,
620
+ * points and content hash. One value to store against an attempt and compare
621
+ * later; the per-slot hashes then say WHICH item moved.
622
+ */
623
+ planHash: string;
624
+ /**
625
+ * The delivery policy the attempt was sat under, every setting spelled out:
626
+ * whether feedback, solutions and hints showed, and which AI help was on.
627
+ * Absent when `planAttempt` was given none. Part of `planHash` when present.
628
+ */
629
+ delivery?: ResolvedDeliveryPolicy;
630
+ /**
631
+ * The scoring policy the attempt was sat under, every setting spelled out:
632
+ * the tries each question gave, which counted, and what tries and hints
633
+ * cost. Absent when `planAttempt` was given none. Part of `planHash` when
634
+ * present.
635
+ */
636
+ scoring?: ResolvedItemScoringPolicy;
637
+ slots: AttemptPlanSlot[];
638
+ /** Sum of every slot's `points`, frozen. The denominator of the paper. */
639
+ totalPoints: number;
620
640
  }
621
641
  /** What {@link verifyAttemptPlan} found when a plan met current content. */
622
642
  interface AttemptPlanDrift {
623
- /** True when the plan and the content still agree in every respect. */
624
- matches: boolean;
625
- /** Slots in the plan that no longer exist in the content at all. */
626
- missingSlotIds: string[];
627
- /** Slots present now that the plan never held — content added since. */
628
- addedSlotIds: string[];
629
- /** Slots whose activity content has been edited since the attempt. */
630
- changedSlotIds: string[];
631
- /** Slots whose item group's stimulus has been edited since the attempt. */
632
- changedStimulusSlotIds: string[];
633
- /**
634
- * Slots of an interactive video whose question now sits in a different quiz,
635
- * at a different moment, or under a different `required` — or that gained or
636
- * lost a quiz altogether. Always empty for content without a timeline.
637
- */
638
- changedCueSlotIds: string[];
639
- /**
640
- * Slots now worth a different number of points. A reweight is a paper
641
- * change — it moves the grade without touching a single question — so it
642
- * cannot be left out of a remark or an appeal.
643
- */
644
- changedPointsSlotIds: string[];
645
- /** Slots presented at a different position now than they were then. */
646
- reorderedSlotIds: string[];
647
- /**
648
- * The delivery policy differs: one plan records a policy the other does not,
649
- * or a setting differs. Not a change to any question, but a change to the
650
- * conditions it was asked under — hints on in one, off in the other — so it
651
- * breaks `matches` like any other difference.
652
- *
653
- * Present only when it is `true`, so a report between two plans without a
654
- * policy has exactly the shape it had before policies existed.
655
- */
656
- deliveryChanged?: true;
657
- /**
658
- * The scoring policy differs: one plan records a policy the other does not,
659
- * or a setting differs. The same answers are worth something else under
660
- * another policy, so it breaks `matches`. Present only when it is `true`.
661
- */
662
- scoringChanged?: true;
643
+ /** True when the plan and the content still agree in every respect. */
644
+ matches: boolean;
645
+ /** Slots in the plan that no longer exist in the content at all. */
646
+ missingSlotIds: string[];
647
+ /** Slots present now that the plan never held — content added since. */
648
+ addedSlotIds: string[];
649
+ /** Slots whose activity content has been edited since the attempt. */
650
+ changedSlotIds: string[];
651
+ /** Slots whose item group's stimulus has been edited since the attempt. */
652
+ changedStimulusSlotIds: string[];
653
+ /**
654
+ * Slots of an interactive video whose question now sits in a different quiz,
655
+ * at a different moment, or under a different `required` — or that gained or
656
+ * lost a quiz altogether. Always empty for content without a timeline.
657
+ */
658
+ changedCueSlotIds: string[];
659
+ /**
660
+ * Slots now worth a different number of points. A reweight is a paper
661
+ * change — it moves the grade without touching a single question — so it
662
+ * cannot be left out of a remark or an appeal.
663
+ */
664
+ changedPointsSlotIds: string[];
665
+ /** Slots presented at a different position now than they were then. */
666
+ reorderedSlotIds: string[];
667
+ /**
668
+ * The delivery policy differs: one plan records a policy the other does not,
669
+ * or a setting differs. Not a change to any question, but a change to the
670
+ * conditions it was asked under — hints on in one, off in the other — so it
671
+ * breaks `matches` like any other difference.
672
+ *
673
+ * Present only when it is `true`, so a report between two plans without a
674
+ * policy has exactly the shape it had before policies existed.
675
+ */
676
+ deliveryChanged?: true;
677
+ /**
678
+ * The scoring policy differs: one plan records a policy the other does not,
679
+ * or a setting differs. The same answers are worth something else under
680
+ * another policy, so it breaks `matches`. Present only when it is `true`.
681
+ */
682
+ scoringChanged?: true;
663
683
  }
664
-
684
+ //#endregion
685
+ //#region src/attempt-plan.d.ts
665
686
  /** Options for {@link planAttempt}. */
666
- interface PlanAttemptOptions<TItem> {
667
- /** Shuffle the top-level entries. A group moves as one block. */
668
- shuffleEntries?: boolean;
669
- /**
670
- * Seed for every shuffle in this attempt. Required whenever anything
671
- * shuffles — the attempt has to be reproducible, which is the entire point
672
- * of writing a plan down. Use the attempt id.
673
- */
674
- seed?: string;
675
- /**
676
- * What each slot is worth. Defaults to 1 for every slot.
677
- *
678
- * Points are resolved HERE, not read from content, because they belong to
679
- * the paper rather than the item: the same question is worth 1 in a practice
680
- * quiz and 3 in a final. Whatever this returns is frozen into the plan and
681
- * is what `composeAssessmentScore` will weight by.
682
- *
683
- * @throws Error when it returns a value that is not a finite, non-negative
684
- * number — a slot worth `NaN` points would poison the whole total.
685
- */
686
- points?: (slot: SequenceSlot<TItem>) => number;
687
- /**
688
- * The delivery policy this attempt is sat under — whether hints were
689
- * offered, whether AI help was, whether feedback and solutions showed.
690
- * Frozen into the plan with every setting spelled out, so the record of the
691
- * conditions a grade was earned under does not depend on today's defaults.
692
- *
693
- * Recorded only when given: a plan made without one is byte-identical to a
694
- * plan made before policies existed, `planHash` included.
695
- *
696
- * @throws Error when the policy does not pass `validateDeliveryPolicy` —
697
- * a misspelled restriction is no restriction, and a plan is the
698
- * record an appeal reads.
699
- */
700
- delivery?: DeliveryPolicy | null;
701
- /**
702
- * The scoring policy this attempt is sat under — how many tries each
703
- * question gives, which one counts, and what tries and hints cost. Frozen
704
- * into the plan with every setting spelled out, like `delivery`, and for a
705
- * stronger reason: every setting in it moves a grade, so a re-grade must
706
- * apply the rules the learner sat under, not today's.
707
- *
708
- * Recorded only when given: a plan made without one is byte-identical to a
709
- * plan made before scoring policies existed, `planHash` included.
710
- *
711
- * @throws Error when the policy does not pass `validateItemScoringPolicy`.
712
- */
713
- scoring?: ItemScoringPolicy | null;
687
+ export interface PlanAttemptOptions<TItem> {
688
+ /** Shuffle the top-level entries. A group moves as one block. */
689
+ shuffleEntries?: boolean;
690
+ /**
691
+ * Seed for every shuffle in this attempt. Required whenever anything
692
+ * shuffles — the attempt has to be reproducible, which is the entire point
693
+ * of writing a plan down. Use the attempt id.
694
+ */
695
+ seed?: string;
696
+ /**
697
+ * What each slot is worth. Defaults to 1 for every slot.
698
+ *
699
+ * Points are resolved HERE, not read from content, because they belong to
700
+ * the paper rather than the item: the same question is worth 1 in a practice
701
+ * quiz and 3 in a final. Whatever this returns is frozen into the plan and
702
+ * is what `composeAssessmentScore` will weight by.
703
+ *
704
+ * @throws Error when it returns a value that is not a finite, non-negative
705
+ * number — a slot worth `NaN` points would poison the whole total.
706
+ */
707
+ points?: (slot: SequenceSlot<TItem>) => number;
708
+ /**
709
+ * The delivery policy this attempt is sat under — whether hints were
710
+ * offered, whether AI help was, whether feedback and solutions showed.
711
+ * Frozen into the plan with every setting spelled out, so the record of the
712
+ * conditions a grade was earned under does not depend on today's defaults.
713
+ *
714
+ * Recorded only when given: a plan made without one is byte-identical to a
715
+ * plan made before policies existed, `planHash` included.
716
+ *
717
+ * @throws Error when the policy does not pass `validateDeliveryPolicy` —
718
+ * a misspelled restriction is no restriction, and a plan is the
719
+ * record an appeal reads.
720
+ */
721
+ delivery?: DeliveryPolicy | null;
722
+ /**
723
+ * The scoring policy this attempt is sat under — how many tries each
724
+ * question gives, which one counts, and what tries and hints cost. Frozen
725
+ * into the plan with every setting spelled out, like `delivery`, and for a
726
+ * stronger reason: every setting in it moves a grade, so a re-grade must
727
+ * apply the rules the learner sat under, not today's.
728
+ *
729
+ * Recorded only when given: a plan made without one is byte-identical to a
730
+ * plan made before scoring policies existed, `planHash` included.
731
+ *
732
+ * @throws Error when the policy does not pass `validateItemScoringPolicy`.
733
+ */
734
+ scoring?: ItemScoringPolicy | null;
714
735
  }
715
736
  /**
716
737
  * Freezes what an attempt is being served: the presented order, each slot's
@@ -728,9 +749,9 @@ interface PlanAttemptOptions<TItem> {
728
749
  * empty, when two entries collide on a `slotKey`, or when `points`
729
750
  * returns a value that is not finite and non-negative.
730
751
  */
731
- declare function planAttempt<TItem extends {
732
- id: string;
733
- type: string;
752
+ export declare function planAttempt<TItem extends {
753
+ id: string;
754
+ type: string;
734
755
  }>(entries: readonly SequenceEntry<TItem>[], options?: PlanAttemptOptions<TItem>): AttemptPlan;
735
756
  /**
736
757
  * Compares a stored plan with the content as it stands now, and reports every
@@ -756,23 +777,23 @@ declare function planAttempt<TItem extends {
756
777
  * A drift is not automatically a problem — a fixed typo changes a hash without
757
778
  * changing what was asked. It is a fact somebody has to be able to see.
758
779
  */
759
- declare function verifyAttemptPlan(plan: AttemptPlan, current: AttemptPlan): AttemptPlanDrift;
780
+ export declare function verifyAttemptPlan(plan: AttemptPlan, current: AttemptPlan): AttemptPlanDrift;
760
781
  /** How {@link scoredItemsFromPlan} fills a slot that has no recorded outcome. */
761
- type MissingOutcomePolicy =
782
+ export type MissingOutcomePolicy =
762
783
  /**
763
784
  * Default. `{ status: 'deferred', reason: 'no_response_recorded' }` — a
764
785
  * non-terminal state, so the composed result stays `provisional` and cannot
765
786
  * be recorded as a final pass or fail.
766
787
  */
767
- 'deferred'
788
+ 'deferred' |
768
789
  /**
769
790
  * `{ status: 'scored', score: 0 }` — the learner left it blank on a paper
770
791
  * that IS complete. Choose this only when you know the attempt was
771
792
  * submitted; it is a real zero and makes the result final.
772
793
  */
773
- | 'zero'
794
+ 'zero' |
774
795
  /** Build the outcome yourself, per slot. */
775
- | ((slot: AttemptPlanSlot) => ItemOutcome);
796
+ ((slot: AttemptPlanSlot) => ItemOutcome);
776
797
  /**
777
798
  * Turns a plan plus whatever outcomes exist into the `ScoredItem[]`
778
799
  * `composeAssessmentScore` consumes.
@@ -793,12 +814,13 @@ type MissingOutcomePolicy =
793
814
  * Pass outcomes keyed by `slotId`. Keys the plan does not know are ignored:
794
815
  * a plan is the authority on what the attempt contained.
795
816
  */
796
- declare function scoredItemsFromPlan(plan: AttemptPlan, outcomes: Readonly<Record<string, ItemOutcome>>, options?: {
797
- missing?: MissingOutcomePolicy;
817
+ export declare function scoredItemsFromPlan(plan: AttemptPlan, outcomes: Readonly<Record<string, ItemOutcome>>, options?: {
818
+ missing?: MissingOutcomePolicy;
798
819
  }): ScoredItem[];
799
820
  /** Convenience alias: the entry type a plan is built from. */
800
- type PlannableEntry = SequenceEntry<ActivityData>;
801
-
821
+ export type PlannableEntry = SequenceEntry<ActivityData>;
822
+ //#endregion
823
+ //#region src/types/attempt-state.d.ts
802
824
  /**
803
825
  * A resumable snapshot of an attempt in progress.
804
826
  *
@@ -812,46 +834,47 @@ type PlannableEntry = SequenceEntry<ActivityData>;
812
834
  * slot ids alone would happily line up against the wrong questions.
813
835
  */
814
836
  interface AttemptState {
815
- /** Version of this envelope, so a stored snapshot stays readable as it evolves. */
816
- stateVersion: '1.0';
817
- /**
818
- * `planHash` of the {@link AttemptPlan} this state belongs to. `restoreAttemptState`
819
- * refuses a plan that does not match, rather than restoring a learner's
820
- * answers onto a paper they never sat.
821
- */
822
- planHash: string;
823
- /** The learner's answers so far, keyed by `slotId`. */
824
- responses: Record<string, LearnerResponse>;
825
- /**
826
- * Slots the learner has already submitted. Kept apart from `responses`
827
- * because they answer different questions: what did they write, and may they
828
- * still change it.
829
- */
830
- submittedSlotIds: string[];
831
- /** Presented position the learner was on, so a resume reopens there. */
832
- index: number;
833
- /** ISO 8601 timestamp of the snapshot, when the caller supplies one. */
834
- savedAt?: string;
837
+ /** Version of this envelope, so a stored snapshot stays readable as it evolves. */
838
+ stateVersion: '1.0';
839
+ /**
840
+ * `planHash` of the {@link AttemptPlan} this state belongs to. `restoreAttemptState`
841
+ * refuses a plan that does not match, rather than restoring a learner's
842
+ * answers onto a paper they never sat.
843
+ */
844
+ planHash: string;
845
+ /** The learner's answers so far, keyed by `slotId`. */
846
+ responses: Record<string, LearnerResponse>;
847
+ /**
848
+ * Slots the learner has already submitted. Kept apart from `responses`
849
+ * because they answer different questions: what did they write, and may they
850
+ * still change it.
851
+ */
852
+ submittedSlotIds: string[];
853
+ /** Presented position the learner was on, so a resume reopens there. */
854
+ index: number;
855
+ /** ISO 8601 timestamp of the snapshot, when the caller supplies one. */
856
+ savedAt?: string;
835
857
  }
836
858
  /** One slot whose response differs between two snapshots. */
837
859
  interface ResponseDiffEntry {
838
- slotId: string;
839
- /** `added` — answered since; `removed` — cleared; `changed` — a different answer. */
840
- change: 'added' | 'removed' | 'changed';
841
- before?: LearnerResponse;
842
- after?: LearnerResponse;
860
+ slotId: string;
861
+ /** `added` — answered since; `removed` — cleared; `changed` — a different answer. */
862
+ change: 'added' | 'removed' | 'changed';
863
+ before?: LearnerResponse;
864
+ after?: LearnerResponse;
843
865
  }
844
-
866
+ //#endregion
867
+ //#region src/attempt-state.d.ts
845
868
  /** What {@link serializeAttemptState} is given about an attempt in progress. */
846
- interface AttemptProgress {
847
- /** Answers so far, keyed by `slotId`. */
848
- responses: Readonly<Record<string, LearnerResponse>>;
849
- /** Slots already submitted. Defaults to none. */
850
- submittedSlotIds?: readonly string[];
851
- /** Presented position the learner is on. Defaults to 0. */
852
- index?: number;
853
- /** ISO 8601 timestamp to stamp the snapshot with. The SDK does not read a clock. */
854
- savedAt?: string;
869
+ export interface AttemptProgress {
870
+ /** Answers so far, keyed by `slotId`. */
871
+ responses: Readonly<Record<string, LearnerResponse>>;
872
+ /** Slots already submitted. Defaults to none. */
873
+ submittedSlotIds?: readonly string[];
874
+ /** Presented position the learner is on. Defaults to 0. */
875
+ index?: number;
876
+ /** ISO 8601 timestamp to stamp the snapshot with. The SDK does not read a clock. */
877
+ savedAt?: string;
855
878
  }
856
879
  /**
857
880
  * Captures an in-progress attempt as a storable snapshot, bound to its plan.
@@ -867,7 +890,7 @@ interface AttemptProgress {
867
890
  * @throws Error when a response or submitted slot is not in the plan, or when
868
891
  * `index` is not a position the plan actually has.
869
892
  */
870
- declare function serializeAttemptState(plan: AttemptPlan, progress: AttemptProgress): AttemptState;
893
+ export declare function serializeAttemptState(plan: AttemptPlan, progress: AttemptProgress): AttemptState;
871
894
  /**
872
895
  * Reopens a stored snapshot against a plan, refusing anything that does not
873
896
  * belong to it.
@@ -881,7 +904,7 @@ declare function serializeAttemptState(plan: AttemptPlan, progress: AttemptProgr
881
904
  * @throws Error when the snapshot belongs to a different plan, or references
882
905
  * slots the plan does not contain.
883
906
  */
884
- declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): AttemptState;
907
+ export declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): AttemptState;
885
908
  /**
886
909
  * Reports how two snapshots' responses differ, slot by slot.
887
910
  *
@@ -893,8 +916,9 @@ declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): At
893
916
  * Entries come back sorted by `slotId`, so the output is stable regardless of
894
917
  * the order the two objects happened to be written in.
895
918
  */
896
- declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
897
-
919
+ export declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
920
+ //#endregion
921
+ //#region src/authoring/item-group.d.ts
898
922
  /**
899
923
  * A new, empty reading or listening testlet for an editor to start from.
900
924
  *
@@ -906,7 +930,7 @@ declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: P
906
930
  *
907
931
  * @throws Error when `newId` returns an empty or repeated id.
908
932
  */
909
- declare function createItemGroupDraft(context: DraftContext): ItemGroup;
933
+ export declare function createItemGroupDraft(context: DraftContext): ItemGroup;
910
934
  /**
911
935
  * A new, empty interactive video for an editor to start from: an item group
912
936
  * whose stimulus is a video with no file yet, no questions, and a timeline with
@@ -919,7 +943,7 @@ declare function createItemGroupDraft(context: DraftContext): ItemGroup;
919
943
  *
920
944
  * @throws Error when `newId` returns an empty or repeated id.
921
945
  */
922
- declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
946
+ export declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
923
947
  /**
924
948
  * Tells an unfinished testlet from a broken one — {@link validateDraft} for the
925
949
  * container that holds several questions around one passage or recording.
@@ -954,7 +978,7 @@ declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
954
978
  * An item of a type that is not registered, or without a `type`, is skipped:
955
979
  * {@link validateItemGroupDraft} already reports it.
956
980
  */
957
- declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
981
+ export declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
958
982
  /**
959
983
  * The item critic over a question set, as `<ActivitySequence>` takes one: each
960
984
  * entry's findings under its index — an item group's under `N.items.M.…` — and,
@@ -962,9 +986,10 @@ declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
962
986
  * {@link critiqueItemGroupDraft}). An entry of a type that is not registered is
963
987
  * skipped.
964
988
  */
965
- declare function critiqueDrafts(entries: readonly unknown[]): ItemFinding[];
966
- declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<ItemGroup>;
967
-
989
+ export declare function critiqueDrafts(entries: readonly unknown[]): ItemFinding[];
990
+ export declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<ItemGroup>;
991
+ //#endregion
992
+ //#region src/authoring/index.d.ts
968
993
  /**
969
994
  * Tells a draft that is not finished from a draft that is wrong.
970
995
  *
@@ -1002,7 +1027,7 @@ declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<I
1002
1027
  * @throws UnknownActivityTypeError when `type` has no registered descriptor —
1003
1028
  * including `'item-group'`, which is a container, not an activity type.
1004
1029
  */
1005
- declare function validateDraft<T extends ActivityType>(type: T, draft: unknown): DraftValidationResult<ActivityDataMap[T]>;
1030
+ export declare function validateDraft<T extends ActivityType>(type: T, draft: unknown): DraftValidationResult<ActivityDataMap[T]>;
1006
1031
  /**
1007
1032
  * A new, empty draft of an activity type, for an editor to start from.
1008
1033
  *
@@ -1020,7 +1045,7 @@ declare function validateDraft<T extends ActivityType>(type: T, draft: unknown):
1020
1045
  * @throws Error when the type declares no `authoring.createDraft`, or when
1021
1046
  * `newId` returns an empty or repeated id.
1022
1047
  */
1023
- declare function createDraft<T extends ActivityType>(type: T, context: DraftContext): ActivityDataMap[T];
1048
+ export declare function createDraft<T extends ActivityType>(type: T, context: DraftContext): ActivityDataMap[T];
1024
1049
  /**
1025
1050
  * What an experienced item writer would point out on review: flaws a learner
1026
1051
  * can exploit or trip over (`warning`) and item-writing guidelines the item
@@ -1043,8 +1068,29 @@ declare function createDraft<T extends ActivityType>(type: T, context: DraftCont
1043
1068
  * @throws UnknownActivityTypeError when `type` has no registered descriptor —
1044
1069
  * including `'item-group'`: use {@link critiqueItemGroupDraft}.
1045
1070
  */
1046
- declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[];
1047
-
1071
+ export declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[];
1072
+ //#endregion
1073
+ //#region src/built-in-types.d.ts
1074
+ /**
1075
+ * The activity types the SDK ships, in one closed list.
1076
+ *
1077
+ * {@link ActivityType} is `keyof ActivityDataMap`, which a host widens by
1078
+ * module augmentation to name its own types, so it cannot say which types are
1079
+ * the SDK's. This list can: every table the SDK keeps per built-in type is
1080
+ * typed against it (`satisfies Record<BuiltInActivityType, …>`) or walks it, so
1081
+ * a type added here is a compile error, or a failing test, everywhere it has
1082
+ * not been handled yet.
1083
+ *
1084
+ * The SDK's own registry holds exactly these, in this order, before a host
1085
+ * registers anything.
1086
+ */
1087
+ export declare const BUILT_IN_ACTIVITY_TYPES: readonly ["multiple-choice", "fill-in-the-blanks", "written-response", "gap-select", "dictation", "read-aloud"];
1088
+ /** One of {@link BUILT_IN_ACTIVITY_TYPES}: an activity type the SDK ships, not one a host registered. */
1089
+ type BuiltInActivityType = (typeof BUILT_IN_ACTIVITY_TYPES)[number];
1090
+ /** Whether `type` names an activity type the SDK ships. */
1091
+ export declare function isBuiltInActivityType(type: unknown): type is BuiltInActivityType;
1092
+ //#endregion
1093
+ //#region src/content-hash.d.ts
1048
1094
  /**
1049
1095
  * Content fingerprinting — "is this the same content the learner was served?"
1050
1096
  *
@@ -1065,7 +1111,7 @@ declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[
1065
1111
  * that disagreed would raise a false alarm every time a payload made a
1066
1112
  * round-trip through a different serializer.
1067
1113
  */
1068
- declare function canonicalJson(value: unknown, seen?: Set<object>): string;
1114
+ export declare function canonicalJson(value: unknown, seen?: Set<object>): string;
1069
1115
  /**
1070
1116
  * FNV-1a over the UTF-8 bytes of `input`, as 16 lowercase hex digits.
1071
1117
  *
@@ -1076,28 +1122,30 @@ declare function canonicalJson(value: unknown, seen?: Set<object>): string;
1076
1122
  * property, sign the plan with a key the content author does not hold; this
1077
1123
  * exists to catch honest edits, which is what actually happens.
1078
1124
  */
1079
- declare function fingerprint(input: string): string;
1125
+ export declare function fingerprint(input: string): string;
1080
1126
  /**
1081
1127
  * Fingerprints any JSON-serialisable value through {@link canonicalJson}, so
1082
1128
  * the result depends on the content and not on how it was written.
1083
1129
  */
1084
- declare function contentHash(value: unknown): string;
1085
-
1130
+ export declare function contentHash(value: unknown): string;
1131
+ //#endregion
1132
+ //#region src/count-words.d.ts
1086
1133
  /**
1087
- * Canonical word counter for written-response bounds (Req 22.9): tokens are
1134
+ * Canonical word counter for written-response bounds: tokens are
1088
1135
  * maximal runs of non-whitespace (split on `\s+`), so hyphenated forms
1089
1136
  * (`well-known`) count as one word. The empty / whitespace-only string counts
1090
1137
  * 0. Consumers must use this helper rather than re-implementing the split so
1091
1138
  * client previews, SDK scoring, and stored `wordCount` values always agree.
1092
1139
  */
1093
- declare function countWords(text: string): number;
1094
-
1140
+ export declare function countWords(text: string): number;
1141
+ //#endregion
1142
+ //#region src/delivery.d.ts
1095
1143
  /**
1096
1144
  * The policy that restricts nothing: every setting `true`. It is what an absent
1097
1145
  * policy resolves to, and it is exactly the behaviour the SDK had before
1098
1146
  * delivery policies existed.
1099
1147
  */
1100
- declare const OPEN_DELIVERY_POLICY: ResolvedDeliveryPolicy;
1148
+ export declare const OPEN_DELIVERY_POLICY: ResolvedDeliveryPolicy;
1101
1149
  /**
1102
1150
  * A policy with every setting spelled out — see {@link DeliveryPolicy}.
1103
1151
  *
@@ -1106,13 +1154,13 @@ declare const OPEN_DELIVERY_POLICY: ResolvedDeliveryPolicy;
1106
1154
  * policy that is not an object at all restricts everything. Check a policy
1107
1155
  * before you store it with {@link validateDeliveryPolicy}; `planAttempt` does.
1108
1156
  */
1109
- declare function resolveDeliveryPolicy(policy: unknown): ResolvedDeliveryPolicy;
1157
+ export declare function resolveDeliveryPolicy(policy: unknown): ResolvedDeliveryPolicy;
1110
1158
  /**
1111
1159
  * The strictest of several policies: a setting is on only where every one of
1112
1160
  * them leaves it on. How a course's policy and an assessment's combine, and
1113
1161
  * how a pager's policy wins over whatever a question it draws was handed.
1114
1162
  */
1115
- declare function combineDeliveryPolicies(...policies: unknown[]): ResolvedDeliveryPolicy;
1163
+ export declare function combineDeliveryPolicies(...policies: unknown[]): ResolvedDeliveryPolicy;
1116
1164
  /**
1117
1165
  * Checks a policy before it is stored: each setting `true`, `false`, `null`
1118
1166
  * or absent, and nothing else — no misspelled setting, no string standing in
@@ -1123,24 +1171,25 @@ declare function combineDeliveryPolicies(...policies: unknown[]): ResolvedDelive
1123
1171
  * policy is a record of the conditions a paper was sat under: it is worth
1124
1172
  * refusing before it is written down, rather than read charitably after.
1125
1173
  */
1126
- declare function validateDeliveryPolicy(policy: unknown): {
1127
- success: true;
1128
- data: DeliveryPolicy;
1174
+ export declare function validateDeliveryPolicy(policy: unknown): {
1175
+ success: true;
1176
+ data: DeliveryPolicy;
1129
1177
  } | {
1130
- success: false;
1131
- issues: DeliveryPolicyIssue[];
1178
+ success: false;
1179
+ issues: DeliveryPolicyIssue[];
1132
1180
  };
1133
-
1181
+ //#endregion
1182
+ //#region src/errors.d.ts
1134
1183
  /** Thrown when activity data fails schema validation at a component boundary. */
1135
- declare class ActivitySchemaError extends Error {
1136
- readonly activityType: string;
1137
- readonly errors: ValidationError[];
1138
- constructor(activityType: string, errors: ValidationError[]);
1184
+ export declare class ActivitySchemaError extends Error {
1185
+ readonly activityType: string;
1186
+ readonly errors: ValidationError[];
1187
+ constructor(activityType: string, errors: ValidationError[]);
1139
1188
  }
1140
1189
  /** Thrown when an unrecognised activity type is passed to the scoring engine. */
1141
- declare class UnknownActivityTypeError extends Error {
1142
- readonly activityType: string;
1143
- constructor(activityType: string);
1190
+ export declare class UnknownActivityTypeError extends Error {
1191
+ readonly activityType: string;
1192
+ constructor(activityType: string);
1144
1193
  }
1145
1194
  /**
1146
1195
  * Thrown when a grading entry point is asked to grade a `redact()` projection
@@ -1152,9 +1201,9 @@ declare class UnknownActivityTypeError extends Error {
1152
1201
  * type comes back `unscorable`, and a deferred one `deferred`, as it does for
1153
1202
  * any item of that type.
1154
1203
  */
1155
- declare class RedactedScoringError extends Error {
1156
- readonly activityType: string;
1157
- constructor(activityType: string);
1204
+ export declare class RedactedScoringError extends Error {
1205
+ readonly activityType: string;
1206
+ constructor(activityType: string);
1158
1207
  }
1159
1208
  /**
1160
1209
  * Thrown when `score()` is called for an activity type whose grading is
@@ -1163,33 +1212,34 @@ declare class RedactedScoringError extends Error {
1163
1212
  * a learner a failing grade for work that simply has not been graded yet.
1164
1213
  * Call `evaluate()` instead, which returns `{ status: 'deferred', ... }`.
1165
1214
  */
1166
- declare class DeferredScoringError extends Error {
1167
- readonly activityType: string;
1168
- constructor(activityType: string);
1215
+ export declare class DeferredScoringError extends Error {
1216
+ readonly activityType: string;
1217
+ constructor(activityType: string);
1169
1218
  }
1170
-
1219
+ //#endregion
1220
+ //#region src/grading.d.ts
1171
1221
  /** Options for {@link gradeFromRubric}. */
1172
- interface GradeFromRubricOptions {
1173
- /**
1174
- * Scaled score [0,1] required to pass. Defaults to the activity's
1175
- * `passThreshold`, or {@link DEFAULT_PASS_THRESHOLD} when absent.
1176
- */
1177
- passThreshold?: number;
1178
- /** Narrative feedback for the learner, carried onto the record verbatim. */
1179
- feedback?: string | null;
1180
- /**
1181
- * Compare the pass line the way the score is displayed — both sides rounded,
1182
- * via `gte` — whichever threshold applies: `passThreshold` above, the
1183
- * activity's own, or the 0.7 default. The returned `score` stays unrounded.
1184
- * Opt-in, as on `score()` and `evaluate()`: switching it on moves pass/fail
1185
- * for totals in the rounding band.
1186
- *
1187
- * Checked before any criterion is read: `null` reads as no policy, and a
1188
- * policy that cannot be applied — an unknown `mode`, or a `dp` that is not a
1189
- * whole number from 0 to 15 — throws a `RangeError`, even for a rubric that
1190
- * turns out to be unscorable.
1191
- */
1192
- rounding?: RoundingPolicy;
1222
+ export interface GradeFromRubricOptions {
1223
+ /**
1224
+ * Scaled score [0,1] required to pass. Defaults to the activity's
1225
+ * `passThreshold`, or {@link DEFAULT_PASS_THRESHOLD} when absent.
1226
+ */
1227
+ passThreshold?: number;
1228
+ /** Narrative feedback for the learner, carried onto the record verbatim. */
1229
+ feedback?: string | null;
1230
+ /**
1231
+ * Compare the pass line the way the score is displayed — both sides rounded,
1232
+ * via `gte` — whichever threshold applies: `passThreshold` above, the
1233
+ * activity's own, or the 0.7 default. The returned `score` stays unrounded.
1234
+ * Opt-in, as on `score()` and `evaluate()`: switching it on moves pass/fail
1235
+ * for totals in the rounding band.
1236
+ *
1237
+ * Checked before any criterion is read: `null` reads as no policy, and a
1238
+ * policy that cannot be applied — an unknown `mode`, or a `dp` that is not a
1239
+ * whole number from 0 to 15 — throws a `RangeError`, even for a rubric that
1240
+ * turns out to be unscorable.
1241
+ */
1242
+ rounding?: RoundingPolicy;
1193
1243
  }
1194
1244
  /**
1195
1245
  * Computes the weighted total from per-criterion scores — the arithmetic that
@@ -1223,9 +1273,9 @@ interface GradeFromRubricOptions {
1223
1273
  * The returned `GradeRecord.score` is always scaled [0,1] against
1224
1274
  * `maxScore: 1`, like every other score in the SDK.
1225
1275
  */
1226
- declare function gradeFromRubric(criteria: readonly CriterionScore[], activityData?: ActivityData, options?: GradeFromRubricOptions): GradeRecord | {
1227
- unscorable: true;
1228
- reason: string;
1276
+ export declare function gradeFromRubric(criteria: readonly CriterionScore[], activityData?: ActivityData, options?: GradeFromRubricOptions): GradeRecord | {
1277
+ unscorable: true;
1278
+ reason: string;
1229
1279
  };
1230
1280
  /**
1231
1281
  * Lifts a {@link GradeRecord} into the `graded` arm of {@link ItemOutcome}, so
@@ -1246,36 +1296,37 @@ declare function gradeFromRubric(criteria: readonly CriterionScore[], activityDa
1246
1296
  * is what it is: the slot is still owed a real grade, so a composed attempt
1247
1297
  * stays `provisional` and names the slot in `rejectedSlotIds`.
1248
1298
  */
1249
- declare function outcomeFromGrade(grade: GradeRecord): ItemOutcome;
1299
+ export declare function outcomeFromGrade(grade: GradeRecord): ItemOutcome;
1250
1300
  /**
1251
1301
  * True when an outcome carries a real grade — either the SDK scored it
1252
1302
  * synchronously or a grader returned one. Use this instead of testing
1253
1303
  * `status === 'scored'`, which silently misses asynchronously graded work.
1254
1304
  */
1255
- declare function hasGrade(outcome: ItemOutcome): outcome is Extract<ItemOutcome, {
1256
- status: 'scored' | 'graded';
1305
+ export declare function hasGrade(outcome: ItemOutcome): outcome is Extract<ItemOutcome, {
1306
+ status: 'scored' | 'graded';
1257
1307
  }>;
1258
-
1308
+ //#endregion
1309
+ //#region src/item-group.d.ts
1259
1310
  /** Narrows a sequence entry to an item group. */
1260
- declare function isItemGroup<TItem extends {
1261
- type: string;
1311
+ export declare function isItemGroup<TItem extends {
1312
+ type: string;
1262
1313
  }>(entry: SequenceEntry<TItem>): entry is ItemGroup<TItem>;
1263
1314
  /** Options for {@link flattenSequence}. */
1264
- interface FlattenSequenceOptions {
1265
- /**
1266
- * Shuffle the top-level entries. A group moves as ONE block — its items are
1267
- * never interleaved with other entries — which is the reason a group exists
1268
- * as a container rather than as a flag on each item.
1269
- */
1270
- shuffleEntries?: boolean;
1271
- /**
1272
- * Seed for every shuffle in this call: the entries, and each group whose
1273
- * `shuffle` is `within-group`. REQUIRED whenever anything shuffles. The SDK
1274
- * never invents one, because the server that stores an attempt and the
1275
- * client that renders it must derive the SAME order, and only a shared seed
1276
- * makes that true. The attempt id is the natural choice.
1277
- */
1278
- seed?: string;
1315
+ export interface FlattenSequenceOptions {
1316
+ /**
1317
+ * Shuffle the top-level entries. A group moves as ONE block — its items are
1318
+ * never interleaved with other entries — which is the reason a group exists
1319
+ * as a container rather than as a flag on each item.
1320
+ */
1321
+ shuffleEntries?: boolean;
1322
+ /**
1323
+ * Seed for every shuffle in this call: the entries, and each group whose
1324
+ * `shuffle` is `within-group`. REQUIRED whenever anything shuffles. The SDK
1325
+ * never invents one, because the server that stores an attempt and the
1326
+ * client that renders it must derive the SAME order, and only a shared seed
1327
+ * makes that true. The attempt id is the natural choice.
1328
+ */
1329
+ seed?: string;
1279
1330
  }
1280
1331
  /**
1281
1332
  * Turns a sequence definition — loose activities and item groups, in authored
@@ -1291,30 +1342,31 @@ interface FlattenSequenceOptions {
1291
1342
  *
1292
1343
  * @throws Error when a shuffle is requested without a `seed`.
1293
1344
  */
1294
- declare function flattenSequence<TItem extends {
1295
- id: string;
1296
- type: string;
1345
+ export declare function flattenSequence<TItem extends {
1346
+ id: string;
1347
+ type: string;
1297
1348
  }>(entries: readonly SequenceEntry<TItem>[], options?: FlattenSequenceOptions): SequenceSlot<TItem>[];
1298
-
1349
+ //#endregion
1350
+ //#region src/types/media-budget.d.ts
1299
1351
  /**
1300
1352
  * What one budgeted recording has cost the learner so far.
1301
1353
  */
1302
1354
  interface MediaPlayLedgerEntry {
1303
- /**
1304
- * Plays consumed. A non-negative integer. It MAY exceed the budget: an
1305
- * invigilator override and a race the server resolved both legitimately
1306
- * produce that, and clamping here would hide it.
1307
- */
1308
- plays: number;
1309
- /**
1310
- * Where playback stood at the last report, in seconds.
1311
- *
1312
- * Restored on mount so a refresh RESUMES the play the learner already paid
1313
- * for instead of charging them again for it. It can only ever let them
1314
- * continue from where they were, never restart, because `seek` resolves to
1315
- * `'none'` under a budget.
1316
- */
1317
- at?: number;
1355
+ /**
1356
+ * Plays consumed. A non-negative integer. It MAY exceed the budget: an
1357
+ * invigilator override and a race the server resolved both legitimately
1358
+ * produce that, and clamping here would hide it.
1359
+ */
1360
+ plays: number;
1361
+ /**
1362
+ * Where playback stood at the last report, in seconds.
1363
+ *
1364
+ * Restored on mount so a refresh RESUMES the play the learner already paid
1365
+ * for instead of charging them again for it. It can only ever let them
1366
+ * continue from where they were, never restart, because `seek` resolves to
1367
+ * `'none'` under a budget.
1368
+ */
1369
+ at?: number;
1318
1370
  }
1319
1371
  /**
1320
1372
  * The spent-play ledger for one attempt.
@@ -1334,13 +1386,13 @@ interface MediaPlayLedgerEntry {
1334
1386
  * Bound to its paper by `planHash` for the same reason `AttemptState` is.
1335
1387
  */
1336
1388
  interface MediaPlayLedger {
1337
- ledgerVersion: '1.0';
1338
- /** The `planHash` of the paper these counts were spent on. */
1339
- planHash: string;
1340
- /** Keyed by `slotMediaKey()` / `stimulusMediaKey()`. An absent key means nothing spent. */
1341
- entries: Record<string, MediaPlayLedgerEntry>;
1342
- /** ISO 8601, when the caller supplies one. The SDK reads no clock. */
1343
- savedAt?: string;
1389
+ ledgerVersion: '1.0';
1390
+ /** The `planHash` of the paper these counts were spent on. */
1391
+ planHash: string;
1392
+ /** Keyed by `slotMediaKey()` / `stimulusMediaKey()`. An absent key means nothing spent. */
1393
+ entries: Record<string, MediaPlayLedgerEntry>;
1394
+ /** ISO 8601, when the caller supplies one. The SDK reads no clock. */
1395
+ savedAt?: string;
1344
1396
  }
1345
1397
  /**
1346
1398
  * What the SDK asks the consumer to record, before a sample of audio is
@@ -1350,28 +1402,29 @@ interface MediaPlayLedger {
1350
1402
  * seeded at 0 both claim 1, and only an atomic write can tell them apart.
1351
1403
  */
1352
1404
  interface MediaPlayClaim {
1353
- /** `slot:…` / `stimulus:…`. */
1354
- key: string;
1355
- /** The count the client believes was already spent — the value to compare against. */
1356
- previousPlaysUsed: number;
1357
- /** The count the client is claiming: `previousPlaysUsed + 1`. */
1358
- playsUsed: number;
1359
- maxPlays: number;
1360
- playsRemaining: number;
1361
- /** Where the learner stood when the claim was made. Forensics; never identity. */
1362
- slotId: string;
1363
- index: number;
1364
- activityId?: string;
1405
+ /** `slot:…` / `stimulus:…`. */
1406
+ key: string;
1407
+ /** The count the client believes was already spent — the value to compare against. */
1408
+ previousPlaysUsed: number;
1409
+ /** The count the client is claiming: `previousPlaysUsed + 1`. */
1410
+ playsUsed: number;
1411
+ maxPlays: number;
1412
+ playsRemaining: number;
1413
+ /** Where the learner stood when the claim was made. Forensics; never identity. */
1414
+ slotId: string;
1415
+ index: number;
1416
+ activityId?: string;
1365
1417
  }
1366
1418
  /** The consumer's authoritative answer to a {@link MediaPlayClaim}. */
1367
1419
  interface MediaPlayGrant {
1368
- /**
1369
- * The count AFTER the server's atomic write. A value greater than
1370
- * `maxPlays` refuses the play — which is how a second tab is caught.
1371
- */
1372
- playsUsed: number;
1420
+ /**
1421
+ * The count AFTER the server's atomic write. A value greater than
1422
+ * `maxPlays` refuses the play — which is how a second tab is caught.
1423
+ */
1424
+ playsUsed: number;
1373
1425
  }
1374
-
1426
+ //#endregion
1427
+ //#region src/media-budget.d.ts
1375
1428
  /**
1376
1429
  * The authored-entry prefix of a slot id: `"3"` for both `"3"` and `"3.1"`.
1377
1430
  *
@@ -1379,9 +1432,9 @@ interface MediaPlayGrant {
1379
1432
  * `keyOf` rejects a `.` in both an entry key and an item key — so the first
1380
1433
  * `.` is always the group/item separator.
1381
1434
  */
1382
- declare function entryKeyOf(slotId: string): string;
1435
+ export declare function entryKeyOf(slotId: string): string;
1383
1436
  /** Budget key for an activity's OWN `data.media`. One budget per slot. */
1384
- declare function slotMediaKey(slotId: string): string;
1437
+ export declare function slotMediaKey(slotId: string): string;
1385
1438
  /**
1386
1439
  * Budget key for an item group's `stimulus.media`.
1387
1440
  *
@@ -1391,15 +1444,15 @@ declare function slotMediaKey(slotId: string): string;
1391
1444
  * `stimulus.id` would collide across papers, which is the thing slot keys and
1392
1445
  * `planHash` exist to prevent.
1393
1446
  */
1394
- declare function stimulusMediaKey(slotId: string): string;
1447
+ export declare function stimulusMediaKey(slotId: string): string;
1395
1448
  /** A playback policy with every default resolved. One derivation, used everywhere. */
1396
- interface ResolvedPlaybackPolicy {
1397
- controls: 'native' | 'minimal';
1398
- /** `null` when the recording is unbudgeted. */
1399
- maxPlays: number | null;
1400
- seek: 'allow' | 'none';
1401
- rate: 'allow' | 'fixed';
1402
- nativeControlHints: readonly NativeControlHint[];
1449
+ export interface ResolvedPlaybackPolicy {
1450
+ controls: 'native' | 'minimal';
1451
+ /** `null` when the recording is unbudgeted. */
1452
+ maxPlays: number | null;
1453
+ seek: 'allow' | 'none';
1454
+ rate: 'allow' | 'fixed';
1455
+ nativeControlHints: readonly NativeControlHint[];
1403
1456
  }
1404
1457
  /**
1405
1458
  * Resolves the defaults once, so the schema refinements, the plan and the
@@ -1408,7 +1461,7 @@ interface ResolvedPlaybackPolicy {
1408
1461
  * Absent `playback` resolves to exactly the SDK's pre-0.8.0 behaviour:
1409
1462
  * `controls: 'native'`, no budget, free seeking, free speed, no hints.
1410
1463
  */
1411
- declare function resolvePlaybackPolicy(media: ActivityMedia): ResolvedPlaybackPolicy;
1464
+ export declare function resolvePlaybackPolicy(media: ActivityMedia): ResolvedPlaybackPolicy;
1412
1465
  /**
1413
1466
  * Every budgeted recording a plan contains: budget key → the `maxPlays` that
1414
1467
  * was frozen when the attempt was planned.
@@ -1416,7 +1469,7 @@ declare function resolvePlaybackPolicy(media: ActivityMedia): ResolvedPlaybackPo
1416
1469
  * Use it to build the storage rows an attempt needs, and to check a stored
1417
1470
  * ledger against the paper it claims to belong to.
1418
1471
  */
1419
- declare function planMediaBudgets(plan: AttemptPlan): Record<string, number>;
1472
+ export declare function planMediaBudgets(plan: AttemptPlan): Record<string, number>;
1420
1473
  /**
1421
1474
  * Validates a set of spent-play counts against the plan that budgeted them,
1422
1475
  * and stamps the envelope.
@@ -1428,8 +1481,8 @@ declare function planMediaBudgets(plan: AttemptPlan): Record<string, number>;
1428
1481
  * @throws Error when a key is not budgeted by the plan, or a count is not a
1429
1482
  * non-negative integer, or a position is not a finite number.
1430
1483
  */
1431
- declare function serializeMediaPlayLedger(plan: AttemptPlan, entries: Readonly<Record<string, MediaPlayLedgerEntry>>, options?: {
1432
- savedAt?: string;
1484
+ export declare function serializeMediaPlayLedger(plan: AttemptPlan, entries: Readonly<Record<string, MediaPlayLedgerEntry>>, options?: {
1485
+ savedAt?: string;
1433
1486
  }): MediaPlayLedger;
1434
1487
  /**
1435
1488
  * Reopens a stored ledger against the paper it was spent on.
@@ -1443,8 +1496,9 @@ declare function serializeMediaPlayLedger(plan: AttemptPlan, entries: Readonly<R
1443
1496
  * @throws Error on an unrecognised `ledgerVersion`, a `planHash` mismatch, or
1444
1497
  * anything `serializeMediaPlayLedger` refuses.
1445
1498
  */
1446
- declare function restoreMediaPlayLedger(plan: AttemptPlan, stored: MediaPlayLedger): MediaPlayLedger;
1447
-
1499
+ export declare function restoreMediaPlayLedger(plan: AttemptPlan, stored: MediaPlayLedger): MediaPlayLedger;
1500
+ //#endregion
1501
+ //#region src/standard-schema.d.ts
1448
1502
  /**
1449
1503
  * Standard Schema v1 (https://standardschema.dev): the interface zod, valibot,
1450
1504
  * ArkType and other validators implement, so a library can accept a schema from
@@ -1457,68 +1511,85 @@ declare function restoreMediaPlayLedger(plan: AttemptPlan, stored: MediaPlayLedg
1457
1511
  */
1458
1512
  /** A schema that validates unknown input and produces `Output`. */
1459
1513
  interface StandardSchemaV1<Input = unknown, Output = Input> {
1460
- /** The Standard Schema properties. */
1461
- readonly '~standard': StandardSchemaV1.Props<Input, Output>;
1514
+ /** The Standard Schema properties. */
1515
+ readonly '~standard': StandardSchemaV1.Props<Input, Output>;
1462
1516
  }
1463
1517
  declare namespace StandardSchemaV1 {
1464
- /** The Standard Schema properties interface. */
1465
- interface Props<Input = unknown, Output = Input> {
1466
- /** The version number of the standard. */
1467
- readonly version: 1;
1468
- /** The vendor name of the schema library. */
1469
- readonly vendor: string;
1470
- /**
1471
- * Validates unknown input values. lk-core validates synchronously, so a
1472
- * schema whose validation returns a Promise is refused when it is read.
1473
- */
1474
- readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
1475
- /** Inferred types associated with the schema. */
1476
- readonly types?: Types<Input, Output> | undefined;
1477
- }
1478
- /** The result interface of the validate function. */
1479
- type Result<Output> = SuccessResult<Output> | FailureResult;
1480
- /** The result interface if validation succeeds. */
1481
- interface SuccessResult<Output> {
1482
- /** The typed output value. */
1483
- readonly value: Output;
1484
- /** The absence of issues indicates success. */
1485
- readonly issues?: undefined;
1486
- }
1487
- /** Options for the validate function. */
1488
- interface Options {
1489
- /** Implicit support for additional vendor-specific parameters, if needed. */
1490
- readonly libraryOptions?: Record<string, unknown> | undefined;
1491
- }
1492
- /** The result interface if validation fails. */
1493
- interface FailureResult {
1494
- /** The issues of failed validation. */
1495
- readonly issues: ReadonlyArray<Issue>;
1496
- }
1497
- /** The issue interface of the failure output. */
1498
- interface Issue {
1499
- /** The error message of the issue. */
1500
- readonly message: string;
1501
- /** The path of the issue, if any. */
1502
- readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
1503
- }
1504
- /** The path segment interface of the issue. */
1505
- interface PathSegment {
1506
- /** The key representing a path segment. */
1507
- readonly key: PropertyKey;
1508
- }
1509
- /** The Standard Schema types interface. */
1510
- interface Types<Input = unknown, Output = Input> {
1511
- /** The input type of the schema. */
1512
- readonly input: Input;
1513
- /** The output type of the schema. */
1514
- readonly output: Output;
1515
- }
1516
- /** Infers the input type of a Standard Schema. */
1517
- type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
1518
- /** Infers the output type of a Standard Schema. */
1519
- type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
1518
+ /** The Standard Schema properties interface. */
1519
+ interface Props<Input = unknown, Output = Input> {
1520
+ /** The version number of the standard. */
1521
+ readonly version: 1;
1522
+ /** The vendor name of the schema library. */
1523
+ readonly vendor: string;
1524
+ /**
1525
+ * Validates unknown input values. lk-core validates synchronously, so a
1526
+ * schema whose validation returns a Promise is refused when it is read.
1527
+ */
1528
+ readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
1529
+ /** Inferred types associated with the schema. */
1530
+ readonly types?: Types<Input, Output> | undefined;
1531
+ }
1532
+ /** The result interface of the validate function. */
1533
+ type Result<Output> = SuccessResult<Output> | FailureResult;
1534
+ /** The result interface if validation succeeds. */
1535
+ interface SuccessResult<Output> {
1536
+ /** The typed output value. */
1537
+ readonly value: Output;
1538
+ /** The absence of issues indicates success. */
1539
+ readonly issues?: undefined;
1540
+ }
1541
+ /** Options for the validate function. */
1542
+ interface Options {
1543
+ /** Implicit support for additional vendor-specific parameters, if needed. */
1544
+ readonly libraryOptions?: Record<string, unknown> | undefined;
1545
+ }
1546
+ /** The result interface if validation fails. */
1547
+ interface FailureResult {
1548
+ /** The issues of failed validation. */
1549
+ readonly issues: ReadonlyArray<Issue>;
1550
+ }
1551
+ /** The issue interface of the failure output. */
1552
+ interface Issue {
1553
+ /** The error message of the issue. */
1554
+ readonly message: string;
1555
+ /** The path of the issue, if any. */
1556
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
1557
+ }
1558
+ /** The path segment interface of the issue. */
1559
+ interface PathSegment {
1560
+ /** The key representing a path segment. */
1561
+ readonly key: PropertyKey;
1562
+ }
1563
+ /** The Standard Schema types interface. */
1564
+ interface Types<Input = unknown, Output = Input> {
1565
+ /** The input type of the schema. */
1566
+ readonly input: Input;
1567
+ /** The output type of the schema. */
1568
+ readonly output: Output;
1569
+ }
1570
+ /** Infers the input type of a Standard Schema. */
1571
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
1572
+ /** Infers the output type of a Standard Schema. */
1573
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
1520
1574
  }
1521
-
1575
+ //#endregion
1576
+ //#region src/registry/define.d.ts
1577
+ /**
1578
+ * Identity helper that gives full type inference when authoring a descriptor:
1579
+ *
1580
+ * ```ts
1581
+ * const myType = defineActivityType<MyTypeData, MyTypeLearnerResponse>({ ... });
1582
+ * registerActivityType(myType);
1583
+ * ```
1584
+ *
1585
+ * In a module of its own so the SDK's built-in descriptors can use it without
1586
+ * importing the registry they are read into.
1587
+ */
1588
+ export declare function defineActivityType<TData extends {
1589
+ type: string;
1590
+ }, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): ActivityTypeDescriptor<TData, TResponse>;
1591
+ //#endregion
1592
+ //#region src/registry/registry.d.ts
1522
1593
  /** ScoringResult without `passed` — the public `score()` / `evaluate()` fill that in. */
1523
1594
  type PartialScoringResult = Omit<ScoringResult, 'passed'>;
1524
1595
  /**
@@ -1541,18 +1612,18 @@ type Sensitivity = 'public' | 'answer-key' | 'author-only';
1541
1612
  * without classifying it hides it, never leaks it.
1542
1613
  */
1543
1614
  interface FieldPolicy {
1544
- readonly [field: string]: Sensitivity | FieldPolicy;
1615
+ readonly [field: string]: Sensitivity | FieldPolicy;
1545
1616
  }
1546
1617
  /** xAPI interaction types defined by xAPI 1.0.3 (cmi.interaction vocabulary). */
1547
1618
  type XAPIInteractionType = 'choice' | 'fill-in' | 'long-fill-in' | 'matching' | 'sequencing' | 'performance' | 'true-false' | 'other';
1548
1619
  /** Interop facts a generic statement builder cannot infer from data alone. */
1549
1620
  interface ActivityTypeInterop<TData> {
1550
- /** IRI for the xAPI Activity `definition.type`. */
1551
- readonly xapiActivityTypeIri?: string;
1552
- /** xAPI `definition.interactionType` for this activity type. */
1553
- readonly xapiInteractionType?: XAPIInteractionType;
1554
- /** Builds the xAPI `correctResponsesPattern` strings for an item. */
1555
- readonly correctResponsesPattern?: (data: TData) => string[];
1621
+ /** IRI for the xAPI Activity `definition.type`. */
1622
+ readonly xapiActivityTypeIri?: string;
1623
+ /** xAPI `definition.interactionType` for this activity type. */
1624
+ readonly xapiInteractionType?: XAPIInteractionType;
1625
+ /** Builds the xAPI `correctResponsesPattern` strings for an item. */
1626
+ readonly correctResponsesPattern?: (data: TData) => string[];
1556
1627
  }
1557
1628
  /**
1558
1629
  * How responses to an activity type are graded:
@@ -1562,12 +1633,12 @@ interface ActivityTypeInterop<TData> {
1562
1633
  * (e.g. word counts), surfaced in `ItemOutcome.partial`.
1563
1634
  */
1564
1635
  type ActivityTypeScoring<TData, TResponse> = {
1565
- readonly kind: 'sync';
1566
- readonly score: (data: TData, response: TResponse) => PartialScoringResult;
1636
+ readonly kind: 'sync';
1637
+ readonly score: (data: TData, response: TResponse) => PartialScoringResult;
1567
1638
  } | {
1568
- readonly kind: 'deferred';
1569
- readonly reason: 'requires_async_grading';
1570
- readonly partial?: (data: TData, response: TResponse | undefined) => DeferredScoringPartial;
1639
+ readonly kind: 'deferred';
1640
+ readonly reason: 'requires_async_grading';
1641
+ readonly partial?: (data: TData, response: TResponse | undefined) => DeferredScoringPartial;
1571
1642
  };
1572
1643
  /**
1573
1644
  * Authoring support for an activity type: the empty draft an editor starts
@@ -1577,47 +1648,47 @@ type ActivityTypeScoring<TData, TResponse> = {
1577
1648
  * `createDraft()` throws for the type.
1578
1649
  */
1579
1650
  interface ActivityTypeAuthoring<TData> {
1580
- /**
1581
- * A new draft: every required field present, nothing authored yet. It must
1582
- * come back from `validateDraft` as `incomplete` — never `invalid`, and never
1583
- * `complete` — so a freshly added question is not reported as an error, and
1584
- * cannot pass validation before anyone has written it.
1585
- */
1586
- readonly createDraft?: (context: DraftContext) => TData;
1587
- /**
1588
- * Reports what is missing (`incomplete`) and what is wrong (`invalid`) in a
1589
- * draft. Receives any plain object and must not throw on one.
1590
- *
1591
- * Report each problem at the path the schema reports it. `validateDraft` adds
1592
- * every schema failure as `invalid` unless an issue returned here sits at that
1593
- * path or inside it — so an issue at the wrong path leaves the schema's
1594
- * message standing beside yours, and makes an unfinished draft read as wrong.
1595
- * An issue inside a path accounts for every failure at that path, a list's
1596
- * length included, so report a rule about a whole list at the list's own path.
1597
- * A failure at the root of the draft is accounted for only by an issue at the
1598
- * root. A `null` the schema refuses, where nothing here reports it, comes back
1599
- * as `null_not_allowed`. A zod 4 schema tells a refused `null` from a rule of
1600
- * yours that merely points at one, which keeps its own code; a schema from
1601
- * another library cannot, so report such a rule here, at its path.
1602
- *
1603
- * A code documented in `docs/authoring.md` is reported with its documented
1604
- * severity. For a code of your own, a severity other than `'incomplete'` is
1605
- * reported as `invalid`.
1606
- */
1607
- readonly checkDraft?: (draft: Readonly<Record<string, unknown>>) => DraftIssue[];
1608
- /**
1609
- * The item critic for the type: what `critiqueDraft` reports about a draft
1610
- * that may be perfectly valid — a flaw a learner can exploit (`warning`), or
1611
- * an item-writing guideline it departs from (`advice`). Receives any plain
1612
- * object, finished or not, and must not throw on one: skip a rule whose
1613
- * fields are not there yet. Never a reason to refuse the item; that is
1614
- * `checkDraft`'s.
1615
- *
1616
- * A code documented in `docs/authoring.md` is reported with its documented
1617
- * severity. For a code of your own, a severity other than `'advice'` is
1618
- * reported as `warning`.
1619
- */
1620
- readonly critique?: (draft: Readonly<Record<string, unknown>>) => ItemFinding[];
1651
+ /**
1652
+ * A new draft: every required field present, nothing authored yet. It must
1653
+ * come back from `validateDraft` as `incomplete` — never `invalid`, and never
1654
+ * `complete` — so a freshly added question is not reported as an error, and
1655
+ * cannot pass validation before anyone has written it.
1656
+ */
1657
+ readonly createDraft?: (context: DraftContext) => TData;
1658
+ /**
1659
+ * Reports what is missing (`incomplete`) and what is wrong (`invalid`) in a
1660
+ * draft. Receives any plain object and must not throw on one.
1661
+ *
1662
+ * Report each problem at the path the schema reports it. `validateDraft` adds
1663
+ * every schema failure as `invalid` unless an issue returned here sits at that
1664
+ * path or inside it — so an issue at the wrong path leaves the schema's
1665
+ * message standing beside yours, and makes an unfinished draft read as wrong.
1666
+ * An issue inside a path accounts for every failure at that path, a list's
1667
+ * length included, so report a rule about a whole list at the list's own path.
1668
+ * A failure at the root of the draft is accounted for only by an issue at the
1669
+ * root. A `null` the schema refuses, where nothing here reports it, comes back
1670
+ * as `null_not_allowed`. A zod 4 schema tells a refused `null` from a rule of
1671
+ * yours that merely points at one, which keeps its own code; a schema from
1672
+ * another library cannot, so report such a rule here, at its path.
1673
+ *
1674
+ * A code documented in `docs/authoring.md` is reported with its documented
1675
+ * severity. For a code of your own, a severity other than `'incomplete'` is
1676
+ * reported as `invalid`.
1677
+ */
1678
+ readonly checkDraft?: (draft: Readonly<Record<string, unknown>>) => DraftIssue[];
1679
+ /**
1680
+ * The item critic for the type: what `critiqueDraft` reports about a draft
1681
+ * that may be perfectly valid — a flaw a learner can exploit (`warning`), or
1682
+ * an item-writing guideline it departs from (`advice`). Receives any plain
1683
+ * object, finished or not, and must not throw on one: skip a rule whose
1684
+ * fields are not there yet. Never a reason to refuse the item; that is
1685
+ * `checkDraft`'s.
1686
+ *
1687
+ * A code documented in `docs/authoring.md` is reported with its documented
1688
+ * severity. For a code of your own, a severity other than `'advice'` is
1689
+ * reported as `warning`.
1690
+ */
1691
+ readonly critique?: (draft: Readonly<Record<string, unknown>>) => ItemFinding[];
1621
1692
  }
1622
1693
  /**
1623
1694
  * A value-level description of an activity type: its contract (schema), its
@@ -1640,77 +1711,66 @@ interface ActivityTypeAuthoring<TData> {
1640
1711
  * ```
1641
1712
  */
1642
1713
  interface ActivityTypeDescriptor<TData extends {
1643
- type: string;
1714
+ type: string;
1644
1715
  }, TResponse> {
1645
- /** The `type` discriminator string (kebab-case by convention). */
1646
- readonly type: TData['type'];
1647
- /**
1648
- * The activity's data contract, as a Standard Schema whose output is the
1649
- * data. Its validation must be synchronous: every entry point that reads it
1650
- * is.
1651
- */
1652
- readonly schema: StandardSchemaV1<unknown, TData>;
1653
- /**
1654
- * The contract as JSON Schema, for `jsonSchemaFor`. Leave it out when
1655
- * `schema` can produce one itself through the Standard JSON Schema converter
1656
- * (`'~standard'.jsonSchema`), as a zod 4.6 schema can; give it to override
1657
- * that, or for a library that cannot.
1658
- */
1659
- readonly jsonSchema?: Readonly<Record<string, unknown>>;
1660
- /** How responses are graded. */
1661
- readonly scoring: ActivityTypeScoring<TData, TResponse>;
1662
- /** Whether a response counts as an answer (vs. blank/untouched). */
1663
- readonly isAnswered?: (response: TResponse | undefined) => boolean;
1664
- /** Per-field sensitivity map driving `redact()`. Fail-closed. */
1665
- readonly fieldPolicy?: FieldPolicy;
1666
- /**
1667
- * Schema the output of `redact(data)` (with default `reveal: 'none'`) must
1668
- * satisfy, as a Standard Schema. Strict by design: it proves the ABSENCE of
1669
- * answer-key fields, so `assertRedacted` can guarantee a payload is safe to
1670
- * send to a learner.
1671
- */
1672
- readonly redactedSchema?: StandardSchemaV1;
1673
- /** Interop facts for xAPI (and later QTI) statement building. */
1674
- readonly interop?: ActivityTypeInterop<TData>;
1675
- /** The interaction-event kinds components for this type emit. */
1676
- readonly interactions?: readonly string[];
1677
- /** Draft support for authoring tools. See {@link ActivityTypeAuthoring}. */
1678
- readonly authoring?: ActivityTypeAuthoring<TData>;
1716
+ /** The `type` discriminator string (kebab-case by convention). */
1717
+ readonly type: TData['type'];
1718
+ /**
1719
+ * The activity's data contract, as a Standard Schema whose output is the
1720
+ * data. Its validation must be synchronous: every entry point that reads it
1721
+ * is.
1722
+ */
1723
+ readonly schema: StandardSchemaV1<unknown, TData>;
1724
+ /**
1725
+ * The contract as JSON Schema, for `jsonSchemaFor`. Leave it out when
1726
+ * `schema` can produce one itself through the Standard JSON Schema converter
1727
+ * (`'~standard'.jsonSchema`), as a zod 4.6 schema can; give it to override
1728
+ * that, or for a library that cannot.
1729
+ */
1730
+ readonly jsonSchema?: Readonly<Record<string, unknown>>;
1731
+ /** How responses are graded. */
1732
+ readonly scoring: ActivityTypeScoring<TData, TResponse>;
1733
+ /** Whether a response counts as an answer (vs. blank/untouched). */
1734
+ readonly isAnswered?: (response: TResponse | undefined) => boolean;
1735
+ /** Per-field sensitivity map driving `redact()`. Fail-closed. */
1736
+ readonly fieldPolicy?: FieldPolicy;
1737
+ /**
1738
+ * Schema the output of `redact(data)` (with default `reveal: 'none'`) must
1739
+ * satisfy, as a Standard Schema. Strict by design: it proves the ABSENCE of
1740
+ * answer-key fields, so `assertRedacted` can guarantee a payload is safe to
1741
+ * send to a learner.
1742
+ */
1743
+ readonly redactedSchema?: StandardSchemaV1;
1744
+ /** Interop facts for xAPI (and later QTI) statement building. */
1745
+ readonly interop?: ActivityTypeInterop<TData>;
1746
+ /** The interaction-event kinds components for this type emit. */
1747
+ readonly interactions?: readonly string[];
1748
+ /** Draft support for authoring tools. See {@link ActivityTypeAuthoring}. */
1749
+ readonly authoring?: ActivityTypeAuthoring<TData>;
1679
1750
  }
1680
1751
  /**
1681
1752
  * Internal type-erased descriptor shape stored in the registry. Dispatch call
1682
1753
  * sites cast payloads back; the public generic API preserves inference.
1683
1754
  */
1684
1755
  interface RegisteredActivityTypeDescriptor {
1685
- readonly type: string;
1686
- readonly schema: StandardSchemaV1;
1687
- readonly jsonSchema?: Readonly<Record<string, unknown>>;
1688
- readonly scoring: {
1689
- readonly kind: 'sync';
1690
- readonly score: (data: unknown, response: unknown) => PartialScoringResult;
1691
- } | {
1692
- readonly kind: 'deferred';
1693
- readonly reason: 'requires_async_grading';
1694
- readonly partial?: (data: unknown, response: unknown) => DeferredScoringPartial;
1695
- };
1696
- readonly isAnswered?: (response: unknown) => boolean;
1697
- readonly fieldPolicy?: FieldPolicy;
1698
- readonly redactedSchema?: StandardSchemaV1;
1699
- readonly interop?: ActivityTypeInterop<unknown>;
1700
- readonly interactions?: readonly string[];
1701
- readonly authoring?: ActivityTypeAuthoring<unknown>;
1756
+ readonly type: string;
1757
+ readonly schema: StandardSchemaV1;
1758
+ readonly jsonSchema?: Readonly<Record<string, unknown>>;
1759
+ readonly scoring: {
1760
+ readonly kind: 'sync';
1761
+ readonly score: (data: unknown, response: unknown) => PartialScoringResult;
1762
+ } | {
1763
+ readonly kind: 'deferred';
1764
+ readonly reason: 'requires_async_grading';
1765
+ readonly partial?: (data: unknown, response: unknown) => DeferredScoringPartial;
1766
+ };
1767
+ readonly isAnswered?: (response: unknown) => boolean;
1768
+ readonly fieldPolicy?: FieldPolicy;
1769
+ readonly redactedSchema?: StandardSchemaV1;
1770
+ readonly interop?: ActivityTypeInterop<unknown>;
1771
+ readonly interactions?: readonly string[];
1772
+ readonly authoring?: ActivityTypeAuthoring<unknown>;
1702
1773
  }
1703
- /**
1704
- * Identity helper that gives full type inference when authoring a descriptor:
1705
- *
1706
- * ```ts
1707
- * const myType = defineActivityType<MyTypeData, MyTypeLearnerResponse>({ ... });
1708
- * registerActivityType(myType);
1709
- * ```
1710
- */
1711
- declare function defineActivityType<TData extends {
1712
- type: string;
1713
- }, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): ActivityTypeDescriptor<TData, TResponse>;
1714
1774
  /**
1715
1775
  * Registers an activity type on the default registry, making it live for
1716
1776
  * `validateActivity`, `score`, `evaluate`, `redact`, and `jsonSchemaFor`.
@@ -1719,14 +1779,15 @@ declare function defineActivityType<TData extends {
1719
1779
  * type's contract or scoring is exactly the class of accident a summative
1720
1780
  * SDK must not allow.
1721
1781
  */
1722
- declare function registerActivityType<TData extends {
1723
- type: string;
1782
+ export declare function registerActivityType<TData extends {
1783
+ type: string;
1724
1784
  }, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): void;
1725
1785
  /** Returns the registered descriptor for `type`, or `undefined`. */
1726
- declare function getActivityTypeDescriptor(type: string): RegisteredActivityTypeDescriptor | undefined;
1786
+ export declare function getActivityTypeDescriptor(type: string): RegisteredActivityTypeDescriptor | undefined;
1727
1787
  /** The type strings currently registered (built-ins plus consumer-registered). */
1728
- declare function registeredActivityTypes(): string[];
1729
-
1788
+ export declare function registeredActivityTypes(): string[];
1789
+ //#endregion
1790
+ //#region src/redact.d.ts
1730
1791
  /**
1731
1792
  * A learner-safe projection of activity data produced by {@link redact}:
1732
1793
  * the activity's public fields plus the `redacted: true` marker. Renderable
@@ -1734,49 +1795,49 @@ declare function registeredActivityTypes(): string[];
1734
1795
  * but stripped of the answer key, scoring rules, authored feedback, and
1735
1796
  * author-only assets.
1736
1797
  */
1737
- interface RedactedActivityData {
1738
- redacted: true;
1739
- schemaVersion: string;
1740
- type: string;
1741
- id: string;
1742
- title: string;
1743
- [key: string]: unknown;
1798
+ export interface RedactedActivityData {
1799
+ redacted: true;
1800
+ schemaVersion: string;
1801
+ type: string;
1802
+ id: string;
1803
+ title: string;
1804
+ [key: string]: unknown;
1744
1805
  }
1745
1806
  /** Options for {@link redact}. */
1746
- interface RedactOptions {
1747
- /**
1748
- * Which sensitivity tiers to keep beyond `public`:
1749
- * - `'none'` (default) — public fields only; the output satisfies the
1750
- * type's strict redacted schema and `assertRedacted`.
1751
- * - `'after-submit'` — public + answer-key fields (for post-submission
1752
- * review renders). `author-only` fields and unclassified fields are
1753
- * STILL removed; the output will NOT pass `assertRedacted`.
1754
- */
1755
- reveal?: 'none' | 'after-submit';
1756
- /**
1757
- * Per-call sensitivity overrides, merged over the type's registered
1758
- * `fieldPolicy` (top-level keys replace; nested objects merge one level).
1759
- *
1760
- * Sensitivity is partly a PEDAGOGICAL decision, not purely a security one —
1761
- * whether a rubric or a hint is learner-visible differs legitimately between
1762
- * deployments — and the SDK must not freeze that choice. Use this to tighten
1763
- * a field the SDK ships as `public`:
1764
- *
1765
- * ```ts
1766
- * redact(essay, { policy: { rubric: 'author-only' } });
1767
- * ```
1768
- *
1769
- * Overrides can only be applied to fields; they cannot re-open a field the
1770
- * caller has not classified, because unclassified still means removed.
1771
- * What can be tightened is a field the type's `redactedSchema` leaves
1772
- * OPTIONAL, as it leaves the rubric above: the schema check rejects a
1773
- * payload that reveals more than the learner-safe shape, and equally one
1774
- * that is missing part of it. Tightening a field the redacted shape requires
1775
- * — a read-aloud item's `scoring`, `recording`, `referenceText` or `locale`,
1776
- * without which the learner has no item to read — throws
1777
- * {@link ActivitySchemaError} instead of hiding it.
1778
- */
1779
- policy?: FieldPolicy;
1807
+ export interface RedactOptions {
1808
+ /**
1809
+ * Which sensitivity tiers to keep beyond `public`:
1810
+ * - `'none'` (default) — public fields only; the output satisfies the
1811
+ * type's strict redacted schema and `assertRedacted`.
1812
+ * - `'after-submit'` — public + answer-key fields (for post-submission
1813
+ * review renders). `author-only` fields and unclassified fields are
1814
+ * STILL removed; the output will NOT pass `assertRedacted`.
1815
+ */
1816
+ reveal?: 'none' | 'after-submit';
1817
+ /**
1818
+ * Per-call sensitivity overrides, merged over the type's registered
1819
+ * `fieldPolicy` (top-level keys replace; nested objects merge one level).
1820
+ *
1821
+ * Sensitivity is partly a PEDAGOGICAL decision, not purely a security one —
1822
+ * whether a rubric or a hint is learner-visible differs legitimately between
1823
+ * deployments — and the SDK must not freeze that choice. Use this to tighten
1824
+ * a field the SDK ships as `public`:
1825
+ *
1826
+ * ```ts
1827
+ * redact(essay, { policy: { rubric: 'author-only' } });
1828
+ * ```
1829
+ *
1830
+ * Overrides can only be applied to fields; they cannot re-open a field the
1831
+ * caller has not classified, because unclassified still means removed.
1832
+ * What can be tightened is a field the type's `redactedSchema` leaves
1833
+ * OPTIONAL, as it leaves the rubric above: the schema check rejects a
1834
+ * payload that reveals more than the learner-safe shape, and equally one
1835
+ * that is missing part of it. Tightening a field the redacted shape requires
1836
+ * — a read-aloud item's `scoring`, `recording`, `referenceText` or `locale`,
1837
+ * without which the learner has no item to read — throws
1838
+ * {@link ActivitySchemaError} instead of hiding it.
1839
+ */
1840
+ policy?: FieldPolicy;
1780
1841
  }
1781
1842
  /**
1782
1843
  * Produces the learner-safe projection of activity data (R7), driven by the
@@ -1793,8 +1854,8 @@ interface RedactOptions {
1793
1854
  * @throws Error when the registered descriptor declares no `fieldPolicy`
1794
1855
  * (redaction cannot guess sensitivities).
1795
1856
  */
1796
- declare function redact<T extends {
1797
- type: string;
1857
+ export declare function redact<T extends {
1858
+ type: string;
1798
1859
  }>(data: T, options?: RedactOptions): RedactedActivityData;
1799
1860
  /**
1800
1861
  * Asserts that `data` is a learner-safe redacted projection: it carries the
@@ -1803,10 +1864,10 @@ declare function redact<T extends {
1803
1864
  * Use this at the server boundary before sending activity data to a client
1804
1865
  * that must not hold the key.
1805
1866
  */
1806
- declare function assertRedacted(data: unknown): asserts data is RedactedActivityData;
1867
+ export declare function assertRedacted(data: unknown): asserts data is RedactedActivityData;
1807
1868
  /** A learner-safe item group: the container with its marker, holding `redact()` projections. */
1808
- type RedactedItemGroup = ItemGroup<RedactedActivityData> & {
1809
- redacted: true;
1869
+ export type RedactedItemGroup = ItemGroup<RedactedActivityData> & {
1870
+ redacted: true;
1810
1871
  };
1811
1872
  /**
1812
1873
  * Produces the learner-safe projection of an item group: the container and
@@ -1818,8 +1879,8 @@ type RedactedItemGroup = ItemGroup<RedactedActivityData> & {
1818
1879
  * With the default `reveal: 'none'` the container is verified against the
1819
1880
  * strict redacted schema; each item was already verified by `redact`.
1820
1881
  */
1821
- declare function redactItemGroup<TItem extends {
1822
- type: string;
1882
+ export declare function redactItemGroup<TItem extends {
1883
+ type: string;
1823
1884
  }>(group: ItemGroup<TItem>, options?: RedactOptions): RedactedItemGroup;
1824
1885
  /**
1825
1886
  * Asserts that `data` is a learner-safe item group: it carries the marker,
@@ -1829,12 +1890,13 @@ declare function redactItemGroup<TItem extends {
1829
1890
  * failures are reported at `items.<index>.…`. Use it at the server boundary
1830
1891
  * before sending a group to a client that must not hold the key.
1831
1892
  */
1832
- declare function assertRedactedItemGroup(data: unknown): asserts data is RedactedItemGroup;
1833
-
1893
+ export declare function assertRedactedItemGroup(data: unknown): asserts data is RedactedItemGroup;
1894
+ //#endregion
1895
+ //#region src/registry/builtins.d.ts
1834
1896
  /** Built-in Multiple Choice descriptor. */
1835
- declare const multipleChoiceType: ActivityTypeDescriptor<MultipleChoiceData, MultipleChoiceLearnerResponse>;
1897
+ export declare const multipleChoiceType: ActivityTypeDescriptor<MultipleChoiceData, MultipleChoiceLearnerResponse>;
1836
1898
  /** Built-in Fill-in-the-Blanks descriptor. */
1837
- declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, FillInTheBlanksLearnerResponse>;
1899
+ export declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, FillInTheBlanksLearnerResponse>;
1838
1900
  /**
1839
1901
  * Built-in Written Response descriptor. Grading is DEFERRED: submissions are
1840
1902
  * graded asynchronously (AI or human) by the consumer; the synchronous
@@ -1842,23 +1904,24 @@ declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, F
1842
1904
  * submitted text with the canonical `countWords()` — the client-supplied
1843
1905
  * count is informational, never trusted.
1844
1906
  */
1845
- declare const writtenResponseType: ActivityTypeDescriptor<WrittenResponseData, WrittenResponseLearnerResponse>;
1907
+ export declare const writtenResponseType: ActivityTypeDescriptor<WrittenResponseData, WrittenResponseLearnerResponse>;
1846
1908
  /** Built-in Gap Select descriptor. */
1847
- declare const gapSelectType: ActivityTypeDescriptor<GapSelectData, GapSelectLearnerResponse>;
1909
+ export declare const gapSelectType: ActivityTypeDescriptor<GapSelectData, GapSelectLearnerResponse>;
1848
1910
  /**
1849
1911
  * Built-in Dictation descriptor. Graded synchronously: the score is the
1850
1912
  * character-level similarity of the typed text to the transcript, a pure
1851
1913
  * computation identical in a browser and on a server.
1852
1914
  */
1853
- declare const dictationType: ActivityTypeDescriptor<DictationData, DictationLearnerResponse>;
1915
+ export declare const dictationType: ActivityTypeDescriptor<DictationData, DictationLearnerResponse>;
1854
1916
  /**
1855
1917
  * Built-in Read Aloud descriptor. Grading is DEFERRED: the SDK calls no
1856
1918
  * assessor, so the synchronous outcome reports only whether a recording was
1857
1919
  * stored, and `gradeReadAloud` produces the grade once the application holds a
1858
1920
  * speech assessment.
1859
1921
  */
1860
- declare const readAloudType: ActivityTypeDescriptor<ReadAloudData, ReadAloudLearnerResponse>;
1861
-
1922
+ export declare const readAloudType: ActivityTypeDescriptor<ReadAloudData, ReadAloudLearnerResponse>;
1923
+ //#endregion
1924
+ //#region src/shuffle.d.ts
1862
1925
  /**
1863
1926
  * Seeded, deterministic shuffling — the ONE algorithm every presentation-order
1864
1927
  * decision in the SDK goes through: option order in a multiple-choice item,
@@ -1873,7 +1936,7 @@ declare const readAloudType: ActivityTypeDescriptor<ReadAloudData, ReadAloudLear
1873
1936
  * permutation test exists so an accidental one fails loudly.
1874
1937
  */
1875
1938
  /** FNV-1a hash of a string → unsigned 32-bit integer. */
1876
- declare function hashSeed(input: string): number;
1939
+ export declare function hashSeed(input: string): number;
1877
1940
  /**
1878
1941
  * Which draw the Fisher–Yates step uses.
1879
1942
  *
@@ -1905,11 +1968,16 @@ declare function hashSeed(input: string): number;
1905
1968
  * is a package major — scheduled, not smuggled in. Choose v2 for new content
1906
1969
  * where no attempt has been recorded yet.
1907
1970
  */
1908
- type ShuffleVersion = 1 | 2;
1971
+ export type ShuffleVersion = 1 | 2;
1909
1972
  /** Options for {@link seededShuffle}. */
1910
- interface SeededShuffleOptions {
1911
- /** Draw algorithm. Defaults to `1` — see {@link ShuffleVersion}. */
1912
- version?: ShuffleVersion;
1973
+ export interface SeededShuffleOptions {
1974
+ /**
1975
+ * Draw algorithm — see {@link ShuffleVersion}. Left out, it is `1`; leaving
1976
+ * it out is deprecated since lk-core 1.3, since a 2.0 may make `2` the
1977
+ * default. Name it: `1` to reproduce an order already recorded, `2` for new
1978
+ * content.
1979
+ */
1980
+ version?: ShuffleVersion;
1913
1981
  }
1914
1982
  /**
1915
1983
  * Returns a new array holding a permutation of `items` determined entirely by
@@ -1920,8 +1988,17 @@ interface SeededShuffleOptions {
1920
1988
  * (`${attemptId}:${itemId}`), so two shuffles in one attempt do not share an
1921
1989
  * order.
1922
1990
  */
1923
- declare function seededShuffle<T>(items: readonly T[], seed: string, options?: SeededShuffleOptions): T[];
1924
-
1991
+ export declare function seededShuffle<T>(items: readonly T[], seed: string, options: SeededShuffleOptions & {
1992
+ version: ShuffleVersion;
1993
+ }): T[];
1994
+ /**
1995
+ * @deprecated Since lk-core 1.3, name the version: `{ version: 1 }` draws
1996
+ * exactly what this does, `{ version: 2 }` reaches every order. A 2.0 may make
1997
+ * `2` the default, which would re-order what this call returns.
1998
+ */
1999
+ export declare function seededShuffle<T>(items: readonly T[], seed: string, options?: SeededShuffleOptions): T[];
2000
+ //#endregion
2001
+ //#region src/timeline.d.ts
1925
2002
  /**
1926
2003
  * Reads a stored {@link MediaProgress}. Never throws: anything that is not one
1927
2004
  * — a string, a stale shape, an object whose getters throw — answers `null`,
@@ -1933,7 +2010,7 @@ declare function seededShuffle<T>(items: readonly T[], seed: string, options?: S
1933
2010
  * re-cut must not put the playhead somewhere it cannot be. Give `duration`
1934
2011
  * once the video's metadata is known, and both positions are held inside it.
1935
2012
  */
1936
- declare function readMediaProgress(value: unknown, duration?: number): MediaProgress | null;
2013
+ export declare function readMediaProgress(value: unknown, duration?: number): MediaProgress | null;
1937
2014
  /**
1938
2015
  * One interactive video's composed result: the scored items whose slot belongs
1939
2016
  * to the entry, composed as one section of weight 1. A slot belongs when
@@ -1948,8 +2025,9 @@ declare function readMediaProgress(value: unknown, duration?: number): MediaProg
1948
2025
  * otherwise compose nothing into a `final` result, and a refusal must
1949
2026
  * never read as a grade.
1950
2027
  */
1951
- declare function composeTimelineScore(entryKey: string, items: readonly ScoredItem[], policy: CompositionPolicy): AssessmentScore;
1952
-
2028
+ export declare function composeTimelineScore(entryKey: string, items: readonly ScoredItem[], policy: CompositionPolicy): AssessmentScore;
2029
+ //#endregion
2030
+ //#region src/timeline-limits.d.ts
1953
2031
  /**
1954
2032
  * The bounds of an interactive video — an item group with a `timeline`.
1955
2033
  *
@@ -1963,78 +2041,80 @@ declare function composeTimelineScore(entryKey: string, items: readonly ScoredIt
1963
2041
  * a read-aloud's microphone included, because every quiz pauses the video
1964
2042
  * first.
1965
2043
  */
1966
- declare const INTERACTIVE_VIDEO_ITEM_TYPES: readonly ["multiple-choice", "fill-in-the-blanks", "gap-select", "dictation", "read-aloud"];
2044
+ export declare const INTERACTIVE_VIDEO_ITEM_TYPES: readonly ["multiple-choice", "fill-in-the-blanks", "gap-select", "dictation", "read-aloud"];
1967
2045
  /** One of {@link INTERACTIVE_VIDEO_ITEM_TYPES}. */
1968
- type InteractiveVideoItemType = (typeof INTERACTIVE_VIDEO_ITEM_TYPES)[number];
2046
+ export type InteractiveVideoItemType = (typeof INTERACTIVE_VIDEO_ITEM_TYPES)[number];
1969
2047
  /** Whether `type` is one of the item types an interactive video may present. */
1970
- declare function isInteractiveVideoItemType(type: unknown): type is InteractiveVideoItemType;
2048
+ export declare function isInteractiveVideoItemType(type: unknown): type is InteractiveVideoItemType;
1971
2049
  /** The most quizzes one video may hold. */
1972
- declare const TIMELINE_MAX_QUIZZES = 100;
2050
+ export declare const TIMELINE_MAX_QUIZZES = 100;
1973
2051
  /**
1974
2052
  * The most questions one interactive video may hold, across all its quizzes.
1975
2053
  * The player keeps every one of them mounted, so an answer survives the
1976
2054
  * learner rewinding past its quiz.
1977
2055
  */
1978
- declare const TIMELINE_MAX_ITEMS = 200;
2056
+ export declare const TIMELINE_MAX_ITEMS = 200;
1979
2057
  /** The most chapters one video may hold. */
1980
- declare const TIMELINE_MAX_CHAPTERS = 100;
2058
+ export declare const TIMELINE_MAX_CHAPTERS = 100;
1981
2059
  /** The longest quiz or chapter title, in UTF-16 units. A title sits on one line of the player. */
1982
- declare const TIMELINE_MAX_TITLE_LENGTH = 120;
1983
-
2060
+ export declare const TIMELINE_MAX_TITLE_LENGTH = 120;
2061
+ //#endregion
2062
+ //#region src/types/theme.d.ts
1984
2063
  /**
1985
2064
  * All CSS custom property tokens consumed by learning-kit components.
1986
2065
  * Every key maps to a `--lk-*` CSS variable name; every value is a CSS value string.
1987
2066
  * Pass a `Partial<ThemeTokens>` to `ThemeProvider` to override individual tokens.
1988
2067
  */
1989
2068
  interface ThemeTokens {
1990
- '--lk-color-primary': string;
1991
- '--lk-color-primary-hover': string;
1992
- '--lk-color-surface': string;
1993
- '--lk-color-surface-raised': string;
1994
- '--lk-color-border': string;
1995
- '--lk-color-text': string;
1996
- '--lk-color-text-muted': string;
1997
- '--lk-color-success': string;
1998
- '--lk-color-error': string;
1999
- '--lk-color-warning': string;
2000
- '--lk-color-focus-ring': string;
2001
- /**
2002
- * The accent a video player draws on its own dark chrome: the played part
2003
- * of the progress bar, quiz markers, the centre play button. Optional, so a
2004
- * theme written before it existed still type-checks; the default is white,
2005
- * which reads on any video. Set it to a brand colour to match a product.
2006
- */
2007
- '--lk-color-media-accent'?: string;
2008
- /**
2009
- * The interactive video's drawn captions. Optional like the accent above, so
2010
- * a theme written before them still type-checks. The primary line's colour;
2011
- * the second language's colour, which must clear 4.5:1 on the caption box;
2012
- * the second line's size as a share of the first (a number, e.g. `0.85`);
2013
- * and the space between the two lines. The second line differs from the
2014
- * first by position and size as well as colour: colour alone would fail
2015
- * WCAG 1.4.1.
2016
- */
2017
- '--lk-iv-caption-color'?: string;
2018
- '--lk-iv-caption-secondary-color'?: string;
2019
- '--lk-iv-caption-secondary-scale'?: string;
2020
- '--lk-iv-caption-gap'?: string;
2021
- '--lk-spacing-xs': string;
2022
- '--lk-spacing-sm': string;
2023
- '--lk-spacing-md': string;
2024
- '--lk-spacing-lg': string;
2025
- '--lk-spacing-xl': string;
2026
- '--lk-font-family-base': string;
2027
- '--lk-font-size-sm': string;
2028
- '--lk-font-size-base': string;
2029
- '--lk-font-size-lg': string;
2030
- '--lk-font-weight-normal': string;
2031
- '--lk-font-weight-bold': string;
2032
- '--lk-line-height-base': string;
2033
- '--lk-radius-sm': string;
2034
- '--lk-radius-base': string;
2035
- '--lk-radius-lg': string;
2036
- '--lk-transition-fast': string;
2037
- '--lk-transition-base': string;
2069
+ '--lk-color-primary': string;
2070
+ '--lk-color-primary-hover': string;
2071
+ '--lk-color-surface': string;
2072
+ '--lk-color-surface-raised': string;
2073
+ '--lk-color-border': string;
2074
+ '--lk-color-text': string;
2075
+ '--lk-color-text-muted': string;
2076
+ '--lk-color-success': string;
2077
+ '--lk-color-error': string;
2078
+ '--lk-color-warning': string;
2079
+ '--lk-color-focus-ring': string;
2080
+ /**
2081
+ * The accent a video player draws on its own dark chrome: the played part
2082
+ * of the progress bar, quiz markers, the centre play button. Optional, so a
2083
+ * theme written before it existed still type-checks; the default is white,
2084
+ * which reads on any video. Set it to a brand colour to match a product.
2085
+ */
2086
+ '--lk-color-media-accent'?: string;
2087
+ /**
2088
+ * The interactive video's drawn captions. Optional like the accent above, so
2089
+ * a theme written before them still type-checks. The primary line's colour;
2090
+ * the second language's colour, which must clear 4.5:1 on the caption box;
2091
+ * the second line's size as a share of the first (a number, e.g. `0.85`);
2092
+ * and the space between the two lines. The second line differs from the
2093
+ * first by position and size as well as colour: colour alone would fail
2094
+ * WCAG 1.4.1.
2095
+ */
2096
+ '--lk-iv-caption-color'?: string;
2097
+ '--lk-iv-caption-secondary-color'?: string;
2098
+ '--lk-iv-caption-secondary-scale'?: string;
2099
+ '--lk-iv-caption-gap'?: string;
2100
+ '--lk-spacing-xs': string;
2101
+ '--lk-spacing-sm': string;
2102
+ '--lk-spacing-md': string;
2103
+ '--lk-spacing-lg': string;
2104
+ '--lk-spacing-xl': string;
2105
+ '--lk-font-family-base': string;
2106
+ '--lk-font-size-sm': string;
2107
+ '--lk-font-size-base': string;
2108
+ '--lk-font-size-lg': string;
2109
+ '--lk-font-weight-normal': string;
2110
+ '--lk-font-weight-bold': string;
2111
+ '--lk-line-height-base': string;
2112
+ '--lk-radius-sm': string;
2113
+ '--lk-radius-base': string;
2114
+ '--lk-radius-lg': string;
2115
+ '--lk-transition-fast': string;
2116
+ '--lk-transition-base': string;
2038
2117
  }
2039
-
2040
- export { AI_COACHING_MAX_TIP_LENGTH, AI_COACHING_MAX_WORDS, AI_CRITIQUE_MAX_FIELD_LENGTH, AI_CRITIQUE_MAX_FINDINGS, AI_DRAFTS_MAX_COUNT, AI_DRAFTS_MAX_REPAIRS, AI_EXPLANATION_TYPES, AI_HINT_TYPES, AI_TEXT_MAX_LENGTH, AI_WRITING_MAX_CORRECTIONS, AI_WRITING_MAX_FIELD_LENGTH, ActivityData, ActivityDataMap, ActivityMedia, ActivitySchemaError, ActivityType, type ActivityTypeAuthoring, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, AiActivityInput, AiCoaching, AiCoachingRequest, AiCritique, AiCritiqueRequest, AiDraftSettings, AiDraftSource, AiDraftType, AiDrafts, AiDraftsRequest, AiDraftsRun, AiExplanationRequest, AiFeature, AiGeneratedDraft, AiGrade, AiHintRequest, AiItemFacts, AiRefusal, AiSupportedActivityType, AiTextResult, AiVideoDraft, AiWritingFeedback, AiWritingFeedbackRequest, AssessmentScore, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptProgress, type AttemptState, CompositionPolicy, CriterionScore, DeferredScoringError, DeferredScoringPartial, type DeliveryPolicy, type DeliveryPolicyIssue, DictationData, DictationLearnerResponse, DraftContext, DraftIssue, DraftValidationResult, type FieldPolicy, FillInTheBlanksData, FillInTheBlanksLearnerResponse, type FlattenSequenceOptions, GapSelectData, GapSelectLearnerResponse, type GradeFromRubricOptions, GradeRecord, INTERACTIVE_VIDEO_ITEM_TYPES, type InteractiveVideoItemType, ItemFinding, ItemGroup, ItemOutcome, ItemScoringPolicy, LearnerResponse, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, MediaProgress, type MissingOutcomePolicy, MultipleChoiceData, MultipleChoiceLearnerResponse, NativeControlHint, OPEN_DELIVERY_POLICY, type PartialScoringResult, type PlanAttemptOptions, type PlannableEntry, ReadAloudData, ReadAloudLearnerResponse, type RedactOptions, type RedactedActivityData, type RedactedItemGroup, RedactedScoringError, type RegisteredActivityTypeDescriptor, type ResolvedDeliveryPolicy, ResolvedItemScoringPolicy, type ResolvedPlaybackPolicy, type ResponseDiffEntry, RoundingPolicy, ScoredItem, ScoringDetail, ScoringResult, type SeededShuffleOptions, type Sensitivity, SequenceEntry, SequenceSlot, type ShuffleVersion, SpeechAssessment, StandardSchemaV1, TIMELINE_MAX_CHAPTERS, TIMELINE_MAX_ITEMS, TIMELINE_MAX_QUIZZES, TIMELINE_MAX_TITLE_LENGTH, type ThemeTokens, UnknownActivityTypeError, ValidationError, WrittenResponseData, WrittenResponseLearnerResponse, type XAPIInteractionType, aiAllowedByContent, aiCoachingRequest, aiCritiqueRequest, aiDraftsRepairRequest, aiDraftsRequest, aiExplanationRequest, aiGradeOf, aiHintRequest, aiSupports, aiWritingFeedbackRequest, assertRedacted, assertRedactedItemGroup, buildAiFacts, canonicalJson, checkAiCoaching, checkAiCritique, checkAiDrafts, checkAiExplanation, checkAiHint, checkAiWritingFeedback, combineDeliveryPolicies, composeTimelineScore, contentHash, countWords, createDraft, createInteractiveVideoDraft, createItemGroupDraft, critiqueDraft, critiqueDrafts, critiqueItemGroupDraft, defineActivityType, dictationType, diffResponses, entryKeyOf, fillInTheBlanksType, fingerprint, flattenSequence, gapSelectType, generateDrafts, getActivityTypeDescriptor, gradeFromRubric, hasGrade, hashSeed, hintRevealsAnswer, interactiveVideoFromDrafts, isInteractiveVideoItemType, isItemGroup, multipleChoiceType, outcomeFromGrade, planAttempt, planMediaBudgets, readAiTextResult, readAloudType, readMediaProgress, redact, redactItemGroup, registerActivityType, registeredActivityTypes, resolveDeliveryPolicy, resolvePlaybackPolicy, restoreAttemptState, restoreMediaPlayLedger, scoredItemsFromPlan, seededShuffle, serializeAttemptState, serializeMediaPlayLedger, slotMediaKey, stimulusMediaKey, validateDeliveryPolicy, validateDraft, validateItemGroupDraft, verifyAttemptPlan, writtenResponseType };
2118
+ //#endregion
2119
+ export { type ActivityAiPermissions, type ActivityData, type ActivityDataMap, type ActivityFeedback, type ActivityMedia, type ActivityResult, type ActivityType, type ActivityTypeAuthoring, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, type AiActivityInput, type AiBlankFact, type AiCoaching, type AiCoachingRequest, type AiCoachingResult, type AiCoachingWord, type AiCriterionJudgement, type AiCritique, type AiCritiqueField, type AiCritiqueFinding, type AiCritiqueFindingResult, type AiCritiqueKind, type AiCritiqueRequest, type AiCritiqueResult, type AiDictationFacts, type AiDraftCaption, type AiDraftProblem, type AiDraftSettings, type AiDraftSource, type AiDraftType, type AiDrafts, type AiDraftsCall, type AiDraftsRequest, type AiDraftsRun, type AiExplanationRequest, type AiFeature, type AiFillInTheBlanksFacts, type AiGapFact, type AiGapSelectFacts, type AiGeneratedDraft, type AiGrade, type AiGroupInput, type AiHintRequest, type AiItemFacts, type AiMaterialFacts, type AiMultipleChoiceFacts, type AiOptionFact, type AiProvenance, type AiReadingFacts, type AiReadingWordFact, type AiRefusal, type AiRubricCriterionFact, type AiSoundFact, type AiSupportedActivityType, type AiTextResult, type AiVerdict, type AiVideoDraft, type AiWordFact, type AiWritingCorrection, type AiWritingFacts, type AiWritingFeedback, type AiWritingFeedbackRequest, type AiWritingFeedbackResult, type AnsweredStatementParams, type AssessmentScore, type AssessmentSectionInput, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptState, type Band, type BlankConfig, type BuiltInActivityType, type CompletedStatementParams, type CompositionPolicy, type CriterionScore, DEFAULT_ITEM_SCORING_POLICY, DEFAULT_PASS_THRESHOLD, DICTATION_MAX_ACCEPTED_TRANSCRIPTS, DICTATION_MAX_EQUIVALENCES, DICTATION_MAX_EQUIVALENCE_LENGTH, DICTATION_MAX_TEXT_LENGTH, DICTATION_MAX_TRANSCRIPT_LENGTH, type DeferredReason, type DeferredScoringPartial, type DeliveryPolicy, type DeliveryPolicyIssue, type DictationAlignment, type DictationCharOp, type DictationData, type DictationEquivalence, type DictationLearnerResponse, type DictationReference, type DictationSlowMedia, type DictationTolerance, type DictationWordAlignment, type DraftComplete, type DraftContext, type DraftIssue, type DraftNotComplete, type DraftSeverity, type DraftValidationResult, EvaluateOptions, type FieldPolicy, type FillInTheBlanksData, type FillInTheBlanksLearnerResponse, type GapSelectBank, type GapSelectChoice, type GapSelectData, type GapSelectGap, type GapSelectLearnerResponse, type GradeReadAloudOptions, type GradeRecord, type Grader, type GraderKind, type GraderUsage, type GradingState, ITEM_SCORING_MAX_RETRIES, type InlineCorrection, type InteractionEvent, type InteractionKind, type ItemFinding, type ItemFindingSeverity, type ItemGroup, type ItemOutcome, type ItemScoringCount, type ItemScoringPolicy, type ItemScoringPolicyIssue, ItemTriesOutcome, type ItemTriesScore, type ItemTry, type ItemTryScore, type LearnerResponse, type LearnerResponseMap, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, type MediaPlaybackPolicy, type MediaProgress, type MediaTimeline, type MediaTrack, type MultipleChoiceData, type MultipleChoiceLearnerResponse, type MultipleChoiceOption, type MultipleChoiceOptionMedia, type NativeControlHint, type PartialScoringResult, type PassFailureReason, READ_ALOUD_MAX_DIMENSION_WEIGHT, READ_ALOUD_MAX_REFERENCE_LENGTH, READ_ALOUD_MAX_SECONDS, READ_ALOUD_MAX_TAKES, type ReadAloudData, type ReadAloudDimension, type ReadAloudDimensionWeight, type ReadAloudLearnerResponse, type ReadAloudSlowMedia, type ReadAloudWordAlignment, type ReadAloudWordState, type RecordingBounds, type RecordingRef, type RedactedActivity, type RedactedBlankConfig, type RedactedDictationData, type RedactedDictationSlowMedia, type RedactedFillInTheBlanksData, type RedactedGapSelectBank, type RedactedGapSelectChoice, type RedactedGapSelectData, type RedactedGapSelectGap, type RedactedMultipleChoiceData, type RedactedMultipleChoiceOption, type RedactedMultipleChoiceOptionMedia, type RedactedReadAloudData, type RedactedStimulus, type RedactedWrittenResponseData, type RegisteredActivityTypeDescriptor, type ResolvedDeliveryPolicy, type ResolvedItemScoringPolicy, type ResponseDiffEntry, type RoundingMode, type RoundingPolicy, SPEECH_ASSESSMENT_MAX_WORDS, type ScoredItem, type ScoringDetail, ScoringOptions, type ScoringOutcome, type ScoringResult, type SectionScore, type Sensitivity, type SequenceEntry, type SequenceSlot, type SequenceSlotGroup, type SpeechAssessment, type SpeechMeasurement, type SpeechPhoneme, type SpeechPhonemeCandidate, type SpeechPlausibilityPolicy, type SpeechSyllable, type SpeechUnscorable, type SpeechUnscorableCode, type SpeechWord, type SpeechWordError, type StandardSchemaV1, type Stimulus, type StimulusKind, type SubmittedStatementParams, type TextMatchPolicy, type TextMatchResult, type ThemeTokens, type TimelineChapter, type TimelineCue, type ValidationError, type ValidationResult, type WavInspection, type WavInspectionPolicy, type WrittenResponseData, type WrittenResponseLearnerResponse, type WrittenResponseRubric, type WrittenResponseRubricCriterion, type XAPIActor, type XAPIConfig, type XAPIContext, type XAPIContextActivities, type XAPIError, type XAPIInteractionType, type XAPIObject, type XAPIObjectParams, type XAPIResult, type XAPIScore, type XAPIStatement, type XAPIStatementParams, XAPIVerb, type XAPIVerbKey, type XAPIVerbObject, XAPI_VERB_DISPLAY, alignDictation, alignReadAloud, classifyBand, composeAssessmentScore, computePassThreshold, dictationJsonSchema, dictationReferenceWords, diffDictationChars, evaluate, evaluateTries, fillInTheBlanksJsonSchema, gapSelectJsonSchema, gradeReadAloud, gte, inspectWav, itemGroupJsonSchema, jsonSchemaFor, levenshteinDistance, matchText, multipleChoiceJsonSchema, outcomeFromUnscorable, readAloudJsonSchema, resolveItemScoringPolicy, roundGrade, score, scoreTries, stimulusJsonSchema, validateActivity, validateItemGroup, validateItemScoringPolicy, validateMedia, validateOptionMedia, validateSpeechAssessment, validateXAPIStatement, writtenResponseJsonSchema, xAPIBuilder, xapiDefinitionFor };
2120
+ //# sourceMappingURL=index.d.cts.map