@intellectif/lk-react 23.1.0 → 23.1.2
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 +23 -0
- package/README.md +9 -5
- package/dist/ActivityErrorBoundary-B379hvtL.cjs +39 -0
- package/dist/ActivityErrorBoundary-B379hvtL.cjs.map +1 -0
- package/dist/ActivityErrorBoundary-Dw6SbWv3.js +34 -0
- package/dist/ActivityErrorBoundary-Dw6SbWv3.js.map +1 -0
- package/dist/ActivityMedia-CQQTRNl7.cjs +641 -0
- package/dist/ActivityMedia-CQQTRNl7.cjs.map +1 -0
- package/dist/ActivityMedia-vDiP-Psa.js +636 -0
- package/dist/ActivityMedia-vDiP-Psa.js.map +1 -0
- package/dist/ActivityPreview-1hhTkYuj.js +240 -0
- package/dist/ActivityPreview-1hhTkYuj.js.map +1 -0
- package/dist/ActivityPreview-BKr34exz.cjs +245 -0
- package/dist/ActivityPreview-BKr34exz.cjs.map +1 -0
- package/dist/ActivitySequence-CkX87pfB.js +839 -0
- package/dist/ActivitySequence-CkX87pfB.js.map +1 -0
- package/dist/ActivitySequence-CmoSyDnp.cjs +844 -0
- package/dist/ActivitySequence-CmoSyDnp.cjs.map +1 -0
- package/dist/Dictation-BlxRp-3k.js +926 -0
- package/dist/Dictation-BlxRp-3k.js.map +1 -0
- package/dist/Dictation-jECzL88E.cjs +931 -0
- package/dist/Dictation-jECzL88E.cjs.map +1 -0
- package/dist/FeedbackRegion-BNNMtTY-.cjs +108 -0
- package/dist/FeedbackRegion-BNNMtTY-.cjs.map +1 -0
- package/dist/FeedbackRegion-CyPSp8bA.js +85 -0
- package/dist/FeedbackRegion-CyPSp8bA.js.map +1 -0
- package/dist/FillInTheBlanks-B6xzqYXx.js +474 -0
- package/dist/FillInTheBlanks-B6xzqYXx.js.map +1 -0
- package/dist/FillInTheBlanks-BpKhdHg2.cjs +479 -0
- package/dist/FillInTheBlanks-BpKhdHg2.cjs.map +1 -0
- package/dist/GapSelect-DUSiaEQH.js +441 -0
- package/dist/GapSelect-DUSiaEQH.js.map +1 -0
- package/dist/GapSelect-payTq_Zn.cjs +446 -0
- package/dist/GapSelect-payTq_Zn.cjs.map +1 -0
- package/dist/InteractiveVideo-BguGv-HA.cjs +2955 -0
- package/dist/InteractiveVideo-BguGv-HA.cjs.map +1 -0
- package/dist/InteractiveVideo-Cg2jbU3j.js +2944 -0
- package/dist/InteractiveVideo-Cg2jbU3j.js.map +1 -0
- package/dist/LkAiProvider-DAPpA3PQ.d.cts +84 -0
- package/dist/LkAiProvider-DAPpA3PQ.d.cts.map +1 -0
- package/dist/LkAiProvider-QdEcIhoo.d.ts +84 -0
- package/dist/LkAiProvider-QdEcIhoo.d.ts.map +1 -0
- package/dist/LkIntlProvider-D_FdYXjQ.js +375 -0
- package/dist/LkIntlProvider-D_FdYXjQ.js.map +1 -0
- package/dist/LkIntlProvider-oi57lYB0.cjs +410 -0
- package/dist/LkIntlProvider-oi57lYB0.cjs.map +1 -0
- package/dist/MultipleChoice-COn5MtKY.cjs +433 -0
- package/dist/MultipleChoice-COn5MtKY.cjs.map +1 -0
- package/dist/MultipleChoice-Dra0_KYD.js +428 -0
- package/dist/MultipleChoice-Dra0_KYD.js.map +1 -0
- package/dist/PronunciationFeedback-DlMPGjkR.cjs +831 -0
- package/dist/PronunciationFeedback-DlMPGjkR.cjs.map +1 -0
- package/dist/PronunciationFeedback-Dxd6XPkO.js +772 -0
- package/dist/PronunciationFeedback-Dxd6XPkO.js.map +1 -0
- package/dist/ReadAloud-C8RhaUqV.js +1092 -0
- package/dist/{chunk-DC4CQCK5.js.map → ReadAloud-C8RhaUqV.js.map} +1 -1
- package/dist/ReadAloud-akDehitT.cjs +1103 -0
- package/dist/ReadAloud-akDehitT.cjs.map +1 -0
- package/dist/StimulusPanel-BgzByfkb.js +74 -0
- package/dist/StimulusPanel-BgzByfkb.js.map +1 -0
- package/dist/StimulusPanel-b66gaN3i.cjs +79 -0
- package/dist/StimulusPanel-b66gaN3i.cjs.map +1 -0
- package/dist/ThemeProvider-B6DyGqzh.d.cts +62 -0
- package/dist/ThemeProvider-B6DyGqzh.d.cts.map +1 -0
- package/dist/ThemeProvider-BCrxBaY-.d.ts +62 -0
- package/dist/ThemeProvider-BCrxBaY-.d.ts.map +1 -0
- package/dist/ThemeProvider-BRN1tj4n.cjs +187 -0
- package/dist/ThemeProvider-BRN1tj4n.cjs.map +1 -0
- package/dist/ThemeProvider-C7K9iMLX.js +158 -0
- package/dist/ThemeProvider-C7K9iMLX.js.map +1 -0
- package/dist/WrittenResponse-Bj3eFmGl.cjs +491 -0
- package/dist/WrittenResponse-Bj3eFmGl.cjs.map +1 -0
- package/dist/WrittenResponse-Cl8G6nO_.js +486 -0
- package/dist/WrittenResponse-Cl8G6nO_.js.map +1 -0
- package/dist/ai/LkAiProvider.cjs +34 -14
- package/dist/ai/LkAiProvider.cjs.map +1 -1
- package/dist/ai/LkAiProvider.d.cts +2 -83
- package/dist/ai/LkAiProvider.d.ts +2 -83
- package/dist/ai/LkAiProvider.js +33 -2
- package/dist/ai/LkAiProvider.js.map +1 -1
- package/dist/ai/useAiHelp.cjs +7 -25
- package/dist/ai/useAiHelp.d.cts +175 -177
- package/dist/ai/useAiHelp.d.cts.map +1 -0
- package/dist/ai/useAiHelp.d.ts +175 -177
- package/dist/ai/useAiHelp.d.ts.map +1 -0
- package/dist/ai/useAiHelp.js +3 -4
- package/dist/components/ActivityPreview.cjs +3 -29
- package/dist/components/ActivityPreview.d.cts +2 -81
- package/dist/components/ActivityPreview.d.ts +2 -81
- package/dist/components/ActivityPreview.js +2 -20
- package/dist/components/ActivitySequence.cjs +3 -30
- package/dist/components/ActivitySequence.d.cts +2 -432
- package/dist/components/ActivitySequence.d.ts +2 -432
- package/dist/components/ActivitySequence.js +2 -21
- package/dist/components/Dictation.cjs +4 -21
- package/dist/components/Dictation.d.cts +2 -19
- package/dist/components/Dictation.d.ts +2 -19
- package/dist/components/Dictation.js +3 -12
- package/dist/components/FillInTheBlanks.cjs +4 -20
- package/dist/components/FillInTheBlanks.d.cts +2 -30
- package/dist/components/FillInTheBlanks.d.ts +2 -30
- package/dist/components/FillInTheBlanks.js +3 -11
- package/dist/components/GapSelect.cjs +4 -20
- package/dist/components/GapSelect.d.cts +2 -27
- package/dist/components/GapSelect.d.ts +2 -27
- package/dist/components/GapSelect.js +3 -11
- package/dist/components/InteractiveVideo.cjs +5 -32
- package/dist/components/InteractiveVideo.d.cts +3 -291
- package/dist/components/InteractiveVideo.d.ts +3 -291
- package/dist/components/InteractiveVideo.js +3 -19
- package/dist/components/MultipleChoice.cjs +4 -20
- package/dist/components/MultipleChoice.d.cts +2 -26
- package/dist/components/MultipleChoice.d.ts +2 -26
- package/dist/components/MultipleChoice.js +3 -11
- package/dist/components/PronunciationFeedback.cjs +4 -17
- package/dist/components/PronunciationFeedback.d.cts +2 -90
- package/dist/components/PronunciationFeedback.d.ts +2 -90
- package/dist/components/PronunciationFeedback.js +3 -8
- package/dist/components/ReadAloud.cjs +4 -22
- package/dist/components/ReadAloud.d.cts +7 -11
- package/dist/components/ReadAloud.d.cts.map +1 -0
- package/dist/components/ReadAloud.d.ts +7 -11
- package/dist/components/ReadAloud.d.ts.map +1 -0
- package/dist/components/ReadAloud.js +3 -13
- package/dist/components/StimulusPanel.cjs +3 -14
- package/dist/components/StimulusPanel.d.cts +2 -51
- package/dist/components/StimulusPanel.d.ts +2 -51
- package/dist/components/StimulusPanel.js +2 -5
- package/dist/components/WrittenResponse.cjs +4 -19
- package/dist/components/WrittenResponse.d.cts +3 -18
- package/dist/components/WrittenResponse.d.ts +3 -18
- package/dist/components/WrittenResponse.js +3 -10
- package/dist/direction-Dq0_HtA5.js +183 -0
- package/dist/direction-Dq0_HtA5.js.map +1 -0
- package/dist/direction-K1pj0HCA.cjs +200 -0
- package/dist/direction-K1pj0HCA.cjs.map +1 -0
- package/dist/hooks/useActivityState.cjs +28 -10
- package/dist/hooks/useActivityState.cjs.map +1 -1
- package/dist/hooks/useActivityState.d.cts +25 -24
- package/dist/hooks/useActivityState.d.cts.map +1 -0
- package/dist/hooks/useActivityState.d.ts +25 -24
- package/dist/hooks/useActivityState.d.ts.map +1 -0
- package/dist/hooks/useActivityState.js +28 -2
- package/dist/hooks/useActivityState.js.map +1 -1
- package/dist/hooks/useSpeechRecorder.cjs +5 -16
- package/dist/hooks/useSpeechRecorder.d.cts +2 -127
- package/dist/hooks/useSpeechRecorder.d.ts +2 -127
- package/dist/hooks/useSpeechRecorder.js +3 -3
- package/dist/hooks/useXAPI.cjs +126 -10
- package/dist/hooks/useXAPI.cjs.map +1 -1
- package/dist/hooks/useXAPI.d.cts +14 -14
- package/dist/hooks/useXAPI.d.cts.map +1 -0
- package/dist/hooks/useXAPI.d.ts +14 -14
- package/dist/hooks/useXAPI.d.ts.map +1 -0
- package/dist/hooks/useXAPI.js +126 -2
- package/dist/hooks/useXAPI.js.map +1 -1
- package/dist/i18n/LkIntlProvider.cjs +9 -32
- package/dist/i18n/LkIntlProvider.d.cts +34 -38
- package/dist/i18n/LkIntlProvider.d.cts.map +1 -0
- package/dist/i18n/LkIntlProvider.d.ts +34 -38
- package/dist/i18n/LkIntlProvider.d.ts.map +1 -0
- package/dist/i18n/LkIntlProvider.js +3 -3
- package/dist/index-6P4rJHrJ.d.cts +432 -0
- package/dist/index-6P4rJHrJ.d.cts.map +1 -0
- package/dist/index-90CX504k.d.ts +90 -0
- package/dist/index-90CX504k.d.ts.map +1 -0
- package/dist/index-B_SgnjsC.d.cts +291 -0
- package/dist/index-B_SgnjsC.d.cts.map +1 -0
- package/dist/index-BavVW5z5.d.cts +25 -0
- package/dist/index-BavVW5z5.d.cts.map +1 -0
- package/dist/index-BhHv6Fiu.d.cts +28 -0
- package/dist/index-BhHv6Fiu.d.cts.map +1 -0
- package/dist/index-Bsu8VciA.d.ts +432 -0
- package/dist/index-Bsu8VciA.d.ts.map +1 -0
- package/dist/index-C1KGpD1k.d.ts +49 -0
- package/dist/index-C1KGpD1k.d.ts.map +1 -0
- package/dist/index-CKTpYTCC.d.cts +49 -0
- package/dist/index-CKTpYTCC.d.cts.map +1 -0
- package/dist/index-CO_SRFJj.d.ts +16 -0
- package/dist/index-CO_SRFJj.d.ts.map +1 -0
- package/dist/index-CSsuUsP7.d.cts +124 -0
- package/dist/index-CSsuUsP7.d.cts.map +1 -0
- package/dist/index-CunUyeuN.d.cts +78 -0
- package/dist/index-CunUyeuN.d.cts.map +1 -0
- package/dist/index-CzfRzks6.d.cts +90 -0
- package/dist/index-CzfRzks6.d.cts.map +1 -0
- package/dist/index-D14xtpBS.d.cts +24 -0
- package/dist/index-D14xtpBS.d.cts.map +1 -0
- package/dist/index-DHRPAPZf.d.ts +291 -0
- package/dist/index-DHRPAPZf.d.ts.map +1 -0
- package/dist/index-DLV6cK26.d.cts +16 -0
- package/dist/index-DLV6cK26.d.cts.map +1 -0
- package/dist/index-DbCCQ9cP.d.ts +124 -0
- package/dist/index-DbCCQ9cP.d.ts.map +1 -0
- package/dist/index-DeV5B2m5.d.ts +24 -0
- package/dist/index-DeV5B2m5.d.ts.map +1 -0
- package/dist/index-TZCJVSge.d.ts +28 -0
- package/dist/index-TZCJVSge.d.ts.map +1 -0
- package/dist/index-ZVvLHsd3.d.ts +25 -0
- package/dist/index-ZVvLHsd3.d.ts.map +1 -0
- package/dist/index-eQwBgpSw.d.ts +78 -0
- package/dist/index-eQwBgpSw.d.ts.map +1 -0
- package/dist/index.cjs +118 -163
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -24
- package/dist/index.d.ts +20 -24
- package/dist/index.js +84 -29
- package/dist/index.js.map +1 -1
- package/dist/theme/ThemeProvider.cjs +8 -28
- package/dist/theme/ThemeProvider.d.cts +2 -59
- package/dist/theme/ThemeProvider.d.ts +2 -59
- package/dist/theme/ThemeProvider.js +3 -3
- package/dist/tries-CbbtZkdG.cjs +363 -0
- package/dist/tries-CbbtZkdG.cjs.map +1 -0
- package/dist/tries-DTHSrLCm.js +310 -0
- package/dist/tries-DTHSrLCm.js.map +1 -0
- package/dist/types-BOQd93x3.d.cts +994 -0
- package/dist/types-BOQd93x3.d.cts.map +1 -0
- package/dist/types-HIrgF_mS.d.ts +994 -0
- package/dist/types-HIrgF_mS.d.ts.map +1 -0
- package/dist/useAiHelp-B-ccDL5Q.js +906 -0
- package/dist/useAiHelp-B-ccDL5Q.js.map +1 -0
- package/dist/useAiHelp-h9yOLFqt.cjs +995 -0
- package/dist/useAiHelp-h9yOLFqt.cjs.map +1 -0
- package/dist/useSpeechRecorder--O_f-xvt.cjs +720 -0
- package/dist/useSpeechRecorder--O_f-xvt.cjs.map +1 -0
- package/dist/useSpeechRecorder-DtAYvl02.d.cts +154 -0
- package/dist/useSpeechRecorder-DtAYvl02.d.cts.map +1 -0
- package/dist/useSpeechRecorder-DtAYvl02.d.ts +154 -0
- package/dist/useSpeechRecorder-DtAYvl02.d.ts.map +1 -0
- package/dist/useSpeechRecorder-zIi9Dlw8.js +709 -0
- package/dist/useSpeechRecorder-zIi9Dlw8.js.map +1 -0
- package/package.json +10 -11
- package/dist/WrittenResponse-B7A5gHMj.d.ts +0 -115
- package/dist/WrittenResponse-BpL9p2Hn.d.cts +0 -115
- package/dist/ai/useAiHelp.cjs.map +0 -1
- package/dist/ai/useAiHelp.js.map +0 -1
- package/dist/chunk-2PNSVBLQ.cjs +0 -54
- package/dist/chunk-2PNSVBLQ.cjs.map +0 -1
- package/dist/chunk-2TW6WLBC.js +0 -80
- package/dist/chunk-2TW6WLBC.js.map +0 -1
- package/dist/chunk-4ZZWZSWI.js +0 -61
- package/dist/chunk-4ZZWZSWI.js.map +0 -1
- package/dist/chunk-6N43WDVG.js +0 -29
- package/dist/chunk-6N43WDVG.js.map +0 -1
- package/dist/chunk-7ALBSPYR.cjs +0 -436
- package/dist/chunk-7ALBSPYR.cjs.map +0 -1
- package/dist/chunk-7NFY3M3W.js +0 -234
- package/dist/chunk-7NFY3M3W.js.map +0 -1
- package/dist/chunk-7SB2MJA4.js +0 -29
- package/dist/chunk-7SB2MJA4.js.map +0 -1
- package/dist/chunk-ABJJ3LII.js +0 -434
- package/dist/chunk-ABJJ3LII.js.map +0 -1
- package/dist/chunk-BIGGXHAW.cjs +0 -342
- package/dist/chunk-BIGGXHAW.cjs.map +0 -1
- package/dist/chunk-C7QZE5BI.js +0 -430
- package/dist/chunk-C7QZE5BI.js.map +0 -1
- package/dist/chunk-CWTUWNV3.cjs +0 -2937
- package/dist/chunk-CWTUWNV3.cjs.map +0 -1
- package/dist/chunk-DC4CQCK5.js +0 -915
- package/dist/chunk-DS6HN3YR.cjs +0 -496
- package/dist/chunk-DS6HN3YR.cjs.map +0 -1
- package/dist/chunk-FDQR4GAZ.js +0 -240
- package/dist/chunk-FDQR4GAZ.js.map +0 -1
- package/dist/chunk-FKGMSOJF.js +0 -394
- package/dist/chunk-FKGMSOJF.js.map +0 -1
- package/dist/chunk-G6PXJ2SA.js +0 -823
- package/dist/chunk-G6PXJ2SA.js.map +0 -1
- package/dist/chunk-HNLRVRQR.js +0 -335
- package/dist/chunk-HNLRVRQR.js.map +0 -1
- package/dist/chunk-J3C72RPK.cjs +0 -31
- package/dist/chunk-J3C72RPK.cjs.map +0 -1
- package/dist/chunk-K63VPFOV.cjs +0 -134
- package/dist/chunk-K63VPFOV.cjs.map +0 -1
- package/dist/chunk-KFLIDTDU.cjs +0 -825
- package/dist/chunk-KFLIDTDU.cjs.map +0 -1
- package/dist/chunk-KHKH5LCT.cjs +0 -250
- package/dist/chunk-KHKH5LCT.cjs.map +0 -1
- package/dist/chunk-LBEKRN6Y.cjs +0 -664
- package/dist/chunk-LBEKRN6Y.cjs.map +0 -1
- package/dist/chunk-LPUWXIPR.cjs +0 -578
- package/dist/chunk-LPUWXIPR.cjs.map +0 -1
- package/dist/chunk-MCO52PV5.js +0 -520
- package/dist/chunk-MCO52PV5.js.map +0 -1
- package/dist/chunk-MKXEM2C5.cjs +0 -396
- package/dist/chunk-MKXEM2C5.cjs.map +0 -1
- package/dist/chunk-MXNC5UNO.js +0 -563
- package/dist/chunk-MXNC5UNO.js.map +0 -1
- package/dist/chunk-NAK55BYU.cjs +0 -859
- package/dist/chunk-NAK55BYU.cjs.map +0 -1
- package/dist/chunk-NDBMKGQ5.cjs +0 -599
- package/dist/chunk-NDBMKGQ5.cjs.map +0 -1
- package/dist/chunk-OD65OZIW.cjs +0 -159
- package/dist/chunk-OD65OZIW.cjs.map +0 -1
- package/dist/chunk-ORT3KLGI.js +0 -50
- package/dist/chunk-ORT3KLGI.js.map +0 -1
- package/dist/chunk-PNNUPUH4.cjs +0 -82
- package/dist/chunk-PNNUPUH4.cjs.map +0 -1
- package/dist/chunk-PWHECW6N.js +0 -2934
- package/dist/chunk-PWHECW6N.js.map +0 -1
- package/dist/chunk-RBS5A2DF.js +0 -857
- package/dist/chunk-RBS5A2DF.js.map +0 -1
- package/dist/chunk-RPWUDXG5.cjs +0 -63
- package/dist/chunk-RPWUDXG5.cjs.map +0 -1
- package/dist/chunk-TCDJY3H6.js +0 -494
- package/dist/chunk-TCDJY3H6.js.map +0 -1
- package/dist/chunk-TP5UMRAU.cjs +0 -918
- package/dist/chunk-TP5UMRAU.cjs.map +0 -1
- package/dist/chunk-TS7J6DTY.js +0 -597
- package/dist/chunk-TS7J6DTY.js.map +0 -1
- package/dist/chunk-TUVENMXB.cjs +0 -20
- package/dist/chunk-TUVENMXB.cjs.map +0 -1
- package/dist/chunk-UDCQTOVU.cjs +0 -523
- package/dist/chunk-UDCQTOVU.cjs.map +0 -1
- package/dist/chunk-UHKZXOXD.js +0 -128
- package/dist/chunk-UHKZXOXD.js.map +0 -1
- package/dist/chunk-V6BA44DS.cjs +0 -236
- package/dist/chunk-V6BA44DS.cjs.map +0 -1
- package/dist/chunk-XO5R73Y4.js +0 -653
- package/dist/chunk-XO5R73Y4.js.map +0 -1
- package/dist/chunk-XOR4MPEN.cjs +0 -31
- package/dist/chunk-XOR4MPEN.cjs.map +0 -1
- package/dist/chunk-YORQQXGO.js +0 -155
- package/dist/chunk-YORQQXGO.js.map +0 -1
- package/dist/chunk-YY4PFR3Z.cjs +0 -432
- package/dist/chunk-YY4PFR3Z.cjs.map +0 -1
- package/dist/chunk-ZPI6Q42R.js +0 -17
- package/dist/chunk-ZPI6Q42R.js.map +0 -1
- package/dist/components/ActivityPreview.cjs.map +0 -1
- package/dist/components/ActivityPreview.js.map +0 -1
- package/dist/components/ActivitySequence.cjs.map +0 -1
- package/dist/components/ActivitySequence.js.map +0 -1
- package/dist/components/Dictation.cjs.map +0 -1
- package/dist/components/Dictation.js.map +0 -1
- package/dist/components/FillInTheBlanks.cjs.map +0 -1
- package/dist/components/FillInTheBlanks.js.map +0 -1
- package/dist/components/GapSelect.cjs.map +0 -1
- package/dist/components/GapSelect.js.map +0 -1
- package/dist/components/InteractiveVideo.cjs.map +0 -1
- package/dist/components/InteractiveVideo.js.map +0 -1
- package/dist/components/MultipleChoice.cjs.map +0 -1
- package/dist/components/MultipleChoice.js.map +0 -1
- package/dist/components/PronunciationFeedback.cjs.map +0 -1
- package/dist/components/PronunciationFeedback.js.map +0 -1
- package/dist/components/ReadAloud.cjs.map +0 -1
- package/dist/components/ReadAloud.js.map +0 -1
- package/dist/components/StimulusPanel.cjs.map +0 -1
- package/dist/components/StimulusPanel.js.map +0 -1
- package/dist/components/WrittenResponse.cjs.map +0 -1
- package/dist/components/WrittenResponse.js.map +0 -1
- package/dist/hooks/useSpeechRecorder.cjs.map +0 -1
- package/dist/hooks/useSpeechRecorder.js.map +0 -1
- package/dist/i18n/LkIntlProvider.cjs.map +0 -1
- package/dist/i18n/LkIntlProvider.js.map +0 -1
- package/dist/machine-CuwKqWXC.d.cts +0 -26
- package/dist/machine-CuwKqWXC.d.ts +0 -26
- package/dist/theme/ThemeProvider.cjs.map +0 -1
- package/dist/theme/ThemeProvider.js.map +0 -1
- package/dist/types-C4IsUQsK.d.ts +0 -989
- package/dist/types-CJgZWtl4.d.cts +0 -989
package/dist/chunk-G6PXJ2SA.js
DELETED
|
@@ -1,823 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { StimulusPanel } from './chunk-4ZZWZSWI.js';
|
|
3
|
-
import { WrittenResponse } from './chunk-FKGMSOJF.js';
|
|
4
|
-
import { MultipleChoice } from './chunk-C7QZE5BI.js';
|
|
5
|
-
import { FillInTheBlanks } from './chunk-TCDJY3H6.js';
|
|
6
|
-
import { GapSelect } from './chunk-ABJJ3LII.js';
|
|
7
|
-
import { Dictation } from './chunk-RBS5A2DF.js';
|
|
8
|
-
import { ReadAloud, stopCaptureGroup } from './chunk-DC4CQCK5.js';
|
|
9
|
-
import { randomSessionId, takeOf, mintTake, SequenceSlotContext } from './chunk-MXNC5UNO.js';
|
|
10
|
-
import { useLkStrings } from './chunk-HNLRVRQR.js';
|
|
11
|
-
import { isItemGroup, flattenSequence, resolveDeliveryPolicy, resolveItemScoringPolicy, resolvePlaybackPolicy, slotMediaKey, stimulusMediaKey } from '@intellectif/lk-core';
|
|
12
|
-
import { useRef, useState, useMemo, useEffect } from 'react';
|
|
13
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
14
|
-
|
|
15
|
-
function slotKeyOf(setKey, slot) {
|
|
16
|
-
return `${setKey}::slot-${slot.slotId}-${slot.activity.id}`;
|
|
17
|
-
}
|
|
18
|
-
function entryKeyOf(slot) {
|
|
19
|
-
return slot.slotId.split(".")[0] ?? slot.slotId;
|
|
20
|
-
}
|
|
21
|
-
var captureScopeCount = 0;
|
|
22
|
-
function SequencePane({
|
|
23
|
-
className,
|
|
24
|
-
hidden,
|
|
25
|
-
channel,
|
|
26
|
-
children
|
|
27
|
-
}) {
|
|
28
|
-
const ref = useRef(null);
|
|
29
|
-
const captureGroup = channel?.captureGroup;
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (!hidden) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (captureGroup !== void 0) {
|
|
35
|
-
stopCaptureGroup(captureGroup);
|
|
36
|
-
}
|
|
37
|
-
const node = ref.current;
|
|
38
|
-
if (node === null) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
for (const media of node.querySelectorAll("audio, video")) {
|
|
42
|
-
const element = media;
|
|
43
|
-
if (!element.paused) {
|
|
44
|
-
element.pause();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}, [hidden, captureGroup]);
|
|
48
|
-
return /* @__PURE__ */ jsx("div", { className, hidden, ref, children: channel === void 0 ? children : /* @__PURE__ */ jsx(SequenceSlotContext.Provider, { value: channel, children }) });
|
|
49
|
-
}
|
|
50
|
-
function shufflesItsOwnOptions(entry) {
|
|
51
|
-
const item = entry;
|
|
52
|
-
return item?.shuffle === true || item?.shuffleChoices === true;
|
|
53
|
-
}
|
|
54
|
-
function ActivitySequence({
|
|
55
|
-
activities,
|
|
56
|
-
renderers,
|
|
57
|
-
onActivityComplete,
|
|
58
|
-
onComplete,
|
|
59
|
-
onFinished,
|
|
60
|
-
onSubmit,
|
|
61
|
-
onInteraction,
|
|
62
|
-
renderMode = "practice",
|
|
63
|
-
shuffle,
|
|
64
|
-
shuffleSeed,
|
|
65
|
-
defaultIndex,
|
|
66
|
-
onIndexChange,
|
|
67
|
-
responses,
|
|
68
|
-
submittedSlotIds,
|
|
69
|
-
outcomes,
|
|
70
|
-
sanitizeHtml,
|
|
71
|
-
theme,
|
|
72
|
-
locale,
|
|
73
|
-
disabled,
|
|
74
|
-
mediaBudget,
|
|
75
|
-
recordingBinding,
|
|
76
|
-
assessments,
|
|
77
|
-
workletUrl,
|
|
78
|
-
strings,
|
|
79
|
-
ai,
|
|
80
|
-
delivery,
|
|
81
|
-
scoring
|
|
82
|
-
}) {
|
|
83
|
-
const sessionIdRef = useRef(null);
|
|
84
|
-
const s = useLkStrings(strings);
|
|
85
|
-
const mediaPlays = mediaBudget?.plays;
|
|
86
|
-
const [captureScope] = useState(() => {
|
|
87
|
-
captureScopeCount += 1;
|
|
88
|
-
return `lk-seq-capture-${captureScopeCount}`;
|
|
89
|
-
});
|
|
90
|
-
const shuffleEntries = shuffle === "entries";
|
|
91
|
-
const needsSeed = shuffleEntries || activities.some(
|
|
92
|
-
(entry) => isItemGroup(entry) ? entry.shuffle === "within-group" || entry.items.some(shufflesItsOwnOptions) : shufflesItsOwnOptions(entry)
|
|
93
|
-
);
|
|
94
|
-
if (needsSeed && shuffleSeed === void 0 && renderMode !== "practice") {
|
|
95
|
-
throw new Error(
|
|
96
|
-
`ActivitySequence: renderMode "${renderMode}" requires a \`shuffleSeed\` when anything in the sequence shuffles: shuffle="entries", a group with shuffle: "within-group", or an activity's own \`data.shuffle\` (multiple choice) or \`data.shuffleChoices\` (gap select), including an activity inside a group. Pass the attempt id, so the server can rebuild every order the learner saw from that one seed.`
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
const seed = needsSeed ? (
|
|
100
|
-
// biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization
|
|
101
|
-
shuffleSeed ?? (sessionIdRef.current ??= randomSessionId())
|
|
102
|
-
) : void 0;
|
|
103
|
-
const slots = useMemo(
|
|
104
|
-
() => flattenSequence(activities, { shuffleEntries, ...seed !== void 0 ? { seed } : {} }),
|
|
105
|
-
[activities, shuffleEntries, seed]
|
|
106
|
-
);
|
|
107
|
-
const [index, setIndex] = useState(() => {
|
|
108
|
-
const requested = Math.trunc(defaultIndex ?? 0);
|
|
109
|
-
if (!Number.isFinite(requested)) {
|
|
110
|
-
return 0;
|
|
111
|
-
}
|
|
112
|
-
return Math.min(Math.max(0, requested), Math.max(0, slots.length - 1));
|
|
113
|
-
});
|
|
114
|
-
const outcomesRef = useRef(null);
|
|
115
|
-
const outcomeSlotsRef = useRef(null);
|
|
116
|
-
const takesRef = useRef(/* @__PURE__ */ new Map());
|
|
117
|
-
const setGenerationRef = useRef(0);
|
|
118
|
-
const indexRef = useRef(index);
|
|
119
|
-
const reportedRef = useRef(false);
|
|
120
|
-
const channelsRef = useRef(/* @__PURE__ */ new Map());
|
|
121
|
-
const callsRef = useRef(/* @__PURE__ */ new Map());
|
|
122
|
-
const hostPendingRef = useRef(/* @__PURE__ */ new Set());
|
|
123
|
-
const [portals, setPortals] = useState(() => /* @__PURE__ */ new Map());
|
|
124
|
-
const portalRefsRef = useRef(/* @__PURE__ */ new Map());
|
|
125
|
-
const modeRef = useRef(renderMode);
|
|
126
|
-
modeRef.current = renderMode;
|
|
127
|
-
const deliveryRef = useRef(resolveDeliveryPolicy(delivery));
|
|
128
|
-
deliveryRef.current = resolveDeliveryPolicy(delivery);
|
|
129
|
-
const scoringKey = JSON.stringify(scoring ?? null);
|
|
130
|
-
const scoringInForce = useMemo(
|
|
131
|
-
() => scoring === void 0 || scoring === null ? void 0 : resolveItemScoringPolicy(scoring),
|
|
132
|
-
[scoringKey]
|
|
133
|
-
);
|
|
134
|
-
const scoringRef = useRef(scoringInForce);
|
|
135
|
-
scoringRef.current = scoringInForce;
|
|
136
|
-
const [, setReported] = useState(false);
|
|
137
|
-
const triesRef = useRef(/* @__PURE__ */ new Map());
|
|
138
|
-
const triedRef = useRef(/* @__PURE__ */ new Map());
|
|
139
|
-
const latestRef = useRef(null);
|
|
140
|
-
const aliveRef = useRef(true);
|
|
141
|
-
useEffect(() => {
|
|
142
|
-
aliveRef.current = true;
|
|
143
|
-
return () => {
|
|
144
|
-
aliveRef.current = false;
|
|
145
|
-
};
|
|
146
|
-
}, []);
|
|
147
|
-
if (outcomesRef.current === null) {
|
|
148
|
-
const submittedAtMount = new Set(submittedSlotIds ?? []);
|
|
149
|
-
outcomesRef.current = slots.map(
|
|
150
|
-
(slot) => submittedAtMount.has(slot.slotId) ? {
|
|
151
|
-
kind: "restored",
|
|
152
|
-
index: slot.index,
|
|
153
|
-
slotId: slot.slotId,
|
|
154
|
-
activityId: slot.activity.id,
|
|
155
|
-
...responses !== void 0 && Object.hasOwn(responses, slot.slotId) ? { response: responses[slot.slotId] } : {}
|
|
156
|
-
} : null
|
|
157
|
-
);
|
|
158
|
-
outcomeSlotsRef.current = slots;
|
|
159
|
-
}
|
|
160
|
-
const regionRef = useRef(null);
|
|
161
|
-
const mountedRef = useRef(false);
|
|
162
|
-
const setKey = JSON.stringify(slots.map((slot) => [slot.slotId, slot.activity.id]));
|
|
163
|
-
const [prevSetKey, setPrevSetKey] = useState(setKey);
|
|
164
|
-
const seedKey = `${setKey}::${mediaBudget?.resumeKey ?? ""}`;
|
|
165
|
-
const mountSetKeyRef = useRef(setKey);
|
|
166
|
-
const mountSeedKeyRef = useRef(seedKey);
|
|
167
|
-
const seedsApply = mountSetKeyRef.current === setKey;
|
|
168
|
-
const mediaSeedsApply = mountSeedKeyRef.current === seedKey || seedsApply;
|
|
169
|
-
if (mountSeedKeyRef.current !== seedKey) {
|
|
170
|
-
mountSeedKeyRef.current = seedKey;
|
|
171
|
-
}
|
|
172
|
-
const submitted = useMemo(() => new Set(submittedSlotIds ?? []), [submittedSlotIds]);
|
|
173
|
-
if (prevSetKey !== setKey) {
|
|
174
|
-
setPrevSetKey(setKey);
|
|
175
|
-
setIndex(0);
|
|
176
|
-
indexRef.current = 0;
|
|
177
|
-
outcomesRef.current = slots.map(() => null);
|
|
178
|
-
outcomeSlotsRef.current = slots;
|
|
179
|
-
takesRef.current = /* @__PURE__ */ new Map();
|
|
180
|
-
setGenerationRef.current += 1;
|
|
181
|
-
channelsRef.current = /* @__PURE__ */ new Map();
|
|
182
|
-
callsRef.current = /* @__PURE__ */ new Map();
|
|
183
|
-
hostPendingRef.current = /* @__PURE__ */ new Set();
|
|
184
|
-
portalRefsRef.current = /* @__PURE__ */ new Map();
|
|
185
|
-
reportedRef.current = false;
|
|
186
|
-
triesRef.current = /* @__PURE__ */ new Map();
|
|
187
|
-
triedRef.current = /* @__PURE__ */ new Map();
|
|
188
|
-
setReported(false);
|
|
189
|
-
}
|
|
190
|
-
const setGeneration = setGenerationRef.current;
|
|
191
|
-
useEffect(() => {
|
|
192
|
-
if (mountedRef.current) {
|
|
193
|
-
regionRef.current?.focus();
|
|
194
|
-
} else {
|
|
195
|
-
mountedRef.current = true;
|
|
196
|
-
}
|
|
197
|
-
}, [index]);
|
|
198
|
-
const reportedIndexRef = useRef(null);
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
if (reportedIndexRef.current === index) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const first = reportedIndexRef.current === null;
|
|
204
|
-
reportedIndexRef.current = index;
|
|
205
|
-
if (first && index === Math.trunc(defaultIndex ?? 0)) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
onIndexChange?.(index);
|
|
209
|
-
}, [index, defaultIndex, onIndexChange]);
|
|
210
|
-
useEffect(() => {
|
|
211
|
-
if (indexRef.current === index) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
indexRef.current = index;
|
|
215
|
-
latestRef.current?.reportIfFinished();
|
|
216
|
-
}, [index]);
|
|
217
|
-
const stimulusMounts = useMemo(() => {
|
|
218
|
-
const mounts = /* @__PURE__ */ new Map();
|
|
219
|
-
for (const slot of slots) {
|
|
220
|
-
if (slot.group === void 0) {
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
const entryKey = entryKeyOf(slot);
|
|
224
|
-
const existing = mounts.get(entryKey);
|
|
225
|
-
if (existing === void 0) {
|
|
226
|
-
mounts.set(entryKey, { entryKey, group: slot.group, first: slot.index, last: slot.index });
|
|
227
|
-
} else {
|
|
228
|
-
existing.last = slot.index;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return [...mounts.values()];
|
|
232
|
-
}, [slots]);
|
|
233
|
-
const total = slots.length;
|
|
234
|
-
const current = slots[index];
|
|
235
|
-
const go = (next) => {
|
|
236
|
-
setIndex(next);
|
|
237
|
-
};
|
|
238
|
-
const reportIfFinished = () => {
|
|
239
|
-
const held = outcomesRef.current;
|
|
240
|
-
const presented = outcomeSlotsRef.current;
|
|
241
|
-
if (held === null || presented === null || reportedRef.current) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
if (hostPendingRef.current.size > 0) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
for (const [at, state] of triesRef.current) {
|
|
248
|
-
if (state === "retrying" || at === indexRef.current) {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
const items = [];
|
|
253
|
-
for (const [at, outcome] of held.entries()) {
|
|
254
|
-
const take = takesRef.current.get(at);
|
|
255
|
-
if (take?.state === "in-flight" || take?.state === "retryable" && at === indexRef.current) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const slot = presented[at];
|
|
259
|
-
if (outcome !== null) {
|
|
260
|
-
items.push(outcome);
|
|
261
|
-
} else if (take?.state === "retryable" && renderMode === "practice" && slot !== void 0) {
|
|
262
|
-
items.push({
|
|
263
|
-
kind: "unsubmitted",
|
|
264
|
-
index: at,
|
|
265
|
-
slotId: slot.slotId,
|
|
266
|
-
activityId: slot.activity.id
|
|
267
|
-
});
|
|
268
|
-
} else {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
reportedRef.current = true;
|
|
273
|
-
setReported(true);
|
|
274
|
-
onFinished?.(items);
|
|
275
|
-
const scored = [];
|
|
276
|
-
for (const item of items) {
|
|
277
|
-
if (item.kind !== "scored") {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
scored.push(item.result);
|
|
281
|
-
}
|
|
282
|
-
onComplete?.(scored);
|
|
283
|
-
};
|
|
284
|
-
const record = (outcome, generation, take, tried) => {
|
|
285
|
-
const held = outcomesRef.current;
|
|
286
|
-
if (held === null || generation !== setGenerationRef.current) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const at = outcome.index;
|
|
290
|
-
const holding = held[at];
|
|
291
|
-
let accepted = outcome;
|
|
292
|
-
if (tried !== void 0) {
|
|
293
|
-
const latest = triedRef.current.get(at);
|
|
294
|
-
if (holding?.kind === "restored") {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
if (holding != null && (reportedRef.current || latest === void 0 || tried <= latest)) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
triedRef.current.set(at, tried);
|
|
301
|
-
} else if (take === void 0) {
|
|
302
|
-
if (holding != null) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
if (holding?.kind === "restored") {
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
const latest = takesRef.current.get(at);
|
|
310
|
-
if (outcome.kind === "responded") {
|
|
311
|
-
if (latest !== void 0 && (take < latest.take || take === latest.take && latest.response !== void 0)) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
takesRef.current.set(at, {
|
|
315
|
-
take,
|
|
316
|
-
// A take this pager hears of first through its answer — a consumer's
|
|
317
|
-
// renderer has no channel — has nothing on its way.
|
|
318
|
-
state: latest?.take === take ? latest.state : "settled",
|
|
319
|
-
response: outcome.response
|
|
320
|
-
});
|
|
321
|
-
} else if (outcome.kind === "scored") {
|
|
322
|
-
if (latest?.take !== take || latest.response === void 0 || holding?.kind === "scored") {
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
accepted = { ...outcome, response: latest.response };
|
|
326
|
-
} else {
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
const next = held.slice();
|
|
331
|
-
next[at] = accepted;
|
|
332
|
-
outcomesRef.current = next;
|
|
333
|
-
if (accepted.kind === "scored") {
|
|
334
|
-
onActivityComplete?.(accepted.result, accepted.index, accepted.slotId);
|
|
335
|
-
}
|
|
336
|
-
reportIfFinished();
|
|
337
|
-
};
|
|
338
|
-
const submitSlot = (generation, at, response) => {
|
|
339
|
-
if (generation !== setGenerationRef.current) {
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
onSubmit?.(response, { slotId: at.slotId, index: at.index, activityId: at.activityId });
|
|
343
|
-
if (at.type === "written-response") {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
if (renderMode !== "practice") {
|
|
347
|
-
record(
|
|
348
|
-
{
|
|
349
|
-
kind: "responded",
|
|
350
|
-
index: at.index,
|
|
351
|
-
slotId: at.slotId,
|
|
352
|
-
activityId: at.activityId,
|
|
353
|
-
response
|
|
354
|
-
},
|
|
355
|
-
generation
|
|
356
|
-
);
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
if (at.type === "read-aloud") {
|
|
360
|
-
record(
|
|
361
|
-
{
|
|
362
|
-
kind: "responded",
|
|
363
|
-
index: at.index,
|
|
364
|
-
slotId: at.slotId,
|
|
365
|
-
activityId: at.activityId,
|
|
366
|
-
response
|
|
367
|
-
},
|
|
368
|
-
generation,
|
|
369
|
-
takeOf(response) ?? mintTake()
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
};
|
|
373
|
-
const completeSlot = (generation, at, result) => {
|
|
374
|
-
const takesAnswers = renderMode === "practice" && at.type === "read-aloud";
|
|
375
|
-
const outcome = {
|
|
376
|
-
kind: "scored",
|
|
377
|
-
index: at.index,
|
|
378
|
-
slotId: at.slotId,
|
|
379
|
-
activityId: at.activityId,
|
|
380
|
-
result
|
|
381
|
-
};
|
|
382
|
-
const tried = takesAnswers ? void 0 : takeOf(result);
|
|
383
|
-
if (tried !== void 0 && renderMode === "practice") {
|
|
384
|
-
record(outcome, generation, void 0, tried);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
record(
|
|
388
|
-
outcome,
|
|
389
|
-
generation,
|
|
390
|
-
// The take the grade is for: stamped by `<ReadAloud>`, and for a
|
|
391
|
-
// consumer's renderer, which cannot stamp one, the slot's latest.
|
|
392
|
-
takesAnswers ? takeOf(result) ?? takesRef.current.get(at.index)?.take : void 0
|
|
393
|
-
);
|
|
394
|
-
};
|
|
395
|
-
const clearSlot = (generation, at) => {
|
|
396
|
-
const held = outcomesRef.current;
|
|
397
|
-
if (!aliveRef.current || held === null || generation !== setGenerationRef.current) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
takesRef.current.delete(at.index);
|
|
401
|
-
if (held[at.index] == null) {
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
const next = held.slice();
|
|
405
|
-
next[at.index] = null;
|
|
406
|
-
outcomesRef.current = next;
|
|
407
|
-
};
|
|
408
|
-
const hostPending = (generation, at, pending) => {
|
|
409
|
-
if (!aliveRef.current || generation !== setGenerationRef.current) {
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
const waiting = hostPendingRef.current;
|
|
413
|
-
if (pending) {
|
|
414
|
-
waiting.add(at.index);
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
if (!waiting.delete(at.index)) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
reportIfFinished();
|
|
421
|
-
};
|
|
422
|
-
const emitFor = (generation, at, type, payload) => {
|
|
423
|
-
if (!aliveRef.current || generation !== setGenerationRef.current) {
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
onInteraction?.({
|
|
427
|
-
type,
|
|
428
|
-
activityId: at.activityId,
|
|
429
|
-
timestamp: Date.now(),
|
|
430
|
-
payload: payload ?? {}
|
|
431
|
-
});
|
|
432
|
-
};
|
|
433
|
-
const updateTake = (generation, at, take, state) => {
|
|
434
|
-
if (!aliveRef.current || generation !== setGenerationRef.current) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
const latest = takesRef.current.get(at);
|
|
438
|
-
if (latest !== void 0 && take < latest.take) {
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
takesRef.current.set(at, latest?.take === take ? { ...latest, state } : { take, state });
|
|
442
|
-
reportIfFinished();
|
|
443
|
-
};
|
|
444
|
-
const updateTries = (generation, at, state) => {
|
|
445
|
-
if (!aliveRef.current || generation !== setGenerationRef.current) {
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
const was = triesRef.current.get(at);
|
|
449
|
-
if (state === "none") {
|
|
450
|
-
triesRef.current.delete(at);
|
|
451
|
-
} else {
|
|
452
|
-
triesRef.current.set(at, state);
|
|
453
|
-
}
|
|
454
|
-
if (was !== void 0 && was !== state) {
|
|
455
|
-
reportIfFinished();
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
latestRef.current = {
|
|
459
|
-
updateTake,
|
|
460
|
-
updateTries,
|
|
461
|
-
reportIfFinished,
|
|
462
|
-
submitSlot,
|
|
463
|
-
completeSlot,
|
|
464
|
-
clearSlot,
|
|
465
|
-
hostPending,
|
|
466
|
-
emit: emitFor
|
|
467
|
-
};
|
|
468
|
-
const callsFor = (slot) => {
|
|
469
|
-
const key = `${slot.index}::${slot.slotId}`;
|
|
470
|
-
let calls = callsRef.current.get(key);
|
|
471
|
-
if (calls === void 0) {
|
|
472
|
-
const generation = setGeneration;
|
|
473
|
-
const at = {
|
|
474
|
-
slotId: slot.slotId,
|
|
475
|
-
index: slot.index,
|
|
476
|
-
activityId: slot.activity.id,
|
|
477
|
-
type: slot.activity.type
|
|
478
|
-
};
|
|
479
|
-
calls = {
|
|
480
|
-
slot: { slotId: at.slotId, index: at.index, activityId: at.activityId },
|
|
481
|
-
onSubmit: (response) => latestRef.current?.submitSlot(generation, at, response),
|
|
482
|
-
onComplete: (result) => latestRef.current?.completeSlot(generation, at, result),
|
|
483
|
-
clear: () => latestRef.current?.clearSlot(generation, at),
|
|
484
|
-
setPending: (pending) => latestRef.current?.hostPending(generation, at, pending === true),
|
|
485
|
-
emit: (type, payload) => latestRef.current?.emit(generation, at, type, payload)
|
|
486
|
-
};
|
|
487
|
-
callsRef.current.set(key, calls);
|
|
488
|
-
}
|
|
489
|
-
return calls;
|
|
490
|
-
};
|
|
491
|
-
const portalRefFor = (key) => {
|
|
492
|
-
let callback = portalRefsRef.current.get(key);
|
|
493
|
-
if (callback === void 0) {
|
|
494
|
-
callback = (node) => {
|
|
495
|
-
setPortals((held) => {
|
|
496
|
-
if (node === null) {
|
|
497
|
-
if (!held.has(key)) {
|
|
498
|
-
return held;
|
|
499
|
-
}
|
|
500
|
-
const next2 = new Map(held);
|
|
501
|
-
next2.delete(key);
|
|
502
|
-
return next2;
|
|
503
|
-
}
|
|
504
|
-
if (held.get(key) === node) {
|
|
505
|
-
return held;
|
|
506
|
-
}
|
|
507
|
-
const next = new Map(held);
|
|
508
|
-
next.set(key, node);
|
|
509
|
-
return next;
|
|
510
|
-
});
|
|
511
|
-
};
|
|
512
|
-
portalRefsRef.current.set(key, callback);
|
|
513
|
-
}
|
|
514
|
-
return callback;
|
|
515
|
-
};
|
|
516
|
-
const channelFor = (slot) => {
|
|
517
|
-
const key = `${slot.index}::${slot.slotId}`;
|
|
518
|
-
let channel = channelsRef.current.get(key);
|
|
519
|
-
if (channel === void 0) {
|
|
520
|
-
const generation = setGeneration;
|
|
521
|
-
const at = slot.index;
|
|
522
|
-
channel = {
|
|
523
|
-
captureGroup: `${captureScope}::${slot.slotId}`,
|
|
524
|
-
// A getter, so the channel keeps the one identity a recorder joined
|
|
525
|
-
// while still answering for the mode in force now.
|
|
526
|
-
get renderMode() {
|
|
527
|
-
return modeRef.current;
|
|
528
|
-
},
|
|
529
|
-
get delivery() {
|
|
530
|
-
return deliveryRef.current;
|
|
531
|
-
},
|
|
532
|
-
get scoring() {
|
|
533
|
-
return scoringRef.current;
|
|
534
|
-
},
|
|
535
|
-
get triesClosed() {
|
|
536
|
-
return reportedRef.current;
|
|
537
|
-
},
|
|
538
|
-
triesState: (state) => {
|
|
539
|
-
latestRef.current?.updateTries(generation, at, state);
|
|
540
|
-
},
|
|
541
|
-
takeState: (take, state) => {
|
|
542
|
-
latestRef.current?.updateTake(generation, at, take, state);
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
channelsRef.current.set(key, channel);
|
|
546
|
-
}
|
|
547
|
-
return channel;
|
|
548
|
-
};
|
|
549
|
-
if (!current) {
|
|
550
|
-
return /* @__PURE__ */ jsx("div", { className: "lk-seq" });
|
|
551
|
-
}
|
|
552
|
-
const budgetedMedia = slots.flatMap((slot) => {
|
|
553
|
-
const found = [];
|
|
554
|
-
const own = slot.activity.media;
|
|
555
|
-
if (own !== void 0 && resolvePlaybackPolicy(own).maxPlays !== null) {
|
|
556
|
-
found.push({ key: slotMediaKey(slot.slotId), url: own.url });
|
|
557
|
-
}
|
|
558
|
-
const stimulus = slot.group?.stimulus.media;
|
|
559
|
-
if (stimulus !== void 0 && resolvePlaybackPolicy(stimulus).maxPlays !== null) {
|
|
560
|
-
found.push({ key: stimulusMediaKey(slot.slotId), url: stimulus.url });
|
|
561
|
-
}
|
|
562
|
-
return found;
|
|
563
|
-
});
|
|
564
|
-
const budgetEnforced = mediaBudget?.enforced ?? renderMode !== "review";
|
|
565
|
-
if (budgetedMedia.length > 0 && renderMode === "exam" && budgetEnforced) {
|
|
566
|
-
if (mediaBudget?.onPlayConsumed === void 0) {
|
|
567
|
-
throw new Error(
|
|
568
|
-
`ActivitySequence: renderMode "exam" with media that declares \`maxPlays\` requires \`mediaBudget.onPlayConsumed\`. The SDK persists nothing, so without it the count lives only in this mount: a refresh silently restores the full budget, and a paper that grants unlimited plays while showing "2 plays remaining" is indistinguishable \u2014 to the learner and to an appeal \u2014 from one that works. Budgeted media: ${[...new Set(budgetedMedia.map((m) => m.key))].join(", ")}.`
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
const resuming = responses !== void 0 && Object.keys(responses).length > 0 || submittedSlotIds !== void 0 && submittedSlotIds.length > 0;
|
|
572
|
-
if (resuming && mediaBudget.plays === void 0) {
|
|
573
|
-
throw new Error(
|
|
574
|
-
"ActivitySequence: this is a resumed attempt (`responses`/`submittedSlotIds` were supplied) but `mediaBudget.plays` is absent. A resume that omits the ledger hands the learner a fresh budget at exactly the moment it matters. Pass `restoreMediaPlayLedger(plan, stored).entries`, or `{}` to state explicitly that nothing was spent."
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
const keysByUrl = /* @__PURE__ */ new Map();
|
|
579
|
-
for (const { key, url } of budgetedMedia) {
|
|
580
|
-
const keys = keysByUrl.get(url) ?? /* @__PURE__ */ new Set();
|
|
581
|
-
keys.add(key);
|
|
582
|
-
keysByUrl.set(url, keys);
|
|
583
|
-
}
|
|
584
|
-
for (const [url, keys] of keysByUrl) {
|
|
585
|
-
if (keys.size > 1) {
|
|
586
|
-
throw new Error(
|
|
587
|
-
`ActivitySequence: media ${JSON.stringify(url)} is budgeted under ${keys.size} separate keys (${[...keys].join(", ")}), so one recording grants ${keys.size} \xD7 maxPlays. Put the questions that share a recording in an item group \u2014 a group's stimulus is one recording with one budget.`
|
|
588
|
-
);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
const bindingFor = (key, slot) => {
|
|
592
|
-
if (mediaBudget === void 0) {
|
|
593
|
-
return void 0;
|
|
594
|
-
}
|
|
595
|
-
const entry = mediaSeedsApply && mediaPlays !== void 0 && Object.hasOwn(mediaPlays, key) ? mediaPlays[key] : void 0;
|
|
596
|
-
return {
|
|
597
|
-
key,
|
|
598
|
-
slotId: slot.slotId,
|
|
599
|
-
index: slot.index,
|
|
600
|
-
activityId: slot.activity.id,
|
|
601
|
-
...entry !== void 0 ? { entry } : {},
|
|
602
|
-
...mediaBudget.enforced !== void 0 ? { enforced: mediaBudget.enforced } : {},
|
|
603
|
-
...mediaBudget.onPlayConsumed !== void 0 ? { onPlayConsumed: mediaBudget.onPlayConsumed } : {},
|
|
604
|
-
...mediaBudget.onPlayRefunded !== void 0 ? { onPlayRefunded: mediaBudget.onPlayRefunded } : {},
|
|
605
|
-
...mediaBudget.onPosition !== void 0 ? { onPosition: mediaBudget.onPosition } : {},
|
|
606
|
-
...mediaBudget.strings !== void 0 ? { strings: mediaBudget.strings } : {}
|
|
607
|
-
};
|
|
608
|
-
};
|
|
609
|
-
const recordingBindingFor = (slot) => {
|
|
610
|
-
if (recordingBinding === void 0) {
|
|
611
|
-
return void 0;
|
|
612
|
-
}
|
|
613
|
-
const at = {
|
|
614
|
-
slotId: slot.slotId,
|
|
615
|
-
index: slot.index,
|
|
616
|
-
activityId: slot.activity.id
|
|
617
|
-
};
|
|
618
|
-
const { assess, playbackUrl } = recordingBinding;
|
|
619
|
-
return {
|
|
620
|
-
upload: (take) => recordingBinding.upload(take, at),
|
|
621
|
-
...assess !== void 0 ? { assess: (ref) => assess.call(recordingBinding, ref, at) } : {},
|
|
622
|
-
...playbackUrl !== void 0 ? { playbackUrl: (ref) => playbackUrl.call(recordingBinding, ref, at) } : {}
|
|
623
|
-
};
|
|
624
|
-
};
|
|
625
|
-
const forwarded = {
|
|
626
|
-
...onInteraction ? { onInteraction } : {},
|
|
627
|
-
renderMode,
|
|
628
|
-
...sanitizeHtml ? { sanitizeHtml } : {},
|
|
629
|
-
...strings !== void 0 ? { strings } : {},
|
|
630
|
-
// Handed to no question in `exam`, where none gives AI help: a
|
|
631
|
-
// `renderers` override is not given ports it must then know to ignore.
|
|
632
|
-
...ai !== void 0 && renderMode !== "exam" ? { ai } : {},
|
|
633
|
-
// As given: each question combines it with the paper's through its
|
|
634
|
-
// channel, so what it is handed and what holds cannot disagree.
|
|
635
|
-
...delivery !== void 0 && delivery !== null ? { delivery } : {},
|
|
636
|
-
// As given, for a `renderers` override to score by. The SDK's own questions
|
|
637
|
-
// read the paper's from their channel, which wins over it.
|
|
638
|
-
...scoring !== void 0 && scoring !== null ? { scoring } : {},
|
|
639
|
-
...theme ? { theme } : {},
|
|
640
|
-
...locale ? { locale } : {},
|
|
641
|
-
...disabled ? { disabled } : {}
|
|
642
|
-
};
|
|
643
|
-
const renderSlot = (slot) => {
|
|
644
|
-
const activity = slot.activity;
|
|
645
|
-
const { slotId, index: slotIndex } = slot;
|
|
646
|
-
const activityId = activity.id;
|
|
647
|
-
const restored = seedsApply && responses !== void 0 && Object.hasOwn(responses, slotId) ? responses[slotId] : void 0;
|
|
648
|
-
const slotOutcome = outcomes !== void 0 && Object.hasOwn(outcomes, slotId) ? outcomes[slotId] : void 0;
|
|
649
|
-
const slotBinding = bindingFor(slotMediaKey(slotId), slot);
|
|
650
|
-
const calls = callsFor(slot);
|
|
651
|
-
const childProps = {
|
|
652
|
-
// `defaultValue`, not `value`: the learner must be able to keep editing
|
|
653
|
-
// a restored answer. A controlled `value` would freeze it unless the
|
|
654
|
-
// consumer also threaded state back, which is not what resume means.
|
|
655
|
-
...restored !== void 0 ? { defaultValue: restored } : {},
|
|
656
|
-
...seedsApply && submitted.has(slotId) ? { defaultSubmitted: true } : {},
|
|
657
|
-
...slotOutcome !== void 0 ? { outcome: slotOutcome } : {},
|
|
658
|
-
// One identity per slot for the life of the set — see `callsFor`. Their
|
|
659
|
-
// bodies are `submitSlot` and `completeSlot`, the same ones a host's own
|
|
660
|
-
// renderer calls, so a question the host draws is recorded exactly as one
|
|
661
|
-
// the SDK draws.
|
|
662
|
-
onComplete: calls.onComplete,
|
|
663
|
-
onSubmit: calls.onSubmit,
|
|
664
|
-
...forwarded,
|
|
665
|
-
...slotBinding !== void 0 ? { mediaBudget: slotBinding } : {}
|
|
666
|
-
};
|
|
667
|
-
const CustomRenderer = renderers?.[activity.type];
|
|
668
|
-
if (CustomRenderer) {
|
|
669
|
-
const portalKey = slotKeyOf(setKey, slot);
|
|
670
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
671
|
-
/* @__PURE__ */ jsx(
|
|
672
|
-
CustomRenderer,
|
|
673
|
-
{
|
|
674
|
-
data: activity,
|
|
675
|
-
...childProps,
|
|
676
|
-
question: {
|
|
677
|
-
slot: calls.slot,
|
|
678
|
-
active: slotIndex === index,
|
|
679
|
-
portalContainer: portals.get(portalKey) ?? null,
|
|
680
|
-
clear: calls.clear,
|
|
681
|
-
setPending: calls.setPending,
|
|
682
|
-
emit: calls.emit
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
),
|
|
686
|
-
/* @__PURE__ */ jsx("div", { className: "lk-seq-portal", ref: portalRefFor(portalKey) })
|
|
687
|
-
] });
|
|
688
|
-
}
|
|
689
|
-
if (activity.type === "multiple-choice") {
|
|
690
|
-
return /* @__PURE__ */ jsx(
|
|
691
|
-
MultipleChoice,
|
|
692
|
-
{
|
|
693
|
-
data: activity,
|
|
694
|
-
...shuffleSeed !== void 0 ? { shuffleSeed } : {},
|
|
695
|
-
...childProps
|
|
696
|
-
}
|
|
697
|
-
);
|
|
698
|
-
}
|
|
699
|
-
if (activity.type === "fill-in-the-blanks") {
|
|
700
|
-
return /* @__PURE__ */ jsx(FillInTheBlanks, { data: activity, ...childProps });
|
|
701
|
-
}
|
|
702
|
-
if (activity.type === "gap-select") {
|
|
703
|
-
return /* @__PURE__ */ jsx(
|
|
704
|
-
GapSelect,
|
|
705
|
-
{
|
|
706
|
-
data: activity,
|
|
707
|
-
...shuffleSeed !== void 0 ? { shuffleSeed } : {},
|
|
708
|
-
...childProps
|
|
709
|
-
}
|
|
710
|
-
);
|
|
711
|
-
}
|
|
712
|
-
if (activity.type === "dictation") {
|
|
713
|
-
return /* @__PURE__ */ jsx(Dictation, { data: activity, ...childProps });
|
|
714
|
-
}
|
|
715
|
-
if (activity.type === "read-aloud") {
|
|
716
|
-
const slotRecordingBinding = recordingBindingFor(slot);
|
|
717
|
-
const slotAssessment = assessments !== void 0 && Object.hasOwn(assessments, slotId) ? assessments[slotId] : void 0;
|
|
718
|
-
return /* @__PURE__ */ jsx(
|
|
719
|
-
ReadAloud,
|
|
720
|
-
{
|
|
721
|
-
data: activity,
|
|
722
|
-
...childProps,
|
|
723
|
-
...slotRecordingBinding !== void 0 ? { recordingBinding: slotRecordingBinding } : {},
|
|
724
|
-
...slotAssessment !== void 0 ? { assessment: slotAssessment } : {},
|
|
725
|
-
...workletUrl !== void 0 ? { workletUrl } : {}
|
|
726
|
-
}
|
|
727
|
-
);
|
|
728
|
-
}
|
|
729
|
-
if (activity.type === "written-response") {
|
|
730
|
-
const { onComplete: _neverGrades, ...writtenResponseProps } = childProps;
|
|
731
|
-
return /* @__PURE__ */ jsx(
|
|
732
|
-
WrittenResponse,
|
|
733
|
-
{
|
|
734
|
-
data: activity,
|
|
735
|
-
...writtenResponseProps,
|
|
736
|
-
onSubmitted: (submission) => record(
|
|
737
|
-
{ kind: "submitted", index: slotIndex, slotId, activityId, submission },
|
|
738
|
-
setGeneration
|
|
739
|
-
)
|
|
740
|
-
}
|
|
741
|
-
);
|
|
742
|
-
}
|
|
743
|
-
return /* @__PURE__ */ jsx("div", { className: "lk-seq-unsupported", role: "note", children: s.unsupportedActivity });
|
|
744
|
-
};
|
|
745
|
-
const currentEntryKey = entryKeyOf(current);
|
|
746
|
-
return /* @__PURE__ */ jsxs("div", { className: "lk-seq", lang: locale, children: [
|
|
747
|
-
/* @__PURE__ */ jsx("div", { className: "lk-seq-progress", "aria-live": "polite", role: "status", children: s.questionProgress(index + 1, total) }),
|
|
748
|
-
stimulusMounts.map(({ entryKey, group, first, last }) => {
|
|
749
|
-
const firstSlot = slots[first];
|
|
750
|
-
const stimulusBinding = firstSlot === void 0 ? void 0 : bindingFor(stimulusMediaKey(firstSlot.slotId), firstSlot);
|
|
751
|
-
return /* @__PURE__ */ jsx(
|
|
752
|
-
SequencePane,
|
|
753
|
-
{
|
|
754
|
-
className: "lk-seq-stimulus",
|
|
755
|
-
hidden: entryKey !== currentEntryKey,
|
|
756
|
-
children: /* @__PURE__ */ jsx(
|
|
757
|
-
StimulusPanel,
|
|
758
|
-
{
|
|
759
|
-
stimulus: group.stimulus,
|
|
760
|
-
range: { first: first + 1, last: last + 1 },
|
|
761
|
-
renderMode,
|
|
762
|
-
...sanitizeHtml ? { sanitizeHtml } : {},
|
|
763
|
-
...locale ? { locale } : {},
|
|
764
|
-
...onInteraction ? { onInteraction } : {},
|
|
765
|
-
...disabled ? { disabled } : {},
|
|
766
|
-
...strings !== void 0 ? { strings } : {},
|
|
767
|
-
...stimulusBinding !== void 0 ? { mediaBudget: stimulusBinding } : {}
|
|
768
|
-
}
|
|
769
|
-
)
|
|
770
|
-
},
|
|
771
|
-
`${setKey}::group-${entryKey}`
|
|
772
|
-
);
|
|
773
|
-
}),
|
|
774
|
-
/* @__PURE__ */ jsx(
|
|
775
|
-
"section",
|
|
776
|
-
{
|
|
777
|
-
className: "lk-seq-question",
|
|
778
|
-
ref: regionRef,
|
|
779
|
-
tabIndex: -1,
|
|
780
|
-
"aria-label": s.questionProgress(index + 1, total),
|
|
781
|
-
children: slots.map((slot) => {
|
|
782
|
-
const slotKey = slotKeyOf(setKey, slot);
|
|
783
|
-
return /* @__PURE__ */ jsx(
|
|
784
|
-
SequencePane,
|
|
785
|
-
{
|
|
786
|
-
className: "lk-seq-slot",
|
|
787
|
-
hidden: slot.index !== index,
|
|
788
|
-
channel: channelFor(slot),
|
|
789
|
-
children: renderSlot(slot)
|
|
790
|
-
},
|
|
791
|
-
slotKey
|
|
792
|
-
);
|
|
793
|
-
})
|
|
794
|
-
}
|
|
795
|
-
),
|
|
796
|
-
/* @__PURE__ */ jsxs("div", { className: "lk-seq-nav", children: [
|
|
797
|
-
/* @__PURE__ */ jsx(
|
|
798
|
-
"button",
|
|
799
|
-
{
|
|
800
|
-
type: "button",
|
|
801
|
-
className: "lk-seq-prev",
|
|
802
|
-
onClick: () => go(index - 1),
|
|
803
|
-
disabled: index === 0,
|
|
804
|
-
children: s.previous
|
|
805
|
-
}
|
|
806
|
-
),
|
|
807
|
-
/* @__PURE__ */ jsx(
|
|
808
|
-
"button",
|
|
809
|
-
{
|
|
810
|
-
type: "button",
|
|
811
|
-
className: "lk-seq-next",
|
|
812
|
-
onClick: () => go(index + 1),
|
|
813
|
-
disabled: index === total - 1,
|
|
814
|
-
children: s.next
|
|
815
|
-
}
|
|
816
|
-
)
|
|
817
|
-
] })
|
|
818
|
-
] });
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
export { ActivitySequence };
|
|
822
|
-
//# sourceMappingURL=chunk-G6PXJ2SA.js.map
|
|
823
|
-
//# sourceMappingURL=chunk-G6PXJ2SA.js.map
|