@mieweb/ui 0.8.0-dev.3 → 0.8.0-dev.5

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/TranscriptView/TranscriptView.tsx"],"names":["cva","React","jsx","jsxs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,IAAM,sBAAA,GAAyBA,2BAAI,+BAAA,EAAiC;AAAA,EAClE,QAAA,EAAU;AAAA,IACR,OAAA,EAAS;AAAA,MACP,KAAA,EAAO,EAAA;AAAA,MACP,IAAA,EAAM;AAAA;AACR,GACF;AAAA,EACA,eAAA,EAAiB;AAAA,IACf,OAAA,EAAS;AAAA;AAEb,CAAC,CAAA;AAOM,SAAS,kBAAkB,EAAA,EAAoB;AACpD,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAI,CAAA;AACzC,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;AAGA,SAAS,mBAAA,CACP,SAAA,EACA,aAAA,EACA,UAAA,EACoB;AACpB,EAAA,IAAI,CAAC,WAAW,OAAO,MAAA;AACvB,EAAA,OACE,aAAA,GAAgB,SAAS,CAAA,IACzB,UAAA,CAAW,QAAA,EAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,SAAS,CAAA,EAAG,IAAA,IACtD,SAAA;AAEJ;AAcA,SAAS,gBAAA,CACP,UACA,KAAA,EACc;AACd,EAAA,MAAM,OAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAK;AAC/B,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACjC,IAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,IAAA,CAAK,SAAA,KAAc,QAAQ,SAAA,EAAW;AACzD,MAAA,IAAA,CAAK,QAAQ,GAAA,GAAM,IAAA;AACnB,MAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA;AAAA,IACvB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,IAAA,CAAK;AAAA,QACR,IAAA;AAAA,QACA,SAAS,OAAA,CAAQ,OAAA;AAAA,QACjB,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,WAAW,OAAA,CAAQ;AAAA,OACpB,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,eAAA,CACP,OACA,MAAA,EACQ;AACR,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,EAAA;AACjC,EAAA,OAAO,KAAA,CAAM,SAAA;AAAA,IACX,CAAC,IAAA,KAAS,MAAA,IAAU,IAAA,CAAK,OAAA,IAAW,SAAS,IAAA,CAAK;AAAA,GACpD;AACF;AAGA,SAAS,gBAAgB,UAAA,EAAwB;AAC/C,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,UAAA;AAAA,IACT,SAAA,EAAW,CAAC,CAAA,KAA2B;AACrC,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAA,CAAE,QAAQ,GAAA,EAAK;AACtC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,UAAA,EAAW;AAAA,MACb;AAAA,IACF;AAAA,GACF;AACF;AAgBO,IAAM,cAAA,GAAuBC,gBAAA,CAAA,UAAA;AAAA,EAIlC,CACE;AAAA,IACE,UAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,MAAA;AAAA,IACA,cAAA,GAAiB,IAAA;AAAA,IACjB,aAAA;AAAA,IACA,gBAAA,GAAmB,KAAA;AAAA,IACnB,cAAA,GAAiB,IAAA;AAAA,IACjB,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,cAAc,SAAA,GAAY;AAAA,KAE5B,GAAA,KACG;AACH,IAAA,MAAM,UAAA,GAAmBA,wBAAuB,IAAI,CAAA;AACpD,IAAA,MAAM,aAAA,GAAsBA,wBAAO,KAAK,CAAA;AAExC,IAAA,MAAM,mBAAA,GACJ,gBACC,UAAA,CAAW,QAAA,IAAY,WAAW,QAAA,CAAS,MAAA,GAAS,IACjD,SAAA,GACA,MAAA,CAAA;AAEN,IAAA,MAAM,WAAA,GAAoBA,gBAAA,CAAA,OAAA;AAAA,MACxB,MACE,mBAAA,KAAwB,SAAA,GACpB,gBAAA,CAAiB,UAAA,CAAW,YAAY,EAAC,EAAG,gBAAgB,CAAA,GAC5D,EAAC;AAAA,MACP,CAAC,mBAAA,EAAqB,UAAA,CAAW,QAAA,EAAU,gBAAgB;AAAA,KAC7D;AAEA,IAAA,MAAM,WAAA,GACJ,mBAAA,KAAwB,SAAA,GACpB,eAAA,CAAgB,WAAA,EAAa,aAAa,CAAA,GAC1C,eAAA,CAAgB,UAAA,CAAW,KAAA,EAAO,aAAa,CAAA;AAGrD,IAAMA,2BAAU,MAAM;AACpB,MAAA,IAAI,CAAC,cAAA,IAAkB,WAAA,GAAc,CAAA,IAAK,cAAc,OAAA,EAAS;AACjE,MAAA,MAAM,EAAA,GAAK,WAAW,OAAA,EAAS,aAAA;AAAA,QAC7B,2BAA2B,WAAW,CAAA,EAAA;AAAA,OACxC;AACA,MAAA,EAAA,EAAI,eAAe,EAAE,KAAA,EAAO,SAAA,EAAW,QAAA,EAAU,UAAU,CAAA;AAAA,IAC7D,CAAA,EAAG,CAAC,cAAA,EAAgB,WAAW,CAAC,CAAA;AAEhC,IAAA,MAAM,MAAA,GAAS,CAAC,MAAA,KAAmB,MAAA,GAAS,MAAM,CAAA;AAKlD,IAAA,MAAM,UAAA,GAAa,CAAC,IAAA,EAAsB,KAAA,KAAkB;AAC1D,MAAA,MAAM,WAAW,KAAA,KAAU,WAAA;AAC3B,MAAA,MAAM,QAAA,GAAW,KAAK,QAAA,IAAY,MAAA;AAClC,MAAA,MAAM,gBAAgB,IAAA,CAAK,KAAA,GAAQ,KAAK,OAAA,IAAW,GAAA,EAAM,QAAQ,CAAC,CAAA;AAElE,MAAA,IAAI,aAAa,iBAAA,EAAmB;AAElC,QAAA,uBACEC,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,uBAAA,EAAuB,KAAA;AAAA,YACvB,IAAA,EAAK,QAAA;AAAA,YACL,QAAA,EAAU,CAAA;AAAA,YACV,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,YAClC,YAAA,EAAY,YAAY,WAAW,CAAA,QAAA,CAAA;AAAA,YACnC,SAAA,EAAW,CAAA,0IAAA,EACT,QAAA,GAAW,mBAAA,GAAsB,EACnC,CAAA,CAAA;AAAA,YACC,GAAG,eAAA,CAAgB,MAAM,MAAA,CAAO,IAAA,CAAK,OAAO,CAAC;AAAA,WAAA;AAAA,UATzC;AAAA,SAUP;AAAA,MAEJ;AAEA,MAAA,IAAI,aAAa,SAAA,EAAW;AAE1B,QAAA,uBACEA,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,uBAAA,EAAuB,KAAA;AAAA,YACvB,IAAA,EAAK,QAAA;AAAA,YACL,QAAA,EAAU,CAAA;AAAA,YACV,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,YAClC,YAAA,EAAY,YAAY,WAAW,CAAA,QAAA,CAAA;AAAA,YACnC,SAAA,EAAW,CAAA,gKAAA,EACT,QAAA,GAAW,mBAAA,GAAsB,EACnC,CAAA,CAAA;AAAA,YACC,GAAG,eAAA,CAAgB,MAAM,MAAA,CAAO,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,YAE7C,QAAA,EAAA;AAAA,WAAA;AAAA,UAXI;AAAA,SAYP;AAAA,MAEJ;AAEA,MAAA,uBACEC,eAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAEC,uBAAA,EAAuB,KAAA;AAAA,UACvB,IAAA,EAAK,QAAA;AAAA,UACL,QAAA,EAAU,CAAA;AAAA,UACV,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,UAClC,SAAA,EAAW,CAAA,uIAAA,EACT,QAAA,GAAW,mCAAA,GAAsC,EACnD,CAAA,CAAA;AAAA,UACC,GAAG,eAAA,CAAgB,MAAM,MAAA,CAAO,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,UAE7C,QAAA,EAAA;AAAA,YAAA,IAAA,CAAK,IAAA;AAAA,YAAM;AAAA;AAAA,SAAA;AAAA,QAVP;AAAA,OAWP;AAAA,IAEJ,CAAA;AAKA,IAAA,MAAM,gBAAA,GAAmB,CAAC,GAAA,EAAiB,KAAA,KAAkB;AAC3D,MAAA,MAAM,WAAW,KAAA,KAAU,WAAA;AAC3B,MAAA,MAAM,OAAA,GAAU,mBAAA;AAAA,QACd,GAAA,CAAI,SAAA;AAAA,QACJ,aAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,uBACED,cAAA,CAAC,KAAA,EAAA,EAAgB,IAAA,EAAK,UAAA,EACpB,QAAA,kBAAAC,eAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,uBAAA,EAAuB,KAAA;AAAA,UACvB,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,UAClC,SAAA,EAAW,CAAA,8KAAA,EACT,QAAA,GAAW,mBAAA,GAAsB,EACnC,CAAA,CAAA;AAAA,UACA,OAAA,EAAS,MAAM,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AAAA,UAEhC,QAAA,EAAA;AAAA,YAAA,cAAA,mCACE,MAAA,EAAA,EAAK,SAAA,EAAU,iDACb,QAAA,EAAA,iBAAA,CAAkB,GAAA,CAAI,OAAO,CAAA,EAChC,CAAA;AAAA,YAED,OAAA,oBACCA,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8CAAA,EACb,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,cAAQ;AAAA,aAAA,EACX,CAAA;AAAA,4BAEFD,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iBAAA,EAAmB,cAAI,IAAA,EAAK;AAAA;AAAA;AAAA,WApBtC,KAsBV,CAAA;AAAA,IAEJ,CAAA;AAEA,IAAA,uBACEC,eAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,uBAAuB,EAAE,OAAA,EAAS,SAAA,EAAW,CAAA,EACpE,QAAA,EAAA;AAAA,MAAA,OAAA,oBACCD,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sEAAA,EACZ,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,sBAEFA,cAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,UAAA;AAAA,UACL,YAAA,EAAY,SAAA;AAAA,UACZ,cAAc,MAAM;AAClB,YAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,UAC1B,CAAA;AAAA,UACA,cAAc,MAAM;AAClB,YAAA,aAAA,CAAc,OAAA,GAAU,KAAA;AAAA,UAC1B,CAAA;AAAA,UACC,GAAI,mBAAA,KAAwB,SAAA,GACzB,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAA,EAAW,WAAA,EAAY,GACvC,EAAE,SAAA,EAAW,yBAAA,EAA0B;AAAA,UAE1C,QAAA,EAAA,mBAAA,KAAwB,YACrB,WAAA,CAAY,GAAA,CAAI,gBAAgB,CAAA,GAChC,UAAA,CAAW,KAAA,CAAM,GAAA,CAAI,UAAU;AAAA;AAAA;AACrC,KAAA,EACF,CAAA;AAAA,EAEJ;AACF;AAEA,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"chunk-DG7KE4YJ.cjs","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n Transcript,\n TranscriptSegment,\n TranscriptWord,\n} from './transcript';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport type TranscriptGranularity = 'word' | 'segment';\n\nexport interface TranscriptViewProps extends VariantProps<\n typeof transcriptViewVariants\n> {\n /** The transcript to render */\n transcript: Transcript;\n /**\n * Rendering granularity. Defaults to 'segment' when the transcript has\n * segments, otherwise 'word'.\n */\n granularity?: TranscriptGranularity;\n /** Controlled playback position (ms); the matching word/segment is highlighted */\n currentTimeMs?: number;\n /** Called with the start time (ms) of a clicked word/segment; the host performs the seek/play */\n onSeek?: (timeMs: number) => void;\n /** Auto-scroll the active word/segment into view (default true) */\n followPlayback?: boolean;\n /**\n * Maps Speaker.id to a display label (e.g. Clinician/Patient). Falls back to\n * Speaker.name from transcript.speakers, then the raw id.\n */\n speakerLabels?: Record<string, string>;\n /** Segment mode: merge consecutive same-speaker segments into one row (default false) */\n mergeSameSpeaker?: boolean;\n /** Segment mode: show mm:ss timestamps (default true) */\n showTimestamps?: boolean;\n /** Rendered in a header row (host supplies copy/re-transcribe/remove buttons) */\n actions?: React.ReactNode;\n /** Additional class name */\n className?: string;\n /** Accessible label for the transcript container (default 'Transcript') */\n 'aria-label'?: string;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst transcriptViewVariants = cva('flex flex-col text-foreground', {\n variants: {\n variant: {\n plain: '',\n card: 'rounded-xl border border-border bg-card text-card-foreground p-3',\n },\n },\n defaultVariants: {\n variant: 'plain',\n },\n});\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Format milliseconds as m:ss (osheet timestamp style) */\nexport function formatTimestampMs(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\n/** Resolve a speaker id to its display label */\nfunction resolveSpeakerLabel(\n speakerId: string | undefined,\n speakerLabels: Record<string, string> | undefined,\n transcript: Transcript\n): string | undefined {\n if (!speakerId) return undefined;\n return (\n speakerLabels?.[speakerId] ??\n transcript.speakers?.find((s) => s.id === speakerId)?.name ??\n speakerId\n );\n}\n\n/** A display row in segment mode (possibly the merge of several source segments) */\ninterface SegmentRow {\n text: string;\n startMs: number;\n endMs: number;\n speakerId?: string;\n}\n\n/**\n * Build segment display rows, optionally merging consecutive same-speaker\n * segments (osheet formatTranscriptText behavior). Empty segments are skipped.\n */\nfunction buildSegmentRows(\n segments: TranscriptSegment[],\n merge: boolean\n): SegmentRow[] {\n const rows: SegmentRow[] = [];\n for (const segment of segments) {\n const text = segment.text.trim();\n if (!text) continue;\n const prev = rows[rows.length - 1];\n if (merge && prev && prev.speakerId === segment.speakerId) {\n prev.text += ' ' + text;\n prev.endMs = segment.endMs;\n } else {\n rows.push({\n text,\n startMs: segment.startMs,\n endMs: segment.endMs,\n speakerId: segment.speakerId,\n });\n }\n }\n return rows;\n}\n\n/** Index of the item whose [startMs, endMs) range contains timeMs, or -1 */\nfunction findActiveIndex(\n items: ReadonlyArray<{ startMs: number; endMs: number }>,\n timeMs: number | undefined\n): number {\n if (timeMs === undefined) return -1;\n return items.findIndex(\n (item) => timeMs >= item.startMs && timeMs < item.endMs\n );\n}\n\n/** Run onActivate for click and Enter/Space keyboard activation */\nfunction activationProps(onActivate: () => void) {\n return {\n onClick: onActivate,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onActivate();\n }\n },\n };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Read-only transcript viewer with word-level and segment-level (diarized)\n * rendering modes.\n *\n * Controlled and persistence-agnostic: the host owns playback and passes the\n * position via `currentTimeMs`; clicking a word/segment reports the target\n * time through `onSeek`. Segment mode matches the osheet artifact-viewer row\n * UX (timestamp | speaker | text, click to seek + play). Editing lives in\n * MediaEditor, not here.\n */\nexport const TranscriptView = React.forwardRef<\n HTMLDivElement,\n TranscriptViewProps\n>(\n (\n {\n transcript,\n granularity,\n currentTimeMs,\n onSeek,\n followPlayback = true,\n speakerLabels,\n mergeSameSpeaker = false,\n showTimestamps = true,\n actions,\n variant,\n className,\n 'aria-label': ariaLabel = 'Transcript',\n },\n ref\n ) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n const isHoveringRef = React.useRef(false);\n\n const resolvedGranularity: TranscriptGranularity =\n granularity ??\n (transcript.segments && transcript.segments.length > 0\n ? 'segment'\n : 'word');\n\n const segmentRows = React.useMemo(\n () =>\n resolvedGranularity === 'segment'\n ? buildSegmentRows(transcript.segments ?? [], mergeSameSpeaker)\n : [],\n [resolvedGranularity, transcript.segments, mergeSameSpeaker]\n );\n\n const activeIndex =\n resolvedGranularity === 'segment'\n ? findActiveIndex(segmentRows, currentTimeMs)\n : findActiveIndex(transcript.words, currentTimeMs);\n\n // Auto-scroll the active item into view, unless the user is hovering\n React.useEffect(() => {\n if (!followPlayback || activeIndex < 0 || isHoveringRef.current) return;\n const el = contentRef.current?.querySelector(\n `[data-transcript-index=\"${activeIndex}\"]`\n );\n el?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }, [followPlayback, activeIndex]);\n\n const seekTo = (timeMs: number) => onSeek?.(timeMs);\n\n // ------------------------------------------------------------------\n // Word mode rendering\n // ------------------------------------------------------------------\n const renderWord = (word: TranscriptWord, index: number) => {\n const isActive = index === activeIndex;\n const wordType = word.wordType ?? 'word';\n const durationSec = ((word.endMs - word.startMs) / 1000).toFixed(1);\n\n if (wordType === 'silence-newline') {\n // Longer pause: force a line break (block element inside inline flow)\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n aria-label={`Silence, ${durationSec} seconds`}\n className={`hover:bg-muted focus-visible:ring-ring block h-3 cursor-pointer rounded transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n />\n );\n }\n\n if (wordType === 'silence') {\n // Short gap: subtle interpunct\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n aria-label={`Silence, ${durationSec} seconds`}\n className={`text-muted-foreground/60 hover:bg-muted focus-visible:ring-ring cursor-pointer rounded px-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n >\n {'\\u00B7 '}\n </span>\n );\n }\n\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n className={`hover:bg-muted focus-visible:ring-ring cursor-pointer rounded px-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20 text-foreground' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n >\n {word.text}{' '}\n </span>\n );\n };\n\n // ------------------------------------------------------------------\n // Segment mode rendering (osheet artifact-viewer row parity)\n // ------------------------------------------------------------------\n const renderSegmentRow = (row: SegmentRow, index: number) => {\n const isActive = index === activeIndex;\n const speaker = resolveSpeakerLabel(\n row.speakerId,\n speakerLabels,\n transcript\n );\n\n return (\n <div key={index} role=\"listitem\">\n <button\n type=\"button\"\n data-transcript-index={index}\n aria-current={isActive ? 'true' : undefined}\n className={`hover:bg-muted focus-visible:ring-ring flex w-full cursor-pointer gap-3 rounded px-2 py-1 text-left text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n onClick={() => seekTo(row.startMs)}\n >\n {showTimestamps && (\n <span className=\"text-muted-foreground w-12 shrink-0 font-mono\">\n {formatTimestampMs(row.startMs)}\n </span>\n )}\n {speaker && (\n <span className=\"text-primary-900 w-24 shrink-0 font-semibold\">\n {speaker}:\n </span>\n )}\n <span className=\"text-foreground\">{row.text}</span>\n </button>\n </div>\n );\n };\n\n return (\n <div ref={ref} className={transcriptViewVariants({ variant, className })}>\n {actions && (\n <div className=\"border-border mb-2 flex items-center justify-end gap-2 border-b pb-2\">\n {actions}\n </div>\n )}\n <div\n ref={contentRef}\n aria-label={ariaLabel}\n onMouseEnter={() => {\n isHoveringRef.current = true;\n }}\n onMouseLeave={() => {\n isHoveringRef.current = false;\n }}\n {...(resolvedGranularity === 'segment'\n ? { role: 'list', className: 'space-y-2' }\n : { className: 'text-sm leading-relaxed' })}\n >\n {resolvedGranularity === 'segment'\n ? segmentRows.map(renderSegmentRow)\n : transcript.words.map(renderWord)}\n </div>\n </div>\n );\n }\n);\n\nTranscriptView.displayName = 'TranscriptView';\n"]}
1
+ {"version":3,"sources":["../src/components/TranscriptView/TranscriptView.tsx"],"names":["cva","React","jsx","jsxs"],"mappings":"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","file":"chunk-VA3WQ5KJ.cjs","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n Transcript,\n TranscriptSegment,\n TranscriptWord,\n} from './transcript';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport type TranscriptGranularity = 'word' | 'segment';\n\nexport interface TranscriptViewProps extends VariantProps<\n typeof transcriptViewVariants\n> {\n /** The transcript to render */\n transcript: Transcript;\n /**\n * Rendering granularity. Defaults to 'segment' when the transcript has\n * segments, otherwise 'word'.\n */\n granularity?: TranscriptGranularity;\n /** Controlled playback position (ms); the matching word/segment is highlighted */\n currentTimeMs?: number;\n /** Called with the start time (ms) of a clicked word/segment; the host performs the seek/play */\n onSeek?: (timeMs: number) => void;\n /** Auto-scroll the active word/segment into view (default true) */\n followPlayback?: boolean;\n /**\n * Maps Speaker.id to a display label (e.g. Clinician/Patient). Falls back to\n * Speaker.name from transcript.speakers, then the raw id.\n */\n speakerLabels?: Record<string, string>;\n /** Segment mode: merge consecutive same-speaker segments into one row (default false) */\n mergeSameSpeaker?: boolean;\n /** Segment mode: show mm:ss timestamps (default true) */\n showTimestamps?: boolean;\n /** Rendered in a header row (host supplies copy/re-transcribe/remove buttons) */\n actions?: React.ReactNode;\n /** Additional class name */\n className?: string;\n /** Accessible label for the transcript container (default 'Transcript') */\n 'aria-label'?: string;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst transcriptViewVariants = cva('flex flex-col text-foreground', {\n variants: {\n variant: {\n plain: '',\n card: 'rounded-xl border border-border bg-card text-card-foreground p-3',\n },\n },\n defaultVariants: {\n variant: 'plain',\n },\n});\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Format milliseconds as m:ss (osheet timestamp style) */\nexport function formatTimestampMs(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\n\n/** Resolve a speaker id to its display label */\nfunction resolveSpeakerLabel(\n speakerId: string | undefined,\n speakerLabels: Record<string, string> | undefined,\n transcript: Transcript\n): string | undefined {\n if (!speakerId) return undefined;\n return (\n speakerLabels?.[speakerId] ??\n transcript.speakers?.find((s) => s.id === speakerId)?.name ??\n speakerId\n );\n}\n\n/** A display row in segment mode (possibly the merge of several source segments) */\ninterface SegmentRow {\n text: string;\n startMs: number;\n endMs: number;\n speakerId?: string;\n}\n\n/**\n * Build segment display rows, optionally merging consecutive same-speaker\n * segments (osheet formatTranscriptText behavior). Empty segments are skipped.\n */\nfunction buildSegmentRows(\n segments: TranscriptSegment[],\n merge: boolean\n): SegmentRow[] {\n const rows: SegmentRow[] = [];\n for (const segment of segments) {\n const text = segment.text.trim();\n if (!text) continue;\n const prev = rows[rows.length - 1];\n if (merge && prev && prev.speakerId === segment.speakerId) {\n prev.text += ' ' + text;\n prev.endMs = segment.endMs;\n } else {\n rows.push({\n text,\n startMs: segment.startMs,\n endMs: segment.endMs,\n speakerId: segment.speakerId,\n });\n }\n }\n return rows;\n}\n\n/** Index of the item whose [startMs, endMs) range contains timeMs, or -1 */\nfunction findActiveIndex(\n items: ReadonlyArray<{ startMs: number; endMs: number }>,\n timeMs: number | undefined\n): number {\n if (timeMs === undefined) return -1;\n return items.findIndex(\n (item) => timeMs >= item.startMs && timeMs < item.endMs\n );\n}\n\n/** Run onActivate for click and Enter/Space keyboard activation */\nfunction activationProps(onActivate: () => void) {\n return {\n onClick: onActivate,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onActivate();\n }\n },\n };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Read-only transcript viewer with word-level and segment-level (diarized)\n * rendering modes.\n *\n * Controlled and persistence-agnostic: the host owns playback and passes the\n * position via `currentTimeMs`; clicking a word/segment reports the target\n * time through `onSeek`. Segment mode matches the osheet artifact-viewer row\n * UX (timestamp | speaker | text, click to seek + play). Editing lives in\n * MediaEditor, not here.\n */\nexport const TranscriptView = React.forwardRef<\n HTMLDivElement,\n TranscriptViewProps\n>(\n (\n {\n transcript,\n granularity,\n currentTimeMs,\n onSeek,\n followPlayback = true,\n speakerLabels,\n mergeSameSpeaker = false,\n showTimestamps = true,\n actions,\n variant,\n className,\n 'aria-label': ariaLabel = 'Transcript',\n },\n ref\n ) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n const isHoveringRef = React.useRef(false);\n\n const resolvedGranularity: TranscriptGranularity =\n granularity ??\n (transcript.segments && transcript.segments.length > 0\n ? 'segment'\n : 'word');\n\n const segmentRows = React.useMemo(\n () =>\n resolvedGranularity === 'segment'\n ? buildSegmentRows(transcript.segments ?? [], mergeSameSpeaker)\n : [],\n [resolvedGranularity, transcript.segments, mergeSameSpeaker]\n );\n\n const activeIndex =\n resolvedGranularity === 'segment'\n ? findActiveIndex(segmentRows, currentTimeMs)\n : findActiveIndex(transcript.words, currentTimeMs);\n\n // Auto-scroll the active item into view, unless the user is hovering\n React.useEffect(() => {\n if (!followPlayback || activeIndex < 0 || isHoveringRef.current) return;\n const el = contentRef.current?.querySelector(\n `[data-transcript-index=\"${activeIndex}\"]`\n );\n el?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }, [followPlayback, activeIndex]);\n\n const seekTo = (timeMs: number) => onSeek?.(timeMs);\n\n // ------------------------------------------------------------------\n // Word mode rendering\n // ------------------------------------------------------------------\n const renderWord = (word: TranscriptWord, index: number) => {\n const isActive = index === activeIndex;\n const wordType = word.wordType ?? 'word';\n const durationSec = ((word.endMs - word.startMs) / 1000).toFixed(1);\n\n if (wordType === 'silence-newline') {\n // Longer pause: force a line break (block element inside inline flow)\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n aria-label={`Silence, ${durationSec} seconds`}\n className={`hover:bg-muted focus-visible:ring-ring block h-3 cursor-pointer rounded transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n />\n );\n }\n\n if (wordType === 'silence') {\n // Short gap: subtle interpunct\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n aria-label={`Silence, ${durationSec} seconds`}\n className={`text-muted-foreground/60 hover:bg-muted focus-visible:ring-ring cursor-pointer rounded px-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n >\n {'\\u00B7 '}\n </span>\n );\n }\n\n return (\n <span\n key={index}\n data-transcript-index={index}\n role=\"button\"\n tabIndex={0}\n aria-current={isActive ? 'true' : undefined}\n className={`hover:bg-muted focus-visible:ring-ring cursor-pointer rounded px-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20 text-foreground' : ''\n }`}\n {...activationProps(() => seekTo(word.startMs))}\n >\n {word.text}{' '}\n </span>\n );\n };\n\n // ------------------------------------------------------------------\n // Segment mode rendering (osheet artifact-viewer row parity)\n // ------------------------------------------------------------------\n const renderSegmentRow = (row: SegmentRow, index: number) => {\n const isActive = index === activeIndex;\n const speaker = resolveSpeakerLabel(\n row.speakerId,\n speakerLabels,\n transcript\n );\n\n return (\n <div key={index} role=\"listitem\">\n <button\n type=\"button\"\n data-transcript-index={index}\n aria-current={isActive ? 'true' : undefined}\n className={`hover:bg-muted focus-visible:ring-ring flex w-full cursor-pointer gap-3 rounded px-2 py-1 text-start text-sm transition-colors focus-visible:ring-2 focus-visible:outline-none ${\n isActive ? 'bg-primary-500/20' : ''\n }`}\n onClick={() => seekTo(row.startMs)}\n >\n {showTimestamps && (\n <span className=\"text-muted-foreground w-12 shrink-0 font-mono\">\n {formatTimestampMs(row.startMs)}\n </span>\n )}\n {speaker && (\n <span className=\"text-primary-900 w-24 shrink-0 font-semibold\">\n {speaker}:\n </span>\n )}\n <span className=\"text-foreground\">{row.text}</span>\n </button>\n </div>\n );\n };\n\n return (\n <div ref={ref} className={transcriptViewVariants({ variant, className })}>\n {actions && (\n <div className=\"border-border mb-2 flex items-center justify-end gap-2 border-b pb-2\">\n {actions}\n </div>\n )}\n <div\n ref={contentRef}\n aria-label={ariaLabel}\n onMouseEnter={() => {\n isHoveringRef.current = true;\n }}\n onMouseLeave={() => {\n isHoveringRef.current = false;\n }}\n {...(resolvedGranularity === 'segment'\n ? { role: 'list', className: 'space-y-2' }\n : { className: 'text-sm leading-relaxed' })}\n >\n {resolvedGranularity === 'segment'\n ? segmentRows.map(renderSegmentRow)\n : transcript.words.map(renderWord)}\n </div>\n </div>\n );\n }\n);\n\nTranscriptView.displayName = 'TranscriptView';\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk3RADKLLD_cjs = require('../../chunk-3RADKLLD.cjs');
3
+ var chunk7LJTW7KF_cjs = require('../../chunk-7LJTW7KF.cjs');
4
4
  require('../../chunk-YMHOF6WA.cjs');
5
5
  require('../../chunk-JP5SGIXA.cjs');
6
6
  require('../../chunk-7AECNMYV.cjs');
@@ -23,23 +23,23 @@ require('../../chunk-SCV7C55E.cjs');
23
23
 
24
24
  Object.defineProperty(exports, "FillerWordsModal", {
25
25
  enumerable: true,
26
- get: function () { return chunk3RADKLLD_cjs.FillerWordsModal; }
26
+ get: function () { return chunk7LJTW7KF_cjs.FillerWordsModal; }
27
27
  });
28
28
  Object.defineProperty(exports, "MediaEditor", {
29
29
  enumerable: true,
30
- get: function () { return chunk3RADKLLD_cjs.MediaEditor; }
30
+ get: function () { return chunk7LJTW7KF_cjs.MediaEditor; }
31
31
  });
32
32
  Object.defineProperty(exports, "SilenceSettingsModal", {
33
33
  enumerable: true,
34
- get: function () { return chunk3RADKLLD_cjs.SilenceSettingsModal; }
34
+ get: function () { return chunk7LJTW7KF_cjs.SilenceSettingsModal; }
35
35
  });
36
36
  Object.defineProperty(exports, "SpeedMarkerMenu", {
37
37
  enumerable: true,
38
- get: function () { return chunk3RADKLLD_cjs.SpeedMarkerMenu; }
38
+ get: function () { return chunk7LJTW7KF_cjs.SpeedMarkerMenu; }
39
39
  });
40
40
  Object.defineProperty(exports, "WordEditorModal", {
41
41
  enumerable: true,
42
- get: function () { return chunk3RADKLLD_cjs.WordEditorModal; }
42
+ get: function () { return chunk7LJTW7KF_cjs.WordEditorModal; }
43
43
  });
44
44
  //# sourceMappingURL=index.cjs.map
45
45
  //# sourceMappingURL=index.cjs.map
@@ -1,4 +1,4 @@
1
- export { FillerWordsModal, MediaEditor, SilenceSettingsModal, SpeedMarkerMenu, WordEditorModal } from '../../chunk-LDQ2T27A.js';
1
+ export { FillerWordsModal, MediaEditor, SilenceSettingsModal, SpeedMarkerMenu, WordEditorModal } from '../../chunk-DWRYYTWT.js';
2
2
  import '../../chunk-OTQ72WX3.js';
3
3
  import '../../chunk-EMMYFHOT.js';
4
4
  import '../../chunk-753Z3NXL.js';
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var chunkDG7KE4YJ_cjs = require('../../chunk-DG7KE4YJ.cjs');
3
+ var chunkVA3WQ5KJ_cjs = require('../../chunk-VA3WQ5KJ.cjs');
4
4
  var chunkNUFUV43P_cjs = require('../../chunk-NUFUV43P.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "TranscriptView", {
9
9
  enumerable: true,
10
- get: function () { return chunkDG7KE4YJ_cjs.TranscriptView; }
10
+ get: function () { return chunkVA3WQ5KJ_cjs.TranscriptView; }
11
11
  });
12
12
  Object.defineProperty(exports, "formatTimestampMs", {
13
13
  enumerable: true,
14
- get: function () { return chunkDG7KE4YJ_cjs.formatTimestampMs; }
14
+ get: function () { return chunkVA3WQ5KJ_cjs.formatTimestampMs; }
15
15
  });
16
16
  Object.defineProperty(exports, "PLAYBACK_SPEEDS", {
17
17
  enumerable: true,
@@ -1,4 +1,4 @@
1
- export { TranscriptView, formatTimestampMs } from '../../chunk-SEPYBAML.js';
1
+ export { TranscriptView, formatTimestampMs } from '../../chunk-RVGTI4F6.js';
2
2
  export { PLAYBACK_SPEEDS } from '../../chunk-6CGM5H4J.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.cjs CHANGED
@@ -15,7 +15,7 @@ var chunkP7UMS4E6_cjs = require('./chunk-P7UMS4E6.cjs');
15
15
  var chunk3IAA3KCE_cjs = require('./chunk-3IAA3KCE.cjs');
16
16
  var chunkZ5KFXHDP_cjs = require('./chunk-Z5KFXHDP.cjs');
17
17
  var chunkVTKXM7IE_cjs = require('./chunk-VTKXM7IE.cjs');
18
- var chunkDG7KE4YJ_cjs = require('./chunk-DG7KE4YJ.cjs');
18
+ var chunkVA3WQ5KJ_cjs = require('./chunk-VA3WQ5KJ.cjs');
19
19
  var chunkZJCPW6MS_cjs = require('./chunk-ZJCPW6MS.cjs');
20
20
  var chunkAHHFFXJR_cjs = require('./chunk-AHHFFXJR.cjs');
21
21
  var chunk7RV6CAP6_cjs = require('./chunk-7RV6CAP6.cjs');
@@ -44,7 +44,7 @@ var chunkP3JEMF6E_cjs = require('./chunk-P3JEMF6E.cjs');
44
44
  var chunk4CUFXCC5_cjs = require('./chunk-4CUFXCC5.cjs');
45
45
  var chunkK4S4FAYX_cjs = require('./chunk-K4S4FAYX.cjs');
46
46
  var chunkYIXTGWT4_cjs = require('./chunk-YIXTGWT4.cjs');
47
- var chunk3RADKLLD_cjs = require('./chunk-3RADKLLD.cjs');
47
+ var chunk7LJTW7KF_cjs = require('./chunk-7LJTW7KF.cjs');
48
48
  var chunkYMHOF6WA_cjs = require('./chunk-YMHOF6WA.cjs');
49
49
  require('./chunk-GLXTVCHN.cjs');
50
50
  var chunkJP5SGIXA_cjs = require('./chunk-JP5SGIXA.cjs');
@@ -64,7 +64,7 @@ var chunk7AECNMYV_cjs = require('./chunk-7AECNMYV.cjs');
64
64
  var chunkN5O47VGS_cjs = require('./chunk-N5O47VGS.cjs');
65
65
  var chunkX4LBUPJO_cjs = require('./chunk-X4LBUPJO.cjs');
66
66
  var chunkIUDY6S7I_cjs = require('./chunk-IUDY6S7I.cjs');
67
- var chunkPBRXDB5K_cjs = require('./chunk-PBRXDB5K.cjs');
67
+ var chunkE6BQVAHF_cjs = require('./chunk-E6BQVAHF.cjs');
68
68
  var chunkHK3AMH3Q_cjs = require('./chunk-HK3AMH3Q.cjs');
69
69
  var chunkEPQPUFS6_cjs = require('./chunk-EPQPUFS6.cjs');
70
70
  var chunkTVLZZI5Q_cjs = require('./chunk-TVLZZI5Q.cjs');
@@ -17611,7 +17611,7 @@ function FilePreviewItem({ file, onRemove, disabled }) {
17611
17611
  "span",
17612
17612
  {
17613
17613
  className: chunkS5RVSXDV_cjs.cn(
17614
- "absolute bottom-2 left-2 px-2 py-0.5",
17614
+ "absolute start-2 bottom-2 px-2 py-0.5",
17615
17615
  "rounded-full text-xs font-medium",
17616
17616
  "bg-black/50 text-white",
17617
17617
  "capitalize"
@@ -18168,15 +18168,15 @@ function DocumentDetectionOverlay({
18168
18168
  {
18169
18169
  className: `absolute inset-4 rounded-lg border-4 transition-colors duration-300 ${borderColor}`,
18170
18170
  children: [
18171
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -left-1 h-6 w-6 rounded-tl border-t-4 border-l-4 border-current" }),
18172
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -right-1 h-6 w-6 rounded-tr border-t-4 border-r-4 border-current" }),
18173
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -bottom-1 -left-1 h-6 w-6 rounded-bl border-b-4 border-l-4 border-current" }),
18174
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -right-1 -bottom-1 h-6 w-6 rounded-br border-r-4 border-b-4 border-current" })
18171
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -start-1 -top-1 h-6 w-6 rounded-ss border-s-4 border-t-4 border-current" }),
18172
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -end-1 -top-1 h-6 w-6 rounded-se border-e-4 border-t-4 border-current" }),
18173
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -start-1 -bottom-1 h-6 w-6 rounded-es border-s-4 border-b-4 border-current" }),
18174
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -end-1 -bottom-1 h-6 w-6 rounded-ee border-e-4 border-b-4 border-current" })
18175
18175
  ]
18176
18176
  }
18177
18177
  ),
18178
18178
  /* @__PURE__ */ jsxRuntime.jsx(CountdownDisplay, { seconds: captureCountdown }),
18179
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-3 right-3 left-3", children: [
18179
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute start-3 end-3 top-3", children: [
18180
18180
  /* @__PURE__ */ jsxRuntime.jsx(
18181
18181
  "div",
18182
18182
  {
@@ -18192,7 +18192,7 @@ function DocumentDetectionOverlay({
18192
18192
  }
18193
18193
  ) })
18194
18194
  ] }),
18195
- showDetailedMetrics && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 bottom-3 left-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap justify-center gap-2 rounded-lg bg-black/60 p-2 backdrop-blur-sm", children: [
18195
+ showDetailedMetrics && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute start-3 end-3 bottom-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap justify-center gap-2 rounded-lg bg-black/60 p-2 backdrop-blur-sm", children: [
18196
18196
  /* @__PURE__ */ jsxRuntime.jsx(StatusPill, { label: "Focus", isOk: isInFocus, value: focusScore }),
18197
18197
  /* @__PURE__ */ jsxRuntime.jsx(
18198
18198
  StatusPill,
@@ -18233,12 +18233,12 @@ function CameraViewfinder({
18233
18233
  isReady && detectionOverlay,
18234
18234
  isReady && !detectionOverlay && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pointer-events-none absolute inset-0", children: [
18235
18235
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-8 rounded-lg border-2 border-white/30", children: [
18236
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-0.5 -left-0.5 h-6 w-6 rounded-tl-lg border-t-4 border-l-4 border-white" }),
18237
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-0.5 -right-0.5 h-6 w-6 rounded-tr-lg border-t-4 border-r-4 border-white" }),
18238
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -bottom-0.5 -left-0.5 h-6 w-6 rounded-bl-lg border-b-4 border-l-4 border-white" }),
18239
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -right-0.5 -bottom-0.5 h-6 w-6 rounded-br-lg border-r-4 border-b-4 border-white" })
18236
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -start-0.5 -top-0.5 h-6 w-6 rounded-ss-lg border-s-4 border-t-4 border-white" }),
18237
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -end-0.5 -top-0.5 h-6 w-6 rounded-se-lg border-e-4 border-t-4 border-white" }),
18238
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -start-0.5 -bottom-0.5 h-6 w-6 rounded-es-lg border-s-4 border-b-4 border-white" }),
18239
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -end-0.5 -bottom-0.5 h-6 w-6 rounded-ee-lg border-e-4 border-b-4 border-white" })
18240
18240
  ] }),
18241
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-0 bottom-4 left-0 text-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-black/50 px-3 py-1 text-sm text-white", children: "Position document within the frame" }) })
18241
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute start-0 end-0 bottom-4 text-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-black/50 px-3 py-1 text-sm text-white", children: "Position document within the frame" }) })
18242
18242
  ] })
18243
18243
  ] });
18244
18244
  }
@@ -18251,7 +18251,7 @@ function PermissionDeniedMessage({ onRetry }) {
18251
18251
  ] }),
18252
18252
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 text-center", children: [
18253
18253
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: "To enable camera access:" }),
18254
- /* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "text-muted-foreground list-inside list-decimal space-y-1 text-left text-sm", children: [
18254
+ /* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "text-muted-foreground list-inside list-decimal space-y-1 text-start text-sm", children: [
18255
18255
  /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Click the camera/lock icon in your browser's address bar" }),
18256
18256
  /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Allow camera access for this site" }),
18257
18257
  /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Click the button below to try again" })
@@ -19897,7 +19897,7 @@ function CreateInvoiceModal({
19897
19897
  type: "button",
19898
19898
  "data-slot": "invoice-modal-order",
19899
19899
  onClick: () => toggleOrder(order.id),
19900
- className: `w-full rounded-lg border p-3 text-left transition-colors ${isSelected ? "border-primary bg-primary/10" : "border-border hover:border-border/80"} `,
19900
+ className: `w-full rounded-lg border p-3 text-start transition-colors ${isSelected ? "border-primary bg-primary/10" : "border-border hover:border-border/80"} `,
19901
19901
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
19902
19902
  /* @__PURE__ */ jsxRuntime.jsx(
19903
19903
  "div",
@@ -20098,7 +20098,7 @@ function CreateInvoiceModal({
20098
20098
  "svg",
20099
20099
  {
20100
20100
  "aria-hidden": "true",
20101
- className: "mr-2 -ml-1 h-4 w-4 animate-spin",
20101
+ className: "-ms-1 me-2 h-4 w-4 animate-spin",
20102
20102
  fill: "none",
20103
20103
  viewBox: "0 0 24 24",
20104
20104
  children: [
@@ -25103,7 +25103,7 @@ function InvoiceList({
25103
25103
  "svg",
25104
25104
  {
25105
25105
  "aria-hidden": "true",
25106
- className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400",
25106
+ className: "absolute start-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400",
25107
25107
  fill: "none",
25108
25108
  stroke: "currentColor",
25109
25109
  viewBox: "0 0 24 24",
@@ -25125,7 +25125,7 @@ function InvoiceList({
25125
25125
  placeholder: "Search invoices...",
25126
25126
  value: searchQuery,
25127
25127
  onChange: handleSearch,
25128
- className: "pl-9"
25128
+ className: "ps-9"
25129
25129
  }
25130
25130
  )
25131
25131
  ] }),
@@ -25151,7 +25151,7 @@ function InvoiceList({
25151
25151
  "svg",
25152
25152
  {
25153
25153
  "aria-hidden": "true",
25154
- className: "mr-1 h-4 w-4",
25154
+ className: "me-1 h-4 w-4",
25155
25155
  fill: "none",
25156
25156
  stroke: "currentColor",
25157
25157
  viewBox: "0 0 24 24",
@@ -25243,11 +25243,11 @@ function InvoiceList({
25243
25243
  className: "overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700",
25244
25244
  children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full", children: [
25245
25245
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50 dark:bg-gray-800", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
25246
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-left text-xs font-medium tracking-wider uppercase", children: "Invoice" }),
25247
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-left text-xs font-medium tracking-wider uppercase sm:table-cell", children: "Employer" }),
25248
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-left text-xs font-medium tracking-wider uppercase md:table-cell", children: "Issued" }),
25249
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-left text-xs font-medium tracking-wider uppercase md:table-cell", children: "Due" }),
25250
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-right text-xs font-medium tracking-wider uppercase", children: "Amount" }),
25246
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-start text-xs font-medium tracking-wider uppercase", children: "Invoice" }),
25247
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-start text-xs font-medium tracking-wider uppercase sm:table-cell", children: "Employer" }),
25248
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-start text-xs font-medium tracking-wider uppercase md:table-cell", children: "Issued" }),
25249
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-start text-xs font-medium tracking-wider uppercase md:table-cell", children: "Due" }),
25250
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-end text-xs font-medium tracking-wider uppercase", children: "Amount" }),
25251
25251
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-center text-xs font-medium tracking-wider uppercase", children: "Status" })
25252
25252
  ] }) }),
25253
25253
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-700", children: filteredInvoices.map((invoice) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -25270,7 +25270,7 @@ function InvoiceList({
25270
25270
  children: formatDate4(invoice.dueDate)
25271
25271
  }
25272
25272
  ) }),
25273
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-gray-900 dark:text-white", children: formatCurrency3(invoice.amount) }) }),
25273
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-end", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-gray-900 dark:text-white", children: formatCurrency3(invoice.amount) }) }),
25274
25274
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(chunkYVL3XATO_cjs.Badge, { variant: getStatusVariant(invoice.status), children: invoice.status }) })
25275
25275
  ]
25276
25276
  },
@@ -25501,12 +25501,12 @@ function InvoicePaymentPage({
25501
25501
  className: "border-t border-gray-200 pt-4 dark:border-gray-700",
25502
25502
  children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-sm", children: [
25503
25503
  /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-muted-foreground", children: [
25504
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 text-left font-medium", children: "Item" }),
25505
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 text-right font-medium", children: "Amount" })
25504
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 text-start font-medium", children: "Item" }),
25505
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "pb-2 text-end font-medium", children: "Amount" })
25506
25506
  ] }) }),
25507
25507
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "text-gray-700 dark:text-gray-300", children: invoice.lineItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
25508
25508
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1", children: item.description }),
25509
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 text-right", children: formatCurrency3(item.total) })
25509
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 text-end", children: formatCurrency3(item.total) })
25510
25510
  ] }, item.id)) })
25511
25511
  ] })
25512
25512
  }
@@ -25666,7 +25666,7 @@ function InvoicePaymentPage({
25666
25666
  "svg",
25667
25667
  {
25668
25668
  "aria-hidden": "true",
25669
- className: "mr-2 -ml-1 h-4 w-4 animate-spin",
25669
+ className: "-ms-1 me-2 h-4 w-4 animate-spin",
25670
25670
  fill: "none",
25671
25671
  viewBox: "0 0 24 24",
25672
25672
  children: [
@@ -25758,7 +25758,7 @@ function InvoiceView({
25758
25758
  "svg",
25759
25759
  {
25760
25760
  "aria-hidden": "true",
25761
- className: "mr-1 h-4 w-4",
25761
+ className: "me-1 h-4 w-4",
25762
25762
  fill: "none",
25763
25763
  stroke: "currentColor",
25764
25764
  viewBox: "0 0 24 24",
@@ -25799,7 +25799,7 @@ function InvoiceView({
25799
25799
  "svg",
25800
25800
  {
25801
25801
  "aria-hidden": "true",
25802
- className: "mr-1 h-4 w-4",
25802
+ className: "me-1 h-4 w-4",
25803
25803
  fill: "none",
25804
25804
  stroke: "currentColor",
25805
25805
  viewBox: "0 0 24 24",
@@ -25830,7 +25830,7 @@ function InvoiceView({
25830
25830
  "svg",
25831
25831
  {
25832
25832
  "aria-hidden": "true",
25833
- className: "mr-1 h-4 w-4",
25833
+ className: "me-1 h-4 w-4",
25834
25834
  fill: "none",
25835
25835
  stroke: "currentColor",
25836
25836
  viewBox: "0 0 24 24",
@@ -25871,7 +25871,7 @@ function InvoiceView({
25871
25871
  "svg",
25872
25872
  {
25873
25873
  "aria-hidden": "true",
25874
- className: "mr-1 h-4 w-4",
25874
+ className: "me-1 h-4 w-4",
25875
25875
  fill: "none",
25876
25876
  stroke: "currentColor",
25877
25877
  viewBox: "0 0 24 24",
@@ -25895,7 +25895,7 @@ function InvoiceView({
25895
25895
  "svg",
25896
25896
  {
25897
25897
  "aria-hidden": "true",
25898
- className: "mr-1 h-4 w-4",
25898
+ className: "me-1 h-4 w-4",
25899
25899
  fill: "none",
25900
25900
  stroke: "currentColor",
25901
25901
  viewBox: "0 0 24 24",
@@ -25945,7 +25945,7 @@ function InvoiceView({
25945
25945
  "div",
25946
25946
  {
25947
25947
  "data-slot": "invoice-view-meta",
25948
- className: "text-left sm:text-right",
25948
+ className: "text-start sm:text-end",
25949
25949
  children: [
25950
25950
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "INVOICE" }),
25951
25951
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-2xl font-bold text-gray-900 dark:text-white", children: invoice.invoiceNumber }),
@@ -25985,10 +25985,10 @@ function InvoiceView({
25985
25985
  className: "mb-6 overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700",
25986
25986
  children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full", children: [
25987
25987
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50 dark:bg-gray-800", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
25988
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-left text-xs font-medium uppercase", children: "Description" }),
25988
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-start text-xs font-medium uppercase", children: "Description" }),
25989
25989
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-center text-xs font-medium uppercase sm:table-cell", children: "Qty" }),
25990
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-right text-xs font-medium uppercase sm:table-cell", children: "Unit Price" }),
25991
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-right text-xs font-medium uppercase", children: "Total" })
25990
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-end text-xs font-medium uppercase sm:table-cell", children: "Unit Price" }),
25991
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-end text-xs font-medium uppercase", children: "Total" })
25992
25992
  ] }) }),
25993
25993
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-700", children: invoice.lineItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "bg-white dark:bg-gray-900", children: [
25994
25994
  /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-3", children: [
@@ -25999,8 +25999,8 @@ function InvoiceView({
25999
25999
  ] })
26000
26000
  ] }),
26001
26001
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "hidden px-4 py-3 text-center text-gray-700 sm:table-cell dark:text-gray-300", children: item.quantity }),
26002
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "hidden px-4 py-3 text-right text-gray-700 sm:table-cell dark:text-gray-300", children: formatCurrency3(item.unitPrice) }),
26003
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-right font-medium text-gray-900 dark:text-white", children: formatCurrency3(item.total) })
26002
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "hidden px-4 py-3 text-end text-gray-700 sm:table-cell dark:text-gray-300", children: formatCurrency3(item.unitPrice) }),
26003
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-end font-medium text-gray-900 dark:text-white", children: formatCurrency3(item.total) })
26004
26004
  ] }, item.id)) })
26005
26005
  ] })
26006
26006
  }
@@ -30255,13 +30255,13 @@ function PaymentHistoryTable({
30255
30255
  className: `overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700 ${className}`,
30256
30256
  children: /* @__PURE__ */ jsxRuntime.jsxs("table", { "data-slot": "payment-history-table", className: "w-full", children: [
30257
30257
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50 dark:bg-gray-800", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
30258
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-left text-xs font-medium tracking-wider uppercase", children: "Date" }),
30259
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-left text-xs font-medium tracking-wider uppercase sm:table-cell", children: "Invoice" }),
30260
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-left text-xs font-medium tracking-wider uppercase md:table-cell", children: "Employer" }),
30261
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-left text-xs font-medium tracking-wider uppercase lg:table-cell", children: "Method" }),
30262
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-right text-xs font-medium tracking-wider uppercase", children: "Amount" }),
30258
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-start text-xs font-medium tracking-wider uppercase", children: "Date" }),
30259
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-start text-xs font-medium tracking-wider uppercase sm:table-cell", children: "Invoice" }),
30260
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-start text-xs font-medium tracking-wider uppercase md:table-cell", children: "Employer" }),
30261
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground hidden px-4 py-3 text-start text-xs font-medium tracking-wider uppercase lg:table-cell", children: "Method" }),
30262
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-end text-xs font-medium tracking-wider uppercase", children: "Amount" }),
30263
30263
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-center text-xs font-medium tracking-wider uppercase", children: "Status" }),
30264
- onRefund && /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-right text-xs font-medium tracking-wider uppercase", children: "Action" })
30264
+ onRefund && /* @__PURE__ */ jsxRuntime.jsx("th", { className: "text-muted-foreground px-4 py-3 text-end text-xs font-medium tracking-wider uppercase", children: "Action" })
30265
30265
  ] }) }),
30266
30266
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-700", children: payments.map((payment) => /* @__PURE__ */ jsxRuntime.jsxs(
30267
30267
  "tr",
@@ -30293,7 +30293,7 @@ function PaymentHistoryTable({
30293
30293
  payment.cardLast4 && ` \u2022\u2022\u2022\u2022 ${payment.cardLast4}`
30294
30294
  ] })
30295
30295
  ] }) }),
30296
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxRuntime.jsx(
30296
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-end", children: /* @__PURE__ */ jsxRuntime.jsx(
30297
30297
  "p",
30298
30298
  {
30299
30299
  className: `font-medium ${payment.status === "refunded" ? "text-muted-foreground line-through" : "text-gray-900 dark:text-white"}`,
@@ -30301,7 +30301,7 @@ function PaymentHistoryTable({
30301
30301
  }
30302
30302
  ) }),
30303
30303
  /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(chunkYVL3XATO_cjs.Badge, { variant: getStatusVariant(payment.status), children: payment.status }) }),
30304
- onRefund && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-right", children: payment.status === "completed" && /* @__PURE__ */ jsxRuntime.jsx(
30304
+ onRefund && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3 text-end", children: payment.status === "completed" && /* @__PURE__ */ jsxRuntime.jsx(
30305
30305
  chunkRDGRKYQ5_cjs.Button,
30306
30306
  {
30307
30307
  variant: "ghost",
@@ -44692,11 +44692,11 @@ Object.defineProperty(exports, "toggleVariants", {
44692
44692
  });
44693
44693
  Object.defineProperty(exports, "TranscriptView", {
44694
44694
  enumerable: true,
44695
- get: function () { return chunkDG7KE4YJ_cjs.TranscriptView; }
44695
+ get: function () { return chunkVA3WQ5KJ_cjs.TranscriptView; }
44696
44696
  });
44697
44697
  Object.defineProperty(exports, "formatTimestampMs", {
44698
44698
  enumerable: true,
44699
- get: function () { return chunkDG7KE4YJ_cjs.formatTimestampMs; }
44699
+ get: function () { return chunkVA3WQ5KJ_cjs.formatTimestampMs; }
44700
44700
  });
44701
44701
  Object.defineProperty(exports, "VisuallyHidden", {
44702
44702
  enumerable: true,
@@ -45196,23 +45196,23 @@ Object.defineProperty(exports, "FenceBlock", {
45196
45196
  });
45197
45197
  Object.defineProperty(exports, "FillerWordsModal", {
45198
45198
  enumerable: true,
45199
- get: function () { return chunk3RADKLLD_cjs.FillerWordsModal; }
45199
+ get: function () { return chunk7LJTW7KF_cjs.FillerWordsModal; }
45200
45200
  });
45201
45201
  Object.defineProperty(exports, "MediaEditor", {
45202
45202
  enumerable: true,
45203
- get: function () { return chunk3RADKLLD_cjs.MediaEditor; }
45203
+ get: function () { return chunk7LJTW7KF_cjs.MediaEditor; }
45204
45204
  });
45205
45205
  Object.defineProperty(exports, "SilenceSettingsModal", {
45206
45206
  enumerable: true,
45207
- get: function () { return chunk3RADKLLD_cjs.SilenceSettingsModal; }
45207
+ get: function () { return chunk7LJTW7KF_cjs.SilenceSettingsModal; }
45208
45208
  });
45209
45209
  Object.defineProperty(exports, "SpeedMarkerMenu", {
45210
45210
  enumerable: true,
45211
- get: function () { return chunk3RADKLLD_cjs.SpeedMarkerMenu; }
45211
+ get: function () { return chunk7LJTW7KF_cjs.SpeedMarkerMenu; }
45212
45212
  });
45213
45213
  Object.defineProperty(exports, "WordEditorModal", {
45214
45214
  enumerable: true,
45215
- get: function () { return chunk3RADKLLD_cjs.WordEditorModal; }
45215
+ get: function () { return chunk7LJTW7KF_cjs.WordEditorModal; }
45216
45216
  });
45217
45217
  Object.defineProperty(exports, "Slider", {
45218
45218
  enumerable: true,
@@ -45440,11 +45440,11 @@ Object.defineProperty(exports, "CollapsibleTrigger", {
45440
45440
  });
45441
45441
  Object.defineProperty(exports, "miewebUIPreset", {
45442
45442
  enumerable: true,
45443
- get: function () { return chunkPBRXDB5K_cjs.miewebUIPreset; }
45443
+ get: function () { return chunkE6BQVAHF_cjs.miewebUIPreset; }
45444
45444
  });
45445
45445
  Object.defineProperty(exports, "miewebUISafelist", {
45446
45446
  enumerable: true,
45447
- get: function () { return chunkPBRXDB5K_cjs.miewebUISafelist; }
45447
+ get: function () { return chunkE6BQVAHF_cjs.miewebUISafelist; }
45448
45448
  });
45449
45449
  Object.defineProperty(exports, "Accordion", {
45450
45450
  enumerable: true,