@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.
Files changed (139) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +5 -2
  3. package/dist/{WrittenResponse-pB1ik8hg.d.cts → WrittenResponse-BPbhERgk.d.cts} +1 -1
  4. package/dist/{WrittenResponse-C0P34En1.d.ts → WrittenResponse-ZAxLR_AU.d.ts} +1 -1
  5. package/dist/{chunk-YEYKJFEC.cjs → chunk-26GQO5I2.cjs} +12 -12
  6. package/dist/{chunk-YEYKJFEC.cjs.map → chunk-26GQO5I2.cjs.map} +1 -1
  7. package/dist/chunk-2HAEQDHQ.js +2330 -0
  8. package/dist/chunk-2HAEQDHQ.js.map +1 -0
  9. package/dist/{chunk-47HHC4GD.js → chunk-33BQNWAQ.js} +5 -5
  10. package/dist/{chunk-47HHC4GD.js.map → chunk-33BQNWAQ.js.map} +1 -1
  11. package/dist/{chunk-SE6WWDVW.cjs → chunk-4H3JTX74.cjs} +13 -13
  12. package/dist/{chunk-SE6WWDVW.cjs.map → chunk-4H3JTX74.cjs.map} +1 -1
  13. package/dist/{chunk-TDJEKXEP.js → chunk-52GXJNQ3.js} +84 -2
  14. package/dist/chunk-52GXJNQ3.js.map +1 -0
  15. package/dist/{chunk-USBANZ7K.cjs → chunk-53YOZOGN.cjs} +5 -5
  16. package/dist/{chunk-USBANZ7K.cjs.map → chunk-53YOZOGN.cjs.map} +1 -1
  17. package/dist/{chunk-LLXCX5KK.js → chunk-AF72QUBI.js} +5 -5
  18. package/dist/{chunk-LLXCX5KK.js.map → chunk-AF72QUBI.js.map} +1 -1
  19. package/dist/{chunk-XUEIUEPI.js → chunk-CE6OGJE6.js} +5 -5
  20. package/dist/{chunk-XUEIUEPI.js.map → chunk-CE6OGJE6.js.map} +1 -1
  21. package/dist/{chunk-RRH7ZPXC.cjs → chunk-DP3DM7FR.cjs} +6 -6
  22. package/dist/{chunk-RRH7ZPXC.cjs.map → chunk-DP3DM7FR.cjs.map} +1 -1
  23. package/dist/{chunk-J2CDPIRC.cjs → chunk-DQ3VVU5T.cjs} +27 -25
  24. package/dist/chunk-DQ3VVU5T.cjs.map +1 -0
  25. package/dist/{chunk-U3APKQ7P.cjs → chunk-EKBEKDWO.cjs} +13 -13
  26. package/dist/{chunk-U3APKQ7P.cjs.map → chunk-EKBEKDWO.cjs.map} +1 -1
  27. package/dist/{chunk-RXS455MR.js → chunk-EVBYEWHO.js} +3 -2
  28. package/dist/chunk-EVBYEWHO.js.map +1 -0
  29. package/dist/{chunk-B2XQLU2E.cjs → chunk-FKGUKFC7.cjs} +24 -6
  30. package/dist/chunk-FKGUKFC7.cjs.map +1 -0
  31. package/dist/{chunk-YMBBM5K7.js → chunk-H6I2JDNW.js} +10 -10
  32. package/dist/{chunk-YMBBM5K7.js.map → chunk-H6I2JDNW.js.map} +1 -1
  33. package/dist/{chunk-XIBOFTOL.js → chunk-HA3VRF6E.js} +22 -4
  34. package/dist/chunk-HA3VRF6E.js.map +1 -0
  35. package/dist/{chunk-I33FOKZ7.js → chunk-I2QGW4GD.js} +14 -12
  36. package/dist/chunk-I2QGW4GD.js.map +1 -0
  37. package/dist/{chunk-72UGRIMM.js → chunk-IE5ZNCWN.js} +5 -5
  38. package/dist/{chunk-72UGRIMM.js.map → chunk-IE5ZNCWN.js.map} +1 -1
  39. package/dist/{chunk-NDQD3ZRY.cjs → chunk-L7NE7PR4.cjs} +13 -13
  40. package/dist/{chunk-NDQD3ZRY.cjs.map → chunk-L7NE7PR4.cjs.map} +1 -1
  41. package/dist/{chunk-D57QZILZ.js → chunk-QEB6O6GU.js} +62 -37
  42. package/dist/chunk-QEB6O6GU.js.map +1 -0
  43. package/dist/{chunk-62AKSD5Y.js → chunk-QM4AV6EG.js} +39 -11
  44. package/dist/chunk-QM4AV6EG.js.map +1 -0
  45. package/dist/{chunk-LGCUOLP6.js → chunk-RT5FTHUU.js} +5 -5
  46. package/dist/{chunk-LGCUOLP6.js.map → chunk-RT5FTHUU.js.map} +1 -1
  47. package/dist/chunk-SRD4KVAP.cjs +2332 -0
  48. package/dist/chunk-SRD4KVAP.cjs.map +1 -0
  49. package/dist/{chunk-BVRUUYYR.cjs → chunk-UAYWLYFW.cjs} +18 -18
  50. package/dist/{chunk-BVRUUYYR.cjs.map → chunk-UAYWLYFW.cjs.map} +1 -1
  51. package/dist/{chunk-D4DQFTA7.cjs → chunk-UCKA22ZJ.cjs} +3 -2
  52. package/dist/chunk-UCKA22ZJ.cjs.map +1 -0
  53. package/dist/{chunk-F4TBCRGI.cjs → chunk-WKOV25NP.cjs} +42 -13
  54. package/dist/chunk-WKOV25NP.cjs.map +1 -0
  55. package/dist/{chunk-WTS34S5E.cjs → chunk-XMJE34FY.cjs} +13 -13
  56. package/dist/{chunk-WTS34S5E.cjs.map → chunk-XMJE34FY.cjs.map} +1 -1
  57. package/dist/{chunk-SWY6PWXK.js → chunk-YWQH35VO.js} +4 -4
  58. package/dist/{chunk-SWY6PWXK.js.map → chunk-YWQH35VO.js.map} +1 -1
  59. package/dist/{chunk-LB3FEV7Z.cjs → chunk-Z6TVOAO5.cjs} +84 -2
  60. package/dist/chunk-Z6TVOAO5.cjs.map +1 -0
  61. package/dist/{chunk-36FTYJWJ.cjs → chunk-ZH5WT2IE.cjs} +80 -55
  62. package/dist/chunk-ZH5WT2IE.cjs.map +1 -0
  63. package/dist/{chunk-BO6P723E.js → chunk-ZJMTHPHY.js} +3 -3
  64. package/dist/{chunk-BO6P723E.js.map → chunk-ZJMTHPHY.js.map} +1 -1
  65. package/dist/components/ActivityPreview.cjs +12 -12
  66. package/dist/components/ActivityPreview.d.cts +2 -2
  67. package/dist/components/ActivityPreview.d.ts +2 -2
  68. package/dist/components/ActivityPreview.js +11 -11
  69. package/dist/components/ActivitySequence.cjs +13 -13
  70. package/dist/components/ActivitySequence.d.cts +14 -7
  71. package/dist/components/ActivitySequence.d.ts +14 -7
  72. package/dist/components/ActivitySequence.js +12 -12
  73. package/dist/components/Dictation.cjs +5 -5
  74. package/dist/components/Dictation.d.cts +1 -1
  75. package/dist/components/Dictation.d.ts +1 -1
  76. package/dist/components/Dictation.js +4 -4
  77. package/dist/components/FillInTheBlanks.cjs +5 -5
  78. package/dist/components/FillInTheBlanks.d.cts +1 -1
  79. package/dist/components/FillInTheBlanks.d.ts +1 -1
  80. package/dist/components/FillInTheBlanks.js +4 -4
  81. package/dist/components/GapSelect.cjs +5 -5
  82. package/dist/components/GapSelect.d.cts +1 -1
  83. package/dist/components/GapSelect.d.ts +1 -1
  84. package/dist/components/GapSelect.js +4 -4
  85. package/dist/components/InteractiveVideo.cjs +26 -0
  86. package/dist/components/InteractiveVideo.cjs.map +1 -0
  87. package/dist/components/InteractiveVideo.d.cts +77 -0
  88. package/dist/components/InteractiveVideo.d.ts +77 -0
  89. package/dist/components/InteractiveVideo.js +17 -0
  90. package/dist/components/InteractiveVideo.js.map +1 -0
  91. package/dist/components/MultipleChoice.cjs +5 -5
  92. package/dist/components/MultipleChoice.d.cts +1 -1
  93. package/dist/components/MultipleChoice.d.ts +1 -1
  94. package/dist/components/MultipleChoice.js +4 -4
  95. package/dist/components/PronunciationFeedback.cjs +4 -4
  96. package/dist/components/PronunciationFeedback.d.cts +5 -2
  97. package/dist/components/PronunciationFeedback.d.ts +5 -2
  98. package/dist/components/PronunciationFeedback.js +3 -3
  99. package/dist/components/ReadAloud.cjs +6 -6
  100. package/dist/components/ReadAloud.d.cts +2 -2
  101. package/dist/components/ReadAloud.d.ts +2 -2
  102. package/dist/components/ReadAloud.js +5 -5
  103. package/dist/components/StimulusPanel.cjs +4 -4
  104. package/dist/components/StimulusPanel.d.cts +1 -1
  105. package/dist/components/StimulusPanel.d.ts +1 -1
  106. package/dist/components/StimulusPanel.js +3 -3
  107. package/dist/components/WrittenResponse.cjs +5 -5
  108. package/dist/components/WrittenResponse.d.cts +3 -3
  109. package/dist/components/WrittenResponse.d.ts +3 -3
  110. package/dist/components/WrittenResponse.js +4 -4
  111. package/dist/i18n/LkIntlProvider.cjs +7 -7
  112. package/dist/i18n/LkIntlProvider.d.cts +2 -2
  113. package/dist/i18n/LkIntlProvider.d.ts +2 -2
  114. package/dist/i18n/LkIntlProvider.js +1 -1
  115. package/dist/index.cjs +44 -39
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.d.cts +3 -2
  118. package/dist/index.d.ts +3 -2
  119. package/dist/index.js +15 -14
  120. package/dist/index.js.map +1 -1
  121. package/dist/{strings--ADnHcaA.d.cts → strings-5588Q4Te.d.cts} +118 -1
  122. package/dist/{strings-CtdSf2St.d.ts → strings-D0IWcsUm.d.ts} +118 -1
  123. package/dist/theme/ThemeProvider.cjs +6 -6
  124. package/dist/theme/ThemeProvider.js +1 -1
  125. package/dist/theme/defaults.css +2 -0
  126. package/dist/theme/skin.css +1365 -1
  127. package/package.json +13 -3
  128. package/dist/chunk-36FTYJWJ.cjs.map +0 -1
  129. package/dist/chunk-62AKSD5Y.js.map +0 -1
  130. package/dist/chunk-B2XQLU2E.cjs.map +0 -1
  131. package/dist/chunk-D4DQFTA7.cjs.map +0 -1
  132. package/dist/chunk-D57QZILZ.js.map +0 -1
  133. package/dist/chunk-F4TBCRGI.cjs.map +0 -1
  134. package/dist/chunk-I33FOKZ7.js.map +0 -1
  135. package/dist/chunk-J2CDPIRC.cjs.map +0 -1
  136. package/dist/chunk-LB3FEV7Z.cjs.map +0 -1
  137. package/dist/chunk-RXS455MR.js.map +0 -1
  138. package/dist/chunk-TDJEKXEP.js.map +0 -1
  139. package/dist/chunk-XIBOFTOL.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/WrittenResponse/WrittenResponse.tsx","../src/components/WrittenResponse/index.tsx"],"names":["WrittenResponse","jsx"],"mappings":"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","file":"chunk-LLXCX5KK.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n type CriterionScore,\n countWords,\n evaluate,\n type GradeRecord,\n type InteractionEvent,\n type ItemOutcome,\n type LearnerResponse,\n type ThemeTokens,\n validateActivity,\n type WrittenResponseData,\n type XAPIStatement,\n xAPIBuilder,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport type { LkStrings, LkStringsOverride } from '../../i18n/strings.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type {\n HtmlSanitizer,\n MediaBudgetBinding,\n MediaTransportStrings,\n Renderable,\n RenderMode,\n} from '../types.js';\n\n/**\n * Payload delivered when the learner submits a written response. Grading is\n * DEFERRED (asynchronous AI/human grading), so there is no score here — and\n * deliberately no fake one: an ungraded submission must never be shown or\n * stored as a 0. The consumer persists `text` and grades it out-of-band.\n */\nexport interface WrittenResponseSubmission {\n /** The submitted text, verbatim. */\n text: string;\n /** Word count of `text`, recomputed with the canonical `countWords()`. */\n wordCount: number;\n /** Whether `wordCount` falls within the activity's `[minWords, maxWords]`. */\n withinWordBounds: boolean;\n /** Time in milliseconds from first interaction to submission. */\n timeSpent: number;\n /** The SUBMITTED-verb xAPI statement built for this submission (no score fields). */\n xapiStatement: XAPIStatement;\n}\n\n/**\n * Props for {@link WrittenResponse}. Mirrors `ActivityProps` except for the\n * completion callback: a deferred-grading activity completes with a\n * {@link WrittenResponseSubmission} (`onSubmitted`), not a scored\n * `ActivityResult` (`onComplete`) — deviation from Req 22.8 recorded in the\n * roadmap (§3.1): fabricating a score of 0 for ungraded work is the exact\n * bug this type exists to fix. Everything else — controlled value, render\n * mode, server outcome, rich text — follows the shared `ActivityProps`\n * contract verbatim.\n */\nexport interface WrittenResponseProps {\n /** Activity content. Accepts a `redact()` projection in `exam` mode. */\n data: Renderable<WrittenResponseData>;\n /**\n * Called on submit with the ungraded submission (text, recomputed word\n * count, bounds flag, timing, xAPI statement). Fires in `practice` and\n * `exam` mode, after `onSubmit`; never in `review`.\n *\n * Optional since lk-react 2.1.0 so a `review`-mode render (which has no submit\n * control) and an exam runner that only wants the raw response through\n * `onSubmit` do not have to pass a no-op. Supply it in `practice`/`exam`\n * unless `onSubmit` already captures everything you persist.\n */\n onSubmitted?: (submission: WrittenResponseSubmission) => void;\n /**\n * Called on submit with the raw learner response and no grade, BEFORE\n * `onSubmitted`. This is the only submit callback an exam runner needs:\n * the server grades the text and returns an {@link ItemOutcome} later.\n */\n onSubmit?: (response: LearnerResponse) => void;\n /**\n * Controlled value: the learner's current response. When present the\n * textarea renders from it (never from internal state) and every keystroke\n * goes out through `onChange` — restore an in-progress attempt, autosave a\n * delta, or drive a review render with it.\n */\n value?: LearnerResponse;\n /** Initial response for an uncontrolled component (ignored when `value` is set). */\n defaultValue?: LearnerResponse;\n /**\n * Mount as already submitted — read at mount only. Without it a resumed\n * attempt reopens an essay the learner had already submitted as editable\n * and re-submittable.\n */\n defaultSubmitted?: boolean;\n /** Fires on every change to the learner's response. Required for a controlled component. */\n onChange?: (response: LearnerResponse) => void;\n /**\n * Presentation mode, default `practice`. `practice` and `exam` are nearly\n * identical here — a written response is never graded client-side, so\n * there is no local score to withhold; `exam` additionally never calls\n * `evaluate()` and renders happily from a `redact()` projection.\n * `review` is read-only and shows the server's `outcome`.\n */\n renderMode?: RenderMode;\n /**\n * Server-computed outcome, rendered by `review` mode: `deferred` shows a\n * \"not graded yet\" affordance, `scored` shows the returned grade and\n * feedback. Ignored in other modes — this component never manufactures an\n * outcome of its own.\n */\n outcome?: ItemOutcome;\n /** Renders `data.promptHtml` when provided. See `HtmlSanitizer`. */\n sanitizeHtml?: HtmlSanitizer;\n /** Binds this activity's own `data.media` to a play budget. See {@link MediaBudgetBinding}. */\n mediaBudget?: MediaBudgetBinding;\n /** Translations for the audio transport chrome. See {@link MediaTransportStrings}. */\n mediaStrings?: Partial<MediaTransportStrings>;\n /** Overrides the SDK's chrome text for this activity. See {@link LkIntlProvider}. */\n strings?: LkStringsOverride;\n onInteraction?: (event: InteractionEvent) => void;\n /** Per-instance token overrides, applied as inline CSS vars on the root. */\n theme?: Partial<ThemeTokens>;\n locale?: string;\n disabled?: boolean;\n}\n\n/**\n * Reads the text out of a learner response. Another activity type's response\n * shape (the `value`/`defaultValue` props take the `LearnerResponse` union,\n * so a generic runner can hand any of them over) reads as empty rather than\n * throwing mid-exam.\n */\nfunction textOf(response: LearnerResponse | undefined): string {\n return response !== undefined && response.type === 'written-response' ? response.text : '';\n}\n\n/**\n * One criterion's score as a percentage of its OWN maximum.\n *\n * `CriterionScore.maxScore` defaults to 1 — the SDK's scaled convention — but\n * a grader may work out of 100, or out of 9 for a CEFR band, and\n * `gradeFromRubric` deliberately stores those judgements verbatim so a grade\n * stays auditable in the units the grader actually used. It normalises when it\n * computes the total; anything DISPLAYING a criterion has to normalise too, or\n * a perfectly ordinary 82/100 renders as \"8200%\". This is the same guard the\n * overall score already applies against `outcome.maxScore`.\n */\nfunction criterionPercent(criterion: CriterionScore): string {\n const max = criterion.maxScore !== undefined && criterion.maxScore > 0 ? criterion.maxScore : 1;\n return `${Math.round(((criterion.score as number) / max) * 100)}%`;\n}\n\n/**\n * Renders the server-computed outcome in `review` mode. The grade shown here\n * always came back from the asynchronous grader — nothing on this path scores,\n * infers, or defaults a grade. A `written-response` outcome carries no\n * per-item `details` (there are no options or blanks to mark), so the render\n * is the scaled score, the pass state, and the grader's feedback.\n */\nfunction GradeBody({ grade, s }: { grade: GradeRecord; s: LkStrings }) {\n return (\n <>\n {grade.feedback ? <p className=\"lk-wr-grade-feedback\">{grade.feedback}</p> : null}\n {grade.criteria && grade.criteria.length > 0 ? (\n <ul className=\"lk-wr-criteria\">\n {grade.criteria.map((criterion) => (\n <li\n className=\"lk-wr-criterion\"\n key={criterion.name}\n data-na={String(criterion.notApplicable === true)}\n >\n <span className=\"lk-wr-criterion-name\">{criterion.name}</span>\n {criterion.notApplicable === true ? (\n <span className=\"lk-wr-criterion-score\">{s.notApplicable}</span>\n ) : (\n <span className=\"lk-wr-criterion-score\">\n {criterion.band ??\n (typeof criterion.score === 'number' ? criterionPercent(criterion) : '')}\n </span>\n )}\n {criterion.comment ? (\n <span className=\"lk-wr-criterion-comment\">{criterion.comment}</span>\n ) : null}\n </li>\n ))}\n </ul>\n ) : null}\n {grade.corrections && grade.corrections.length > 0 ? (\n <ul className=\"lk-wr-corrections\">\n {grade.corrections.map((correction) => (\n <li className=\"lk-wr-correction\" key={`${correction.original}:${correction.corrected}`}>\n <del className=\"lk-wr-correction-original\">{correction.original}</del>{' '}\n <ins className=\"lk-wr-correction-corrected\">{correction.corrected}</ins>\n {correction.explanation ? (\n <span className=\"lk-wr-correction-explanation\">{correction.explanation}</span>\n ) : null}\n </li>\n ))}\n </ul>\n ) : null}\n {grade.requiresHumanReview === true ? (\n <p className=\"lk-wr-review-flag\">{s.awaitingHumanReview}</p>\n ) : null}\n </>\n );\n}\n\n/**\n * Renders the server-computed outcome in `review` mode. The grade shown here\n * always came back from the grader — nothing on this path scores, infers, or\n * defaults a grade.\n */\nfunction OutcomeSummary({ outcome, s }: { outcome: ItemOutcome; s: LkStrings }) {\n if (outcome.status === 'scored' || outcome.status === 'graded') {\n // `score` is scaled [0–1] against `maxScore`; normalising by `maxScore`\n // is a no-op for the canonical maxScore of 1 and keeps an unscaled\n // grader payload (8.5 / 10) from rendering as 850%.\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return (\n <div\n className=\"lk-wr-outcome\"\n data-status={outcome.status}\n data-passed={String(outcome.passed)}\n >\n <p className=\"lk-wr-grade\">{s.scoreAnnouncement(percent, outcome.passed)}</p>\n {outcome.status === 'graded' ? (\n <GradeBody grade={outcome.grade} s={s} />\n ) : outcome.feedback ? (\n <p className=\"lk-wr-grade-feedback\">{outcome.feedback}</p>\n ) : null}\n </div>\n );\n }\n if (outcome.status === 'deferred') {\n return (\n <div className=\"lk-wr-outcome\" data-status=\"deferred\">\n <p className=\"lk-wr-grade\">{s.awaitingGrade}</p>\n </div>\n );\n }\n // `unscorable` reasons are developer-facing strings; surface the state, not\n // the reason, and leave it on the element for diagnostics.\n return (\n <div className=\"lk-wr-outcome\" data-status=\"unscorable\" data-reason={outcome.reason}>\n <p className=\"lk-wr-grade\">{s.couldNotBeGraded}</p>\n </div>\n );\n}\n\nexport function WrittenResponse({\n data,\n onSubmitted,\n onSubmit,\n value,\n defaultValue,\n defaultSubmitted,\n onChange,\n renderMode = 'practice',\n outcome,\n sanitizeHtml,\n mediaBudget,\n mediaStrings,\n strings,\n onInteraction,\n theme,\n locale,\n disabled,\n}: WrittenResponseProps) {\n // Dev-only boundary validation (Req 2.3), same convention as MC/FIB. The\n // content schema is loose, so a `redact()` projection validates too.\n const s = useLkStrings(strings);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n const result = validateActivity('written-response', data);\n return result.success ? null : new ActivitySchemaError('written-response', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n const isControlled = value !== undefined;\n const [innerText, setInnerText] = useState<string>(() => textOf(defaultValue));\n const [summary, setSummary] = useState<string | null>(null);\n\n /**\n * Rich text is rendered ONLY through a caller-supplied sanitiser, and only\n * when the author actually shipped the HTML sidecar. Without both, the\n * plain-text prompt is rendered as an escaped React child.\n */\n const promptHtml = useMemo(() => {\n if (sanitizeHtml === undefined || typeof data.promptHtml !== 'string') {\n return null;\n }\n return sanitizeHtml(data.promptHtml);\n }, [data.promptHtml, sanitizeHtml]);\n\n // Latest seed text, kept in a ref so `defaultValue` is NOT a reset trigger:\n // callers pass an object literal, whose identity changes every render.\n const defaultTextRef = useRef<string>(textOf(defaultValue));\n useEffect(() => {\n defaultTextRef.current = textOf(defaultValue);\n }, [defaultValue]);\n\n // Reset on data-prop change (Req 3.7): back to the seed (empty when there\n // is none — the v1 behaviour), never the previous activity's draft.\n // Mirror `defaultSubmitted` so the reset below returns to the SEEDED state.\n // Resetting unconditionally to idle unlocked an item the learner had already\n // committed — which made `defaultSubmitted` a no-op here, since this effect\n // runs right after the first paint.\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity guard so the MOUNT run is a no-op. Without it this effect fires\n // after the first paint and undoes every seed it was just given; with it,\n // only a real `data` change resets. A parent that rebuilds structurally\n // identical entries in render (`activities={raw.map(redact)}`) must not\n // unlock or revert a restored answer — the pager already remounts a slot\n // whose activity actually changed, via its key.\n const lastDataRef = useRef(data);\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInnerText(defaultTextRef.current);\n setSummary(null);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n if (devError) {\n throw devError;\n }\n\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n\n const text = isControlled ? textOf(value) : innerText;\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n const wordCount = countWords(text);\n const withinBounds = wordCount >= data.minWords && wordCount <= data.maxWords;\n\n const handleChange = (next: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n // A controlled component renders from `props.value` only; the caller's\n // state is the single source of truth for the text.\n if (!isControlled) {\n setInnerText(next);\n }\n const nextWordCount = countWords(next);\n onChange?.({ type: 'written-response', text: next, wordCount: nextWordCount });\n onInteraction?.({\n type: 'text-changed',\n activityId: data.id,\n timestamp: Date.now(),\n payload: { wordCount: nextWordCount },\n });\n };\n\n // Practice reveals nothing an essay could leak, but it DOES run the local\n // submit path and emit a practice xAPI statement for work the server is\n // supposed to grade. MultipleChoice and FillInTheBlanks have refused\n // redacted data in `practice` since 0.5.0; this component silently accepted\n // it, so an all-essay redacted paper mounted without `renderMode` looked\n // entirely healthy end to end. Fail at render, like its siblings.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Written Response \"${data.id}\" received redacted activity data in renderMode \"practice\". ` +\n 'Practice runs the local submit path and emits a practice-mode xAPI statement, so an ' +\n 'exam item wired this way is graded nowhere and looks fine while it happens. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive || text.trim().length === 0) {\n return;\n }\n let finalWordCount = wordCount;\n let finalWithinBounds = withinBounds;\n // `exam` mode must not call evaluate(): the component does not grade, and\n // a redacted projection carries no scoring input anyway. The two facts\n // evaluate() returns for a deferred type (recomputed word count, bounds)\n // are exactly what is computed above, so the payload is identical either\n // way; practice keeps going through core so the numbers stay canonical.\n if (!isExam) {\n const itemOutcome = evaluate(data, { type: 'written-response', text, wordCount });\n const partial = itemOutcome.status === 'deferred' ? itemOutcome.partial : undefined;\n if (typeof partial?.wordCount === 'number') {\n finalWordCount = partial.wordCount;\n }\n if (typeof partial?.withinWordBounds === 'boolean') {\n finalWithinBounds = partial.withinWordBounds;\n }\n }\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildSubmittedStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n type: 'http://adlnet.gov/expapi/activities/cmi.interaction',\n interactionType: 'long-fill-in',\n },\n timeSpentMs: timeSpent,\n response: text,\n resultExtensions: {\n 'urn:learning-kit:extension:word-count': finalWordCount,\n 'urn:learning-kit:extension:within-word-bounds': finalWithinBounds,\n },\n });\n // Raw response first (an exam runner persists this), then the fuller\n // ungraded submission — mirroring `onSubmit` before `onComplete`.\n onSubmit?.({ type: 'written-response', text, wordCount: finalWordCount });\n onSubmitted?.({\n text,\n wordCount: finalWordCount,\n withinWordBounds: finalWithinBounds,\n timeSpent,\n xapiStatement,\n });\n setSummary(s.responseSubmitted);\n onInteraction?.({\n type: 'submitted',\n activityId: data.id,\n timestamp: Date.now(),\n payload: { wordCount: finalWordCount, withinWordBounds: finalWithinBounds },\n });\n };\n\n const promptId = `${data.id}-prompt`;\n const counterId = `${data.id}-counter`;\n const boundsLabel = s.wordBounds(data.minWords, data.maxWords);\n\n return (\n <form\n className=\"lk-wr\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n {promptHtml === null ? (\n <p className=\"lk-wr-prompt\" id={promptId}>\n {data.prompt}\n </p>\n ) : (\n // A div, not a p: sanitised author HTML may contain block content.\n <div\n className=\"lk-wr-prompt\"\n id={promptId}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: rendered only through the caller-supplied HtmlSanitizer — the SDK never injects unsanitised markup\n dangerouslySetInnerHTML={{ __html: promptHtml }}\n />\n )}\n <textarea\n className=\"lk-wr-textarea\"\n aria-labelledby={promptId}\n aria-describedby={counterId}\n value={text}\n onChange={(event) => handleChange(event.target.value)}\n // `review` uses readOnly rather than disabled: the submitted essay\n // must stay focusable, selectable and scrollable for a screen reader\n // and a keyboard, while remaining uneditable.\n disabled={!isReview && inactive}\n readOnly={isReview}\n rows={8}\n />\n <div\n className=\"lk-wr-counter\"\n id={counterId}\n aria-live=\"polite\"\n data-within-bounds={withinBounds}\n >\n {s.wordCount(wordCount)} ({boundsLabel})\n </div>\n {isReview ? null : (\n <button\n type=\"submit\"\n className=\"lk-wr-submit\"\n disabled={inactive || text.trim().length === 0}\n >\n {s.submit}\n </button>\n )}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? outcome ? <OutcomeSummary outcome={outcome} s={s} /> : null : summary}\n </FeedbackRegion>\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport {\n WrittenResponse as WrittenResponseCore,\n type WrittenResponseProps,\n} from './WrittenResponse.js';\n\nexport type { HtmlSanitizer, Renderable, RenderMode } from '../types.js';\nexport type { WrittenResponseProps, WrittenResponseSubmission } from './WrittenResponse.js';\n\n/**\n * Public Written Response activity: a labelled textarea with a live word\n * counter for free-text writing graded asynchronously (AI or human). The core\n * is wrapped in `ActivityErrorBoundary` so a render failure (incl. the dev\n * schema-validation throw) degrades to an accessible fallback.\n */\nexport function WrittenResponse(props: WrittenResponseProps) {\n // Read here rather than in the boundary: a class component cannot call a\n // hook, and the fallback it renders is learner-facing text like any other.\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <WrittenResponseCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/WrittenResponse/WrittenResponse.tsx","../src/components/WrittenResponse/index.tsx"],"names":["WrittenResponse","jsx"],"mappings":"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","file":"chunk-AF72QUBI.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n type CriterionScore,\n countWords,\n evaluate,\n type GradeRecord,\n type InteractionEvent,\n type ItemOutcome,\n type LearnerResponse,\n type ThemeTokens,\n validateActivity,\n type WrittenResponseData,\n type XAPIStatement,\n xAPIBuilder,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport type { LkStrings, LkStringsOverride } from '../../i18n/strings.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type {\n HtmlSanitizer,\n MediaBudgetBinding,\n MediaTransportStrings,\n Renderable,\n RenderMode,\n} from '../types.js';\n\n/**\n * Payload delivered when the learner submits a written response. Grading is\n * DEFERRED (asynchronous AI/human grading), so there is no score here — and\n * deliberately no fake one: an ungraded submission must never be shown or\n * stored as a 0. The consumer persists `text` and grades it out-of-band.\n */\nexport interface WrittenResponseSubmission {\n /** The submitted text, verbatim. */\n text: string;\n /** Word count of `text`, recomputed with the canonical `countWords()`. */\n wordCount: number;\n /** Whether `wordCount` falls within the activity's `[minWords, maxWords]`. */\n withinWordBounds: boolean;\n /** Time in milliseconds from first interaction to submission. */\n timeSpent: number;\n /** The SUBMITTED-verb xAPI statement built for this submission (no score fields). */\n xapiStatement: XAPIStatement;\n}\n\n/**\n * Props for {@link WrittenResponse}. Mirrors `ActivityProps` except for the\n * completion callback: a deferred-grading activity completes with a\n * {@link WrittenResponseSubmission} (`onSubmitted`), not a scored\n * `ActivityResult` (`onComplete`) — deviation from Req 22.8 recorded in the\n * roadmap (§3.1): fabricating a score of 0 for ungraded work is the exact\n * bug this type exists to fix. Everything else — controlled value, render\n * mode, server outcome, rich text — follows the shared `ActivityProps`\n * contract verbatim.\n */\nexport interface WrittenResponseProps {\n /** Activity content. Accepts a `redact()` projection in `exam` mode. */\n data: Renderable<WrittenResponseData>;\n /**\n * Called on submit with the ungraded submission (text, recomputed word\n * count, bounds flag, timing, xAPI statement). Fires in `practice` and\n * `exam` mode, after `onSubmit`; never in `review`.\n *\n * Optional since lk-react 2.1.0 so a `review`-mode render (which has no submit\n * control) and an exam runner that only wants the raw response through\n * `onSubmit` do not have to pass a no-op. Supply it in `practice`/`exam`\n * unless `onSubmit` already captures everything you persist.\n */\n onSubmitted?: (submission: WrittenResponseSubmission) => void;\n /**\n * Called on submit with the raw learner response and no grade, BEFORE\n * `onSubmitted`. This is the only submit callback an exam runner needs:\n * the server grades the text and returns an {@link ItemOutcome} later.\n */\n onSubmit?: (response: LearnerResponse) => void;\n /**\n * Controlled value: the learner's current response. When present the\n * textarea renders from it (never from internal state) and every keystroke\n * goes out through `onChange` — restore an in-progress attempt, autosave a\n * delta, or drive a review render with it.\n */\n value?: LearnerResponse;\n /** Initial response for an uncontrolled component (ignored when `value` is set). */\n defaultValue?: LearnerResponse;\n /**\n * Mount as already submitted — read at mount only. Without it a resumed\n * attempt reopens an essay the learner had already submitted as editable\n * and re-submittable.\n */\n defaultSubmitted?: boolean;\n /** Fires on every change to the learner's response. Required for a controlled component. */\n onChange?: (response: LearnerResponse) => void;\n /**\n * Presentation mode, default `practice`. `practice` and `exam` are nearly\n * identical here — a written response is never graded client-side, so\n * there is no local score to withhold; `exam` additionally never calls\n * `evaluate()` and renders happily from a `redact()` projection.\n * `review` is read-only and shows the server's `outcome`.\n */\n renderMode?: RenderMode;\n /**\n * Server-computed outcome, rendered by `review` mode: `deferred` shows a\n * \"not graded yet\" affordance, `scored` shows the returned grade and\n * feedback. Ignored in other modes — this component never manufactures an\n * outcome of its own.\n */\n outcome?: ItemOutcome;\n /** Renders `data.promptHtml` when provided. See `HtmlSanitizer`. */\n sanitizeHtml?: HtmlSanitizer;\n /** Binds this activity's own `data.media` to a play budget. See {@link MediaBudgetBinding}. */\n mediaBudget?: MediaBudgetBinding;\n /** Translations for the audio transport chrome. See {@link MediaTransportStrings}. */\n mediaStrings?: Partial<MediaTransportStrings>;\n /** Overrides the SDK's chrome text for this activity. See {@link LkIntlProvider}. */\n strings?: LkStringsOverride;\n onInteraction?: (event: InteractionEvent) => void;\n /** Per-instance token overrides, applied as inline CSS vars on the root. */\n theme?: Partial<ThemeTokens>;\n locale?: string;\n disabled?: boolean;\n}\n\n/**\n * Reads the text out of a learner response. Another activity type's response\n * shape (the `value`/`defaultValue` props take the `LearnerResponse` union,\n * so a generic runner can hand any of them over) reads as empty rather than\n * throwing mid-exam.\n */\nfunction textOf(response: LearnerResponse | undefined): string {\n return response !== undefined && response.type === 'written-response' ? response.text : '';\n}\n\n/**\n * One criterion's score as a percentage of its OWN maximum.\n *\n * `CriterionScore.maxScore` defaults to 1 — the SDK's scaled convention — but\n * a grader may work out of 100, or out of 9 for a CEFR band, and\n * `gradeFromRubric` deliberately stores those judgements verbatim so a grade\n * stays auditable in the units the grader actually used. It normalises when it\n * computes the total; anything DISPLAYING a criterion has to normalise too, or\n * a perfectly ordinary 82/100 renders as \"8200%\". This is the same guard the\n * overall score already applies against `outcome.maxScore`.\n */\nfunction criterionPercent(criterion: CriterionScore): string {\n const max = criterion.maxScore !== undefined && criterion.maxScore > 0 ? criterion.maxScore : 1;\n return `${Math.round(((criterion.score as number) / max) * 100)}%`;\n}\n\n/**\n * Renders the server-computed outcome in `review` mode. The grade shown here\n * always came back from the asynchronous grader — nothing on this path scores,\n * infers, or defaults a grade. A `written-response` outcome carries no\n * per-item `details` (there are no options or blanks to mark), so the render\n * is the scaled score, the pass state, and the grader's feedback.\n */\nfunction GradeBody({ grade, s }: { grade: GradeRecord; s: LkStrings }) {\n return (\n <>\n {grade.feedback ? <p className=\"lk-wr-grade-feedback\">{grade.feedback}</p> : null}\n {grade.criteria && grade.criteria.length > 0 ? (\n <ul className=\"lk-wr-criteria\">\n {grade.criteria.map((criterion) => (\n <li\n className=\"lk-wr-criterion\"\n key={criterion.name}\n data-na={String(criterion.notApplicable === true)}\n >\n <span className=\"lk-wr-criterion-name\">{criterion.name}</span>\n {criterion.notApplicable === true ? (\n <span className=\"lk-wr-criterion-score\">{s.notApplicable}</span>\n ) : (\n <span className=\"lk-wr-criterion-score\">\n {criterion.band ??\n (typeof criterion.score === 'number' ? criterionPercent(criterion) : '')}\n </span>\n )}\n {criterion.comment ? (\n <span className=\"lk-wr-criterion-comment\">{criterion.comment}</span>\n ) : null}\n </li>\n ))}\n </ul>\n ) : null}\n {grade.corrections && grade.corrections.length > 0 ? (\n <ul className=\"lk-wr-corrections\">\n {grade.corrections.map((correction) => (\n <li className=\"lk-wr-correction\" key={`${correction.original}:${correction.corrected}`}>\n <del className=\"lk-wr-correction-original\">{correction.original}</del>{' '}\n <ins className=\"lk-wr-correction-corrected\">{correction.corrected}</ins>\n {correction.explanation ? (\n <span className=\"lk-wr-correction-explanation\">{correction.explanation}</span>\n ) : null}\n </li>\n ))}\n </ul>\n ) : null}\n {grade.requiresHumanReview === true ? (\n <p className=\"lk-wr-review-flag\">{s.awaitingHumanReview}</p>\n ) : null}\n </>\n );\n}\n\n/**\n * Renders the server-computed outcome in `review` mode. The grade shown here\n * always came back from the grader — nothing on this path scores, infers, or\n * defaults a grade.\n */\nfunction OutcomeSummary({ outcome, s }: { outcome: ItemOutcome; s: LkStrings }) {\n if (outcome.status === 'scored' || outcome.status === 'graded') {\n // `score` is scaled [0–1] against `maxScore`; normalising by `maxScore`\n // is a no-op for the canonical maxScore of 1 and keeps an unscaled\n // grader payload (8.5 / 10) from rendering as 850%.\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return (\n <div\n className=\"lk-wr-outcome\"\n data-status={outcome.status}\n data-passed={String(outcome.passed)}\n >\n <p className=\"lk-wr-grade\">{s.scoreAnnouncement(percent, outcome.passed)}</p>\n {outcome.status === 'graded' ? (\n <GradeBody grade={outcome.grade} s={s} />\n ) : outcome.feedback ? (\n <p className=\"lk-wr-grade-feedback\">{outcome.feedback}</p>\n ) : null}\n </div>\n );\n }\n if (outcome.status === 'deferred') {\n return (\n <div className=\"lk-wr-outcome\" data-status=\"deferred\">\n <p className=\"lk-wr-grade\">{s.awaitingGrade}</p>\n </div>\n );\n }\n // `unscorable` reasons are developer-facing strings; surface the state, not\n // the reason, and leave it on the element for diagnostics.\n return (\n <div className=\"lk-wr-outcome\" data-status=\"unscorable\" data-reason={outcome.reason}>\n <p className=\"lk-wr-grade\">{s.couldNotBeGraded}</p>\n </div>\n );\n}\n\nexport function WrittenResponse({\n data,\n onSubmitted,\n onSubmit,\n value,\n defaultValue,\n defaultSubmitted,\n onChange,\n renderMode = 'practice',\n outcome,\n sanitizeHtml,\n mediaBudget,\n mediaStrings,\n strings,\n onInteraction,\n theme,\n locale,\n disabled,\n}: WrittenResponseProps) {\n // Dev-only boundary validation (Req 2.3), same convention as MC/FIB. The\n // content schema is loose, so a `redact()` projection validates too.\n const s = useLkStrings(strings);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n const result = validateActivity('written-response', data);\n return result.success ? null : new ActivitySchemaError('written-response', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n const isControlled = value !== undefined;\n const [innerText, setInnerText] = useState<string>(() => textOf(defaultValue));\n const [summary, setSummary] = useState<string | null>(null);\n\n /**\n * Rich text is rendered ONLY through a caller-supplied sanitiser, and only\n * when the author actually shipped the HTML sidecar. Without both, the\n * plain-text prompt is rendered as an escaped React child.\n */\n const promptHtml = useMemo(() => {\n if (sanitizeHtml === undefined || typeof data.promptHtml !== 'string') {\n return null;\n }\n return sanitizeHtml(data.promptHtml);\n }, [data.promptHtml, sanitizeHtml]);\n\n // Latest seed text, kept in a ref so `defaultValue` is NOT a reset trigger:\n // callers pass an object literal, whose identity changes every render.\n const defaultTextRef = useRef<string>(textOf(defaultValue));\n useEffect(() => {\n defaultTextRef.current = textOf(defaultValue);\n }, [defaultValue]);\n\n // Reset on data-prop change (Req 3.7): back to the seed (empty when there\n // is none — the v1 behaviour), never the previous activity's draft.\n // Mirror `defaultSubmitted` so the reset below returns to the SEEDED state.\n // Resetting unconditionally to idle unlocked an item the learner had already\n // committed — which made `defaultSubmitted` a no-op here, since this effect\n // runs right after the first paint.\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity guard so the MOUNT run is a no-op. Without it this effect fires\n // after the first paint and undoes every seed it was just given; with it,\n // only a real `data` change resets. A parent that rebuilds structurally\n // identical entries in render (`activities={raw.map(redact)}`) must not\n // unlock or revert a restored answer — the pager already remounts a slot\n // whose activity actually changed, via its key.\n const lastDataRef = useRef(data);\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInnerText(defaultTextRef.current);\n setSummary(null);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n if (devError) {\n throw devError;\n }\n\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n\n const text = isControlled ? textOf(value) : innerText;\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n const wordCount = countWords(text);\n const withinBounds = wordCount >= data.minWords && wordCount <= data.maxWords;\n\n const handleChange = (next: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n // A controlled component renders from `props.value` only; the caller's\n // state is the single source of truth for the text.\n if (!isControlled) {\n setInnerText(next);\n }\n const nextWordCount = countWords(next);\n onChange?.({ type: 'written-response', text: next, wordCount: nextWordCount });\n onInteraction?.({\n type: 'text-changed',\n activityId: data.id,\n timestamp: Date.now(),\n payload: { wordCount: nextWordCount },\n });\n };\n\n // Practice reveals nothing an essay could leak, but it DOES run the local\n // submit path and emit a practice xAPI statement for work the server is\n // supposed to grade. MultipleChoice and FillInTheBlanks have refused\n // redacted data in `practice` since 0.5.0; this component silently accepted\n // it, so an all-essay redacted paper mounted without `renderMode` looked\n // entirely healthy end to end. Fail at render, like its siblings.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Written Response \"${data.id}\" received redacted activity data in renderMode \"practice\". ` +\n 'Practice runs the local submit path and emits a practice-mode xAPI statement, so an ' +\n 'exam item wired this way is graded nowhere and looks fine while it happens. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive || text.trim().length === 0) {\n return;\n }\n let finalWordCount = wordCount;\n let finalWithinBounds = withinBounds;\n // `exam` mode must not call evaluate(): the component does not grade, and\n // a redacted projection carries no scoring input anyway. The two facts\n // evaluate() returns for a deferred type (recomputed word count, bounds)\n // are exactly what is computed above, so the payload is identical either\n // way; practice keeps going through core so the numbers stay canonical.\n if (!isExam) {\n const itemOutcome = evaluate(data, { type: 'written-response', text, wordCount });\n const partial = itemOutcome.status === 'deferred' ? itemOutcome.partial : undefined;\n if (typeof partial?.wordCount === 'number') {\n finalWordCount = partial.wordCount;\n }\n if (typeof partial?.withinWordBounds === 'boolean') {\n finalWithinBounds = partial.withinWordBounds;\n }\n }\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildSubmittedStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n type: 'http://adlnet.gov/expapi/activities/cmi.interaction',\n interactionType: 'long-fill-in',\n },\n timeSpentMs: timeSpent,\n response: text,\n resultExtensions: {\n 'urn:learning-kit:extension:word-count': finalWordCount,\n 'urn:learning-kit:extension:within-word-bounds': finalWithinBounds,\n },\n });\n // Raw response first (an exam runner persists this), then the fuller\n // ungraded submission — mirroring `onSubmit` before `onComplete`.\n onSubmit?.({ type: 'written-response', text, wordCount: finalWordCount });\n onSubmitted?.({\n text,\n wordCount: finalWordCount,\n withinWordBounds: finalWithinBounds,\n timeSpent,\n xapiStatement,\n });\n setSummary(s.responseSubmitted);\n onInteraction?.({\n type: 'submitted',\n activityId: data.id,\n timestamp: Date.now(),\n payload: { wordCount: finalWordCount, withinWordBounds: finalWithinBounds },\n });\n };\n\n const promptId = `${data.id}-prompt`;\n const counterId = `${data.id}-counter`;\n const boundsLabel = s.wordBounds(data.minWords, data.maxWords);\n\n return (\n <form\n className=\"lk-wr\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n {promptHtml === null ? (\n <p className=\"lk-wr-prompt\" id={promptId}>\n {data.prompt}\n </p>\n ) : (\n // A div, not a p: sanitised author HTML may contain block content.\n <div\n className=\"lk-wr-prompt\"\n id={promptId}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: rendered only through the caller-supplied HtmlSanitizer — the SDK never injects unsanitised markup\n dangerouslySetInnerHTML={{ __html: promptHtml }}\n />\n )}\n <textarea\n className=\"lk-wr-textarea\"\n aria-labelledby={promptId}\n aria-describedby={counterId}\n value={text}\n onChange={(event) => handleChange(event.target.value)}\n // `review` uses readOnly rather than disabled: the submitted essay\n // must stay focusable, selectable and scrollable for a screen reader\n // and a keyboard, while remaining uneditable.\n disabled={!isReview && inactive}\n readOnly={isReview}\n rows={8}\n />\n <div\n className=\"lk-wr-counter\"\n id={counterId}\n aria-live=\"polite\"\n data-within-bounds={withinBounds}\n >\n {s.wordCount(wordCount)} ({boundsLabel})\n </div>\n {isReview ? null : (\n <button\n type=\"submit\"\n className=\"lk-wr-submit\"\n disabled={inactive || text.trim().length === 0}\n >\n {s.submit}\n </button>\n )}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? outcome ? <OutcomeSummary outcome={outcome} s={s} /> : null : summary}\n </FeedbackRegion>\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport {\n WrittenResponse as WrittenResponseCore,\n type WrittenResponseProps,\n} from './WrittenResponse.js';\n\nexport type { HtmlSanitizer, Renderable, RenderMode } from '../types.js';\nexport type { WrittenResponseProps, WrittenResponseSubmission } from './WrittenResponse.js';\n\n/**\n * Public Written Response activity: a labelled textarea with a live word\n * counter for free-text writing graded asynchronously (AI or human). The core\n * is wrapped in `ActivityErrorBoundary` so a render failure (incl. the dev\n * schema-validation throw) degrades to an accessible fallback.\n */\nexport function WrittenResponse(props: WrittenResponseProps) {\n // Read here rather than in the boundary: a class component cannot call a\n // hook, and the fallback it renders is learner-facing text like any other.\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <WrittenResponseCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { FeedbackRegion } from './chunk-RCMYEWBE.js';
3
- import { ActivityErrorBoundary, isDevelopment, randomSessionId, ANONYMOUS_ACTOR, objectIdFor } from './chunk-BO6P723E.js';
4
- import { ActivityMedia } from './chunk-XIBOFTOL.js';
3
+ import { ActivityErrorBoundary, isDevelopment, randomSessionId, ANONYMOUS_ACTOR, objectIdFor } from './chunk-ZJMTHPHY.js';
4
+ import { ActivityMedia } from './chunk-HA3VRF6E.js';
5
5
  import { useActivityState } from './chunk-6N43WDVG.js';
6
- import { useLkStrings } from './chunk-TDJEKXEP.js';
6
+ import { useLkStrings } from './chunk-52GXJNQ3.js';
7
7
  import { assertRedacted, validateActivity, ActivitySchemaError, seededShuffle, score, xAPIBuilder, xapiDefinitionFor } from '@intellectif/lk-core';
8
8
  import { useMemo, useState, useRef, useEffect } from 'react';
9
9
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -315,5 +315,5 @@ function GapSelect2(props) {
315
315
  }
316
316
 
317
317
  export { GapSelect2 as GapSelect };
318
- //# sourceMappingURL=chunk-XUEIUEPI.js.map
319
- //# sourceMappingURL=chunk-XUEIUEPI.js.map
318
+ //# sourceMappingURL=chunk-CE6OGJE6.js.map
319
+ //# sourceMappingURL=chunk-CE6OGJE6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/GapSelect/GapSelect.tsx","../src/components/GapSelect/index.tsx"],"names":["result","GapSelect","jsx"],"mappings":"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","file":"chunk-XUEIUEPI.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n assertRedacted,\n type GapSelectBank,\n type GapSelectChoice,\n type GapSelectData,\n type GapSelectGap,\n type GapSelectLearnerResponse,\n type LearnerResponse,\n type ScoringDetail,\n type ScoringResult,\n score,\n seededShuffle,\n validateActivity,\n xAPIBuilder,\n xapiDefinitionFor,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor, randomSessionId } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type { ActivityProps } from '../types.js';\n\nexport interface GapSelectProps extends ActivityProps<GapSelectData> {\n /**\n * Seeds the per-gap choice shuffle when `data.shuffleChoices` is set. Pass\n * the attempt id, exactly as on `<MultipleChoice>`: an order nobody can\n * reproduce cannot be reconciled with the attempt a server recorded. Without\n * one, a random per-mount seed is used — stable within the mount, and\n * deliberately not reproducible.\n */\n shuffleSeed?: string;\n}\n\nconst PLACEHOLDER = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\ntype Segment = { kind: 'text'; value: string } | { kind: 'gap'; id: string; ordinal: number };\n\n/** Splits a passage into literal text and its `{{id}}` gaps, in order. */\nfunction parsePassage(passage: string): Segment[] {\n const segments: Segment[] = [];\n const re = new RegExp(PLACEHOLDER);\n let last = 0;\n let ordinal = 0;\n let match = re.exec(passage);\n while (match !== null) {\n if (match.index > last) {\n segments.push({ kind: 'text', value: passage.slice(last, match.index) });\n }\n ordinal += 1;\n segments.push({ kind: 'gap', id: match[1] as string, ordinal });\n last = match.index + match[0].length;\n match = re.exec(passage);\n }\n if (last < passage.length) {\n segments.push({ kind: 'text', value: passage.slice(last) });\n }\n return segments;\n}\n\nconst NO_SELECTIONS: Record<string, string> = {};\n\n/**\n * The selections out of a `LearnerResponse`. A response of another activity\n * type reads as \"nothing selected\" rather than throwing — a controlled host\n * that has not yet swapped its state on an activity change would otherwise\n * crash the attempt.\n */\nfunction selectionsOf(response: LearnerResponse | undefined): Record<string, string> {\n return response !== undefined && response.type === 'gap-select'\n ? response.selections\n : NO_SELECTIONS;\n}\n\n/** Per-gap correctness keyed by gap id, preferring the unambiguous `outcome`. */\nfunction correctnessByItem(details: readonly ScoringDetail[]): Map<string, boolean> {\n const map = new Map<string, boolean>();\n for (const detail of details) {\n map.set(\n detail.itemId,\n detail.outcome !== undefined ? detail.outcome === 'correct' : detail.correct,\n );\n }\n return map;\n}\n\n/**\n * The choices a gap offers: its own list, or the bank it names.\n *\n * Both survive redaction — they are what the learner picks from — so this is\n * the one resolution that works identically on full and redacted data.\n */\nfunction choicesFor(\n banks: readonly GapSelectBank[] | undefined,\n gap: GapSelectGap,\n): readonly GapSelectChoice[] {\n if (gap.choices !== undefined) {\n return gap.choices;\n }\n return banks?.find((bank) => bank.id === gap.bankId)?.choices ?? [];\n}\n\nexport function GapSelect({\n data,\n onComplete,\n onSubmit,\n onChange,\n onInteraction,\n value,\n defaultValue,\n defaultSubmitted,\n renderMode = 'practice',\n outcome,\n mediaBudget,\n mediaStrings,\n strings,\n theme,\n locale,\n disabled,\n shuffleSeed,\n}: GapSelectProps) {\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n const s = useLkStrings(strings);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n if (data.redacted === true) {\n try {\n assertRedacted(data);\n return null;\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n }\n const result = validateActivity('gap-select', data);\n return result.success ? null : new ActivitySchemaError('gap-select', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n const isControlled = value !== undefined;\n const [internalSelections, setInternalSelections] = useState<Record<string, string>>(() =>\n selectionsOf(defaultValue),\n );\n const [result, setResult] = useState<ScoringResult | null>(null);\n const [summary, setSummary] = useState<string | null>(null);\n const [feedbackHidden, setFeedbackHidden] = useState(false);\n\n const selections = isControlled ? selectionsOf(value) : internalSelections;\n\n const defaultValueRef = useRef(defaultValue);\n useEffect(() => {\n defaultValueRef.current = defaultValue;\n }, [defaultValue]);\n\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity-guarded so the mount run is a no-op: without it this fires after\n // the first paint and undoes every seed it was just given (Req 3.7).\n const lastDataRef = useRef(data);\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInternalSelections(selectionsOf(defaultValueRef.current));\n setResult(null);\n setSummary(null);\n setFeedbackHidden(false);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n const segments = useMemo(() => parsePassage(data.passage), [data.passage]);\n const gapById = useMemo(() => new Map(data.gaps.map((gap) => [gap.id, gap])), [data.gaps]);\n\n const sessionIdRef = useRef<string | null>(null);\n /**\n * The choices each gap shows, in the order it shows them.\n *\n * Seeded PER GAP, not once for the activity: two gaps drawing on the same\n * word bank must not be dealt the same order, or the bank's distractors line\n * up column-wise and the second gap becomes easier than the first.\n */\n const choicesByGap = useMemo(() => {\n const map = new Map<string, readonly GapSelectChoice[]>();\n // biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization\n const seedSource = shuffleSeed ?? (sessionIdRef.current ??= randomSessionId());\n for (const gap of data.gaps) {\n const choices = choicesFor(data.banks, gap);\n map.set(\n gap.id,\n data.shuffleChoices === true\n ? seededShuffle(choices, `${seedSource}:${data.id}:${gap.id}`)\n : choices,\n );\n }\n return map;\n }, [data, shuffleSeed]);\n\n // All hooks are called before these throws, so hook order stays stable.\n if (devError) {\n throw devError;\n }\n // Practice grades locally, and a redacted projection has no answer key to\n // grade against — `score()` would throw RedactedScoringError from the submit\n // handler, where no error boundary can reach it and after the learner has\n // answered. Fail at render instead, in production too, exactly as every other\n // built-in does.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Gap Select \"${data.id}\" received redacted activity data in renderMode \"practice\", ` +\n 'which grades locally and has no answer key to grade against. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n\n /**\n * Whether answer-key-derived information may be shown. Never in `exam`; in\n * `practice` only once this component has scored; in `review` only once the\n * caller supplies a SCORED outcome.\n */\n const revealing = isReview ? outcome?.status === 'scored' : !isExam && submitted;\n\n const fireInteraction = (\n type: 'gap-selected' | 'submitted',\n payload: Record<string, unknown>,\n ): void => {\n onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });\n };\n\n const handleSelect = (gapId: string, choiceId: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n const next = { ...selections, [gapId]: choiceId };\n if (!isControlled) {\n setInternalSelections(next);\n }\n onChange?.({ type: 'gap-select', selections: next });\n fireInteraction('gap-selected', { gapId, choiceId });\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive) {\n return;\n }\n const response: GapSelectLearnerResponse = { type: 'gap-select', selections };\n onSubmit?.(response);\n\n if (isExam) {\n // The client neither grades nor reveals: no score(), no read of any\n // answer-key field, no onComplete, and no xAPI statement — its\n // correctResponsesPattern IS the answer key.\n complete();\n setSummary(s.answerSubmitted);\n fireInteraction('submitted', { selections });\n return;\n }\n\n const scoringResult = score('gap-select', data as GapSelectData, response);\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildAnsweredStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n ...xapiDefinitionFor(data),\n },\n scoringResult,\n timeSpentMs: timeSpent,\n response: JSON.stringify(selections),\n });\n setResult(scoringResult);\n onComplete?.({\n score: scoringResult.score,\n maxScore: scoringResult.maxScore,\n passed: scoringResult.passed,\n timeSpent,\n xapiStatement,\n });\n const overall = scoringResult.feedback;\n setSummary(\n `${s.answerSubmitted} ${s.scoreAnnouncement(\n Math.round(scoringResult.score * 100),\n scoringResult.passed,\n )}${overall ? ` ${overall}` : ''}`,\n );\n fireInteraction('submitted', { selections, score: scoringResult.score });\n };\n\n const correctByGap = useMemo(() => {\n if (isExam) {\n return new Map<string, boolean>();\n }\n if (isReview) {\n return outcome?.status === 'scored'\n ? correctnessByItem(outcome.details)\n : new Map<string, boolean>();\n }\n return correctnessByItem(result?.details ?? []);\n }, [isExam, isReview, outcome, result]);\n\n const reviewSummary = useMemo(() => {\n if (!isReview || outcome === undefined) {\n return null;\n }\n if (outcome.status === 'scored') {\n return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n if (outcome.status === 'deferred') {\n return s.notGradedYet;\n }\n if (outcome.status === 'graded') {\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return `${s.scoreAnnouncement(percent, outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n return s.noGradeAvailable;\n }, [isReview, outcome, s]);\n\n const anyFeedback = data.gaps.some((gap) => gap.feedback !== undefined);\n\n return (\n <form\n className=\"lk-gs\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n <fieldset disabled={inactive}>\n <p className=\"lk-gs-passage\">\n {segments.map((seg, i) => {\n if (seg.kind === 'text') {\n // biome-ignore lint/suspicious/noArrayIndexKey: passage segments are positional and static\n return <span key={`t${i}`}>{seg.value}</span>;\n }\n const gap = gapById.get(seg.id);\n if (!gap) {\n return null;\n }\n const choices = choicesByGap.get(seg.id) ?? [];\n const correctness = correctByGap.get(seg.id);\n // Read defensively and never in exam: a redact() projection omits\n // both at runtime while the type still says they are there.\n const gapFeedback = isExam ? undefined : gap.feedback;\n return (\n <span key={seg.id} className=\"lk-gs-gap\">\n <select\n className=\"lk-gs-select\"\n aria-label={s.gapLabel(seg.ordinal)}\n value={selections[seg.id] ?? ''}\n disabled={inactive}\n aria-disabled={inactive || undefined}\n data-correct={\n revealing && correctness !== undefined ? String(correctness) : undefined\n }\n onChange={(e) => handleSelect(seg.id, e.target.value)}\n >\n {/*\n The empty entry is part of the contract, not a decoration.\n It is how a learner leaves a gap alone — and how they take\n an answer back — so \"not answered\" stays distinguishable\n from \"answered wrongly\" all the way into ItemOutcome, where\n the scorer reports it as `incorrect-omission`.\n */}\n <option value=\"\">{s.gapPlaceholder}</option>\n {choices.map((choice) => (\n <option key={choice.id} value={choice.id}>\n {choice.text}\n </option>\n ))}\n </select>\n {revealing && !feedbackHidden && gapFeedback ? (\n <span\n className=\"lk-gs-gap-feedback\"\n role=\"note\"\n data-correct={correctness !== undefined ? String(correctness) : undefined}\n >\n {gapFeedback}\n </span>\n ) : null}\n </span>\n );\n })}\n </p>\n {isReview ? null : (\n <button type=\"submit\" disabled={inactive}>\n {isExam ? s.submitAnswers : s.checkAnswers}\n </button>\n )}\n </fieldset>\n {revealing && anyFeedback ? (\n <button\n type=\"button\"\n className=\"lk-gs-feedback-toggle\"\n aria-expanded={!feedbackHidden}\n onClick={() => setFeedbackHidden((h) => !h)}\n >\n {feedbackHidden ? s.showFeedback : s.hideFeedback}\n </button>\n ) : null}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? reviewSummary : summary}\n </FeedbackRegion>\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport { GapSelect as GapSelectCore, type GapSelectProps } from './GapSelect.js';\n\nexport type { GapSelectProps } from './GapSelect.js';\n\n/**\n * Public Gap Select activity: the core wrapped in `ActivityErrorBoundary` so a\n * render failure (including the dev schema-validation throw and the\n * redacted-in-`practice` guard) degrades to an accessible fallback instead of\n * crashing the host.\n */\nexport function GapSelect(props: GapSelectProps) {\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <GapSelectCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/GapSelect/GapSelect.tsx","../src/components/GapSelect/index.tsx"],"names":["result","GapSelect","jsx"],"mappings":";;;;;;;;;AAsCA,IAAM,WAAA,GAAc,0BAAA;AAKpB,SAAS,aAAa,OAAA,EAA4B;AAChD,EAAA,MAAM,WAAsB,EAAC;AAC7B,EAAA,MAAM,EAAA,GAAK,IAAI,MAAA,CAAO,WAAW,CAAA;AACjC,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,KAAA,GAAQ,EAAA,CAAG,IAAA,CAAK,OAAO,CAAA;AAC3B,EAAA,OAAO,UAAU,IAAA,EAAM;AACrB,IAAA,IAAI,KAAA,CAAM,QAAQ,IAAA,EAAM;AACtB,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,KAAK,CAAA,EAAG,CAAA;AAAA,IACzE;AACA,IAAA,OAAA,IAAW,CAAA;AACX,IAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,IAAI,KAAA,CAAM,CAAC,CAAA,EAAa,OAAA,EAAS,CAAA;AAC9D,IAAA,IAAA,GAAO,KAAA,CAAM,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,CAAE,MAAA;AAC9B,IAAA,KAAA,GAAQ,EAAA,CAAG,KAAK,OAAO,CAAA;AAAA,EACzB;AACA,EAAA,IAAI,IAAA,GAAO,QAAQ,MAAA,EAAQ;AACzB,IAAA,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAO,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,EAAG,CAAA;AAAA,EAC5D;AACA,EAAA,OAAO,QAAA;AACT;AAEA,IAAM,gBAAwC,EAAC;AAQ/C,SAAS,aAAa,QAAA,EAA+D;AACnF,EAAA,OAAO,aAAa,MAAA,IAAa,QAAA,CAAS,IAAA,KAAS,YAAA,GAC/C,SAAS,UAAA,GACT,aAAA;AACN;AAGA,SAAS,kBAAkB,OAAA,EAAyD;AAClF,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAqB;AACrC,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,GAAA,CAAI,GAAA;AAAA,MACF,MAAA,CAAO,MAAA;AAAA,MACP,OAAO,OAAA,KAAY,MAAA,GAAY,MAAA,CAAO,OAAA,KAAY,YAAY,MAAA,CAAO;AAAA,KACvE;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAQA,SAAS,UAAA,CACP,OACA,GAAA,EAC4B;AAC5B,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAW;AAC7B,IAAA,OAAO,GAAA,CAAI,OAAA;AAAA,EACb;AACA,EAAA,OAAO,KAAA,EAAO,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,OAAO,GAAA,CAAI,MAAM,CAAA,EAAG,OAAA,IAAW,EAAC;AACpE;AAEO,SAAS,SAAA,CAAU;AAAA,EACxB,IAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA,GAAa,UAAA;AAAA,EACb,OAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,MAAM,SAAS,UAAA,KAAe,MAAA;AAC9B,EAAA,MAAM,WAAW,UAAA,KAAe,QAAA;AAChC,EAAA,MAAM,CAAA,GAAI,aAAa,OAAO,CAAA;AAE9B,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC7B,IAAA,IAAI,CAAC,eAAc,EAAG;AACpB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,CAAK,aAAa,IAAA,EAAM;AAC1B,MAAA,IAAI;AACF,QAAA,cAAA,CAAe,IAAI,CAAA;AACnB,QAAA,OAAO,IAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAO,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACjE;AAAA,IACF;AACA,IAAA,MAAMA,OAAAA,GAAS,gBAAA,CAAiB,YAAA,EAAc,IAAI,CAAA;AAClD,IAAA,OAAOA,QAAO,OAAA,GAAU,IAAA,GAAO,IAAI,mBAAA,CAAoB,YAAA,EAAcA,QAAO,MAAM,CAAA;AAAA,EACpF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,EAAE,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,YAAA,EAAc,OAAM,GAAI,gBAAA;AAAA,IACtD,gBAAA,KAAqB,OAAO,WAAA,GAAc;AAAA,GAC5C;AACA,EAAA,MAAM,eAAe,KAAA,KAAU,MAAA;AAC/B,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAI,QAAA;AAAA,IAAiC,MACnF,aAAa,YAAY;AAAA,GAC3B;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA+B,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAwB,IAAI,CAAA;AAC1D,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAS,KAAK,CAAA;AAE1D,EAAA,MAAM,UAAA,GAAa,YAAA,GAAe,YAAA,CAAa,KAAK,CAAA,GAAI,kBAAA;AAExD,EAAA,MAAM,eAAA,GAAkB,OAAO,YAAY,CAAA;AAC3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,eAAA,CAAgB,OAAA,GAAU,YAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAEjB,EAAA,MAAM,mBAAA,GAAsB,OAAO,gBAAgB,CAAA;AACnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,mBAAA,CAAoB,OAAA,GAAU,gBAAA;AAAA,EAChC,CAAA,EAAG,CAAC,gBAAgB,CAAC,CAAA;AAIrB,EAAA,MAAM,WAAA,GAAc,OAAO,IAAI,CAAA;AAC/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAA,CAAY,YAAY,IAAA,EAAM;AAChC,MAAA;AAAA,IACF;AACA,IAAA,WAAA,CAAY,OAAA,GAAU,IAAA;AACtB,IAAA,qBAAA,CAAsB,YAAA,CAAa,eAAA,CAAgB,OAAO,CAAC,CAAA;AAC3D,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,iBAAA,CAAkB,KAAK,CAAA;AACvB,IAAA,KAAA,CAAM,mBAAA,CAAoB,OAAA,KAAY,IAAA,GAAO,WAAA,GAAc,MAAM,CAAA;AAAA,EACnE,CAAA,EAAG,CAAC,IAAA,EAAM,KAAK,CAAC,CAAA;AAEhB,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,MAAM,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA,EAAG,CAAC,IAAA,CAAK,OAAO,CAAC,CAAA;AACzE,EAAA,MAAM,OAAA,GAAU,QAAQ,MAAM,IAAI,IAAI,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,GAAA,KAAQ,CAAC,GAAA,CAAI,EAAA,EAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAA,CAAK,IAAI,CAAC,CAAA;AAEzF,EAAA,MAAM,YAAA,GAAe,OAAsB,IAAI,CAAA;AAQ/C,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AACjC,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAwC;AAExD,IAAA,MAAM,UAAA,GAAa,WAAA,KAAgB,YAAA,CAAa,OAAA,KAAY,eAAA,EAAgB,CAAA;AAC5E,IAAA,KAAA,MAAW,GAAA,IAAO,KAAK,IAAA,EAAM;AAC3B,MAAA,MAAM,OAAA,GAAU,UAAA,CAAW,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAC1C,MAAA,GAAA,CAAI,GAAA;AAAA,QACF,GAAA,CAAI,EAAA;AAAA,QACJ,IAAA,CAAK,cAAA,KAAmB,IAAA,GACpB,aAAA,CAAc,SAAS,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,EAAE,EAAE,CAAA,GAC3D;AAAA,OACN;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,IAAA,EAAM,WAAW,CAAC,CAAA;AAGtB,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAM,QAAA;AAAA,EACR;AAMA,EAAA,IAAI,IAAA,CAAK,QAAA,KAAa,IAAA,IAAQ,UAAA,KAAe,UAAA,EAAY;AACvD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,YAAA,EAAe,KAAK,EAAE,CAAA,oNAAA;AAAA,KAGxB;AAAA,EACF;AAEA,EAAA,MAAM,YAAY,KAAA,KAAU,WAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,QAAA,KAAa,IAAA,IAAQ,SAAA,IAAa,QAAA;AAOnD,EAAA,MAAM,YAAY,QAAA,GAAW,OAAA,EAAS,MAAA,KAAW,QAAA,GAAW,CAAC,MAAA,IAAU,SAAA;AAEvE,EAAA,MAAM,eAAA,GAAkB,CACtB,IAAA,EACA,OAAA,KACS;AACT,IAAA,aAAA,GAAgB,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,CAAK,EAAA,EAAI,WAAW,IAAA,CAAK,GAAA,EAAI,EAAG,OAAA,EAAS,CAAA;AAAA,EAC/E,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,EAAe,QAAA,KAA2B;AAC9D,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA;AAAA,IACF;AACA,IAAA,IAAI,UAAU,MAAA,EAAQ;AACpB,MAAA,KAAA,EAAM;AAAA,IACR;AACA,IAAA,MAAM,OAAO,EAAE,GAAG,YAAY,CAAC,KAAK,GAAG,QAAA,EAAS;AAChD,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,qBAAA,CAAsB,IAAI,CAAA;AAAA,IAC5B;AACA,IAAA,QAAA,GAAW,EAAE,IAAA,EAAM,YAAA,EAAc,UAAA,EAAY,MAAM,CAAA;AACnD,IAAA,eAAA,CAAgB,cAAA,EAAgB,EAAE,KAAA,EAAO,QAAA,EAAU,CAAA;AAAA,EACrD,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAAiC;AACrD,IAAA,KAAA,CAAM,cAAA,EAAe;AACrB,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAA,GAAqC,EAAE,IAAA,EAAM,YAAA,EAAc,UAAA,EAAW;AAC5E,IAAA,QAAA,GAAW,QAAQ,CAAA;AAEnB,IAAA,IAAI,MAAA,EAAQ;AAIV,MAAA,QAAA,EAAS;AACT,MAAA,UAAA,CAAW,EAAE,eAAe,CAAA;AAC5B,MAAA,eAAA,CAAgB,WAAA,EAAa,EAAE,UAAA,EAAY,CAAA;AAC3C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,YAAA,EAAc,IAAA,EAAuB,QAAQ,CAAA;AACzE,IAAA,QAAA,EAAS;AACT,IAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,IAAA,MAAM,aAAA,GAAgB,YAAY,sBAAA,CAAuB;AAAA,MACvD,KAAA,EAAO,eAAA;AAAA,MACP,MAAA,EAAQ;AAAA,QACN,EAAA,EAAI,WAAA,CAAY,IAAA,CAAK,EAAE,CAAA;AAAA,QACvB,IAAA,EAAM,EAAE,CAAC,IAAA,CAAK,UAAU,OAAO,GAAG,KAAK,KAAA,EAAM;AAAA,QAC7C,GAAG,kBAAkB,IAAI;AAAA,OAC3B;AAAA,MACA,aAAA;AAAA,MACA,WAAA,EAAa,SAAA;AAAA,MACb,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,UAAU;AAAA,KACpC,CAAA;AACD,IAAA,SAAA,CAAU,aAAa,CAAA;AACvB,IAAA,UAAA,GAAa;AAAA,MACX,OAAO,aAAA,CAAc,KAAA;AAAA,MACrB,UAAU,aAAA,CAAc,QAAA;AAAA,MACxB,QAAQ,aAAA,CAAc,MAAA;AAAA,MACtB,SAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,MAAM,UAAU,aAAA,CAAc,QAAA;AAC9B,IAAA,UAAA;AAAA,MACE,CAAA,EAAG,CAAA,CAAE,eAAe,CAAA,CAAA,EAAI,CAAA,CAAE,iBAAA;AAAA,QACxB,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,KAAA,GAAQ,GAAG,CAAA;AAAA,QACpC,aAAA,CAAc;AAAA,OACf,CAAA,EAAG,OAAA,GAAU,CAAA,CAAA,EAAI,OAAO,KAAK,EAAE,CAAA;AAAA,KAClC;AACA,IAAA,eAAA,CAAgB,aAAa,EAAE,UAAA,EAAY,KAAA,EAAO,aAAA,CAAc,OAAO,CAAA;AAAA,EACzE,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,2BAAW,GAAA,EAAqB;AAAA,IAClC;AACA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAO,OAAA,EAAS,WAAW,QAAA,GACvB,iBAAA,CAAkB,QAAQ,OAAO,CAAA,uBAC7B,GAAA,EAAqB;AAAA,IAC/B;AACA,IAAA,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,IAAW,EAAE,CAAA;AAAA,EAChD,GAAG,CAAC,MAAA,EAAQ,QAAA,EAAU,OAAA,EAAS,MAAM,CAAC,CAAA;AAEtC,EAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,IAAI,CAAC,QAAA,IAAY,OAAA,KAAY,MAAA,EAAW;AACtC,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAA,CAAQ,WAAW,QAAA,EAAU;AAC/B,MAAA,OAAO,GAAG,CAAA,CAAE,iBAAA,CAAkB,KAAK,KAAA,CAAM,OAAA,CAAQ,QAAQ,GAAG,CAAA,EAAG,QAAQ,MAAM,CAAC,GAC5E,OAAA,CAAQ,QAAA,GAAW,IAAI,OAAA,CAAQ,QAAQ,KAAK,EAC9C,CAAA,CAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAA,CAAQ,WAAW,UAAA,EAAY;AACjC,MAAA,OAAO,CAAA,CAAE,YAAA;AAAA,IACX;AACA,IAAA,IAAI,OAAA,CAAQ,WAAW,QAAA,EAAU;AAC/B,MAAA,MAAM,UACJ,OAAA,CAAQ,QAAA,GAAW,CAAA,GACf,IAAA,CAAK,MAAO,OAAA,CAAQ,KAAA,GAAQ,OAAA,CAAQ,QAAA,GAAY,GAAG,CAAA,GACnD,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,QAAQ,GAAG,CAAA;AACpC,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,iBAAA,CAAkB,OAAA,EAAS,QAAQ,MAAM,CAAC,CAAA,EACpD,OAAA,CAAQ,QAAA,GAAW,CAAA,CAAA,EAAI,OAAA,CAAQ,QAAQ,KAAK,EAC9C,CAAA,CAAA;AAAA,IACF;AACA,IAAA,OAAO,CAAA,CAAE,gBAAA;AAAA,EACX,CAAA,EAAG,CAAC,QAAA,EAAU,OAAA,EAAS,CAAC,CAAC,CAAA;AAEzB,EAAA,MAAM,WAAA,GAAc,KAAK,IAAA,CAAK,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,CAAI,aAAa,MAAS,CAAA;AAEtE,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,OAAA;AAAA,MACV,cAAY,IAAA,CAAK,KAAA;AAAA,MACjB,IAAA,EAAM,MAAA;AAAA,MACN,kBAAA,EAAkB,UAAA;AAAA,MAClB,KAAA,EAAO,KAAA;AAAA,MACP,QAAA,EAAU,YAAA;AAAA,MAET,QAAA,EAAA;AAAA,QAAA,IAAA,CAAK,KAAA,mBACJ,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,OAAO,IAAA,CAAK,KAAA;AAAA,YACZ,UAAA;AAAA,YACC,GAAI,WAAA,KAAgB,MAAA,GAAY,EAAE,WAAA,KAAgB,EAAC;AAAA,YACnD,GAAI,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,KAAiB,EAAC;AAAA,YACrD,GAAI,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,KAAY,EAAC;AAAA,YAC3C,GAAI,aAAA,KAAkB,MAAA,GAAY,EAAE,aAAA,KAAkB,EAAC;AAAA,YACvD,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW;AAAC;AAAA,SAC5C,GACE,IAAA;AAAA,wBACJ,IAAA,CAAC,UAAA,EAAA,EAAS,QAAA,EAAU,QAAA,EAClB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,OAAE,SAAA,EAAU,eAAA,EACV,mBAAS,GAAA,CAAI,CAAC,KAAK,CAAA,KAAM;AACxB,YAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AAEvB,cAAA,2BAAQ,MAAA,EAAA,EAAoB,QAAA,EAAA,GAAA,CAAI,KAAA,EAAA,EAAd,CAAA,CAAA,EAAI,CAAC,CAAA,CAAe,CAAA;AAAA,YACxC;AACA,YAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAC9B,YAAA,IAAI,CAAC,GAAA,EAAK;AACR,cAAA,OAAO,IAAA;AAAA,YACT;AACA,YAAA,MAAM,UAAU,YAAA,CAAa,GAAA,CAAI,GAAA,CAAI,EAAE,KAAK,EAAC;AAC7C,YAAA,MAAM,WAAA,GAAc,YAAA,CAAa,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAG3C,YAAA,MAAM,WAAA,GAAc,MAAA,GAAS,MAAA,GAAY,GAAA,CAAI,QAAA;AAC7C,YAAA,uBACE,IAAA,CAAC,MAAA,EAAA,EAAkB,SAAA,EAAU,WAAA,EAC3B,QAAA,EAAA;AAAA,8BAAA,IAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,cAAA;AAAA,kBACV,YAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA;AAAA,kBAClC,KAAA,EAAO,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,IAAK,EAAA;AAAA,kBAC7B,QAAA,EAAU,QAAA;AAAA,kBACV,iBAAe,QAAA,IAAY,MAAA;AAAA,kBAC3B,gBACE,SAAA,IAAa,WAAA,KAAgB,MAAA,GAAY,MAAA,CAAO,WAAW,CAAA,GAAI,MAAA;AAAA,kBAEjE,QAAA,EAAU,CAAC,CAAA,KAAM,YAAA,CAAa,IAAI,EAAA,EAAI,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,kBASpD,QAAA,EAAA;AAAA,oCAAA,GAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,EAAA,EAAI,QAAA,EAAA,CAAA,CAAE,cAAA,EAAe,CAAA;AAAA,oBAClC,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,qBACZ,GAAA,CAAC,QAAA,EAAA,EAAuB,KAAA,EAAO,MAAA,CAAO,EAAA,EACnC,QAAA,EAAA,MAAA,CAAO,IAAA,EAAA,EADG,MAAA,CAAO,EAEpB,CACD;AAAA;AAAA;AAAA,eACH;AAAA,cACC,SAAA,IAAa,CAAC,cAAA,IAAkB,WAAA,mBAC/B,GAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,oBAAA;AAAA,kBACV,IAAA,EAAK,MAAA;AAAA,kBACL,cAAA,EAAc,WAAA,KAAgB,MAAA,GAAY,MAAA,CAAO,WAAW,CAAA,GAAI,MAAA;AAAA,kBAE/D,QAAA,EAAA;AAAA;AAAA,eACH,GACE;AAAA,aAAA,EAAA,EAlCK,IAAI,EAmCf,CAAA;AAAA,UAEJ,CAAC,CAAA,EACH,CAAA;AAAA,UACC,QAAA,GAAW,IAAA,mBACV,GAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,QAAA,EAAU,QAAA,EAC7B,QAAA,EAAA,MAAA,GAAS,CAAA,CAAE,aAAA,GAAgB,CAAA,CAAE,YAAA,EAChC;AAAA,SAAA,EAEJ,CAAA;AAAA,QACC,aAAa,WAAA,mBACZ,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,uBAAA;AAAA,YACV,iBAAe,CAAC,cAAA;AAAA,YAChB,SAAS,MAAM,iBAAA,CAAkB,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,YAEzC,QAAA,EAAA,cAAA,GAAiB,CAAA,CAAE,YAAA,GAAe,CAAA,CAAE;AAAA;AAAA,SACvC,GACE,IAAA;AAAA,wBACJ,GAAA,CAAC,kBAAe,EAAA,EAAI,CAAA,EAAG,KAAK,EAAE,CAAA,SAAA,CAAA,EAC3B,QAAA,EAAA,QAAA,GAAW,aAAA,GAAgB,OAAA,EAC9B;AAAA;AAAA;AAAA,GACF;AAEJ;AC9aO,SAASC,WAAU,KAAA,EAAuB;AAC/C,EAAA,MAAM,OAAA,GAAU,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA;AAC1C,EAAA,uBACEC,GAAAA,CAAC,qBAAA,EAAA,EAAsB,aAAA,EAAe,KAAA,CAAM,IAAA,EAAM,KAAA,EAAO,OAAA,EACvD,QAAA,kBAAAA,GAAAA,CAAC,SAAA,EAAA,EAAe,GAAG,OAAO,CAAA,EAC5B,CAAA;AAEJ","file":"chunk-CE6OGJE6.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n assertRedacted,\n type GapSelectBank,\n type GapSelectChoice,\n type GapSelectData,\n type GapSelectGap,\n type GapSelectLearnerResponse,\n type LearnerResponse,\n type ScoringDetail,\n type ScoringResult,\n score,\n seededShuffle,\n validateActivity,\n xAPIBuilder,\n xapiDefinitionFor,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor, randomSessionId } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type { ActivityProps } from '../types.js';\n\nexport interface GapSelectProps extends ActivityProps<GapSelectData> {\n /**\n * Seeds the per-gap choice shuffle when `data.shuffleChoices` is set. Pass\n * the attempt id, exactly as on `<MultipleChoice>`: an order nobody can\n * reproduce cannot be reconciled with the attempt a server recorded. Without\n * one, a random per-mount seed is used — stable within the mount, and\n * deliberately not reproducible.\n */\n shuffleSeed?: string;\n}\n\nconst PLACEHOLDER = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\ntype Segment = { kind: 'text'; value: string } | { kind: 'gap'; id: string; ordinal: number };\n\n/** Splits a passage into literal text and its `{{id}}` gaps, in order. */\nfunction parsePassage(passage: string): Segment[] {\n const segments: Segment[] = [];\n const re = new RegExp(PLACEHOLDER);\n let last = 0;\n let ordinal = 0;\n let match = re.exec(passage);\n while (match !== null) {\n if (match.index > last) {\n segments.push({ kind: 'text', value: passage.slice(last, match.index) });\n }\n ordinal += 1;\n segments.push({ kind: 'gap', id: match[1] as string, ordinal });\n last = match.index + match[0].length;\n match = re.exec(passage);\n }\n if (last < passage.length) {\n segments.push({ kind: 'text', value: passage.slice(last) });\n }\n return segments;\n}\n\nconst NO_SELECTIONS: Record<string, string> = {};\n\n/**\n * The selections out of a `LearnerResponse`. A response of another activity\n * type reads as \"nothing selected\" rather than throwing — a controlled host\n * that has not yet swapped its state on an activity change would otherwise\n * crash the attempt.\n */\nfunction selectionsOf(response: LearnerResponse | undefined): Record<string, string> {\n return response !== undefined && response.type === 'gap-select'\n ? response.selections\n : NO_SELECTIONS;\n}\n\n/** Per-gap correctness keyed by gap id, preferring the unambiguous `outcome`. */\nfunction correctnessByItem(details: readonly ScoringDetail[]): Map<string, boolean> {\n const map = new Map<string, boolean>();\n for (const detail of details) {\n map.set(\n detail.itemId,\n detail.outcome !== undefined ? detail.outcome === 'correct' : detail.correct,\n );\n }\n return map;\n}\n\n/**\n * The choices a gap offers: its own list, or the bank it names.\n *\n * Both survive redaction — they are what the learner picks from — so this is\n * the one resolution that works identically on full and redacted data.\n */\nfunction choicesFor(\n banks: readonly GapSelectBank[] | undefined,\n gap: GapSelectGap,\n): readonly GapSelectChoice[] {\n if (gap.choices !== undefined) {\n return gap.choices;\n }\n return banks?.find((bank) => bank.id === gap.bankId)?.choices ?? [];\n}\n\nexport function GapSelect({\n data,\n onComplete,\n onSubmit,\n onChange,\n onInteraction,\n value,\n defaultValue,\n defaultSubmitted,\n renderMode = 'practice',\n outcome,\n mediaBudget,\n mediaStrings,\n strings,\n theme,\n locale,\n disabled,\n shuffleSeed,\n}: GapSelectProps) {\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n const s = useLkStrings(strings);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n if (data.redacted === true) {\n try {\n assertRedacted(data);\n return null;\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n }\n const result = validateActivity('gap-select', data);\n return result.success ? null : new ActivitySchemaError('gap-select', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n const isControlled = value !== undefined;\n const [internalSelections, setInternalSelections] = useState<Record<string, string>>(() =>\n selectionsOf(defaultValue),\n );\n const [result, setResult] = useState<ScoringResult | null>(null);\n const [summary, setSummary] = useState<string | null>(null);\n const [feedbackHidden, setFeedbackHidden] = useState(false);\n\n const selections = isControlled ? selectionsOf(value) : internalSelections;\n\n const defaultValueRef = useRef(defaultValue);\n useEffect(() => {\n defaultValueRef.current = defaultValue;\n }, [defaultValue]);\n\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity-guarded so the mount run is a no-op: without it this fires after\n // the first paint and undoes every seed it was just given (Req 3.7).\n const lastDataRef = useRef(data);\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInternalSelections(selectionsOf(defaultValueRef.current));\n setResult(null);\n setSummary(null);\n setFeedbackHidden(false);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n const segments = useMemo(() => parsePassage(data.passage), [data.passage]);\n const gapById = useMemo(() => new Map(data.gaps.map((gap) => [gap.id, gap])), [data.gaps]);\n\n const sessionIdRef = useRef<string | null>(null);\n /**\n * The choices each gap shows, in the order it shows them.\n *\n * Seeded PER GAP, not once for the activity: two gaps drawing on the same\n * word bank must not be dealt the same order, or the bank's distractors line\n * up column-wise and the second gap becomes easier than the first.\n */\n const choicesByGap = useMemo(() => {\n const map = new Map<string, readonly GapSelectChoice[]>();\n // biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization\n const seedSource = shuffleSeed ?? (sessionIdRef.current ??= randomSessionId());\n for (const gap of data.gaps) {\n const choices = choicesFor(data.banks, gap);\n map.set(\n gap.id,\n data.shuffleChoices === true\n ? seededShuffle(choices, `${seedSource}:${data.id}:${gap.id}`)\n : choices,\n );\n }\n return map;\n }, [data, shuffleSeed]);\n\n // All hooks are called before these throws, so hook order stays stable.\n if (devError) {\n throw devError;\n }\n // Practice grades locally, and a redacted projection has no answer key to\n // grade against — `score()` would throw RedactedScoringError from the submit\n // handler, where no error boundary can reach it and after the learner has\n // answered. Fail at render instead, in production too, exactly as every other\n // built-in does.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Gap Select \"${data.id}\" received redacted activity data in renderMode \"practice\", ` +\n 'which grades locally and has no answer key to grade against. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n\n /**\n * Whether answer-key-derived information may be shown. Never in `exam`; in\n * `practice` only once this component has scored; in `review` only once the\n * caller supplies a SCORED outcome.\n */\n const revealing = isReview ? outcome?.status === 'scored' : !isExam && submitted;\n\n const fireInteraction = (\n type: 'gap-selected' | 'submitted',\n payload: Record<string, unknown>,\n ): void => {\n onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });\n };\n\n const handleSelect = (gapId: string, choiceId: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n const next = { ...selections, [gapId]: choiceId };\n if (!isControlled) {\n setInternalSelections(next);\n }\n onChange?.({ type: 'gap-select', selections: next });\n fireInteraction('gap-selected', { gapId, choiceId });\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive) {\n return;\n }\n const response: GapSelectLearnerResponse = { type: 'gap-select', selections };\n onSubmit?.(response);\n\n if (isExam) {\n // The client neither grades nor reveals: no score(), no read of any\n // answer-key field, no onComplete, and no xAPI statement — its\n // correctResponsesPattern IS the answer key.\n complete();\n setSummary(s.answerSubmitted);\n fireInteraction('submitted', { selections });\n return;\n }\n\n const scoringResult = score('gap-select', data as GapSelectData, response);\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildAnsweredStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n ...xapiDefinitionFor(data),\n },\n scoringResult,\n timeSpentMs: timeSpent,\n response: JSON.stringify(selections),\n });\n setResult(scoringResult);\n onComplete?.({\n score: scoringResult.score,\n maxScore: scoringResult.maxScore,\n passed: scoringResult.passed,\n timeSpent,\n xapiStatement,\n });\n const overall = scoringResult.feedback;\n setSummary(\n `${s.answerSubmitted} ${s.scoreAnnouncement(\n Math.round(scoringResult.score * 100),\n scoringResult.passed,\n )}${overall ? ` ${overall}` : ''}`,\n );\n fireInteraction('submitted', { selections, score: scoringResult.score });\n };\n\n const correctByGap = useMemo(() => {\n if (isExam) {\n return new Map<string, boolean>();\n }\n if (isReview) {\n return outcome?.status === 'scored'\n ? correctnessByItem(outcome.details)\n : new Map<string, boolean>();\n }\n return correctnessByItem(result?.details ?? []);\n }, [isExam, isReview, outcome, result]);\n\n const reviewSummary = useMemo(() => {\n if (!isReview || outcome === undefined) {\n return null;\n }\n if (outcome.status === 'scored') {\n return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n if (outcome.status === 'deferred') {\n return s.notGradedYet;\n }\n if (outcome.status === 'graded') {\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return `${s.scoreAnnouncement(percent, outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n return s.noGradeAvailable;\n }, [isReview, outcome, s]);\n\n const anyFeedback = data.gaps.some((gap) => gap.feedback !== undefined);\n\n return (\n <form\n className=\"lk-gs\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n <fieldset disabled={inactive}>\n <p className=\"lk-gs-passage\">\n {segments.map((seg, i) => {\n if (seg.kind === 'text') {\n // biome-ignore lint/suspicious/noArrayIndexKey: passage segments are positional and static\n return <span key={`t${i}`}>{seg.value}</span>;\n }\n const gap = gapById.get(seg.id);\n if (!gap) {\n return null;\n }\n const choices = choicesByGap.get(seg.id) ?? [];\n const correctness = correctByGap.get(seg.id);\n // Read defensively and never in exam: a redact() projection omits\n // both at runtime while the type still says they are there.\n const gapFeedback = isExam ? undefined : gap.feedback;\n return (\n <span key={seg.id} className=\"lk-gs-gap\">\n <select\n className=\"lk-gs-select\"\n aria-label={s.gapLabel(seg.ordinal)}\n value={selections[seg.id] ?? ''}\n disabled={inactive}\n aria-disabled={inactive || undefined}\n data-correct={\n revealing && correctness !== undefined ? String(correctness) : undefined\n }\n onChange={(e) => handleSelect(seg.id, e.target.value)}\n >\n {/*\n The empty entry is part of the contract, not a decoration.\n It is how a learner leaves a gap alone — and how they take\n an answer back — so \"not answered\" stays distinguishable\n from \"answered wrongly\" all the way into ItemOutcome, where\n the scorer reports it as `incorrect-omission`.\n */}\n <option value=\"\">{s.gapPlaceholder}</option>\n {choices.map((choice) => (\n <option key={choice.id} value={choice.id}>\n {choice.text}\n </option>\n ))}\n </select>\n {revealing && !feedbackHidden && gapFeedback ? (\n <span\n className=\"lk-gs-gap-feedback\"\n role=\"note\"\n data-correct={correctness !== undefined ? String(correctness) : undefined}\n >\n {gapFeedback}\n </span>\n ) : null}\n </span>\n );\n })}\n </p>\n {isReview ? null : (\n <button type=\"submit\" disabled={inactive}>\n {isExam ? s.submitAnswers : s.checkAnswers}\n </button>\n )}\n </fieldset>\n {revealing && anyFeedback ? (\n <button\n type=\"button\"\n className=\"lk-gs-feedback-toggle\"\n aria-expanded={!feedbackHidden}\n onClick={() => setFeedbackHidden((h) => !h)}\n >\n {feedbackHidden ? s.showFeedback : s.hideFeedback}\n </button>\n ) : null}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? reviewSummary : summary}\n </FeedbackRegion>\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport { GapSelect as GapSelectCore, type GapSelectProps } from './GapSelect.js';\n\nexport type { GapSelectProps } from './GapSelect.js';\n\n/**\n * Public Gap Select activity: the core wrapped in `ActivityErrorBoundary` so a\n * render failure (including the dev schema-validation throw and the\n * redacted-in-`practice` guard) degrades to an accessible fallback instead of\n * crashing the host.\n */\nexport function GapSelect(props: GapSelectProps) {\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <GapSelectCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkB2XQLU2E_cjs = require('./chunk-B2XQLU2E.cjs');
5
- var chunkLB3FEV7Z_cjs = require('./chunk-LB3FEV7Z.cjs');
4
+ var chunkFKGUKFC7_cjs = require('./chunk-FKGUKFC7.cjs');
5
+ var chunkZ6TVOAO5_cjs = require('./chunk-Z6TVOAO5.cjs');
6
6
  var react = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
 
@@ -19,7 +19,7 @@ function StimulusPanel({
19
19
  strings
20
20
  }) {
21
21
  const titleId = react.useId();
22
- const s = chunkLB3FEV7Z_cjs.useLkStrings(strings);
22
+ const s = chunkZ6TVOAO5_cjs.useLkStrings(strings);
23
23
  const bodyHtml = react.useMemo(() => {
24
24
  if (sanitizeHtml === void 0 || typeof stimulus.bodyHtml !== "string") {
25
25
  return null;
@@ -33,7 +33,7 @@ function StimulusPanel({
33
33
  stimulus.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-stimulus-title", id: titleId, ...contentLang, children: stimulus.title }) : null,
34
34
  rangeText !== null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "lk-stimulus-range", children: rangeText }) : null,
35
35
  stimulus.media !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
36
- chunkB2XQLU2E_cjs.ActivityMedia,
36
+ chunkFKGUKFC7_cjs.ActivityMedia,
37
37
  {
38
38
  media: stimulus.media,
39
39
  ...renderMode !== void 0 ? { renderMode } : {},
@@ -59,5 +59,5 @@ function StimulusPanel({
59
59
  }
60
60
 
61
61
  exports.StimulusPanel = StimulusPanel;
62
- //# sourceMappingURL=chunk-RRH7ZPXC.cjs.map
63
- //# sourceMappingURL=chunk-RRH7ZPXC.cjs.map
62
+ //# sourceMappingURL=chunk-DP3DM7FR.cjs.map
63
+ //# sourceMappingURL=chunk-DP3DM7FR.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/StimulusPanel/StimulusPanel.tsx"],"names":["useId","useLkStrings","useMemo","jsxs","jsx","ActivityMedia"],"mappings":"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","file":"chunk-RRH7ZPXC.cjs","sourcesContent":["'use client';\n\nimport type { InteractionEvent, Stimulus } from '@intellectif/lk-core';\nimport { useId, useMemo } from 'react';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport type { LkStringsOverride } from '../../i18n/strings.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport type {\n HtmlSanitizer,\n MediaBudgetBinding,\n MediaTransportStrings,\n RenderMode,\n} from '../types.js';\n\nexport interface StimulusPanelProps {\n stimulus: Stimulus;\n /**\n * 1-based presented positions of the first and last question this material\n * serves, rendered as \"Questions 3–8\" so a learner knows how far the\n * passage carries.\n */\n range?: { first: number; last: number };\n /** Renders `stimulus.bodyHtml` when provided. See `HtmlSanitizer`. */\n sanitizeHtml?: HtmlSanitizer;\n locale?: string;\n /**\n * Forwarded to the stimulus's own media. `review` keeps the browser's control\n * bar even under an enforcing policy — a graded paper cannot be changed by\n * listening again.\n */\n renderMode?: RenderMode;\n /**\n * Binds this group's recording to a play budget the consumer persists. One\n * recording serves every question in the group, so the key is derived from\n * the ENTRY rather than the slot — see `stimulusMediaKey()` in lk-core.\n */\n mediaBudget?: MediaBudgetBinding;\n /** Translations for the audio transport chrome. */\n mediaStrings?: Partial<MediaTransportStrings>;\n onInteraction?: (event: InteractionEvent) => void;\n disabled?: boolean;\n /** Overrides the SDK's chrome text for this panel. See {@link LkIntlProvider}. */\n strings?: LkStringsOverride;\n}\n\n/**\n * Presents a shared stimulus — the passage, recording or image an item group's\n * questions refer to. A landmark region named by its title (or by its kind),\n * so a screen-reader user can jump back to the material from any question.\n *\n * Rich text follows the SDK-wide rule: `bodyHtml` is rendered only through a\n * caller-supplied sanitiser, and the plain `body` is the fallback — which the\n * schema guarantees exists whenever `bodyHtml` does.\n */\nexport function StimulusPanel({\n stimulus,\n range,\n sanitizeHtml,\n locale,\n renderMode,\n mediaBudget,\n mediaStrings,\n onInteraction,\n disabled,\n strings,\n}: StimulusPanelProps): React.JSX.Element {\n const titleId = useId();\n const s = useLkStrings(strings);\n\n const bodyHtml = useMemo(() => {\n if (sanitizeHtml === undefined || typeof stimulus.bodyHtml !== 'string') {\n return null;\n }\n return sanitizeHtml(stimulus.bodyHtml);\n }, [stimulus.bodyHtml, sanitizeHtml]);\n\n const rangeText = range === undefined ? null : s.stimulusRange(range.first, range.last);\n\n const naming =\n stimulus.title !== undefined\n ? { 'aria-labelledby': titleId }\n : { 'aria-label': s.stimulusKind[stimulus.kind] };\n\n // The AUTHORED parts carry the stimulus language; the SDK's own chrome does\n // not. Declaring `stimulus.locale` on the whole region made a screen reader\n // read \"Recording\" and \"Questions 3–5\" — English strings this package ships\n // — in the passage's voice, so a Spanish listening panel announced its own\n // name and the only orientation text in it with Spanish phonetics\n // (WCAG 3.1.2 Language of Parts). Scope the declaration to the content it\n // actually describes.\n const contentLang = stimulus.locale !== undefined ? { lang: stimulus.locale } : {};\n\n return (\n <section className=\"lk-stimulus\" data-kind={stimulus.kind} lang={locale} {...naming}>\n {stimulus.title !== undefined ? (\n <p className=\"lk-stimulus-title\" id={titleId} {...contentLang}>\n {stimulus.title}\n </p>\n ) : null}\n {rangeText !== null ? <p className=\"lk-stimulus-range\">{rangeText}</p> : null}\n {stimulus.media !== undefined ? (\n <ActivityMedia\n media={stimulus.media}\n {...(renderMode !== undefined ? { renderMode } : {})}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(disabled !== undefined ? { disabled } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n {bodyHtml !== null ? (\n <div\n className=\"lk-stimulus-body\"\n data-format=\"html\"\n {...contentLang}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: rendered only through the caller-supplied HtmlSanitizer — the SDK never injects unsanitised markup\n dangerouslySetInnerHTML={{ __html: bodyHtml }}\n />\n ) : stimulus.body !== undefined ? (\n <div className=\"lk-stimulus-body\" data-format=\"text\" {...contentLang}>\n {stimulus.body}\n </div>\n ) : null}\n {stimulus.attribution !== undefined ? (\n <p className=\"lk-stimulus-attribution\" {...contentLang}>\n <cite>{stimulus.attribution}</cite>\n </p>\n ) : null}\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/StimulusPanel/StimulusPanel.tsx"],"names":["useId","useLkStrings","useMemo","jsxs","jsx","ActivityMedia"],"mappings":"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","file":"chunk-DP3DM7FR.cjs","sourcesContent":["'use client';\n\nimport type { InteractionEvent, Stimulus } from '@intellectif/lk-core';\nimport { useId, useMemo } from 'react';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport type { LkStringsOverride } from '../../i18n/strings.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport type {\n HtmlSanitizer,\n MediaBudgetBinding,\n MediaTransportStrings,\n RenderMode,\n} from '../types.js';\n\nexport interface StimulusPanelProps {\n stimulus: Stimulus;\n /**\n * 1-based presented positions of the first and last question this material\n * serves, rendered as \"Questions 3–8\" so a learner knows how far the\n * passage carries.\n */\n range?: { first: number; last: number };\n /** Renders `stimulus.bodyHtml` when provided. See `HtmlSanitizer`. */\n sanitizeHtml?: HtmlSanitizer;\n locale?: string;\n /**\n * Forwarded to the stimulus's own media. `review` keeps the browser's control\n * bar even under an enforcing policy — a graded paper cannot be changed by\n * listening again.\n */\n renderMode?: RenderMode;\n /**\n * Binds this group's recording to a play budget the consumer persists. One\n * recording serves every question in the group, so the key is derived from\n * the ENTRY rather than the slot — see `stimulusMediaKey()` in lk-core.\n */\n mediaBudget?: MediaBudgetBinding;\n /** Translations for the audio transport chrome. */\n mediaStrings?: Partial<MediaTransportStrings>;\n onInteraction?: (event: InteractionEvent) => void;\n disabled?: boolean;\n /** Overrides the SDK's chrome text for this panel. See {@link LkIntlProvider}. */\n strings?: LkStringsOverride;\n}\n\n/**\n * Presents a shared stimulus — the passage, recording or image an item group's\n * questions refer to. A landmark region named by its title (or by its kind),\n * so a screen-reader user can jump back to the material from any question.\n *\n * Rich text follows the SDK-wide rule: `bodyHtml` is rendered only through a\n * caller-supplied sanitiser, and the plain `body` is the fallback — which the\n * schema guarantees exists whenever `bodyHtml` does.\n */\nexport function StimulusPanel({\n stimulus,\n range,\n sanitizeHtml,\n locale,\n renderMode,\n mediaBudget,\n mediaStrings,\n onInteraction,\n disabled,\n strings,\n}: StimulusPanelProps): React.JSX.Element {\n const titleId = useId();\n const s = useLkStrings(strings);\n\n const bodyHtml = useMemo(() => {\n if (sanitizeHtml === undefined || typeof stimulus.bodyHtml !== 'string') {\n return null;\n }\n return sanitizeHtml(stimulus.bodyHtml);\n }, [stimulus.bodyHtml, sanitizeHtml]);\n\n const rangeText = range === undefined ? null : s.stimulusRange(range.first, range.last);\n\n const naming =\n stimulus.title !== undefined\n ? { 'aria-labelledby': titleId }\n : { 'aria-label': s.stimulusKind[stimulus.kind] };\n\n // The AUTHORED parts carry the stimulus language; the SDK's own chrome does\n // not. Declaring `stimulus.locale` on the whole region made a screen reader\n // read \"Recording\" and \"Questions 3–5\" — English strings this package ships\n // — in the passage's voice, so a Spanish listening panel announced its own\n // name and the only orientation text in it with Spanish phonetics\n // (WCAG 3.1.2 Language of Parts). Scope the declaration to the content it\n // actually describes.\n const contentLang = stimulus.locale !== undefined ? { lang: stimulus.locale } : {};\n\n return (\n <section className=\"lk-stimulus\" data-kind={stimulus.kind} lang={locale} {...naming}>\n {stimulus.title !== undefined ? (\n <p className=\"lk-stimulus-title\" id={titleId} {...contentLang}>\n {stimulus.title}\n </p>\n ) : null}\n {rangeText !== null ? <p className=\"lk-stimulus-range\">{rangeText}</p> : null}\n {stimulus.media !== undefined ? (\n <ActivityMedia\n media={stimulus.media}\n {...(renderMode !== undefined ? { renderMode } : {})}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(disabled !== undefined ? { disabled } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n {bodyHtml !== null ? (\n <div\n className=\"lk-stimulus-body\"\n data-format=\"html\"\n {...contentLang}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: rendered only through the caller-supplied HtmlSanitizer — the SDK never injects unsanitised markup\n dangerouslySetInnerHTML={{ __html: bodyHtml }}\n />\n ) : stimulus.body !== undefined ? (\n <div className=\"lk-stimulus-body\" data-format=\"text\" {...contentLang}>\n {stimulus.body}\n </div>\n ) : null}\n {stimulus.attribution !== undefined ? (\n <p className=\"lk-stimulus-attribution\" {...contentLang}>\n <cite>{stimulus.attribution}</cite>\n </p>\n ) : null}\n </section>\n );\n}\n"]}
@@ -1,15 +1,15 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkRRH7ZPXC_cjs = require('./chunk-RRH7ZPXC.cjs');
5
- var chunkYEYKJFEC_cjs = require('./chunk-YEYKJFEC.cjs');
6
- var chunkNDQD3ZRY_cjs = require('./chunk-NDQD3ZRY.cjs');
7
- var chunkSE6WWDVW_cjs = require('./chunk-SE6WWDVW.cjs');
8
- var chunkU3APKQ7P_cjs = require('./chunk-U3APKQ7P.cjs');
9
- var chunkWTS34S5E_cjs = require('./chunk-WTS34S5E.cjs');
10
- var chunk36FTYJWJ_cjs = require('./chunk-36FTYJWJ.cjs');
11
- var chunkUSBANZ7K_cjs = require('./chunk-USBANZ7K.cjs');
12
- var chunkLB3FEV7Z_cjs = require('./chunk-LB3FEV7Z.cjs');
4
+ var chunkDP3DM7FR_cjs = require('./chunk-DP3DM7FR.cjs');
5
+ var chunk26GQO5I2_cjs = require('./chunk-26GQO5I2.cjs');
6
+ var chunkL7NE7PR4_cjs = require('./chunk-L7NE7PR4.cjs');
7
+ var chunk4H3JTX74_cjs = require('./chunk-4H3JTX74.cjs');
8
+ var chunkEKBEKDWO_cjs = require('./chunk-EKBEKDWO.cjs');
9
+ var chunkXMJE34FY_cjs = require('./chunk-XMJE34FY.cjs');
10
+ var chunkZH5WT2IE_cjs = require('./chunk-ZH5WT2IE.cjs');
11
+ var chunk53YOZOGN_cjs = require('./chunk-53YOZOGN.cjs');
12
+ var chunkZ6TVOAO5_cjs = require('./chunk-Z6TVOAO5.cjs');
13
13
  var lkCore = require('@intellectif/lk-core');
14
14
  var react = require('react');
15
15
  var jsxRuntime = require('react/jsx-runtime');
@@ -31,7 +31,7 @@ function SequencePane({
31
31
  return;
32
32
  }
33
33
  if (captureGroup !== void 0) {
34
- chunk36FTYJWJ_cjs.stopCaptureGroup(captureGroup);
34
+ chunkZH5WT2IE_cjs.stopCaptureGroup(captureGroup);
35
35
  }
36
36
  const node = ref.current;
37
37
  if (node === null) {
@@ -44,7 +44,7 @@ function SequencePane({
44
44
  }
45
45
  }
46
46
  }, [hidden, captureGroup]);
47
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, hidden, ref, children: channel === void 0 ? children : /* @__PURE__ */ jsxRuntime.jsx(chunk36FTYJWJ_cjs.SequenceSlotContext.Provider, { value: channel, children }) });
47
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, hidden, ref, children: channel === void 0 ? children : /* @__PURE__ */ jsxRuntime.jsx(chunkZH5WT2IE_cjs.SequenceSlotContext.Provider, { value: channel, children }) });
48
48
  }
49
49
  function shufflesItsOwnOptions(entry) {
50
50
  const item = entry;
@@ -73,10 +73,11 @@ function ActivitySequence({
73
73
  mediaBudget,
74
74
  recordingBinding,
75
75
  assessments,
76
+ workletUrl,
76
77
  strings
77
78
  }) {
78
79
  const sessionIdRef = react.useRef(null);
79
- const s = chunkLB3FEV7Z_cjs.useLkStrings(strings);
80
+ const s = chunkZ6TVOAO5_cjs.useLkStrings(strings);
80
81
  const mediaPlays = mediaBudget?.plays;
81
82
  const [captureScope] = react.useState(() => {
82
83
  captureScopeCount += 1;
@@ -93,7 +94,7 @@ function ActivitySequence({
93
94
  }
94
95
  const seed = needsSeed ? (
95
96
  // biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization
96
- shuffleSeed ?? (sessionIdRef.current ??= chunkUSBANZ7K_cjs.randomSessionId())
97
+ shuffleSeed ?? (sessionIdRef.current ??= chunk53YOZOGN_cjs.randomSessionId())
97
98
  ) : void 0;
98
99
  const slots = react.useMemo(
99
100
  () => lkCore.flattenSequence(activities, { shuffleEntries, ...seed !== void 0 ? { seed } : {} }),
@@ -421,7 +422,7 @@ function ActivitySequence({
421
422
  setGeneration,
422
423
  // The take the grade is for: stamped by `<ReadAloud>`, and for a
423
424
  // consumer's renderer, which cannot stamp one, the slot's latest.
424
- takesAnswers ? chunk36FTYJWJ_cjs.takeOf(result) ?? takesRef.current.get(slotIndex)?.take : void 0
425
+ takesAnswers ? chunkZH5WT2IE_cjs.takeOf(result) ?? takesRef.current.get(slotIndex)?.take : void 0
425
426
  ),
426
427
  onSubmit: (response) => {
427
428
  if (setGeneration !== setGenerationRef.current) {
@@ -442,7 +443,7 @@ function ActivitySequence({
442
443
  record(
443
444
  { kind: "responded", index: slotIndex, slotId, activityId, response },
444
445
  setGeneration,
445
- chunk36FTYJWJ_cjs.takeOf(response) ?? chunk36FTYJWJ_cjs.mintTake()
446
+ chunkZH5WT2IE_cjs.takeOf(response) ?? chunkZH5WT2IE_cjs.mintTake()
446
447
  );
447
448
  }
448
449
  },
@@ -455,7 +456,7 @@ function ActivitySequence({
455
456
  }
456
457
  if (activity.type === "multiple-choice") {
457
458
  return /* @__PURE__ */ jsxRuntime.jsx(
458
- chunkNDQD3ZRY_cjs.MultipleChoice,
459
+ chunkL7NE7PR4_cjs.MultipleChoice,
459
460
  {
460
461
  data: activity,
461
462
  ...shuffleSeed !== void 0 ? { shuffleSeed } : {},
@@ -464,11 +465,11 @@ function ActivitySequence({
464
465
  );
465
466
  }
466
467
  if (activity.type === "fill-in-the-blanks") {
467
- return /* @__PURE__ */ jsxRuntime.jsx(chunkSE6WWDVW_cjs.FillInTheBlanks, { data: activity, ...childProps });
468
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk4H3JTX74_cjs.FillInTheBlanks, { data: activity, ...childProps });
468
469
  }
469
470
  if (activity.type === "gap-select") {
470
471
  return /* @__PURE__ */ jsxRuntime.jsx(
471
- chunkU3APKQ7P_cjs.GapSelect,
472
+ chunkEKBEKDWO_cjs.GapSelect,
472
473
  {
473
474
  data: activity,
474
475
  ...shuffleSeed !== void 0 ? { shuffleSeed } : {},
@@ -477,25 +478,26 @@ function ActivitySequence({
477
478
  );
478
479
  }
479
480
  if (activity.type === "dictation") {
480
- return /* @__PURE__ */ jsxRuntime.jsx(chunkWTS34S5E_cjs.Dictation, { data: activity, ...childProps });
481
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkXMJE34FY_cjs.Dictation, { data: activity, ...childProps });
481
482
  }
482
483
  if (activity.type === "read-aloud") {
483
484
  const slotRecordingBinding = recordingBindingFor(slot);
484
485
  const slotAssessment = assessments !== void 0 && Object.hasOwn(assessments, slotId) ? assessments[slotId] : void 0;
485
486
  return /* @__PURE__ */ jsxRuntime.jsx(
486
- chunk36FTYJWJ_cjs.ReadAloud,
487
+ chunkZH5WT2IE_cjs.ReadAloud,
487
488
  {
488
489
  data: activity,
489
490
  ...childProps,
490
491
  ...slotRecordingBinding !== void 0 ? { recordingBinding: slotRecordingBinding } : {},
491
- ...slotAssessment !== void 0 ? { assessment: slotAssessment } : {}
492
+ ...slotAssessment !== void 0 ? { assessment: slotAssessment } : {},
493
+ ...workletUrl !== void 0 ? { workletUrl } : {}
492
494
  }
493
495
  );
494
496
  }
495
497
  if (activity.type === "written-response") {
496
498
  const { onComplete: _neverGrades, ...writtenResponseProps } = childProps;
497
499
  return /* @__PURE__ */ jsxRuntime.jsx(
498
- chunkYEYKJFEC_cjs.WrittenResponse,
500
+ chunk26GQO5I2_cjs.WrittenResponse,
499
501
  {
500
502
  data: activity,
501
503
  ...writtenResponseProps,
@@ -520,7 +522,7 @@ function ActivitySequence({
520
522
  className: "lk-seq-stimulus",
521
523
  hidden: entryKey !== currentEntryKey,
522
524
  children: /* @__PURE__ */ jsxRuntime.jsx(
523
- chunkRRH7ZPXC_cjs.StimulusPanel,
525
+ chunkDP3DM7FR_cjs.StimulusPanel,
524
526
  {
525
527
  stimulus: group.stimulus,
526
528
  range: { first: first + 1, last: last + 1 },
@@ -585,5 +587,5 @@ function ActivitySequence({
585
587
  }
586
588
 
587
589
  exports.ActivitySequence = ActivitySequence;
588
- //# sourceMappingURL=chunk-J2CDPIRC.cjs.map
589
- //# sourceMappingURL=chunk-J2CDPIRC.cjs.map
590
+ //# sourceMappingURL=chunk-DQ3VVU5T.cjs.map
591
+ //# sourceMappingURL=chunk-DQ3VVU5T.cjs.map