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