@intellectif/lk-react 14.0.0 → 15.0.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 +49 -0
- package/README.md +5 -2
- package/dist/{WrittenResponse-pB1ik8hg.d.cts → WrittenResponse-BPbhERgk.d.cts} +1 -1
- package/dist/{WrittenResponse-C0P34En1.d.ts → WrittenResponse-ZAxLR_AU.d.ts} +1 -1
- package/dist/{chunk-YEYKJFEC.cjs → chunk-26GQO5I2.cjs} +12 -12
- package/dist/{chunk-YEYKJFEC.cjs.map → chunk-26GQO5I2.cjs.map} +1 -1
- package/dist/chunk-2HAEQDHQ.js +2330 -0
- package/dist/chunk-2HAEQDHQ.js.map +1 -0
- package/dist/{chunk-47HHC4GD.js → chunk-33BQNWAQ.js} +5 -5
- package/dist/{chunk-47HHC4GD.js.map → chunk-33BQNWAQ.js.map} +1 -1
- package/dist/{chunk-SE6WWDVW.cjs → chunk-4H3JTX74.cjs} +13 -13
- package/dist/{chunk-SE6WWDVW.cjs.map → chunk-4H3JTX74.cjs.map} +1 -1
- package/dist/{chunk-TDJEKXEP.js → chunk-52GXJNQ3.js} +84 -2
- package/dist/chunk-52GXJNQ3.js.map +1 -0
- package/dist/{chunk-USBANZ7K.cjs → chunk-53YOZOGN.cjs} +5 -5
- package/dist/{chunk-USBANZ7K.cjs.map → chunk-53YOZOGN.cjs.map} +1 -1
- package/dist/{chunk-LLXCX5KK.js → chunk-AF72QUBI.js} +5 -5
- package/dist/{chunk-LLXCX5KK.js.map → chunk-AF72QUBI.js.map} +1 -1
- package/dist/{chunk-XUEIUEPI.js → chunk-CE6OGJE6.js} +5 -5
- package/dist/{chunk-XUEIUEPI.js.map → chunk-CE6OGJE6.js.map} +1 -1
- package/dist/{chunk-RRH7ZPXC.cjs → chunk-DP3DM7FR.cjs} +6 -6
- package/dist/{chunk-RRH7ZPXC.cjs.map → chunk-DP3DM7FR.cjs.map} +1 -1
- package/dist/{chunk-J2CDPIRC.cjs → chunk-DQ3VVU5T.cjs} +27 -25
- package/dist/chunk-DQ3VVU5T.cjs.map +1 -0
- package/dist/{chunk-U3APKQ7P.cjs → chunk-EKBEKDWO.cjs} +13 -13
- package/dist/{chunk-U3APKQ7P.cjs.map → chunk-EKBEKDWO.cjs.map} +1 -1
- package/dist/{chunk-RXS455MR.js → chunk-EVBYEWHO.js} +3 -2
- package/dist/chunk-EVBYEWHO.js.map +1 -0
- package/dist/{chunk-B2XQLU2E.cjs → chunk-FKGUKFC7.cjs} +24 -6
- package/dist/chunk-FKGUKFC7.cjs.map +1 -0
- package/dist/{chunk-YMBBM5K7.js → chunk-H6I2JDNW.js} +10 -10
- package/dist/{chunk-YMBBM5K7.js.map → chunk-H6I2JDNW.js.map} +1 -1
- package/dist/{chunk-XIBOFTOL.js → chunk-HA3VRF6E.js} +22 -4
- package/dist/chunk-HA3VRF6E.js.map +1 -0
- package/dist/{chunk-I33FOKZ7.js → chunk-I2QGW4GD.js} +14 -12
- package/dist/chunk-I2QGW4GD.js.map +1 -0
- package/dist/{chunk-72UGRIMM.js → chunk-IE5ZNCWN.js} +5 -5
- package/dist/{chunk-72UGRIMM.js.map → chunk-IE5ZNCWN.js.map} +1 -1
- package/dist/{chunk-NDQD3ZRY.cjs → chunk-L7NE7PR4.cjs} +13 -13
- package/dist/{chunk-NDQD3ZRY.cjs.map → chunk-L7NE7PR4.cjs.map} +1 -1
- package/dist/{chunk-D57QZILZ.js → chunk-QEB6O6GU.js} +62 -37
- package/dist/chunk-QEB6O6GU.js.map +1 -0
- package/dist/{chunk-62AKSD5Y.js → chunk-QM4AV6EG.js} +39 -11
- package/dist/chunk-QM4AV6EG.js.map +1 -0
- package/dist/{chunk-LGCUOLP6.js → chunk-RT5FTHUU.js} +5 -5
- package/dist/{chunk-LGCUOLP6.js.map → chunk-RT5FTHUU.js.map} +1 -1
- package/dist/chunk-SRD4KVAP.cjs +2332 -0
- package/dist/chunk-SRD4KVAP.cjs.map +1 -0
- package/dist/{chunk-BVRUUYYR.cjs → chunk-UAYWLYFW.cjs} +18 -18
- package/dist/{chunk-BVRUUYYR.cjs.map → chunk-UAYWLYFW.cjs.map} +1 -1
- package/dist/{chunk-D4DQFTA7.cjs → chunk-UCKA22ZJ.cjs} +3 -2
- package/dist/chunk-UCKA22ZJ.cjs.map +1 -0
- package/dist/{chunk-F4TBCRGI.cjs → chunk-WKOV25NP.cjs} +42 -13
- package/dist/chunk-WKOV25NP.cjs.map +1 -0
- package/dist/{chunk-WTS34S5E.cjs → chunk-XMJE34FY.cjs} +13 -13
- package/dist/{chunk-WTS34S5E.cjs.map → chunk-XMJE34FY.cjs.map} +1 -1
- package/dist/{chunk-SWY6PWXK.js → chunk-YWQH35VO.js} +4 -4
- package/dist/{chunk-SWY6PWXK.js.map → chunk-YWQH35VO.js.map} +1 -1
- package/dist/{chunk-LB3FEV7Z.cjs → chunk-Z6TVOAO5.cjs} +84 -2
- package/dist/chunk-Z6TVOAO5.cjs.map +1 -0
- package/dist/{chunk-36FTYJWJ.cjs → chunk-ZH5WT2IE.cjs} +80 -55
- package/dist/chunk-ZH5WT2IE.cjs.map +1 -0
- package/dist/{chunk-BO6P723E.js → chunk-ZJMTHPHY.js} +3 -3
- package/dist/{chunk-BO6P723E.js.map → chunk-ZJMTHPHY.js.map} +1 -1
- package/dist/components/ActivityPreview.cjs +12 -12
- package/dist/components/ActivityPreview.d.cts +2 -2
- package/dist/components/ActivityPreview.d.ts +2 -2
- package/dist/components/ActivityPreview.js +11 -11
- package/dist/components/ActivitySequence.cjs +13 -13
- package/dist/components/ActivitySequence.d.cts +14 -7
- package/dist/components/ActivitySequence.d.ts +14 -7
- package/dist/components/ActivitySequence.js +12 -12
- package/dist/components/Dictation.cjs +5 -5
- package/dist/components/Dictation.d.cts +1 -1
- package/dist/components/Dictation.d.ts +1 -1
- package/dist/components/Dictation.js +4 -4
- package/dist/components/FillInTheBlanks.cjs +5 -5
- package/dist/components/FillInTheBlanks.d.cts +1 -1
- package/dist/components/FillInTheBlanks.d.ts +1 -1
- package/dist/components/FillInTheBlanks.js +4 -4
- package/dist/components/GapSelect.cjs +5 -5
- package/dist/components/GapSelect.d.cts +1 -1
- package/dist/components/GapSelect.d.ts +1 -1
- package/dist/components/GapSelect.js +4 -4
- package/dist/components/InteractiveVideo.cjs +26 -0
- package/dist/components/InteractiveVideo.cjs.map +1 -0
- package/dist/components/InteractiveVideo.d.cts +77 -0
- package/dist/components/InteractiveVideo.d.ts +77 -0
- package/dist/components/InteractiveVideo.js +17 -0
- package/dist/components/InteractiveVideo.js.map +1 -0
- package/dist/components/MultipleChoice.cjs +5 -5
- package/dist/components/MultipleChoice.d.cts +1 -1
- package/dist/components/MultipleChoice.d.ts +1 -1
- package/dist/components/MultipleChoice.js +4 -4
- package/dist/components/PronunciationFeedback.cjs +4 -4
- package/dist/components/PronunciationFeedback.d.cts +5 -2
- package/dist/components/PronunciationFeedback.d.ts +5 -2
- package/dist/components/PronunciationFeedback.js +3 -3
- package/dist/components/ReadAloud.cjs +6 -6
- package/dist/components/ReadAloud.d.cts +2 -2
- package/dist/components/ReadAloud.d.ts +2 -2
- package/dist/components/ReadAloud.js +5 -5
- package/dist/components/StimulusPanel.cjs +4 -4
- package/dist/components/StimulusPanel.d.cts +1 -1
- package/dist/components/StimulusPanel.d.ts +1 -1
- package/dist/components/StimulusPanel.js +3 -3
- package/dist/components/WrittenResponse.cjs +5 -5
- package/dist/components/WrittenResponse.d.cts +3 -3
- package/dist/components/WrittenResponse.d.ts +3 -3
- package/dist/components/WrittenResponse.js +4 -4
- package/dist/i18n/LkIntlProvider.cjs +7 -7
- package/dist/i18n/LkIntlProvider.d.cts +2 -2
- package/dist/i18n/LkIntlProvider.d.ts +2 -2
- package/dist/i18n/LkIntlProvider.js +1 -1
- package/dist/index.cjs +44 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +15 -14
- package/dist/index.js.map +1 -1
- package/dist/{strings--ADnHcaA.d.cts → strings-5588Q4Te.d.cts} +118 -1
- package/dist/{strings-CtdSf2St.d.ts → strings-D0IWcsUm.d.ts} +118 -1
- package/dist/theme/ThemeProvider.cjs +6 -6
- package/dist/theme/ThemeProvider.js +1 -1
- package/dist/theme/defaults.css +2 -0
- package/dist/theme/skin.css +1365 -1
- package/package.json +13 -3
- package/dist/chunk-36FTYJWJ.cjs.map +0 -1
- package/dist/chunk-62AKSD5Y.js.map +0 -1
- package/dist/chunk-B2XQLU2E.cjs.map +0 -1
- package/dist/chunk-D4DQFTA7.cjs.map +0 -1
- package/dist/chunk-D57QZILZ.js.map +0 -1
- package/dist/chunk-F4TBCRGI.cjs.map +0 -1
- package/dist/chunk-I33FOKZ7.js.map +0 -1
- package/dist/chunk-J2CDPIRC.cjs.map +0 -1
- package/dist/chunk-LB3FEV7Z.cjs.map +0 -1
- package/dist/chunk-RXS455MR.js.map +0 -1
- package/dist/chunk-TDJEKXEP.js.map +0 -1
- package/dist/chunk-XIBOFTOL.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/i18n/strings.ts","../src/i18n/LkIntlProvider.tsx"],"names":["createContext","useMemo","jsx","useContext"],"mappings":"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","file":"chunk-Z6TVOAO5.cjs","sourcesContent":["import type { ReadAloudDimension, ReadAloudWordState, Stimulus } from '@intellectif/lk-core';\nimport type { CaptionSize } from '../components/InteractiveVideo/prefs.js';\nimport type { VideoShortcutAction } from '../components/InteractiveVideo/shortcuts.js';\nimport type { MediaTransportStrings } from '../components/types.js';\nimport type { SpeechRecorderError } from '../hooks/useSpeechRecorder.js';\n\n/**\n * Every string the SDK's own chrome renders.\n *\n * Until 0.8.1 these were literals, and `locale` set only the `lang` attribute —\n * so a learner sitting a Spanish paper read a Spanish passage inside an English\n * scaffold, and \"No plays remaining\" on a listening exam was untranslatable.\n * This is the whole surface, in one place, so a consumer can replace it.\n *\n * **Interpolation and plurals are functions, not format strings.** A message\n * like `\"Question {n} of {total}\"` needs a parser, and a parser needs plural\n * rules for every locale the SDK does not know. A function hands both problems\n * to the consumer, who has `Intl.PluralRules` and knows their own language:\n *\n * ```ts\n * questionProgress: (index, total) => `Pregunta ${index} de ${total}`,\n * wordCount: (n) => `${n} ${n === 1 ? 'palabra' : 'palabras'}`,\n * ```\n *\n * It also lets a translation reorder its arguments, which a positional token\n * cannot, and TypeScript checks the arity. No parser, no message catalogue\n * format, no runtime dependency.\n *\n * **What is deliberately NOT here: thrown errors.** Every `throw` in this\n * package is addressed to the developer who wired the component up, not to the\n * learner. Translating them would make them unsearchable and would put the one\n * audience who can act on them behind a translation. They stay English.\n */\nexport interface LkStrings {\n // ── Submission ─────────────────────────────────────────────────────────\n /** Multiple Choice submit button, and Written Response. */\n submit: string;\n /** Fill-in-the-Blanks in `practice`: the learner is checking their own work. */\n checkAnswers: string;\n /** Fill-in-the-Blanks in `exam`: nothing is checked on the client. */\n submitAnswers: string;\n\n // ── Outcome, announced after submit ────────────────────────────────────\n /**\n * The scored result, read by a screen reader on submit.\n *\n * `percent` is already rounded to a whole number. The authored overall\n * feedback is appended SEPARATELY by the component, so a translation of this\n * sentence never has to carry the author's words — the two were previously\n * concatenated into one literal, which made the score sentence untranslatable\n * without also touching authored content.\n */\n scoreAnnouncement: (percent: number, passed: boolean) => string;\n /** Prefix announced on submit, before the score sentence. */\n answerSubmitted: string;\n /** An answer submitted for grading that has none yet. Never rendered as 0%. */\n notGradedYet: string;\n /** An outcome that carries no grade and never will. */\n noGradeAvailable: string;\n\n // ── Feedback disclosure ────────────────────────────────────────────────\n showFeedback: string;\n hideFeedback: string;\n\n // ── Fill-in-the-Blanks ─────────────────────────────────────────────────\n /** Accessible name of a blank's input. `ordinal` is 1-based. */\n blankLabel: (ordinal: number) => string;\n\n // ── Gap select ────────────────────────────────────────────────────────────\n /** Accessible name of the selector for one gap in a Gap Select passage. */\n gapLabel: (ordinal: number) => string;\n /**\n * The empty first entry of a gap's selector — how a learner leaves a gap\n * alone, and how they take an answer back. Never a real choice.\n */\n gapPlaceholder: string;\n showHint: string;\n hideHint: string;\n\n // ── Written Response ───────────────────────────────────────────────────\n /**\n * Announced when an essay is handed in. Distinct from {@link LkStrings.awaitingGrade},\n * which is the `review`-mode state of a submission made earlier: this one\n * confirms the act, and is the only thing a learner hears at the moment they\n * commit work that nothing on the client will grade.\n */\n responseSubmitted: string;\n /** Live word counter. Needs the count for languages whose plural rules differ. */\n wordCount: (count: number) => string;\n /** The authored bounds, e.g. \"50–200 words\". `min` is 0 when unbounded below. */\n wordBounds: (min: number, max: number) => string;\n /** A rubric criterion the grader marked not applicable. */\n notApplicable: string;\n /** A returned grade flagged for a human to look at — learner-visible by design. */\n awaitingHumanReview: string;\n /** Submitted, no grade back yet. */\n awaitingGrade: string;\n /** The grader could not produce a grade. */\n couldNotBeGraded: string;\n\n // ── Sequence pager ─────────────────────────────────────────────────────\n previous: string;\n next: string;\n /** Progress label, also the question region's accessible name. `index` is 1-based. */\n questionProgress: (index: number, total: number) => string;\n /** Shown when no renderer is registered for an activity type. */\n unsupportedActivity: string;\n\n // ── Dictation ──────────────────────────────────────────────────────────\n /** Accessible name of the box the learner types the recording into. */\n dictationInputLabel: string;\n /** Accessible name of the group holding the recording. */\n dictationRecording: string;\n /** Accessible name of the group holding the slower recording, and its default `alt`. */\n dictationSlowRecording: string;\n /** The progressive-hint button, with how many transcript words are shown so far. */\n dictationRevealNextWord: (revealed: number, total: number) => string;\n /** Hides every revealed hint word again. */\n dictationResetHints: string;\n /** The solution toggle: shows the transcript after the attempt is marked. */\n showSolution: string;\n hideSolution: string;\n /** Accessible name of the revealed transcript. */\n dictationSolutionLabel: string;\n /** Accessible name of the word-by-word marked result. */\n dictationMarksLabel: string;\n /** Tells the learner the marks compare the normalised text, not what they typed. */\n dictationDiffNote: string;\n /**\n * The four sentences a screen reader hears for a marked word — the only\n * channel the marks have for assistive technology; the glyphs and the\n * character diff are decoration.\n */\n dictationWordCorrect: (word: string) => string;\n dictationWordWrong: (word: string, expected: string) => string;\n dictationWordMissing: (expected: string) => string;\n dictationWordExtra: (word: string) => string;\n /** The legend rows; the character-level marks reuse the same four. */\n dictationLegendCorrect: string;\n dictationLegendWrong: string;\n dictationLegendMissing: string;\n dictationLegendExtra: string;\n /** Marked result of an attempt with no words in it once punctuation and spacing are ignored, an empty one included. */\n dictationNothingTyped: string;\n /**\n * Appended to the score announcement, e.g. \"4 of 6 words correct.\" — a whole\n * sentence, because authored feedback may follow it.\n */\n dictationWordsSummary: (correct: number, total: number) => string;\n\n // ── Read aloud ─────────────────────────────────────────────────────────\n /** Accessible name of the group holding the model recording. */\n readAloudModelRecording: string;\n /** Accessible name of the group holding the slower model recording, and its default `alt`. */\n readAloudSlowRecording: string;\n /** Starts a take. */\n readAloudRecord: string;\n /** Ends the take in progress. */\n readAloudStop: string;\n /** Throws the take away so the learner can start over. */\n readAloudRerecord: string;\n /** Accessible name of the player for the take the learner just made. */\n readAloudYourRecording: string;\n /**\n * In place of the player for the learner's own take, and of the buttons that\n * play one word of it, when the page refuses to play it — most often a\n * Content-Security-Policy whose `media-src` does not allow `blob:`. Said\n * rather than left as controls that do nothing when pressed.\n */\n readAloudPlaybackUnavailable: string;\n /**\n * Live progress while recording. Whole seconds, not a `m:ss` clock: a\n * recording is bounded in seconds by the item, and a translation should not\n * have to reimplement a clock to change the word around it.\n *\n * Shown on screen and hidden from assistive technology: it changes every\n * second, and a screen reader that spoke each change would speak into the\n * take being assessed. The two sentences below are what is announced instead.\n */\n readAloudRecordingProgress: (seconds: number, maxSeconds: number) => string;\n /** Announced once when a capture begins. */\n readAloudRecordingStarted: string;\n /**\n * Announced once when a capture ends, by the learner or at its own bound.\n * Carries the length because the progress counter is not announced: a take\n * that reads back as \"20 of 20 seconds\" is one that stopped itself.\n */\n readAloudRecordingStopped: (seconds: number, maxSeconds: number) => string;\n /** How many takes are left. Called with 0 as well, so the wording is one translation's. */\n readAloudTakesRemaining: (remaining: number, max: number) => string;\n /** `exam` only: hands the item in with no recording at all, deliberately. */\n readAloudSubmitWithoutRecording: string;\n /** Pending, while the take travels to the application's storage. */\n readAloudUploading: string;\n /** The take never reached storage, so nothing was submitted. */\n readAloudUploadFailed: string;\n /** Retries whichever step just failed. */\n readAloudTryAgain: string;\n /** Pending, while the assessor judges the take. */\n readAloudAssessing: string;\n /** The binding stores recordings but judges none, so there is no feedback to show. */\n readAloudAssessmentUnavailable: string;\n /** The assessor found no speech, or too little of it, in the take. */\n readAloudNotHeard: string;\n /** The assessor produced no grade for any other reason. The code itself is never shown. */\n readAloudNotAssessed: string;\n /** The assessment could not be run at all — a failure of the call, not of the reading. */\n readAloudAssessmentFailed: string;\n /**\n * What went wrong with the microphone or with the take. One function rather\n * than five keys, so a translation keeps the five sentences together and the\n * SDK keeps one name for the concept.\n */\n readAloudRecorderError: (reason: SpeechRecorderError) => string;\n\n // ── Pronunciation feedback ─────────────────────────────────────────────\n /** Accessible name of the whole feedback region. */\n pronunciationFeedbackLabel: string;\n /** Name of one scored dimension, as a learner reads it. */\n pronunciationDimension: (dimension: ReadAloudDimension) => string;\n /** A dimension or a word the engine did not measure. NEVER rendered as 0%. */\n pronunciationNotAssessed: string;\n /** Accessible name of the word-by-word marks. */\n pronunciationWordsLabel: string;\n /** One legend row per marking state — the same four states the marks carry. */\n pronunciationLegend: (state: ReadAloudWordState) => string;\n /**\n * The four sentences a screen reader hears for a marked word: the only\n * channel the marks have for assistive technology, since the glyph and the\n * decoration are both hidden from it.\n */\n pronunciationWordCorrect: (word: string) => string;\n pronunciationWordMispronounced: (word: string) => string;\n pronunciationWordOmitted: (word: string) => string;\n pronunciationWordInserted: (word: string) => string;\n /** Opens one word's syllables, sounds and timings. */\n pronunciationWordDetails: (word: string) => string;\n pronunciationSyllables: string;\n pronunciationPhonemes: string;\n /** A syllable the engine also spelled out, e.g. `('ˈhæ', 'ha')`. */\n pronunciationSyllableSpelling: (syllable: string, grapheme: string) => string;\n /** A sound the engine named no symbol for; `ordinal` is 1-based. */\n pronunciationPhonemePosition: (ordinal: number) => string;\n /** Introduces the sounds the engine thought it heard in a sound's place. */\n pronunciationHeardAs: string;\n /** Plays one word out of the learner's own take. */\n pronunciationPlayWord: (word: string) => string;\n pronunciationBreakUnexpected: string;\n pronunciationBreakMissing: string;\n /** Shown only past the caller's own monotone threshold; the SDK sets none. */\n pronunciationMonotone: string;\n /** Names the alphabet the phoneme symbols are written in. */\n pronunciationIpaNote: string;\n\n // ── Interactive video ──────────────────────────────────────────────────\n // Play, pause, mute, volume, speed, the progress bar's name and the time\n // readout are the `media` strings below: the same controls, the same words.\n /** Jump buttons, e.g. \"Back 10 seconds\". */\n videoBack: (seconds: number) => string;\n videoForward: (seconds: number) => string;\n /** The centre button once the video has ended. */\n videoReplay: string;\n /** The time readout flips between elapsed and remaining; these name what a press shows next. */\n videoShowRemaining: string;\n videoShowElapsed: string;\n /** The captions button, named by what a press does. */\n videoCaptionsShow: string;\n videoCaptionsHide: string;\n /** In the captions menu when a caption file could not be read. */\n videoCaptionsFailed: string;\n /** A speed in the speed menu, e.g. \"1.25×\". */\n videoSpeedValue: (rate: number) => string;\n videoSettings: string;\n videoCaptionLanguage: string;\n videoCaptionSize: string;\n videoCaptionSizeValue: (size: CaptionSize) => string;\n videoCaptionBackground: string;\n videoKeyboardShortcuts: string;\n videoShortcutList: string;\n /** Closes the shortcut list. */\n videoClose: string;\n /** A setting's state in the settings menu. */\n videoOn: string;\n videoOff: string;\n /** What each row of the shortcut list does. */\n videoShortcut: (action: VideoShortcutAction) => string;\n /** The button that opens the panel below the video, and its two tabs. */\n videoPanel: string;\n videoContents: string;\n videoTranscript: string;\n videoTranscriptSearch: string;\n videoTranscriptNoMatch: string;\n videoPictureInPicture: string;\n videoFullscreen: string;\n videoExitFullscreen: string;\n /**\n * Why the video will not play, by `MediaError.code` (1 aborted, 2 network,\n * 3 decode, 4 source), with 0 for anything else.\n */\n videoError: (code: number) => string;\n videoTryAgain: string;\n /** A quiz with no title of its own. */\n videoQuiz: string;\n /** Where the learner is inside a quiz, e.g. \"Question 2 of 5\". */\n videoQuestionProgress: (index: number, total: number) => string;\n /** A step of the quiz's step indicator, for assistive technology. */\n videoQuestionStep: (index: number, answered: boolean) => string;\n videoNextQuestion: string;\n videoContinue: string;\n videoSkipQuiz: string;\n videoRewatch: string;\n /** Exam mode, once a question is submitted: saved, not graded. */\n videoAnswerSaved: string;\n videoRequired: string;\n /** A quiz's progress in the contents panel and on the end screen. */\n videoQuizProgress: (answered: number, total: number) => string;\n /** Announced when a quiz opens. */\n videoQuizOpened: (time: string, questions: number) => string;\n /** Announced when a seek stopped at a required quiz. */\n videoHeldAtQuiz: (time: string) => string;\n /** Announced when a seek stopped at the furthest point reached. */\n videoHeldAhead: string;\n videoEnded: string;\n /** Practice end screen: questions answered, and the score. */\n videoEndScore: (answered: number, total: number, percent: number) => string;\n /** Exam end screen: questions answered, no score. */\n videoEndAnswered: (answered: number, total: number) => string;\n videoWatchAgain: string;\n videoFinish: string;\n\n // ── Authoring preview ──────────────────────────────────────────────────\n /**\n * `<ActivityPreview>`, in place of a draft that still has something missing.\n * Author-facing, not learner-facing — but an editor is translated too.\n */\n previewIncomplete: string;\n /** `<ActivityPreview>`, in place of a draft with something wrong in it. */\n previewInvalid: string;\n\n // ── Embedded media ────────────────────────────────────────────────────────\n /**\n * Accessible name of a provider iframe whose author supplied no `alt`.\n * `MediaSchema` requires `alt` on an embed, so validated content never\n * reaches this — but `validateActivity` is opt-in, and a screen-reader\n * learner meeting an unvalidated one should not meet it in English.\n */\n embeddedMedia: string;\n\n // ── Shared stimulus ────────────────────────────────────────────────────\n /**\n * Accessible name of the stimulus region when the author gave it no title.\n * Keyed by `Stimulus['kind']`, because \"Recording\" and \"Passage\" do not share\n * a gender or an article in every language.\n */\n stimulusKind: Record<Stimulus['kind'], string>;\n /**\n * How far the material carries, e.g. \"Questions 3–8\". Called with equal\n * `first` and `last` for a single question, so a translation can choose its\n * own singular rather than receive a pre-pluralised English one.\n */\n stimulusRange: (first: number, last: number) => string;\n\n // ── Error boundary ─────────────────────────────────────────────────────\n /** Production fallback when an activity throws during render. */\n activityFailed: string;\n /** The same, when the activity's title is known. */\n activityFailedNamed: (title: string) => string;\n /** Production fallback when the activity has no title to name. */\n activityFailedUnnamed: string;\n\n // ── Audio transport ────────────────────────────────────────────────────\n /**\n * The listening-paper transport. Shipped in 0.8.0 as its own `mediaStrings`\n * prop, which still works — this is the same shape, reachable from the one\n * provider so a consumer does not wire two mechanisms.\n */\n media: MediaTransportStrings;\n}\n\n/** A partial override, nested one level for {@link LkStrings.media}. */\nexport type LkStringsOverride = Partial<Omit<LkStrings, 'media' | 'stimulusKind'>> & {\n media?: Partial<MediaTransportStrings>;\n stimulusKind?: Partial<Record<Stimulus['kind'], string>>;\n};\n\n/**\n * English defaults, byte-identical to what every component rendered before the\n * strings surface existed. Supplying no override changes nothing on screen.\n */\nexport const DEFAULT_STRINGS: LkStrings = {\n submit: 'Submit',\n checkAnswers: 'Check answers',\n submitAnswers: 'Submit answers',\n\n scoreAnnouncement: (percent, passed) =>\n `Score ${percent}%. ${passed ? 'Passed.' : 'Not passed.'}`,\n answerSubmitted: 'Answer submitted.',\n notGradedYet: 'Not graded yet.',\n noGradeAvailable: 'No grade available.',\n\n showFeedback: 'Show feedback',\n hideFeedback: 'Hide feedback',\n\n blankLabel: (ordinal) => `Fill in blank ${ordinal}`,\n\n gapLabel: (ordinal) => `Choose the answer for gap ${ordinal}`,\n gapPlaceholder: 'Choose…',\n showHint: 'Show hint',\n hideHint: 'Hide hint',\n\n responseSubmitted:\n 'Response submitted. It will be graded and your result will appear here later.',\n wordCount: (count) => `${count} ${count === 1 ? 'word' : 'words'}`,\n wordBounds: (min, max) => (min > 0 ? `${min}–${max} words` : `up to ${max} words`),\n notApplicable: 'Not applicable',\n awaitingHumanReview: 'This grade is awaiting review by a teacher.',\n awaitingGrade: 'Not graded yet. This response is waiting for its grade.',\n couldNotBeGraded: 'This response could not be graded.',\n\n previous: 'Previous',\n next: 'Next',\n questionProgress: (index, total) => `Question ${index} of ${total}`,\n unsupportedActivity: 'This activity type has no renderer. Supply one through the renderers prop.',\n\n dictationInputLabel: 'Type what you hear',\n dictationRecording: 'Recording',\n dictationSlowRecording: 'Slow recording',\n dictationRevealNextWord: (revealed, total) =>\n `Reveal the next word (${revealed} of ${total} shown)`,\n dictationResetHints: 'Reset hints',\n showSolution: 'Show solution',\n hideSolution: 'Hide solution',\n dictationSolutionLabel: 'Solution',\n dictationMarksLabel: 'Your answer, word by word',\n dictationDiffNote: 'Compared after ignoring case, punctuation and extra spaces.',\n dictationWordCorrect: (word) => `“${word}” is correct`,\n dictationWordWrong: (word, expected) => `“${word}” should be “${expected}”`,\n dictationWordMissing: (expected) => `“${expected}” is missing`,\n dictationWordExtra: (word) => `“${word}” is extra`,\n dictationLegendCorrect: 'Correct',\n dictationLegendWrong: 'Wrong',\n dictationLegendMissing: 'Missing',\n dictationLegendExtra: 'Extra',\n dictationNothingTyped: 'Nothing to compare: no words were entered.',\n dictationWordsSummary: (correct, total) =>\n `${correct} of ${total} ${total === 1 ? 'word' : 'words'} correct.`,\n\n readAloudModelRecording: 'Model recording',\n readAloudSlowRecording: 'Slow model recording',\n readAloudRecord: 'Record',\n readAloudStop: 'Stop recording',\n readAloudRerecord: 'Record again',\n readAloudYourRecording: 'Your recording',\n readAloudPlaybackUnavailable: 'Your recording cannot be played back on this page.',\n readAloudRecordingProgress: (seconds, maxSeconds) =>\n `Recording: ${seconds} of ${maxSeconds} seconds`,\n readAloudRecordingStarted: 'Recording started.',\n readAloudRecordingStopped: (seconds, maxSeconds) =>\n `Recording stopped. ${seconds} of ${maxSeconds} seconds recorded.`,\n readAloudTakesRemaining: (remaining, max) =>\n `${remaining} of ${max} recording${max === 1 ? '' : 's'} left`,\n readAloudSubmitWithoutRecording: 'Submit without recording',\n readAloudUploading: 'Sending your recording…',\n readAloudUploadFailed: 'Your recording could not be sent.',\n readAloudTryAgain: 'Try again',\n readAloudAssessing: 'Checking your pronunciation…',\n readAloudAssessmentUnavailable: 'Pronunciation feedback is not available for this activity.',\n readAloudNotHeard: 'We could not hear you. Record again somewhere quieter.',\n readAloudNotAssessed: 'This recording could not be assessed. Try recording it again.',\n readAloudAssessmentFailed: 'Your pronunciation could not be checked.',\n readAloudRecorderError: (reason) => {\n switch (reason) {\n case 'permission-denied':\n return 'This page is not allowed to use the microphone.';\n case 'no-device':\n return 'No microphone was found.';\n case 'unsupported':\n return 'This browser cannot record audio.';\n case 'too-short':\n return 'That recording was too short.';\n default:\n return 'The recording could not be made.';\n }\n },\n\n pronunciationFeedbackLabel: 'Pronunciation feedback',\n pronunciationDimension: (dimension) => {\n switch (dimension) {\n case 'accuracy':\n return 'Accuracy';\n case 'fluency':\n return 'Fluency';\n case 'completeness':\n return 'Completeness';\n default:\n return 'Intonation';\n }\n },\n pronunciationNotAssessed: 'Not assessed',\n pronunciationWordsLabel: 'Your reading, word by word',\n pronunciationLegend: (state) => {\n switch (state) {\n case 'correct':\n return 'Read correctly';\n case 'mispronounced':\n return 'Mispronounced';\n case 'omitted':\n return 'Not read';\n default:\n return 'Added';\n }\n },\n pronunciationWordCorrect: (word) => `“${word}” was read correctly`,\n pronunciationWordMispronounced: (word) => `“${word}” was mispronounced`,\n pronunciationWordOmitted: (word) => `“${word}” was not read`,\n pronunciationWordInserted: (word) => `“${word}” was added`,\n pronunciationWordDetails: (word) => `Details for “${word}”`,\n pronunciationSyllables: 'Syllables',\n pronunciationPhonemes: 'Sounds',\n pronunciationSyllableSpelling: (syllable, grapheme) => `${syllable} (spelled “${grapheme}”)`,\n pronunciationPhonemePosition: (ordinal) => `Sound ${ordinal}`,\n pronunciationHeardAs: 'Heard as',\n pronunciationPlayWord: (word) => `Play “${word}”`,\n pronunciationBreakUnexpected: 'There was an unexpected pause here.',\n pronunciationBreakMissing: 'A pause was expected here.',\n pronunciationMonotone: 'Your reading stayed on one note. Try varying your pitch.',\n pronunciationIpaNote: 'Sounds are written in the International Phonetic Alphabet.',\n videoBack: (seconds) => `Back ${seconds} seconds`,\n videoForward: (seconds) => `Forward ${seconds} seconds`,\n videoReplay: 'Replay',\n videoShowRemaining: 'Show time remaining',\n videoShowElapsed: 'Show time elapsed',\n videoCaptionsShow: 'Show captions',\n videoCaptionsHide: 'Hide captions',\n videoCaptionsFailed: 'Captions could not be loaded.',\n videoSpeedValue: (rate) => (rate === 1 ? 'Normal' : `${rate}×`),\n videoSettings: 'Settings',\n videoCaptionLanguage: 'Captions',\n videoCaptionSize: 'Caption size',\n videoCaptionSizeValue: (size) =>\n size === 'small' ? 'Small' : size === 'large' ? 'Large' : 'Medium',\n videoCaptionBackground: 'Caption background',\n videoKeyboardShortcuts: 'Keyboard shortcuts',\n videoShortcutList: 'Shortcut list',\n videoClose: 'Close',\n videoOn: 'On',\n videoOff: 'Off',\n videoShortcut: (action) => {\n switch (action) {\n case 'play-pause':\n return 'Play or pause';\n case 'jump-10':\n return 'Back or forward 10 seconds';\n case 'jump-5':\n return 'Back or forward 5 seconds';\n case 'jump-1':\n return 'Back or forward 1 second';\n case 'frame':\n return 'Previous or next frame, while paused';\n case 'speed':\n return 'Slower or faster';\n case 'percent':\n return 'Jump to 0% – 90%';\n case 'start-end':\n return 'Start or end';\n case 'chapter':\n return 'Previous or next chapter or quiz';\n case 'mute':\n return 'Mute';\n case 'captions':\n return 'Captions';\n case 'transcript':\n return 'Transcript';\n case 'picture-in-picture':\n return 'Picture in picture';\n case 'fullscreen':\n return 'Fullscreen';\n default:\n return 'This list';\n }\n },\n videoPanel: 'Contents and transcript',\n videoContents: 'Contents',\n videoTranscript: 'Transcript',\n videoTranscriptSearch: 'Search the transcript',\n videoTranscriptNoMatch: 'No lines match.',\n videoPictureInPicture: 'Picture in picture',\n videoFullscreen: 'Fullscreen',\n videoExitFullscreen: 'Exit fullscreen',\n videoError: (code) =>\n code === 2\n ? 'The connection dropped while the video was loading.'\n : code === 3\n ? 'This video file could not be played.'\n : code === 4\n ? 'The video could not be loaded.'\n : 'The video stopped before it could play.',\n videoTryAgain: 'Try again',\n videoQuiz: 'Quiz',\n videoQuestionProgress: (index, total) => `Question ${index} of ${total}`,\n videoQuestionStep: (index, answered) => `Question ${index}${answered ? ', answered' : ''}`,\n videoNextQuestion: 'Next question',\n videoContinue: 'Continue video',\n videoSkipQuiz: 'Skip quiz',\n videoRewatch: 'Rewatch',\n videoAnswerSaved: 'Answer saved',\n videoRequired: 'Required',\n videoQuizProgress: (answered, total) =>\n answered === total\n ? 'Answered'\n : answered === 0\n ? 'Not started'\n : `${answered} of ${total} answered`,\n videoQuizOpened: (time, questions) =>\n `Video paused. Quiz at ${time}, ${questions} question${questions === 1 ? '' : 's'}.`,\n videoHeldAtQuiz: (time) => `Finish the quiz at ${time} to continue.`,\n videoHeldAhead: 'You can rewind, but not skip ahead.',\n videoEnded: 'You reached the end',\n videoEndScore: (answered, total, percent) => `You answered ${answered} of ${total} · ${percent}%`,\n videoEndAnswered: (answered, total) => `You answered ${answered} of ${total} questions`,\n videoWatchAgain: 'Watch again',\n videoFinish: 'Finish',\n\n previewIncomplete: 'This activity is not finished yet, so it cannot be previewed.',\n previewInvalid: 'This activity has a problem to fix before it can be previewed.',\n\n embeddedMedia: 'Embedded media',\n\n stimulusKind: {\n text: 'Passage',\n audio: 'Recording',\n video: 'Video',\n image: 'Image',\n mixed: 'Material',\n },\n stimulusRange: (first, last) =>\n first === last ? `Question ${first}` : `Questions ${first}–${last}`,\n\n activityFailed: 'Activity failed to render',\n activityFailedNamed: (title) => `\"${title}\" could not be displayed.`,\n activityFailedUnnamed: 'This activity could not be displayed.',\n\n media: {\n play: 'Play',\n pause: 'Pause',\n preparing: 'Preparing…',\n mute: 'Mute',\n unmute: 'Unmute',\n volume: 'Volume',\n speed: 'Playback speed',\n seek: 'Seek',\n timeValue: (elapsed, duration) => `${elapsed} of ${duration}`,\n playsRemaining: (remaining, max) =>\n `${remaining} of ${max} play${max === 1 ? '' : 's'} remaining`,\n noPlaysRemaining: 'No plays remaining',\n lastPlayConfirm: 'This is your last play. Start it now?',\n lastPlayStart: 'Start last play',\n lastPlayCancel: 'Not yet',\n seekBlocked: 'Rewinding is not available for this recording.',\n rateBlocked: 'Playback speed is fixed for this recording.',\n playFailed: 'The recording could not be started. Try again.',\n },\n};\n\n/**\n * Layers an override onto a base dictionary.\n *\n * Two levels deep and no further, because the shape is two levels deep. A\n * generic deep merge would silently accept a nested object where a function\n * belongs and fail at render instead of at the call site.\n */\nexport function mergeStrings(base: LkStrings, override?: LkStringsOverride): LkStrings {\n if (override === undefined) {\n return base;\n }\n const { media, stimulusKind, ...flat } = override;\n return {\n ...base,\n ...flat,\n stimulusKind: { ...base.stimulusKind, ...stimulusKind },\n media: { ...base.media, ...media },\n };\n}\n","'use client';\n\nimport { createContext, useContext, useMemo } from 'react';\nimport type { LkStrings, LkStringsOverride } from './strings.js';\nimport { DEFAULT_STRINGS, mergeStrings } from './strings.js';\n\nexport type { LkStrings, LkStringsOverride } from './strings.js';\nexport { DEFAULT_STRINGS, mergeStrings } from './strings.js';\n\n/** Writing direction of the surrounding UI. `auto` defers to the locale. */\nexport type LkDirection = 'ltr' | 'rtl' | 'auto';\n\ninterface LkIntlValue {\n strings: LkStrings;\n locale: string | undefined;\n direction: 'ltr' | 'rtl';\n}\n\nconst LkIntlContext = createContext<LkIntlValue | null>(null);\n\n/**\n * Locales written right-to-left, by language subtag.\n *\n * A short list rather than a dependency: these are the RTL scripts in living\n * use, and the set has not changed in decades. `Intl.Locale.textInfo` would be\n * better but is not available everywhere this package runs, and an explicit\n * `direction` prop overrides this in either direction anyway.\n */\nconst RTL_LANGUAGES = new Set(['ar', 'arc', 'dv', 'fa', 'he', 'ku', 'ps', 'sd', 'ug', 'ur', 'yi']);\n\n/** Resolves a BCP 47 tag to a writing direction. */\nexport function directionForLocale(locale: string | undefined): 'ltr' | 'rtl' {\n if (locale === undefined) {\n return 'ltr';\n }\n const language = locale.split('-')[0]?.toLowerCase() ?? '';\n return RTL_LANGUAGES.has(language) ? 'rtl' : 'ltr';\n}\n\nexport interface LkIntlProviderProps {\n /**\n * Replaces the SDK's own chrome text. Anything omitted keeps its English\n * default, so a partial translation degrades to mixed rather than to blank.\n *\n * A nested provider REPLACES the one above it rather than layering onto it —\n * as a nested `ThemeProvider` restarts from `defaultTheme`. To layer, use a\n * component's own `strings` prop, or compose with `mergeStrings`.\n */\n strings?: LkStringsOverride;\n /**\n * BCP 47 tag for the SDK's chrome — NOT for the authored content, which\n * carries its own `locale`. Sets `lang` on the wrapper so a screen reader\n * reads \"Question 3 of 10\" in the interface language rather than in the\n * language of the passage beside it (WCAG 3.1.2).\n */\n locale?: string;\n /**\n * Writing direction. Defaults to `auto`, which derives it from `locale`.\n * Set it explicitly when the surrounding application already manages `dir`\n * and you do not want a second element declaring one.\n */\n direction?: LkDirection;\n children: React.ReactNode;\n}\n\n/**\n * Supplies the SDK's chrome text and writing direction to everything beneath.\n *\n * Mirrors `ThemeProvider`: a provider for the whole tree, and a per-component\n * prop for the exceptions. The component prop wins, so a single activity can\n * be relabelled without a second provider.\n *\n * ```tsx\n * <LkIntlProvider locale=\"es\" strings={{\n * submit: 'Enviar',\n * checkAnswers: 'Comprobar respuestas',\n * questionProgress: (i, total) => `Pregunta ${i} de ${total}`,\n * wordCount: (n) => `${n} ${n === 1 ? 'palabra' : 'palabras'}`,\n * media: { noPlaysRemaining: 'No quedan reproducciones' },\n * }}>\n * <ActivitySequence … />\n * </LkIntlProvider>\n * ```\n *\n * The SDK ships **English only**. Bundling Spanish, Portuguese or Arabic would\n * mean shipping translations nobody in this repo can review, and a wrong\n * \"No plays remaining\" on a listening exam is worse than an English one that a\n * teacher can see is untranslated. The mechanism is the deliverable; the words\n * belong to whoever speaks the language.\n */\nexport function LkIntlProvider({\n strings,\n locale,\n direction = 'auto',\n children,\n}: LkIntlProviderProps): React.JSX.Element {\n const value = useMemo<LkIntlValue>(\n () => ({\n strings: mergeStrings(DEFAULT_STRINGS, strings),\n locale,\n direction: direction === 'auto' ? directionForLocale(locale) : direction,\n }),\n [strings, locale, direction],\n );\n\n // Declare `dir` only when something actually told us the direction. With no\n // locale and no explicit `direction`, writing dir=\"ltr\" would flip an RTL\n // host's own subtree back to left-to-right — the context value stays\n // concrete for `useLkDirection`; it is only the DOM declaration we withhold.\n const declared = direction === 'auto' && locale === undefined ? undefined : value.direction;\n\n return (\n <LkIntlContext.Provider value={value}>\n <div className=\"lk-intl\" lang={locale} dir={declared}>\n {children}\n </div>\n </LkIntlContext.Provider>\n );\n}\n\n/**\n * The strings in force, with an optional per-component override layered on top.\n *\n * Usable without a provider: every component calls this, and one rendered\n * standalone still needs its labels. Falling back to the English defaults is\n * what keeps `<MultipleChoice>` working with no setup at all.\n */\nexport function useLkStrings(override?: LkStringsOverride): LkStrings {\n const context = useContext(LkIntlContext);\n const base = context?.strings ?? DEFAULT_STRINGS;\n return useMemo(() => mergeStrings(base, override), [base, override]);\n}\n\n/** The direction in force. `ltr` with no provider. */\nexport function useLkDirection(): 'ltr' | 'rtl' {\n return useContext(LkIntlContext)?.direction ?? 'ltr';\n}\n"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkWKOV25NP_cjs = require('./chunk-WKOV25NP.cjs');
|
|
5
5
|
var chunkUDCQTOVU_cjs = require('./chunk-UDCQTOVU.cjs');
|
|
6
6
|
var chunkOD65OZIW_cjs = require('./chunk-OD65OZIW.cjs');
|
|
7
7
|
var chunkBRPEB43C_cjs = require('./chunk-BRPEB43C.cjs');
|
|
8
|
-
var
|
|
9
|
-
var
|
|
8
|
+
var chunk53YOZOGN_cjs = require('./chunk-53YOZOGN.cjs');
|
|
9
|
+
var chunkFKGUKFC7_cjs = require('./chunk-FKGUKFC7.cjs');
|
|
10
10
|
var chunkXOR4MPEN_cjs = require('./chunk-XOR4MPEN.cjs');
|
|
11
|
-
var
|
|
11
|
+
var chunkZ6TVOAO5_cjs = require('./chunk-Z6TVOAO5.cjs');
|
|
12
12
|
var lkCore = require('@intellectif/lk-core');
|
|
13
13
|
var react = require('react');
|
|
14
14
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -56,6 +56,20 @@ function stampTake(value, take) {
|
|
|
56
56
|
function takeOf(value) {
|
|
57
57
|
return typeof value === "object" && value !== null ? takes.get(value) : void 0;
|
|
58
58
|
}
|
|
59
|
+
var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
60
|
+
function readRecordingBounds(recording) {
|
|
61
|
+
const bounds = typeof recording === "object" && recording !== null ? recording : {};
|
|
62
|
+
const maxSeconds = isNumber(bounds.maxSeconds) && bounds.maxSeconds > 0 ? Math.min(bounds.maxSeconds, lkCore.READ_ALOUD_MAX_SECONDS) : lkCore.READ_ALOUD_MAX_SECONDS;
|
|
63
|
+
const minSeconds = isNumber(bounds.minSeconds) && bounds.minSeconds >= 0 && bounds.minSeconds < maxSeconds ? bounds.minSeconds : void 0;
|
|
64
|
+
const takes2 = bounds.maxTakes;
|
|
65
|
+
const maxTakes = takes2 === void 0 || takes2 === null ? void 0 : isNumber(takes2) ? Math.min(Math.max(1, Math.floor(takes2)), lkCore.READ_ALOUD_MAX_TAKES) : lkCore.READ_ALOUD_MAX_TAKES;
|
|
66
|
+
return { maxSeconds, minSeconds, maxTakes };
|
|
67
|
+
}
|
|
68
|
+
function secondsWithin(milliseconds, maxSeconds, rounding) {
|
|
69
|
+
const seconds = milliseconds / 1e3;
|
|
70
|
+
const whole = rounding === "nearest" ? Math.round(seconds) : Math.floor(seconds);
|
|
71
|
+
return Math.min(Math.max(0, whole), maxSeconds);
|
|
72
|
+
}
|
|
59
73
|
var modelsGroupCount = 0;
|
|
60
74
|
var VISIBLE_TEXT_RE = /[^\p{White_Space}\p{Cc}\p{Cf}\p{Default_Ignorable_Code_Point}]/u;
|
|
61
75
|
var MARK_ID_RE = /^w\d+$/;
|
|
@@ -74,6 +88,9 @@ function takeStateOf(phase, uploaded) {
|
|
|
74
88
|
}
|
|
75
89
|
return offersRetry(phase, uploaded) ? "retryable" : "settled";
|
|
76
90
|
}
|
|
91
|
+
function capturing(status) {
|
|
92
|
+
return status === "recording" || status === "requesting-permission";
|
|
93
|
+
}
|
|
77
94
|
function readingKeyOf(data, bounds) {
|
|
78
95
|
const text = (value) => typeof value === "string" ? value : null;
|
|
79
96
|
return JSON.stringify([
|
|
@@ -155,7 +172,7 @@ function OutcomeSummary({
|
|
|
155
172
|
"data-status": reading.status,
|
|
156
173
|
"data-passed": String(reading.grade.passed),
|
|
157
174
|
children: scoreShown ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
158
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.scoreAnnouncement(
|
|
175
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.scoreAnnouncement(chunkWKOV25NP_cjs.percentOfGrade(reading.grade), reading.grade.passed) }),
|
|
159
176
|
reading.grade.feedback ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade-feedback", dir: "auto", children: reading.grade.feedback }) : null
|
|
160
177
|
] })
|
|
161
178
|
}
|
|
@@ -202,15 +219,16 @@ function ReadAloud({
|
|
|
202
219
|
recordingBinding,
|
|
203
220
|
assessment,
|
|
204
221
|
breakThreshold,
|
|
205
|
-
monotoneThreshold
|
|
222
|
+
monotoneThreshold,
|
|
223
|
+
workletUrl
|
|
206
224
|
}) {
|
|
207
225
|
const isExam = renderMode === "exam";
|
|
208
226
|
const isReview = renderMode === "review";
|
|
209
|
-
const s =
|
|
227
|
+
const s = chunkZ6TVOAO5_cjs.useLkStrings(strings);
|
|
210
228
|
const slot = react.useContext(SequenceSlotContext);
|
|
211
229
|
const captureGroup = slot?.captureGroup;
|
|
212
230
|
const devError = react.useMemo(() => {
|
|
213
|
-
if (!
|
|
231
|
+
if (!chunk53YOZOGN_cjs.isDevelopment()) {
|
|
214
232
|
return null;
|
|
215
233
|
}
|
|
216
234
|
if (data.redacted === true) {
|
|
@@ -224,19 +242,19 @@ function ReadAloud({
|
|
|
224
242
|
const result = lkCore.validateActivity("read-aloud", data);
|
|
225
243
|
return result.success ? null : new lkCore.ActivitySchemaError("read-aloud", result.errors);
|
|
226
244
|
}, [data]);
|
|
227
|
-
const
|
|
228
|
-
const maxSeconds = typeof bounds?.maxSeconds === "number" && bounds.maxSeconds > 0 ? Math.min(bounds.maxSeconds, lkCore.READ_ALOUD_MAX_SECONDS) : lkCore.READ_ALOUD_MAX_SECONDS;
|
|
229
|
-
const minSeconds = typeof bounds?.minSeconds === "number" ? bounds.minSeconds : void 0;
|
|
230
|
-
const maxTakes = typeof bounds?.maxTakes === "number" && Number.isFinite(bounds.maxTakes) ? Math.min(Math.max(1, Math.floor(bounds.maxTakes)), lkCore.READ_ALOUD_MAX_TAKES) : void 0;
|
|
245
|
+
const { maxSeconds, minSeconds, maxTakes } = readRecordingBounds(data.recording);
|
|
231
246
|
const readingKey = readingKeyOf(data, { maxSeconds, minSeconds, maxTakes });
|
|
232
247
|
const recorder = chunkUDCQTOVU_cjs.useSpeechRecorder(
|
|
233
248
|
react.useMemo(
|
|
234
249
|
() => ({
|
|
235
250
|
maxDurationMs: maxSeconds * 1e3,
|
|
236
251
|
...minSeconds !== void 0 ? { minDurationMs: minSeconds * 1e3 } : {},
|
|
237
|
-
...maxTakes !== void 0 ? { maxTakes } : {}
|
|
252
|
+
...maxTakes !== void 0 ? { maxTakes } : {},
|
|
253
|
+
// Forwarded, never defaulted: without it the recorder mints its own
|
|
254
|
+
// `blob:` module, which is the one a strict policy refuses.
|
|
255
|
+
...workletUrl !== void 0 ? { workletUrl } : {}
|
|
238
256
|
}),
|
|
239
|
-
[maxSeconds, minSeconds, maxTakes]
|
|
257
|
+
[maxSeconds, minSeconds, maxTakes, workletUrl]
|
|
240
258
|
)
|
|
241
259
|
);
|
|
242
260
|
const { state, start, complete, getTimeSpent, reset } = chunkXOR4MPEN_cjs.useActivityState(
|
|
@@ -334,7 +352,7 @@ function ReadAloud({
|
|
|
334
352
|
const statusRef = react.useRef(recorder.status);
|
|
335
353
|
statusRef.current = recorder.status;
|
|
336
354
|
const releaseMicrophone = react.useCallback(() => {
|
|
337
|
-
if (statusRef.current
|
|
355
|
+
if (capturing(statusRef.current)) {
|
|
338
356
|
recorder.discard();
|
|
339
357
|
}
|
|
340
358
|
}, [recorder.discard]);
|
|
@@ -373,8 +391,9 @@ function ReadAloud({
|
|
|
373
391
|
slot.takeState(take2, phaseTakeState);
|
|
374
392
|
}, [slot, phaseTake, phaseTakeState]);
|
|
375
393
|
const modelsRef = react.useRef(null);
|
|
394
|
+
const isCapturing = capturing(recorder.status);
|
|
376
395
|
react.useEffect(() => {
|
|
377
|
-
if (
|
|
396
|
+
if (!isCapturing) {
|
|
378
397
|
return;
|
|
379
398
|
}
|
|
380
399
|
const node = modelsRef.current;
|
|
@@ -394,11 +413,14 @@ function ReadAloud({
|
|
|
394
413
|
return () => {
|
|
395
414
|
node.removeEventListener("play", hush, true);
|
|
396
415
|
};
|
|
397
|
-
}, [
|
|
416
|
+
}, [isCapturing]);
|
|
398
417
|
const slowMedia = react.useMemo(
|
|
399
418
|
() => slowMediaFor(data, s.readAloudSlowRecording),
|
|
400
419
|
[data, s.readAloudSlowRecording]
|
|
401
420
|
);
|
|
421
|
+
const takeAudio = isReview ? playbackUrl : takeUrl;
|
|
422
|
+
const playback = chunkWKOV25NP_cjs.usePlaybackRefusal(takeAudio);
|
|
423
|
+
const submitRef = react.useRef(null);
|
|
402
424
|
if (devError) {
|
|
403
425
|
throw devError;
|
|
404
426
|
}
|
|
@@ -444,7 +466,7 @@ function ReadAloud({
|
|
|
444
466
|
if (run !== runRef.current) {
|
|
445
467
|
return;
|
|
446
468
|
}
|
|
447
|
-
const result =
|
|
469
|
+
const result = chunkWKOV25NP_cjs.readAssessResult(answer);
|
|
448
470
|
if (result.status === "failed") {
|
|
449
471
|
raise({ kind: "assess-failed", take: take2, retryable: result.retryable });
|
|
450
472
|
fire("assessment-failed", { takes: takes2, durationMs, retryable: result.retryable });
|
|
@@ -475,9 +497,9 @@ function ReadAloud({
|
|
|
475
497
|
passed: grade.passed,
|
|
476
498
|
timeSpent,
|
|
477
499
|
xapiStatement: lkCore.xAPIBuilder.buildAnsweredStatement({
|
|
478
|
-
actor:
|
|
500
|
+
actor: chunk53YOZOGN_cjs.ANONYMOUS_ACTOR,
|
|
479
501
|
object: {
|
|
480
|
-
id:
|
|
502
|
+
id: chunk53YOZOGN_cjs.objectIdFor(data.id),
|
|
481
503
|
name: { [data.locale ?? "en-US"]: data.title },
|
|
482
504
|
...lkCore.xapiDefinitionFor(data)
|
|
483
505
|
},
|
|
@@ -487,7 +509,7 @@ function ReadAloud({
|
|
|
487
509
|
// optional, and an empty list is the honest reading of "no per-word
|
|
488
510
|
// marks were stored" — never a mark of its own.
|
|
489
511
|
scoringResult: {
|
|
490
|
-
score:
|
|
512
|
+
score: chunkWKOV25NP_cjs.fractionOfGrade(grade),
|
|
491
513
|
maxScore: 1,
|
|
492
514
|
passed: grade.passed,
|
|
493
515
|
feedback: grade.feedback,
|
|
@@ -581,8 +603,8 @@ function ReadAloud({
|
|
|
581
603
|
};
|
|
582
604
|
const contentLang = typeof data.locale === "string" ? data.locale : void 0;
|
|
583
605
|
const contentDir = chunkOD65OZIW_cjs.localeDirectionOf(data.locale);
|
|
584
|
-
const outcomeReading = react.useMemo(() =>
|
|
585
|
-
const keptEvidence = react.useMemo(() =>
|
|
606
|
+
const outcomeReading = react.useMemo(() => chunkWKOV25NP_cjs.readOutcome(outcome), [outcome]);
|
|
607
|
+
const keptEvidence = react.useMemo(() => chunkWKOV25NP_cjs.readEvidence(assessment), [assessment]);
|
|
586
608
|
const storedGrade = outcomeReading?.kind === "graded" && outcomeReading.status === "graded" ? outcomeReading.grade : null;
|
|
587
609
|
const storedMarks = react.useMemo(
|
|
588
610
|
() => isReview && keptEvidence === null && storedGrade?.details !== void 0 ? marksFromDetails(storedGrade.details) : null,
|
|
@@ -590,7 +612,7 @@ function ReadAloud({
|
|
|
590
612
|
);
|
|
591
613
|
const feedbackAssessment = isReview ? keptEvidence : phase.kind === "graded" ? phase.assessment : null;
|
|
592
614
|
const feedbackGrade = isReview ? storedGrade : phase.kind === "graded" ? phase.grade : null;
|
|
593
|
-
const feedbackAudio =
|
|
615
|
+
const feedbackAudio = playback.refused ? null : takeAudio;
|
|
594
616
|
const rootRef = react.useRef(null);
|
|
595
617
|
const [panelLostTheGrade, setPanelLostTheGrade] = react.useState(false);
|
|
596
618
|
const panelHasGrade = feedbackAssessment !== null && feedbackGrade !== null;
|
|
@@ -608,7 +630,10 @@ function ReadAloud({
|
|
|
608
630
|
return { text: s.readAloudRecordingStarted, feedback: null };
|
|
609
631
|
}
|
|
610
632
|
const stopped = recorder.status === "recorded" && take !== null ? {
|
|
611
|
-
text: s.readAloudRecordingStopped(
|
|
633
|
+
text: s.readAloudRecordingStopped(
|
|
634
|
+
secondsWithin(take.durationMs, maxSeconds, "nearest"),
|
|
635
|
+
maxSeconds
|
|
636
|
+
),
|
|
612
637
|
feedback: null
|
|
613
638
|
} : null;
|
|
614
639
|
if (isExam) {
|
|
@@ -621,7 +646,7 @@ function ReadAloud({
|
|
|
621
646
|
case "graded": {
|
|
622
647
|
const grade = phase.grade;
|
|
623
648
|
return grade === null ? { text: `${s.answerSubmitted} ${s.couldNotBeGraded}`, feedback: null } : {
|
|
624
|
-
text: `${s.answerSubmitted} ${s.scoreAnnouncement(
|
|
649
|
+
text: `${s.answerSubmitted} ${s.scoreAnnouncement(chunkWKOV25NP_cjs.percentOfGrade(grade), grade.passed)}`,
|
|
625
650
|
feedback: grade.feedback
|
|
626
651
|
};
|
|
627
652
|
}
|
|
@@ -654,7 +679,7 @@ function ReadAloud({
|
|
|
654
679
|
data.media !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "lk-ra-model", children: [
|
|
655
680
|
/* @__PURE__ */ jsxRuntime.jsx("legend", { className: "lk-ra-model-label", children: s.readAloudModelRecording }),
|
|
656
681
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
657
|
-
|
|
682
|
+
chunkFKGUKFC7_cjs.ActivityMedia,
|
|
658
683
|
{
|
|
659
684
|
media: data.media,
|
|
660
685
|
renderMode,
|
|
@@ -664,14 +689,14 @@ function ReadAloud({
|
|
|
664
689
|
...strings !== void 0 ? { strings } : {},
|
|
665
690
|
...onInteraction !== void 0 ? { onInteraction } : {},
|
|
666
691
|
...locale !== void 0 ? { locale } : {},
|
|
667
|
-
...disabled
|
|
692
|
+
...disabled === true || isCapturing ? { disabled: true } : {}
|
|
668
693
|
}
|
|
669
694
|
)
|
|
670
695
|
] }) : null,
|
|
671
696
|
slowMedia !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "lk-ra-model", "data-slow": "true", children: [
|
|
672
697
|
/* @__PURE__ */ jsxRuntime.jsx("legend", { className: "lk-ra-model-label", children: s.readAloudSlowRecording }),
|
|
673
698
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
674
|
-
|
|
699
|
+
chunkFKGUKFC7_cjs.ActivityMedia,
|
|
675
700
|
{
|
|
676
701
|
media: slowMedia,
|
|
677
702
|
renderMode,
|
|
@@ -679,7 +704,7 @@ function ReadAloud({
|
|
|
679
704
|
...mediaStrings !== void 0 ? { mediaStrings } : {},
|
|
680
705
|
...strings !== void 0 ? { strings } : {},
|
|
681
706
|
...locale !== void 0 ? { locale } : {},
|
|
682
|
-
...disabled
|
|
707
|
+
...disabled === true || isCapturing ? { disabled: true } : {}
|
|
683
708
|
}
|
|
684
709
|
)
|
|
685
710
|
] }) : null
|
|
@@ -722,41 +747,40 @@ function ReadAloud({
|
|
|
722
747
|
// whole second, so as a live region it announced ten times in a
|
|
723
748
|
// ten-second take — into the microphone. What a screen-reader
|
|
724
749
|
// learner needs instead is said once each, below.
|
|
725
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-progress", "aria-hidden": "true", children: s.readAloudRecordingProgress(
|
|
750
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-progress", "aria-hidden": "true", children: s.readAloudRecordingProgress(
|
|
751
|
+
secondsWithin(recorder.elapsedMs, maxSeconds, "down"),
|
|
752
|
+
maxSeconds
|
|
753
|
+
) })
|
|
726
754
|
) : null,
|
|
727
755
|
takesLeft !== void 0 && maxTakes !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-takes", children: s.readAloudTakesRemaining(takesLeft, maxTakes) }) : null
|
|
728
756
|
]
|
|
729
757
|
}
|
|
730
758
|
),
|
|
731
|
-
|
|
759
|
+
takeAudio === null ? null : playback.refused ? (
|
|
760
|
+
// In the player's place, not beside it: a player the page will not
|
|
761
|
+
// load looks exactly like one that works until it is pressed, and then
|
|
762
|
+
// does nothing. A note rather than an alert — the learner can still
|
|
763
|
+
// submit, and nothing here asks them to act.
|
|
764
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-take-unavailable", role: "note", children: s.readAloudPlaybackUnavailable })
|
|
765
|
+
) : (
|
|
732
766
|
// biome-ignore lint/a11y/useMediaCaption: the learner's own take has no caption track to offer; its accessible name says whose recording it is
|
|
733
767
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
734
768
|
"audio",
|
|
735
769
|
{
|
|
736
770
|
className: "lk-ra-take",
|
|
737
771
|
controls: true,
|
|
738
|
-
src:
|
|
772
|
+
src: takeAudio,
|
|
739
773
|
"aria-label": s.readAloudYourRecording,
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
)
|
|
743
|
-
) : null,
|
|
744
|
-
isReview && playbackUrl !== null ? (
|
|
745
|
-
// biome-ignore lint/a11y/useMediaCaption: the learner's own take has no caption track to offer; its accessible name says whose recording it is
|
|
746
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
747
|
-
"audio",
|
|
748
|
-
{
|
|
749
|
-
className: "lk-ra-take",
|
|
750
|
-
controls: true,
|
|
751
|
-
src: playbackUrl,
|
|
752
|
-
"aria-label": s.readAloudYourRecording
|
|
774
|
+
onError: (event) => playback.refuse(event.currentTarget),
|
|
775
|
+
...isReview ? {} : { "data-take": recorder.takesUsed }
|
|
753
776
|
}
|
|
754
777
|
)
|
|
755
|
-
)
|
|
778
|
+
),
|
|
756
779
|
isReview || submitted ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-ra-actions", children: [
|
|
757
780
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
758
781
|
"button",
|
|
759
782
|
{
|
|
783
|
+
ref: submitRef,
|
|
760
784
|
type: "submit",
|
|
761
785
|
className: "lk-ra-submit",
|
|
762
786
|
disabled: disabled === true,
|
|
@@ -791,6 +815,7 @@ function ReadAloud({
|
|
|
791
815
|
type: "button",
|
|
792
816
|
className: "lk-ra-retry",
|
|
793
817
|
onClick: () => {
|
|
818
|
+
submitRef.current?.focus();
|
|
794
819
|
if (phase.kind === "upload-failed") {
|
|
795
820
|
void submitTake(recorder.take);
|
|
796
821
|
} else if (phase.kind === "assess-failed" && uploaded !== null) {
|
|
@@ -804,7 +829,7 @@ function ReadAloud({
|
|
|
804
829
|
busy ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-pending", role: "status", "aria-busy": "true", children: phase.kind === "uploading" ? s.readAloudUploading : s.readAloudAssessing }) : null,
|
|
805
830
|
alertText !== null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-alert", role: "alert", children: alertText }, errorNonce) : null,
|
|
806
831
|
feedbackAssessment !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
807
|
-
|
|
832
|
+
chunkWKOV25NP_cjs.PronunciationFeedback,
|
|
808
833
|
{
|
|
809
834
|
data: { referenceText: data.referenceText, locale: data.locale },
|
|
810
835
|
assessment: feedbackAssessment,
|
|
@@ -818,14 +843,14 @@ function ReadAloud({
|
|
|
818
843
|
) : null,
|
|
819
844
|
storedMarks !== null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-ra-marks", children: [
|
|
820
845
|
/* @__PURE__ */ jsxRuntime.jsx("ol", { className: "lk-ra-words", "aria-label": s.pronunciationWordsLabel, dir: contentDir, children: storedMarks.map((entry, index) => {
|
|
821
|
-
const sentence =
|
|
846
|
+
const sentence = chunkWKOV25NP_cjs.markSentence(entry, s);
|
|
822
847
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
823
848
|
"li",
|
|
824
849
|
{
|
|
825
850
|
className: "lk-ra-word",
|
|
826
851
|
"data-state": entry.state,
|
|
827
852
|
children: [
|
|
828
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style:
|
|
853
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style: chunkWKOV25NP_cjs.VISUALLY_HIDDEN, children: sentence }),
|
|
829
854
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
830
855
|
"span",
|
|
831
856
|
{
|
|
@@ -849,15 +874,15 @@ function ReadAloud({
|
|
|
849
874
|
// but a live region is the only thing that TELLS a screen-reader
|
|
850
875
|
// learner a grade arrived, since nothing takes focus. Clipped rather
|
|
851
876
|
// than `display: none`, which would stop it being announced at all.
|
|
852
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style:
|
|
877
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style: chunkWKOV25NP_cjs.VISUALLY_HIDDEN, children: /* @__PURE__ */ jsxRuntime.jsx(AnnouncementText, { announcement }) })
|
|
853
878
|
) : /* @__PURE__ */ jsxRuntime.jsx(AnnouncementText, { announcement }) })
|
|
854
879
|
]
|
|
855
880
|
}
|
|
856
881
|
);
|
|
857
882
|
}
|
|
858
883
|
function ReadAloud2(props) {
|
|
859
|
-
const strings =
|
|
860
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
884
|
+
const strings = chunkZ6TVOAO5_cjs.useLkStrings(props.strings);
|
|
885
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunk53YOZOGN_cjs.ActivityErrorBoundary, { activityTitle: props.data?.title, strings, children: /* @__PURE__ */ jsxRuntime.jsx(ReadAloud, { ...props }) });
|
|
861
886
|
}
|
|
862
887
|
|
|
863
888
|
exports.ReadAloud = ReadAloud2;
|
|
@@ -865,5 +890,5 @@ exports.SequenceSlotContext = SequenceSlotContext;
|
|
|
865
890
|
exports.mintTake = mintTake;
|
|
866
891
|
exports.stopCaptureGroup = stopCaptureGroup;
|
|
867
892
|
exports.takeOf = takeOf;
|
|
868
|
-
//# sourceMappingURL=chunk-
|
|
869
|
-
//# sourceMappingURL=chunk-
|
|
893
|
+
//# sourceMappingURL=chunk-ZH5WT2IE.cjs.map
|
|
894
|
+
//# sourceMappingURL=chunk-ZH5WT2IE.cjs.map
|