@intellectif/lk-core 0.13.1 → 0.14.1
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 +29 -0
- package/README.md +1 -1
- package/dist/{activity-DfAmJ1sl.d.cts → activity-BVkg9VDo.d.cts} +153 -4
- package/dist/{activity-DfAmJ1sl.d.ts → activity-BVkg9VDo.d.ts} +153 -4
- package/dist/{chunk-DQKJUMUW.cjs → chunk-2NIALQEH.cjs} +24 -19
- package/dist/chunk-2NIALQEH.cjs.map +1 -0
- package/dist/{chunk-XKKKWKRH.js → chunk-6RND47QE.js} +694 -126
- package/dist/chunk-6RND47QE.js.map +1 -0
- package/dist/{chunk-FT7SAC3X.cjs → chunk-E7LPIZXI.cjs} +13 -10
- package/dist/chunk-E7LPIZXI.cjs.map +1 -0
- package/dist/chunk-J5OIRIOW.cjs +1034 -0
- package/dist/chunk-J5OIRIOW.cjs.map +1 -0
- package/dist/{chunk-PYP3HCRQ.js → chunk-KTDOZR7Y.js} +7 -4
- package/dist/chunk-KTDOZR7Y.js.map +1 -0
- package/dist/{chunk-Y36S3X3L.js → chunk-NBADQ3JU.js} +7 -2
- package/dist/chunk-NBADQ3JU.js.map +1 -0
- package/dist/chunk-RTIR6R2U.js +1034 -0
- package/dist/chunk-RTIR6R2U.js.map +1 -0
- package/dist/{chunk-XONKWL6D.cjs → chunk-VCXIPLEW.cjs} +585 -17
- package/dist/chunk-VCXIPLEW.cjs.map +1 -0
- package/dist/{index-BefQ8FAS.d.cts → index-BE1bM2Wi.d.cts} +238 -16
- package/dist/{index-BiIvdASA.d.ts → index-v2_-Fyn3.d.ts} +238 -16
- package/dist/index.cjs +110 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -17
- package/dist/index.d.ts +45 -17
- package/dist/index.js +35 -5
- package/dist/index.js.map +1 -1
- package/dist/schemas.cjs +11 -3
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/schemas.js +10 -2
- package/dist/scoring.cjs +23 -3
- package/dist/scoring.cjs.map +1 -1
- package/dist/scoring.d.cts +471 -16
- package/dist/scoring.d.ts +471 -16
- package/dist/scoring.js +24 -4
- package/dist/xapi.cjs +3 -3
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/dist/xapi.js +2 -2
- package/package.json +1 -1
- package/vectors/README.md +63 -3
- package/vectors/replay.d.mts +7 -2
- package/vectors/replay.mjs +83 -1
- package/vectors/scoring.json +10875 -2
- package/dist/chunk-DQKJUMUW.cjs.map +0 -1
- package/dist/chunk-FGN4LLSP.js +0 -387
- package/dist/chunk-FGN4LLSP.js.map +0 -1
- package/dist/chunk-FT7SAC3X.cjs.map +0 -1
- package/dist/chunk-PYP3HCRQ.js.map +0 -1
- package/dist/chunk-UHQVIC3P.cjs +0 -387
- package/dist/chunk-UHQVIC3P.cjs.map +0 -1
- package/dist/chunk-XKKKWKRH.js.map +0 -1
- package/dist/chunk-XONKWL6D.cjs.map +0 -1
- package/dist/chunk-Y36S3X3L.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @intellectif/lk-core
|
|
2
2
|
|
|
3
|
+
## 0.14.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ecc47e0: `validateXAPIStatement` now recognises a production browser build. In production it is meant to log a malformed statement and send it anyway, and to throw only in development. It read `NODE_ENV` in a way no bundler replaces, and a browser has no `process` to read at run time, so in every production browser app it took the development path and threw — a malformed statement brought down the activity that built it rather than being logged. It now reads the literal `process.env.NODE_ENV` your bundler substitutes. Node, where `process` exists, behaves as before, and no grade changes.
|
|
8
|
+
|
|
9
|
+
## 0.14.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 7d25492: A built-in `read-aloud` activity type: the learner reads a text aloud, a pronunciation-assessment engine judges the recording, and the SDK turns that judgement into a grade.
|
|
14
|
+
|
|
15
|
+
- `ReadAloudData` carries the `referenceText` the learner reads, a `locale` in canonical BCP 47 with a region, a model recording and an optional slower one (`slowMedia`, a separate file that needs the recording it is the slower reading of), the bounds of a take (`recording`), and `scoring.dimensions` — one to four of `accuracy`, `fluency`, `completeness` and `prosody`, each weighted, at least one above 0. There is no default set of dimensions and a new draft starts with none: an untouched draft must not quietly become a grading rule. The text, the weights and the bounds are all public, so a read-aloud item has no answer key: `redact()` drops the authored feedback, marks the copy, and keeps the rest — a projection a learner may render in full. The schema refuses a text nothing survives of once punctuation and spacing are folded away (`"..."` marks no word at all, so a silent take would record no omission and a perfect reading would align as one insertion after another), and, for now, a script written without spaces between its words, because per-word marks need boundaries the SDK does not compute. Nineteen draft issue codes (`ra_*`) with their severities and paths are in the authoring guide.
|
|
16
|
+
- `ReadAloudLearnerResponse` carries a `RecordingRef` — `{ key, mimeType }`, where the key is opaque storage identity your application issues, never a URL and never bytes — or `null` for a learner who submitted without recording. A `durationMs` the browser reports may ride along and no grade reads it.
|
|
17
|
+
- **Grading is deferred.** `evaluate(data, response)` answers `{ status: 'deferred', reason: 'requires_async_grading', maxScore: 1, partial: { hasRecording } }`, and `score('read-aloud', data, response)` throws `DeferredScoringError` rather than inventing a number. A stored read-aloud item therefore keeps a composed assessment result provisional until it is graded; an unscorable one is left out of the total, so route those to a re-record or a person before releasing a verdict.
|
|
18
|
+
- `SpeechAssessment` is the evidence shape, neutral across engines: the assessed locale, the reference text and recording key the assessment is bound to, who assessed it, dimension scores on a declared 0–100 scale, the recognised text, and per-word marks with optional syllables, phonemes, what each was heard as, timings and break confidences. An absent score means "not measured" and is never a 0. `validateSpeechAssessment(value)` answers `{ success: true, data }` or `{ success: false, errors }` — one error per problem, with the same `path`, `message` and `code` `validateActivity` gives a schema failure — and every object is strict, so a misspelt key is an error rather than silently ignored. Three rules span fields: a scripted assessment carries its `referenceText` and `recordingKey`; a phoneme that names a symbol, or what it was heard as, needs `phonemeAlphabet`; and the words carry at most 8000 characters between them, as they are written and again as they spell once normalised — one character can stand for eighteen, and the marks are made by aligning tokens, so a per-word cap bounds no total.
|
|
19
|
+
- `gradeReadAloud(data, response, assessment, { measured, plausibility, allowAiAssessor?, rounding? })` returns a `GradeRecord` or `{ unscorable: true, code, reason }`. `measured` is your server's own measurement of the stored recording and `plausibility` your own policy; neither has a default, because every value in them decides whether a grade exists. Ten reasons a take is unscorable rather than a zero — evidence that is not well formed, not scripted, made for another locale, another text or another take, produced by a generative model you did not opt into, no speech, too little voiced time, more words per second than your policy allows, or a weighted dimension the assessment does not score. A blank grades 0 with every reference word marked omitted and no grader, because nobody measured it. The weighted dimensions become rubric criteria out of 100 and `gradeFromRubric` computes the total; `GradeRecord.details` carries one mark per reference word, and **word marks never move the item score**.
|
|
20
|
+
- `alignReadAloud(data, assessment)` returns the same comparison as a list a review screen can render: every reference word with its state — correct, mispronounced or omitted — and every inserted word where it was spoken, each pointing back into `assessment.words` so syllables, phonemes and timings are one lookup away. `reference` and `heard` are normalised, because that is what was compared. Branch on `state`, never on `heard === ''`: an inserted word whose text normalises to nothing reads empty too.
|
|
21
|
+
- `inspectWav(bytes, { silenceDbfs, frameMs })` measures a 16-bit PCM WAV's duration, sample rate, channels, peak level and voiced time without a decoding library, and refuses what it cannot read as `not_wav`, `unsupported_encoding` or `truncated`. Both policy fields are required, because neither has an answer that is right for every microphone. Voiced time is counted in windows and never exceeds the duration, which is what `gradeReadAloud` requires of a measurement.
|
|
22
|
+
- Additive elsewhere: `GradeRecord.details`, a machine-readable `code` on an `ItemOutcome`'s unscorable arm, written by the new `outcomeFromUnscorable`; a `rounding` option on `gradeFromRubric`, so a pass line can be compared the way a score is displayed, with the score itself left unrounded; and recording and assessment `InteractionKind` literals. `GraderKind`'s three values are now documented: `'auto'` is a non-generative measurement engine, `'ai'` a generative model, `'human'` a person.
|
|
23
|
+
- `@intellectif/lk-core/scoring` now names its own functions' types. Every argument, return value and nested shape a public signature on that subpath mentions is re-exported from it — twenty type names, including `GradeRecord`, `ItemOutcome`, `ReadAloudData`, `SpeechAssessment`, `SpeechWord` and `WavInspection`. A function whose arguments cannot be named is one that has to be called from `any`, which is how evidence stops being checked. Type-only: the bundle is unchanged.
|
|
24
|
+
|
|
25
|
+
**Upgrading.**
|
|
26
|
+
|
|
27
|
+
- `read-aloud` is now a built-in. If you registered an activity type of your own under that name, `registerActivityType` will throw; rename yours before upgrading.
|
|
28
|
+
- **`RedactedScoringError`'s message has been reworded**, for every type it is thrown for and not only the new one. Its old remedy — "or use `evaluate()` which returns `{ status: "unscorable" }`" — is not true of a deferred type, which `evaluate()` answers `deferred` for, redacted or not. The class, its `name` and its `activityType` are unchanged and no grade moves; only the sentence does, so an assertion on the exact text needs updating.
|
|
29
|
+
- A `switch` that must be exhaustive over `ActivityType`, `InteractionKind` or the redacted activity union gains new members to handle.
|
|
30
|
+
- **The grade-stability corpus is written in encoding version 2.** `CORPUS_VERSION` is now `2`: a vector can carry the bytes of a recording, as `{ "$bytes": "<base64>" }`, which `inspectWav` needs. `replay()` throws rather than comparing a corpus written in another encoding, so if you replay `vectors/scoring.json` yourself, load the `replay.mjs` shipped beside it rather than a copy you pinned earlier. No expectation moved with the bump, and every grade a released version froze replays unchanged.
|
|
31
|
+
|
|
3
32
|
## 0.13.1
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @intellectif/lk-core
|
|
|
14
14
|
|
|
15
15
|
## What's in the box
|
|
16
16
|
|
|
17
|
-
- **Activity schemas** for `multiple-choice`, `fill-in-the-blanks`, `written-response`, `gap-select` and `
|
|
17
|
+
- **Activity schemas** for `multiple-choice`, `fill-in-the-blanks`, `written-response`, `gap-select`, `dictation` and `read-aloud`, with semantic refinements (e.g. *at least one correct option*, *single-select ⇒ exactly one correct*, *passage ↔ blank-id bijection*, *image/embed require `alt`*, *a dictation title never contains its whole transcript as words*, *a read-aloud's text leaves at least one word once punctuation is folded away*). Loose at every level, so your sidecar fields survive validation.
|
|
18
18
|
- **`validateActivity(type, data)`** — the authoritative runtime validator. Returns a typed `{ success, data }` or a structured `{ success: false, errors[] }`, and **throws `UnknownActivityTypeError` if `type` is not registered** — so guard it when validating a content bank that may carry types this build does not know. `validateItemGroup(data)` is the equivalent for a `Stimulus` + `ItemGroup` container, which `validateActivity` cannot take.
|
|
19
19
|
- **`validateDraft(type, draft)`** — for editors. Reports `complete`, `incomplete` (something not written yet) or `invalid` (something wrong), each issue with a `severity` and a `code` — documented for every problem the checks recognise — and deliberately no `success` boolean to misread. Stricter than `validateActivity`, never looser. **`createDraft(type, { newId })`** returns an empty draft to start from; a multiple-choice draft marks no option correct.
|
|
20
20
|
- **An open type system** — `defineActivityType` / `registerActivityType` make an activity type a *value*, not a hard-coded union member: register one and `validateActivity`, `validateDraft`, `score`, `evaluate`, `redact` and `jsonSchemaFor` all work for it, with no SDK release. An `authoring` block on the descriptor gives it draft support.
|
|
@@ -77,13 +77,21 @@ declare function matchText(input: string, accepted: string | readonly string[],
|
|
|
77
77
|
* The SDK models the SHAPE and the arithmetic. It never calls a model, never
|
|
78
78
|
* holds a key, and never decides what a rubric means — that stays yours.
|
|
79
79
|
*/
|
|
80
|
+
|
|
80
81
|
/**
|
|
81
82
|
* Lifecycle of a deferred grade. A grade exists only in the `graded` state;
|
|
82
83
|
* every other state means "no grade, and here is why" — which is precisely the
|
|
83
84
|
* distinction that stops an ungraded submission being rendered as a zero.
|
|
84
85
|
*/
|
|
85
86
|
type GradingState = 'queued' | 'running' | 'graded' | 'failed' | 'skipped';
|
|
86
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* Who produced a grade.
|
|
89
|
+
*
|
|
90
|
+
* - `'auto'` — a non-generative measurement engine, for example a
|
|
91
|
+
* pronunciation-assessment service.
|
|
92
|
+
* - `'ai'` — a generative model.
|
|
93
|
+
* - `'human'` — a person.
|
|
94
|
+
*/
|
|
87
95
|
type GraderKind = 'ai' | 'human' | 'auto';
|
|
88
96
|
/** Provenance of a grade, so a re-grade two years later is explicable. */
|
|
89
97
|
interface Grader {
|
|
@@ -166,6 +174,12 @@ interface GradeRecord {
|
|
|
166
174
|
feedback: string | null;
|
|
167
175
|
/** Per-criterion breakdown, when the grader worked against a rubric. */
|
|
168
176
|
criteria?: CriterionScore[];
|
|
177
|
+
/**
|
|
178
|
+
* Per-item marks carried by a grade — for example the per-word marks of a
|
|
179
|
+
* read-aloud grade. `outcomeFromGrade` does not mirror them onto the
|
|
180
|
+
* outcome; read `outcome.grade.details`.
|
|
181
|
+
*/
|
|
182
|
+
details?: ScoringDetail[];
|
|
169
183
|
/** Corrections anchored in the learner's text. */
|
|
170
184
|
corrections?: InlineCorrection[];
|
|
171
185
|
/** Supporting observations the grader cited. */
|
|
@@ -361,6 +375,7 @@ interface ActivityDataMap {
|
|
|
361
375
|
'written-response': WrittenResponseData;
|
|
362
376
|
'gap-select': GapSelectData;
|
|
363
377
|
dictation: DictationData;
|
|
378
|
+
'read-aloud': ReadAloudData;
|
|
364
379
|
}
|
|
365
380
|
/**
|
|
366
381
|
* The set of activity types supported by learning-kit. Derived from
|
|
@@ -885,6 +900,96 @@ interface DictationData {
|
|
|
885
900
|
/** Subjective difficulty on a 1–5 scale. */
|
|
886
901
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
887
902
|
}
|
|
903
|
+
/** A dimension of speech a pronunciation assessor scores, on a 0–100 scale. */
|
|
904
|
+
type ReadAloudDimension = 'accuracy' | 'fluency' | 'completeness' | 'prosody';
|
|
905
|
+
/** One assessor dimension counted towards a read-aloud grade, and its weight. */
|
|
906
|
+
interface ReadAloudDimensionWeight {
|
|
907
|
+
name: ReadAloudDimension;
|
|
908
|
+
/**
|
|
909
|
+
* Relative weight, 0..1000 (`READ_ALOUD_MAX_DIMENSION_WEIGHT`). Weights need
|
|
910
|
+
* not add up to anything; a weight of 0 leaves the dimension out of the grade.
|
|
911
|
+
*/
|
|
912
|
+
weight: number;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* The limits on a read-aloud take, applied where the learner records. No grade
|
|
916
|
+
* reads them: whether a take is plausible speech is decided from the server's
|
|
917
|
+
* own measurement of the recording, never from a bound the client enforced.
|
|
918
|
+
*/
|
|
919
|
+
interface RecordingBounds {
|
|
920
|
+
/** The longest take, in seconds: above 0, and at most `READ_ALOUD_MAX_SECONDS` (300). */
|
|
921
|
+
maxSeconds: number;
|
|
922
|
+
/** The shortest take, in seconds: at least 0, and below `maxSeconds`. */
|
|
923
|
+
minSeconds?: number;
|
|
924
|
+
/** How many takes the learner may record: a whole number from 1 to `READ_ALOUD_MAX_TAKES` (20). */
|
|
925
|
+
maxTakes?: number;
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* A second, slower model recording of the reference text — a separate file,
|
|
929
|
+
* not a `playbackRate` change. It carries no `captionsUrl` and no `playback`
|
|
930
|
+
* policy of its own, requires `media`, must be a different file from it, and
|
|
931
|
+
* cannot accompany a play limit on `media`.
|
|
932
|
+
*/
|
|
933
|
+
interface ReadAloudSlowMedia {
|
|
934
|
+
type: 'audio';
|
|
935
|
+
/** Source URL, under the same policy as {@link ActivityMedia.url}. */
|
|
936
|
+
url: string;
|
|
937
|
+
/** Accessible label — a description ("Model recording, slow"). */
|
|
938
|
+
alt?: string;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Data contract for a Read Aloud activity: the learner reads a text aloud, an
|
|
942
|
+
* assessor measures the recording, and the grade is the weighted total of the
|
|
943
|
+
* assessor's dimension scores.
|
|
944
|
+
*
|
|
945
|
+
* Grading is deferred — `evaluate()` returns `deferred` until the application
|
|
946
|
+
* holds an assessment — and nothing here is an answer key: the learner is shown
|
|
947
|
+
* the text they are asked to read.
|
|
948
|
+
*/
|
|
949
|
+
interface ReadAloudData {
|
|
950
|
+
schemaVersion: '1.0';
|
|
951
|
+
type: 'read-aloud';
|
|
952
|
+
/** Unique identifier for this activity. */
|
|
953
|
+
id: string;
|
|
954
|
+
/** Human-readable title used in xAPI statements and error boundaries. */
|
|
955
|
+
title: string;
|
|
956
|
+
/** Optional instructions shown to the learner, as plain text. */
|
|
957
|
+
instructions?: string;
|
|
958
|
+
/**
|
|
959
|
+
* The text the learner reads aloud. Shown to the learner (public). At most
|
|
960
|
+
* `READ_ALOUD_MAX_REFERENCE_LENGTH` code points before and after
|
|
961
|
+
* normalisation, in a script written with spaces between words.
|
|
962
|
+
*/
|
|
963
|
+
referenceText: string;
|
|
964
|
+
/**
|
|
965
|
+
* BCP 47 tag in canonical form with a region (e.g. `en-US`). GRADE-DECIDING:
|
|
966
|
+
* an assessment made for another locale is unscorable.
|
|
967
|
+
*/
|
|
968
|
+
locale: string;
|
|
969
|
+
/** A model recording of the text. Audio only; a playback policy is allowed. */
|
|
970
|
+
media?: ActivityMedia;
|
|
971
|
+
/** A second, slower model recording. See {@link ReadAloudSlowMedia}. */
|
|
972
|
+
slowMedia?: ReadAloudSlowMedia;
|
|
973
|
+
/** The limits on a take. See {@link RecordingBounds}. */
|
|
974
|
+
recording: RecordingBounds;
|
|
975
|
+
/**
|
|
976
|
+
* The assessor dimensions the grade is made of, with their weights: 1 to 4
|
|
977
|
+
* entries, each name at most once, at least one weight above 0. A weighted
|
|
978
|
+
* dimension the assessment has no score for makes the take unscorable, never
|
|
979
|
+
* a zero. Public.
|
|
980
|
+
*/
|
|
981
|
+
scoring: {
|
|
982
|
+
dimensions: ReadAloudDimensionWeight[];
|
|
983
|
+
};
|
|
984
|
+
/** Minimum scaled score [0–1] required to pass once graded. Defaults to {@link DEFAULT_PASS_THRESHOLD} (0.7) when absent. */
|
|
985
|
+
passThreshold?: number;
|
|
986
|
+
/** Optional authored overall feedback, selected once the grade exists. */
|
|
987
|
+
feedback?: ActivityFeedback;
|
|
988
|
+
/** IRI references to learning objectives addressed by this activity. */
|
|
989
|
+
learningObjectives?: string[];
|
|
990
|
+
/** Subjective difficulty on a 1–5 scale. */
|
|
991
|
+
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
992
|
+
}
|
|
888
993
|
/**
|
|
889
994
|
* Maps each ActivityType string to its learner-response shape. Open for
|
|
890
995
|
* extension via module augmentation, mirroring {@link ActivityDataMap}.
|
|
@@ -895,6 +1000,7 @@ interface LearnerResponseMap {
|
|
|
895
1000
|
'written-response': WrittenResponseLearnerResponse;
|
|
896
1001
|
'gap-select': GapSelectLearnerResponse;
|
|
897
1002
|
dictation: DictationLearnerResponse;
|
|
1003
|
+
'read-aloud': ReadAloudLearnerResponse;
|
|
898
1004
|
}
|
|
899
1005
|
/** Union of all learner response shapes. */
|
|
900
1006
|
type LearnerResponse = LearnerResponseMap[keyof LearnerResponseMap];
|
|
@@ -947,6 +1053,28 @@ interface DictationLearnerResponse {
|
|
|
947
1053
|
/** Hint words revealed before submitting (practice only). Absent or 0 means none. */
|
|
948
1054
|
hintsRevealed?: number;
|
|
949
1055
|
}
|
|
1056
|
+
/**
|
|
1057
|
+
* A learner recording held by the application. `key` is opaque,
|
|
1058
|
+
* application-issued storage identity: never a URL or bytes. `durationMs` is a
|
|
1059
|
+
* client claim no grade reads.
|
|
1060
|
+
*/
|
|
1061
|
+
interface RecordingRef {
|
|
1062
|
+
key: string;
|
|
1063
|
+
/** The media type the recording was stored as, e.g. `audio/wav`. */
|
|
1064
|
+
mimeType: string;
|
|
1065
|
+
durationMs?: number;
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Learner response for a Read Aloud activity: a reference to the recording the
|
|
1069
|
+
* application stored, never the audio itself.
|
|
1070
|
+
*/
|
|
1071
|
+
interface ReadAloudLearnerResponse {
|
|
1072
|
+
type: 'read-aloud';
|
|
1073
|
+
/** `null`: the learner submitted without recording (a blank). A take that failed to upload is never `null`. */
|
|
1074
|
+
recording: RecordingRef | null;
|
|
1075
|
+
/** Telemetry: takes used. No grade reads it. */
|
|
1076
|
+
takes?: number;
|
|
1077
|
+
}
|
|
950
1078
|
/**
|
|
951
1079
|
* Fine-grained outcome of the learner's action on a single item, replacing the
|
|
952
1080
|
* ambiguous {@link ScoringDetail.correct}:
|
|
@@ -989,7 +1117,9 @@ interface ScoringDetail {
|
|
|
989
1117
|
* The item's own scaled score in [0, 1], for a type that grades its items on
|
|
990
1118
|
* a continuum rather than right or wrong. Written by the dictation scorer
|
|
991
1119
|
* (the similarity of each transcript word to what was typed for it) and by
|
|
992
|
-
*
|
|
1120
|
+
* `gradeReadAloud` (the assessor's accuracy for each reference word as a
|
|
1121
|
+
* fraction, 0 for an omitted word, and absent where the assessor gave none).
|
|
1122
|
+
* Absent, an item is right or wrong: read `outcome`.
|
|
993
1123
|
*/
|
|
994
1124
|
score?: number;
|
|
995
1125
|
}
|
|
@@ -1082,6 +1212,11 @@ type ItemOutcome = {
|
|
|
1082
1212
|
reason: string;
|
|
1083
1213
|
/** Maximum possible scaled score, when known. */
|
|
1084
1214
|
maxScore: number;
|
|
1215
|
+
/**
|
|
1216
|
+
* A machine-readable reason, written by `outcomeFromUnscorable` — for
|
|
1217
|
+
* example a read-aloud `SpeechUnscorableCode`. `evaluate` never writes it.
|
|
1218
|
+
*/
|
|
1219
|
+
code?: string;
|
|
1085
1220
|
};
|
|
1086
1221
|
/** A single validation error produced by `validateActivity`. */
|
|
1087
1222
|
interface ValidationError {
|
|
@@ -1134,7 +1269,21 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1134
1269
|
/** A charged play produced no audio — a failed or expired media URL. */
|
|
1135
1270
|
| 'media-play-errored'
|
|
1136
1271
|
/** A charged play was returned, because the consumer accepted the refund. */
|
|
1137
|
-
| 'media-play-refunded'
|
|
1272
|
+
| 'media-play-refunded'
|
|
1273
|
+
/** The microphone began capturing a take. */
|
|
1274
|
+
| 'recording-started'
|
|
1275
|
+
/** A take ended, by the learner or at its time limit. */
|
|
1276
|
+
| 'recording-stopped'
|
|
1277
|
+
/** A take was thrown away, to record another. */
|
|
1278
|
+
| 'recording-discarded'
|
|
1279
|
+
/** The application stored a take and returned its reference. */
|
|
1280
|
+
| 'recording-uploaded'
|
|
1281
|
+
/** Storing a take failed. A take that failed to upload is never a blank answer. */
|
|
1282
|
+
| 'recording-upload-failed'
|
|
1283
|
+
/** A stored take was sent for assessment. */
|
|
1284
|
+
| 'assessment-requested'
|
|
1285
|
+
/** An assessment request failed: the take has no grade. */
|
|
1286
|
+
| 'assessment-failed' | (string & {});
|
|
1138
1287
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1139
1288
|
interface InteractionEvent {
|
|
1140
1289
|
/** The kind of interaction that occurred. */
|
|
@@ -1147,4 +1296,4 @@ interface InteractionEvent {
|
|
|
1147
1296
|
payload: Record<string, unknown>;
|
|
1148
1297
|
}
|
|
1149
1298
|
|
|
1150
|
-
export { type
|
|
1299
|
+
export { type WrittenResponseData as $, type ActivityData as A, type BlankConfig as B, type CriterionScore as C, type DeferredReason as D, type MultipleChoiceLearnerResponse as E, type FillInTheBlanksData as F, type GapSelectBank as G, type MultipleChoiceOption as H, type InlineCorrection as I, type MultipleChoiceOptionMedia as J, type ReadAloudDimension as K, type LearnerResponse as L, type MediaPlaybackPolicy as M, type NativeControlHint as N, type ReadAloudDimensionWeight as O, type ReadAloudLearnerResponse as P, type ReadAloudSlowMedia as Q, type ReadAloudData as R, type RecordingBounds as S, type RecordingRef as T, type ScoringDetail as U, type ScoringOutcome as V, type ScoringResult as W, type TextMatchPolicy as X, type TextMatchResult as Y, type ValidationError as Z, type ValidationResult as _, type ActivityDataMap as a, type WrittenResponseLearnerResponse as a0, type WrittenResponseRubric as a1, type WrittenResponseRubricCriterion as a2, type XAPIActor as a3, type XAPIConfig as a4, type XAPIContext as a5, type XAPIContextActivities as a6, type XAPIError as a7, type XAPIObject as a8, type XAPIResult as a9, type XAPIScore as aa, type XAPIStatement as ab, type XAPIVerbObject as ac, levenshteinDistance as ad, matchText as ae, type ActivityFeedback as b, type ActivityMedia as c, type ActivityResult as d, type ActivityType as e, type DeferredScoringPartial as f, type DictationData as g, type DictationEquivalence as h, type DictationLearnerResponse as i, type DictationSlowMedia as j, type DictationTolerance as k, type FillInTheBlanksLearnerResponse as l, type GapSelectChoice as m, type GapSelectData as n, type GapSelectGap as o, type GapSelectLearnerResponse as p, type GradeRecord as q, type Grader as r, type GraderKind as s, type GraderUsage as t, type GradingState as u, type InteractionEvent as v, type InteractionKind as w, type ItemOutcome as x, type LearnerResponseMap as y, type MultipleChoiceData as z };
|
|
@@ -77,13 +77,21 @@ declare function matchText(input: string, accepted: string | readonly string[],
|
|
|
77
77
|
* The SDK models the SHAPE and the arithmetic. It never calls a model, never
|
|
78
78
|
* holds a key, and never decides what a rubric means — that stays yours.
|
|
79
79
|
*/
|
|
80
|
+
|
|
80
81
|
/**
|
|
81
82
|
* Lifecycle of a deferred grade. A grade exists only in the `graded` state;
|
|
82
83
|
* every other state means "no grade, and here is why" — which is precisely the
|
|
83
84
|
* distinction that stops an ungraded submission being rendered as a zero.
|
|
84
85
|
*/
|
|
85
86
|
type GradingState = 'queued' | 'running' | 'graded' | 'failed' | 'skipped';
|
|
86
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* Who produced a grade.
|
|
89
|
+
*
|
|
90
|
+
* - `'auto'` — a non-generative measurement engine, for example a
|
|
91
|
+
* pronunciation-assessment service.
|
|
92
|
+
* - `'ai'` — a generative model.
|
|
93
|
+
* - `'human'` — a person.
|
|
94
|
+
*/
|
|
87
95
|
type GraderKind = 'ai' | 'human' | 'auto';
|
|
88
96
|
/** Provenance of a grade, so a re-grade two years later is explicable. */
|
|
89
97
|
interface Grader {
|
|
@@ -166,6 +174,12 @@ interface GradeRecord {
|
|
|
166
174
|
feedback: string | null;
|
|
167
175
|
/** Per-criterion breakdown, when the grader worked against a rubric. */
|
|
168
176
|
criteria?: CriterionScore[];
|
|
177
|
+
/**
|
|
178
|
+
* Per-item marks carried by a grade — for example the per-word marks of a
|
|
179
|
+
* read-aloud grade. `outcomeFromGrade` does not mirror them onto the
|
|
180
|
+
* outcome; read `outcome.grade.details`.
|
|
181
|
+
*/
|
|
182
|
+
details?: ScoringDetail[];
|
|
169
183
|
/** Corrections anchored in the learner's text. */
|
|
170
184
|
corrections?: InlineCorrection[];
|
|
171
185
|
/** Supporting observations the grader cited. */
|
|
@@ -361,6 +375,7 @@ interface ActivityDataMap {
|
|
|
361
375
|
'written-response': WrittenResponseData;
|
|
362
376
|
'gap-select': GapSelectData;
|
|
363
377
|
dictation: DictationData;
|
|
378
|
+
'read-aloud': ReadAloudData;
|
|
364
379
|
}
|
|
365
380
|
/**
|
|
366
381
|
* The set of activity types supported by learning-kit. Derived from
|
|
@@ -885,6 +900,96 @@ interface DictationData {
|
|
|
885
900
|
/** Subjective difficulty on a 1–5 scale. */
|
|
886
901
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
887
902
|
}
|
|
903
|
+
/** A dimension of speech a pronunciation assessor scores, on a 0–100 scale. */
|
|
904
|
+
type ReadAloudDimension = 'accuracy' | 'fluency' | 'completeness' | 'prosody';
|
|
905
|
+
/** One assessor dimension counted towards a read-aloud grade, and its weight. */
|
|
906
|
+
interface ReadAloudDimensionWeight {
|
|
907
|
+
name: ReadAloudDimension;
|
|
908
|
+
/**
|
|
909
|
+
* Relative weight, 0..1000 (`READ_ALOUD_MAX_DIMENSION_WEIGHT`). Weights need
|
|
910
|
+
* not add up to anything; a weight of 0 leaves the dimension out of the grade.
|
|
911
|
+
*/
|
|
912
|
+
weight: number;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* The limits on a read-aloud take, applied where the learner records. No grade
|
|
916
|
+
* reads them: whether a take is plausible speech is decided from the server's
|
|
917
|
+
* own measurement of the recording, never from a bound the client enforced.
|
|
918
|
+
*/
|
|
919
|
+
interface RecordingBounds {
|
|
920
|
+
/** The longest take, in seconds: above 0, and at most `READ_ALOUD_MAX_SECONDS` (300). */
|
|
921
|
+
maxSeconds: number;
|
|
922
|
+
/** The shortest take, in seconds: at least 0, and below `maxSeconds`. */
|
|
923
|
+
minSeconds?: number;
|
|
924
|
+
/** How many takes the learner may record: a whole number from 1 to `READ_ALOUD_MAX_TAKES` (20). */
|
|
925
|
+
maxTakes?: number;
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* A second, slower model recording of the reference text — a separate file,
|
|
929
|
+
* not a `playbackRate` change. It carries no `captionsUrl` and no `playback`
|
|
930
|
+
* policy of its own, requires `media`, must be a different file from it, and
|
|
931
|
+
* cannot accompany a play limit on `media`.
|
|
932
|
+
*/
|
|
933
|
+
interface ReadAloudSlowMedia {
|
|
934
|
+
type: 'audio';
|
|
935
|
+
/** Source URL, under the same policy as {@link ActivityMedia.url}. */
|
|
936
|
+
url: string;
|
|
937
|
+
/** Accessible label — a description ("Model recording, slow"). */
|
|
938
|
+
alt?: string;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Data contract for a Read Aloud activity: the learner reads a text aloud, an
|
|
942
|
+
* assessor measures the recording, and the grade is the weighted total of the
|
|
943
|
+
* assessor's dimension scores.
|
|
944
|
+
*
|
|
945
|
+
* Grading is deferred — `evaluate()` returns `deferred` until the application
|
|
946
|
+
* holds an assessment — and nothing here is an answer key: the learner is shown
|
|
947
|
+
* the text they are asked to read.
|
|
948
|
+
*/
|
|
949
|
+
interface ReadAloudData {
|
|
950
|
+
schemaVersion: '1.0';
|
|
951
|
+
type: 'read-aloud';
|
|
952
|
+
/** Unique identifier for this activity. */
|
|
953
|
+
id: string;
|
|
954
|
+
/** Human-readable title used in xAPI statements and error boundaries. */
|
|
955
|
+
title: string;
|
|
956
|
+
/** Optional instructions shown to the learner, as plain text. */
|
|
957
|
+
instructions?: string;
|
|
958
|
+
/**
|
|
959
|
+
* The text the learner reads aloud. Shown to the learner (public). At most
|
|
960
|
+
* `READ_ALOUD_MAX_REFERENCE_LENGTH` code points before and after
|
|
961
|
+
* normalisation, in a script written with spaces between words.
|
|
962
|
+
*/
|
|
963
|
+
referenceText: string;
|
|
964
|
+
/**
|
|
965
|
+
* BCP 47 tag in canonical form with a region (e.g. `en-US`). GRADE-DECIDING:
|
|
966
|
+
* an assessment made for another locale is unscorable.
|
|
967
|
+
*/
|
|
968
|
+
locale: string;
|
|
969
|
+
/** A model recording of the text. Audio only; a playback policy is allowed. */
|
|
970
|
+
media?: ActivityMedia;
|
|
971
|
+
/** A second, slower model recording. See {@link ReadAloudSlowMedia}. */
|
|
972
|
+
slowMedia?: ReadAloudSlowMedia;
|
|
973
|
+
/** The limits on a take. See {@link RecordingBounds}. */
|
|
974
|
+
recording: RecordingBounds;
|
|
975
|
+
/**
|
|
976
|
+
* The assessor dimensions the grade is made of, with their weights: 1 to 4
|
|
977
|
+
* entries, each name at most once, at least one weight above 0. A weighted
|
|
978
|
+
* dimension the assessment has no score for makes the take unscorable, never
|
|
979
|
+
* a zero. Public.
|
|
980
|
+
*/
|
|
981
|
+
scoring: {
|
|
982
|
+
dimensions: ReadAloudDimensionWeight[];
|
|
983
|
+
};
|
|
984
|
+
/** Minimum scaled score [0–1] required to pass once graded. Defaults to {@link DEFAULT_PASS_THRESHOLD} (0.7) when absent. */
|
|
985
|
+
passThreshold?: number;
|
|
986
|
+
/** Optional authored overall feedback, selected once the grade exists. */
|
|
987
|
+
feedback?: ActivityFeedback;
|
|
988
|
+
/** IRI references to learning objectives addressed by this activity. */
|
|
989
|
+
learningObjectives?: string[];
|
|
990
|
+
/** Subjective difficulty on a 1–5 scale. */
|
|
991
|
+
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
992
|
+
}
|
|
888
993
|
/**
|
|
889
994
|
* Maps each ActivityType string to its learner-response shape. Open for
|
|
890
995
|
* extension via module augmentation, mirroring {@link ActivityDataMap}.
|
|
@@ -895,6 +1000,7 @@ interface LearnerResponseMap {
|
|
|
895
1000
|
'written-response': WrittenResponseLearnerResponse;
|
|
896
1001
|
'gap-select': GapSelectLearnerResponse;
|
|
897
1002
|
dictation: DictationLearnerResponse;
|
|
1003
|
+
'read-aloud': ReadAloudLearnerResponse;
|
|
898
1004
|
}
|
|
899
1005
|
/** Union of all learner response shapes. */
|
|
900
1006
|
type LearnerResponse = LearnerResponseMap[keyof LearnerResponseMap];
|
|
@@ -947,6 +1053,28 @@ interface DictationLearnerResponse {
|
|
|
947
1053
|
/** Hint words revealed before submitting (practice only). Absent or 0 means none. */
|
|
948
1054
|
hintsRevealed?: number;
|
|
949
1055
|
}
|
|
1056
|
+
/**
|
|
1057
|
+
* A learner recording held by the application. `key` is opaque,
|
|
1058
|
+
* application-issued storage identity: never a URL or bytes. `durationMs` is a
|
|
1059
|
+
* client claim no grade reads.
|
|
1060
|
+
*/
|
|
1061
|
+
interface RecordingRef {
|
|
1062
|
+
key: string;
|
|
1063
|
+
/** The media type the recording was stored as, e.g. `audio/wav`. */
|
|
1064
|
+
mimeType: string;
|
|
1065
|
+
durationMs?: number;
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Learner response for a Read Aloud activity: a reference to the recording the
|
|
1069
|
+
* application stored, never the audio itself.
|
|
1070
|
+
*/
|
|
1071
|
+
interface ReadAloudLearnerResponse {
|
|
1072
|
+
type: 'read-aloud';
|
|
1073
|
+
/** `null`: the learner submitted without recording (a blank). A take that failed to upload is never `null`. */
|
|
1074
|
+
recording: RecordingRef | null;
|
|
1075
|
+
/** Telemetry: takes used. No grade reads it. */
|
|
1076
|
+
takes?: number;
|
|
1077
|
+
}
|
|
950
1078
|
/**
|
|
951
1079
|
* Fine-grained outcome of the learner's action on a single item, replacing the
|
|
952
1080
|
* ambiguous {@link ScoringDetail.correct}:
|
|
@@ -989,7 +1117,9 @@ interface ScoringDetail {
|
|
|
989
1117
|
* The item's own scaled score in [0, 1], for a type that grades its items on
|
|
990
1118
|
* a continuum rather than right or wrong. Written by the dictation scorer
|
|
991
1119
|
* (the similarity of each transcript word to what was typed for it) and by
|
|
992
|
-
*
|
|
1120
|
+
* `gradeReadAloud` (the assessor's accuracy for each reference word as a
|
|
1121
|
+
* fraction, 0 for an omitted word, and absent where the assessor gave none).
|
|
1122
|
+
* Absent, an item is right or wrong: read `outcome`.
|
|
993
1123
|
*/
|
|
994
1124
|
score?: number;
|
|
995
1125
|
}
|
|
@@ -1082,6 +1212,11 @@ type ItemOutcome = {
|
|
|
1082
1212
|
reason: string;
|
|
1083
1213
|
/** Maximum possible scaled score, when known. */
|
|
1084
1214
|
maxScore: number;
|
|
1215
|
+
/**
|
|
1216
|
+
* A machine-readable reason, written by `outcomeFromUnscorable` — for
|
|
1217
|
+
* example a read-aloud `SpeechUnscorableCode`. `evaluate` never writes it.
|
|
1218
|
+
*/
|
|
1219
|
+
code?: string;
|
|
1085
1220
|
};
|
|
1086
1221
|
/** A single validation error produced by `validateActivity`. */
|
|
1087
1222
|
interface ValidationError {
|
|
@@ -1134,7 +1269,21 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1134
1269
|
/** A charged play produced no audio — a failed or expired media URL. */
|
|
1135
1270
|
| 'media-play-errored'
|
|
1136
1271
|
/** A charged play was returned, because the consumer accepted the refund. */
|
|
1137
|
-
| 'media-play-refunded'
|
|
1272
|
+
| 'media-play-refunded'
|
|
1273
|
+
/** The microphone began capturing a take. */
|
|
1274
|
+
| 'recording-started'
|
|
1275
|
+
/** A take ended, by the learner or at its time limit. */
|
|
1276
|
+
| 'recording-stopped'
|
|
1277
|
+
/** A take was thrown away, to record another. */
|
|
1278
|
+
| 'recording-discarded'
|
|
1279
|
+
/** The application stored a take and returned its reference. */
|
|
1280
|
+
| 'recording-uploaded'
|
|
1281
|
+
/** Storing a take failed. A take that failed to upload is never a blank answer. */
|
|
1282
|
+
| 'recording-upload-failed'
|
|
1283
|
+
/** A stored take was sent for assessment. */
|
|
1284
|
+
| 'assessment-requested'
|
|
1285
|
+
/** An assessment request failed: the take has no grade. */
|
|
1286
|
+
| 'assessment-failed' | (string & {});
|
|
1138
1287
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1139
1288
|
interface InteractionEvent {
|
|
1140
1289
|
/** The kind of interaction that occurred. */
|
|
@@ -1147,4 +1296,4 @@ interface InteractionEvent {
|
|
|
1147
1296
|
payload: Record<string, unknown>;
|
|
1148
1297
|
}
|
|
1149
1298
|
|
|
1150
|
-
export { type
|
|
1299
|
+
export { type WrittenResponseData as $, type ActivityData as A, type BlankConfig as B, type CriterionScore as C, type DeferredReason as D, type MultipleChoiceLearnerResponse as E, type FillInTheBlanksData as F, type GapSelectBank as G, type MultipleChoiceOption as H, type InlineCorrection as I, type MultipleChoiceOptionMedia as J, type ReadAloudDimension as K, type LearnerResponse as L, type MediaPlaybackPolicy as M, type NativeControlHint as N, type ReadAloudDimensionWeight as O, type ReadAloudLearnerResponse as P, type ReadAloudSlowMedia as Q, type ReadAloudData as R, type RecordingBounds as S, type RecordingRef as T, type ScoringDetail as U, type ScoringOutcome as V, type ScoringResult as W, type TextMatchPolicy as X, type TextMatchResult as Y, type ValidationError as Z, type ValidationResult as _, type ActivityDataMap as a, type WrittenResponseLearnerResponse as a0, type WrittenResponseRubric as a1, type WrittenResponseRubricCriterion as a2, type XAPIActor as a3, type XAPIConfig as a4, type XAPIContext as a5, type XAPIContextActivities as a6, type XAPIError as a7, type XAPIObject as a8, type XAPIResult as a9, type XAPIScore as aa, type XAPIStatement as ab, type XAPIVerbObject as ac, levenshteinDistance as ad, matchText as ae, type ActivityFeedback as b, type ActivityMedia as c, type ActivityResult as d, type ActivityType as e, type DeferredScoringPartial as f, type DictationData as g, type DictationEquivalence as h, type DictationLearnerResponse as i, type DictationSlowMedia as j, type DictationTolerance as k, type FillInTheBlanksLearnerResponse as l, type GapSelectChoice as m, type GapSelectData as n, type GapSelectGap as o, type GapSelectLearnerResponse as p, type GradeRecord as q, type Grader as r, type GraderKind as s, type GraderUsage as t, type GradingState as u, type InteractionEvent as v, type InteractionKind as w, type ItemOutcome as x, type LearnerResponseMap as y, type MultipleChoiceData as z };
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
var _chunkVCXIPLEWcjs = require('./chunk-VCXIPLEW.cjs');
|
|
14
15
|
|
|
15
16
|
// src/schemas/item-group.ts
|
|
16
17
|
var _v4 = require('zod/v4');
|
|
@@ -38,7 +39,7 @@ var StimulusSchema = _v4.z.looseObject({
|
|
|
38
39
|
title: _v4.z.string().optional(),
|
|
39
40
|
body: _v4.z.string().optional(),
|
|
40
41
|
bodyHtml: _v4.z.string().optional(),
|
|
41
|
-
media:
|
|
42
|
+
media: _chunkVCXIPLEWcjs.MediaSchema.optional(),
|
|
42
43
|
transcript: _v4.z.string().optional(),
|
|
43
44
|
locale: _v4.z.string().optional(),
|
|
44
45
|
attribution: _v4.z.string().optional()
|
|
@@ -88,7 +89,7 @@ var RedactedStimulusSchema = _v4.z.strictObject({
|
|
|
88
89
|
title: _v4.z.string().optional(),
|
|
89
90
|
body: _v4.z.string().optional(),
|
|
90
91
|
bodyHtml: _v4.z.string().optional(),
|
|
91
|
-
media:
|
|
92
|
+
media: _chunkVCXIPLEWcjs.RedactedMediaSchema.optional(),
|
|
92
93
|
locale: _v4.z.string().optional(),
|
|
93
94
|
attribution: _v4.z.string().optional()
|
|
94
95
|
});
|
|
@@ -103,11 +104,11 @@ var RedactedItemGroupSchema = _v4.z.strictObject({
|
|
|
103
104
|
items: _v4.z.array(_v4.z.unknown()).min(1),
|
|
104
105
|
shuffle: _v4.z.enum(["none", "within-group"]).optional()
|
|
105
106
|
}).check((ctx) => {
|
|
106
|
-
if (
|
|
107
|
+
if (_chunkVCXIPLEWcjs.groupCaptionsRevealDictation.call(void 0, ctx.value)) {
|
|
107
108
|
ctx.issues.push({
|
|
108
109
|
code: "custom",
|
|
109
110
|
input: _optionalChain([ctx, 'access', _ => _.value, 'access', _2 => _2.stimulus, 'access', _3 => _3.media, 'optionalAccess', _4 => _4.captionsUrl]),
|
|
110
|
-
message:
|
|
111
|
+
message: _chunkVCXIPLEWcjs.GROUP_CAPTIONS_REVEAL_DICTATION,
|
|
111
112
|
path: ["stimulus", "media", "captionsUrl"]
|
|
112
113
|
});
|
|
113
114
|
}
|
|
@@ -127,7 +128,7 @@ function validateItemGroup(data) {
|
|
|
127
128
|
const errors = [];
|
|
128
129
|
const items = [];
|
|
129
130
|
container.data.items.forEach((item, index) => {
|
|
130
|
-
const descriptor =
|
|
131
|
+
const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, item.type);
|
|
131
132
|
if (descriptor === void 0) {
|
|
132
133
|
errors.push({
|
|
133
134
|
path: ["items", String(index), "type"],
|
|
@@ -143,10 +144,10 @@ function validateItemGroup(data) {
|
|
|
143
144
|
}
|
|
144
145
|
items.push(parsed.data);
|
|
145
146
|
});
|
|
146
|
-
if (
|
|
147
|
+
if (_chunkVCXIPLEWcjs.groupCaptionsRevealDictation.call(void 0, container.data)) {
|
|
147
148
|
errors.push({
|
|
148
149
|
path: ["stimulus", "media", "captionsUrl"],
|
|
149
|
-
message:
|
|
150
|
+
message: _chunkVCXIPLEWcjs.GROUP_CAPTIONS_REVEAL_DICTATION,
|
|
150
151
|
code: "custom"
|
|
151
152
|
});
|
|
152
153
|
}
|
|
@@ -160,34 +161,37 @@ function validateItemGroup(data) {
|
|
|
160
161
|
|
|
161
162
|
var stimulusJsonSchema = _v4.z.toJSONSchema(StimulusSchema, { target: "draft-7" });
|
|
162
163
|
var itemGroupJsonSchema = _v4.z.toJSONSchema(ItemGroupSchema, { target: "draft-7" });
|
|
163
|
-
var gapSelectJsonSchema = _v4.z.toJSONSchema(
|
|
164
|
+
var gapSelectJsonSchema = _v4.z.toJSONSchema(_chunkVCXIPLEWcjs.GapSelectDataSchema, {
|
|
165
|
+
target: "draft-7"
|
|
166
|
+
});
|
|
167
|
+
var dictationJsonSchema = _v4.z.toJSONSchema(_chunkVCXIPLEWcjs.DictationDataSchema, {
|
|
164
168
|
target: "draft-7"
|
|
165
169
|
});
|
|
166
|
-
var
|
|
170
|
+
var readAloudJsonSchema = _v4.z.toJSONSchema(_chunkVCXIPLEWcjs.ReadAloudDataSchema, {
|
|
167
171
|
target: "draft-7"
|
|
168
172
|
});
|
|
169
|
-
var multipleChoiceJsonSchema = _v4.z.toJSONSchema(
|
|
173
|
+
var multipleChoiceJsonSchema = _v4.z.toJSONSchema(_chunkVCXIPLEWcjs.MultipleChoiceDataSchema, {
|
|
170
174
|
target: "draft-7"
|
|
171
175
|
});
|
|
172
|
-
var fillInTheBlanksJsonSchema = _v4.z.toJSONSchema(
|
|
176
|
+
var fillInTheBlanksJsonSchema = _v4.z.toJSONSchema(_chunkVCXIPLEWcjs.FillInTheBlanksDataSchema, {
|
|
173
177
|
target: "draft-7"
|
|
174
178
|
});
|
|
175
|
-
var writtenResponseJsonSchema = _v4.z.toJSONSchema(
|
|
179
|
+
var writtenResponseJsonSchema = _v4.z.toJSONSchema(_chunkVCXIPLEWcjs.WrittenResponseDataSchema, {
|
|
176
180
|
target: "draft-7"
|
|
177
181
|
});
|
|
178
182
|
function jsonSchemaFor(type) {
|
|
179
|
-
const descriptor =
|
|
183
|
+
const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, type);
|
|
180
184
|
if (descriptor === void 0) {
|
|
181
|
-
throw new (0,
|
|
185
|
+
throw new (0, _chunkVCXIPLEWcjs.UnknownActivityTypeError)(type);
|
|
182
186
|
}
|
|
183
187
|
return _v4.z.toJSONSchema(descriptor.schema, { target: "draft-7" });
|
|
184
188
|
}
|
|
185
189
|
|
|
186
190
|
// src/schemas/index.ts
|
|
187
191
|
function validateActivity(type, data) {
|
|
188
|
-
const descriptor =
|
|
192
|
+
const descriptor = _chunkVCXIPLEWcjs.getActivityTypeDescriptor.call(void 0, type);
|
|
189
193
|
if (descriptor === void 0) {
|
|
190
|
-
throw new (0,
|
|
194
|
+
throw new (0, _chunkVCXIPLEWcjs.UnknownActivityTypeError)(String(type));
|
|
191
195
|
}
|
|
192
196
|
const result = descriptor.schema.safeParse(data);
|
|
193
197
|
if (result.success) {
|
|
@@ -218,5 +222,6 @@ function validateActivity(type, data) {
|
|
|
218
222
|
|
|
219
223
|
|
|
220
224
|
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
|
|
226
|
+
exports.StimulusSchema = StimulusSchema; exports.ItemGroupSchema = ItemGroupSchema; exports.RedactedStimulusSchema = RedactedStimulusSchema; exports.RedactedItemGroupSchema = RedactedItemGroupSchema; exports.validateItemGroup = validateItemGroup; exports.stimulusJsonSchema = stimulusJsonSchema; exports.itemGroupJsonSchema = itemGroupJsonSchema; exports.gapSelectJsonSchema = gapSelectJsonSchema; exports.dictationJsonSchema = dictationJsonSchema; exports.readAloudJsonSchema = readAloudJsonSchema; exports.multipleChoiceJsonSchema = multipleChoiceJsonSchema; exports.fillInTheBlanksJsonSchema = fillInTheBlanksJsonSchema; exports.writtenResponseJsonSchema = writtenResponseJsonSchema; exports.jsonSchemaFor = jsonSchemaFor; exports.validateActivity = validateActivity;
|
|
227
|
+
//# sourceMappingURL=chunk-2NIALQEH.cjs.map
|