@mieweb/ui 0.7.2 → 0.7.3

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 (144) hide show
  1. package/dist/CsvBlock-OTFG3PYZ.cjs +15 -0
  2. package/dist/{CsvBlock-LVJARITD.cjs.map → CsvBlock-OTFG3PYZ.cjs.map} +1 -1
  3. package/dist/CsvBlock-PUSTBQ5B.js +6 -0
  4. package/dist/{CsvBlock-VTYNQ75L.js.map → CsvBlock-PUSTBQ5B.js.map} +1 -1
  5. package/dist/HtmlPreviewBlock-QHLSIMWJ.cjs +15 -0
  6. package/dist/{HtmlPreviewBlock-F33P37UD.cjs.map → HtmlPreviewBlock-QHLSIMWJ.cjs.map} +1 -1
  7. package/dist/HtmlPreviewBlock-YF2YVKKX.js +6 -0
  8. package/dist/{HtmlPreviewBlock-N4PPVJLJ.js.map → HtmlPreviewBlock-YF2YVKKX.js.map} +1 -1
  9. package/dist/MermaidBlock-H3TWNC4D.js +6 -0
  10. package/dist/{MermaidBlock-HUT53CRG.js.map → MermaidBlock-H3TWNC4D.js.map} +1 -1
  11. package/dist/MermaidBlock-ZLLBO3VY.cjs +15 -0
  12. package/dist/{MermaidBlock-G5X4FPUN.cjs.map → MermaidBlock-ZLLBO3VY.cjs.map} +1 -1
  13. package/dist/SurveyBlock-JLHS3YQD.js +6 -0
  14. package/dist/{SurveyBlock-PM3ZMWWR.js.map → SurveyBlock-JLHS3YQD.js.map} +1 -1
  15. package/dist/SurveyBlock-M2ZRTGVJ.cjs +15 -0
  16. package/dist/{SurveyBlock-ORTPGA5T.cjs.map → SurveyBlock-M2ZRTGVJ.cjs.map} +1 -1
  17. package/dist/brands/index.cjs +17 -17
  18. package/dist/brands/index.js +4 -4
  19. package/dist/{chunk-6QVI6DAO.cjs → chunk-4CUFXCC5.cjs} +5 -5
  20. package/dist/{chunk-6QVI6DAO.cjs.map → chunk-4CUFXCC5.cjs.map} +1 -1
  21. package/dist/{chunk-BMRQ4VME.js → chunk-4PIW3Y5M.js} +15 -8
  22. package/dist/chunk-4PIW3Y5M.js.map +1 -0
  23. package/dist/{chunk-6OCYG6J2.js → chunk-5J5PEUUA.js} +4 -4
  24. package/dist/{chunk-6OCYG6J2.js.map → chunk-5J5PEUUA.js.map} +1 -1
  25. package/dist/{chunk-DWIF6VXZ.js → chunk-6MMIWE7H.js} +13 -2
  26. package/dist/chunk-6MMIWE7H.js.map +1 -0
  27. package/dist/chunk-7C226TQI.js +76 -0
  28. package/dist/chunk-7C226TQI.js.map +1 -0
  29. package/dist/{chunk-WRYZ2752.js → chunk-D2GID3YK.js} +29 -6
  30. package/dist/chunk-D2GID3YK.js.map +1 -0
  31. package/dist/{chunk-VE6OUO7X.js → chunk-DWCYEPTT.js} +3 -3
  32. package/dist/{chunk-VE6OUO7X.js.map → chunk-DWCYEPTT.js.map} +1 -1
  33. package/dist/{chunk-NU6QKULE.js → chunk-EHQ77LL5.js} +3 -3
  34. package/dist/{chunk-NU6QKULE.js.map → chunk-EHQ77LL5.js.map} +1 -1
  35. package/dist/{chunk-PS5INHGC.js → chunk-EMMYFHOT.js} +3 -3
  36. package/dist/{chunk-PS5INHGC.js.map → chunk-EMMYFHOT.js.map} +1 -1
  37. package/dist/{chunk-ABAOZASX.cjs → chunk-FN6VHMLM.cjs} +8 -8
  38. package/dist/{chunk-ABAOZASX.cjs.map → chunk-FN6VHMLM.cjs.map} +1 -1
  39. package/dist/{chunk-H3HF36ZL.js → chunk-FPVRQCCL.js} +3 -3
  40. package/dist/{chunk-H3HF36ZL.js.map → chunk-FPVRQCCL.js.map} +1 -1
  41. package/dist/{chunk-5BDCQBYW.js → chunk-FTRGZOVJ.js} +3 -3
  42. package/dist/{chunk-5BDCQBYW.js.map → chunk-FTRGZOVJ.js.map} +1 -1
  43. package/dist/{chunk-7EB7665B.cjs → chunk-H7QSGFMZ.cjs} +8 -8
  44. package/dist/{chunk-7EB7665B.cjs.map → chunk-H7QSGFMZ.cjs.map} +1 -1
  45. package/dist/{chunk-VA7QN4DX.cjs → chunk-JDHIBJ5K.cjs} +2 -2
  46. package/dist/{chunk-VA7QN4DX.cjs.map → chunk-JDHIBJ5K.cjs.map} +1 -1
  47. package/dist/{chunk-OGPJ3LRF.cjs → chunk-JP5SGIXA.cjs} +4 -4
  48. package/dist/{chunk-OGPJ3LRF.cjs.map → chunk-JP5SGIXA.cjs.map} +1 -1
  49. package/dist/{chunk-TU36DBH2.cjs → chunk-K4S4FAYX.cjs} +9 -9
  50. package/dist/{chunk-TU36DBH2.cjs.map → chunk-K4S4FAYX.cjs.map} +1 -1
  51. package/dist/{chunk-3SRBIXQX.js → chunk-KRGKPUJH.js} +3 -3
  52. package/dist/{chunk-3SRBIXQX.js.map → chunk-KRGKPUJH.js.map} +1 -1
  53. package/dist/{chunk-NGLI2MSM.js → chunk-LC7YHZXM.js} +4 -4
  54. package/dist/{chunk-NGLI2MSM.js.map → chunk-LC7YHZXM.js.map} +1 -1
  55. package/dist/{chunk-6OQE4ZMG.cjs → chunk-LJBWCUKP.cjs} +8 -8
  56. package/dist/{chunk-6OQE4ZMG.cjs.map → chunk-LJBWCUKP.cjs.map} +1 -1
  57. package/dist/{chunk-54OW6ZPL.cjs → chunk-LJDBD2DD.cjs} +13 -2
  58. package/dist/chunk-LJDBD2DD.cjs.map +1 -0
  59. package/dist/{chunk-BCJFOSZX.js → chunk-MO65V64I.js} +2 -2
  60. package/dist/{chunk-BCJFOSZX.js.map → chunk-MO65V64I.js.map} +1 -1
  61. package/dist/{chunk-BX5ZODPF.js → chunk-N3Y43KOB.js} +3 -3
  62. package/dist/{chunk-BX5ZODPF.js.map → chunk-N3Y43KOB.js.map} +1 -1
  63. package/dist/{chunk-RZFSJD67.js → chunk-NLBT5O2X.js} +3 -3
  64. package/dist/{chunk-RZFSJD67.js.map → chunk-NLBT5O2X.js.map} +1 -1
  65. package/dist/{chunk-VWCMOWGH.cjs → chunk-NQ2D2V6O.cjs} +16 -16
  66. package/dist/{chunk-VWCMOWGH.cjs.map → chunk-NQ2D2V6O.cjs.map} +1 -1
  67. package/dist/{chunk-7AMOKHTW.cjs → chunk-P3JEMF6E.cjs} +4 -4
  68. package/dist/{chunk-7AMOKHTW.cjs.map → chunk-P3JEMF6E.cjs.map} +1 -1
  69. package/dist/{chunk-M26KJKZG.cjs → chunk-RDGRKYQ5.cjs} +29 -6
  70. package/dist/chunk-RDGRKYQ5.cjs.map +1 -0
  71. package/dist/chunk-SEN7FIF3.cjs +158 -0
  72. package/dist/chunk-SEN7FIF3.cjs.map +1 -0
  73. package/dist/{chunk-VVI32P7L.cjs → chunk-SPWVKDGC.cjs} +15 -7
  74. package/dist/chunk-SPWVKDGC.cjs.map +1 -0
  75. package/dist/{chunk-Q5VBO3I5.cjs → chunk-SYIFEJSF.cjs} +26 -26
  76. package/dist/{chunk-Q5VBO3I5.cjs.map → chunk-SYIFEJSF.cjs.map} +1 -1
  77. package/dist/{chunk-CKRRJO7T.cjs → chunk-TVLZZI5Q.cjs} +5 -5
  78. package/dist/{chunk-CKRRJO7T.cjs.map → chunk-TVLZZI5Q.cjs.map} +1 -1
  79. package/dist/{chunk-QI2SB6U3.cjs → chunk-URHXR5SC.cjs} +14 -14
  80. package/dist/{chunk-QI2SB6U3.cjs.map → chunk-URHXR5SC.cjs.map} +1 -1
  81. package/dist/{chunk-MWPPOX6F.js → chunk-UZ5NGGMI.js} +4 -4
  82. package/dist/{chunk-MWPPOX6F.js.map → chunk-UZ5NGGMI.js.map} +1 -1
  83. package/dist/{chunk-RUEEDOE3.cjs → chunk-YIXTGWT4.cjs} +5 -5
  84. package/dist/{chunk-RUEEDOE3.cjs.map → chunk-YIXTGWT4.cjs.map} +1 -1
  85. package/dist/{chunk-OLFTGCGD.js → chunk-Z4PECE5S.js} +7 -7
  86. package/dist/{chunk-OLFTGCGD.js.map → chunk-Z4PECE5S.js.map} +1 -1
  87. package/dist/components/AlertDialog/index.cjs +3 -3
  88. package/dist/components/AlertDialog/index.js +2 -2
  89. package/dist/components/Button/index.cjs +3 -3
  90. package/dist/components/Button/index.js +1 -1
  91. package/dist/components/CountryCodeDropdown/index.cjs +4 -4
  92. package/dist/components/CountryCodeDropdown/index.d.cts +5 -1
  93. package/dist/components/CountryCodeDropdown/index.d.ts +5 -1
  94. package/dist/components/CountryCodeDropdown/index.js +1 -1
  95. package/dist/components/FloatingWindow/index.cjs +4 -4
  96. package/dist/components/FloatingWindow/index.js +2 -2
  97. package/dist/components/Markdown/index.cjs +16 -16
  98. package/dist/components/Markdown/index.js +7 -7
  99. package/dist/components/MediaEditor/index.cjs +8 -8
  100. package/dist/components/MediaEditor/index.js +3 -3
  101. package/dist/components/MediaPlayer/index.cjs +5 -5
  102. package/dist/components/MediaPlayer/index.js +2 -2
  103. package/dist/components/Q/index.cjs +109 -0
  104. package/dist/components/Q/index.cjs.map +1 -0
  105. package/dist/components/Q/index.d.cts +27 -0
  106. package/dist/components/Q/index.d.ts +27 -0
  107. package/dist/components/Q/index.js +4 -0
  108. package/dist/components/Q/index.js.map +1 -0
  109. package/dist/components/RichTextEditor/index.cjs +5 -5
  110. package/dist/components/RichTextEditor/index.js +2 -2
  111. package/dist/datavis.cjs +2 -2
  112. package/dist/datavis.js +1 -1
  113. package/dist/esheet.cjs +5 -5
  114. package/dist/esheet.js +2 -2
  115. package/dist/index.cjs +967 -594
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.d.cts +219 -3
  118. package/dist/index.d.ts +219 -3
  119. package/dist/index.js +408 -39
  120. package/dist/index.js.map +1 -1
  121. package/dist/q.cjs +109 -0
  122. package/dist/q.cjs.map +1 -0
  123. package/dist/q.d.cts +5 -0
  124. package/dist/q.d.ts +5 -0
  125. package/dist/q.js +4 -0
  126. package/dist/q.js.map +1 -0
  127. package/dist/styles.css +1 -1
  128. package/dist/tailwind-preset.cjs +4 -4
  129. package/dist/tailwind-preset.js +1 -1
  130. package/package.json +19 -4
  131. package/dist/CsvBlock-LVJARITD.cjs +0 -15
  132. package/dist/CsvBlock-VTYNQ75L.js +0 -6
  133. package/dist/HtmlPreviewBlock-F33P37UD.cjs +0 -15
  134. package/dist/HtmlPreviewBlock-N4PPVJLJ.js +0 -6
  135. package/dist/MermaidBlock-G5X4FPUN.cjs +0 -15
  136. package/dist/MermaidBlock-HUT53CRG.js +0 -6
  137. package/dist/SurveyBlock-ORTPGA5T.cjs +0 -15
  138. package/dist/SurveyBlock-PM3ZMWWR.js +0 -6
  139. package/dist/chunk-54OW6ZPL.cjs.map +0 -1
  140. package/dist/chunk-BMRQ4VME.js.map +0 -1
  141. package/dist/chunk-DWIF6VXZ.js.map +0 -1
  142. package/dist/chunk-M26KJKZG.cjs.map +0 -1
  143. package/dist/chunk-VVI32P7L.cjs.map +0 -1
  144. package/dist/chunk-WRYZ2752.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/MediaEditor/FillerWordsModal.tsx","../src/components/MediaEditor/WordEditorModal.tsx","../src/components/MediaEditor/SilenceSettingsModal.tsx","../src/components/MediaEditor/SpeedMarkerMenu.tsx","../src/components/MediaEditor/ScriptPanel.tsx","../src/components/MediaEditor/MediaEditor.tsx"],"names":["React","React2","jsxs","jsx","React3","React4","React5","formatDuration"],"mappings":"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","file":"chunk-NGLI2MSM.js","sourcesContent":["/**\n * FillerWordsModal — select filler words (and long silences) to mark deleted.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. Pure UI: match\n * counts/durations come in via props (see useTranscriptEdits.fillerAnalysis);\n * the selection is reported through onApply.\n */\n\nimport * as React from 'react';\nimport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalClose,\n ModalBody,\n ModalFooter,\n} from '../Modal';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\nimport { Checkbox } from '../Checkbox';\nimport { Select } from '../Select';\nimport { DEFAULT_FILLER_WORDS } from '../../hooks/useTranscriptEdits';\nimport type { SilenceThresholdCount } from '../../hooks/useTranscriptEdits';\n\nexport interface FillerWordsModalProps {\n isOpen: boolean;\n onClose: () => void;\n /** Apply removal: selected filler words + optional silence threshold (seconds) */\n onApply: (\n fillerWords: string[],\n removeSilenceAboveSec: number | null\n ) => void;\n /** Occurrence count per normalized word */\n matchingCounts: Map<string, number>;\n /** Total duration (ms) per filler word */\n fillerDurations: Map<string, number>;\n /** Count and total duration of silences at each threshold */\n silenceCounts: SilenceThresholdCount[];\n /** Current total edited duration in ms */\n currentDurationMs: number;\n}\n\nconst SILENCE_THRESHOLD_OPTIONS = [0.3, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0];\n\n/** Format duration in seconds or m:ss */\nfunction formatDuration(ms: number): string {\n const totalSeconds = Math.round(ms / 1000);\n if (totalSeconds < 90) {\n return `${totalSeconds}s`;\n }\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\n/** Modal for selecting filler words to remove from the edited transcript */\nexport const FillerWordsModal: React.FC<FillerWordsModalProps> = ({\n isOpen,\n onClose,\n onApply,\n matchingCounts,\n fillerDurations,\n silenceCounts,\n currentDurationMs,\n}) => {\n const [searchTerm, setSearchTerm] = React.useState('');\n const [selectedFillers, setSelectedFillers] = React.useState<Set<string>>(\n new Set(DEFAULT_FILLER_WORDS)\n );\n const [customWord, setCustomWord] = React.useState('');\n const [removeSilence, setRemoveSilence] = React.useState(false);\n const [silenceThreshold, setSilenceThreshold] = React.useState(0.4);\n\n // Filter filler words based on search, then sort by count (matches first)\n const filteredFillers = DEFAULT_FILLER_WORDS.filter((word) =>\n word.toLowerCase().includes(searchTerm.toLowerCase())\n ).sort((a, b) => {\n const countA = matchingCounts.get(a) || 0;\n const countB = matchingCounts.get(b) || 0;\n if (countB !== countA) return countB - countA;\n return a.localeCompare(b);\n });\n\n // Custom words that have been added, sorted by count\n const customFillers = Array.from(selectedFillers)\n .filter((word) => !DEFAULT_FILLER_WORDS.includes(word))\n .filter((word) => word.toLowerCase().includes(searchTerm.toLowerCase()))\n .sort((a, b) => {\n const countA = matchingCounts.get(a) || 0;\n const countB = matchingCounts.get(b) || 0;\n if (countB !== countA) return countB - countA;\n return a.localeCompare(b);\n });\n\n const toggleFiller = (word: string) => {\n setSelectedFillers((prev) => {\n const next = new Set(prev);\n if (next.has(word)) {\n next.delete(word);\n } else {\n next.add(word);\n }\n return next;\n });\n };\n\n const handleAddCustom = () => {\n const trimmed = customWord.trim().toLowerCase();\n if (trimmed && !selectedFillers.has(trimmed)) {\n setSelectedFillers((prev) => new Set([...prev, trimmed]));\n setCustomWord('');\n }\n };\n\n // Count and duration of silences that would be removed at the current threshold\n const silenceData = removeSilence\n ? silenceCounts.find((s) => s.threshold === silenceThreshold) || {\n count: 0,\n durationMs: 0,\n }\n : { count: 0, durationMs: 0 };\n const silenceRemovalCount = silenceData.count;\n const silenceDurationMs = silenceData.durationMs;\n\n const handleApply = () => {\n onApply(\n Array.from(selectedFillers),\n removeSilence ? silenceThreshold : null\n );\n onClose();\n };\n\n const selectAll = () => {\n setSelectedFillers(new Set([...DEFAULT_FILLER_WORDS, ...customFillers]));\n };\n\n const selectNone = () => {\n setSelectedFillers(new Set());\n };\n\n // Total matches (filler words + silences)\n const fillerMatches = Array.from(selectedFillers).reduce(\n (sum, word) => sum + (matchingCounts.get(word) || 0),\n 0\n );\n const totalMatches = fillerMatches + silenceRemovalCount;\n\n // Time saved from filler words + silences\n const fillerTimeSavedMs = Array.from(selectedFillers).reduce(\n (sum, word) => sum + (fillerDurations.get(word) || 0),\n 0\n );\n const totalTimeSavedMs = fillerTimeSavedMs + silenceDurationMs;\n const newDurationMs = currentDurationMs - totalTimeSavedMs;\n\n const renderFillerItem = (word: string, isCustom: boolean) => {\n const count = matchingCounts.get(word) || 0;\n return (\n <label\n key={word}\n className=\"hover:bg-muted flex cursor-pointer items-center gap-2 rounded-md px-1.5 py-1 text-sm transition-colors\"\n >\n <Checkbox\n size=\"sm\"\n checked={selectedFillers.has(word)}\n onChange={() => toggleFiller(word)}\n aria-label={`Remove \"${word}\"`}\n />\n <span className=\"text-foreground min-w-0 flex-1 truncate\">{word}</span>\n {count > 0 && (\n <span className=\"text-muted-foreground text-xs\">({count})</span>\n )}\n {isCustom && (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:ring-ring rounded px-1 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n onClick={(e) => {\n e.preventDefault();\n setSelectedFillers((prev) => {\n const next = new Set(prev);\n next.delete(word);\n return next;\n });\n }}\n aria-label={`Remove ${word}`}\n >\n ×\n </button>\n )}\n </label>\n );\n };\n\n return (\n <Modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n size=\"lg\"\n >\n <ModalHeader>\n <ModalTitle>Remove Filler Words</ModalTitle>\n <ModalClose aria-label=\"Close modal\" />\n </ModalHeader>\n\n <ModalBody className=\"flex flex-col gap-3\">\n <Input\n size=\"sm\"\n type=\"text\"\n placeholder=\"Search filler words...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n aria-label=\"Search filler words\"\n />\n\n <div className=\"flex items-center gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={selectAll}>\n Select All\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={selectNone}>\n Select None\n </Button>\n </div>\n\n <div className=\"border-border bg-muted/40 flex flex-wrap items-center gap-2 rounded-lg border px-3 py-2\">\n <Checkbox\n size=\"sm\"\n label=\"Remove silences greater than\"\n checked={removeSilence}\n onChange={(e) => setRemoveSilence(e.target.checked)}\n />\n <div className=\"w-24\">\n <Select\n size=\"sm\"\n options={SILENCE_THRESHOLD_OPTIONS.map((t) => ({\n value: String(t),\n label: `${t}s`,\n }))}\n value={String(silenceThreshold)}\n onValueChange={(value) => setSilenceThreshold(parseFloat(value))}\n disabled={!removeSilence}\n aria-label=\"Silence threshold in seconds\"\n />\n </div>\n {removeSilence && silenceRemovalCount > 0 && (\n <span className=\"text-muted-foreground text-xs\">\n ({silenceRemovalCount} silences)\n </span>\n )}\n </div>\n\n <div className=\"border-border grid max-h-56 grid-cols-2 gap-x-3 gap-y-0.5 overflow-y-auto rounded-lg border p-2 sm:grid-cols-3\">\n {filteredFillers.map((word) => renderFillerItem(word, false))}\n {customFillers.map((word) => renderFillerItem(word, true))}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <Input\n size=\"sm\"\n type=\"text\"\n placeholder=\"Add custom filler word...\"\n value={customWord}\n onChange={(e) => setCustomWord(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddCustom();\n }\n }}\n aria-label=\"Add custom filler word\"\n />\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleAddCustom}\n disabled={!customWord.trim()}\n >\n Add\n </Button>\n </div>\n </ModalBody>\n\n <ModalFooter className=\"justify-between\">\n <span className=\"text-muted-foreground text-sm\">\n {totalMatches} items • saves {formatDuration(totalTimeSavedMs)} →{' '}\n {formatDuration(newDurationMs)}\n </span>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancel\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={handleApply}\n disabled={totalMatches === 0}\n >\n Mark as Deleted ({totalMatches})\n </Button>\n </div>\n </ModalFooter>\n </Modal>\n );\n};\n\nFillerWordsModal.displayName = 'FillerWordsModal';\n","/**\n * WordEditorModal — edit a word's text or split a silence into segments.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. For silences,\n * space-separated durations (e.g. \"1 1 4 1\") split the silence; the\n * remainder becomes the final segment.\n */\n\nimport * as React from 'react';\nimport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalClose,\n ModalBody,\n ModalFooter,\n} from '../Modal';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\nimport { isSilenceType } from '../TranscriptView/transcript';\nimport type { EditableWord } from '../TranscriptView/transcript';\n\nexport interface WordEditorModalProps {\n isOpen: boolean;\n editableWord: EditableWord | null;\n onClose: () => void;\n /** Save a new text for the word */\n onSave: (newText: string) => void;\n /** Split a silence into segments with the given durations (seconds) */\n onSplitSilence: (durations: number[]) => void;\n /** Toggle the word's deleted state */\n onDelete: () => void;\n}\n\ninterface SilenceSplitResult {\n durations: number[];\n remainder: number;\n error?: string;\n}\n\n/**\n * Modal for editing a word or splitting a silence.\n * For silences, enter space-separated durations (e.g., \"1 1 4 1\") to split.\n */\nexport const WordEditorModal: React.FC<WordEditorModalProps> = ({\n isOpen,\n editableWord,\n onClose,\n onSave,\n onSplitSilence,\n onDelete,\n}) => {\n const [inputValue, setInputValue] = React.useState('');\n const [error, setError] = React.useState<string | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n const isSilence = isSilenceType(editableWord?.word.wordType);\n const durationMs = editableWord\n ? editableWord.word.endMs - editableWord.word.startMs\n : 0;\n const durationSec = durationMs / 1000;\n\n // Reset input when the modal opens\n React.useEffect(() => {\n if (isOpen && editableWord) {\n if (isSilence) {\n setInputValue('');\n } else {\n setInputValue(editableWord.word.text);\n }\n setError(null);\n // Focus input after a short delay so it wins over the modal's focus trap\n setTimeout(() => inputRef.current?.focus(), 50);\n }\n }, [isOpen, editableWord, isSilence]);\n\n // Parse silence split input (pure function, no side effects)\n const parseSilenceSplit = (input: string): SilenceSplitResult | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n const parts = trimmed.split(/\\s+/);\n const durations: number[] = [];\n let total = 0;\n\n for (const part of parts) {\n const num = parseFloat(part);\n if (isNaN(num) || num <= 0) {\n return {\n durations: [],\n remainder: 0,\n error: `Invalid number: \"${part}\"`,\n };\n }\n durations.push(num);\n total += num;\n }\n\n if (total >= durationSec) {\n return {\n durations: [],\n remainder: 0,\n error: `Total (${total.toFixed(1)}s) exceeds silence duration (${durationSec.toFixed(1)}s)`,\n };\n }\n\n const remainder = durationSec - total;\n return { durations, remainder };\n };\n\n const handleApply = () => {\n if (isSilence) {\n const parsed = parseSilenceSplit(inputValue);\n if (parsed?.error) {\n setError(parsed.error);\n return;\n }\n if (parsed && parsed.durations.length > 0) {\n // Add the remainder as the final segment\n const allDurations = [...parsed.durations, parsed.remainder];\n onSplitSilence(allDurations);\n onClose();\n }\n } else {\n const trimmed = inputValue.trim();\n if (trimmed && trimmed !== editableWord?.word.text) {\n onSave(trimmed);\n }\n onClose();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleApply();\n }\n };\n\n // Preview for silence splitting\n const preview = isSilence ? parseSilenceSplit(inputValue) : null;\n\n const applyDisabled = isSilence\n ? !inputValue.trim() ||\n !!preview?.error ||\n !preview ||\n preview.durations.length === 0\n : !inputValue.trim();\n\n return (\n <Modal\n open={isOpen && editableWord !== null}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n size=\"md\"\n >\n <ModalHeader>\n <ModalTitle>{isSilence ? 'Split Silence' : 'Edit Word'}</ModalTitle>\n <ModalClose aria-label=\"Close editor\" />\n </ModalHeader>\n\n <ModalBody className=\"flex flex-col gap-2\">\n {isSilence ? (\n <>\n <p className=\"text-foreground m-0 text-sm\">\n Silence duration:{' '}\n <strong className=\"font-semibold\">\n {durationSec.toFixed(1)}s\n </strong>\n </p>\n <p className=\"text-muted-foreground m-0 text-xs\">\n Enter space-separated durations to split (e.g., &quot;1 1 4\n 1&quot;)\n </p>\n <Input\n ref={inputRef}\n type=\"text\"\n value={inputValue}\n onChange={(e) => {\n setInputValue(e.target.value);\n setError(null);\n }}\n onKeyDown={handleKeyDown}\n placeholder=\"1 2 3...\"\n aria-label=\"Split durations\"\n />\n {error && (\n <p className=\"text-destructive m-0 text-sm\" role=\"alert\">\n {error}\n </p>\n )}\n {preview &&\n !preview.error &&\n preview.durations.length > 0 &&\n !error && (\n <p className=\"text-muted-foreground m-0 text-sm\">\n Preview:{' '}\n {[...preview.durations, preview.remainder]\n .map((d) => `[${d.toFixed(1)}s]`)\n .join(' ')}\n </p>\n )}\n {preview?.error && !error && (\n <p className=\"text-destructive m-0 text-sm\" role=\"alert\">\n {preview.error}\n </p>\n )}\n </>\n ) : (\n <>\n <p className=\"text-foreground m-0 text-sm\">Edit the word text:</p>\n <Input\n ref={inputRef}\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={handleKeyDown}\n aria-label=\"Word text\"\n />\n </>\n )}\n </ModalBody>\n\n <ModalFooter className=\"justify-between\">\n <Button\n variant={editableWord?.deleted ? 'secondary' : 'danger'}\n size=\"sm\"\n onClick={onDelete}\n >\n {editableWord?.deleted ? 'Restore' : 'Delete'}\n </Button>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancel\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={handleApply}\n disabled={applyDisabled}\n >\n {isSilence ? 'Split' : 'Save'}\n </Button>\n </div>\n </ModalFooter>\n </Modal>\n );\n};\n\nWordEditorModal.displayName = 'WordEditorModal';\n","/**\n * SilenceSettingsModal — configure silence detection thresholds.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. The paragraph\n * break threshold is clamped to be >= the minimum silence duration.\n */\n\nimport * as React from 'react';\nimport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalClose,\n ModalBody,\n ModalFooter,\n} from '../Modal';\nimport { Button } from '../Button';\nimport { Slider } from '../Slider';\n\nexport interface SilenceSettingsModalProps {\n isOpen: boolean;\n onClose: () => void;\n /** Current minimum silence duration (ms) */\n minSilenceMs: number;\n /** Current paragraph break threshold (ms) */\n nlSilenceMs: number;\n /** Apply new thresholds (both in ms) */\n onApply: (minSilenceMs: number, nlSilenceMs: number) => void;\n}\n\n/** Modal for configuring silence detection settings */\nexport const SilenceSettingsModal: React.FC<SilenceSettingsModalProps> = ({\n isOpen,\n onClose,\n minSilenceMs,\n nlSilenceMs,\n onApply,\n}) => {\n const [threshold, setThreshold] = React.useState(minSilenceMs / 1000);\n const [nlThreshold, setNlThreshold] = React.useState(nlSilenceMs / 1000);\n\n // Reset when the modal opens\n React.useEffect(() => {\n if (isOpen) {\n setThreshold(minSilenceMs / 1000);\n setNlThreshold(nlSilenceMs / 1000);\n }\n }, [isOpen, minSilenceMs, nlSilenceMs]);\n\n const handleApply = () => {\n // Ensure nlThreshold is always >= threshold\n const finalNlThreshold = Math.max(nlThreshold, threshold);\n onApply(Math.round(threshold * 1000), Math.round(finalNlThreshold * 1000));\n onClose();\n };\n\n // Auto-adjust newline threshold if it would be less than the min threshold\n const handleThresholdChange = (value: number) => {\n setThreshold(value);\n if (nlThreshold < value) {\n setNlThreshold(value);\n }\n };\n\n const formatSeconds = (v: number) => `${v.toFixed(1)}s`;\n\n return (\n <Modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n size=\"md\"\n >\n <ModalHeader>\n <ModalTitle>Silence Settings</ModalTitle>\n <ModalClose aria-label=\"Close modal\" />\n </ModalHeader>\n\n <ModalBody className=\"flex flex-col gap-6\">\n <div className=\"flex flex-col gap-1\">\n <Slider\n label=\"Minimum silence duration\"\n min={0.1}\n max={2}\n step={0.1}\n value={threshold}\n onValueChange={handleThresholdChange}\n showValue\n formatValue={formatSeconds}\n aria-label=\"Minimum silence duration\"\n />\n <p className=\"text-muted-foreground m-0 text-xs\">\n Gaps shorter than this will not be shown as silences.\n </p>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Slider\n label=\"Paragraph break threshold\"\n min={threshold}\n max={5}\n step={0.1}\n value={nlThreshold}\n onValueChange={setNlThreshold}\n showValue\n formatValue={formatSeconds}\n aria-label=\"Paragraph break threshold\"\n />\n <p className=\"text-muted-foreground m-0 text-xs\">\n Silences longer than this will create paragraph breaks.\n </p>\n </div>\n </ModalBody>\n\n <ModalFooter>\n <Button variant=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancel\n </Button>\n <Button variant=\"primary\" size=\"sm\" onClick={handleApply}>\n Apply\n </Button>\n </ModalFooter>\n </Modal>\n );\n};\n\nSilenceSettingsModal.displayName = 'SilenceSettingsModal';\n","/**\n * SpeedMarkerMenu — context-menu popup for setting per-word speed markers.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. Hand-built (plain\n * elements + tokens): a positioned context menu has no @mieweb/ui primitive.\n */\n\nimport * as React from 'react';\nimport type { PlaybackSpeed, SpeedMarker } from '../TranscriptView/transcript';\nimport { PLAYBACK_SPEEDS } from '../TranscriptView/transcript';\n\nexport interface SpeedMarkerMenuProps {\n isOpen: boolean;\n /** Viewport coordinates for the menu (already clamped by the caller) */\n position: { x: number; y: number } | null;\n /** The edited-word index the menu applies to */\n wordIndex: number | null;\n /** Existing marker at that word, if any */\n currentMarker: SpeedMarker | undefined;\n defaultSpeed: PlaybackSpeed;\n onSetSpeed: (speed: PlaybackSpeed) => void;\n onRemoveMarker: () => void;\n onClose: () => void;\n}\n\n/** Popup menu for setting speed markers on a word */\nexport const SpeedMarkerMenu: React.FC<SpeedMarkerMenuProps> = ({\n isOpen,\n position,\n currentMarker,\n defaultSpeed,\n onSetSpeed,\n onRemoveMarker,\n onClose,\n}) => {\n const menuRef = React.useRef<HTMLDivElement>(null);\n\n // Close on escape or click outside\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n const handleClickOutside = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n onClose();\n }\n };\n if (isOpen) {\n document.addEventListener('keydown', handleKeyDown);\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }\n }, [isOpen, onClose]);\n\n if (!isOpen || !position) return null;\n\n return (\n <div\n ref={menuRef}\n className=\"border-border bg-card text-card-foreground fixed z-50 min-w-36 overflow-hidden rounded-lg border shadow-lg\"\n style={{ left: position.x, top: position.y }}\n role=\"menu\"\n aria-label=\"Set speed marker\"\n >\n <div className=\"border-border text-muted-foreground border-b px-3 py-1.5 text-xs font-semibold\">\n Set Speed Marker\n </div>\n <div className=\"flex flex-col p-1\">\n {PLAYBACK_SPEEDS.map((speed) => {\n const isActive = currentMarker?.speed === speed;\n const isDefault = speed === defaultSpeed && !currentMarker;\n return (\n <button\n key={speed}\n type=\"button\"\n className={`focus-visible:ring-ring flex items-center justify-between gap-2 rounded-md px-2.5 py-1 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive\n ? 'bg-primary-600 font-medium text-white'\n : 'text-foreground hover:bg-muted'\n }`}\n onClick={() => {\n onSetSpeed(speed);\n onClose();\n }}\n role=\"menuitem\"\n >\n {speed}x\n {isDefault && (\n <span className=\"text-muted-foreground text-xs\">default</span>\n )}\n </button>\n );\n })}\n </div>\n {currentMarker && (\n <button\n type=\"button\"\n className=\"border-border text-destructive hover:bg-destructive/10 focus-visible:ring-ring w-full border-t px-2.5 py-1.5 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => {\n onRemoveMarker();\n onClose();\n }}\n role=\"menuitem\"\n >\n Remove Marker\n </button>\n )}\n </div>\n );\n};\n\nSpeedMarkerMenu.displayName = 'SpeedMarkerMenu';\n","/**\n * ScriptPanel — the transcript \"script\" as editable YAML/JSON, side by side\n * with the editor.\n *\n * Two sources: \"Editor\" is the live edit state (EditableWord[], remapped as\n * you edit) and can be edited as text and applied back; \"Original\" is the\n * canonical transcript (immutable, read-only). The panel live-follows the\n * editor until you start typing; Apply parses + validates and replaces the\n * edit state (undo-safe via useTranscriptEdits.replaceEditedWords).\n *\n * js-yaml is loaded lazily on first use (same pattern as Markdown's\n * SurveyBlock) so it stays out of the MediaEditor bundle.\n */\n\nimport * as React from 'react';\nimport { Button } from '../Button';\nimport type {\n Transcript,\n EditableWord,\n TranscriptWord,\n} from '../TranscriptView/transcript';\n\nlet yamlPromise: Promise<typeof import('js-yaml')> | null = null;\nfunction loadYaml() {\n yamlPromise ??= import(/* @vite-ignore */ 'js-yaml');\n return yamlPromise;\n}\n\nexport interface ScriptPanelProps {\n /** The canonical transcript (read-only source) */\n transcript: Transcript;\n /** The live edit state (editable source) */\n editedWords: EditableWord[];\n /** Apply parsed script back into the editor */\n onApply: (words: EditableWord[]) => void;\n /** Close the panel */\n onClose: () => void;\n className?: string;\n}\n\ntype ScriptSource = 'editor' | 'original';\ntype ScriptFormat = 'yaml' | 'json';\n\n/** Parse + validate script text into EditableWord[]; throws with a readable message. */\nasync function parseScript(\n text: string,\n format: ScriptFormat\n): Promise<EditableWord[]> {\n let data: unknown;\n if (format === 'json') {\n data = JSON.parse(text);\n } else {\n const yaml = await loadYaml();\n data = yaml.load(text);\n }\n if (!Array.isArray(data)) {\n throw new Error('Script must be a list of word entries.');\n }\n return data.map((raw, i) => {\n const ew = raw as {\n originalIndex?: unknown;\n deleted?: unknown;\n inserted?: unknown;\n word?: Record<string, unknown>;\n };\n const w = ew.word;\n if (\n !w ||\n typeof w.text !== 'string' ||\n typeof w.startMs !== 'number' ||\n typeof w.endMs !== 'number'\n ) {\n throw new Error(\n `Entry ${i + 1}: each entry needs word.text, word.startMs and word.endMs.`\n );\n }\n if (\n w.wordType !== undefined &&\n w.wordType !== 'word' &&\n w.wordType !== 'silence' &&\n w.wordType !== 'silence-newline'\n ) {\n throw new Error(\n `Entry ${i + 1}: wordType must be 'word', 'silence' or 'silence-newline'.`\n );\n }\n const word: TranscriptWord = {\n text: w.text,\n startMs: w.startMs,\n endMs: w.endMs,\n ...(typeof w.wordType === 'string'\n ? { wordType: w.wordType as TranscriptWord['wordType'] }\n : {}),\n ...(typeof w.speakerId === 'string' ? { speakerId: w.speakerId } : {}),\n };\n return {\n originalIndex:\n typeof ew.originalIndex === 'number' ? ew.originalIndex : -1,\n deleted: Boolean(ew.deleted),\n ...(ew.inserted !== undefined ? { inserted: Boolean(ew.inserted) } : {}),\n word,\n } as EditableWord;\n });\n}\n\nexport const ScriptPanel: React.FC<ScriptPanelProps> = ({\n transcript,\n editedWords,\n onApply,\n onClose,\n className,\n}) => {\n const [source, setSource] = React.useState<ScriptSource>('editor');\n const [format, setFormat] = React.useState<ScriptFormat>('yaml');\n const [text, setText] = React.useState('');\n const [dirty, setDirty] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const readOnly = source === 'original';\n\n // Live-follow the selected source until the user starts editing.\n React.useEffect(() => {\n if (dirty) return;\n let cancelled = false;\n const data = source === 'original' ? transcript : editedWords;\n (async () => {\n const serialized =\n format === 'json'\n ? JSON.stringify(data, null, 2)\n : (await loadYaml()).dump(data, { lineWidth: 120 });\n if (!cancelled) {\n setText(serialized);\n setError(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [source, format, transcript, editedWords, dirty]);\n\n const handleApply = async () => {\n try {\n const words = await parseScript(text, format);\n onApply(words);\n setDirty(false);\n setError(null);\n } catch (err) {\n setError(\n err instanceof Error ? err.message : 'Could not parse the script.'\n );\n }\n };\n\n const handleReset = () => {\n setDirty(false);\n setError(null);\n };\n\n const sourceButton = (value: ScriptSource, label: string) => (\n <button\n type=\"button\"\n onClick={() => {\n setSource(value);\n setDirty(false);\n setError(null);\n }}\n aria-pressed={source === value}\n className={`focus-visible:ring-ring rounded px-1.5 py-0.5 text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n source === value\n ? 'bg-primary-800 font-medium text-white'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground'\n }`}\n >\n {label}\n </button>\n );\n\n return (\n <aside\n className={`border-border bg-card flex w-80 shrink-0 flex-col border-l lg:w-96 ${className ?? ''}`}\n aria-label=\"Transcript script\"\n >\n <div className=\"border-border flex shrink-0 flex-wrap items-center gap-1.5 border-b px-3 py-2\">\n <span className=\"text-foreground text-xs font-semibold\">Script</span>\n <span className=\"bg-border mx-1 h-4 w-px\" aria-hidden=\"true\" />\n {sourceButton('editor', 'Editor')}\n {sourceButton('original', 'Original')}\n <span className=\"bg-border mx-1 h-4 w-px\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n onClick={() => {\n setFormat(format === 'yaml' ? 'json' : 'yaml');\n setDirty(false);\n setError(null);\n }}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:ring-ring rounded px-1.5 py-0.5 text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n title=\"Toggle YAML / JSON\"\n >\n {format.toUpperCase()}\n </button>\n <span className=\"text-muted-foreground ml-auto text-[10px]\">\n {readOnly ? 'read-only' : dirty ? 'edited' : 'live'}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClose}\n aria-label=\"Close script panel\"\n >\n ✕\n </Button>\n </div>\n\n <textarea\n value={text}\n readOnly={readOnly}\n spellCheck={false}\n onChange={(e) => {\n setText(e.target.value);\n setDirty(true);\n }}\n className=\"text-foreground min-h-0 flex-1 resize-none bg-transparent p-3 font-mono text-xs leading-relaxed focus:outline-none\"\n aria-label={`Script source (${source}, ${format.toUpperCase()})`}\n />\n\n {error && (\n <p\n className=\"border-border text-destructive m-0 shrink-0 border-t px-3 py-2 text-xs\"\n role=\"alert\"\n >\n {error}\n </p>\n )}\n\n {!readOnly && (\n <div className=\"border-border flex shrink-0 items-center gap-2 border-t px-3 py-2\">\n <Button size=\"sm\" onClick={handleApply} disabled={!dirty}>\n Apply\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleReset}\n disabled={!dirty}\n title=\"Throw away unapplied typing and re-sync from the editor\"\n >\n Discard\n </Button>\n <span className=\"text-muted-foreground text-[10px]\">\n Apply pushes into the editor &mdash; revert an applied change with\n Undo\n </span>\n </div>\n )}\n </aside>\n );\n};\n","/**\n * MediaEditor — media playback + editable word-level transcript.\n *\n * Composition of MediaPlayer (imperative MediaPlayerRef) and an editable\n * word-mode transcript, with all edit state held by useTranscriptEdits.\n * Ported from pulseclip's TranscriptViewer; UI-only state (cursor,\n * selection, modals, sequence-playback bookkeeping) lives here.\n *\n * Controlled + persistence-agnostic: edits flow out via\n * onEditorStateChange / onEditedWordsRender and back in via\n * initialEditedWords / initialUndoStack. Timestamps in ms.\n */\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Button } from '../Button';\nimport { Select } from '../Select';\nimport type {\n Transcript,\n TranscriptWord,\n EditableWord,\n PlaybackSegment,\n PlaybackSpeed,\n SpeedMarker,\n} from '../TranscriptView/transcript';\nimport { PLAYBACK_SPEEDS, isSilenceType } from '../TranscriptView/transcript';\nimport { useTranscriptEdits } from '../../hooks/useTranscriptEdits';\nimport {\n MediaPlayer,\n type MediaPlayerRef,\n type MediaKind,\n} from '../MediaPlayer/MediaPlayer';\nimport { FillerWordsModal } from './FillerWordsModal';\nimport { WordEditorModal } from './WordEditorModal';\nimport { SilenceSettingsModal } from './SilenceSettingsModal';\nimport { SpeedMarkerMenu } from './SpeedMarkerMenu';\nimport { ScriptPanel } from './ScriptPanel';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport interface MediaEditorProps extends VariantProps<\n typeof mediaEditorVariants\n> {\n /** Media URL */\n src: string;\n /** Force the media kind; inferred from the src extension when omitted */\n kind?: MediaKind;\n /** The source transcript (canonical, immutable) */\n transcript: Transcript;\n /** Initial edited words (from saved edits) */\n initialEditedWords?: EditableWord[];\n /** Initial undo stack (from saved edits) */\n initialUndoStack?: EditableWord[][];\n /** Initial speed markers (from saved edits) */\n initialSpeedMarkers?: SpeedMarker[];\n /** Initial default playback speed (from saved edits) */\n initialDefaultSpeed?: PlaybackSpeed;\n /**\n * Fired when speed markers or the default speed change (including once on\n * mount with the initial values) — lets the host persist and bake speed\n * into exports alongside the edit list.\n */\n onSpeedStateChange?: (\n speedMarkers: SpeedMarker[],\n defaultSpeed: PlaybackSpeed\n ) => void;\n /** Fired after every edit mutation (for persistence) */\n onEditorStateChange?: (\n editedWords: EditableWord[],\n undoStack: EditableWord[][]\n ) => void;\n /** Fired when the hasEdits flag changes */\n onHasEditsChange?: (hasEdits: boolean) => void;\n /** Fired when the cursor moves (start time of the cursor word in ms, or null) */\n onCursorTimestampChange?: (timestampMs: number | null) => void;\n /** Fired whenever the edited words change — lets the host build raw-data views */\n onEditedWordsRender?: (editedWords: EditableWord[]) => void;\n /**\n * Undo beyond the editor's own history.\n *\n * The editor's undo is word-level, which is the right grain for typing and\n * the wrong one for a host that also versions the document — undoing a batch\n * change one word at a time is not undoing it. When a host provides this, the\n * Undo control stays available once the editor's own stack is empty and hands\n * over instead of going dead, so there is one Undo rather than two.\n */\n onUndoBeyond?: () => void;\n /** Whether the host has anything left to undo. Keeps Undo live at depth 0. */\n canUndoBeyond?: boolean;\n /** What `onUndoBeyond` would undo, for the tooltip (e.g. a version name). */\n undoBeyondLabel?: string;\n /**\n * Redo beyond the editor's own history — the counterpart to `onUndoBeyond`.\n * The editor redoes its own word-level steps first and only calls this once\n * they are exhausted, so the pair walks the same states in both directions.\n */\n onRedo?: () => void;\n canRedo?: boolean;\n /** What `onRedo` would redo, for the tooltip. */\n redoLabel?: string;\n /** Optional ref to the internal MediaPlayer (host escape hatch, e.g. thumbnail capture) */\n playerRef?: React.Ref<MediaPlayerRef>;\n /** Additional class name */\n className?: string;\n /**\n * 'horizontal' (default): media stacked above the transcript.\n * 'vertical': media and transcript side by side.\n */\n splitLayout?: 'horizontal' | 'vertical';\n}\n\ninterface SelectionRange {\n start: number;\n end: number;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst mediaEditorVariants = cva(\n // Root is always a row so the ScriptPanel can dock on the right; the\n // media/transcript split direction lives on the inner wrapper below.\n 'flex h-full min-h-0 w-full overflow-hidden rounded-xl border border-border bg-card text-card-foreground',\n {\n variants: {\n splitLayout: {\n horizontal: '',\n vertical: '',\n },\n },\n defaultVariants: {\n splitLayout: 'horizontal',\n },\n }\n);\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Bring a word into view WITHIN the transcript, never by moving the page.\n *\n * `Element.scrollIntoView` walks up to the nearest scrolling ancestor. Above\n * the md breakpoint that is the transcript's own box and the behaviour is\n * right. Below it the editor grows to its content instead of scrolling\n * internally, so the nearest scrolling ancestor is the DOCUMENT — following\n * the active word dragged the whole page down, taking the player and its\n * controls off screen a word at a time, and any attempt to scroll back was\n * undone by the next word.\n *\n * Scrolling the container directly cannot escape it. The clamped-both-ways\n * arithmetic reproduces `block: 'nearest'`, so behaviour above the breakpoint\n * is unchanged.\n */\nfunction scrollWordIntoTranscript(\n container: HTMLElement | null,\n wordIndex: number\n): void {\n if (!container) return;\n // Not its own scrolling box (the small-screen layout) — nothing to scroll,\n // and anything we did here would move the page instead.\n if (container.scrollHeight <= container.clientHeight) return;\n\n const el = container.querySelector(`[data-word-index=\"${wordIndex}\"]`);\n if (!el) return;\n\n const containerBox = container.getBoundingClientRect();\n const wordBox = el.getBoundingClientRect();\n\n const above = wordBox.top - containerBox.top;\n const below = wordBox.bottom - containerBox.bottom;\n // Already fully visible: `nearest` scrolls nothing.\n const delta = above < 0 ? above : below > 0 ? below : 0;\n if (delta === 0) return;\n\n container.scrollTo({\n top: container.scrollTop + delta,\n behavior: 'smooth',\n });\n}\n\n/** Format duration: seconds only if <90s, min:sec if <60min, h:mm:ss otherwise */\nfunction formatDuration(ms: number): string {\n const totalSeconds = Math.round(ms / 1000);\n if (totalSeconds < 90) {\n return `${totalSeconds}s`;\n }\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;\n }\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\ninterface WordVisualState {\n isActive: boolean;\n isCursor: boolean;\n isSelected: boolean;\n isDeleted: boolean;\n isInserted: boolean;\n isSilence: boolean;\n isSilenceNewline: boolean;\n isAnchor: boolean;\n isFocused: boolean;\n hasSpeedMarker: boolean;\n /** Word plays at a speed differing from the default — the whole region is marked */\n isSped: boolean;\n}\n\n/**\n * Tailwind classes for one transcript word. Background/color states are\n * mutually exclusive (precedence: anchor > active > selected > deleted >\n * inserted > silence) so token utilities never conflict.\n */\nfunction wordClassName(s: WordVisualState): string {\n const parts = [\n 'relative cursor-pointer rounded-sm px-1 py-0.5 transition-colors duration-150',\n ];\n\n if (s.isSilence) {\n parts.push('text-xs font-medium italic tracking-wide');\n }\n if (s.isSilenceNewline) {\n parts.push('mt-1.5 block w-fit');\n }\n\n if (s.isAnchor) {\n parts.push('bg-warning/40 outline outline-2 outline-warning');\n } else if (s.isActive) {\n parts.push('bg-primary-800 font-medium text-white');\n } else if (s.isSelected && s.isFocused) {\n parts.push('bg-primary-500/40');\n } else if (s.isDeleted) {\n parts.push(\n 'bg-destructive/10 text-destructive line-through opacity-40 hover:bg-destructive/20 hover:opacity-70'\n );\n } else if (s.isInserted) {\n parts.push('bg-success/15 text-success hover:bg-success/25');\n } else if (s.isSilenceNewline) {\n parts.push('text-primary-500 hover:bg-primary-500/15');\n } else if (s.isSilence) {\n parts.push(\n 'border border-dashed border-border bg-muted text-muted-foreground hover:bg-muted/70'\n );\n } else {\n parts.push('hover:bg-primary-500/30');\n }\n\n // Keep the strikethrough visible when a deleted word is also active/selected/anchored\n if (\n s.isDeleted &&\n (s.isActive || (s.isSelected && s.isFocused) || s.isAnchor)\n ) {\n parts.push('line-through opacity-60');\n }\n\n // Cursor outline only when the transcript has focus (source behavior)\n if (s.isCursor && s.isFocused && !s.isAnchor) {\n if (s.isDeleted) {\n parts.push('outline outline-2 outline-offset-1 outline-destructive');\n } else if (s.isActive) {\n parts.push('outline outline-2 outline-offset-1 outline-background');\n } else {\n parts.push('outline outline-2 outline-offset-1 outline-primary-500');\n }\n }\n\n if (s.hasSpeedMarker) {\n parts.push('ml-0.5 border-l-[3px] border-l-warning pl-1.5');\n }\n\n // A dotted warning underline spans every word of a re-timed region, so the\n // affected range reads at a glance (the badge only sits on the first word)\n if (s.isSped) {\n parts.push(\n 'underline decoration-warning decoration-dotted decoration-2 underline-offset-4'\n );\n }\n\n return parts.join(' ');\n}\n\n/** Blinking caret rendered inside the cursor word */\nconst Caret: React.FC<{ side: 'before' | 'after' }> = ({ side }) => (\n <span\n aria-hidden=\"true\"\n className={`bg-primary-500 absolute top-0.5 bottom-0.5 w-0.5 motion-safe:animate-pulse ${\n side === 'before' ? '-left-px' : 'right-0.5'\n }`}\n />\n);\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Media editor: MediaPlayer on top, an editable word-mode transcript below,\n * and a toolbar with speed control, filler removal, and edit statistics.\n *\n * Interactions (ported from pulseclip's TranscriptViewer):\n * - Click a word: seek and play just that word\n * - Double-click: set a range anchor; click another word to select the range\n * - Mouse-down + drag: select a range; long-press (500ms) opens the editor\n * - Right-click: speed marker menu\n * - Keyboard: arrows (+Shift to select), Home/End, Backspace/Delete toggle\n * delete, Cmd/Ctrl+X/C/V cut/copy/paste, Cmd/Ctrl+Z undo, Space plays the\n * edited timeline from the cursor, Enter opens the word editor\n */\nexport const MediaEditor = React.forwardRef<HTMLDivElement, MediaEditorProps>(\n (\n {\n src,\n kind,\n transcript,\n initialEditedWords,\n initialUndoStack,\n initialSpeedMarkers,\n initialDefaultSpeed,\n onEditorStateChange,\n onHasEditsChange,\n onCursorTimestampChange,\n onEditedWordsRender,\n onSpeedStateChange,\n onUndoBeyond,\n canUndoBeyond = false,\n undoBeyondLabel,\n onRedo,\n canRedo = false,\n redoLabel,\n playerRef: externalPlayerRef,\n className,\n splitLayout,\n },\n ref\n ) => {\n // -- Edit state (headless hook) --\n const edits = useTranscriptEdits({\n transcript,\n initialEditedWords,\n initialUndoStack,\n initialSpeedMarkers,\n initialDefaultSpeed,\n onChange: onEditorStateChange,\n });\n const {\n editedWords,\n undoStack,\n clipboard,\n hasEdits,\n undo,\n redo,\n canRedo: canRedoWords,\n toggleWordDeleted,\n deleteRange,\n cut,\n copy,\n paste,\n setWordText,\n splitSilence,\n deleteWord,\n replaceEditedWords,\n removeFillers,\n setSilenceThresholds,\n silenceThresholds,\n speedMarkers,\n defaultSpeed,\n setDefaultSpeed,\n toggleSpeedMarker,\n setSpeedForRange,\n removeSpeedMarker,\n getSpeedAtIndex,\n getSpeedMarkerAtIndex,\n playbackSegments,\n stats,\n fillerAnalysis,\n } = edits;\n\n // Undo and Redo are one control pair: they appear and disappear together,\n // and whichever cannot act is disabled rather than removed. A button that\n // vanishes shifts the ones beside it; a lone greyed Redo reads as broken.\n // Each side prefers the editor's own history and falls through to the\n // host's, so the pair walks the same states in both directions.\n // A host that sets the capability flag without the handler would otherwise\n // get an enabled button that does nothing, so both are required.\n const canUndoAnything =\n undoStack.length > 0 || (canUndoBeyond && !!onUndoBeyond);\n const canRedoAnything = canRedoWords || (canRedo && !!onRedo);\n const showUndoRedo = canUndoAnything || canRedoAnything || !!onRedo;\n\n // -- UI state --\n const [activeWordIndex, setActiveWordIndex] = React.useState<number | null>(\n null\n );\n const [cursorIndex, setCursorIndex] = React.useState<number>(0);\n // 'before' = caret before the cursor word; 'after' = after the last word\n const [cursorPosition, setCursorPosition] = React.useState<\n 'before' | 'after'\n >('before');\n const [selectionAnchor, setSelectionAnchor] = React.useState<number | null>(\n null\n );\n const [selection, setSelection] = React.useState<SelectionRange | null>(\n null\n );\n const [doubleClickAnchor, setDoubleClickAnchor] = React.useState<\n number | null\n >(null);\n const [isPlayingSequence, setIsPlayingSequence] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n const [showFillerModal, setShowFillerModal] = React.useState(false);\n const [showSilenceModal, setShowSilenceModal] = React.useState(false);\n const [showScriptPanel, setShowScriptPanel] = React.useState(false);\n const [editorWordIndex, setEditorWordIndex] = React.useState<number | null>(\n null\n );\n const [speedMenuWordIndex, setSpeedMenuWordIndex] = React.useState<\n number | null\n >(null);\n const [speedMenuPosition, setSpeedMenuPosition] = React.useState<{\n x: number;\n y: number;\n } | null>(null);\n\n // -- Refs --\n const playerRef = React.useRef<MediaPlayerRef>(null);\n // Mirror the internal player handle to the host-provided ref via a STABLE\n // delegating proxy: every call forwards to playerRef.current at call time.\n // (Snapshotting playerRef.current with [] deps captured the first-commit\n // handle — ref assignment doesn't re-render, so hosts could hold a stale\n // handle whose mediaElement stayed null forever.)\n React.useImperativeHandle(\n externalPlayerRef,\n (): MediaPlayerRef => ({\n seekToMs: (timeMs) => playerRef.current?.seekToMs(timeMs),\n play: () => playerRef.current?.play(),\n pause: () => playerRef.current?.pause(),\n getCurrentTimeMs: () => playerRef.current?.getCurrentTimeMs() ?? 0,\n getDurationMs: () => playerRef.current?.getDurationMs() ?? 0,\n isPaused: () => playerRef.current?.isPaused() ?? true,\n setPlaybackRate: (rate) => playerRef.current?.setPlaybackRate(rate),\n get mediaElement() {\n return playerRef.current?.mediaElement ?? null;\n },\n }),\n []\n );\n const contentRef = React.useRef<HTMLDivElement>(null);\n const userSetCursor = React.useRef<number | null>(null);\n const isDragging = React.useRef<boolean>(false);\n const longPressTimer = React.useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n const longPressTriggered = React.useRef<boolean>(false);\n // Drag selection: document-level listeners and the auto-scroll frame read\n // these refs because they outlive the render that attached them\n const selectionAnchorRef = React.useRef<number | null>(null);\n const dragPointer = React.useRef<{ x: number; y: number } | null>(null);\n const dragScrollFrame = React.useRef<number | null>(null);\n const dragListeners = React.useRef<{\n move: (e: MouseEvent) => void;\n up: () => void;\n } | null>(null);\n const wordPlaybackStartMs = React.useRef<number | null>(null);\n const wordPlaybackEndMs = React.useRef<number | null>(null);\n // Edited-timeline sequence playback\n const sequenceSegments = React.useRef<PlaybackSegment[]>([]);\n const currentSegmentIndex = React.useRef<number>(0);\n\n // ------------------------------------------------------------------\n // Parent notifications\n // ------------------------------------------------------------------\n\n React.useEffect(() => {\n onHasEditsChange?.(hasEdits);\n }, [hasEdits, onHasEditsChange]);\n\n React.useEffect(() => {\n onEditedWordsRender?.(editedWords);\n }, [editedWords, onEditedWordsRender]);\n\n // Documented to fire only on mount and on real speed-state changes —\n // hosts persist on it — so the callback rides a ref: a new function\n // identity per render must not re-notify unchanged state.\n const onSpeedStateChangeRef = React.useRef(onSpeedStateChange);\n React.useEffect(() => {\n onSpeedStateChangeRef.current = onSpeedStateChange;\n });\n React.useEffect(() => {\n onSpeedStateChangeRef.current?.(speedMarkers, defaultSpeed);\n }, [speedMarkers, defaultSpeed]);\n\n // Report cursor timestamp changes to the parent\n React.useEffect(() => {\n if (onCursorTimestampChange) {\n const word = editedWords[cursorIndex];\n if (word && !word.deleted) {\n onCursorTimestampChange(word.word.startMs);\n } else {\n onCursorTimestampChange(null);\n }\n }\n }, [cursorIndex, editedWords, onCursorTimestampChange]);\n\n // ------------------------------------------------------------------\n // Transcript change / cursor sync / focus\n // ------------------------------------------------------------------\n\n // Reset UI state when the transcript changes (edit state resets in the hook)\n const prevTranscriptRef = React.useRef(transcript);\n React.useEffect(() => {\n if (prevTranscriptRef.current === transcript) return;\n prevTranscriptRef.current = transcript;\n setCursorIndex(0);\n setCursorPosition('before');\n setSelection(null);\n setSelectionAnchor(null);\n setDoubleClickAnchor(null);\n setActiveWordIndex(null);\n setIsPlayingSequence(false);\n sequenceSegments.current = [];\n currentSegmentIndex.current = 0;\n }, [transcript]);\n\n // Sync cursor with the active word while playing (unless a click-seek is pending)\n React.useEffect(() => {\n if (userSetCursor.current !== null) {\n return;\n }\n if (activeWordIndex !== null && activeWordIndex >= 0) {\n setCursorIndex(activeWordIndex);\n setCursorPosition('before');\n setSelection(null);\n setSelectionAnchor(null);\n }\n }, [activeWordIndex]);\n\n // Auto-scroll the active word into view during playback\n React.useEffect(() => {\n if (activeWordIndex === null) return;\n scrollWordIntoTranscript(contentRef.current, activeWordIndex);\n }, [activeWordIndex]);\n\n // Auto-focus the transcript for keyboard navigation.\n //\n // `preventScroll` matters: focusing an element the browser considers\n // off-screen scrolls it into view, and below the md breakpoint the\n // transcript is part of a page-length document rather than its own\n // scrolling box — so this landed the reader partway down the transcript\n // with the player above the fold, on every load.\n React.useEffect(() => {\n contentRef.current?.focus({ preventScroll: true });\n }, [transcript]);\n\n // Apply the default speed when it changes (and no marker overrides it)\n React.useEffect(() => {\n const player = playerRef.current;\n if (!player) return;\n const timeMs = player.getCurrentTimeMs();\n const currentWordIndex = editedWords.findIndex(\n (ew) =>\n !ew.deleted && timeMs >= ew.word.startMs && timeMs < ew.word.endMs\n );\n const targetSpeed =\n currentWordIndex >= 0\n ? getSpeedAtIndex(currentWordIndex)\n : defaultSpeed;\n player.setPlaybackRate(targetSpeed);\n }, [defaultSpeed, speedMarkers, editedWords, getSpeedAtIndex]);\n\n // ------------------------------------------------------------------\n // Playback engine (timeupdate-driven)\n // ------------------------------------------------------------------\n\n const handleTimeUpdate = (timeMs: number) => {\n const player = playerRef.current;\n if (!player) return;\n\n // Segment-based playback of the edited timeline (jumps over deletions\n // and honors reordered/pasted words)\n if (isPlayingSequence && sequenceSegments.current.length > 0) {\n const currentSeg =\n sequenceSegments.current[currentSegmentIndex.current];\n if (currentSeg && timeMs >= currentSeg.endMs) {\n const nextIndex = currentSegmentIndex.current + 1;\n if (nextIndex < sequenceSegments.current.length) {\n currentSegmentIndex.current = nextIndex;\n player.seekToMs(sequenceSegments.current[nextIndex].startMs);\n } else {\n // End of all segments\n player.pause();\n setIsPlayingSequence(false);\n sequenceSegments.current = [];\n currentSegmentIndex.current = 0;\n }\n }\n } else if (hasEdits && !player.isPaused()) {\n // During normal playback with edits, skip over deleted words\n const inDeletedWord = editedWords.some(\n (ew) =>\n ew.deleted && timeMs >= ew.word.startMs && timeMs < ew.word.endMs\n );\n if (inDeletedWord) {\n const nextNonDeleted = editedWords.find(\n (ew) => !ew.deleted && ew.word.startMs >= timeMs\n );\n if (nextNonDeleted) {\n player.seekToMs(nextNonDeleted.word.startMs);\n }\n }\n }\n\n // Stop playback at the end of single-word playback, reseek to its start\n if (\n wordPlaybackEndMs.current !== null &&\n timeMs >= wordPlaybackEndMs.current\n ) {\n player.pause();\n if (wordPlaybackStartMs.current !== null) {\n player.seekToMs(wordPlaybackStartMs.current);\n wordPlaybackStartMs.current = null;\n }\n wordPlaybackEndMs.current = null;\n }\n\n // Find the active word. During segment playback use the current\n // segment's indices (disambiguates duplicate/pasted words that share\n // timing); otherwise fall back to a time-based lookup.\n let editedIndex = -1;\n if (isPlayingSequence && sequenceSegments.current.length > 0) {\n const currentSeg =\n sequenceSegments.current[currentSegmentIndex.current];\n if (currentSeg) {\n for (const idx of currentSeg.editedIndices) {\n const ew = editedWords[idx];\n if (\n ew &&\n !ew.deleted &&\n timeMs >= ew.word.startMs &&\n timeMs < ew.word.endMs\n ) {\n editedIndex = idx;\n break;\n }\n }\n }\n }\n if (editedIndex === -1) {\n editedIndex = editedWords.findIndex(\n (ew) =>\n !ew.deleted && timeMs >= ew.word.startMs && timeMs < ew.word.endMs\n );\n }\n\n // Update playback rate from speed markers when the word changes\n if (editedIndex !== activeWordIndex && editedIndex >= 0) {\n player.setPlaybackRate(getSpeedAtIndex(editedIndex));\n }\n setActiveWordIndex(editedIndex >= 0 ? editedIndex : null);\n\n // Playback has resumed reporting time: release the click-seek cursor lock\n userSetCursor.current = null;\n };\n\n const stopSequencePlayback = () => {\n setIsPlayingSequence(false);\n sequenceSegments.current = [];\n currentSegmentIndex.current = 0;\n };\n\n // ------------------------------------------------------------------\n // Selection / clipboard helpers\n // ------------------------------------------------------------------\n\n /** Indices covered by the selection, or the cursor word */\n const selectionIndices = React.useCallback((): number[] => {\n if (selection) {\n const indices: number[] = [];\n for (let i = selection.start; i <= selection.end; i++) indices.push(i);\n return indices;\n }\n return [cursorIndex];\n }, [selection, cursorIndex]);\n\n const handleCut = React.useCallback(() => {\n cut(selectionIndices());\n }, [cut, selectionIndices]);\n\n const handlePaste = React.useCallback(() => {\n if (!clipboard) return;\n const pastedCount = clipboard.words.length;\n const insertIndex = paste(cursorIndex, cursorPosition !== 'after');\n if (insertIndex !== null) {\n setCursorIndex(insertIndex + pastedCount - 1);\n setCursorPosition('after');\n setSelection(null);\n setSelectionAnchor(null);\n }\n }, [clipboard, paste, cursorIndex, cursorPosition]);\n\n // Toggle deleted state for the selection (anchor decides) or cursor word\n const handleDeleteToggle = React.useCallback(() => {\n if (selection) {\n const anchorIndex = selectionAnchor ?? selection.start;\n const indices: number[] = [anchorIndex];\n for (let i = selection.start; i <= selection.end; i++) {\n if (i !== anchorIndex) indices.push(i);\n }\n deleteRange(indices);\n } else {\n toggleWordDeleted(cursorIndex);\n }\n }, [\n selection,\n selectionAnchor,\n cursorIndex,\n deleteRange,\n toggleWordDeleted,\n ]);\n\n // Copy: put plain text on the system clipboard + fill the internal clipboard\n const handleCopy = React.useCallback(\n (e: React.ClipboardEvent) => {\n const indices = selectionIndices();\n const selectedWords = indices\n .map((i) => editedWords[i])\n .filter((ew): ew is EditableWord => ew !== undefined && !ew.deleted);\n if (selectedWords.length === 0) return;\n const selectedText = selectedWords\n .filter((ew) => !isSilenceType(ew.word.wordType))\n .map((ew) => ew.word.text)\n .join(' ');\n e.preventDefault();\n e.clipboardData.setData('text/plain', selectedText);\n copy(indices);\n },\n [selectionIndices, editedWords, copy]\n );\n\n // ------------------------------------------------------------------\n // Word editor modal\n // ------------------------------------------------------------------\n\n const openWordEditor = React.useCallback((index: number) => {\n setEditorWordIndex(index);\n }, []);\n\n const closeWordEditor = React.useCallback(() => {\n setEditorWordIndex(null);\n // Restore focus to the transcript after the modal closes\n setTimeout(() => contentRef.current?.focus(), 0);\n }, []);\n\n const handleEditorSave = React.useCallback(\n (newText: string) => {\n if (editorWordIndex === null) return;\n setWordText(editorWordIndex, newText);\n },\n [editorWordIndex, setWordText]\n );\n\n const handleEditorSplitSilence = React.useCallback(\n (durations: number[]) => {\n if (editorWordIndex === null) return;\n splitSilence(editorWordIndex, durations);\n },\n [editorWordIndex, splitSilence]\n );\n\n const handleEditorDelete = React.useCallback(() => {\n if (editorWordIndex !== null) {\n deleteWord(editorWordIndex);\n closeWordEditor();\n }\n }, [editorWordIndex, deleteWord, closeWordEditor]);\n\n // ------------------------------------------------------------------\n // Mouse interactions\n // ------------------------------------------------------------------\n\n const handleWordClick = (\n word: TranscriptWord,\n index: number,\n e: React.MouseEvent\n ) => {\n setCursorIndex(index);\n setCursorPosition('before');\n userSetCursor.current = index;\n\n if (e.shiftKey && selectionAnchor !== null) {\n // Extend selection with shift+click\n setSelection({\n start: Math.min(selectionAnchor, index),\n end: Math.max(selectionAnchor, index),\n });\n } else if (\n doubleClickAnchor !== null &&\n doubleClickAnchor !== index &&\n !isDragging.current\n ) {\n // A double-click anchor exists and a different word was clicked: select the range\n const start = Math.min(doubleClickAnchor, index);\n const end = Math.max(doubleClickAnchor, index);\n setSelection({ start, end });\n setSelectionAnchor(doubleClickAnchor);\n setDoubleClickAnchor(null);\n } else if (doubleClickAnchor === index) {\n // Clicking the anchor itself — wait for a potential double-click\n } else if (!isDragging.current) {\n // Clear selection, set a new anchor, and play just this word\n setSelectionAnchor(index);\n setSelection(null);\n\n const player = playerRef.current;\n if (player) {\n player.pause();\n player.seekToMs(word.startMs);\n wordPlaybackStartMs.current = word.startMs;\n wordPlaybackEndMs.current = word.endMs;\n player.play();\n }\n }\n };\n\n const handleWordDoubleClick = (index: number, e: React.MouseEvent) => {\n e.preventDefault();\n // Don't trigger if a long press already fired\n if (longPressTriggered.current) return;\n\n if (doubleClickAnchor === index) {\n setDoubleClickAnchor(null);\n } else {\n setDoubleClickAnchor(index);\n setSelection(null);\n }\n };\n\n const AUTOSCROLL_EDGE_PX = 24;\n const AUTOSCROLL_MAX_STEP_PX = 24;\n\n const extendDragSelection = (index: number) => {\n const anchor = selectionAnchorRef.current;\n if (!isDragging.current || anchor === null) return;\n setSelection({\n start: Math.min(anchor, index),\n end: Math.max(anchor, index),\n });\n setCursorIndex(index);\n };\n\n /** Word index under a viewport point, or null when the point misses every span */\n const wordIndexAtPoint = (x: number, y: number): number | null => {\n const span = document\n .elementFromPoint?.(x, y)\n ?.closest?.('[data-word-index]');\n if (!span) return null;\n const parsed = Number((span as HTMLElement).dataset.wordIndex);\n return Number.isInteger(parsed) ? parsed : null;\n };\n\n /**\n * Extends the selection to the word nearest the held pointer, clamping a\n * pointer that has left the pane back inside it. Extra probe points cover\n * padding and end-of-line whitespace, where the pointer misses every span\n * and per-word mouseenter would never fire.\n */\n const extendSelectionToPointer = () => {\n const container = contentRef.current;\n const pointer = dragPointer.current;\n if (!container || !pointer) return;\n\n // Clamp into the VISIBLE part of the pane: elementFromPoint only\n // resolves inside the viewport, and the pane can extend beyond it\n const rect = container.getBoundingClientRect();\n const top = Math.max(rect.top, 0);\n const bottom = Math.min(rect.bottom, window.innerHeight);\n const left = Math.max(rect.left, 0);\n const right = Math.min(rect.right, window.innerWidth);\n if (bottom <= top || right <= left) return;\n const y = Math.min(Math.max(pointer.y, top + 2), bottom - 2);\n const x = Math.min(Math.max(pointer.x, left + 2), right - 2);\n for (const rawX of [x, left + (right - left) / 2, left + 16]) {\n const probeX = Math.min(Math.max(rawX, left + 2), right - 2);\n const index = wordIndexAtPoint(probeX, y);\n if (index !== null) {\n extendDragSelection(index);\n return;\n }\n }\n\n // Every probe missed: the point sits in empty pane space (below the\n // last line of a short or fully scrolled transcript, or above the\n // first). Standard editor behavior: extend to the nearest end.\n const spans =\n container.querySelectorAll<HTMLElement>('[data-word-index]');\n if (spans.length === 0) return;\n // Above every span (top padding): extend to the first word without\n // scanning — the backward walk below would touch every span. Below\n // the last line is already O(1): the walk's first probe matches.\n if (spans[0].getBoundingClientRect().top > y) {\n const parsed = Number(spans[0].dataset.wordIndex);\n if (Number.isInteger(parsed)) extendDragSelection(parsed);\n return;\n }\n for (let i = spans.length - 1; i >= 0; i--) {\n const spanRect = spans[i].getBoundingClientRect();\n if (spanRect.top <= y) {\n const parsed = Number(spans[i].dataset.wordIndex);\n if (Number.isInteger(parsed)) extendDragSelection(parsed);\n return;\n }\n }\n };\n\n /** Scrolls the pane while the held pointer sits at or beyond its edge */\n const stepDragAutoScroll = () => {\n dragScrollFrame.current = null;\n const container = contentRef.current;\n const pointer = dragPointer.current;\n if (!isDragging.current || !container || !pointer) return;\n\n // Edge zones measured on the VISIBLE part of the pane, since its own\n // bounds can extend past the viewport\n const rect = container.getBoundingClientRect();\n const top = Math.max(rect.top, 0);\n const bottom = Math.min(rect.bottom, window.innerHeight);\n // Pane fully offscreen: keep the loop alive but never scroll it\n if (bottom <= top) {\n dragScrollFrame.current = requestAnimationFrame(stepDragAutoScroll);\n return;\n }\n let step = 0;\n if (pointer.y < top + AUTOSCROLL_EDGE_PX) {\n step = Math.max(\n (pointer.y - (top + AUTOSCROLL_EDGE_PX)) / 3,\n -AUTOSCROLL_MAX_STEP_PX\n );\n } else if (pointer.y > bottom - AUTOSCROLL_EDGE_PX) {\n step = Math.min(\n (pointer.y - (bottom - AUTOSCROLL_EDGE_PX)) / 3,\n AUTOSCROLL_MAX_STEP_PX\n );\n }\n if (step !== 0) {\n // Re-extend only when the pane actually moved: held at a clamped\n // top/bottom nothing shifts under the pointer, and mousemove already\n // covers pointer motion\n const before = container.scrollTop;\n container.scrollTop += step;\n if (container.scrollTop !== before) {\n extendSelectionToPointer();\n }\n }\n dragScrollFrame.current = requestAnimationFrame(stepDragAutoScroll);\n };\n\n const detachDragListeners = () => {\n if (dragListeners.current) {\n document.removeEventListener('mousemove', dragListeners.current.move);\n document.removeEventListener('mouseup', dragListeners.current.up);\n dragListeners.current = null;\n }\n if (dragScrollFrame.current !== null) {\n cancelAnimationFrame(dragScrollFrame.current);\n dragScrollFrame.current = null;\n }\n };\n\n const handleMouseUp = () => {\n if (longPressTimer.current) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n if (isDragging.current) {\n isDragging.current = false;\n }\n detachDragListeners();\n };\n\n /**\n * Document-level tracking for the lifetime of one drag, so the selection\n * keeps following after the pointer leaves the pane and the pane scrolls\n * itself when held at an edge. The exact handler pair is kept in a ref so\n * detaching survives re-renders.\n */\n const beginDragTracking = () => {\n detachDragListeners();\n\n const up = () => handleMouseUp();\n const move = (e: MouseEvent) => {\n if (!isDragging.current) return;\n // Button released outside the window: no mouseup will arrive\n if (e.buttons === 0) {\n up();\n return;\n }\n dragPointer.current = { x: e.clientX, y: e.clientY };\n\n // Leaving the pane cancels the pending long press (it used to cancel\n // the whole drag), but the selection keeps tracking the pointer\n const container = contentRef.current;\n if (container && longPressTimer.current) {\n const rect = container.getBoundingClientRect();\n const outside =\n e.clientX < rect.left ||\n e.clientX > rect.right ||\n e.clientY < rect.top ||\n e.clientY > rect.bottom;\n if (outside) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n }\n extendSelectionToPointer();\n };\n\n dragListeners.current = { move, up };\n document.addEventListener('mousemove', move);\n document.addEventListener('mouseup', up);\n dragScrollFrame.current = requestAnimationFrame(stepDragAutoScroll);\n };\n\n // Never leave document listeners, the scroll frame, or a pending\n // long-press timer behind on unmount\n React.useEffect(\n () => () => {\n if (dragListeners.current) {\n document.removeEventListener('mousemove', dragListeners.current.move);\n document.removeEventListener('mouseup', dragListeners.current.up);\n dragListeners.current = null;\n }\n if (dragScrollFrame.current !== null) {\n cancelAnimationFrame(dragScrollFrame.current);\n dragScrollFrame.current = null;\n }\n if (longPressTimer.current) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n },\n []\n );\n\n const handleWordMouseDown = (index: number, e: React.MouseEvent) => {\n if (e.button !== 0) return;\n\n // Long press (500ms) opens the word editor\n longPressTriggered.current = false;\n longPressTimer.current = setTimeout(() => {\n longPressTriggered.current = true;\n openWordEditor(index);\n }, 500);\n\n isDragging.current = true;\n selectionAnchorRef.current = index;\n dragPointer.current = { x: e.clientX, y: e.clientY };\n setSelectionAnchor(index);\n setCursorIndex(index);\n setCursorPosition('before');\n setSelection(null);\n beginDragTracking();\n };\n\n const handleWordMouseEnter = (index: number) => {\n // Cancel the long press when dragging to another word\n if (longPressTimer.current) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n\n extendDragSelection(index);\n };\n\n const handleWordContextMenu = (index: number, e: React.MouseEvent) => {\n e.preventDefault();\n // Position the speed menu near the word, clamped to the viewport\n const rect = e.currentTarget.getBoundingClientRect();\n const menuHeight = 280;\n const menuWidth = 150;\n\n let x = rect.left;\n let y = rect.bottom + 4;\n\n if (x + menuWidth > window.innerWidth) {\n x = window.innerWidth - menuWidth - 8;\n }\n if (y + menuHeight > window.innerHeight) {\n y = rect.top - menuHeight - 4;\n if (y < 0) {\n y = 8;\n }\n }\n\n setSpeedMenuPosition({ x, y });\n setSpeedMenuWordIndex(index);\n };\n\n // ------------------------------------------------------------------\n // Keyboard\n // ------------------------------------------------------------------\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n const wordCount = editedWords.length;\n if (wordCount === 0) return;\n\n let newIndex = cursorIndex;\n let handled = false;\n\n if (e.key === 'Delete' || e.key === 'Backspace') {\n handleDeleteToggle();\n handled = true;\n } else if ((e.metaKey || e.ctrlKey) && e.key === 'x') {\n handleCut();\n handled = true;\n } else if ((e.metaKey || e.ctrlKey) && e.key === 'v' && clipboard) {\n handlePaste();\n handled = true;\n } else if ((e.metaKey || e.ctrlKey) && e.key === 'z' && !e.shiftKey) {\n undo();\n handled = true;\n } else if (\n (e.metaKey || e.ctrlKey) &&\n ((e.key === 'z' && e.shiftKey) || e.key === 'y')\n ) {\n // Redo. ⌘Y is accepted for anyone arriving from Windows but is never\n // advertised — on macOS it is Chrome's own History shortcut and the\n // browser wins. The button shows ⇧⌘Z, which is what this handles.\n // Word-level first, then the host's, mirroring Undo.\n if (canRedoWords) redo();\n else if (canRedo && onRedo) onRedo();\n handled = true;\n } else if (e.key === 'ArrowLeft') {\n if (cursorPosition === 'after') {\n // Move from 'after' the last word back to 'before' it\n setCursorPosition('before');\n } else {\n newIndex = Math.max(0, cursorIndex - 1);\n }\n handled = true;\n } else if (e.key === 'ArrowRight') {\n if (cursorIndex === wordCount - 1 && cursorPosition === 'before') {\n // At the last word: move the caret after it\n setCursorPosition('after');\n } else if (cursorPosition !== 'after') {\n newIndex = Math.min(wordCount - 1, cursorIndex + 1);\n }\n handled = true;\n } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n // Find the visually nearest word on the previous/next row\n const currentElement = contentRef.current?.querySelector(\n `[data-word-index=\"${cursorIndex}\"]`\n ) as HTMLElement | null;\n if (currentElement) {\n const currentRect = currentElement.getBoundingClientRect();\n const currentCenterX = currentRect.left + currentRect.width / 2;\n\n const direction = e.key === 'ArrowUp' ? -1 : 1;\n let bestMatch = cursorIndex;\n let bestDistance = Infinity;\n let targetRowTop: number | null = null;\n\n for (\n let i = cursorIndex + direction;\n i >= 0 && i < wordCount;\n i += direction\n ) {\n const el = contentRef.current?.querySelector(\n `[data-word-index=\"${i}\"]`\n ) as HTMLElement | null;\n if (!el) continue;\n\n const rect = el.getBoundingClientRect();\n const isOnDifferentRow =\n direction === -1\n ? rect.bottom <= currentRect.top\n : rect.top >= currentRect.bottom;\n\n if (isOnDifferentRow) {\n // The first word on a different row establishes the target row\n if (targetRowTop === null) {\n targetRowTop = rect.top;\n }\n const isSameTargetRow = Math.abs(rect.top - targetRowTop) < 5;\n if (isSameTargetRow) {\n const centerX = rect.left + rect.width / 2;\n const distance = Math.abs(centerX - currentCenterX);\n if (distance < bestDistance) {\n bestDistance = distance;\n bestMatch = i;\n }\n } else {\n // Moved past the target row; stop searching\n break;\n }\n }\n }\n newIndex = bestMatch;\n }\n handled = true;\n } else if (e.key === 'Home') {\n newIndex = 0;\n handled = true;\n } else if (e.key === 'End') {\n newIndex = wordCount - 1;\n handled = true;\n } else if (e.key === 'Enter') {\n openWordEditor(cursorIndex);\n handled = true;\n } else if (e.key === ' ') {\n // Toggle play/pause from the cursor position\n const ew = editedWords[cursorIndex];\n const player = playerRef.current;\n if (player && ew && !ew.deleted) {\n if (player.isPaused()) {\n if (hasEdits) {\n // Play the edited timeline as a segment sequence\n const segments = playbackSegments;\n if (segments.length > 0) {\n let startSegmentIdx = 0;\n for (let i = 0; i < segments.length; i++) {\n if (segments[i].editedIndices.includes(cursorIndex)) {\n startSegmentIdx = i;\n break;\n }\n }\n sequenceSegments.current = segments;\n currentSegmentIndex.current = startSegmentIdx;\n setIsPlayingSequence(true);\n // Start from the cursor word's time, not the segment's start\n player.seekToMs(ew.word.startMs);\n player.play();\n }\n } else {\n // Normal playback from the cursor\n player.seekToMs(ew.word.startMs);\n player.play();\n }\n } else {\n player.pause();\n setIsPlayingSequence(false);\n }\n }\n handled = true;\n }\n\n if (handled) {\n e.preventDefault();\n e.stopPropagation();\n if (newIndex !== cursorIndex) {\n setCursorIndex(newIndex);\n setCursorPosition('before');\n }\n\n if (e.shiftKey && e.key !== 'Delete' && e.key !== 'Backspace') {\n // Extend the selection (not for delete operations)\n const anchor = selectionAnchor ?? cursorIndex;\n if (selectionAnchor === null) {\n setSelectionAnchor(cursorIndex);\n }\n setSelection({\n start: Math.min(anchor, newIndex),\n end: Math.max(anchor, newIndex),\n });\n } else if (!e.metaKey && !e.ctrlKey) {\n // Clear the selection when moving without shift (not for cut/paste)\n setSelection(null);\n setSelectionAnchor(null);\n }\n\n // Scroll the cursor into view\n scrollWordIntoTranscript(contentRef.current, newIndex);\n }\n },\n [\n editedWords,\n cursorIndex,\n cursorPosition,\n selectionAnchor,\n clipboard,\n hasEdits,\n playbackSegments,\n handleDeleteToggle,\n handleCut,\n handlePaste,\n undo,\n redo,\n canRedoWords,\n canRedo,\n onRedo,\n openWordEditor,\n ]\n );\n\n // ------------------------------------------------------------------\n // Rendering\n // ------------------------------------------------------------------\n\n const isWordSelected = (index: number): boolean => {\n if (!selection) return false;\n return index >= selection.start && index <= selection.end;\n };\n\n const renderWord = (ew: EditableWord, index: number) => {\n const isActive = index === activeWordIndex;\n const isCursor = index === cursorIndex;\n const isSelected = isWordSelected(index);\n const isDeleted = ew.deleted;\n const isInserted = ew.inserted ?? false;\n const isSilence =\n ew.word.wordType === 'silence' ||\n ew.word.wordType === 'silence-newline';\n const isSilenceNewline = ew.word.wordType === 'silence-newline';\n const isAnchor = index === doubleClickAnchor;\n const showCursorBefore = isCursor && cursorPosition === 'before';\n const showCursorAfter =\n isCursor &&\n cursorPosition === 'after' &&\n index === editedWords.length - 1;\n const speedMarker = getSpeedMarkerAtIndex(index);\n const hasSpeedMarker = !!speedMarker;\n\n // For silences, show the duration adjusted for the effective speed\n const effectiveSpeed = getSpeedAtIndex(index);\n let displayText = ew.word.text;\n if (isSilence && effectiveSpeed !== 1) {\n const originalDurationMs = ew.word.endMs - ew.word.startMs;\n const adjustedDurationSec = originalDurationMs / effectiveSpeed / 1000;\n displayText = `[${adjustedDurationSec.toFixed(1)}s]`;\n }\n\n const title = `${ew.word.startMs}ms - ${ew.word.endMs}ms${\n ew.word.confidence ? ` (${Math.round(ew.word.confidence * 100)}%)` : ''\n }${\n isSilence\n ? ` [SILENCE: ${((ew.word.endMs - ew.word.startMs) / 1000).toFixed(1)}s${\n effectiveSpeed !== 1\n ? ` → ${((ew.word.endMs - ew.word.startMs) / effectiveSpeed / 1000).toFixed(1)}s @ ${effectiveSpeed}x`\n : ''\n }]`\n : ''\n }${isDeleted ? ' [DELETED]' : ''}${isInserted ? ' [INSERTED]' : ''}${\n hasSpeedMarker ? ` [SPEED: ${speedMarker.speed}x]` : ''\n }${\n isAnchor\n ? ' [ANCHOR - click another word to select range, double-click to clear]'\n : ''\n }${!isAnchor && !isDeleted ? ' (right-click to set speed marker)' : ''}`;\n\n return (\n // Keyboard interaction is owned by the parent listbox via roving focus\n // (aria-activedescendant); options are pointer affordances only.\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus\n <span\n key={`${ew.originalIndex}-${index}`}\n id={`word-${index}`}\n data-word-index={index}\n className={wordClassName({\n isActive,\n isCursor,\n isSelected,\n isDeleted,\n isInserted,\n isSilence,\n isSilenceNewline,\n isAnchor,\n isFocused,\n hasSpeedMarker,\n isSped: effectiveSpeed !== defaultSpeed,\n })}\n onClick={(e) => handleWordClick(ew.word, index, e)}\n onDoubleClick={(e) => handleWordDoubleClick(index, e)}\n onMouseDown={(e) => handleWordMouseDown(index, e)}\n onMouseEnter={() => handleWordMouseEnter(index)}\n onContextMenu={(e) => handleWordContextMenu(index, e)}\n role=\"option\"\n aria-selected={isSelected || isCursor}\n title={title}\n >\n {showCursorBefore && isFocused && <Caret side=\"before\" />}\n {hasSpeedMarker && (\n <span\n className=\"border-warning/50 bg-warning/20 text-warning-foreground mr-1 inline-block rounded-sm border px-0.5 align-middle text-[9px] leading-snug font-semibold\"\n title={`Speed: ${speedMarker.speed}x from here`}\n >\n {speedMarker.speed}x\n </span>\n )}\n {displayText} {showCursorAfter && isFocused && <Caret side=\"after\" />}\n </span>\n );\n };\n\n const showEditBar =\n hasEdits || doubleClickAnchor !== null || selection !== null;\n\n return (\n <div\n ref={ref}\n className={mediaEditorVariants({ splitLayout, className })}\n >\n <div\n className={`flex min-h-0 min-w-0 flex-1 ${\n splitLayout === 'vertical' ? 'flex-col md:flex-row' : 'flex-col'\n }`}\n >\n {/* Media surface */}\n {/*\n The cap is written twice on purpose. `max-h-[50%]` is a percentage\n of the parent's height, which only resolves while the editor is a\n fixed-height shell — on a small screen the parent grows to its\n content, the percentage resolves against an indeterminate height,\n and the rule silently becomes no cap at all. A portrait phone\n recording then took the full viewport on its own and pushed its own\n controls off the bottom of the screen. The `dvh` cap always\n resolves; the md variant keeps existing desktop behaviour byte for\n byte.\n\n `dvh` rather than `vh`, matching Modal and Sheet: on iOS Safari\n `vh` measures the viewport as if the browser chrome were hidden, so\n while the address bar is on screen `55vh` is taller than 55% of\n what you can actually see — which would put the player's own\n controls back under the fold, the exact failure this cap exists to\n prevent.\n */}\n <div\n className={`border-border bg-background flex min-h-0 shrink-0 ${\n splitLayout === 'vertical'\n ? 'max-h-[55dvh] md:max-h-none md:w-1/2 md:border-r'\n : 'max-h-[55dvh] border-b md:max-h-[50%]'\n }`}\n >\n <MediaPlayer\n ref={playerRef}\n src={src}\n kind={kind}\n aria-label=\"Media player\"\n onTimeUpdate={handleTimeUpdate}\n onEnded={stopSequencePlayback}\n />\n </div>\n\n {/* Transcript editor */}\n <div\n className={`flex min-h-0 flex-1 flex-col ${splitLayout === 'vertical' ? 'md:w-1/2' : ''}`}\n >\n {/* Toolbar */}\n <div className=\"border-border flex shrink-0 flex-wrap items-center justify-between gap-2 border-b px-3 py-2\">\n <div className=\"flex items-center gap-2\">\n {hasEdits && (\n <span className=\"bg-warning/20 text-warning-foreground rounded px-1.5 py-0.5 text-xs font-semibold\">\n Edited\n </span>\n )}\n <label\n className=\"text-muted-foreground text-xs\"\n htmlFor=\"media-editor-default-speed\"\n >\n Speed:\n </label>\n <div className=\"w-20\">\n <Select\n id=\"media-editor-default-speed\"\n size=\"sm\"\n options={PLAYBACK_SPEEDS.map((speed) => ({\n value: String(speed),\n label: `${speed}x`,\n }))}\n value={String(defaultSpeed)}\n onValueChange={(value) =>\n setDefaultSpeed(parseFloat(value) as PlaybackSpeed)\n }\n aria-label=\"Default playback speed\"\n />\n </div>\n {speedMarkers.length > 0 && (\n <span\n className=\"text-muted-foreground text-xs\"\n title={`${speedMarkers.length} speed marker(s) set. Right-click on a word to add/remove speed markers.`}\n >\n {speedMarkers.length} marker\n {speedMarkers.length !== 1 ? 's' : ''}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowFillerModal(true)}\n aria-label=\"Remove filler words\"\n title=\"Remove filler words\"\n >\n ✂️\n </Button>\n {/* Undo and Redo appear and disappear together. A lone greyed\n Redo reads as broken, and an Undo that vanishes at the end\n of history while Redo merely greys is two rules for one\n pair — so whichever is inert is disabled, not removed. */}\n {showUndoRedo && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={!canUndoAnything}\n // Word-level first; the host only gets it once the\n // editor's own history is spent.\n onClick={undoStack.length > 0 ? undo : onUndoBeyond}\n aria-label={\n undoStack.length > 0\n ? `Undo (${undoStack.length} available)`\n : canUndoBeyond && undoBeyondLabel\n ? `Undo: ${undoBeyondLabel}`\n : 'Undo'\n }\n title={\n undoStack.length > 0\n ? `Undo (⌘Z) — ${undoStack.length} step${undoStack.length === 1 ? '' : 's'}`\n : canUndoBeyond\n ? undoBeyondLabel\n ? `Undo (⌘Z) — back to \"${undoBeyondLabel}\"`\n : 'Undo (⌘Z)'\n : 'Nothing to undo'\n }\n >\n Undo{undoStack.length > 0 ? ` (${undoStack.length})` : ''}{' '}\n <kbd className=\"text-[10px] opacity-60\">⌘Z</kbd>\n </Button>\n )}\n {showUndoRedo && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n // Word-level first, mirroring Undo, so the pair steps back\n // and forward through the same states in the same order.\n onClick={canRedoWords ? redo : onRedo}\n disabled={!canRedoAnything}\n aria-label={\n !canRedoWords && canRedo && redoLabel\n ? `Redo: ${redoLabel}`\n : 'Redo'\n }\n title={\n canRedoWords\n ? 'Redo (⇧⌘Z)'\n : canRedo && redoLabel\n ? `Redo (⇧⌘Z) — forward to \"${redoLabel}\"`\n : canRedo\n ? 'Redo (⇧⌘Z)'\n : 'Nothing to redo'\n }\n >\n Redo <kbd className=\"text-[10px] opacity-60\">⇧⌘Z</kbd>\n </Button>\n )}\n </div>\n\n <div className=\"text-muted-foreground flex items-center gap-2 text-xs\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowScriptPanel((v) => !v)}\n aria-pressed={showScriptPanel}\n aria-label=\"Show script\"\n title=\"Show the transcript script (editable YAML/JSON)\"\n >\n Script\n </Button>\n <span>{stats.activeWordCount} words</span>\n <button\n type=\"button\"\n className=\"hover:bg-muted hover:text-foreground focus-visible:ring-ring rounded px-1 underline decoration-dotted transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => setShowSilenceModal(true)}\n title={\n stats.activeSilenceCount > 0\n ? `Click to configure silence detection (currently ≥${(silenceThresholds.minSilenceMs / 1000).toFixed(1)}s)`\n : `No silences detected (threshold: ${(silenceThresholds.minSilenceMs / 1000).toFixed(1)}s). Click to configure.`\n }\n aria-label=\"Configure silence detection\"\n >\n {stats.activeSilenceCount} silences\n </button>\n {(stats.deletedWordCount > 0 ||\n stats.deletedSilenceCount > 0) && (\n <span className=\"text-destructive\">\n {stats.deletedWordCount + stats.deletedSilenceCount} deleted\n </span>\n )}\n {transcript.speakers && (\n <span>{transcript.speakers.length} speakers</span>\n )}\n <span>{formatDuration(stats.editedDurationMs)}</span>\n </div>\n </div>\n\n {/* Contextual edit actions */}\n {showEditBar && (\n <div className=\"border-border bg-muted/40 flex shrink-0 items-center gap-1 border-b px-3 py-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => openWordEditor(cursorIndex)}\n title=\"Edit selected word (Enter)\"\n >\n Edit <kbd className=\"text-[10px] opacity-60\">↵</kbd>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleDeleteToggle}\n title=\"Delete selected word (Del)\"\n >\n Del <kbd className=\"text-[10px] opacity-60\">⌫</kbd>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleCut}\n title=\"Cut selection (⌘X)\"\n >\n Cut <kbd className=\"text-[10px] opacity-60\">⌘X</kbd>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handlePaste}\n disabled={!clipboard}\n title=\"Paste (⌘V)\"\n >\n Paste <kbd className=\"text-[10px] opacity-60\">⌘V</kbd>\n </Button>\n </div>\n )}\n\n {/* Editable transcript */}\n <div\n ref={contentRef}\n className={`focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto p-3 text-sm leading-relaxed select-none focus:outline-none focus-visible:ring-2 focus-visible:ring-inset ${\n isFocused ? 'bg-muted/20' : ''\n }`}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onCopy={handleCopy}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onMouseUp={handleMouseUp}\n role=\"listbox\"\n aria-label=\"Transcript words\"\n aria-activedescendant={`word-${cursorIndex}`}\n >\n {editedWords.map(renderWord)}\n </div>\n </div>\n </div>\n\n {showScriptPanel && (\n <ScriptPanel\n transcript={transcript}\n editedWords={editedWords}\n onApply={replaceEditedWords}\n onClose={() => setShowScriptPanel(false)}\n />\n )}\n\n {/* Modals & menus */}\n <FillerWordsModal\n isOpen={showFillerModal}\n onClose={() => setShowFillerModal(false)}\n onApply={removeFillers}\n matchingCounts={fillerAnalysis.matchCounts}\n fillerDurations={fillerAnalysis.durations}\n silenceCounts={fillerAnalysis.silenceCounts}\n currentDurationMs={stats.editedDurationMs}\n />\n\n <SilenceSettingsModal\n isOpen={showSilenceModal}\n onClose={() => setShowSilenceModal(false)}\n minSilenceMs={silenceThresholds.minSilenceMs}\n nlSilenceMs={silenceThresholds.nlSilenceMs}\n onApply={setSilenceThresholds}\n />\n\n <WordEditorModal\n isOpen={editorWordIndex !== null}\n editableWord={\n editorWordIndex !== null\n ? (editedWords[editorWordIndex] ?? null)\n : null\n }\n onClose={closeWordEditor}\n onSave={handleEditorSave}\n onSplitSilence={handleEditorSplitSilence}\n onDelete={handleEditorDelete}\n />\n\n <SpeedMarkerMenu\n isOpen={speedMenuWordIndex !== null}\n position={speedMenuPosition}\n wordIndex={speedMenuWordIndex}\n currentMarker={\n speedMenuWordIndex !== null\n ? getSpeedMarkerAtIndex(speedMenuWordIndex)\n : undefined\n }\n defaultSpeed={defaultSpeed}\n onSetSpeed={(speed) => {\n if (speedMenuWordIndex === null) return;\n // With an active selection the speed applies to the whole range\n // (and only the range); otherwise the classic from-here-on marker\n if (selection) {\n setSpeedForRange(selection.start, selection.end, speed);\n } else {\n toggleSpeedMarker(speedMenuWordIndex, speed);\n }\n }}\n onRemoveMarker={() => {\n if (speedMenuWordIndex !== null) {\n removeSpeedMarker(speedMenuWordIndex);\n }\n }}\n onClose={() => {\n setSpeedMenuWordIndex(null);\n setSpeedMenuPosition(null);\n }}\n />\n </div>\n );\n }\n);\n\nMediaEditor.displayName = 'MediaEditor';\n"]}
1
+ {"version":3,"sources":["../src/components/MediaEditor/FillerWordsModal.tsx","../src/components/MediaEditor/WordEditorModal.tsx","../src/components/MediaEditor/SilenceSettingsModal.tsx","../src/components/MediaEditor/SpeedMarkerMenu.tsx","../src/components/MediaEditor/ScriptPanel.tsx","../src/components/MediaEditor/MediaEditor.tsx"],"names":["React","React2","jsxs","jsx","React3","React4","React5","formatDuration"],"mappings":";;;;;;;;;;;;;AA0CA,IAAM,yBAAA,GAA4B,CAAC,GAAA,EAAK,GAAA,EAAK,KAAK,IAAA,EAAM,CAAA,EAAK,KAAK,CAAG,CAAA;AAGrE,SAAS,eAAe,EAAA,EAAoB;AAC1C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAI,CAAA;AACzC,EAAA,IAAI,eAAe,EAAA,EAAI;AACrB,IAAA,OAAO,GAAG,YAAY,CAAA,CAAA,CAAA;AAAA,EACxB;AACA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,EAAE,CAAA;AAC5C,EAAA,MAAM,UAAU,YAAA,GAAe,EAAA;AAC/B,EAAA,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AACvD;AAGO,IAAM,mBAAoD,CAAC;AAAA,EAChE,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAUA,gBAAS,EAAE,CAAA;AACrD,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAUA,MAAA,CAAA,QAAA;AAAA,IAClD,IAAI,IAAI,oBAAoB;AAAA,GAC9B;AACA,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAUA,gBAAS,EAAE,CAAA;AACrD,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAUA,gBAAS,KAAK,CAAA;AAC9D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAUA,gBAAS,GAAG,CAAA;AAGlE,EAAA,MAAM,kBAAkB,oBAAA,CAAqB,MAAA;AAAA,IAAO,CAAC,SACnD,IAAA,CAAK,WAAA,GAAc,QAAA,CAAS,UAAA,CAAW,aAAa;AAAA,GACtD,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACf,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA;AACxC,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA;AACxC,IAAA,IAAI,MAAA,KAAW,MAAA,EAAQ,OAAO,MAAA,GAAS,MAAA;AACvC,IAAA,OAAO,CAAA,CAAE,cAAc,CAAC,CAAA;AAAA,EAC1B,CAAC,CAAA;AAGD,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,IAAA,CAAK,eAAe,CAAA,CAC7C,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,oBAAA,CAAqB,QAAA,CAAS,IAAI,CAAC,CAAA,CACrD,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAAS,UAAA,CAAW,WAAA,EAAa,CAAC,CAAA,CACtE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AACd,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA;AACxC,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA;AACxC,IAAA,IAAI,MAAA,KAAW,MAAA,EAAQ,OAAO,MAAA,GAAS,MAAA;AACvC,IAAA,OAAO,CAAA,CAAE,cAAc,CAAC,CAAA;AAAA,EAC1B,CAAC,CAAA;AAEH,EAAA,MAAM,YAAA,GAAe,CAAC,IAAA,KAAiB;AACrC,IAAA,kBAAA,CAAmB,CAAC,IAAA,KAAS;AAC3B,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAClB,QAAA,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MACf;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,kBAAkB,MAAM;AAC5B,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,IAAA,EAAK,CAAE,WAAA,EAAY;AAC9C,IAAA,IAAI,OAAA,IAAW,CAAC,eAAA,CAAgB,GAAA,CAAI,OAAO,CAAA,EAAG;AAC5C,MAAA,kBAAA,CAAmB,CAAC,yBAAS,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,EAAM,OAAO,CAAC,CAAC,CAAA;AACxD,MAAA,aAAA,CAAc,EAAE,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,WAAA,GAAc,gBAChB,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAA,KAAc,gBAAgB,CAAA,IAAK;AAAA,IAC7D,KAAA,EAAO,CAAA;AAAA,IACP,UAAA,EAAY;AAAA,GACd,GACA,EAAE,KAAA,EAAO,CAAA,EAAG,YAAY,CAAA,EAAE;AAC9B,EAAA,MAAM,sBAAsB,WAAA,CAAY,KAAA;AACxC,EAAA,MAAM,oBAAoB,WAAA,CAAY,UAAA;AAEtC,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,OAAA;AAAA,MACE,KAAA,CAAM,KAAK,eAAe,CAAA;AAAA,MAC1B,gBAAgB,gBAAA,GAAmB;AAAA,KACrC;AACA,IAAA,OAAA,EAAQ;AAAA,EACV,CAAA;AAEA,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,kBAAA,iBAAmB,IAAI,IAAI,CAAC,GAAG,sBAAsB,GAAG,aAAa,CAAC,CAAC,CAAA;AAAA,EACzE,CAAA;AAEA,EAAA,MAAM,aAAa,MAAM;AACvB,IAAA,kBAAA,iBAAmB,IAAI,KAAK,CAAA;AAAA,EAC9B,CAAA;AAGA,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,IAAA,CAAK,eAAe,CAAA,CAAE,MAAA;AAAA,IAChD,CAAC,GAAA,EAAK,IAAA,KAAS,OAAO,cAAA,CAAe,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA,CAAA;AAAA,IAClD;AAAA,GACF;AACA,EAAA,MAAM,eAAe,aAAA,GAAgB,mBAAA;AAGrC,EAAA,MAAM,iBAAA,GAAoB,KAAA,CAAM,IAAA,CAAK,eAAe,CAAA,CAAE,MAAA;AAAA,IACpD,CAAC,GAAA,EAAK,IAAA,KAAS,OAAO,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA,CAAA;AAAA,IACnD;AAAA,GACF;AACA,EAAA,MAAM,mBAAmB,iBAAA,GAAoB,iBAAA;AAC7C,EAAA,MAAM,gBAAgB,iBAAA,GAAoB,gBAAA;AAE1C,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,EAAc,QAAA,KAAsB;AAC5D,IAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA;AAC1C,IAAA,uBACE,IAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QAEC,SAAA,EAAU,wGAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,IAAA;AAAA,cACL,OAAA,EAAS,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA;AAAA,cACjC,QAAA,EAAU,MAAM,YAAA,CAAa,IAAI,CAAA;AAAA,cACjC,YAAA,EAAY,WAAW,IAAI,CAAA,CAAA;AAAA;AAAA,WAC7B;AAAA,0BACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yCAAA,EAA2C,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,UAC/D,KAAA,GAAQ,CAAA,oBACP,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,+BAAA,EAAgC,QAAA,EAAA;AAAA,YAAA,GAAA;AAAA,YAAE,KAAA;AAAA,YAAM;AAAA,WAAA,EAAC,CAAA;AAAA,UAE1D,QAAA,oBACC,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAA,EAAU,6KAAA;AAAA,cACV,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,gBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,gBAAA,kBAAA,CAAmB,CAAC,IAAA,KAAS;AAC3B,kBAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,kBAAA,IAAA,CAAK,OAAO,IAAI,CAAA;AAChB,kBAAA,OAAO,IAAA;AAAA,gBACT,CAAC,CAAA;AAAA,cACH,CAAA;AAAA,cACA,YAAA,EAAY,UAAU,IAAI,CAAA,CAAA;AAAA,cAC3B,QAAA,EAAA;AAAA;AAAA;AAED;AAAA,OAAA;AAAA,MA5BG;AAAA,KA8BP;AAAA,EAEJ,CAAA;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,MAAA;AAAA,MACN,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,CAAC,MAAM,OAAA,EAAQ;AAAA,MACrB,CAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,cAAW,QAAA,EAAA,qBAAA,EAAmB,CAAA;AAAA,0BAC/B,GAAA,CAAC,UAAA,EAAA,EAAW,YAAA,EAAW,aAAA,EAAc;AAAA,SAAA,EACvC,CAAA;AAAA,wBAEA,IAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,qBAAA,EACnB,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,IAAA;AAAA,cACL,IAAA,EAAK,MAAA;AAAA,cACL,WAAA,EAAY,wBAAA;AAAA,cACZ,KAAA,EAAO,UAAA;AAAA,cACP,UAAU,CAAC,CAAA,KAAM,aAAA,CAAc,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cAC7C,YAAA,EAAW;AAAA;AAAA,WACb;AAAA,0BAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAO,OAAA,EAAQ,OAAA,EAAQ,MAAK,IAAA,EAAK,OAAA,EAAS,WAAW,QAAA,EAAA,YAAA,EAEtD,CAAA;AAAA,4BACA,GAAA,CAAC,UAAO,OAAA,EAAQ,OAAA,EAAQ,MAAK,IAAA,EAAK,OAAA,EAAS,YAAY,QAAA,EAAA,aAAA,EAEvD;AAAA,WAAA,EACF,CAAA;AAAA,0BAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yFAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,IAAA;AAAA,gBACL,KAAA,EAAM,8BAAA;AAAA,gBACN,OAAA,EAAS,aAAA;AAAA,gBACT,UAAU,CAAC,CAAA,KAAM,gBAAA,CAAiB,CAAA,CAAE,OAAO,OAAO;AAAA;AAAA,aACpD;AAAA,4BACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EACb,QAAA,kBAAA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,IAAA;AAAA,gBACL,OAAA,EAAS,yBAAA,CAA0B,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,kBAC7C,KAAA,EAAO,OAAO,CAAC,CAAA;AAAA,kBACf,KAAA,EAAO,GAAG,CAAC,CAAA,CAAA;AAAA,iBACb,CAAE,CAAA;AAAA,gBACF,KAAA,EAAO,OAAO,gBAAgB,CAAA;AAAA,gBAC9B,eAAe,CAAC,KAAA,KAAU,mBAAA,CAAoB,UAAA,CAAW,KAAK,CAAC,CAAA;AAAA,gBAC/D,UAAU,CAAC,aAAA;AAAA,gBACX,YAAA,EAAW;AAAA;AAAA,aACb,EACF,CAAA;AAAA,YACC,iBAAiB,mBAAA,GAAsB,CAAA,oBACtC,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,+BAAA,EAAgC,QAAA,EAAA;AAAA,cAAA,GAAA;AAAA,cAC5C,mBAAA;AAAA,cAAoB;AAAA,aAAA,EACxB;AAAA,WAAA,EAEJ,CAAA;AAAA,0BAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gHAAA,EACZ,QAAA,EAAA;AAAA,YAAA,eAAA,CAAgB,IAAI,CAAC,IAAA,KAAS,gBAAA,CAAiB,IAAA,EAAM,KAAK,CAAC,CAAA;AAAA,YAC3D,cAAc,GAAA,CAAI,CAAC,SAAS,gBAAA,CAAiB,IAAA,EAAM,IAAI,CAAC;AAAA,WAAA,EAC3D,CAAA;AAAA,0BAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,IAAA;AAAA,gBACL,IAAA,EAAK,MAAA;AAAA,gBACL,WAAA,EAAY,2BAAA;AAAA,gBACZ,KAAA,EAAO,UAAA;AAAA,gBACP,UAAU,CAAC,CAAA,KAAM,aAAA,CAAc,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,gBAC7C,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,kBAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AACrB,oBAAA,CAAA,CAAE,cAAA,EAAe;AACjB,oBAAA,eAAA,EAAgB;AAAA,kBAClB;AAAA,gBACF,CAAA;AAAA,gBACA,YAAA,EAAW;AAAA;AAAA,aACb;AAAA,4BACA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,WAAA;AAAA,gBACR,IAAA,EAAK,IAAA;AAAA,gBACL,OAAA,EAAS,eAAA;AAAA,gBACT,QAAA,EAAU,CAAC,UAAA,CAAW,IAAA,EAAK;AAAA,gBAC5B,QAAA,EAAA;AAAA;AAAA;AAED,WAAA,EACF;AAAA,SAAA,EACF,CAAA;AAAA,wBAEA,IAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,iBAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,+BAAA,EACb,QAAA,EAAA;AAAA,YAAA,YAAA;AAAA,YAAa,sBAAA;AAAA,YAAgB,eAAe,gBAAgB,CAAA;AAAA,YAAE,SAAA;AAAA,YAAG,GAAA;AAAA,YACjE,eAAe,aAAa;AAAA,WAAA,EAC/B,CAAA;AAAA,0BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAO,OAAA,EAAQ,WAAA,EAAY,MAAK,IAAA,EAAK,OAAA,EAAS,SAAS,QAAA,EAAA,QAAA,EAExD,CAAA;AAAA,4BACA,IAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,SAAA;AAAA,gBACR,IAAA,EAAK,IAAA;AAAA,gBACL,OAAA,EAAS,WAAA;AAAA,gBACT,UAAU,YAAA,KAAiB,CAAA;AAAA,gBAC5B,QAAA,EAAA;AAAA,kBAAA,mBAAA;AAAA,kBACmB,YAAA;AAAA,kBAAa;AAAA;AAAA;AAAA;AACjC,WAAA,EACF;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,gBAAA,CAAiB,WAAA,GAAc,kBAAA;ACtQxB,IAAM,kBAAkD,CAAC;AAAA,EAC9D,MAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAUC,gBAAS,EAAE,CAAA;AACrD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,gBAAwB,IAAI,CAAA;AAC5D,EAAA,MAAM,QAAA,GAAiBA,cAAyB,IAAI,CAAA;AAEpD,EAAA,MAAM,SAAA,GAAY,aAAA,CAAc,YAAA,EAAc,IAAA,CAAK,QAAQ,CAAA;AAC3D,EAAA,MAAM,aAAa,YAAA,GACf,YAAA,CAAa,KAAK,KAAA,GAAQ,YAAA,CAAa,KAAK,OAAA,GAC5C,CAAA;AACJ,EAAA,MAAM,cAAc,UAAA,GAAa,GAAA;AAGjC,EAAMA,iBAAU,MAAM;AACpB,IAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,aAAA,CAAc,EAAE,CAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,aAAA,CAAc,YAAA,CAAa,KAAK,IAAI,CAAA;AAAA,MACtC;AACA,MAAA,QAAA,CAAS,IAAI,CAAA;AAEb,MAAA,UAAA,CAAW,MAAM,QAAA,CAAS,OAAA,EAAS,KAAA,IAAS,EAAE,CAAA;AAAA,IAChD;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,YAAA,EAAc,SAAS,CAAC,CAAA;AAGpC,EAAA,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAA6C;AACtE,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,IAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AAErB,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA;AACjC,IAAA,MAAM,YAAsB,EAAC;AAC7B,IAAA,IAAI,KAAA,GAAQ,CAAA;AAEZ,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,MAAM,GAAA,GAAM,WAAW,IAAI,CAAA;AAC3B,MAAA,IAAI,KAAA,CAAM,GAAG,CAAA,IAAK,GAAA,IAAO,CAAA,EAAG;AAC1B,QAAA,OAAO;AAAA,UACL,WAAW,EAAC;AAAA,UACZ,SAAA,EAAW,CAAA;AAAA,UACX,KAAA,EAAO,oBAAoB,IAAI,CAAA,CAAA;AAAA,SACjC;AAAA,MACF;AACA,MAAA,SAAA,CAAU,KAAK,GAAG,CAAA;AAClB,MAAA,KAAA,IAAS,GAAA;AAAA,IACX;AAEA,IAAA,IAAI,SAAS,WAAA,EAAa;AACxB,MAAA,OAAO;AAAA,QACL,WAAW,EAAC;AAAA,QACZ,SAAA,EAAW,CAAA;AAAA,QACX,KAAA,EAAO,CAAA,OAAA,EAAU,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,6BAAA,EAAgC,WAAA,CAAY,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA;AAAA,OACzF;AAAA,IACF;AAEA,IAAA,MAAM,YAAY,WAAA,GAAc,KAAA;AAChC,IAAA,OAAO,EAAE,WAAW,SAAA,EAAU;AAAA,EAChC,CAAA;AAEA,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,MAAA,GAAS,kBAAkB,UAAU,CAAA;AAC3C,MAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,QAAA,QAAA,CAAS,OAAO,KAAK,CAAA;AACrB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,MAAA,IAAU,MAAA,CAAO,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AAEzC,QAAA,MAAM,eAAe,CAAC,GAAG,MAAA,CAAO,SAAA,EAAW,OAAO,SAAS,CAAA;AAC3D,QAAA,cAAA,CAAe,YAAY,CAAA;AAC3B,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAM,OAAA,GAAU,WAAW,IAAA,EAAK;AAChC,MAAA,IAAI,OAAA,IAAW,OAAA,KAAY,YAAA,EAAc,IAAA,CAAK,IAAA,EAAM;AAClD,QAAA,MAAA,CAAO,OAAO,CAAA;AAAA,MAChB;AACA,MAAA,OAAA,EAAQ;AAAA,IACV;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA2B;AAChD,IAAA,IAAI,CAAA,CAAE,QAAQ,OAAA,EAAS;AACrB,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,WAAA,EAAY;AAAA,IACd;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,OAAA,GAAU,SAAA,GAAY,iBAAA,CAAkB,UAAU,CAAA,GAAI,IAAA;AAE5D,EAAA,MAAM,gBAAgB,SAAA,GAClB,CAAC,WAAW,IAAA,EAAK,IACjB,CAAC,CAAC,OAAA,EAAS,KAAA,IACX,CAAC,WACD,OAAA,CAAQ,SAAA,CAAU,WAAW,CAAA,GAC7B,CAAC,WAAW,IAAA,EAAK;AAErB,EAAA,uBACEC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,UAAU,YAAA,KAAiB,IAAA;AAAA,MACjC,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,CAAC,MAAM,OAAA,EAAQ;AAAA,MACrB,CAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAAA,KAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,UAAA,EAAA,EAAY,QAAA,EAAA,SAAA,GAAY,eAAA,GAAkB,WAAA,EAAY,CAAA;AAAA,0BACvDA,GAAAA,CAAC,UAAA,EAAA,EAAW,YAAA,EAAW,cAAA,EAAe;AAAA,SAAA,EACxC,CAAA;AAAA,wBAEAA,IAAC,SAAA,EAAA,EAAU,SAAA,EAAU,uBAClB,QAAA,EAAA,SAAA,mBACCD,KAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6BAAA,EAA8B,QAAA,EAAA;AAAA,YAAA,mBAAA;AAAA,YACvB,GAAA;AAAA,4BAClBA,IAAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAU,eAAA,EACf,QAAA,EAAA;AAAA,cAAA,WAAA,CAAY,QAAQ,CAAC,CAAA;AAAA,cAAE;AAAA,aAAA,EAC1B;AAAA,WAAA,EACF,CAAA;AAAA,0BACAC,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qCAAoC,QAAA,EAAA,4DAAA,EAGjD,CAAA;AAAA,0BACAA,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAK,MAAA;AAAA,cACL,KAAA,EAAO,UAAA;AAAA,cACP,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,gBAAA,aAAA,CAAc,CAAA,CAAE,OAAO,KAAK,CAAA;AAC5B,gBAAA,QAAA,CAAS,IAAI,CAAA;AAAA,cACf,CAAA;AAAA,cACA,SAAA,EAAW,aAAA;AAAA,cACX,WAAA,EAAY,UAAA;AAAA,cACZ,YAAA,EAAW;AAAA;AAAA,WACb;AAAA,UACC,KAAA,oBACCA,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,8BAAA,EAA+B,IAAA,EAAK,SAC9C,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,UAED,OAAA,IACC,CAAC,OAAA,CAAQ,KAAA,IACT,QAAQ,SAAA,CAAU,MAAA,GAAS,CAAA,IAC3B,CAAC,KAAA,oBACCD,IAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,mCAAA,EAAoC,QAAA,EAAA;AAAA,YAAA,UAAA;AAAA,YACtC,GAAA;AAAA,YACR,CAAC,GAAG,OAAA,CAAQ,WAAW,OAAA,CAAQ,SAAS,EACtC,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAA,EAAI,EAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAI,CAAA,CAC/B,KAAK,GAAG;AAAA,WAAA,EACb,CAAA;AAAA,UAEH,OAAA,EAAS,KAAA,IAAS,CAAC,KAAA,oBAClBC,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,8BAAA,EAA+B,IAAA,EAAK,OAAA,EAC9C,QAAA,EAAA,OAAA,CAAQ,KAAA,EACX;AAAA,SAAA,EAEJ,CAAA,mBAEAD,IAAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6BAAA,EAA8B,QAAA,EAAA,qBAAA,EAAmB,CAAA;AAAA,0BAC9DA,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAK,MAAA;AAAA,cACL,KAAA,EAAO,UAAA;AAAA,cACP,UAAU,CAAC,CAAA,KAAM,aAAA,CAAc,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cAC7C,SAAA,EAAW,aAAA;AAAA,cACX,YAAA,EAAW;AAAA;AAAA;AACb,SAAA,EACF,CAAA,EAEJ,CAAA;AAAA,wBAEAD,IAAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,iBAAA,EACrB,QAAA,EAAA;AAAA,0BAAAC,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,YAAA,EAAc,OAAA,GAAU,WAAA,GAAc,QAAA;AAAA,cAC/C,IAAA,EAAK,IAAA;AAAA,cACL,OAAA,EAAS,QAAA;AAAA,cAER,QAAA,EAAA,YAAA,EAAc,UAAU,SAAA,GAAY;AAAA;AAAA,WACvC;AAAA,0BACAD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,GAAAA,CAAC,UAAO,OAAA,EAAQ,WAAA,EAAY,MAAK,IAAA,EAAK,OAAA,EAAS,SAAS,QAAA,EAAA,QAAA,EAExD,CAAA;AAAA,4BACAA,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,SAAA;AAAA,gBACR,IAAA,EAAK,IAAA;AAAA,gBACL,OAAA,EAAS,WAAA;AAAA,gBACT,QAAA,EAAU,aAAA;AAAA,gBAET,sBAAY,OAAA,GAAU;AAAA;AAAA;AACzB,WAAA,EACF;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AC3NvB,IAAM,uBAA4D,CAAC;AAAA,EACxE,MAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAUC,MAAA,CAAA,QAAA,CAAS,eAAe,GAAI,CAAA;AACpE,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAUA,MAAA,CAAA,QAAA,CAAS,cAAc,GAAI,CAAA;AAGvE,EAAMA,iBAAU,MAAM;AACpB,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,CAAa,eAAe,GAAI,CAAA;AAChC,MAAA,cAAA,CAAe,cAAc,GAAI,CAAA;AAAA,IACnC;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,YAAA,EAAc,WAAW,CAAC,CAAA;AAEtC,EAAA,MAAM,cAAc,MAAM;AAExB,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,GAAA,CAAI,WAAA,EAAa,SAAS,CAAA;AACxD,IAAA,OAAA,CAAQ,IAAA,CAAK,MAAM,SAAA,GAAY,GAAI,GAAG,IAAA,CAAK,KAAA,CAAM,gBAAA,GAAmB,GAAI,CAAC,CAAA;AACzE,IAAA,OAAA,EAAQ;AAAA,EACV,CAAA;AAGA,EAAA,MAAM,qBAAA,GAAwB,CAAC,KAAA,KAAkB;AAC/C,IAAA,YAAA,CAAa,KAAK,CAAA;AAClB,IAAA,IAAI,cAAc,KAAA,EAAO;AACvB,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,gBAAgB,CAAC,CAAA,KAAc,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAEpD,EAAA,uBACEF,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,MAAA;AAAA,MACN,YAAA,EAAc,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,CAAC,MAAM,OAAA,EAAQ;AAAA,MACrB,CAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAAA,KAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,cAAW,QAAA,EAAA,kBAAA,EAAgB,CAAA;AAAA,0BAC5BA,GAAAA,CAAC,UAAA,EAAA,EAAW,YAAA,EAAW,aAAA,EAAc;AAAA,SAAA,EACvC,CAAA;AAAA,wBAEAD,IAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,qBAAA,EACnB,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAM,0BAAA;AAAA,gBACN,GAAA,EAAK,GAAA;AAAA,gBACL,GAAA,EAAK,CAAA;AAAA,gBACL,IAAA,EAAM,GAAA;AAAA,gBACN,KAAA,EAAO,SAAA;AAAA,gBACP,aAAA,EAAe,qBAAA;AAAA,gBACf,SAAA,EAAS,IAAA;AAAA,gBACT,WAAA,EAAa,aAAA;AAAA,gBACb,YAAA,EAAW;AAAA;AAAA,aACb;AAAA,4BACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qCAAoC,QAAA,EAAA,uDAAA,EAEjD;AAAA,WAAA,EACF,CAAA;AAAA,0BAEAD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAM,2BAAA;AAAA,gBACN,GAAA,EAAK,SAAA;AAAA,gBACL,GAAA,EAAK,CAAA;AAAA,gBACL,IAAA,EAAM,GAAA;AAAA,gBACN,KAAA,EAAO,WAAA;AAAA,gBACP,aAAA,EAAe,cAAA;AAAA,gBACf,SAAA,EAAS,IAAA;AAAA,gBACT,WAAA,EAAa,aAAA;AAAA,gBACb,YAAA,EAAW;AAAA;AAAA,aACb;AAAA,4BACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qCAAoC,QAAA,EAAA,yDAAA,EAEjD;AAAA,WAAA,EACF;AAAA,SAAA,EACF,CAAA;AAAA,wBAEAD,KAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,UAAO,OAAA,EAAQ,WAAA,EAAY,MAAK,IAAA,EAAK,OAAA,EAAS,SAAS,QAAA,EAAA,QAAA,EAExD,CAAA;AAAA,0BACAA,IAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,WAAU,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,WAAA,EAAa,QAAA,EAAA,OAAA,EAE1D;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,oBAAA,CAAqB,WAAA,GAAc,sBAAA;ACrG5B,IAAM,kBAAkD,CAAC;AAAA,EAC9D,MAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,OAAA,GAAgBE,cAAuB,IAAI,CAAA;AAGjD,EAAMA,iBAAU,MAAM;AACpB,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAqB;AAC1C,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,OAAA,EAAQ;AAAA,IAClC,CAAA;AACA,IAAA,MAAM,kBAAA,GAAqB,CAAC,CAAA,KAAkB;AAC5C,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAC,OAAA,CAAQ,QAAQ,QAAA,CAAS,CAAA,CAAE,MAAc,CAAA,EAAG;AAClE,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF,CAAA;AACA,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,aAAa,CAAA;AAClD,MAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,kBAAkB,CAAA;AACzD,MAAA,OAAO,MAAM;AACX,QAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,aAAa,CAAA;AACrD,QAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,kBAAkB,CAAA;AAAA,MAC9D,CAAA;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,OAAO,CAAC,CAAA;AAEpB,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,QAAA,EAAU,OAAO,IAAA;AAEjC,EAAA,uBACEH,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,OAAA;AAAA,MACL,SAAA,EAAU,4GAAA;AAAA,MACV,OAAO,EAAE,IAAA,EAAM,SAAS,CAAA,EAAG,GAAA,EAAK,SAAS,CAAA,EAAE;AAAA,MAC3C,IAAA,EAAK,MAAA;AAAA,MACL,YAAA,EAAW,kBAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAAC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gFAAA,EAAiF,QAAA,EAAA,kBAAA,EAEhG,CAAA;AAAA,wBACAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBACZ,QAAA,EAAA,eAAA,CAAgB,GAAA,CAAI,CAAC,KAAA,KAAU;AAC9B,UAAA,MAAM,QAAA,GAAW,eAAe,KAAA,KAAU,KAAA;AAC1C,UAAA,MAAM,SAAA,GAAY,KAAA,KAAU,YAAA,IAAgB,CAAC,aAAA;AAC7C,UAAA,uBACED,IAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,IAAA,EAAK,QAAA;AAAA,cACL,SAAA,EAAW,CAAA,2KAAA,EACT,QAAA,GACI,uCAAA,GACA,gCACN,CAAA,CAAA;AAAA,cACA,SAAS,MAAM;AACb,gBAAA,UAAA,CAAW,KAAK,CAAA;AAChB,gBAAA,OAAA,EAAQ;AAAA,cACV,CAAA;AAAA,cACA,IAAA,EAAK,UAAA;AAAA,cAEJ,QAAA,EAAA;AAAA,gBAAA,KAAA;AAAA,gBAAM,GAAA;AAAA,gBACN,6BACCC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAgC,QAAA,EAAA,SAAA,EAAO;AAAA;AAAA,aAAA;AAAA,YAfpD;AAAA,WAiBP;AAAA,QAEJ,CAAC,CAAA,EACH,CAAA;AAAA,QACC,iCACCA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,kMAAA;AAAA,YACV,SAAS,MAAM;AACb,cAAA,cAAA,EAAe;AACf,cAAA,OAAA,EAAQ;AAAA,YACV,CAAA;AAAA,YACA,IAAA,EAAK,UAAA;AAAA,YACN,QAAA,EAAA;AAAA;AAAA;AAED;AAAA;AAAA,GAEJ;AAEJ;AAEA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AC5F9B,IAAI,WAAA,GAAwD,IAAA;AAC5D,SAAS,QAAA,GAAW;AAClB,EAAA,WAAA,KAAgB;AAAA;AAAA,IAA0B;AAAA,GAAS;AACnD,EAAA,OAAO,WAAA;AACT;AAkBA,eAAe,WAAA,CACb,MACA,MAAA,EACyB;AACzB,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,IAAA,IAAA,GAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACxB,CAAA,MAAO;AACL,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,EAAS;AAC5B,IAAA,IAAA,GAAO,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,EACvB;AACA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,EAC1D;AACA,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,KAAM;AAC1B,IAAA,MAAM,EAAA,GAAK,GAAA;AAMX,IAAA,MAAM,IAAI,EAAA,CAAG,IAAA;AACb,IAAA,IACE,CAAC,CAAA,IACD,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,IAClB,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,IACrB,OAAO,CAAA,CAAE,UAAU,QAAA,EACnB;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,0DAAA;AAAA,OAChB;AAAA,IACF;AACA,IAAA,IACE,CAAA,CAAE,QAAA,KAAa,MAAA,IACf,CAAA,CAAE,QAAA,KAAa,MAAA,IACf,CAAA,CAAE,QAAA,KAAa,SAAA,IACf,CAAA,CAAE,QAAA,KAAa,iBAAA,EACf;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,0DAAA;AAAA,OAChB;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAuB;AAAA,MAC3B,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,SAAS,CAAA,CAAE,OAAA;AAAA,MACX,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,GAAI,OAAO,CAAA,CAAE,QAAA,KAAa,QAAA,GACtB,EAAE,QAAA,EAAU,CAAA,CAAE,QAAA,EAAuC,GACrD,EAAC;AAAA,MACL,GAAI,OAAO,CAAA,CAAE,SAAA,KAAc,QAAA,GAAW,EAAE,SAAA,EAAW,CAAA,CAAE,SAAA,EAAU,GAAI;AAAC,KACtE;AACA,IAAA,OAAO;AAAA,MACL,eACE,OAAO,EAAA,CAAG,aAAA,KAAkB,QAAA,GAAW,GAAG,aAAA,GAAgB,EAAA;AAAA,MAC5D,OAAA,EAAS,OAAA,CAAQ,EAAA,CAAG,OAAO,CAAA;AAAA,MAC3B,GAAI,EAAA,CAAG,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,OAAA,CAAQ,EAAA,CAAG,QAAQ,CAAA,EAAE,GAAI,EAAC;AAAA,MACtE;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH;AAEO,IAAM,cAA0C,CAAC;AAAA,EACtD,UAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUG,gBAAuB,QAAQ,CAAA;AACjE,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUA,gBAAuB,MAAM,CAAA;AAC/D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUA,gBAAS,EAAE,CAAA;AACzC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,gBAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,gBAAwB,IAAI,CAAA;AAE5D,EAAA,MAAM,WAAW,MAAA,KAAW,UAAA;AAG5B,EAAMA,iBAAU,MAAM;AACpB,IAAA,IAAI,KAAA,EAAO;AACX,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,MAAM,IAAA,GAAO,MAAA,KAAW,UAAA,GAAa,UAAA,GAAa,WAAA;AAClD,IAAA,CAAC,YAAY;AACX,MAAA,MAAM,aACJ,MAAA,KAAW,MAAA,GACP,IAAA,CAAK,SAAA,CAAU,MAAM,IAAA,EAAM,CAAC,CAAA,GAAA,CAC3B,MAAM,UAAS,EAAG,IAAA,CAAK,MAAM,EAAE,SAAA,EAAW,KAAK,CAAA;AACtD,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAA,CAAQ,UAAU,CAAA;AAClB,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAA,GAAG;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,QAAQ,UAAA,EAAY,WAAA,EAAa,KAAK,CAAC,CAAA;AAEnD,EAAA,MAAM,cAAc,YAAY;AAC9B,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,CAAY,IAAA,EAAM,MAAM,CAAA;AAC5C,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,QAAA,CAAS,KAAK,CAAA;AACd,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACf,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA;AAAA,QACE,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU;AAAA,OACvC;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,QAAA,CAAS,KAAK,CAAA;AACd,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAC,KAAA,EAAqB,KAAA,qBACzCH,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAS,MAAM;AACb,QAAA,SAAA,CAAU,KAAK,CAAA;AACf,QAAA,QAAA,CAAS,KAAK,CAAA;AACd,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACf,CAAA;AAAA,MACA,gBAAc,MAAA,KAAW,KAAA;AAAA,MACzB,SAAA,EAAW,CAAA,wHAAA,EACT,MAAA,KAAW,KAAA,GACP,0CACA,4DACN,CAAA,CAAA;AAAA,MAEC,QAAA,EAAA;AAAA;AAAA,GACH;AAGF,EAAA,uBACED,IAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,CAAA,mEAAA,EAAsE,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,MAChG,YAAA,EAAW,mBAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+EAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uCAAA,EAAwC,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,0BAC9DA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EAA0B,eAAY,MAAA,EAAO,CAAA;AAAA,UAC5D,YAAA,CAAa,UAAU,QAAQ,CAAA;AAAA,UAC/B,YAAA,CAAa,YAAY,UAAU,CAAA;AAAA,0BACpCA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EAA0B,eAAY,MAAA,EAAO,CAAA;AAAA,0BAC7DA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAS,MAAM;AACb,gBAAA,SAAA,CAAU,MAAA,KAAW,MAAA,GAAS,MAAA,GAAS,MAAM,CAAA;AAC7C,gBAAA,QAAA,CAAS,KAAK,CAAA;AACd,gBAAA,QAAA,CAAS,IAAI,CAAA;AAAA,cACf,CAAA;AAAA,cACA,SAAA,EAAU,oLAAA;AAAA,cACV,KAAA,EAAM,oBAAA;AAAA,cAEL,iBAAO,WAAA;AAAY;AAAA,WACtB;AAAA,0BACAA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6CACb,QAAA,EAAA,QAAA,GAAW,WAAA,GAAc,KAAA,GAAQ,QAAA,GAAW,MAAA,EAC/C,CAAA;AAAA,0BACAA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,OAAA;AAAA,cACR,IAAA,EAAK,IAAA;AAAA,cACL,OAAA,EAAS,OAAA;AAAA,cACT,YAAA,EAAW,oBAAA;AAAA,cACZ,QAAA,EAAA;AAAA;AAAA;AAED,SAAA,EACF,CAAA;AAAA,wBAEAA,GAAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,IAAA;AAAA,YACP,QAAA;AAAA,YACA,UAAA,EAAY,KAAA;AAAA,YACZ,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,cAAA,OAAA,CAAQ,CAAA,CAAE,OAAO,KAAK,CAAA;AACtB,cAAA,QAAA,CAAS,IAAI,CAAA;AAAA,YACf,CAAA;AAAA,YACA,SAAA,EAAU,oHAAA;AAAA,YACV,cAAY,CAAA,eAAA,EAAkB,MAAM,CAAA,EAAA,EAAK,MAAA,CAAO,aAAa,CAAA,CAAA;AAAA;AAAA,SAC/D;AAAA,QAEC,yBACCA,GAAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,wEAAA;AAAA,YACV,IAAA,EAAK,OAAA;AAAA,YAEJ,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAGD,CAAC,QAAA,oBACAD,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mEAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,UAAO,IAAA,EAAK,IAAA,EAAK,SAAS,WAAA,EAAa,QAAA,EAAU,CAAC,KAAA,EAAO,QAAA,EAAA,OAAA,EAE1D,CAAA;AAAA,0BACAA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,OAAA;AAAA,cACR,IAAA,EAAK,IAAA;AAAA,cACL,OAAA,EAAS,WAAA;AAAA,cACT,UAAU,CAAC,KAAA;AAAA,cACX,KAAA,EAAM,yDAAA;AAAA,cACP,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAoC,QAAA,EAAA,wEAAA,EAGpD;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GAEJ;AAEJ,CAAA;ACtIA,IAAM,mBAAA,GAAsB,GAAA;AAAA;AAAA;AAAA,EAG1B,yGAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,WAAA,EAAa;AAAA,QACX,UAAA,EAAY,EAAA;AAAA,QACZ,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,WAAA,EAAa;AAAA;AACf;AAEJ,CAAA;AAqBA,SAAS,wBAAA,CACP,WACA,SAAA,EACM;AACN,EAAA,IAAI,CAAC,SAAA,EAAW;AAGhB,EAAA,IAAI,SAAA,CAAU,YAAA,IAAgB,SAAA,CAAU,YAAA,EAAc;AAEtD,EAAA,MAAM,EAAA,GAAK,SAAA,CAAU,aAAA,CAAc,CAAA,kBAAA,EAAqB,SAAS,CAAA,EAAA,CAAI,CAAA;AACrE,EAAA,IAAI,CAAC,EAAA,EAAI;AAET,EAAA,MAAM,YAAA,GAAe,UAAU,qBAAA,EAAsB;AACrD,EAAA,MAAM,OAAA,GAAU,GAAG,qBAAA,EAAsB;AAEzC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,GAAM,YAAA,CAAa,GAAA;AACzC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,GAAS,YAAA,CAAa,MAAA;AAE5C,EAAA,MAAM,QAAQ,KAAA,GAAQ,CAAA,GAAI,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,GAAQ,CAAA;AACtD,EAAA,IAAI,UAAU,CAAA,EAAG;AAEjB,EAAA,SAAA,CAAU,QAAA,CAAS;AAAA,IACjB,GAAA,EAAK,UAAU,SAAA,GAAY,KAAA;AAAA,IAC3B,QAAA,EAAU;AAAA,GACX,CAAA;AACH;AAGA,SAASI,gBAAe,EAAA,EAAoB;AAC1C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAI,CAAA;AACzC,EAAA,IAAI,eAAe,EAAA,EAAI;AACrB,IAAA,OAAO,GAAG,YAAY,CAAA,CAAA,CAAA;AAAA,EACxB;AACA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,IAAI,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAO,YAAA,GAAe,OAAQ,EAAE,CAAA;AACrD,EAAA,MAAM,UAAU,YAAA,GAAe,EAAA;AAC/B,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,OAAO,GAAG,KAAK,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,IAAI,MAAA,CAAO,OAAO,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,EACzF;AACA,EAAA,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AACvD;AAsBA,SAAS,cAAc,CAAA,EAA4B;AACjD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ;AAAA,GACF;AAEA,EAAA,IAAI,EAAE,SAAA,EAAW;AACf,IAAA,KAAA,CAAM,KAAK,0CAA0C,CAAA;AAAA,EACvD;AACA,EAAA,IAAI,EAAE,gBAAA,EAAkB;AACtB,IAAA,KAAA,CAAM,KAAK,oBAAoB,CAAA;AAAA,EACjC;AAEA,EAAA,IAAI,EAAE,QAAA,EAAU;AACd,IAAA,KAAA,CAAM,KAAK,iDAAiD,CAAA;AAAA,EAC9D,CAAA,MAAA,IAAW,EAAE,QAAA,EAAU;AACrB,IAAA,KAAA,CAAM,KAAK,uCAAuC,CAAA;AAAA,EACpD,CAAA,MAAA,IAAW,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,SAAA,EAAW;AACtC,IAAA,KAAA,CAAM,KAAK,mBAAmB,CAAA;AAAA,EAChC,CAAA,MAAA,IAAW,EAAE,SAAA,EAAW;AACtB,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ;AAAA,KACF;AAAA,EACF,CAAA,MAAA,IAAW,EAAE,UAAA,EAAY;AACvB,IAAA,KAAA,CAAM,KAAK,gDAAgD,CAAA;AAAA,EAC7D,CAAA,MAAA,IAAW,EAAE,gBAAA,EAAkB;AAC7B,IAAA,KAAA,CAAM,KAAK,0CAA0C,CAAA;AAAA,EACvD,CAAA,MAAA,IAAW,EAAE,SAAA,EAAW;AACtB,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ;AAAA,KACF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,KAAA,CAAM,KAAK,yBAAyB,CAAA;AAAA,EACtC;AAGA,EAAA,IACE,CAAA,CAAE,cACD,CAAA,CAAE,QAAA,IAAa,EAAE,UAAA,IAAc,CAAA,CAAE,SAAA,IAAc,CAAA,CAAE,QAAA,CAAA,EAClD;AACA,IAAA,KAAA,CAAM,KAAK,yBAAyB,CAAA;AAAA,EACtC;AAGA,EAAA,IAAI,EAAE,QAAA,IAAY,CAAA,CAAE,SAAA,IAAa,CAAC,EAAE,QAAA,EAAU;AAC5C,IAAA,IAAI,EAAE,SAAA,EAAW;AACf,MAAA,KAAA,CAAM,KAAK,wDAAwD,CAAA;AAAA,IACrE,CAAA,MAAA,IAAW,EAAE,QAAA,EAAU;AACrB,MAAA,KAAA,CAAM,KAAK,uDAAuD,CAAA;AAAA,IACpE,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAK,wDAAwD,CAAA;AAAA,IACrE;AAAA,EACF;AAEA,EAAA,IAAI,EAAE,cAAA,EAAgB;AACpB,IAAA,KAAA,CAAM,KAAK,+CAA+C,CAAA;AAAA,EAC5D;AAIA,EAAA,IAAI,EAAE,MAAA,EAAQ;AACZ,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,GAAG,CAAA;AACvB;AAGA,IAAM,KAAA,GAAgD,CAAC,EAAE,IAAA,uBACvDJ,GAAAA;AAAA,EAAC,MAAA;AAAA,EAAA;AAAA,IACC,aAAA,EAAY,MAAA;AAAA,IACZ,SAAA,EAAW,CAAA,2EAAA,EACT,IAAA,KAAS,QAAA,GAAW,aAAa,WACnC,CAAA;AAAA;AACF,CAAA;AAoBK,IAAM,WAAA,GAAoB,MAAA,CAAA,UAAA;AAAA,EAC/B,CACE;AAAA,IACE,GAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,gBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,mBAAA;AAAA,IACA,gBAAA;AAAA,IACA,uBAAA;AAAA,IACA,mBAAA;AAAA,IACA,kBAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA,GAAgB,KAAA;AAAA,IAChB,eAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,SAAA;AAAA,IACA,SAAA,EAAW,iBAAA;AAAA,IACX,SAAA;AAAA,IACA;AAAA,KAEF,GAAA,KACG;AAEH,IAAA,MAAM,QAAQ,kBAAA,CAAmB;AAAA,MAC/B,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,gBAAA;AAAA,MACA,mBAAA;AAAA,MACA,mBAAA;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AACD,IAAA,MAAM;AAAA,MACJ,WAAA;AAAA,MACA,SAAA;AAAA,MACA,SAAA;AAAA,MACA,QAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA,EAAS,YAAA;AAAA,MACT,iBAAA;AAAA,MACA,WAAA;AAAA,MACA,GAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,aAAA;AAAA,MACA,oBAAA;AAAA,MACA,iBAAA;AAAA,MACA,YAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,iBAAA;AAAA,MACA,gBAAA;AAAA,MACA,iBAAA;AAAA,MACA,eAAA;AAAA,MACA,qBAAA;AAAA,MACA,gBAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF,GAAI,KAAA;AASJ,IAAA,MAAM,kBACJ,SAAA,CAAU,MAAA,GAAS,CAAA,IAAM,aAAA,IAAiB,CAAC,CAAC,YAAA;AAC9C,IAAA,MAAM,eAAA,GAAkB,YAAA,IAAiB,OAAA,IAAW,CAAC,CAAC,MAAA;AACtD,IAAA,MAAM,YAAA,GAAe,eAAA,IAAmB,eAAA,IAAmB,CAAC,CAAC,MAAA;AAG7D,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,MAAA,CAAA,QAAA;AAAA,MAClD;AAAA,KACF;AACA,IAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAU,gBAAiB,CAAC,CAAA;AAE9D,IAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAU,gBAEhD,QAAQ,CAAA;AACV,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,MAAA,CAAA,QAAA;AAAA,MAClD;AAAA,KACF;AACA,IAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAU,MAAA,CAAA,QAAA;AAAA,MACtC;AAAA,KACF;AACA,IAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAU,gBAEtD,IAAI,CAAA;AACN,IAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAU,gBAAS,KAAK,CAAA;AACtE,IAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAU,gBAAS,KAAK,CAAA;AACtD,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,gBAAS,KAAK,CAAA;AAClE,IAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAU,gBAAS,KAAK,CAAA;AACpE,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,gBAAS,KAAK,CAAA;AAClE,IAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAU,MAAA,CAAA,QAAA;AAAA,MAClD;AAAA,KACF;AACA,IAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAU,gBAExD,IAAI,CAAA;AACN,IAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAU,gBAG9C,IAAI,CAAA;AAGd,IAAA,MAAM,SAAA,GAAkB,cAAuB,IAAI,CAAA;AAMnD,IAAM,MAAA,CAAA,mBAAA;AAAA,MACJ,iBAAA;AAAA,MACA,OAAuB;AAAA,QACrB,UAAU,CAAC,MAAA,KAAW,SAAA,CAAU,OAAA,EAAS,SAAS,MAAM,CAAA;AAAA,QACxD,IAAA,EAAM,MAAM,SAAA,CAAU,OAAA,EAAS,IAAA,EAAK;AAAA,QACpC,KAAA,EAAO,MAAM,SAAA,CAAU,OAAA,EAAS,KAAA,EAAM;AAAA,QACtC,gBAAA,EAAkB,MAAM,SAAA,CAAU,OAAA,EAAS,kBAAiB,IAAK,CAAA;AAAA,QACjE,aAAA,EAAe,MAAM,SAAA,CAAU,OAAA,EAAS,eAAc,IAAK,CAAA;AAAA,QAC3D,QAAA,EAAU,MAAM,SAAA,CAAU,OAAA,EAAS,UAAS,IAAK,IAAA;AAAA,QACjD,iBAAiB,CAAC,IAAA,KAAS,SAAA,CAAU,OAAA,EAAS,gBAAgB,IAAI,CAAA;AAAA,QAClE,IAAI,YAAA,GAAe;AACjB,UAAA,OAAO,SAAA,CAAU,SAAS,YAAA,IAAgB,IAAA;AAAA,QAC5C;AAAA,OACF,CAAA;AAAA,MACA;AAAC,KACH;AACA,IAAA,MAAM,UAAA,GAAmB,cAAuB,IAAI,CAAA;AACpD,IAAA,MAAM,aAAA,GAAsB,cAAsB,IAAI,CAAA;AACtD,IAAA,MAAM,UAAA,GAAmB,cAAgB,KAAK,CAAA;AAC9C,IAAA,MAAM,cAAA,GAAuB,MAAA,CAAA,MAAA;AAAA,MAC3B;AAAA,KACF;AACA,IAAA,MAAM,kBAAA,GAA2B,cAAgB,KAAK,CAAA;AAGtD,IAAA,MAAM,kBAAA,GAA2B,cAAsB,IAAI,CAAA;AAC3D,IAAA,MAAM,WAAA,GAAoB,cAAwC,IAAI,CAAA;AACtE,IAAA,MAAM,eAAA,GAAwB,cAAsB,IAAI,CAAA;AACxD,IAAA,MAAM,aAAA,GAAsB,cAGlB,IAAI,CAAA;AACd,IAAA,MAAM,mBAAA,GAA4B,cAAsB,IAAI,CAAA;AAC5D,IAAA,MAAM,iBAAA,GAA0B,cAAsB,IAAI,CAAA;AAE1D,IAAA,MAAM,gBAAA,GAAyB,MAAA,CAAA,MAAA,CAA0B,EAAE,CAAA;AAC3D,IAAA,MAAM,mBAAA,GAA4B,cAAe,CAAC,CAAA;AAMlD,IAAM,iBAAU,MAAM;AACpB,MAAA,gBAAA,GAAmB,QAAQ,CAAA;AAAA,IAC7B,CAAA,EAAG,CAAC,QAAA,EAAU,gBAAgB,CAAC,CAAA;AAE/B,IAAM,iBAAU,MAAM;AACpB,MAAA,mBAAA,GAAsB,WAAW,CAAA;AAAA,IACnC,CAAA,EAAG,CAAC,WAAA,EAAa,mBAAmB,CAAC,CAAA;AAKrC,IAAA,MAAM,qBAAA,GAA8B,cAAO,kBAAkB,CAAA;AAC7D,IAAM,iBAAU,MAAM;AACpB,MAAA,qBAAA,CAAsB,OAAA,GAAU,kBAAA;AAAA,IAClC,CAAC,CAAA;AACD,IAAM,iBAAU,MAAM;AACpB,MAAA,qBAAA,CAAsB,OAAA,GAAU,cAAc,YAAY,CAAA;AAAA,IAC5D,CAAA,EAAG,CAAC,YAAA,EAAc,YAAY,CAAC,CAAA;AAG/B,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,uBAAA,EAAyB;AAC3B,QAAA,MAAM,IAAA,GAAO,YAAY,WAAW,CAAA;AACpC,QAAA,IAAI,IAAA,IAAQ,CAAC,IAAA,CAAK,OAAA,EAAS;AACzB,UAAA,uBAAA,CAAwB,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,QAC3C,CAAA,MAAO;AACL,UAAA,uBAAA,CAAwB,IAAI,CAAA;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,CAAA,EAAG,CAAC,WAAA,EAAa,WAAA,EAAa,uBAAuB,CAAC,CAAA;AAOtD,IAAA,MAAM,iBAAA,GAA0B,cAAO,UAAU,CAAA;AACjD,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,iBAAA,CAAkB,YAAY,UAAA,EAAY;AAC9C,MAAA,iBAAA,CAAkB,OAAA,GAAU,UAAA;AAC5B,MAAA,cAAA,CAAe,CAAC,CAAA;AAChB,MAAA,iBAAA,CAAkB,QAAQ,CAAA;AAC1B,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,MAAA,oBAAA,CAAqB,IAAI,CAAA;AACzB,MAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,MAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,MAAA,gBAAA,CAAiB,UAAU,EAAC;AAC5B,MAAA,mBAAA,CAAoB,OAAA,GAAU,CAAA;AAAA,IAChC,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAGf,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,aAAA,CAAc,YAAY,IAAA,EAAM;AAClC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,eAAA,KAAoB,IAAA,IAAQ,eAAA,IAAmB,CAAA,EAAG;AACpD,QAAA,cAAA,CAAe,eAAe,CAAA;AAC9B,QAAA,iBAAA,CAAkB,QAAQ,CAAA;AAC1B,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,MACzB;AAAA,IACF,CAAA,EAAG,CAAC,eAAe,CAAC,CAAA;AAGpB,IAAM,iBAAU,MAAM;AACpB,MAAA,IAAI,oBAAoB,IAAA,EAAM;AAC9B,MAAA,wBAAA,CAAyB,UAAA,CAAW,SAAS,eAAe,CAAA;AAAA,IAC9D,CAAA,EAAG,CAAC,eAAe,CAAC,CAAA;AASpB,IAAM,iBAAU,MAAM;AACpB,MAAA,UAAA,CAAW,OAAA,EAAS,KAAA,CAAM,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,IACnD,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAGf,IAAM,iBAAU,MAAM;AACpB,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,MAAA,GAAS,OAAO,gBAAA,EAAiB;AACvC,MAAA,MAAM,mBAAmB,WAAA,CAAY,SAAA;AAAA,QACnC,CAAC,EAAA,KACC,CAAC,EAAA,CAAG,OAAA,IAAW,MAAA,IAAU,EAAA,CAAG,IAAA,CAAK,OAAA,IAAW,MAAA,GAAS,EAAA,CAAG,IAAA,CAAK;AAAA,OACjE;AACA,MAAA,MAAM,WAAA,GACJ,gBAAA,IAAoB,CAAA,GAChB,eAAA,CAAgB,gBAAgB,CAAA,GAChC,YAAA;AACN,MAAA,MAAA,CAAO,gBAAgB,WAAW,CAAA;AAAA,IACpC,GAAG,CAAC,YAAA,EAAc,YAAA,EAAc,WAAA,EAAa,eAAe,CAAC,CAAA;AAM7D,IAAA,MAAM,gBAAA,GAAmB,CAAC,MAAA,KAAmB;AAC3C,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,CAAC,MAAA,EAAQ;AAIb,MAAA,IAAI,iBAAA,IAAqB,gBAAA,CAAiB,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC5D,QAAA,MAAM,UAAA,GACJ,gBAAA,CAAiB,OAAA,CAAQ,mBAAA,CAAoB,OAAO,CAAA;AACtD,QAAA,IAAI,UAAA,IAAc,MAAA,IAAU,UAAA,CAAW,KAAA,EAAO;AAC5C,UAAA,MAAM,SAAA,GAAY,oBAAoB,OAAA,GAAU,CAAA;AAChD,UAAA,IAAI,SAAA,GAAY,gBAAA,CAAiB,OAAA,CAAQ,MAAA,EAAQ;AAC/C,YAAA,mBAAA,CAAoB,OAAA,GAAU,SAAA;AAC9B,YAAA,MAAA,CAAO,QAAA,CAAS,gBAAA,CAAiB,OAAA,CAAQ,SAAS,EAAE,OAAO,CAAA;AAAA,UAC7D,CAAA,MAAO;AAEL,YAAA,MAAA,CAAO,KAAA,EAAM;AACb,YAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,YAAA,gBAAA,CAAiB,UAAU,EAAC;AAC5B,YAAA,mBAAA,CAAoB,OAAA,GAAU,CAAA;AAAA,UAChC;AAAA,QACF;AAAA,MACF,CAAA,MAAA,IAAW,QAAA,IAAY,CAAC,MAAA,CAAO,UAAS,EAAG;AAEzC,QAAA,MAAM,gBAAgB,WAAA,CAAY,IAAA;AAAA,UAChC,CAAC,EAAA,KACC,EAAA,CAAG,OAAA,IAAW,MAAA,IAAU,GAAG,IAAA,CAAK,OAAA,IAAW,MAAA,GAAS,EAAA,CAAG,IAAA,CAAK;AAAA,SAChE;AACA,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,MAAM,iBAAiB,WAAA,CAAY,IAAA;AAAA,YACjC,CAAC,EAAA,KAAO,CAAC,GAAG,OAAA,IAAW,EAAA,CAAG,KAAK,OAAA,IAAW;AAAA,WAC5C;AACA,UAAA,IAAI,cAAA,EAAgB;AAClB,YAAA,MAAA,CAAO,QAAA,CAAS,cAAA,CAAe,IAAA,CAAK,OAAO,CAAA;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAGA,MAAA,IACE,iBAAA,CAAkB,OAAA,KAAY,IAAA,IAC9B,MAAA,IAAU,kBAAkB,OAAA,EAC5B;AACA,QAAA,MAAA,CAAO,KAAA,EAAM;AACb,QAAA,IAAI,mBAAA,CAAoB,YAAY,IAAA,EAAM;AACxC,UAAA,MAAA,CAAO,QAAA,CAAS,oBAAoB,OAAO,CAAA;AAC3C,UAAA,mBAAA,CAAoB,OAAA,GAAU,IAAA;AAAA,QAChC;AACA,QAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAAA,MAC9B;AAKA,MAAA,IAAI,WAAA,GAAc,EAAA;AAClB,MAAA,IAAI,iBAAA,IAAqB,gBAAA,CAAiB,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC5D,QAAA,MAAM,UAAA,GACJ,gBAAA,CAAiB,OAAA,CAAQ,mBAAA,CAAoB,OAAO,CAAA;AACtD,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,KAAA,MAAW,GAAA,IAAO,WAAW,aAAA,EAAe;AAC1C,YAAA,MAAM,EAAA,GAAK,YAAY,GAAG,CAAA;AAC1B,YAAA,IACE,EAAA,IACA,CAAC,EAAA,CAAG,OAAA,IACJ,MAAA,IAAU,EAAA,CAAG,IAAA,CAAK,OAAA,IAClB,MAAA,GAAS,EAAA,CAAG,IAAA,CAAK,KAAA,EACjB;AACA,cAAA,WAAA,GAAc,GAAA;AACd,cAAA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,MAAA,IAAI,gBAAgB,EAAA,EAAI;AACtB,QAAA,WAAA,GAAc,WAAA,CAAY,SAAA;AAAA,UACxB,CAAC,EAAA,KACC,CAAC,EAAA,CAAG,OAAA,IAAW,MAAA,IAAU,EAAA,CAAG,IAAA,CAAK,OAAA,IAAW,MAAA,GAAS,EAAA,CAAG,IAAA,CAAK;AAAA,SACjE;AAAA,MACF;AAGA,MAAA,IAAI,WAAA,KAAgB,eAAA,IAAmB,WAAA,IAAe,CAAA,EAAG;AACvD,QAAA,MAAA,CAAO,eAAA,CAAgB,eAAA,CAAgB,WAAW,CAAC,CAAA;AAAA,MACrD;AACA,MAAA,kBAAA,CAAmB,WAAA,IAAe,CAAA,GAAI,WAAA,GAAc,IAAI,CAAA;AAGxD,MAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,IAC1B,CAAA;AAEA,IAAA,MAAM,uBAAuB,MAAM;AACjC,MAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,MAAA,gBAAA,CAAiB,UAAU,EAAC;AAC5B,MAAA,mBAAA,CAAoB,OAAA,GAAU,CAAA;AAAA,IAChC,CAAA;AAOA,IAAA,MAAM,gBAAA,GAAyB,mBAAY,MAAgB;AACzD,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAM,UAAoB,EAAC;AAC3B,QAAA,KAAA,IAAS,CAAA,GAAI,UAAU,KAAA,EAAO,CAAA,IAAK,UAAU,GAAA,EAAK,CAAA,EAAA,EAAK,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AACrE,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,OAAO,CAAC,WAAW,CAAA;AAAA,IACrB,CAAA,EAAG,CAAC,SAAA,EAAW,WAAW,CAAC,CAAA;AAE3B,IAAA,MAAM,SAAA,GAAkB,mBAAY,MAAM;AACxC,MAAA,GAAA,CAAI,kBAAkB,CAAA;AAAA,IACxB,CAAA,EAAG,CAAC,GAAA,EAAK,gBAAgB,CAAC,CAAA;AAE1B,IAAA,MAAM,WAAA,GAAoB,mBAAY,MAAM;AAC1C,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,MAAM,WAAA,GAAc,UAAU,KAAA,CAAM,MAAA;AACpC,MAAA,MAAM,WAAA,GAAc,KAAA,CAAM,WAAA,EAAa,cAAA,KAAmB,OAAO,CAAA;AACjE,MAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,QAAA,cAAA,CAAe,WAAA,GAAc,cAAc,CAAC,CAAA;AAC5C,QAAA,iBAAA,CAAkB,OAAO,CAAA;AACzB,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,MACzB;AAAA,IACF,GAAG,CAAC,SAAA,EAAW,KAAA,EAAO,WAAA,EAAa,cAAc,CAAC,CAAA;AAGlD,IAAA,MAAM,kBAAA,GAA2B,mBAAY,MAAM;AACjD,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAM,WAAA,GAAc,mBAAmB,SAAA,CAAU,KAAA;AACjD,QAAA,MAAM,OAAA,GAAoB,CAAC,WAAW,CAAA;AACtC,QAAA,KAAA,IAAS,IAAI,SAAA,CAAU,KAAA,EAAO,CAAA,IAAK,SAAA,CAAU,KAAK,CAAA,EAAA,EAAK;AACrD,UAAA,IAAI,CAAA,KAAM,WAAA,EAAa,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,QACvC;AACA,QAAA,WAAA,CAAY,OAAO,CAAA;AAAA,MACrB,CAAA,MAAO;AACL,QAAA,iBAAA,CAAkB,WAAW,CAAA;AAAA,MAC/B;AAAA,IACF,CAAA,EAAG;AAAA,MACD,SAAA;AAAA,MACA,eAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AAGD,IAAA,MAAM,UAAA,GAAmB,MAAA,CAAA,WAAA;AAAA,MACvB,CAAC,CAAA,KAA4B;AAC3B,QAAA,MAAM,UAAU,gBAAA,EAAiB;AACjC,QAAA,MAAM,gBAAgB,OAAA,CACnB,GAAA,CAAI,CAAC,CAAA,KAAM,YAAY,CAAC,CAAC,CAAA,CACzB,MAAA,CAAO,CAAC,EAAA,KAA2B,EAAA,KAAO,MAAA,IAAa,CAAC,GAAG,OAAO,CAAA;AACrE,QAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAChC,QAAA,MAAM,YAAA,GAAe,cAClB,MAAA,CAAO,CAAC,OAAO,CAAC,aAAA,CAAc,GAAG,IAAA,CAAK,QAAQ,CAAC,CAAA,CAC/C,GAAA,CAAI,CAAC,EAAA,KAAO,EAAA,CAAG,KAAK,IAAI,CAAA,CACxB,KAAK,GAAG,CAAA;AACX,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,CAAA,CAAE,aAAA,CAAc,OAAA,CAAQ,YAAA,EAAc,YAAY,CAAA;AAClD,QAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MACd,CAAA;AAAA,MACA,CAAC,gBAAA,EAAkB,WAAA,EAAa,IAAI;AAAA,KACtC;AAMA,IAAA,MAAM,cAAA,GAAuB,MAAA,CAAA,WAAA,CAAY,CAAC,KAAA,KAAkB;AAC1D,MAAA,kBAAA,CAAmB,KAAK,CAAA;AAAA,IAC1B,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,eAAA,GAAwB,mBAAY,MAAM;AAC9C,MAAA,kBAAA,CAAmB,IAAI,CAAA;AAEvB,MAAA,UAAA,CAAW,MAAM,UAAA,CAAW,OAAA,EAAS,KAAA,IAAS,CAAC,CAAA;AAAA,IACjD,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,gBAAA,GAAyB,MAAA,CAAA,WAAA;AAAA,MAC7B,CAAC,OAAA,KAAoB;AACnB,QAAA,IAAI,oBAAoB,IAAA,EAAM;AAC9B,QAAA,WAAA,CAAY,iBAAiB,OAAO,CAAA;AAAA,MACtC,CAAA;AAAA,MACA,CAAC,iBAAiB,WAAW;AAAA,KAC/B;AAEA,IAAA,MAAM,wBAAA,GAAiC,MAAA,CAAA,WAAA;AAAA,MACrC,CAAC,SAAA,KAAwB;AACvB,QAAA,IAAI,oBAAoB,IAAA,EAAM;AAC9B,QAAA,YAAA,CAAa,iBAAiB,SAAS,CAAA;AAAA,MACzC,CAAA;AAAA,MACA,CAAC,iBAAiB,YAAY;AAAA,KAChC;AAEA,IAAA,MAAM,kBAAA,GAA2B,mBAAY,MAAM;AACjD,MAAA,IAAI,oBAAoB,IAAA,EAAM;AAC5B,QAAA,UAAA,CAAW,eAAe,CAAA;AAC1B,QAAA,eAAA,EAAgB;AAAA,MAClB;AAAA,IACF,CAAA,EAAG,CAAC,eAAA,EAAiB,UAAA,EAAY,eAAe,CAAC,CAAA;AAMjD,IAAA,MAAM,eAAA,GAAkB,CACtB,IAAA,EACA,KAAA,EACA,CAAA,KACG;AACH,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,iBAAA,CAAkB,QAAQ,CAAA;AAC1B,MAAA,aAAA,CAAc,OAAA,GAAU,KAAA;AAExB,MAAA,IAAI,CAAA,CAAE,QAAA,IAAY,eAAA,KAAoB,IAAA,EAAM;AAE1C,QAAA,YAAA,CAAa;AAAA,UACX,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,KAAK,CAAA;AAAA,UACtC,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,KAAK;AAAA,SACrC,CAAA;AAAA,MACH,WACE,iBAAA,KAAsB,IAAA,IACtB,sBAAsB,KAAA,IACtB,CAAC,WAAW,OAAA,EACZ;AAEA,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,KAAK,CAAA;AAC/C,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,KAAK,CAAA;AAC7C,QAAA,YAAA,CAAa,EAAE,KAAA,EAAO,GAAA,EAAK,CAAA;AAC3B,QAAA,kBAAA,CAAmB,iBAAiB,CAAA;AACpC,QAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA,MAC3B,CAAA,MAAA,IAAW,sBAAsB,KAAA,EAAO,CAExC,MAAA,IAAW,CAAC,UAAA,CAAW,OAAA,EAAS;AAE9B,QAAA,kBAAA,CAAmB,KAAK,CAAA;AACxB,QAAA,YAAA,CAAa,IAAI,CAAA;AAEjB,QAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,MAAA,CAAO,KAAA,EAAM;AACb,UAAA,MAAA,CAAO,QAAA,CAAS,KAAK,OAAO,CAAA;AAC5B,UAAA,mBAAA,CAAoB,UAAU,IAAA,CAAK,OAAA;AACnC,UAAA,iBAAA,CAAkB,UAAU,IAAA,CAAK,KAAA;AACjC,UAAA,MAAA,CAAO,IAAA,EAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,qBAAA,GAAwB,CAAC,KAAA,EAAe,CAAA,KAAwB;AACpE,MAAA,CAAA,CAAE,cAAA,EAAe;AAEjB,MAAA,IAAI,mBAAmB,OAAA,EAAS;AAEhC,MAAA,IAAI,sBAAsB,KAAA,EAAO;AAC/B,QAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA,MAC3B,CAAA,MAAO;AACL,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,QAAA,YAAA,CAAa,IAAI,CAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,kBAAA,GAAqB,EAAA;AAC3B,IAAA,MAAM,sBAAA,GAAyB,EAAA;AAE/B,IAAA,MAAM,mBAAA,GAAsB,CAAC,KAAA,KAAkB;AAC7C,MAAA,MAAM,SAAS,kBAAA,CAAmB,OAAA;AAClC,MAAA,IAAI,CAAC,UAAA,CAAW,OAAA,IAAW,MAAA,KAAW,IAAA,EAAM;AAC5C,MAAA,YAAA,CAAa;AAAA,QACX,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,KAAK,CAAA;AAAA,QAC7B,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,KAAK;AAAA,OAC5B,CAAA;AACD,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB,CAAA;AAGA,IAAA,MAAM,gBAAA,GAAmB,CAAC,CAAA,EAAW,CAAA,KAA6B;AAChE,MAAA,MAAM,OAAO,QAAA,CACV,gBAAA,GAAmB,GAAG,CAAC,CAAA,EACtB,UAAU,mBAAmB,CAAA;AACjC,MAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,MAAA,MAAM,MAAA,GAAS,MAAA,CAAQ,IAAA,CAAqB,OAAA,CAAQ,SAAS,CAAA;AAC7D,MAAA,OAAO,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,GAAI,MAAA,GAAS,IAAA;AAAA,IAC7C,CAAA;AAQA,IAAA,MAAM,2BAA2B,MAAM;AACrC,MAAA,MAAM,YAAY,UAAA,CAAW,OAAA;AAC7B,MAAA,MAAM,UAAU,WAAA,CAAY,OAAA;AAC5B,MAAA,IAAI,CAAC,SAAA,IAAa,CAAC,OAAA,EAAS;AAI5B,MAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA;AAChC,MAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,OAAO,WAAW,CAAA;AACvD,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAM,CAAC,CAAA;AAClC,MAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,EAAO,OAAO,UAAU,CAAA;AACpD,MAAA,IAAI,MAAA,IAAU,GAAA,IAAO,KAAA,IAAS,IAAA,EAAM;AACpC,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA,EAAG,MAAA,GAAS,CAAC,CAAA;AAC3D,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,CAAA,EAAG,IAAA,GAAO,CAAC,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAA;AAC3D,MAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,CAAA,EAAG,IAAA,GAAA,CAAQ,QAAQ,IAAA,IAAQ,CAAA,EAAG,IAAA,GAAO,EAAE,CAAA,EAAG;AAC5D,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,MAAM,IAAA,GAAO,CAAC,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAA;AAC3D,QAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,MAAA,EAAQ,CAAC,CAAA;AACxC,QAAA,IAAI,UAAU,IAAA,EAAM;AAClB,UAAA,mBAAA,CAAoB,KAAK,CAAA;AACzB,UAAA;AAAA,QACF;AAAA,MACF;AAKA,MAAA,MAAM,KAAA,GACJ,SAAA,CAAU,gBAAA,CAA8B,mBAAmB,CAAA;AAC7D,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAIxB,MAAA,IAAI,MAAM,CAAC,CAAA,CAAE,qBAAA,EAAsB,CAAE,MAAM,CAAA,EAAG;AAC5C,QAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAChD,QAAA,IAAI,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,sBAAuB,MAAM,CAAA;AACxD,QAAA;AAAA,MACF;AACA,MAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,QAAA,MAAM,QAAA,GAAW,KAAA,CAAM,CAAC,CAAA,CAAE,qBAAA,EAAsB;AAChD,QAAA,IAAI,QAAA,CAAS,OAAO,CAAA,EAAG;AACrB,UAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAChD,UAAA,IAAI,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,sBAAuB,MAAM,CAAA;AACxD,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA;AAGA,IAAA,MAAM,qBAAqB,MAAM;AAC/B,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,MAAA,MAAM,YAAY,UAAA,CAAW,OAAA;AAC7B,MAAA,MAAM,UAAU,WAAA,CAAY,OAAA;AAC5B,MAAA,IAAI,CAAC,UAAA,CAAW,OAAA,IAAW,CAAC,SAAA,IAAa,CAAC,OAAA,EAAS;AAInD,MAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA;AAChC,MAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,OAAO,WAAW,CAAA;AAEvD,MAAA,IAAI,UAAU,GAAA,EAAK;AACjB,QAAA,eAAA,CAAgB,OAAA,GAAU,sBAAsB,kBAAkB,CAAA;AAClE,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,GAAO,CAAA;AACX,MAAA,IAAI,OAAA,CAAQ,CAAA,GAAI,GAAA,GAAM,kBAAA,EAAoB;AACxC,QAAA,IAAA,GAAO,IAAA,CAAK,GAAA;AAAA,UAAA,CACT,OAAA,CAAQ,CAAA,IAAK,GAAA,GAAM,kBAAA,CAAA,IAAuB,CAAA;AAAA,UAC3C,CAAC;AAAA,SACH;AAAA,MACF,CAAA,MAAA,IAAW,OAAA,CAAQ,CAAA,GAAI,MAAA,GAAS,kBAAA,EAAoB;AAClD,QAAA,IAAA,GAAO,IAAA,CAAK,GAAA;AAAA,UAAA,CACT,OAAA,CAAQ,CAAA,IAAK,MAAA,GAAS,kBAAA,CAAA,IAAuB,CAAA;AAAA,UAC9C;AAAA,SACF;AAAA,MACF;AACA,MAAA,IAAI,SAAS,CAAA,EAAG;AAId,QAAA,MAAM,SAAS,SAAA,CAAU,SAAA;AACzB,QAAA,SAAA,CAAU,SAAA,IAAa,IAAA;AACvB,QAAA,IAAI,SAAA,CAAU,cAAc,MAAA,EAAQ;AAClC,UAAA,wBAAA,EAAyB;AAAA,QAC3B;AAAA,MACF;AACA,MAAA,eAAA,CAAgB,OAAA,GAAU,sBAAsB,kBAAkB,CAAA;AAAA,IACpE,CAAA;AAEA,IAAA,MAAM,sBAAsB,MAAM;AAChC,MAAA,IAAI,cAAc,OAAA,EAAS;AACzB,QAAA,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,aAAA,CAAc,OAAA,CAAQ,IAAI,CAAA;AACpE,QAAA,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,aAAA,CAAc,OAAA,CAAQ,EAAE,CAAA;AAChE,QAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,MAC1B;AACA,MAAA,IAAI,eAAA,CAAgB,YAAY,IAAA,EAAM;AACpC,QAAA,oBAAA,CAAqB,gBAAgB,OAAO,CAAA;AAC5C,QAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,MAC5B;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,gBAAgB,MAAM;AAC1B,MAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,QAAA,YAAA,CAAa,eAAe,OAAO,CAAA;AACnC,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AACA,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,UAAA,CAAW,OAAA,GAAU,KAAA;AAAA,MACvB;AACA,MAAA,mBAAA,EAAoB;AAAA,IACtB,CAAA;AAQA,IAAA,MAAM,oBAAoB,MAAM;AAC9B,MAAA,mBAAA,EAAoB;AAEpB,MAAA,MAAM,EAAA,GAAK,MAAM,aAAA,EAAc;AAC/B,MAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAkB;AAC9B,QAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AAEzB,QAAA,IAAI,CAAA,CAAE,YAAY,CAAA,EAAG;AACnB,UAAA,EAAA,EAAG;AACH,UAAA;AAAA,QACF;AACA,QAAA,WAAA,CAAY,UAAU,EAAE,CAAA,EAAG,EAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA,EAAQ;AAInD,QAAA,MAAM,YAAY,UAAA,CAAW,OAAA;AAC7B,QAAA,IAAI,SAAA,IAAa,eAAe,OAAA,EAAS;AACvC,UAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,UAAA,MAAM,OAAA,GACJ,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,QACjB,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,KAAA,IACjB,EAAE,OAAA,GAAU,IAAA,CAAK,GAAA,IACjB,CAAA,CAAE,UAAU,IAAA,CAAK,MAAA;AACnB,UAAA,IAAI,OAAA,EAAS;AACX,YAAA,YAAA,CAAa,eAAe,OAAO,CAAA;AACnC,YAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,UAC3B;AAAA,QACF;AACA,QAAA,wBAAA,EAAyB;AAAA,MAC3B,CAAA;AAEA,MAAA,aAAA,CAAc,OAAA,GAAU,EAAE,IAAA,EAAM,EAAA,EAAG;AACnC,MAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,IAAI,CAAA;AAC3C,MAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,EAAE,CAAA;AACvC,MAAA,eAAA,CAAgB,OAAA,GAAU,sBAAsB,kBAAkB,CAAA;AAAA,IACpE,CAAA;AAIA,IAAM,MAAA,CAAA,SAAA;AAAA,MACJ,MAAM,MAAM;AACV,QAAA,IAAI,cAAc,OAAA,EAAS;AACzB,UAAA,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,aAAA,CAAc,OAAA,CAAQ,IAAI,CAAA;AACpE,UAAA,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,aAAA,CAAc,OAAA,CAAQ,EAAE,CAAA;AAChE,UAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,QAC1B;AACA,QAAA,IAAI,eAAA,CAAgB,YAAY,IAAA,EAAM;AACpC,UAAA,oBAAA,CAAqB,gBAAgB,OAAO,CAAA;AAC5C,UAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,QAC5B;AACA,QAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,UAAA,YAAA,CAAa,eAAe,OAAO,CAAA;AACnC,UAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,QAC3B;AAAA,MACF,CAAA;AAAA,MACA;AAAC,KACH;AAEA,IAAA,MAAM,mBAAA,GAAsB,CAAC,KAAA,EAAe,CAAA,KAAwB;AAClE,MAAA,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AAGpB,MAAA,kBAAA,CAAmB,OAAA,GAAU,KAAA;AAC7B,MAAA,cAAA,CAAe,OAAA,GAAU,WAAW,MAAM;AACxC,QAAA,kBAAA,CAAmB,OAAA,GAAU,IAAA;AAC7B,QAAA,cAAA,CAAe,KAAK,CAAA;AAAA,MACtB,GAAG,GAAG,CAAA;AAEN,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,MAAA,kBAAA,CAAmB,OAAA,GAAU,KAAA;AAC7B,MAAA,WAAA,CAAY,UAAU,EAAE,CAAA,EAAG,EAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA,EAAQ;AACnD,MAAA,kBAAA,CAAmB,KAAK,CAAA;AACxB,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,iBAAA,CAAkB,QAAQ,CAAA;AAC1B,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,iBAAA,EAAkB;AAAA,IACpB,CAAA;AAEA,IAAA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAkB;AAE9C,MAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,QAAA,YAAA,CAAa,eAAe,OAAO,CAAA;AACnC,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAEA,MAAA,mBAAA,CAAoB,KAAK,CAAA;AAAA,IAC3B,CAAA;AAEA,IAAA,MAAM,qBAAA,GAAwB,CAAC,KAAA,EAAe,CAAA,KAAwB;AACpE,MAAA,CAAA,CAAE,cAAA,EAAe;AAEjB,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,aAAA,CAAc,qBAAA,EAAsB;AACnD,MAAA,MAAM,UAAA,GAAa,GAAA;AACnB,MAAA,MAAM,SAAA,GAAY,GAAA;AAElB,MAAA,IAAI,IAAI,IAAA,CAAK,IAAA;AACb,MAAA,IAAI,CAAA,GAAI,KAAK,MAAA,GAAS,CAAA;AAEtB,MAAA,IAAI,CAAA,GAAI,SAAA,GAAY,MAAA,CAAO,UAAA,EAAY;AACrC,QAAA,CAAA,GAAI,MAAA,CAAO,aAAa,SAAA,GAAY,CAAA;AAAA,MACtC;AACA,MAAA,IAAI,CAAA,GAAI,UAAA,GAAa,MAAA,CAAO,WAAA,EAAa;AACvC,QAAA,CAAA,GAAI,IAAA,CAAK,MAAM,UAAA,GAAa,CAAA;AAC5B,QAAA,IAAI,IAAI,CAAA,EAAG;AACT,UAAA,CAAA,GAAI,CAAA;AAAA,QACN;AAAA,MACF;AAEA,MAAA,oBAAA,CAAqB,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA;AAC7B,MAAA,qBAAA,CAAsB,KAAK,CAAA;AAAA,IAC7B,CAAA;AAMA,IAAA,MAAM,aAAA,GAAsB,MAAA,CAAA,WAAA;AAAA,MAC1B,CAAC,CAAA,KAA2B;AAC1B,QAAA,MAAM,YAAY,WAAA,CAAY,MAAA;AAC9B,QAAA,IAAI,cAAc,CAAA,EAAG;AAErB,QAAA,IAAI,QAAA,GAAW,WAAA;AACf,QAAA,IAAI,OAAA,GAAU,KAAA;AAEd,QAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,IAAY,CAAA,CAAE,QAAQ,WAAA,EAAa;AAC/C,UAAA,kBAAA,EAAmB;AACnB,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,YAAY,CAAA,CAAE,OAAA,IAAW,EAAE,OAAA,KAAY,CAAA,CAAE,QAAQ,GAAA,EAAK;AACpD,UAAA,SAAA,EAAU;AACV,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAA,CAAY,EAAE,OAAA,IAAW,CAAA,CAAE,YAAY,CAAA,CAAE,GAAA,KAAQ,OAAO,SAAA,EAAW;AACjE,UAAA,WAAA,EAAY;AACZ,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAA,CAAY,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,KAAY,EAAE,GAAA,KAAQ,GAAA,IAAO,CAAC,CAAA,CAAE,QAAA,EAAU;AACnE,UAAA,IAAA,EAAK;AACL,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAA,CACG,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,MACd,CAAA,CAAE,GAAA,KAAQ,GAAA,IAAO,CAAA,CAAE,QAAA,IAAa,CAAA,CAAE,GAAA,KAAQ,GAAA,CAAA,EAC5C;AAKA,UAAA,IAAI,cAAc,IAAA,EAAK;AAAA,eAAA,IACd,OAAA,IAAW,QAAQ,MAAA,EAAO;AACnC,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,WAAA,EAAa;AAChC,UAAA,IAAI,mBAAmB,OAAA,EAAS;AAE9B,YAAA,iBAAA,CAAkB,QAAQ,CAAA;AAAA,UAC5B,CAAA,MAAO;AACL,YAAA,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAA,GAAc,CAAC,CAAA;AAAA,UACxC;AACA,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,YAAA,EAAc;AACjC,UAAA,IAAI,WAAA,KAAgB,SAAA,GAAY,CAAA,IAAK,cAAA,KAAmB,QAAA,EAAU;AAEhE,YAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,UAC3B,CAAA,MAAA,IAAW,mBAAmB,OAAA,EAAS;AACrC,YAAA,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,SAAA,GAAY,CAAA,EAAG,cAAc,CAAC,CAAA;AAAA,UACpD;AACA,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,WAAW,CAAA,CAAE,GAAA,KAAQ,SAAA,IAAa,CAAA,CAAE,QAAQ,WAAA,EAAa;AAEvD,UAAA,MAAM,cAAA,GAAiB,WAAW,OAAA,EAAS,aAAA;AAAA,YACzC,qBAAqB,WAAW,CAAA,EAAA;AAAA,WAClC;AACA,UAAA,IAAI,cAAA,EAAgB;AAClB,YAAA,MAAM,WAAA,GAAc,eAAe,qBAAA,EAAsB;AACzD,YAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,IAAA,GAAO,WAAA,CAAY,KAAA,GAAQ,CAAA;AAE9D,YAAA,MAAM,SAAA,GAAY,CAAA,CAAE,GAAA,KAAQ,SAAA,GAAY,EAAA,GAAK,CAAA;AAC7C,YAAA,IAAI,SAAA,GAAY,WAAA;AAChB,YAAA,IAAI,YAAA,GAAe,QAAA;AACnB,YAAA,IAAI,YAAA,GAA8B,IAAA;AAElC,YAAA,KAAA,IACM,CAAA,GAAI,cAAc,SAAA,EACtB,CAAA,IAAK,KAAK,CAAA,GAAI,SAAA,EACd,KAAK,SAAA,EACL;AACA,cAAA,MAAM,EAAA,GAAK,WAAW,OAAA,EAAS,aAAA;AAAA,gBAC7B,qBAAqB,CAAC,CAAA,EAAA;AAAA,eACxB;AACA,cAAA,IAAI,CAAC,EAAA,EAAI;AAET,cAAA,MAAM,IAAA,GAAO,GAAG,qBAAA,EAAsB;AACtC,cAAA,MAAM,gBAAA,GACJ,cAAc,EAAA,GACV,IAAA,CAAK,UAAU,WAAA,CAAY,GAAA,GAC3B,IAAA,CAAK,GAAA,IAAO,WAAA,CAAY,MAAA;AAE9B,cAAA,IAAI,gBAAA,EAAkB;AAEpB,gBAAA,IAAI,iBAAiB,IAAA,EAAM;AACzB,kBAAA,YAAA,GAAe,IAAA,CAAK,GAAA;AAAA,gBACtB;AACA,gBAAA,MAAM,kBAAkB,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,GAAM,YAAY,CAAA,GAAI,CAAA;AAC5D,gBAAA,IAAI,eAAA,EAAiB;AACnB,kBAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,CAAA;AACzC,kBAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,OAAA,GAAU,cAAc,CAAA;AAClD,kBAAA,IAAI,WAAW,YAAA,EAAc;AAC3B,oBAAA,YAAA,GAAe,QAAA;AACf,oBAAA,SAAA,GAAY,CAAA;AAAA,kBACd;AAAA,gBACF,CAAA,MAAO;AAEL,kBAAA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AACA,YAAA,QAAA,GAAW,SAAA;AAAA,UACb;AACA,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,MAAA,EAAQ;AAC3B,UAAA,QAAA,GAAW,CAAA;AACX,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,KAAA,EAAO;AAC1B,UAAA,QAAA,GAAW,SAAA,GAAY,CAAA;AACvB,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,EAAS;AAC5B,UAAA,cAAA,CAAe,WAAW,CAAA;AAC1B,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,GAAA,EAAK;AAExB,UAAA,MAAM,EAAA,GAAK,YAAY,WAAW,CAAA;AAClC,UAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,UAAA,IAAI,MAAA,IAAU,EAAA,IAAM,CAAC,EAAA,CAAG,OAAA,EAAS;AAC/B,YAAA,IAAI,MAAA,CAAO,UAAS,EAAG;AACrB,cAAA,IAAI,QAAA,EAAU;AAEZ,gBAAA,MAAM,QAAA,GAAW,gBAAA;AACjB,gBAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,kBAAA,IAAI,eAAA,GAAkB,CAAA;AACtB,kBAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACxC,oBAAA,IAAI,SAAS,CAAC,CAAA,CAAE,aAAA,CAAc,QAAA,CAAS,WAAW,CAAA,EAAG;AACnD,sBAAA,eAAA,GAAkB,CAAA;AAClB,sBAAA;AAAA,oBACF;AAAA,kBACF;AACA,kBAAA,gBAAA,CAAiB,OAAA,GAAU,QAAA;AAC3B,kBAAA,mBAAA,CAAoB,OAAA,GAAU,eAAA;AAC9B,kBAAA,oBAAA,CAAqB,IAAI,CAAA;AAEzB,kBAAA,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,IAAA,CAAK,OAAO,CAAA;AAC/B,kBAAA,MAAA,CAAO,IAAA,EAAK;AAAA,gBACd;AAAA,cACF,CAAA,MAAO;AAEL,gBAAA,MAAA,CAAO,QAAA,CAAS,EAAA,CAAG,IAAA,CAAK,OAAO,CAAA;AAC/B,gBAAA,MAAA,CAAO,IAAA,EAAK;AAAA,cACd;AAAA,YACF,CAAA,MAAO;AACL,cAAA,MAAA,CAAO,KAAA,EAAM;AACb,cAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,YAC5B;AAAA,UACF;AACA,UAAA,OAAA,GAAU,IAAA;AAAA,QACZ;AAEA,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,UAAA,IAAI,aAAa,WAAA,EAAa;AAC5B,YAAA,cAAA,CAAe,QAAQ,CAAA;AACvB,YAAA,iBAAA,CAAkB,QAAQ,CAAA;AAAA,UAC5B;AAEA,UAAA,IAAI,EAAE,QAAA,IAAY,CAAA,CAAE,QAAQ,QAAA,IAAY,CAAA,CAAE,QAAQ,WAAA,EAAa;AAE7D,YAAA,MAAM,SAAS,eAAA,IAAmB,WAAA;AAClC,YAAA,IAAI,oBAAoB,IAAA,EAAM;AAC5B,cAAA,kBAAA,CAAmB,WAAW,CAAA;AAAA,YAChC;AACA,YAAA,YAAA,CAAa;AAAA,cACX,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAA;AAAA,cAChC,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,QAAQ;AAAA,aAC/B,CAAA;AAAA,UACH,WAAW,CAAC,CAAA,CAAE,OAAA,IAAW,CAAC,EAAE,OAAA,EAAS;AAEnC,YAAA,YAAA,CAAa,IAAI,CAAA;AACjB,YAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,UACzB;AAGA,UAAA,wBAAA,CAAyB,UAAA,CAAW,SAAS,QAAQ,CAAA;AAAA,QACvD;AAAA,MACF,CAAA;AAAA,MACA;AAAA,QACE,WAAA;AAAA,QACA,WAAA;AAAA,QACA,cAAA;AAAA,QACA,eAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA,gBAAA;AAAA,QACA,kBAAA;AAAA,QACA,SAAA;AAAA,QACA,WAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA;AACF,KACF;AAMA,IAAA,MAAM,cAAA,GAAiB,CAAC,KAAA,KAA2B;AACjD,MAAA,IAAI,CAAC,WAAW,OAAO,KAAA;AACvB,MAAA,OAAO,KAAA,IAAS,SAAA,CAAU,KAAA,IAAS,KAAA,IAAS,SAAA,CAAU,GAAA;AAAA,IACxD,CAAA;AAEA,IAAA,MAAM,UAAA,GAAa,CAAC,EAAA,EAAkB,KAAA,KAAkB;AACtD,MAAA,MAAM,WAAW,KAAA,KAAU,eAAA;AAC3B,MAAA,MAAM,WAAW,KAAA,KAAU,WAAA;AAC3B,MAAA,MAAM,UAAA,GAAa,eAAe,KAAK,CAAA;AACvC,MAAA,MAAM,YAAY,EAAA,CAAG,OAAA;AACrB,MAAA,MAAM,UAAA,GAAa,GAAG,QAAA,IAAY,KAAA;AAClC,MAAA,MAAM,YACJ,EAAA,CAAG,IAAA,CAAK,aAAa,SAAA,IACrB,EAAA,CAAG,KAAK,QAAA,KAAa,iBAAA;AACvB,MAAA,MAAM,gBAAA,GAAmB,EAAA,CAAG,IAAA,CAAK,QAAA,KAAa,iBAAA;AAC9C,MAAA,MAAM,WAAW,KAAA,KAAU,iBAAA;AAC3B,MAAA,MAAM,gBAAA,GAAmB,YAAY,cAAA,KAAmB,QAAA;AACxD,MAAA,MAAM,kBACJ,QAAA,IACA,cAAA,KAAmB,OAAA,IACnB,KAAA,KAAU,YAAY,MAAA,GAAS,CAAA;AACjC,MAAA,MAAM,WAAA,GAAc,sBAAsB,KAAK,CAAA;AAC/C,MAAA,MAAM,cAAA,GAAiB,CAAC,CAAC,WAAA;AAGzB,MAAA,MAAM,cAAA,GAAiB,gBAAgB,KAAK,CAAA;AAC5C,MAAA,IAAI,WAAA,GAAc,GAAG,IAAA,CAAK,IAAA;AAC1B,MAAA,IAAI,SAAA,IAAa,mBAAmB,CAAA,EAAG;AACrC,QAAA,MAAM,kBAAA,GAAqB,EAAA,CAAG,IAAA,CAAK,KAAA,GAAQ,GAAG,IAAA,CAAK,OAAA;AACnD,QAAA,MAAM,mBAAA,GAAsB,qBAAqB,cAAA,GAAiB,GAAA;AAClE,QAAA,WAAA,GAAc,CAAA,CAAA,EAAI,mBAAA,CAAoB,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AAAA,MAClD;AAEA,MAAA,MAAM,QAAQ,CAAA,EAAG,EAAA,CAAG,IAAA,CAAK,OAAO,QAAQ,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA,EAAA,EACnD,GAAG,IAAA,CAAK,UAAA,GAAa,KAAK,IAAA,CAAK,KAAA,CAAM,GAAG,IAAA,CAAK,UAAA,GAAa,GAAG,CAAC,OAAO,EACvE,CAAA,EACE,YACI,CAAA,WAAA,EAAA,CAAA,CAAgB,EAAA,CAAG,KAAK,KAAA,GAAQ,EAAA,CAAG,IAAA,CAAK,OAAA,IAAW,KAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EACjE,cAAA,KAAmB,IACf,CAAA,QAAA,EAAA,CAAA,CAAQ,EAAA,CAAG,IAAA,CAAK,KAAA,GAAQ,GAAG,IAAA,CAAK,OAAA,IAAW,cAAA,GAAiB,GAAA,EAAM,QAAQ,CAAC,CAAC,CAAA,IAAA,EAAO,cAAc,MACjG,EACN,CAAA,CAAA,CAAA,GACA,EACN,CAAA,EAAG,SAAA,GAAY,eAAe,EAAE,CAAA,EAAG,UAAA,GAAa,aAAA,GAAgB,EAAE,CAAA,EAChE,cAAA,GAAiB,YAAY,WAAA,CAAY,KAAK,OAAO,EACvD,CAAA,EACE,QAAA,GACI,uEAAA,GACA,EACN,CAAA,EAAG,CAAC,YAAY,CAAC,SAAA,GAAY,uCAAuC,EAAE,CAAA,CAAA;AAEtE,MAAA;AAAA;AAAA;AAAA;AAAA,wBAIED,IAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,EAAA,EAAI,QAAQ,KAAK,CAAA,CAAA;AAAA,YACjB,iBAAA,EAAiB,KAAA;AAAA,YACjB,WAAW,aAAA,CAAc;AAAA,cACvB,QAAA;AAAA,cACA,QAAA;AAAA,cACA,UAAA;AAAA,cACA,SAAA;AAAA,cACA,UAAA;AAAA,cACA,SAAA;AAAA,cACA,gBAAA;AAAA,cACA,QAAA;AAAA,cACA,SAAA;AAAA,cACA,cAAA;AAAA,cACA,QAAQ,cAAA,KAAmB;AAAA,aAC5B,CAAA;AAAA,YACD,SAAS,CAAC,CAAA,KAAM,gBAAgB,EAAA,CAAG,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,YACjD,aAAA,EAAe,CAAC,CAAA,KAAM,qBAAA,CAAsB,OAAO,CAAC,CAAA;AAAA,YACpD,WAAA,EAAa,CAAC,CAAA,KAAM,mBAAA,CAAoB,OAAO,CAAC,CAAA;AAAA,YAChD,YAAA,EAAc,MAAM,oBAAA,CAAqB,KAAK,CAAA;AAAA,YAC9C,aAAA,EAAe,CAAC,CAAA,KAAM,qBAAA,CAAsB,OAAO,CAAC,CAAA;AAAA,YACpD,IAAA,EAAK,QAAA;AAAA,YACL,iBAAe,UAAA,IAAc,QAAA;AAAA,YAC7B,KAAA;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,gBAAA,IAAoB,SAAA,oBAAaC,GAAAA,CAAC,KAAA,EAAA,EAAM,MAAK,QAAA,EAAS,CAAA;AAAA,cACtD,kCACCD,IAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,uJAAA;AAAA,kBACV,KAAA,EAAO,CAAA,OAAA,EAAU,WAAA,CAAY,KAAK,CAAA,WAAA,CAAA;AAAA,kBAEjC,QAAA,EAAA;AAAA,oBAAA,WAAA,CAAY,KAAA;AAAA,oBAAM;AAAA;AAAA;AAAA,eACrB;AAAA,cAED,WAAA;AAAA,cAAY,GAAA;AAAA,cAAE,mBAAmB,SAAA,oBAAaC,GAAAA,CAAC,KAAA,EAAA,EAAM,MAAK,OAAA,EAAQ;AAAA;AAAA,WAAA;AAAA,UAlC9D,CAAA,EAAG,EAAA,CAAG,aAAa,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA;AAmCnC;AAAA,IAEJ,CAAA;AAEA,IAAA,MAAM,WAAA,GACJ,QAAA,IAAY,iBAAA,KAAsB,IAAA,IAAQ,SAAA,KAAc,IAAA;AAE1D,IAAA,uBACED,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,mBAAA,CAAoB,EAAE,WAAA,EAAa,WAAW,CAAA;AAAA,QAEzD,QAAA,EAAA;AAAA,0BAAAA,IAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,CAAA,4BAAA,EACT,WAAA,KAAgB,UAAA,GAAa,yBAAyB,UACxD,CAAA,CAAA;AAAA,cAqBA,QAAA,EAAA;AAAA,gCAAAC,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,CAAA,kDAAA,EACT,WAAA,KAAgB,UAAA,GACZ,qDACA,uCACN,CAAA,CAAA;AAAA,oBAEA,QAAA,kBAAAA,GAAAA;AAAA,sBAAC,WAAA;AAAA,sBAAA;AAAA,wBACC,GAAA,EAAK,SAAA;AAAA,wBACL,GAAA;AAAA,wBACA,IAAA;AAAA,wBACA,YAAA,EAAW,cAAA;AAAA,wBACX,YAAA,EAAc,gBAAA;AAAA,wBACd,OAAA,EAAS;AAAA;AAAA;AACX;AAAA,iBACF;AAAA,gCAGAD,IAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,CAAA,6BAAA,EAAgC,WAAA,KAAgB,UAAA,GAAa,aAAa,EAAE,CAAA,CAAA;AAAA,oBAGvF,QAAA,EAAA;AAAA,sCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6FAAA,EACb,QAAA,EAAA;AAAA,wCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACZ,QAAA,EAAA;AAAA,0BAAA,QAAA,oBACCC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qFAAoF,QAAA,EAAA,QAAA,EAEpG,CAAA;AAAA,0CAEFA,GAAAA;AAAA,4BAAC,OAAA;AAAA,4BAAA;AAAA,8BACC,SAAA,EAAU,+BAAA;AAAA,8BACV,OAAA,EAAQ,4BAAA;AAAA,8BACT,QAAA,EAAA;AAAA;AAAA,2BAED;AAAA,0CACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,QACb,QAAA,kBAAAA,GAAAA;AAAA,4BAAC,MAAA;AAAA,4BAAA;AAAA,8BACC,EAAA,EAAG,4BAAA;AAAA,8BACH,IAAA,EAAK,IAAA;AAAA,8BACL,OAAA,EAAS,eAAA,CAAgB,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,gCACvC,KAAA,EAAO,OAAO,KAAK,CAAA;AAAA,gCACnB,KAAA,EAAO,GAAG,KAAK,CAAA,CAAA;AAAA,+BACjB,CAAE,CAAA;AAAA,8BACF,KAAA,EAAO,OAAO,YAAY,CAAA;AAAA,8BAC1B,eAAe,CAAC,KAAA,KACd,eAAA,CAAgB,UAAA,CAAW,KAAK,CAAkB,CAAA;AAAA,8BAEpD,YAAA,EAAW;AAAA;AAAA,2BACb,EACF,CAAA;AAAA,0BACC,YAAA,CAAa,MAAA,GAAS,CAAA,oBACrBD,IAAAA;AAAA,4BAAC,MAAA;AAAA,4BAAA;AAAA,8BACC,SAAA,EAAU,+BAAA;AAAA,8BACV,KAAA,EAAO,CAAA,EAAG,YAAA,CAAa,MAAM,CAAA,wEAAA,CAAA;AAAA,8BAE5B,QAAA,EAAA;AAAA,gCAAA,YAAA,CAAa,MAAA;AAAA,gCAAO,SAAA;AAAA,gCACpB,YAAA,CAAa,MAAA,KAAW,CAAA,GAAI,GAAA,GAAM;AAAA;AAAA;AAAA,2BACrC;AAAA,0CAEFC,GAAAA;AAAA,4BAAC,MAAA;AAAA,4BAAA;AAAA,8BACC,OAAA,EAAQ,OAAA;AAAA,8BACR,IAAA,EAAK,IAAA;AAAA,8BACL,OAAA,EAAS,MAAM,kBAAA,CAAmB,IAAI,CAAA;AAAA,8BACtC,YAAA,EAAW,qBAAA;AAAA,8BACX,KAAA,EAAM,qBAAA;AAAA,8BACP,QAAA,EAAA;AAAA;AAAA,2BAED;AAAA,0BAKC,gCACCD,IAAAA;AAAA,4BAAC,MAAA;AAAA,4BAAA;AAAA,8BACC,OAAA,EAAQ,OAAA;AAAA,8BACR,IAAA,EAAK,IAAA;AAAA,8BACL,UAAU,CAAC,eAAA;AAAA,8BAGX,OAAA,EAAS,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,IAAA,GAAO,YAAA;AAAA,8BACvC,YAAA,EACE,SAAA,CAAU,MAAA,GAAS,CAAA,GACf,CAAA,MAAA,EAAS,SAAA,CAAU,MAAM,CAAA,WAAA,CAAA,GACzB,aAAA,IAAiB,eAAA,GACf,CAAA,MAAA,EAAS,eAAe,CAAA,CAAA,GACxB,MAAA;AAAA,8BAER,OACE,SAAA,CAAU,MAAA,GAAS,IACf,CAAA,sBAAA,EAAe,SAAA,CAAU,MAAM,CAAA,KAAA,EAAQ,SAAA,CAAU,WAAW,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,CAAA,GACxE,aAAA,GACE,kBACE,CAAA,+BAAA,EAAwB,eAAe,MACvC,gBAAA,GACF,iBAAA;AAAA,8BAET,QAAA,EAAA;AAAA,gCAAA,MAAA;AAAA,gCACM,UAAU,MAAA,GAAS,CAAA,GAAI,CAAA,EAAA,EAAK,SAAA,CAAU,MAAM,CAAA,CAAA,CAAA,GAAM,EAAA;AAAA,gCAAI,GAAA;AAAA,gDAC3DC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,QAAA,EAAA,SAAA,EAAE;AAAA;AAAA;AAAA,2BAC5C;AAAA,0BAED,gCACCD,IAAAA;AAAA,4BAAC,MAAA;AAAA,4BAAA;AAAA,8BACC,OAAA,EAAQ,OAAA;AAAA,8BACR,IAAA,EAAK,IAAA;AAAA,8BAGL,OAAA,EAAS,eAAe,IAAA,GAAO,MAAA;AAAA,8BAC/B,UAAU,CAAC,eAAA;AAAA,8BACX,cACE,CAAC,YAAA,IAAgB,WAAW,SAAA,GACxB,CAAA,MAAA,EAAS,SAAS,CAAA,CAAA,GAClB,MAAA;AAAA,8BAEN,KAAA,EACE,eACI,sBAAA,GACA,OAAA,IAAW,YACT,CAAA,wCAAA,EAA4B,SAAS,CAAA,CAAA,CAAA,GACrC,OAAA,GACE,sBAAA,GACA,iBAAA;AAAA,8BAEX,QAAA,EAAA;AAAA,gCAAA,OAAA;AAAA,gDACMC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,QAAA,EAAA,eAAA,EAAG;AAAA;AAAA;AAAA;AAClD,yBAAA,EAEJ,CAAA;AAAA,wCAEAD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uDAAA,EACb,QAAA,EAAA;AAAA,0CAAAC,GAAAA;AAAA,4BAAC,MAAA;AAAA,4BAAA;AAAA,8BACC,OAAA,EAAQ,OAAA;AAAA,8BACR,IAAA,EAAK,IAAA;AAAA,8BACL,SAAS,MAAM,kBAAA,CAAmB,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,8BAC3C,cAAA,EAAc,eAAA;AAAA,8BACd,YAAA,EAAW,aAAA;AAAA,8BACX,KAAA,EAAM,iDAAA;AAAA,8BACP,QAAA,EAAA;AAAA;AAAA,2BAED;AAAA,0CACAD,KAAC,MAAA,EAAA,EAAM,QAAA,EAAA;AAAA,4BAAA,KAAA,CAAM,eAAA;AAAA,4BAAgB;AAAA,2BAAA,EAAM,CAAA;AAAA,0CACnCA,IAAAA;AAAA,4BAAC,QAAA;AAAA,4BAAA;AAAA,8BACC,IAAA,EAAK,QAAA;AAAA,8BACL,SAAA,EAAU,yKAAA;AAAA,8BACV,OAAA,EAAS,MAAM,mBAAA,CAAoB,IAAI,CAAA;AAAA,8BACvC,OACE,KAAA,CAAM,kBAAA,GAAqB,IACvB,CAAA,sDAAA,EAAA,CAAqD,iBAAA,CAAkB,eAAe,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,OACtG,CAAA,iCAAA,EAAA,CAAqC,iBAAA,CAAkB,eAAe,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,uBAAA,CAAA;AAAA,8BAE5F,YAAA,EAAW,6BAAA;AAAA,8BAEV,QAAA,EAAA;AAAA,gCAAA,KAAA,CAAM,kBAAA;AAAA,gCAAmB;AAAA;AAAA;AAAA,2BAC5B;AAAA,0BAAA,CACE,KAAA,CAAM,gBAAA,GAAmB,CAAA,IACzB,KAAA,CAAM,mBAAA,GAAsB,sBAC5BA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,KAAA,CAAM,mBAAmB,KAAA,CAAM,mBAAA;AAAA,4BAAoB;AAAA,2BAAA,EACtD,CAAA;AAAA,0BAED,UAAA,CAAW,QAAA,oBACVA,IAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA;AAAA,4BAAA,UAAA,CAAW,QAAA,CAAS,MAAA;AAAA,4BAAO;AAAA,2BAAA,EAAS,CAAA;AAAA,0CAE7CC,GAAAA,CAAC,MAAA,EAAA,EAAM,UAAAI,eAAAA,CAAe,KAAA,CAAM,gBAAgB,CAAA,EAAE;AAAA,yBAAA,EAChD;AAAA,uBAAA,EACF,CAAA;AAAA,sBAGC,WAAA,oBACCL,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,+EAAA,EACb,QAAA,EAAA;AAAA,wCAAAA,IAAAA;AAAA,0BAAC,MAAA;AAAA,0BAAA;AAAA,4BACC,OAAA,EAAQ,OAAA;AAAA,4BACR,IAAA,EAAK,IAAA;AAAA,4BACL,OAAA,EAAS,MAAM,cAAA,CAAe,WAAW,CAAA;AAAA,4BACzC,KAAA,EAAM,4BAAA;AAAA,4BACP,QAAA,EAAA;AAAA,8BAAA,OAAA;AAAA,8CACMC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,QAAA,EAAA,QAAA,EAAC;AAAA;AAAA;AAAA,yBAChD;AAAA,wCACAD,IAAAA;AAAA,0BAAC,MAAA;AAAA,0BAAA;AAAA,4BACC,OAAA,EAAQ,OAAA;AAAA,4BACR,IAAA,EAAK,IAAA;AAAA,4BACL,OAAA,EAAS,kBAAA;AAAA,4BACT,KAAA,EAAM,4BAAA;AAAA,4BACP,QAAA,EAAA;AAAA,8BAAA,MAAA;AAAA,8CACKC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,QAAA,EAAA,QAAA,EAAC;AAAA;AAAA;AAAA,yBAC/C;AAAA,wCACAD,IAAAA;AAAA,0BAAC,MAAA;AAAA,0BAAA;AAAA,4BACC,OAAA,EAAQ,OAAA;AAAA,4BACR,IAAA,EAAK,IAAA;AAAA,4BACL,OAAA,EAAS,SAAA;AAAA,4BACT,KAAA,EAAM,yBAAA;AAAA,4BACP,QAAA,EAAA;AAAA,8BAAA,MAAA;AAAA,8CACKC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,QAAA,EAAA,SAAA,EAAE;AAAA;AAAA;AAAA,yBAChD;AAAA,wCACAD,IAAAA;AAAA,0BAAC,MAAA;AAAA,0BAAA;AAAA,4BACC,OAAA,EAAQ,OAAA;AAAA,4BACR,IAAA,EAAK,IAAA;AAAA,4BACL,OAAA,EAAS,WAAA;AAAA,4BACT,UAAU,CAAC,SAAA;AAAA,4BACX,KAAA,EAAM,iBAAA;AAAA,4BACP,QAAA,EAAA;AAAA,8BAAA,QAAA;AAAA,8CACOC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,QAAA,EAAA,SAAA,EAAE;AAAA;AAAA;AAAA;AAClD,uBAAA,EACF,CAAA;AAAA,sCAIFA,GAAAA;AAAA,wBAAC,KAAA;AAAA,wBAAA;AAAA,0BACC,GAAA,EAAK,UAAA;AAAA,0BACL,SAAA,EAAW,CAAA,gKAAA,EACT,SAAA,GAAY,aAAA,GAAgB,EAC9B,CAAA,CAAA;AAAA,0BACA,QAAA,EAAU,CAAA;AAAA,0BACV,SAAA,EAAW,aAAA;AAAA,0BACX,MAAA,EAAQ,UAAA;AAAA,0BACR,OAAA,EAAS,MAAM,YAAA,CAAa,IAAI,CAAA;AAAA,0BAChC,MAAA,EAAQ,MAAM,YAAA,CAAa,KAAK,CAAA;AAAA,0BAChC,SAAA,EAAW,aAAA;AAAA,0BACX,IAAA,EAAK,SAAA;AAAA,0BACL,YAAA,EAAW,kBAAA;AAAA,0BACX,uBAAA,EAAuB,QAAQ,WAAW,CAAA,CAAA;AAAA,0BAEzC,QAAA,EAAA,WAAA,CAAY,IAAI,UAAU;AAAA;AAAA;AAC7B;AAAA;AAAA;AACF;AAAA;AAAA,WACF;AAAA,UAEC,mCACCA,GAAAA;AAAA,YAAC,WAAA;AAAA,YAAA;AAAA,cACC,UAAA;AAAA,cACA,WAAA;AAAA,cACA,OAAA,EAAS,kBAAA;AAAA,cACT,OAAA,EAAS,MAAM,kBAAA,CAAmB,KAAK;AAAA;AAAA,WACzC;AAAA,0BAIFA,GAAAA;AAAA,YAAC,gBAAA;AAAA,YAAA;AAAA,cACC,MAAA,EAAQ,eAAA;AAAA,cACR,OAAA,EAAS,MAAM,kBAAA,CAAmB,KAAK,CAAA;AAAA,cACvC,OAAA,EAAS,aAAA;AAAA,cACT,gBAAgB,cAAA,CAAe,WAAA;AAAA,cAC/B,iBAAiB,cAAA,CAAe,SAAA;AAAA,cAChC,eAAe,cAAA,CAAe,aAAA;AAAA,cAC9B,mBAAmB,KAAA,CAAM;AAAA;AAAA,WAC3B;AAAA,0BAEAA,GAAAA;AAAA,YAAC,oBAAA;AAAA,YAAA;AAAA,cACC,MAAA,EAAQ,gBAAA;AAAA,cACR,OAAA,EAAS,MAAM,mBAAA,CAAoB,KAAK,CAAA;AAAA,cACxC,cAAc,iBAAA,CAAkB,YAAA;AAAA,cAChC,aAAa,iBAAA,CAAkB,WAAA;AAAA,cAC/B,OAAA,EAAS;AAAA;AAAA,WACX;AAAA,0BAEAA,GAAAA;AAAA,YAAC,eAAA;AAAA,YAAA;AAAA,cACC,QAAQ,eAAA,KAAoB,IAAA;AAAA,cAC5B,cACE,eAAA,KAAoB,IAAA,GACf,WAAA,CAAY,eAAe,KAAK,IAAA,GACjC,IAAA;AAAA,cAEN,OAAA,EAAS,eAAA;AAAA,cACT,MAAA,EAAQ,gBAAA;AAAA,cACR,cAAA,EAAgB,wBAAA;AAAA,cAChB,QAAA,EAAU;AAAA;AAAA,WACZ;AAAA,0BAEAA,GAAAA;AAAA,YAAC,eAAA;AAAA,YAAA;AAAA,cACC,QAAQ,kBAAA,KAAuB,IAAA;AAAA,cAC/B,QAAA,EAAU,iBAAA;AAAA,cACV,SAAA,EAAW,kBAAA;AAAA,cACX,aAAA,EACE,kBAAA,KAAuB,IAAA,GACnB,qBAAA,CAAsB,kBAAkB,CAAA,GACxC,MAAA;AAAA,cAEN,YAAA;AAAA,cACA,UAAA,EAAY,CAAC,KAAA,KAAU;AACrB,gBAAA,IAAI,uBAAuB,IAAA,EAAM;AAGjC,gBAAA,IAAI,SAAA,EAAW;AACb,kBAAA,gBAAA,CAAiB,SAAA,CAAU,KAAA,EAAO,SAAA,CAAU,GAAA,EAAK,KAAK,CAAA;AAAA,gBACxD,CAAA,MAAO;AACL,kBAAA,iBAAA,CAAkB,oBAAoB,KAAK,CAAA;AAAA,gBAC7C;AAAA,cACF,CAAA;AAAA,cACA,gBAAgB,MAAM;AACpB,gBAAA,IAAI,uBAAuB,IAAA,EAAM;AAC/B,kBAAA,iBAAA,CAAkB,kBAAkB,CAAA;AAAA,gBACtC;AAAA,cACF,CAAA;AAAA,cACA,SAAS,MAAM;AACb,gBAAA,qBAAA,CAAsB,IAAI,CAAA;AAC1B,gBAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA,cAC3B;AAAA;AAAA;AACF;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"chunk-LC7YHZXM.js","sourcesContent":["/**\n * FillerWordsModal — select filler words (and long silences) to mark deleted.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. Pure UI: match\n * counts/durations come in via props (see useTranscriptEdits.fillerAnalysis);\n * the selection is reported through onApply.\n */\n\nimport * as React from 'react';\nimport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalClose,\n ModalBody,\n ModalFooter,\n} from '../Modal';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\nimport { Checkbox } from '../Checkbox';\nimport { Select } from '../Select';\nimport { DEFAULT_FILLER_WORDS } from '../../hooks/useTranscriptEdits';\nimport type { SilenceThresholdCount } from '../../hooks/useTranscriptEdits';\n\nexport interface FillerWordsModalProps {\n isOpen: boolean;\n onClose: () => void;\n /** Apply removal: selected filler words + optional silence threshold (seconds) */\n onApply: (\n fillerWords: string[],\n removeSilenceAboveSec: number | null\n ) => void;\n /** Occurrence count per normalized word */\n matchingCounts: Map<string, number>;\n /** Total duration (ms) per filler word */\n fillerDurations: Map<string, number>;\n /** Count and total duration of silences at each threshold */\n silenceCounts: SilenceThresholdCount[];\n /** Current total edited duration in ms */\n currentDurationMs: number;\n}\n\nconst SILENCE_THRESHOLD_OPTIONS = [0.3, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0];\n\n/** Format duration in seconds or m:ss */\nfunction formatDuration(ms: number): string {\n const totalSeconds = Math.round(ms / 1000);\n if (totalSeconds < 90) {\n return `${totalSeconds}s`;\n }\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\n/** Modal for selecting filler words to remove from the edited transcript */\nexport const FillerWordsModal: React.FC<FillerWordsModalProps> = ({\n isOpen,\n onClose,\n onApply,\n matchingCounts,\n fillerDurations,\n silenceCounts,\n currentDurationMs,\n}) => {\n const [searchTerm, setSearchTerm] = React.useState('');\n const [selectedFillers, setSelectedFillers] = React.useState<Set<string>>(\n new Set(DEFAULT_FILLER_WORDS)\n );\n const [customWord, setCustomWord] = React.useState('');\n const [removeSilence, setRemoveSilence] = React.useState(false);\n const [silenceThreshold, setSilenceThreshold] = React.useState(0.4);\n\n // Filter filler words based on search, then sort by count (matches first)\n const filteredFillers = DEFAULT_FILLER_WORDS.filter((word) =>\n word.toLowerCase().includes(searchTerm.toLowerCase())\n ).sort((a, b) => {\n const countA = matchingCounts.get(a) || 0;\n const countB = matchingCounts.get(b) || 0;\n if (countB !== countA) return countB - countA;\n return a.localeCompare(b);\n });\n\n // Custom words that have been added, sorted by count\n const customFillers = Array.from(selectedFillers)\n .filter((word) => !DEFAULT_FILLER_WORDS.includes(word))\n .filter((word) => word.toLowerCase().includes(searchTerm.toLowerCase()))\n .sort((a, b) => {\n const countA = matchingCounts.get(a) || 0;\n const countB = matchingCounts.get(b) || 0;\n if (countB !== countA) return countB - countA;\n return a.localeCompare(b);\n });\n\n const toggleFiller = (word: string) => {\n setSelectedFillers((prev) => {\n const next = new Set(prev);\n if (next.has(word)) {\n next.delete(word);\n } else {\n next.add(word);\n }\n return next;\n });\n };\n\n const handleAddCustom = () => {\n const trimmed = customWord.trim().toLowerCase();\n if (trimmed && !selectedFillers.has(trimmed)) {\n setSelectedFillers((prev) => new Set([...prev, trimmed]));\n setCustomWord('');\n }\n };\n\n // Count and duration of silences that would be removed at the current threshold\n const silenceData = removeSilence\n ? silenceCounts.find((s) => s.threshold === silenceThreshold) || {\n count: 0,\n durationMs: 0,\n }\n : { count: 0, durationMs: 0 };\n const silenceRemovalCount = silenceData.count;\n const silenceDurationMs = silenceData.durationMs;\n\n const handleApply = () => {\n onApply(\n Array.from(selectedFillers),\n removeSilence ? silenceThreshold : null\n );\n onClose();\n };\n\n const selectAll = () => {\n setSelectedFillers(new Set([...DEFAULT_FILLER_WORDS, ...customFillers]));\n };\n\n const selectNone = () => {\n setSelectedFillers(new Set());\n };\n\n // Total matches (filler words + silences)\n const fillerMatches = Array.from(selectedFillers).reduce(\n (sum, word) => sum + (matchingCounts.get(word) || 0),\n 0\n );\n const totalMatches = fillerMatches + silenceRemovalCount;\n\n // Time saved from filler words + silences\n const fillerTimeSavedMs = Array.from(selectedFillers).reduce(\n (sum, word) => sum + (fillerDurations.get(word) || 0),\n 0\n );\n const totalTimeSavedMs = fillerTimeSavedMs + silenceDurationMs;\n const newDurationMs = currentDurationMs - totalTimeSavedMs;\n\n const renderFillerItem = (word: string, isCustom: boolean) => {\n const count = matchingCounts.get(word) || 0;\n return (\n <label\n key={word}\n className=\"hover:bg-muted flex cursor-pointer items-center gap-2 rounded-md px-1.5 py-1 text-sm transition-colors\"\n >\n <Checkbox\n size=\"sm\"\n checked={selectedFillers.has(word)}\n onChange={() => toggleFiller(word)}\n aria-label={`Remove \"${word}\"`}\n />\n <span className=\"text-foreground min-w-0 flex-1 truncate\">{word}</span>\n {count > 0 && (\n <span className=\"text-muted-foreground text-xs\">({count})</span>\n )}\n {isCustom && (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:ring-ring rounded px-1 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n onClick={(e) => {\n e.preventDefault();\n setSelectedFillers((prev) => {\n const next = new Set(prev);\n next.delete(word);\n return next;\n });\n }}\n aria-label={`Remove ${word}`}\n >\n ×\n </button>\n )}\n </label>\n );\n };\n\n return (\n <Modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n size=\"lg\"\n >\n <ModalHeader>\n <ModalTitle>Remove Filler Words</ModalTitle>\n <ModalClose aria-label=\"Close modal\" />\n </ModalHeader>\n\n <ModalBody className=\"flex flex-col gap-3\">\n <Input\n size=\"sm\"\n type=\"text\"\n placeholder=\"Search filler words...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n aria-label=\"Search filler words\"\n />\n\n <div className=\"flex items-center gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={selectAll}>\n Select All\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={selectNone}>\n Select None\n </Button>\n </div>\n\n <div className=\"border-border bg-muted/40 flex flex-wrap items-center gap-2 rounded-lg border px-3 py-2\">\n <Checkbox\n size=\"sm\"\n label=\"Remove silences greater than\"\n checked={removeSilence}\n onChange={(e) => setRemoveSilence(e.target.checked)}\n />\n <div className=\"w-24\">\n <Select\n size=\"sm\"\n options={SILENCE_THRESHOLD_OPTIONS.map((t) => ({\n value: String(t),\n label: `${t}s`,\n }))}\n value={String(silenceThreshold)}\n onValueChange={(value) => setSilenceThreshold(parseFloat(value))}\n disabled={!removeSilence}\n aria-label=\"Silence threshold in seconds\"\n />\n </div>\n {removeSilence && silenceRemovalCount > 0 && (\n <span className=\"text-muted-foreground text-xs\">\n ({silenceRemovalCount} silences)\n </span>\n )}\n </div>\n\n <div className=\"border-border grid max-h-56 grid-cols-2 gap-x-3 gap-y-0.5 overflow-y-auto rounded-lg border p-2 sm:grid-cols-3\">\n {filteredFillers.map((word) => renderFillerItem(word, false))}\n {customFillers.map((word) => renderFillerItem(word, true))}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <Input\n size=\"sm\"\n type=\"text\"\n placeholder=\"Add custom filler word...\"\n value={customWord}\n onChange={(e) => setCustomWord(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddCustom();\n }\n }}\n aria-label=\"Add custom filler word\"\n />\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleAddCustom}\n disabled={!customWord.trim()}\n >\n Add\n </Button>\n </div>\n </ModalBody>\n\n <ModalFooter className=\"justify-between\">\n <span className=\"text-muted-foreground text-sm\">\n {totalMatches} items • saves {formatDuration(totalTimeSavedMs)} →{' '}\n {formatDuration(newDurationMs)}\n </span>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancel\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={handleApply}\n disabled={totalMatches === 0}\n >\n Mark as Deleted ({totalMatches})\n </Button>\n </div>\n </ModalFooter>\n </Modal>\n );\n};\n\nFillerWordsModal.displayName = 'FillerWordsModal';\n","/**\n * WordEditorModal — edit a word's text or split a silence into segments.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. For silences,\n * space-separated durations (e.g. \"1 1 4 1\") split the silence; the\n * remainder becomes the final segment.\n */\n\nimport * as React from 'react';\nimport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalClose,\n ModalBody,\n ModalFooter,\n} from '../Modal';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\nimport { isSilenceType } from '../TranscriptView/transcript';\nimport type { EditableWord } from '../TranscriptView/transcript';\n\nexport interface WordEditorModalProps {\n isOpen: boolean;\n editableWord: EditableWord | null;\n onClose: () => void;\n /** Save a new text for the word */\n onSave: (newText: string) => void;\n /** Split a silence into segments with the given durations (seconds) */\n onSplitSilence: (durations: number[]) => void;\n /** Toggle the word's deleted state */\n onDelete: () => void;\n}\n\ninterface SilenceSplitResult {\n durations: number[];\n remainder: number;\n error?: string;\n}\n\n/**\n * Modal for editing a word or splitting a silence.\n * For silences, enter space-separated durations (e.g., \"1 1 4 1\") to split.\n */\nexport const WordEditorModal: React.FC<WordEditorModalProps> = ({\n isOpen,\n editableWord,\n onClose,\n onSave,\n onSplitSilence,\n onDelete,\n}) => {\n const [inputValue, setInputValue] = React.useState('');\n const [error, setError] = React.useState<string | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n const isSilence = isSilenceType(editableWord?.word.wordType);\n const durationMs = editableWord\n ? editableWord.word.endMs - editableWord.word.startMs\n : 0;\n const durationSec = durationMs / 1000;\n\n // Reset input when the modal opens\n React.useEffect(() => {\n if (isOpen && editableWord) {\n if (isSilence) {\n setInputValue('');\n } else {\n setInputValue(editableWord.word.text);\n }\n setError(null);\n // Focus input after a short delay so it wins over the modal's focus trap\n setTimeout(() => inputRef.current?.focus(), 50);\n }\n }, [isOpen, editableWord, isSilence]);\n\n // Parse silence split input (pure function, no side effects)\n const parseSilenceSplit = (input: string): SilenceSplitResult | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n const parts = trimmed.split(/\\s+/);\n const durations: number[] = [];\n let total = 0;\n\n for (const part of parts) {\n const num = parseFloat(part);\n if (isNaN(num) || num <= 0) {\n return {\n durations: [],\n remainder: 0,\n error: `Invalid number: \"${part}\"`,\n };\n }\n durations.push(num);\n total += num;\n }\n\n if (total >= durationSec) {\n return {\n durations: [],\n remainder: 0,\n error: `Total (${total.toFixed(1)}s) exceeds silence duration (${durationSec.toFixed(1)}s)`,\n };\n }\n\n const remainder = durationSec - total;\n return { durations, remainder };\n };\n\n const handleApply = () => {\n if (isSilence) {\n const parsed = parseSilenceSplit(inputValue);\n if (parsed?.error) {\n setError(parsed.error);\n return;\n }\n if (parsed && parsed.durations.length > 0) {\n // Add the remainder as the final segment\n const allDurations = [...parsed.durations, parsed.remainder];\n onSplitSilence(allDurations);\n onClose();\n }\n } else {\n const trimmed = inputValue.trim();\n if (trimmed && trimmed !== editableWord?.word.text) {\n onSave(trimmed);\n }\n onClose();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleApply();\n }\n };\n\n // Preview for silence splitting\n const preview = isSilence ? parseSilenceSplit(inputValue) : null;\n\n const applyDisabled = isSilence\n ? !inputValue.trim() ||\n !!preview?.error ||\n !preview ||\n preview.durations.length === 0\n : !inputValue.trim();\n\n return (\n <Modal\n open={isOpen && editableWord !== null}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n size=\"md\"\n >\n <ModalHeader>\n <ModalTitle>{isSilence ? 'Split Silence' : 'Edit Word'}</ModalTitle>\n <ModalClose aria-label=\"Close editor\" />\n </ModalHeader>\n\n <ModalBody className=\"flex flex-col gap-2\">\n {isSilence ? (\n <>\n <p className=\"text-foreground m-0 text-sm\">\n Silence duration:{' '}\n <strong className=\"font-semibold\">\n {durationSec.toFixed(1)}s\n </strong>\n </p>\n <p className=\"text-muted-foreground m-0 text-xs\">\n Enter space-separated durations to split (e.g., &quot;1 1 4\n 1&quot;)\n </p>\n <Input\n ref={inputRef}\n type=\"text\"\n value={inputValue}\n onChange={(e) => {\n setInputValue(e.target.value);\n setError(null);\n }}\n onKeyDown={handleKeyDown}\n placeholder=\"1 2 3...\"\n aria-label=\"Split durations\"\n />\n {error && (\n <p className=\"text-destructive m-0 text-sm\" role=\"alert\">\n {error}\n </p>\n )}\n {preview &&\n !preview.error &&\n preview.durations.length > 0 &&\n !error && (\n <p className=\"text-muted-foreground m-0 text-sm\">\n Preview:{' '}\n {[...preview.durations, preview.remainder]\n .map((d) => `[${d.toFixed(1)}s]`)\n .join(' ')}\n </p>\n )}\n {preview?.error && !error && (\n <p className=\"text-destructive m-0 text-sm\" role=\"alert\">\n {preview.error}\n </p>\n )}\n </>\n ) : (\n <>\n <p className=\"text-foreground m-0 text-sm\">Edit the word text:</p>\n <Input\n ref={inputRef}\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={handleKeyDown}\n aria-label=\"Word text\"\n />\n </>\n )}\n </ModalBody>\n\n <ModalFooter className=\"justify-between\">\n <Button\n variant={editableWord?.deleted ? 'secondary' : 'danger'}\n size=\"sm\"\n onClick={onDelete}\n >\n {editableWord?.deleted ? 'Restore' : 'Delete'}\n </Button>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancel\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={handleApply}\n disabled={applyDisabled}\n >\n {isSilence ? 'Split' : 'Save'}\n </Button>\n </div>\n </ModalFooter>\n </Modal>\n );\n};\n\nWordEditorModal.displayName = 'WordEditorModal';\n","/**\n * SilenceSettingsModal — configure silence detection thresholds.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. The paragraph\n * break threshold is clamped to be >= the minimum silence duration.\n */\n\nimport * as React from 'react';\nimport {\n Modal,\n ModalHeader,\n ModalTitle,\n ModalClose,\n ModalBody,\n ModalFooter,\n} from '../Modal';\nimport { Button } from '../Button';\nimport { Slider } from '../Slider';\n\nexport interface SilenceSettingsModalProps {\n isOpen: boolean;\n onClose: () => void;\n /** Current minimum silence duration (ms) */\n minSilenceMs: number;\n /** Current paragraph break threshold (ms) */\n nlSilenceMs: number;\n /** Apply new thresholds (both in ms) */\n onApply: (minSilenceMs: number, nlSilenceMs: number) => void;\n}\n\n/** Modal for configuring silence detection settings */\nexport const SilenceSettingsModal: React.FC<SilenceSettingsModalProps> = ({\n isOpen,\n onClose,\n minSilenceMs,\n nlSilenceMs,\n onApply,\n}) => {\n const [threshold, setThreshold] = React.useState(minSilenceMs / 1000);\n const [nlThreshold, setNlThreshold] = React.useState(nlSilenceMs / 1000);\n\n // Reset when the modal opens\n React.useEffect(() => {\n if (isOpen) {\n setThreshold(minSilenceMs / 1000);\n setNlThreshold(nlSilenceMs / 1000);\n }\n }, [isOpen, minSilenceMs, nlSilenceMs]);\n\n const handleApply = () => {\n // Ensure nlThreshold is always >= threshold\n const finalNlThreshold = Math.max(nlThreshold, threshold);\n onApply(Math.round(threshold * 1000), Math.round(finalNlThreshold * 1000));\n onClose();\n };\n\n // Auto-adjust newline threshold if it would be less than the min threshold\n const handleThresholdChange = (value: number) => {\n setThreshold(value);\n if (nlThreshold < value) {\n setNlThreshold(value);\n }\n };\n\n const formatSeconds = (v: number) => `${v.toFixed(1)}s`;\n\n return (\n <Modal\n open={isOpen}\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n size=\"md\"\n >\n <ModalHeader>\n <ModalTitle>Silence Settings</ModalTitle>\n <ModalClose aria-label=\"Close modal\" />\n </ModalHeader>\n\n <ModalBody className=\"flex flex-col gap-6\">\n <div className=\"flex flex-col gap-1\">\n <Slider\n label=\"Minimum silence duration\"\n min={0.1}\n max={2}\n step={0.1}\n value={threshold}\n onValueChange={handleThresholdChange}\n showValue\n formatValue={formatSeconds}\n aria-label=\"Minimum silence duration\"\n />\n <p className=\"text-muted-foreground m-0 text-xs\">\n Gaps shorter than this will not be shown as silences.\n </p>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Slider\n label=\"Paragraph break threshold\"\n min={threshold}\n max={5}\n step={0.1}\n value={nlThreshold}\n onValueChange={setNlThreshold}\n showValue\n formatValue={formatSeconds}\n aria-label=\"Paragraph break threshold\"\n />\n <p className=\"text-muted-foreground m-0 text-xs\">\n Silences longer than this will create paragraph breaks.\n </p>\n </div>\n </ModalBody>\n\n <ModalFooter>\n <Button variant=\"secondary\" size=\"sm\" onClick={onClose}>\n Cancel\n </Button>\n <Button variant=\"primary\" size=\"sm\" onClick={handleApply}>\n Apply\n </Button>\n </ModalFooter>\n </Modal>\n );\n};\n\nSilenceSettingsModal.displayName = 'SilenceSettingsModal';\n","/**\n * SpeedMarkerMenu — context-menu popup for setting per-word speed markers.\n *\n * Ported from pulseclip's TranscriptViewer for @mieweb/ui. Hand-built (plain\n * elements + tokens): a positioned context menu has no @mieweb/ui primitive.\n */\n\nimport * as React from 'react';\nimport type { PlaybackSpeed, SpeedMarker } from '../TranscriptView/transcript';\nimport { PLAYBACK_SPEEDS } from '../TranscriptView/transcript';\n\nexport interface SpeedMarkerMenuProps {\n isOpen: boolean;\n /** Viewport coordinates for the menu (already clamped by the caller) */\n position: { x: number; y: number } | null;\n /** The edited-word index the menu applies to */\n wordIndex: number | null;\n /** Existing marker at that word, if any */\n currentMarker: SpeedMarker | undefined;\n defaultSpeed: PlaybackSpeed;\n onSetSpeed: (speed: PlaybackSpeed) => void;\n onRemoveMarker: () => void;\n onClose: () => void;\n}\n\n/** Popup menu for setting speed markers on a word */\nexport const SpeedMarkerMenu: React.FC<SpeedMarkerMenuProps> = ({\n isOpen,\n position,\n currentMarker,\n defaultSpeed,\n onSetSpeed,\n onRemoveMarker,\n onClose,\n}) => {\n const menuRef = React.useRef<HTMLDivElement>(null);\n\n // Close on escape or click outside\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n const handleClickOutside = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n onClose();\n }\n };\n if (isOpen) {\n document.addEventListener('keydown', handleKeyDown);\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }\n }, [isOpen, onClose]);\n\n if (!isOpen || !position) return null;\n\n return (\n <div\n ref={menuRef}\n className=\"border-border bg-card text-card-foreground fixed z-50 min-w-36 overflow-hidden rounded-lg border shadow-lg\"\n style={{ left: position.x, top: position.y }}\n role=\"menu\"\n aria-label=\"Set speed marker\"\n >\n <div className=\"border-border text-muted-foreground border-b px-3 py-1.5 text-xs font-semibold\">\n Set Speed Marker\n </div>\n <div className=\"flex flex-col p-1\">\n {PLAYBACK_SPEEDS.map((speed) => {\n const isActive = currentMarker?.speed === speed;\n const isDefault = speed === defaultSpeed && !currentMarker;\n return (\n <button\n key={speed}\n type=\"button\"\n className={`focus-visible:ring-ring flex items-center justify-between gap-2 rounded-md px-2.5 py-1 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive\n ? 'bg-primary-600 font-medium text-white'\n : 'text-foreground hover:bg-muted'\n }`}\n onClick={() => {\n onSetSpeed(speed);\n onClose();\n }}\n role=\"menuitem\"\n >\n {speed}x\n {isDefault && (\n <span className=\"text-muted-foreground text-xs\">default</span>\n )}\n </button>\n );\n })}\n </div>\n {currentMarker && (\n <button\n type=\"button\"\n className=\"border-border text-destructive hover:bg-destructive/10 focus-visible:ring-ring w-full border-t px-2.5 py-1.5 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => {\n onRemoveMarker();\n onClose();\n }}\n role=\"menuitem\"\n >\n Remove Marker\n </button>\n )}\n </div>\n );\n};\n\nSpeedMarkerMenu.displayName = 'SpeedMarkerMenu';\n","/**\n * ScriptPanel — the transcript \"script\" as editable YAML/JSON, side by side\n * with the editor.\n *\n * Two sources: \"Editor\" is the live edit state (EditableWord[], remapped as\n * you edit) and can be edited as text and applied back; \"Original\" is the\n * canonical transcript (immutable, read-only). The panel live-follows the\n * editor until you start typing; Apply parses + validates and replaces the\n * edit state (undo-safe via useTranscriptEdits.replaceEditedWords).\n *\n * js-yaml is loaded lazily on first use (same pattern as Markdown's\n * SurveyBlock) so it stays out of the MediaEditor bundle.\n */\n\nimport * as React from 'react';\nimport { Button } from '../Button';\nimport type {\n Transcript,\n EditableWord,\n TranscriptWord,\n} from '../TranscriptView/transcript';\n\nlet yamlPromise: Promise<typeof import('js-yaml')> | null = null;\nfunction loadYaml() {\n yamlPromise ??= import(/* @vite-ignore */ 'js-yaml');\n return yamlPromise;\n}\n\nexport interface ScriptPanelProps {\n /** The canonical transcript (read-only source) */\n transcript: Transcript;\n /** The live edit state (editable source) */\n editedWords: EditableWord[];\n /** Apply parsed script back into the editor */\n onApply: (words: EditableWord[]) => void;\n /** Close the panel */\n onClose: () => void;\n className?: string;\n}\n\ntype ScriptSource = 'editor' | 'original';\ntype ScriptFormat = 'yaml' | 'json';\n\n/** Parse + validate script text into EditableWord[]; throws with a readable message. */\nasync function parseScript(\n text: string,\n format: ScriptFormat\n): Promise<EditableWord[]> {\n let data: unknown;\n if (format === 'json') {\n data = JSON.parse(text);\n } else {\n const yaml = await loadYaml();\n data = yaml.load(text);\n }\n if (!Array.isArray(data)) {\n throw new Error('Script must be a list of word entries.');\n }\n return data.map((raw, i) => {\n const ew = raw as {\n originalIndex?: unknown;\n deleted?: unknown;\n inserted?: unknown;\n word?: Record<string, unknown>;\n };\n const w = ew.word;\n if (\n !w ||\n typeof w.text !== 'string' ||\n typeof w.startMs !== 'number' ||\n typeof w.endMs !== 'number'\n ) {\n throw new Error(\n `Entry ${i + 1}: each entry needs word.text, word.startMs and word.endMs.`\n );\n }\n if (\n w.wordType !== undefined &&\n w.wordType !== 'word' &&\n w.wordType !== 'silence' &&\n w.wordType !== 'silence-newline'\n ) {\n throw new Error(\n `Entry ${i + 1}: wordType must be 'word', 'silence' or 'silence-newline'.`\n );\n }\n const word: TranscriptWord = {\n text: w.text,\n startMs: w.startMs,\n endMs: w.endMs,\n ...(typeof w.wordType === 'string'\n ? { wordType: w.wordType as TranscriptWord['wordType'] }\n : {}),\n ...(typeof w.speakerId === 'string' ? { speakerId: w.speakerId } : {}),\n };\n return {\n originalIndex:\n typeof ew.originalIndex === 'number' ? ew.originalIndex : -1,\n deleted: Boolean(ew.deleted),\n ...(ew.inserted !== undefined ? { inserted: Boolean(ew.inserted) } : {}),\n word,\n } as EditableWord;\n });\n}\n\nexport const ScriptPanel: React.FC<ScriptPanelProps> = ({\n transcript,\n editedWords,\n onApply,\n onClose,\n className,\n}) => {\n const [source, setSource] = React.useState<ScriptSource>('editor');\n const [format, setFormat] = React.useState<ScriptFormat>('yaml');\n const [text, setText] = React.useState('');\n const [dirty, setDirty] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const readOnly = source === 'original';\n\n // Live-follow the selected source until the user starts editing.\n React.useEffect(() => {\n if (dirty) return;\n let cancelled = false;\n const data = source === 'original' ? transcript : editedWords;\n (async () => {\n const serialized =\n format === 'json'\n ? JSON.stringify(data, null, 2)\n : (await loadYaml()).dump(data, { lineWidth: 120 });\n if (!cancelled) {\n setText(serialized);\n setError(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [source, format, transcript, editedWords, dirty]);\n\n const handleApply = async () => {\n try {\n const words = await parseScript(text, format);\n onApply(words);\n setDirty(false);\n setError(null);\n } catch (err) {\n setError(\n err instanceof Error ? err.message : 'Could not parse the script.'\n );\n }\n };\n\n const handleReset = () => {\n setDirty(false);\n setError(null);\n };\n\n const sourceButton = (value: ScriptSource, label: string) => (\n <button\n type=\"button\"\n onClick={() => {\n setSource(value);\n setDirty(false);\n setError(null);\n }}\n aria-pressed={source === value}\n className={`focus-visible:ring-ring rounded px-1.5 py-0.5 text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n source === value\n ? 'bg-primary-800 font-medium text-white'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground'\n }`}\n >\n {label}\n </button>\n );\n\n return (\n <aside\n className={`border-border bg-card flex w-80 shrink-0 flex-col border-l lg:w-96 ${className ?? ''}`}\n aria-label=\"Transcript script\"\n >\n <div className=\"border-border flex shrink-0 flex-wrap items-center gap-1.5 border-b px-3 py-2\">\n <span className=\"text-foreground text-xs font-semibold\">Script</span>\n <span className=\"bg-border mx-1 h-4 w-px\" aria-hidden=\"true\" />\n {sourceButton('editor', 'Editor')}\n {sourceButton('original', 'Original')}\n <span className=\"bg-border mx-1 h-4 w-px\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n onClick={() => {\n setFormat(format === 'yaml' ? 'json' : 'yaml');\n setDirty(false);\n setError(null);\n }}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:ring-ring rounded px-1.5 py-0.5 text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n title=\"Toggle YAML / JSON\"\n >\n {format.toUpperCase()}\n </button>\n <span className=\"text-muted-foreground ml-auto text-[10px]\">\n {readOnly ? 'read-only' : dirty ? 'edited' : 'live'}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClose}\n aria-label=\"Close script panel\"\n >\n ✕\n </Button>\n </div>\n\n <textarea\n value={text}\n readOnly={readOnly}\n spellCheck={false}\n onChange={(e) => {\n setText(e.target.value);\n setDirty(true);\n }}\n className=\"text-foreground min-h-0 flex-1 resize-none bg-transparent p-3 font-mono text-xs leading-relaxed focus:outline-none\"\n aria-label={`Script source (${source}, ${format.toUpperCase()})`}\n />\n\n {error && (\n <p\n className=\"border-border text-destructive m-0 shrink-0 border-t px-3 py-2 text-xs\"\n role=\"alert\"\n >\n {error}\n </p>\n )}\n\n {!readOnly && (\n <div className=\"border-border flex shrink-0 items-center gap-2 border-t px-3 py-2\">\n <Button size=\"sm\" onClick={handleApply} disabled={!dirty}>\n Apply\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleReset}\n disabled={!dirty}\n title=\"Throw away unapplied typing and re-sync from the editor\"\n >\n Discard\n </Button>\n <span className=\"text-muted-foreground text-[10px]\">\n Apply pushes into the editor &mdash; revert an applied change with\n Undo\n </span>\n </div>\n )}\n </aside>\n );\n};\n","/**\n * MediaEditor — media playback + editable word-level transcript.\n *\n * Composition of MediaPlayer (imperative MediaPlayerRef) and an editable\n * word-mode transcript, with all edit state held by useTranscriptEdits.\n * Ported from pulseclip's TranscriptViewer; UI-only state (cursor,\n * selection, modals, sequence-playback bookkeeping) lives here.\n *\n * Controlled + persistence-agnostic: edits flow out via\n * onEditorStateChange / onEditedWordsRender and back in via\n * initialEditedWords / initialUndoStack. Timestamps in ms.\n */\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Button } from '../Button';\nimport { Select } from '../Select';\nimport type {\n Transcript,\n TranscriptWord,\n EditableWord,\n PlaybackSegment,\n PlaybackSpeed,\n SpeedMarker,\n} from '../TranscriptView/transcript';\nimport { PLAYBACK_SPEEDS, isSilenceType } from '../TranscriptView/transcript';\nimport { useTranscriptEdits } from '../../hooks/useTranscriptEdits';\nimport {\n MediaPlayer,\n type MediaPlayerRef,\n type MediaKind,\n} from '../MediaPlayer/MediaPlayer';\nimport { FillerWordsModal } from './FillerWordsModal';\nimport { WordEditorModal } from './WordEditorModal';\nimport { SilenceSettingsModal } from './SilenceSettingsModal';\nimport { SpeedMarkerMenu } from './SpeedMarkerMenu';\nimport { ScriptPanel } from './ScriptPanel';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport interface MediaEditorProps extends VariantProps<\n typeof mediaEditorVariants\n> {\n /** Media URL */\n src: string;\n /** Force the media kind; inferred from the src extension when omitted */\n kind?: MediaKind;\n /** The source transcript (canonical, immutable) */\n transcript: Transcript;\n /** Initial edited words (from saved edits) */\n initialEditedWords?: EditableWord[];\n /** Initial undo stack (from saved edits) */\n initialUndoStack?: EditableWord[][];\n /** Initial speed markers (from saved edits) */\n initialSpeedMarkers?: SpeedMarker[];\n /** Initial default playback speed (from saved edits) */\n initialDefaultSpeed?: PlaybackSpeed;\n /**\n * Fired when speed markers or the default speed change (including once on\n * mount with the initial values) — lets the host persist and bake speed\n * into exports alongside the edit list.\n */\n onSpeedStateChange?: (\n speedMarkers: SpeedMarker[],\n defaultSpeed: PlaybackSpeed\n ) => void;\n /** Fired after every edit mutation (for persistence) */\n onEditorStateChange?: (\n editedWords: EditableWord[],\n undoStack: EditableWord[][]\n ) => void;\n /** Fired when the hasEdits flag changes */\n onHasEditsChange?: (hasEdits: boolean) => void;\n /** Fired when the cursor moves (start time of the cursor word in ms, or null) */\n onCursorTimestampChange?: (timestampMs: number | null) => void;\n /** Fired whenever the edited words change — lets the host build raw-data views */\n onEditedWordsRender?: (editedWords: EditableWord[]) => void;\n /**\n * Undo beyond the editor's own history.\n *\n * The editor's undo is word-level, which is the right grain for typing and\n * the wrong one for a host that also versions the document — undoing a batch\n * change one word at a time is not undoing it. When a host provides this, the\n * Undo control stays available once the editor's own stack is empty and hands\n * over instead of going dead, so there is one Undo rather than two.\n */\n onUndoBeyond?: () => void;\n /** Whether the host has anything left to undo. Keeps Undo live at depth 0. */\n canUndoBeyond?: boolean;\n /** What `onUndoBeyond` would undo, for the tooltip (e.g. a version name). */\n undoBeyondLabel?: string;\n /**\n * Redo beyond the editor's own history — the counterpart to `onUndoBeyond`.\n * The editor redoes its own word-level steps first and only calls this once\n * they are exhausted, so the pair walks the same states in both directions.\n */\n onRedo?: () => void;\n canRedo?: boolean;\n /** What `onRedo` would redo, for the tooltip. */\n redoLabel?: string;\n /** Optional ref to the internal MediaPlayer (host escape hatch, e.g. thumbnail capture) */\n playerRef?: React.Ref<MediaPlayerRef>;\n /** Additional class name */\n className?: string;\n /**\n * 'horizontal' (default): media stacked above the transcript.\n * 'vertical': media and transcript side by side.\n */\n splitLayout?: 'horizontal' | 'vertical';\n}\n\ninterface SelectionRange {\n start: number;\n end: number;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst mediaEditorVariants = cva(\n // Root is always a row so the ScriptPanel can dock on the right; the\n // media/transcript split direction lives on the inner wrapper below.\n 'flex h-full min-h-0 w-full overflow-hidden rounded-xl border border-border bg-card text-card-foreground',\n {\n variants: {\n splitLayout: {\n horizontal: '',\n vertical: '',\n },\n },\n defaultVariants: {\n splitLayout: 'horizontal',\n },\n }\n);\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Bring a word into view WITHIN the transcript, never by moving the page.\n *\n * `Element.scrollIntoView` walks up to the nearest scrolling ancestor. Above\n * the md breakpoint that is the transcript's own box and the behaviour is\n * right. Below it the editor grows to its content instead of scrolling\n * internally, so the nearest scrolling ancestor is the DOCUMENT — following\n * the active word dragged the whole page down, taking the player and its\n * controls off screen a word at a time, and any attempt to scroll back was\n * undone by the next word.\n *\n * Scrolling the container directly cannot escape it. The clamped-both-ways\n * arithmetic reproduces `block: 'nearest'`, so behaviour above the breakpoint\n * is unchanged.\n */\nfunction scrollWordIntoTranscript(\n container: HTMLElement | null,\n wordIndex: number\n): void {\n if (!container) return;\n // Not its own scrolling box (the small-screen layout) — nothing to scroll,\n // and anything we did here would move the page instead.\n if (container.scrollHeight <= container.clientHeight) return;\n\n const el = container.querySelector(`[data-word-index=\"${wordIndex}\"]`);\n if (!el) return;\n\n const containerBox = container.getBoundingClientRect();\n const wordBox = el.getBoundingClientRect();\n\n const above = wordBox.top - containerBox.top;\n const below = wordBox.bottom - containerBox.bottom;\n // Already fully visible: `nearest` scrolls nothing.\n const delta = above < 0 ? above : below > 0 ? below : 0;\n if (delta === 0) return;\n\n container.scrollTo({\n top: container.scrollTop + delta,\n behavior: 'smooth',\n });\n}\n\n/** Format duration: seconds only if <90s, min:sec if <60min, h:mm:ss otherwise */\nfunction formatDuration(ms: number): string {\n const totalSeconds = Math.round(ms / 1000);\n if (totalSeconds < 90) {\n return `${totalSeconds}s`;\n }\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;\n }\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\ninterface WordVisualState {\n isActive: boolean;\n isCursor: boolean;\n isSelected: boolean;\n isDeleted: boolean;\n isInserted: boolean;\n isSilence: boolean;\n isSilenceNewline: boolean;\n isAnchor: boolean;\n isFocused: boolean;\n hasSpeedMarker: boolean;\n /** Word plays at a speed differing from the default — the whole region is marked */\n isSped: boolean;\n}\n\n/**\n * Tailwind classes for one transcript word. Background/color states are\n * mutually exclusive (precedence: anchor > active > selected > deleted >\n * inserted > silence) so token utilities never conflict.\n */\nfunction wordClassName(s: WordVisualState): string {\n const parts = [\n 'relative cursor-pointer rounded-sm px-1 py-0.5 transition-colors duration-150',\n ];\n\n if (s.isSilence) {\n parts.push('text-xs font-medium italic tracking-wide');\n }\n if (s.isSilenceNewline) {\n parts.push('mt-1.5 block w-fit');\n }\n\n if (s.isAnchor) {\n parts.push('bg-warning/40 outline outline-2 outline-warning');\n } else if (s.isActive) {\n parts.push('bg-primary-800 font-medium text-white');\n } else if (s.isSelected && s.isFocused) {\n parts.push('bg-primary-500/40');\n } else if (s.isDeleted) {\n parts.push(\n 'bg-destructive/10 text-destructive line-through opacity-40 hover:bg-destructive/20 hover:opacity-70'\n );\n } else if (s.isInserted) {\n parts.push('bg-success/15 text-success hover:bg-success/25');\n } else if (s.isSilenceNewline) {\n parts.push('text-primary-500 hover:bg-primary-500/15');\n } else if (s.isSilence) {\n parts.push(\n 'border border-dashed border-border bg-muted text-muted-foreground hover:bg-muted/70'\n );\n } else {\n parts.push('hover:bg-primary-500/30');\n }\n\n // Keep the strikethrough visible when a deleted word is also active/selected/anchored\n if (\n s.isDeleted &&\n (s.isActive || (s.isSelected && s.isFocused) || s.isAnchor)\n ) {\n parts.push('line-through opacity-60');\n }\n\n // Cursor outline only when the transcript has focus (source behavior)\n if (s.isCursor && s.isFocused && !s.isAnchor) {\n if (s.isDeleted) {\n parts.push('outline outline-2 outline-offset-1 outline-destructive');\n } else if (s.isActive) {\n parts.push('outline outline-2 outline-offset-1 outline-background');\n } else {\n parts.push('outline outline-2 outline-offset-1 outline-primary-500');\n }\n }\n\n if (s.hasSpeedMarker) {\n parts.push('ml-0.5 border-l-[3px] border-l-warning pl-1.5');\n }\n\n // A dotted warning underline spans every word of a re-timed region, so the\n // affected range reads at a glance (the badge only sits on the first word)\n if (s.isSped) {\n parts.push(\n 'underline decoration-warning decoration-dotted decoration-2 underline-offset-4'\n );\n }\n\n return parts.join(' ');\n}\n\n/** Blinking caret rendered inside the cursor word */\nconst Caret: React.FC<{ side: 'before' | 'after' }> = ({ side }) => (\n <span\n aria-hidden=\"true\"\n className={`bg-primary-500 absolute top-0.5 bottom-0.5 w-0.5 motion-safe:animate-pulse ${\n side === 'before' ? '-left-px' : 'right-0.5'\n }`}\n />\n);\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Media editor: MediaPlayer on top, an editable word-mode transcript below,\n * and a toolbar with speed control, filler removal, and edit statistics.\n *\n * Interactions (ported from pulseclip's TranscriptViewer):\n * - Click a word: seek and play just that word\n * - Double-click: set a range anchor; click another word to select the range\n * - Mouse-down + drag: select a range; long-press (500ms) opens the editor\n * - Right-click: speed marker menu\n * - Keyboard: arrows (+Shift to select), Home/End, Backspace/Delete toggle\n * delete, Cmd/Ctrl+X/C/V cut/copy/paste, Cmd/Ctrl+Z undo, Space plays the\n * edited timeline from the cursor, Enter opens the word editor\n */\nexport const MediaEditor = React.forwardRef<HTMLDivElement, MediaEditorProps>(\n (\n {\n src,\n kind,\n transcript,\n initialEditedWords,\n initialUndoStack,\n initialSpeedMarkers,\n initialDefaultSpeed,\n onEditorStateChange,\n onHasEditsChange,\n onCursorTimestampChange,\n onEditedWordsRender,\n onSpeedStateChange,\n onUndoBeyond,\n canUndoBeyond = false,\n undoBeyondLabel,\n onRedo,\n canRedo = false,\n redoLabel,\n playerRef: externalPlayerRef,\n className,\n splitLayout,\n },\n ref\n ) => {\n // -- Edit state (headless hook) --\n const edits = useTranscriptEdits({\n transcript,\n initialEditedWords,\n initialUndoStack,\n initialSpeedMarkers,\n initialDefaultSpeed,\n onChange: onEditorStateChange,\n });\n const {\n editedWords,\n undoStack,\n clipboard,\n hasEdits,\n undo,\n redo,\n canRedo: canRedoWords,\n toggleWordDeleted,\n deleteRange,\n cut,\n copy,\n paste,\n setWordText,\n splitSilence,\n deleteWord,\n replaceEditedWords,\n removeFillers,\n setSilenceThresholds,\n silenceThresholds,\n speedMarkers,\n defaultSpeed,\n setDefaultSpeed,\n toggleSpeedMarker,\n setSpeedForRange,\n removeSpeedMarker,\n getSpeedAtIndex,\n getSpeedMarkerAtIndex,\n playbackSegments,\n stats,\n fillerAnalysis,\n } = edits;\n\n // Undo and Redo are one control pair: they appear and disappear together,\n // and whichever cannot act is disabled rather than removed. A button that\n // vanishes shifts the ones beside it; a lone greyed Redo reads as broken.\n // Each side prefers the editor's own history and falls through to the\n // host's, so the pair walks the same states in both directions.\n // A host that sets the capability flag without the handler would otherwise\n // get an enabled button that does nothing, so both are required.\n const canUndoAnything =\n undoStack.length > 0 || (canUndoBeyond && !!onUndoBeyond);\n const canRedoAnything = canRedoWords || (canRedo && !!onRedo);\n const showUndoRedo = canUndoAnything || canRedoAnything || !!onRedo;\n\n // -- UI state --\n const [activeWordIndex, setActiveWordIndex] = React.useState<number | null>(\n null\n );\n const [cursorIndex, setCursorIndex] = React.useState<number>(0);\n // 'before' = caret before the cursor word; 'after' = after the last word\n const [cursorPosition, setCursorPosition] = React.useState<\n 'before' | 'after'\n >('before');\n const [selectionAnchor, setSelectionAnchor] = React.useState<number | null>(\n null\n );\n const [selection, setSelection] = React.useState<SelectionRange | null>(\n null\n );\n const [doubleClickAnchor, setDoubleClickAnchor] = React.useState<\n number | null\n >(null);\n const [isPlayingSequence, setIsPlayingSequence] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n const [showFillerModal, setShowFillerModal] = React.useState(false);\n const [showSilenceModal, setShowSilenceModal] = React.useState(false);\n const [showScriptPanel, setShowScriptPanel] = React.useState(false);\n const [editorWordIndex, setEditorWordIndex] = React.useState<number | null>(\n null\n );\n const [speedMenuWordIndex, setSpeedMenuWordIndex] = React.useState<\n number | null\n >(null);\n const [speedMenuPosition, setSpeedMenuPosition] = React.useState<{\n x: number;\n y: number;\n } | null>(null);\n\n // -- Refs --\n const playerRef = React.useRef<MediaPlayerRef>(null);\n // Mirror the internal player handle to the host-provided ref via a STABLE\n // delegating proxy: every call forwards to playerRef.current at call time.\n // (Snapshotting playerRef.current with [] deps captured the first-commit\n // handle — ref assignment doesn't re-render, so hosts could hold a stale\n // handle whose mediaElement stayed null forever.)\n React.useImperativeHandle(\n externalPlayerRef,\n (): MediaPlayerRef => ({\n seekToMs: (timeMs) => playerRef.current?.seekToMs(timeMs),\n play: () => playerRef.current?.play(),\n pause: () => playerRef.current?.pause(),\n getCurrentTimeMs: () => playerRef.current?.getCurrentTimeMs() ?? 0,\n getDurationMs: () => playerRef.current?.getDurationMs() ?? 0,\n isPaused: () => playerRef.current?.isPaused() ?? true,\n setPlaybackRate: (rate) => playerRef.current?.setPlaybackRate(rate),\n get mediaElement() {\n return playerRef.current?.mediaElement ?? null;\n },\n }),\n []\n );\n const contentRef = React.useRef<HTMLDivElement>(null);\n const userSetCursor = React.useRef<number | null>(null);\n const isDragging = React.useRef<boolean>(false);\n const longPressTimer = React.useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n const longPressTriggered = React.useRef<boolean>(false);\n // Drag selection: document-level listeners and the auto-scroll frame read\n // these refs because they outlive the render that attached them\n const selectionAnchorRef = React.useRef<number | null>(null);\n const dragPointer = React.useRef<{ x: number; y: number } | null>(null);\n const dragScrollFrame = React.useRef<number | null>(null);\n const dragListeners = React.useRef<{\n move: (e: MouseEvent) => void;\n up: () => void;\n } | null>(null);\n const wordPlaybackStartMs = React.useRef<number | null>(null);\n const wordPlaybackEndMs = React.useRef<number | null>(null);\n // Edited-timeline sequence playback\n const sequenceSegments = React.useRef<PlaybackSegment[]>([]);\n const currentSegmentIndex = React.useRef<number>(0);\n\n // ------------------------------------------------------------------\n // Parent notifications\n // ------------------------------------------------------------------\n\n React.useEffect(() => {\n onHasEditsChange?.(hasEdits);\n }, [hasEdits, onHasEditsChange]);\n\n React.useEffect(() => {\n onEditedWordsRender?.(editedWords);\n }, [editedWords, onEditedWordsRender]);\n\n // Documented to fire only on mount and on real speed-state changes —\n // hosts persist on it — so the callback rides a ref: a new function\n // identity per render must not re-notify unchanged state.\n const onSpeedStateChangeRef = React.useRef(onSpeedStateChange);\n React.useEffect(() => {\n onSpeedStateChangeRef.current = onSpeedStateChange;\n });\n React.useEffect(() => {\n onSpeedStateChangeRef.current?.(speedMarkers, defaultSpeed);\n }, [speedMarkers, defaultSpeed]);\n\n // Report cursor timestamp changes to the parent\n React.useEffect(() => {\n if (onCursorTimestampChange) {\n const word = editedWords[cursorIndex];\n if (word && !word.deleted) {\n onCursorTimestampChange(word.word.startMs);\n } else {\n onCursorTimestampChange(null);\n }\n }\n }, [cursorIndex, editedWords, onCursorTimestampChange]);\n\n // ------------------------------------------------------------------\n // Transcript change / cursor sync / focus\n // ------------------------------------------------------------------\n\n // Reset UI state when the transcript changes (edit state resets in the hook)\n const prevTranscriptRef = React.useRef(transcript);\n React.useEffect(() => {\n if (prevTranscriptRef.current === transcript) return;\n prevTranscriptRef.current = transcript;\n setCursorIndex(0);\n setCursorPosition('before');\n setSelection(null);\n setSelectionAnchor(null);\n setDoubleClickAnchor(null);\n setActiveWordIndex(null);\n setIsPlayingSequence(false);\n sequenceSegments.current = [];\n currentSegmentIndex.current = 0;\n }, [transcript]);\n\n // Sync cursor with the active word while playing (unless a click-seek is pending)\n React.useEffect(() => {\n if (userSetCursor.current !== null) {\n return;\n }\n if (activeWordIndex !== null && activeWordIndex >= 0) {\n setCursorIndex(activeWordIndex);\n setCursorPosition('before');\n setSelection(null);\n setSelectionAnchor(null);\n }\n }, [activeWordIndex]);\n\n // Auto-scroll the active word into view during playback\n React.useEffect(() => {\n if (activeWordIndex === null) return;\n scrollWordIntoTranscript(contentRef.current, activeWordIndex);\n }, [activeWordIndex]);\n\n // Auto-focus the transcript for keyboard navigation.\n //\n // `preventScroll` matters: focusing an element the browser considers\n // off-screen scrolls it into view, and below the md breakpoint the\n // transcript is part of a page-length document rather than its own\n // scrolling box — so this landed the reader partway down the transcript\n // with the player above the fold, on every load.\n React.useEffect(() => {\n contentRef.current?.focus({ preventScroll: true });\n }, [transcript]);\n\n // Apply the default speed when it changes (and no marker overrides it)\n React.useEffect(() => {\n const player = playerRef.current;\n if (!player) return;\n const timeMs = player.getCurrentTimeMs();\n const currentWordIndex = editedWords.findIndex(\n (ew) =>\n !ew.deleted && timeMs >= ew.word.startMs && timeMs < ew.word.endMs\n );\n const targetSpeed =\n currentWordIndex >= 0\n ? getSpeedAtIndex(currentWordIndex)\n : defaultSpeed;\n player.setPlaybackRate(targetSpeed);\n }, [defaultSpeed, speedMarkers, editedWords, getSpeedAtIndex]);\n\n // ------------------------------------------------------------------\n // Playback engine (timeupdate-driven)\n // ------------------------------------------------------------------\n\n const handleTimeUpdate = (timeMs: number) => {\n const player = playerRef.current;\n if (!player) return;\n\n // Segment-based playback of the edited timeline (jumps over deletions\n // and honors reordered/pasted words)\n if (isPlayingSequence && sequenceSegments.current.length > 0) {\n const currentSeg =\n sequenceSegments.current[currentSegmentIndex.current];\n if (currentSeg && timeMs >= currentSeg.endMs) {\n const nextIndex = currentSegmentIndex.current + 1;\n if (nextIndex < sequenceSegments.current.length) {\n currentSegmentIndex.current = nextIndex;\n player.seekToMs(sequenceSegments.current[nextIndex].startMs);\n } else {\n // End of all segments\n player.pause();\n setIsPlayingSequence(false);\n sequenceSegments.current = [];\n currentSegmentIndex.current = 0;\n }\n }\n } else if (hasEdits && !player.isPaused()) {\n // During normal playback with edits, skip over deleted words\n const inDeletedWord = editedWords.some(\n (ew) =>\n ew.deleted && timeMs >= ew.word.startMs && timeMs < ew.word.endMs\n );\n if (inDeletedWord) {\n const nextNonDeleted = editedWords.find(\n (ew) => !ew.deleted && ew.word.startMs >= timeMs\n );\n if (nextNonDeleted) {\n player.seekToMs(nextNonDeleted.word.startMs);\n }\n }\n }\n\n // Stop playback at the end of single-word playback, reseek to its start\n if (\n wordPlaybackEndMs.current !== null &&\n timeMs >= wordPlaybackEndMs.current\n ) {\n player.pause();\n if (wordPlaybackStartMs.current !== null) {\n player.seekToMs(wordPlaybackStartMs.current);\n wordPlaybackStartMs.current = null;\n }\n wordPlaybackEndMs.current = null;\n }\n\n // Find the active word. During segment playback use the current\n // segment's indices (disambiguates duplicate/pasted words that share\n // timing); otherwise fall back to a time-based lookup.\n let editedIndex = -1;\n if (isPlayingSequence && sequenceSegments.current.length > 0) {\n const currentSeg =\n sequenceSegments.current[currentSegmentIndex.current];\n if (currentSeg) {\n for (const idx of currentSeg.editedIndices) {\n const ew = editedWords[idx];\n if (\n ew &&\n !ew.deleted &&\n timeMs >= ew.word.startMs &&\n timeMs < ew.word.endMs\n ) {\n editedIndex = idx;\n break;\n }\n }\n }\n }\n if (editedIndex === -1) {\n editedIndex = editedWords.findIndex(\n (ew) =>\n !ew.deleted && timeMs >= ew.word.startMs && timeMs < ew.word.endMs\n );\n }\n\n // Update playback rate from speed markers when the word changes\n if (editedIndex !== activeWordIndex && editedIndex >= 0) {\n player.setPlaybackRate(getSpeedAtIndex(editedIndex));\n }\n setActiveWordIndex(editedIndex >= 0 ? editedIndex : null);\n\n // Playback has resumed reporting time: release the click-seek cursor lock\n userSetCursor.current = null;\n };\n\n const stopSequencePlayback = () => {\n setIsPlayingSequence(false);\n sequenceSegments.current = [];\n currentSegmentIndex.current = 0;\n };\n\n // ------------------------------------------------------------------\n // Selection / clipboard helpers\n // ------------------------------------------------------------------\n\n /** Indices covered by the selection, or the cursor word */\n const selectionIndices = React.useCallback((): number[] => {\n if (selection) {\n const indices: number[] = [];\n for (let i = selection.start; i <= selection.end; i++) indices.push(i);\n return indices;\n }\n return [cursorIndex];\n }, [selection, cursorIndex]);\n\n const handleCut = React.useCallback(() => {\n cut(selectionIndices());\n }, [cut, selectionIndices]);\n\n const handlePaste = React.useCallback(() => {\n if (!clipboard) return;\n const pastedCount = clipboard.words.length;\n const insertIndex = paste(cursorIndex, cursorPosition !== 'after');\n if (insertIndex !== null) {\n setCursorIndex(insertIndex + pastedCount - 1);\n setCursorPosition('after');\n setSelection(null);\n setSelectionAnchor(null);\n }\n }, [clipboard, paste, cursorIndex, cursorPosition]);\n\n // Toggle deleted state for the selection (anchor decides) or cursor word\n const handleDeleteToggle = React.useCallback(() => {\n if (selection) {\n const anchorIndex = selectionAnchor ?? selection.start;\n const indices: number[] = [anchorIndex];\n for (let i = selection.start; i <= selection.end; i++) {\n if (i !== anchorIndex) indices.push(i);\n }\n deleteRange(indices);\n } else {\n toggleWordDeleted(cursorIndex);\n }\n }, [\n selection,\n selectionAnchor,\n cursorIndex,\n deleteRange,\n toggleWordDeleted,\n ]);\n\n // Copy: put plain text on the system clipboard + fill the internal clipboard\n const handleCopy = React.useCallback(\n (e: React.ClipboardEvent) => {\n const indices = selectionIndices();\n const selectedWords = indices\n .map((i) => editedWords[i])\n .filter((ew): ew is EditableWord => ew !== undefined && !ew.deleted);\n if (selectedWords.length === 0) return;\n const selectedText = selectedWords\n .filter((ew) => !isSilenceType(ew.word.wordType))\n .map((ew) => ew.word.text)\n .join(' ');\n e.preventDefault();\n e.clipboardData.setData('text/plain', selectedText);\n copy(indices);\n },\n [selectionIndices, editedWords, copy]\n );\n\n // ------------------------------------------------------------------\n // Word editor modal\n // ------------------------------------------------------------------\n\n const openWordEditor = React.useCallback((index: number) => {\n setEditorWordIndex(index);\n }, []);\n\n const closeWordEditor = React.useCallback(() => {\n setEditorWordIndex(null);\n // Restore focus to the transcript after the modal closes\n setTimeout(() => contentRef.current?.focus(), 0);\n }, []);\n\n const handleEditorSave = React.useCallback(\n (newText: string) => {\n if (editorWordIndex === null) return;\n setWordText(editorWordIndex, newText);\n },\n [editorWordIndex, setWordText]\n );\n\n const handleEditorSplitSilence = React.useCallback(\n (durations: number[]) => {\n if (editorWordIndex === null) return;\n splitSilence(editorWordIndex, durations);\n },\n [editorWordIndex, splitSilence]\n );\n\n const handleEditorDelete = React.useCallback(() => {\n if (editorWordIndex !== null) {\n deleteWord(editorWordIndex);\n closeWordEditor();\n }\n }, [editorWordIndex, deleteWord, closeWordEditor]);\n\n // ------------------------------------------------------------------\n // Mouse interactions\n // ------------------------------------------------------------------\n\n const handleWordClick = (\n word: TranscriptWord,\n index: number,\n e: React.MouseEvent\n ) => {\n setCursorIndex(index);\n setCursorPosition('before');\n userSetCursor.current = index;\n\n if (e.shiftKey && selectionAnchor !== null) {\n // Extend selection with shift+click\n setSelection({\n start: Math.min(selectionAnchor, index),\n end: Math.max(selectionAnchor, index),\n });\n } else if (\n doubleClickAnchor !== null &&\n doubleClickAnchor !== index &&\n !isDragging.current\n ) {\n // A double-click anchor exists and a different word was clicked: select the range\n const start = Math.min(doubleClickAnchor, index);\n const end = Math.max(doubleClickAnchor, index);\n setSelection({ start, end });\n setSelectionAnchor(doubleClickAnchor);\n setDoubleClickAnchor(null);\n } else if (doubleClickAnchor === index) {\n // Clicking the anchor itself — wait for a potential double-click\n } else if (!isDragging.current) {\n // Clear selection, set a new anchor, and play just this word\n setSelectionAnchor(index);\n setSelection(null);\n\n const player = playerRef.current;\n if (player) {\n player.pause();\n player.seekToMs(word.startMs);\n wordPlaybackStartMs.current = word.startMs;\n wordPlaybackEndMs.current = word.endMs;\n player.play();\n }\n }\n };\n\n const handleWordDoubleClick = (index: number, e: React.MouseEvent) => {\n e.preventDefault();\n // Don't trigger if a long press already fired\n if (longPressTriggered.current) return;\n\n if (doubleClickAnchor === index) {\n setDoubleClickAnchor(null);\n } else {\n setDoubleClickAnchor(index);\n setSelection(null);\n }\n };\n\n const AUTOSCROLL_EDGE_PX = 24;\n const AUTOSCROLL_MAX_STEP_PX = 24;\n\n const extendDragSelection = (index: number) => {\n const anchor = selectionAnchorRef.current;\n if (!isDragging.current || anchor === null) return;\n setSelection({\n start: Math.min(anchor, index),\n end: Math.max(anchor, index),\n });\n setCursorIndex(index);\n };\n\n /** Word index under a viewport point, or null when the point misses every span */\n const wordIndexAtPoint = (x: number, y: number): number | null => {\n const span = document\n .elementFromPoint?.(x, y)\n ?.closest?.('[data-word-index]');\n if (!span) return null;\n const parsed = Number((span as HTMLElement).dataset.wordIndex);\n return Number.isInteger(parsed) ? parsed : null;\n };\n\n /**\n * Extends the selection to the word nearest the held pointer, clamping a\n * pointer that has left the pane back inside it. Extra probe points cover\n * padding and end-of-line whitespace, where the pointer misses every span\n * and per-word mouseenter would never fire.\n */\n const extendSelectionToPointer = () => {\n const container = contentRef.current;\n const pointer = dragPointer.current;\n if (!container || !pointer) return;\n\n // Clamp into the VISIBLE part of the pane: elementFromPoint only\n // resolves inside the viewport, and the pane can extend beyond it\n const rect = container.getBoundingClientRect();\n const top = Math.max(rect.top, 0);\n const bottom = Math.min(rect.bottom, window.innerHeight);\n const left = Math.max(rect.left, 0);\n const right = Math.min(rect.right, window.innerWidth);\n if (bottom <= top || right <= left) return;\n const y = Math.min(Math.max(pointer.y, top + 2), bottom - 2);\n const x = Math.min(Math.max(pointer.x, left + 2), right - 2);\n for (const rawX of [x, left + (right - left) / 2, left + 16]) {\n const probeX = Math.min(Math.max(rawX, left + 2), right - 2);\n const index = wordIndexAtPoint(probeX, y);\n if (index !== null) {\n extendDragSelection(index);\n return;\n }\n }\n\n // Every probe missed: the point sits in empty pane space (below the\n // last line of a short or fully scrolled transcript, or above the\n // first). Standard editor behavior: extend to the nearest end.\n const spans =\n container.querySelectorAll<HTMLElement>('[data-word-index]');\n if (spans.length === 0) return;\n // Above every span (top padding): extend to the first word without\n // scanning — the backward walk below would touch every span. Below\n // the last line is already O(1): the walk's first probe matches.\n if (spans[0].getBoundingClientRect().top > y) {\n const parsed = Number(spans[0].dataset.wordIndex);\n if (Number.isInteger(parsed)) extendDragSelection(parsed);\n return;\n }\n for (let i = spans.length - 1; i >= 0; i--) {\n const spanRect = spans[i].getBoundingClientRect();\n if (spanRect.top <= y) {\n const parsed = Number(spans[i].dataset.wordIndex);\n if (Number.isInteger(parsed)) extendDragSelection(parsed);\n return;\n }\n }\n };\n\n /** Scrolls the pane while the held pointer sits at or beyond its edge */\n const stepDragAutoScroll = () => {\n dragScrollFrame.current = null;\n const container = contentRef.current;\n const pointer = dragPointer.current;\n if (!isDragging.current || !container || !pointer) return;\n\n // Edge zones measured on the VISIBLE part of the pane, since its own\n // bounds can extend past the viewport\n const rect = container.getBoundingClientRect();\n const top = Math.max(rect.top, 0);\n const bottom = Math.min(rect.bottom, window.innerHeight);\n // Pane fully offscreen: keep the loop alive but never scroll it\n if (bottom <= top) {\n dragScrollFrame.current = requestAnimationFrame(stepDragAutoScroll);\n return;\n }\n let step = 0;\n if (pointer.y < top + AUTOSCROLL_EDGE_PX) {\n step = Math.max(\n (pointer.y - (top + AUTOSCROLL_EDGE_PX)) / 3,\n -AUTOSCROLL_MAX_STEP_PX\n );\n } else if (pointer.y > bottom - AUTOSCROLL_EDGE_PX) {\n step = Math.min(\n (pointer.y - (bottom - AUTOSCROLL_EDGE_PX)) / 3,\n AUTOSCROLL_MAX_STEP_PX\n );\n }\n if (step !== 0) {\n // Re-extend only when the pane actually moved: held at a clamped\n // top/bottom nothing shifts under the pointer, and mousemove already\n // covers pointer motion\n const before = container.scrollTop;\n container.scrollTop += step;\n if (container.scrollTop !== before) {\n extendSelectionToPointer();\n }\n }\n dragScrollFrame.current = requestAnimationFrame(stepDragAutoScroll);\n };\n\n const detachDragListeners = () => {\n if (dragListeners.current) {\n document.removeEventListener('mousemove', dragListeners.current.move);\n document.removeEventListener('mouseup', dragListeners.current.up);\n dragListeners.current = null;\n }\n if (dragScrollFrame.current !== null) {\n cancelAnimationFrame(dragScrollFrame.current);\n dragScrollFrame.current = null;\n }\n };\n\n const handleMouseUp = () => {\n if (longPressTimer.current) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n if (isDragging.current) {\n isDragging.current = false;\n }\n detachDragListeners();\n };\n\n /**\n * Document-level tracking for the lifetime of one drag, so the selection\n * keeps following after the pointer leaves the pane and the pane scrolls\n * itself when held at an edge. The exact handler pair is kept in a ref so\n * detaching survives re-renders.\n */\n const beginDragTracking = () => {\n detachDragListeners();\n\n const up = () => handleMouseUp();\n const move = (e: MouseEvent) => {\n if (!isDragging.current) return;\n // Button released outside the window: no mouseup will arrive\n if (e.buttons === 0) {\n up();\n return;\n }\n dragPointer.current = { x: e.clientX, y: e.clientY };\n\n // Leaving the pane cancels the pending long press (it used to cancel\n // the whole drag), but the selection keeps tracking the pointer\n const container = contentRef.current;\n if (container && longPressTimer.current) {\n const rect = container.getBoundingClientRect();\n const outside =\n e.clientX < rect.left ||\n e.clientX > rect.right ||\n e.clientY < rect.top ||\n e.clientY > rect.bottom;\n if (outside) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n }\n extendSelectionToPointer();\n };\n\n dragListeners.current = { move, up };\n document.addEventListener('mousemove', move);\n document.addEventListener('mouseup', up);\n dragScrollFrame.current = requestAnimationFrame(stepDragAutoScroll);\n };\n\n // Never leave document listeners, the scroll frame, or a pending\n // long-press timer behind on unmount\n React.useEffect(\n () => () => {\n if (dragListeners.current) {\n document.removeEventListener('mousemove', dragListeners.current.move);\n document.removeEventListener('mouseup', dragListeners.current.up);\n dragListeners.current = null;\n }\n if (dragScrollFrame.current !== null) {\n cancelAnimationFrame(dragScrollFrame.current);\n dragScrollFrame.current = null;\n }\n if (longPressTimer.current) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n },\n []\n );\n\n const handleWordMouseDown = (index: number, e: React.MouseEvent) => {\n if (e.button !== 0) return;\n\n // Long press (500ms) opens the word editor\n longPressTriggered.current = false;\n longPressTimer.current = setTimeout(() => {\n longPressTriggered.current = true;\n openWordEditor(index);\n }, 500);\n\n isDragging.current = true;\n selectionAnchorRef.current = index;\n dragPointer.current = { x: e.clientX, y: e.clientY };\n setSelectionAnchor(index);\n setCursorIndex(index);\n setCursorPosition('before');\n setSelection(null);\n beginDragTracking();\n };\n\n const handleWordMouseEnter = (index: number) => {\n // Cancel the long press when dragging to another word\n if (longPressTimer.current) {\n clearTimeout(longPressTimer.current);\n longPressTimer.current = null;\n }\n\n extendDragSelection(index);\n };\n\n const handleWordContextMenu = (index: number, e: React.MouseEvent) => {\n e.preventDefault();\n // Position the speed menu near the word, clamped to the viewport\n const rect = e.currentTarget.getBoundingClientRect();\n const menuHeight = 280;\n const menuWidth = 150;\n\n let x = rect.left;\n let y = rect.bottom + 4;\n\n if (x + menuWidth > window.innerWidth) {\n x = window.innerWidth - menuWidth - 8;\n }\n if (y + menuHeight > window.innerHeight) {\n y = rect.top - menuHeight - 4;\n if (y < 0) {\n y = 8;\n }\n }\n\n setSpeedMenuPosition({ x, y });\n setSpeedMenuWordIndex(index);\n };\n\n // ------------------------------------------------------------------\n // Keyboard\n // ------------------------------------------------------------------\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n const wordCount = editedWords.length;\n if (wordCount === 0) return;\n\n let newIndex = cursorIndex;\n let handled = false;\n\n if (e.key === 'Delete' || e.key === 'Backspace') {\n handleDeleteToggle();\n handled = true;\n } else if ((e.metaKey || e.ctrlKey) && e.key === 'x') {\n handleCut();\n handled = true;\n } else if ((e.metaKey || e.ctrlKey) && e.key === 'v' && clipboard) {\n handlePaste();\n handled = true;\n } else if ((e.metaKey || e.ctrlKey) && e.key === 'z' && !e.shiftKey) {\n undo();\n handled = true;\n } else if (\n (e.metaKey || e.ctrlKey) &&\n ((e.key === 'z' && e.shiftKey) || e.key === 'y')\n ) {\n // Redo. ⌘Y is accepted for anyone arriving from Windows but is never\n // advertised — on macOS it is Chrome's own History shortcut and the\n // browser wins. The button shows ⇧⌘Z, which is what this handles.\n // Word-level first, then the host's, mirroring Undo.\n if (canRedoWords) redo();\n else if (canRedo && onRedo) onRedo();\n handled = true;\n } else if (e.key === 'ArrowLeft') {\n if (cursorPosition === 'after') {\n // Move from 'after' the last word back to 'before' it\n setCursorPosition('before');\n } else {\n newIndex = Math.max(0, cursorIndex - 1);\n }\n handled = true;\n } else if (e.key === 'ArrowRight') {\n if (cursorIndex === wordCount - 1 && cursorPosition === 'before') {\n // At the last word: move the caret after it\n setCursorPosition('after');\n } else if (cursorPosition !== 'after') {\n newIndex = Math.min(wordCount - 1, cursorIndex + 1);\n }\n handled = true;\n } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n // Find the visually nearest word on the previous/next row\n const currentElement = contentRef.current?.querySelector(\n `[data-word-index=\"${cursorIndex}\"]`\n ) as HTMLElement | null;\n if (currentElement) {\n const currentRect = currentElement.getBoundingClientRect();\n const currentCenterX = currentRect.left + currentRect.width / 2;\n\n const direction = e.key === 'ArrowUp' ? -1 : 1;\n let bestMatch = cursorIndex;\n let bestDistance = Infinity;\n let targetRowTop: number | null = null;\n\n for (\n let i = cursorIndex + direction;\n i >= 0 && i < wordCount;\n i += direction\n ) {\n const el = contentRef.current?.querySelector(\n `[data-word-index=\"${i}\"]`\n ) as HTMLElement | null;\n if (!el) continue;\n\n const rect = el.getBoundingClientRect();\n const isOnDifferentRow =\n direction === -1\n ? rect.bottom <= currentRect.top\n : rect.top >= currentRect.bottom;\n\n if (isOnDifferentRow) {\n // The first word on a different row establishes the target row\n if (targetRowTop === null) {\n targetRowTop = rect.top;\n }\n const isSameTargetRow = Math.abs(rect.top - targetRowTop) < 5;\n if (isSameTargetRow) {\n const centerX = rect.left + rect.width / 2;\n const distance = Math.abs(centerX - currentCenterX);\n if (distance < bestDistance) {\n bestDistance = distance;\n bestMatch = i;\n }\n } else {\n // Moved past the target row; stop searching\n break;\n }\n }\n }\n newIndex = bestMatch;\n }\n handled = true;\n } else if (e.key === 'Home') {\n newIndex = 0;\n handled = true;\n } else if (e.key === 'End') {\n newIndex = wordCount - 1;\n handled = true;\n } else if (e.key === 'Enter') {\n openWordEditor(cursorIndex);\n handled = true;\n } else if (e.key === ' ') {\n // Toggle play/pause from the cursor position\n const ew = editedWords[cursorIndex];\n const player = playerRef.current;\n if (player && ew && !ew.deleted) {\n if (player.isPaused()) {\n if (hasEdits) {\n // Play the edited timeline as a segment sequence\n const segments = playbackSegments;\n if (segments.length > 0) {\n let startSegmentIdx = 0;\n for (let i = 0; i < segments.length; i++) {\n if (segments[i].editedIndices.includes(cursorIndex)) {\n startSegmentIdx = i;\n break;\n }\n }\n sequenceSegments.current = segments;\n currentSegmentIndex.current = startSegmentIdx;\n setIsPlayingSequence(true);\n // Start from the cursor word's time, not the segment's start\n player.seekToMs(ew.word.startMs);\n player.play();\n }\n } else {\n // Normal playback from the cursor\n player.seekToMs(ew.word.startMs);\n player.play();\n }\n } else {\n player.pause();\n setIsPlayingSequence(false);\n }\n }\n handled = true;\n }\n\n if (handled) {\n e.preventDefault();\n e.stopPropagation();\n if (newIndex !== cursorIndex) {\n setCursorIndex(newIndex);\n setCursorPosition('before');\n }\n\n if (e.shiftKey && e.key !== 'Delete' && e.key !== 'Backspace') {\n // Extend the selection (not for delete operations)\n const anchor = selectionAnchor ?? cursorIndex;\n if (selectionAnchor === null) {\n setSelectionAnchor(cursorIndex);\n }\n setSelection({\n start: Math.min(anchor, newIndex),\n end: Math.max(anchor, newIndex),\n });\n } else if (!e.metaKey && !e.ctrlKey) {\n // Clear the selection when moving without shift (not for cut/paste)\n setSelection(null);\n setSelectionAnchor(null);\n }\n\n // Scroll the cursor into view\n scrollWordIntoTranscript(contentRef.current, newIndex);\n }\n },\n [\n editedWords,\n cursorIndex,\n cursorPosition,\n selectionAnchor,\n clipboard,\n hasEdits,\n playbackSegments,\n handleDeleteToggle,\n handleCut,\n handlePaste,\n undo,\n redo,\n canRedoWords,\n canRedo,\n onRedo,\n openWordEditor,\n ]\n );\n\n // ------------------------------------------------------------------\n // Rendering\n // ------------------------------------------------------------------\n\n const isWordSelected = (index: number): boolean => {\n if (!selection) return false;\n return index >= selection.start && index <= selection.end;\n };\n\n const renderWord = (ew: EditableWord, index: number) => {\n const isActive = index === activeWordIndex;\n const isCursor = index === cursorIndex;\n const isSelected = isWordSelected(index);\n const isDeleted = ew.deleted;\n const isInserted = ew.inserted ?? false;\n const isSilence =\n ew.word.wordType === 'silence' ||\n ew.word.wordType === 'silence-newline';\n const isSilenceNewline = ew.word.wordType === 'silence-newline';\n const isAnchor = index === doubleClickAnchor;\n const showCursorBefore = isCursor && cursorPosition === 'before';\n const showCursorAfter =\n isCursor &&\n cursorPosition === 'after' &&\n index === editedWords.length - 1;\n const speedMarker = getSpeedMarkerAtIndex(index);\n const hasSpeedMarker = !!speedMarker;\n\n // For silences, show the duration adjusted for the effective speed\n const effectiveSpeed = getSpeedAtIndex(index);\n let displayText = ew.word.text;\n if (isSilence && effectiveSpeed !== 1) {\n const originalDurationMs = ew.word.endMs - ew.word.startMs;\n const adjustedDurationSec = originalDurationMs / effectiveSpeed / 1000;\n displayText = `[${adjustedDurationSec.toFixed(1)}s]`;\n }\n\n const title = `${ew.word.startMs}ms - ${ew.word.endMs}ms${\n ew.word.confidence ? ` (${Math.round(ew.word.confidence * 100)}%)` : ''\n }${\n isSilence\n ? ` [SILENCE: ${((ew.word.endMs - ew.word.startMs) / 1000).toFixed(1)}s${\n effectiveSpeed !== 1\n ? ` → ${((ew.word.endMs - ew.word.startMs) / effectiveSpeed / 1000).toFixed(1)}s @ ${effectiveSpeed}x`\n : ''\n }]`\n : ''\n }${isDeleted ? ' [DELETED]' : ''}${isInserted ? ' [INSERTED]' : ''}${\n hasSpeedMarker ? ` [SPEED: ${speedMarker.speed}x]` : ''\n }${\n isAnchor\n ? ' [ANCHOR - click another word to select range, double-click to clear]'\n : ''\n }${!isAnchor && !isDeleted ? ' (right-click to set speed marker)' : ''}`;\n\n return (\n // Keyboard interaction is owned by the parent listbox via roving focus\n // (aria-activedescendant); options are pointer affordances only.\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus\n <span\n key={`${ew.originalIndex}-${index}`}\n id={`word-${index}`}\n data-word-index={index}\n className={wordClassName({\n isActive,\n isCursor,\n isSelected,\n isDeleted,\n isInserted,\n isSilence,\n isSilenceNewline,\n isAnchor,\n isFocused,\n hasSpeedMarker,\n isSped: effectiveSpeed !== defaultSpeed,\n })}\n onClick={(e) => handleWordClick(ew.word, index, e)}\n onDoubleClick={(e) => handleWordDoubleClick(index, e)}\n onMouseDown={(e) => handleWordMouseDown(index, e)}\n onMouseEnter={() => handleWordMouseEnter(index)}\n onContextMenu={(e) => handleWordContextMenu(index, e)}\n role=\"option\"\n aria-selected={isSelected || isCursor}\n title={title}\n >\n {showCursorBefore && isFocused && <Caret side=\"before\" />}\n {hasSpeedMarker && (\n <span\n className=\"border-warning/50 bg-warning/20 text-warning-foreground mr-1 inline-block rounded-sm border px-0.5 align-middle text-[9px] leading-snug font-semibold\"\n title={`Speed: ${speedMarker.speed}x from here`}\n >\n {speedMarker.speed}x\n </span>\n )}\n {displayText} {showCursorAfter && isFocused && <Caret side=\"after\" />}\n </span>\n );\n };\n\n const showEditBar =\n hasEdits || doubleClickAnchor !== null || selection !== null;\n\n return (\n <div\n ref={ref}\n className={mediaEditorVariants({ splitLayout, className })}\n >\n <div\n className={`flex min-h-0 min-w-0 flex-1 ${\n splitLayout === 'vertical' ? 'flex-col md:flex-row' : 'flex-col'\n }`}\n >\n {/* Media surface */}\n {/*\n The cap is written twice on purpose. `max-h-[50%]` is a percentage\n of the parent's height, which only resolves while the editor is a\n fixed-height shell — on a small screen the parent grows to its\n content, the percentage resolves against an indeterminate height,\n and the rule silently becomes no cap at all. A portrait phone\n recording then took the full viewport on its own and pushed its own\n controls off the bottom of the screen. The `dvh` cap always\n resolves; the md variant keeps existing desktop behaviour byte for\n byte.\n\n `dvh` rather than `vh`, matching Modal and Sheet: on iOS Safari\n `vh` measures the viewport as if the browser chrome were hidden, so\n while the address bar is on screen `55vh` is taller than 55% of\n what you can actually see — which would put the player's own\n controls back under the fold, the exact failure this cap exists to\n prevent.\n */}\n <div\n className={`border-border bg-background flex min-h-0 shrink-0 ${\n splitLayout === 'vertical'\n ? 'max-h-[55dvh] md:max-h-none md:w-1/2 md:border-r'\n : 'max-h-[55dvh] border-b md:max-h-[50%]'\n }`}\n >\n <MediaPlayer\n ref={playerRef}\n src={src}\n kind={kind}\n aria-label=\"Media player\"\n onTimeUpdate={handleTimeUpdate}\n onEnded={stopSequencePlayback}\n />\n </div>\n\n {/* Transcript editor */}\n <div\n className={`flex min-h-0 flex-1 flex-col ${splitLayout === 'vertical' ? 'md:w-1/2' : ''}`}\n >\n {/* Toolbar */}\n <div className=\"border-border flex shrink-0 flex-wrap items-center justify-between gap-2 border-b px-3 py-2\">\n <div className=\"flex items-center gap-2\">\n {hasEdits && (\n <span className=\"bg-warning/20 text-warning-foreground rounded px-1.5 py-0.5 text-xs font-semibold\">\n Edited\n </span>\n )}\n <label\n className=\"text-muted-foreground text-xs\"\n htmlFor=\"media-editor-default-speed\"\n >\n Speed:\n </label>\n <div className=\"w-20\">\n <Select\n id=\"media-editor-default-speed\"\n size=\"sm\"\n options={PLAYBACK_SPEEDS.map((speed) => ({\n value: String(speed),\n label: `${speed}x`,\n }))}\n value={String(defaultSpeed)}\n onValueChange={(value) =>\n setDefaultSpeed(parseFloat(value) as PlaybackSpeed)\n }\n aria-label=\"Default playback speed\"\n />\n </div>\n {speedMarkers.length > 0 && (\n <span\n className=\"text-muted-foreground text-xs\"\n title={`${speedMarkers.length} speed marker(s) set. Right-click on a word to add/remove speed markers.`}\n >\n {speedMarkers.length} marker\n {speedMarkers.length !== 1 ? 's' : ''}\n </span>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowFillerModal(true)}\n aria-label=\"Remove filler words\"\n title=\"Remove filler words\"\n >\n ✂️\n </Button>\n {/* Undo and Redo appear and disappear together. A lone greyed\n Redo reads as broken, and an Undo that vanishes at the end\n of history while Redo merely greys is two rules for one\n pair — so whichever is inert is disabled, not removed. */}\n {showUndoRedo && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={!canUndoAnything}\n // Word-level first; the host only gets it once the\n // editor's own history is spent.\n onClick={undoStack.length > 0 ? undo : onUndoBeyond}\n aria-label={\n undoStack.length > 0\n ? `Undo (${undoStack.length} available)`\n : canUndoBeyond && undoBeyondLabel\n ? `Undo: ${undoBeyondLabel}`\n : 'Undo'\n }\n title={\n undoStack.length > 0\n ? `Undo (⌘Z) — ${undoStack.length} step${undoStack.length === 1 ? '' : 's'}`\n : canUndoBeyond\n ? undoBeyondLabel\n ? `Undo (⌘Z) — back to \"${undoBeyondLabel}\"`\n : 'Undo (⌘Z)'\n : 'Nothing to undo'\n }\n >\n Undo{undoStack.length > 0 ? ` (${undoStack.length})` : ''}{' '}\n <kbd className=\"text-[10px] opacity-60\">⌘Z</kbd>\n </Button>\n )}\n {showUndoRedo && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n // Word-level first, mirroring Undo, so the pair steps back\n // and forward through the same states in the same order.\n onClick={canRedoWords ? redo : onRedo}\n disabled={!canRedoAnything}\n aria-label={\n !canRedoWords && canRedo && redoLabel\n ? `Redo: ${redoLabel}`\n : 'Redo'\n }\n title={\n canRedoWords\n ? 'Redo (⇧⌘Z)'\n : canRedo && redoLabel\n ? `Redo (⇧⌘Z) — forward to \"${redoLabel}\"`\n : canRedo\n ? 'Redo (⇧⌘Z)'\n : 'Nothing to redo'\n }\n >\n Redo <kbd className=\"text-[10px] opacity-60\">⇧⌘Z</kbd>\n </Button>\n )}\n </div>\n\n <div className=\"text-muted-foreground flex items-center gap-2 text-xs\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowScriptPanel((v) => !v)}\n aria-pressed={showScriptPanel}\n aria-label=\"Show script\"\n title=\"Show the transcript script (editable YAML/JSON)\"\n >\n Script\n </Button>\n <span>{stats.activeWordCount} words</span>\n <button\n type=\"button\"\n className=\"hover:bg-muted hover:text-foreground focus-visible:ring-ring rounded px-1 underline decoration-dotted transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => setShowSilenceModal(true)}\n title={\n stats.activeSilenceCount > 0\n ? `Click to configure silence detection (currently ≥${(silenceThresholds.minSilenceMs / 1000).toFixed(1)}s)`\n : `No silences detected (threshold: ${(silenceThresholds.minSilenceMs / 1000).toFixed(1)}s). Click to configure.`\n }\n aria-label=\"Configure silence detection\"\n >\n {stats.activeSilenceCount} silences\n </button>\n {(stats.deletedWordCount > 0 ||\n stats.deletedSilenceCount > 0) && (\n <span className=\"text-destructive\">\n {stats.deletedWordCount + stats.deletedSilenceCount} deleted\n </span>\n )}\n {transcript.speakers && (\n <span>{transcript.speakers.length} speakers</span>\n )}\n <span>{formatDuration(stats.editedDurationMs)}</span>\n </div>\n </div>\n\n {/* Contextual edit actions */}\n {showEditBar && (\n <div className=\"border-border bg-muted/40 flex shrink-0 items-center gap-1 border-b px-3 py-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => openWordEditor(cursorIndex)}\n title=\"Edit selected word (Enter)\"\n >\n Edit <kbd className=\"text-[10px] opacity-60\">↵</kbd>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleDeleteToggle}\n title=\"Delete selected word (Del)\"\n >\n Del <kbd className=\"text-[10px] opacity-60\">⌫</kbd>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleCut}\n title=\"Cut selection (⌘X)\"\n >\n Cut <kbd className=\"text-[10px] opacity-60\">⌘X</kbd>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handlePaste}\n disabled={!clipboard}\n title=\"Paste (⌘V)\"\n >\n Paste <kbd className=\"text-[10px] opacity-60\">⌘V</kbd>\n </Button>\n </div>\n )}\n\n {/* Editable transcript */}\n <div\n ref={contentRef}\n className={`focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto p-3 text-sm leading-relaxed select-none focus:outline-none focus-visible:ring-2 focus-visible:ring-inset ${\n isFocused ? 'bg-muted/20' : ''\n }`}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onCopy={handleCopy}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onMouseUp={handleMouseUp}\n role=\"listbox\"\n aria-label=\"Transcript words\"\n aria-activedescendant={`word-${cursorIndex}`}\n >\n {editedWords.map(renderWord)}\n </div>\n </div>\n </div>\n\n {showScriptPanel && (\n <ScriptPanel\n transcript={transcript}\n editedWords={editedWords}\n onApply={replaceEditedWords}\n onClose={() => setShowScriptPanel(false)}\n />\n )}\n\n {/* Modals & menus */}\n <FillerWordsModal\n isOpen={showFillerModal}\n onClose={() => setShowFillerModal(false)}\n onApply={removeFillers}\n matchingCounts={fillerAnalysis.matchCounts}\n fillerDurations={fillerAnalysis.durations}\n silenceCounts={fillerAnalysis.silenceCounts}\n currentDurationMs={stats.editedDurationMs}\n />\n\n <SilenceSettingsModal\n isOpen={showSilenceModal}\n onClose={() => setShowSilenceModal(false)}\n minSilenceMs={silenceThresholds.minSilenceMs}\n nlSilenceMs={silenceThresholds.nlSilenceMs}\n onApply={setSilenceThresholds}\n />\n\n <WordEditorModal\n isOpen={editorWordIndex !== null}\n editableWord={\n editorWordIndex !== null\n ? (editedWords[editorWordIndex] ?? null)\n : null\n }\n onClose={closeWordEditor}\n onSave={handleEditorSave}\n onSplitSilence={handleEditorSplitSilence}\n onDelete={handleEditorDelete}\n />\n\n <SpeedMarkerMenu\n isOpen={speedMenuWordIndex !== null}\n position={speedMenuPosition}\n wordIndex={speedMenuWordIndex}\n currentMarker={\n speedMenuWordIndex !== null\n ? getSpeedMarkerAtIndex(speedMenuWordIndex)\n : undefined\n }\n defaultSpeed={defaultSpeed}\n onSetSpeed={(speed) => {\n if (speedMenuWordIndex === null) return;\n // With an active selection the speed applies to the whole range\n // (and only the range); otherwise the classic from-here-on marker\n if (selection) {\n setSpeedForRange(selection.start, selection.end, speed);\n } else {\n toggleSpeedMarker(speedMenuWordIndex, speed);\n }\n }}\n onRemoveMarker={() => {\n if (speedMenuWordIndex !== null) {\n removeSpeedMarker(speedMenuWordIndex);\n }\n }}\n onClose={() => {\n setSpeedMenuWordIndex(null);\n setSpeedMenuPosition(null);\n }}\n />\n </div>\n );\n }\n);\n\nMediaEditor.displayName = 'MediaEditor';\n"]}