@intellectif/lk-react 15.0.0 → 16.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 +51 -0
- package/README.md +2 -2
- package/dist/{WrittenResponse-BPbhERgk.d.cts → WrittenResponse-C2zw-1jK.d.cts} +1 -1
- package/dist/{WrittenResponse-ZAxLR_AU.d.ts → WrittenResponse-CTiNpSCC.d.ts} +1 -1
- package/dist/{chunk-ZH5WT2IE.cjs → chunk-2WM2KSO7.cjs} +25 -25
- package/dist/{chunk-ZH5WT2IE.cjs.map → chunk-2WM2KSO7.cjs.map} +1 -1
- package/dist/{chunk-XMJE34FY.cjs → chunk-2YZZL5FV.cjs} +13 -13
- package/dist/{chunk-XMJE34FY.cjs.map → chunk-2YZZL5FV.cjs.map} +1 -1
- package/dist/{chunk-2HAEQDHQ.js → chunk-3IHVDQRC.js} +492 -139
- package/dist/chunk-3IHVDQRC.js.map +1 -0
- package/dist/{chunk-IE5ZNCWN.js → chunk-4AQ4SWJ3.js} +5 -5
- package/dist/{chunk-IE5ZNCWN.js.map → chunk-4AQ4SWJ3.js.map} +1 -1
- package/dist/{chunk-RT5FTHUU.js → chunk-4X7NFEDB.js} +5 -5
- package/dist/{chunk-RT5FTHUU.js.map → chunk-4X7NFEDB.js.map} +1 -1
- package/dist/{chunk-SRD4KVAP.cjs → chunk-A2CPCOJA.cjs} +503 -149
- package/dist/chunk-A2CPCOJA.cjs.map +1 -0
- package/dist/{chunk-AF72QUBI.js → chunk-AEUP63CZ.js} +5 -5
- package/dist/{chunk-AF72QUBI.js.map → chunk-AEUP63CZ.js.map} +1 -1
- package/dist/{chunk-DQ3VVU5T.cjs → chunk-ALDGRDYD.cjs} +24 -24
- package/dist/{chunk-DQ3VVU5T.cjs.map → chunk-ALDGRDYD.cjs.map} +1 -1
- package/dist/{chunk-WKOV25NP.cjs → chunk-BO64SLHL.cjs} +8 -8
- package/dist/{chunk-WKOV25NP.cjs.map → chunk-BO64SLHL.cjs.map} +1 -1
- package/dist/{chunk-L7NE7PR4.cjs → chunk-DMCFARGP.cjs} +13 -13
- package/dist/{chunk-L7NE7PR4.cjs.map → chunk-DMCFARGP.cjs.map} +1 -1
- package/dist/{chunk-QM4AV6EG.js → chunk-HJLVWZOM.js} +4 -4
- package/dist/{chunk-QM4AV6EG.js.map → chunk-HJLVWZOM.js.map} +1 -1
- package/dist/{chunk-ZJMTHPHY.js → chunk-ICAYWVNF.js} +3 -3
- package/dist/{chunk-ZJMTHPHY.js.map → chunk-ICAYWVNF.js.map} +1 -1
- package/dist/{chunk-26GQO5I2.cjs → chunk-JYC2VV3Y.cjs} +12 -12
- package/dist/{chunk-26GQO5I2.cjs.map → chunk-JYC2VV3Y.cjs.map} +1 -1
- package/dist/{chunk-UCKA22ZJ.cjs → chunk-K63VPFOV.cjs} +9 -2
- package/dist/chunk-K63VPFOV.cjs.map +1 -0
- package/dist/{chunk-YWQH35VO.js → chunk-NOF6HJDV.js} +4 -4
- package/dist/{chunk-YWQH35VO.js.map → chunk-NOF6HJDV.js.map} +1 -1
- package/dist/{chunk-I2QGW4GD.js → chunk-OOYKKO3V.js} +11 -11
- package/dist/{chunk-I2QGW4GD.js.map → chunk-OOYKKO3V.js.map} +1 -1
- package/dist/{chunk-FKGUKFC7.cjs → chunk-OXUUE3HX.cjs} +5 -5
- package/dist/{chunk-FKGUKFC7.cjs.map → chunk-OXUUE3HX.cjs.map} +1 -1
- package/dist/{chunk-53YOZOGN.cjs → chunk-P5FGJMMI.cjs} +5 -5
- package/dist/{chunk-53YOZOGN.cjs.map → chunk-P5FGJMMI.cjs.map} +1 -1
- package/dist/{chunk-UAYWLYFW.cjs → chunk-QADR2XMQ.cjs} +18 -18
- package/dist/{chunk-UAYWLYFW.cjs.map → chunk-QADR2XMQ.cjs.map} +1 -1
- package/dist/{chunk-52GXJNQ3.js → chunk-QIA5FAAW.js} +8 -2
- package/dist/chunk-QIA5FAAW.js.map +1 -0
- package/dist/{chunk-EKBEKDWO.cjs → chunk-RJGCT35F.cjs} +13 -13
- package/dist/{chunk-EKBEKDWO.cjs.map → chunk-RJGCT35F.cjs.map} +1 -1
- package/dist/{chunk-33BQNWAQ.js → chunk-T33AJYLW.js} +5 -5
- package/dist/{chunk-33BQNWAQ.js.map → chunk-T33AJYLW.js.map} +1 -1
- package/dist/{chunk-EVBYEWHO.js → chunk-UHKZXOXD.js} +9 -2
- package/dist/chunk-UHKZXOXD.js.map +1 -0
- package/dist/{chunk-HA3VRF6E.js → chunk-UIGSH2XB.js} +3 -3
- package/dist/{chunk-HA3VRF6E.js.map → chunk-UIGSH2XB.js.map} +1 -1
- package/dist/{chunk-Z6TVOAO5.cjs → chunk-UISZWFI7.cjs} +8 -2
- package/dist/chunk-UISZWFI7.cjs.map +1 -0
- package/dist/{chunk-CE6OGJE6.js → chunk-UYRQEIB7.js} +5 -5
- package/dist/{chunk-CE6OGJE6.js.map → chunk-UYRQEIB7.js.map} +1 -1
- package/dist/{chunk-QEB6O6GU.js → chunk-W32ND3ZR.js} +6 -6
- package/dist/{chunk-QEB6O6GU.js.map → chunk-W32ND3ZR.js.map} +1 -1
- package/dist/{chunk-H6I2JDNW.js → chunk-WBLRUJ77.js} +10 -10
- package/dist/{chunk-H6I2JDNW.js.map → chunk-WBLRUJ77.js.map} +1 -1
- package/dist/{chunk-DP3DM7FR.cjs → chunk-WGIMLXRW.cjs} +6 -6
- package/dist/{chunk-DP3DM7FR.cjs.map → chunk-WGIMLXRW.cjs.map} +1 -1
- package/dist/{chunk-4H3JTX74.cjs → chunk-ZA5QUQ2V.cjs} +13 -13
- package/dist/{chunk-4H3JTX74.cjs.map → chunk-ZA5QUQ2V.cjs.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 +2 -2
- package/dist/components/ActivitySequence.d.ts +2 -2
- 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 +15 -11
- package/dist/components/InteractiveVideo.d.cts +50 -4
- package/dist/components/InteractiveVideo.d.ts +50 -4
- package/dist/components/InteractiveVideo.js +10 -10
- 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 +1 -1
- package/dist/components/PronunciationFeedback.d.ts +1 -1
- 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 +41 -37
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +15 -15
- package/dist/{strings-D0IWcsUm.d.ts → strings-Dgc5-DeA.d.ts} +21 -2
- package/dist/{strings-5588Q4Te.d.cts → strings-zY2QQYpU.d.cts} +21 -2
- package/dist/theme/ThemeProvider.cjs +6 -6
- package/dist/theme/ThemeProvider.js +1 -1
- package/dist/theme/defaults.css +7 -0
- package/dist/theme/skin.css +44 -6
- package/package.json +3 -3
- package/dist/chunk-2HAEQDHQ.js.map +0 -1
- package/dist/chunk-52GXJNQ3.js.map +0 -1
- package/dist/chunk-EVBYEWHO.js.map +0 -1
- package/dist/chunk-SRD4KVAP.cjs.map +0 -1
- package/dist/chunk-UCKA22ZJ.cjs.map +0 -1
- package/dist/chunk-Z6TVOAO5.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# @intellectif/lk-react
|
|
2
2
|
|
|
3
|
+
## 16.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 7992fac: `<InteractiveVideo>` shows two caption languages at once: a first line and, when the learner asks for
|
|
8
|
+
it, a second under it — the language they are learning and their own, one line each.
|
|
9
|
+
|
|
10
|
+
- **Settings → Captions → Second language** picks the second line; the captions row reads
|
|
11
|
+
`English + Español`. Picking the second line's language as the first swaps them. **C** turns both
|
|
12
|
+
lines off and on, keeping both choices; **Shift + C** turns the second line off and on, and is listed
|
|
13
|
+
in the shortcut sheet.
|
|
14
|
+
- Each line shows its own cue, so a translation segmented differently from the audio still reads
|
|
15
|
+
line for line. The transcript shows the second language under each row, paired by overlap, and its
|
|
16
|
+
search finds either language; the spoiler limit holds for both.
|
|
17
|
+
- Each language loads once for the life of the video, in parallel, and a late file never lands in a
|
|
18
|
+
line that has moved on to another language. A second language that fails to load never takes the
|
|
19
|
+
first with it, and the menu says which failed.
|
|
20
|
+
- **`defaultPreferences`** (new): preferences a host suggests, below what the learner chose — a
|
|
21
|
+
language pair, say. `preferences` keeps its meaning and is now documented as a force.
|
|
22
|
+
**`onPreferencesChange(next, change)`** (new) reports each change the learner makes, for a host that
|
|
23
|
+
keeps the choice on the learner's account and passes it back as `defaultPreferences`.
|
|
24
|
+
`VideoPreferences` gains `secondaryCaptionLanguage`. The player now stores only the fields a learner
|
|
25
|
+
changed, so a host suggestion still reaches a learner who never chose that field; a payload stored
|
|
26
|
+
by 15.x reads as every field chosen.
|
|
27
|
+
- **`resolveCaptionTracks(tracks, preferences)`** (new export): the rules the player uses to choose
|
|
28
|
+
each line's track. A language now matches its regional tracks (`pt` finds `pt-BR`), and where two
|
|
29
|
+
tracks share a language the `captions` one wins. A second line appears only when the learner asked
|
|
30
|
+
for one — never a fallback.
|
|
31
|
+
- `dir="auto"` on every caption line, transcript row and menu item that shows a track's text, so an
|
|
32
|
+
Arabic line's punctuation lands on the right side.
|
|
33
|
+
- Four optional tokens style the lines: `--lk-iv-caption-color`, `--lk-iv-caption-secondary-color`
|
|
34
|
+
(warm yellow, clearing 4.5:1 on the caption box), `--lk-iv-caption-secondary-scale` and
|
|
35
|
+
`--lk-iv-caption-gap`. The second line differs by position and size as well as colour. Four new
|
|
36
|
+
strings, all in `docs/i18n.md`.
|
|
37
|
+
|
|
38
|
+
**One DOM change, for hosts that style the captions:** the lines now sit inside a
|
|
39
|
+
`<div class="lk-iv-captions">`, which is what is positioned over the video and rises with the
|
|
40
|
+
controls. Each line keeps `.lk-iv-caption`, its `span`, `data-size` and `data-background` (and gains
|
|
41
|
+
`data-role`, `lang` and `dir`), so rules that style a line's text still match. A rule that positions
|
|
42
|
+
`.lk-iv-caption` over the video should move to `.lk-iv-captions`.
|
|
43
|
+
|
|
44
|
+
**Major** because the peer range moves to `@intellectif/lk-core@^0.16.0`, whose tightened dictation
|
|
45
|
+
rule can refuse stored content. Nothing in this package was removed.
|
|
46
|
+
|
|
47
|
+
See `docs/interactive-video.md` and the 0.15 → 0.16 section of `docs/upgrading.md`.
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- Updated dependencies [7992fac]
|
|
52
|
+
- @intellectif/lk-core@0.16.0
|
|
53
|
+
|
|
3
54
|
## 15.0.0
|
|
4
55
|
|
|
5
56
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ export function Demo() {
|
|
|
72
72
|
- **`<ReadAloud>`** — the learner reads a text aloud. A model recording and an optional slower one (same playback policy, and both kept silent for as long as a take is being recorded, so the microphone never picks up the model), a microphone control bounded by the item's take budget and its time limit, playback of the take before it is sent, and a word-by-word pronunciation result. The SDK captures and renders; it stores nothing and judges nothing: `recordingBinding.upload` puts the take in **your** storage and `recordingBinding.assess` (`practice` only) returns **your** server's judgement, so no audio, no key and no assessor ever sit in the component. In `exam` it uploads, submits and locks without scoring, revealing or assessing — and a take whose upload failed offers a retry and blocks submit rather than silently becoming a blank. In `review` it renders the stored `outcome`, marked from an `assessment` you pass or, failing that, rebuilt from the outcome's stored `details`.
|
|
73
73
|
- **`<PronunciationFeedback>`** — the marks on their own, for a review screen that has evidence but no activity: the graded dimensions (accuracy, fluency, completeness, prosody — one the engine did not measure reads "not assessed", **never 0%**), and every word marked `correct` / `mispronounced` / `omitted` / `inserted` with a hidden sentence per word for screen readers and a glyph plus a text decoration for everyone else. A word opens onto its syllables, its sounds, what was heard instead, and a button that plays just that word. Evidence it cannot trust is checked before it is aligned, so in production a malformed assessment costs the word list — never the grade beside it.
|
|
74
74
|
- **`<WrittenResponse>`** — free-text writing with a live word counter and bounds messaging, graded **asynchronously**: it emits an ungraded submission (never a fake zero) and a SUBMITTED-verb xAPI statement, and renders a returned `GradeRecord` in `review` mode with per-criterion scores and inline corrections.
|
|
75
|
-
- **`<InteractiveVideo>`** — a video that stops at each quiz and asks its questions over itself, then plays on. One player: a progress bar that marks every quiz and previews the caption under the pointer, speed, volume, captions drawn from WebVTT it parses itself (through a `captionsLoader` when the file needs the learner's credentials), a contents and transcript panel, picture-in-picture, fullscreen and a keyboard map with a shortcut sheet. A quiz covers the video and grows the player rather than scrolling inside it, every question of an opened quiz stays mounted so a rewind loses no answer, the controls are `inert` while it is open, and a **required** quiz holds both playback and seeking until it is answered. Answers report with the slot the question sits in and the quiz it belongs to, and `onProgress` gives a resume point that is never past an unanswered required quiz. See the [interactive video guide](https://github.com/intellectif/learning-kit/blob/main/docs/interactive-video.md).
|
|
75
|
+
- **`<InteractiveVideo>`** — a video that stops at each quiz and asks its questions over itself, then plays on. One player: a progress bar that marks every quiz and previews the caption under the pointer, speed, volume, captions drawn from WebVTT it parses itself (through a `captionsLoader` when the file needs the learner's credentials) — in one language or two at once, a second line under the first for a learner matching what they hear to what it means — a contents and transcript panel, picture-in-picture, fullscreen and a keyboard map with a shortcut sheet. A quiz covers the video and grows the player rather than scrolling inside it, every question of an opened quiz stays mounted so a rewind loses no answer, the controls are `inert` while it is open, and a **required** quiz holds both playback and seeking until it is answered. Answers report with the slot the question sits in and the quiz it belongs to, and `onProgress` gives a resume point that is never past an unanswered required quiz. See the [interactive video guide](https://github.com/intellectif/learning-kit/blob/main/docs/interactive-video.md).
|
|
76
76
|
- **`<ActivitySequence>`** — in-place "question set" pager (Previous/Next, "Question X of N", no scrolling, focus-managed). Accepts item groups and keeps their stimulus beside every question; `onSubmit` reports every raw answer with its `slotId`, which is the only response channel an `exam` sequence has. `onFinished` is the completion signal for a set that mixes scored and deferred-graded items, where `onComplete` can never fire. A read-aloud slot takes its storage from `recordingBinding`, whose methods are told which slot a take belongs to, and a `review` its per-word marks from `assessments`, keyed by `slotId` — there is a [worked example](https://github.com/intellectif/learning-kit/blob/main/docs/speech-assessment.md#in-a-question-set).
|
|
77
77
|
- **Resume and review a whole attempt** — `<ActivitySequence>` takes `defaultIndex`, `responses` and `submittedSlotIds` (read at mount; remount with a `key` to show a different attempt), so an interrupted paper reopens on the right question with the right answers and already-committed questions still committed. `onIndexChange` reports every position the pager lands on, including a clamp it had to apply. Pass `renderMode="review"` plus server-computed `outcomes` to render a finished attempt read-only. Pairs with `serializeAttemptState` / `restoreAttemptState` in `lk-core`.
|
|
78
78
|
- **`renderMode`** — `practice` (default: the component scores locally and reveals correctness), `exam` (never scores, never reveals; submit emits the raw response for the server to grade), `review` (read-only, marks correctness only from an `outcome` you supply). This is the single switch that takes grading off the client.
|
|
@@ -91,7 +91,7 @@ export function Demo() {
|
|
|
91
91
|
- **`useSpeechRecorder(options)`** — the capture half of a read-aloud, usable on its own: microphone permission, an RMS level for a meter, a minimum take length, and an auto-stop measured from the **sample count** rather than a timer, so a take can never outrun its own limit. It yields **16 kHz mono 16-bit PCM WAV** — the one format `inspectWav` in `lk-core` measures without a decoder. SSR-safe by construction (support is discovered inside `start()`, never probed during render, so a server render and its hydration cannot disagree), and the microphone and the audio context are released on stop, discard, error and unmount alike. Where a Content-Security-Policy's `script-src` does not allow `blob:`, serve `CAPTURE_PROCESSOR_SOURCE` — exported beside the hook, with the contract it meets written on it — and pass its URL as `workletUrl`. A `workletUrl` that fails to load is not reported: the hook falls back to the main-thread `ScriptProcessorNode`, so check that the module is fetched.
|
|
92
92
|
- **`<ThemeProvider>` + `defaults.css`** — `--lk-*` design-token system; automatic dark mode via `prefers-color-scheme` (SSR-safe with `useSyncExternalStore`).
|
|
93
93
|
- **`createTailwindTheme(theme)`** — optional Tailwind interop; consume the SDK palette from your own utilities.
|
|
94
|
-
- **`<LkIntlProvider>`** — all
|
|
94
|
+
- **`<LkIntlProvider>`** — all 167 strings the SDK's own chrome renders, replaceable in one place, with a per-component `strings` prop for the exceptions. Interpolation and plurals are **functions**, not format strings, so your `Intl.PluralRules` does the work and TypeScript checks the arity. `locale` sets `lang` and derives `dir`; the skin uses logical properties, so RTL follows. The SDK ships the mechanism and **English only** — see [docs/i18n.md](https://github.com/intellectif/learning-kit/blob/main/docs/i18n.md).
|
|
95
95
|
- **WCAG 2.2 AA** — axe-clean unit + Playwright e2e tests; full keyboard operability; numerically-verified contrast.
|
|
96
96
|
- **RSC-compatible** — every component carries `'use client'` and hydrates inside a React Server Component tree.
|
|
97
97
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { XAPIStatement, WrittenResponseData, LearnerResponse, ItemOutcome, InteractionEvent, ThemeTokens } from '@intellectif/lk-core';
|
|
2
|
-
import { f as Renderable, e as RenderMode, H as HtmlSanitizer, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from './strings-
|
|
2
|
+
import { f as Renderable, e as RenderMode, H as HtmlSanitizer, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from './strings-zY2QQYpU.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Payload delivered when the learner submits a written response. Grading is
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { XAPIStatement, WrittenResponseData, LearnerResponse, ItemOutcome, InteractionEvent, ThemeTokens } from '@intellectif/lk-core';
|
|
2
|
-
import { f as Renderable, e as RenderMode, H as HtmlSanitizer, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from './strings-
|
|
2
|
+
import { f as Renderable, e as RenderMode, H as HtmlSanitizer, M as MediaBudgetBinding, b as MediaTransportStrings, a as LkStringsOverride } from './strings-Dgc5-DeA.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Payload delivered when the learner submits a written response. Grading is
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkBO64SLHL_cjs = require('./chunk-BO64SLHL.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 chunkP5FGJMMI_cjs = require('./chunk-P5FGJMMI.cjs');
|
|
9
|
+
var chunkOXUUE3HX_cjs = require('./chunk-OXUUE3HX.cjs');
|
|
10
10
|
var chunkXOR4MPEN_cjs = require('./chunk-XOR4MPEN.cjs');
|
|
11
|
-
var
|
|
11
|
+
var chunkUISZWFI7_cjs = require('./chunk-UISZWFI7.cjs');
|
|
12
12
|
var lkCore = require('@intellectif/lk-core');
|
|
13
13
|
var react = require('react');
|
|
14
14
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -172,7 +172,7 @@ function OutcomeSummary({
|
|
|
172
172
|
"data-status": reading.status,
|
|
173
173
|
"data-passed": String(reading.grade.passed),
|
|
174
174
|
children: scoreShown ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
175
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.scoreAnnouncement(
|
|
175
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade", children: s.scoreAnnouncement(chunkBO64SLHL_cjs.percentOfGrade(reading.grade), reading.grade.passed) }),
|
|
176
176
|
reading.grade.feedback ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-grade-feedback", dir: "auto", children: reading.grade.feedback }) : null
|
|
177
177
|
] })
|
|
178
178
|
}
|
|
@@ -224,11 +224,11 @@ function ReadAloud({
|
|
|
224
224
|
}) {
|
|
225
225
|
const isExam = renderMode === "exam";
|
|
226
226
|
const isReview = renderMode === "review";
|
|
227
|
-
const s =
|
|
227
|
+
const s = chunkUISZWFI7_cjs.useLkStrings(strings);
|
|
228
228
|
const slot = react.useContext(SequenceSlotContext);
|
|
229
229
|
const captureGroup = slot?.captureGroup;
|
|
230
230
|
const devError = react.useMemo(() => {
|
|
231
|
-
if (!
|
|
231
|
+
if (!chunkP5FGJMMI_cjs.isDevelopment()) {
|
|
232
232
|
return null;
|
|
233
233
|
}
|
|
234
234
|
if (data.redacted === true) {
|
|
@@ -419,7 +419,7 @@ function ReadAloud({
|
|
|
419
419
|
[data, s.readAloudSlowRecording]
|
|
420
420
|
);
|
|
421
421
|
const takeAudio = isReview ? playbackUrl : takeUrl;
|
|
422
|
-
const playback =
|
|
422
|
+
const playback = chunkBO64SLHL_cjs.usePlaybackRefusal(takeAudio);
|
|
423
423
|
const submitRef = react.useRef(null);
|
|
424
424
|
if (devError) {
|
|
425
425
|
throw devError;
|
|
@@ -466,7 +466,7 @@ function ReadAloud({
|
|
|
466
466
|
if (run !== runRef.current) {
|
|
467
467
|
return;
|
|
468
468
|
}
|
|
469
|
-
const result =
|
|
469
|
+
const result = chunkBO64SLHL_cjs.readAssessResult(answer);
|
|
470
470
|
if (result.status === "failed") {
|
|
471
471
|
raise({ kind: "assess-failed", take: take2, retryable: result.retryable });
|
|
472
472
|
fire("assessment-failed", { takes: takes2, durationMs, retryable: result.retryable });
|
|
@@ -497,9 +497,9 @@ function ReadAloud({
|
|
|
497
497
|
passed: grade.passed,
|
|
498
498
|
timeSpent,
|
|
499
499
|
xapiStatement: lkCore.xAPIBuilder.buildAnsweredStatement({
|
|
500
|
-
actor:
|
|
500
|
+
actor: chunkP5FGJMMI_cjs.ANONYMOUS_ACTOR,
|
|
501
501
|
object: {
|
|
502
|
-
id:
|
|
502
|
+
id: chunkP5FGJMMI_cjs.objectIdFor(data.id),
|
|
503
503
|
name: { [data.locale ?? "en-US"]: data.title },
|
|
504
504
|
...lkCore.xapiDefinitionFor(data)
|
|
505
505
|
},
|
|
@@ -509,7 +509,7 @@ function ReadAloud({
|
|
|
509
509
|
// optional, and an empty list is the honest reading of "no per-word
|
|
510
510
|
// marks were stored" — never a mark of its own.
|
|
511
511
|
scoringResult: {
|
|
512
|
-
score:
|
|
512
|
+
score: chunkBO64SLHL_cjs.fractionOfGrade(grade),
|
|
513
513
|
maxScore: 1,
|
|
514
514
|
passed: grade.passed,
|
|
515
515
|
feedback: grade.feedback,
|
|
@@ -603,8 +603,8 @@ function ReadAloud({
|
|
|
603
603
|
};
|
|
604
604
|
const contentLang = typeof data.locale === "string" ? data.locale : void 0;
|
|
605
605
|
const contentDir = chunkOD65OZIW_cjs.localeDirectionOf(data.locale);
|
|
606
|
-
const outcomeReading = react.useMemo(() =>
|
|
607
|
-
const keptEvidence = react.useMemo(() =>
|
|
606
|
+
const outcomeReading = react.useMemo(() => chunkBO64SLHL_cjs.readOutcome(outcome), [outcome]);
|
|
607
|
+
const keptEvidence = react.useMemo(() => chunkBO64SLHL_cjs.readEvidence(assessment), [assessment]);
|
|
608
608
|
const storedGrade = outcomeReading?.kind === "graded" && outcomeReading.status === "graded" ? outcomeReading.grade : null;
|
|
609
609
|
const storedMarks = react.useMemo(
|
|
610
610
|
() => isReview && keptEvidence === null && storedGrade?.details !== void 0 ? marksFromDetails(storedGrade.details) : null,
|
|
@@ -646,7 +646,7 @@ function ReadAloud({
|
|
|
646
646
|
case "graded": {
|
|
647
647
|
const grade = phase.grade;
|
|
648
648
|
return grade === null ? { text: `${s.answerSubmitted} ${s.couldNotBeGraded}`, feedback: null } : {
|
|
649
|
-
text: `${s.answerSubmitted} ${s.scoreAnnouncement(
|
|
649
|
+
text: `${s.answerSubmitted} ${s.scoreAnnouncement(chunkBO64SLHL_cjs.percentOfGrade(grade), grade.passed)}`,
|
|
650
650
|
feedback: grade.feedback
|
|
651
651
|
};
|
|
652
652
|
}
|
|
@@ -679,7 +679,7 @@ function ReadAloud({
|
|
|
679
679
|
data.media !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "lk-ra-model", children: [
|
|
680
680
|
/* @__PURE__ */ jsxRuntime.jsx("legend", { className: "lk-ra-model-label", children: s.readAloudModelRecording }),
|
|
681
681
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
682
|
-
|
|
682
|
+
chunkOXUUE3HX_cjs.ActivityMedia,
|
|
683
683
|
{
|
|
684
684
|
media: data.media,
|
|
685
685
|
renderMode,
|
|
@@ -696,7 +696,7 @@ function ReadAloud({
|
|
|
696
696
|
slowMedia !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: "lk-ra-model", "data-slow": "true", children: [
|
|
697
697
|
/* @__PURE__ */ jsxRuntime.jsx("legend", { className: "lk-ra-model-label", children: s.readAloudSlowRecording }),
|
|
698
698
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
699
|
-
|
|
699
|
+
chunkOXUUE3HX_cjs.ActivityMedia,
|
|
700
700
|
{
|
|
701
701
|
media: slowMedia,
|
|
702
702
|
renderMode,
|
|
@@ -829,7 +829,7 @@ function ReadAloud({
|
|
|
829
829
|
busy ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-pending", role: "status", "aria-busy": "true", children: phase.kind === "uploading" ? s.readAloudUploading : s.readAloudAssessing }) : null,
|
|
830
830
|
alertText !== null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-ra-alert", role: "alert", children: alertText }, errorNonce) : null,
|
|
831
831
|
feedbackAssessment !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
832
|
-
|
|
832
|
+
chunkBO64SLHL_cjs.PronunciationFeedback,
|
|
833
833
|
{
|
|
834
834
|
data: { referenceText: data.referenceText, locale: data.locale },
|
|
835
835
|
assessment: feedbackAssessment,
|
|
@@ -843,14 +843,14 @@ function ReadAloud({
|
|
|
843
843
|
) : null,
|
|
844
844
|
storedMarks !== null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lk-ra-marks", children: [
|
|
845
845
|
/* @__PURE__ */ jsxRuntime.jsx("ol", { className: "lk-ra-words", "aria-label": s.pronunciationWordsLabel, dir: contentDir, children: storedMarks.map((entry, index) => {
|
|
846
|
-
const sentence =
|
|
846
|
+
const sentence = chunkBO64SLHL_cjs.markSentence(entry, s);
|
|
847
847
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
848
848
|
"li",
|
|
849
849
|
{
|
|
850
850
|
className: "lk-ra-word",
|
|
851
851
|
"data-state": entry.state,
|
|
852
852
|
children: [
|
|
853
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style:
|
|
853
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style: chunkBO64SLHL_cjs.VISUALLY_HIDDEN, children: sentence }),
|
|
854
854
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
855
855
|
"span",
|
|
856
856
|
{
|
|
@@ -874,15 +874,15 @@ function ReadAloud({
|
|
|
874
874
|
// but a live region is the only thing that TELLS a screen-reader
|
|
875
875
|
// learner a grade arrived, since nothing takes focus. Clipped rather
|
|
876
876
|
// than `display: none`, which would stop it being announced at all.
|
|
877
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style:
|
|
877
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lk-visually-hidden", style: chunkBO64SLHL_cjs.VISUALLY_HIDDEN, children: /* @__PURE__ */ jsxRuntime.jsx(AnnouncementText, { announcement }) })
|
|
878
878
|
) : /* @__PURE__ */ jsxRuntime.jsx(AnnouncementText, { announcement }) })
|
|
879
879
|
]
|
|
880
880
|
}
|
|
881
881
|
);
|
|
882
882
|
}
|
|
883
883
|
function ReadAloud2(props) {
|
|
884
|
-
const strings =
|
|
885
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
884
|
+
const strings = chunkUISZWFI7_cjs.useLkStrings(props.strings);
|
|
885
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkP5FGJMMI_cjs.ActivityErrorBoundary, { activityTitle: props.data?.title, strings, children: /* @__PURE__ */ jsxRuntime.jsx(ReadAloud, { ...props }) });
|
|
886
886
|
}
|
|
887
887
|
|
|
888
888
|
exports.ReadAloud = ReadAloud2;
|
|
@@ -890,5 +890,5 @@ exports.SequenceSlotContext = SequenceSlotContext;
|
|
|
890
890
|
exports.mintTake = mintTake;
|
|
891
891
|
exports.stopCaptureGroup = stopCaptureGroup;
|
|
892
892
|
exports.takeOf = takeOf;
|
|
893
|
-
//# sourceMappingURL=chunk-
|
|
894
|
-
//# sourceMappingURL=chunk-
|
|
893
|
+
//# sourceMappingURL=chunk-2WM2KSO7.cjs.map
|
|
894
|
+
//# sourceMappingURL=chunk-2WM2KSO7.cjs.map
|