chordia-ui 3.2.2 → 3.2.4

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 (39) hide show
  1. package/README.md +61 -0
  2. package/dist/IntegrationCard.cjs.js +2 -0
  3. package/dist/IntegrationCard.cjs.js.map +1 -0
  4. package/dist/IntegrationCard.es.js +217 -0
  5. package/dist/IntegrationCard.es.js.map +1 -0
  6. package/dist/UploadInteraction.cjs.js +2 -0
  7. package/dist/UploadInteraction.cjs.js.map +1 -0
  8. package/dist/UploadInteraction.es.js +379 -0
  9. package/dist/UploadInteraction.es.js.map +1 -0
  10. package/dist/components/layout.cjs.js +2 -2
  11. package/dist/components/layout.cjs.js.map +1 -1
  12. package/dist/components/layout.es.js +202 -411
  13. package/dist/components/layout.es.js.map +1 -1
  14. package/dist/components/onboarding.cjs.js +2 -0
  15. package/dist/components/onboarding.cjs.js.map +1 -0
  16. package/dist/components/onboarding.es.js +712 -0
  17. package/dist/components/onboarding.es.js.map +1 -0
  18. package/dist/index.cjs.js +1 -1
  19. package/dist/index.cjs2.js +2 -2
  20. package/dist/index.cjs2.js.map +1 -1
  21. package/dist/index.es.js +49 -41
  22. package/dist/index.es.js.map +1 -1
  23. package/dist/index.es2.js +869 -811
  24. package/dist/index.es2.js.map +1 -1
  25. package/dist/pages/interactionDetails.cjs.js +1 -1
  26. package/dist/pages/interactionDetails.cjs.js.map +1 -1
  27. package/dist/pages/interactionDetails.es.js +16 -15
  28. package/dist/pages/interactionDetails.es.js.map +1 -1
  29. package/dist/style.css +1 -1
  30. package/package.json +5 -1
  31. package/src/components/index.js +3 -0
  32. package/src/components/login/LoginPage.jsx +107 -5
  33. package/src/components/onboarding/AddTeammates.jsx +278 -0
  34. package/src/components/onboarding/ConnectData.jsx +89 -0
  35. package/src/components/onboarding/GettingStarted.jsx +524 -0
  36. package/src/components/onboarding/UploadEvaluate.jsx +255 -0
  37. package/src/components/onboarding/UploadInteraction.jsx +186 -0
  38. package/src/components/onboarding/index.js +5 -0
  39. package/src/tokens/colors.css +13 -0
@@ -1 +1 @@
1
- {"version":3,"file":"interactionDetails.cjs.js","sources":["../../src/components/pages/interactionDetails/CoachingSynthesisCard.jsx","../../src/components/pages/interactionDetails/InteractionContext.jsx","../../src/components/pages/interactionDetails/InteractionScores.jsx","../../src/components/pages/interactionDetails/InteractionSignals.jsx","../../src/components/pages/interactionDetails/InteractionGuidance.jsx","../../src/components/pages/interactionDetails/InteractionNBA.jsx","../../src/components/pages/interactionDetails/InteractionRecording.jsx","../../src/components/pages/interactionDetails/InteractionTranscript.jsx","../../src/components/common/MessageThread.jsx","../../src/components/pages/interactionDetails/InteractionDetailPanel.jsx","../../src/components/pages/interactionDetails/ExpandPatternComparison.jsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { TrendingUp, Lightbulb, Building, MessageSquareQuote } from \"lucide-react\";\n\n/**\n * CoachingSynthesisCard — displays LLM-generated coaching synthesis from Compass.\n *\n * Props:\n * - data object Coaching synthesis response (see shape below)\n * - loading boolean Show shimmer loading state\n * - error string Error message to display\n *\n * Data shape (from compass/summaries/coaching.py):\n * - one_liner string One-sentence summary\n * - context string Situational factors\n * - strengths Array<{ text: string, quote?: string }>\n * - improvements Array<{ text: string, quote?: string }>\n * - organizational Array<{ text: string, quote?: string }> (alias: organizational_insights)\n * - overall string \"effective\" | \"strong\" | \"needs_improvement\" | \"mixed\"\n */\n\nconst STYLE_ID = \"coaching-synthesis-keyframes\";\n\nfunction ensureKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n @keyframes coaching-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n @keyframes coaching-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n }\n `;\n document.head.appendChild(style);\n}\n\nexport default function CoachingSynthesisCard({ data, loading, error }) {\n React.useEffect(() => { ensureKeyframes(); }, []);\n\n // Loading state\n if (loading) {\n return (\n <div style={{\n padding: \"20px 0\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n }}>\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n }}>\n <div style={{\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n background: \"var(--rail-tone)\",\n animation: \"coaching-pulse 1.5s ease-in-out infinite\",\n }} />\n <span style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--rail-tone)\",\n fontFamily: \"var(--font-sans)\",\n fontWeight: 500,\n }}>\n Compass is synthesizing coaching insights…\n </span>\n </div>\n {/* Shimmer lines */}\n {[180, 260, 220].map((w, i) => (\n <div\n key={i}\n style={{\n height: 10,\n width: w,\n maxWidth: \"100%\",\n borderRadius: 4,\n background: \"linear-gradient(90deg, var(--hover-warm-subtle) 25%, var(--hover-warm) 50%, var(--hover-warm-subtle) 75%)\",\n backgroundSize: \"200% 100%\",\n animation: `coaching-shimmer 1.8s ease-in-out infinite`,\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div style={{\n padding: \"16px 0\",\n fontSize: \"var(--text-base)\",\n color: \"var(--text-faint)\",\n fontFamily: \"var(--font-sans)\",\n }}>\n Unable to generate coaching summary.\n </div>\n );\n }\n\n // No data\n if (!data) return null;\n\n const strengths = data.strengths || [];\n const improvements = data.improvements || [];\n const organizational = data.organizational || data.organizational_insights || [];\n const oneLiner = typeof data.one_liner === \"string\" ? data.one_liner : data.one_liner?.text || \"\";\n const context = typeof data.context === \"string\" ? data.context : data.context?.text || \"\";\n\n return (\n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 14,\n fontFamily: \"var(--font-sans)\",\n }}>\n {/* One-liner */}\n {oneLiner && (\n <div style={{\n fontSize: \"var(--text-lg)\",\n fontWeight: 600,\n color: \"var(--text-strong)\",\n lineHeight: 1.4,\n }}>\n {oneLiner}\n </div>\n )}\n\n {/* Context */}\n {context && (\n <div style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-muted)\",\n lineHeight: 1.45,\n }}>\n {context}\n </div>\n )}\n\n {/* Strengths */}\n {strengths.length > 0 && (\n <CoachingSection\n icon={<TrendingUp size={13} />}\n label=\"Strengths\"\n color=\"var(--rail-discovery)\"\n items={strengths}\n />\n )}\n\n {/* Improvements */}\n {improvements.length > 0 && (\n <CoachingSection\n icon={<Lightbulb size={13} />}\n label=\"Improvements\"\n color=\"var(--rail-compliance)\"\n items={improvements}\n />\n )}\n\n {/* Organizational */}\n {organizational.length > 0 && (\n <CoachingSection\n icon={<Building size={13} />}\n label=\"Organizational\"\n color=\"var(--rail-outcome)\"\n items={organizational}\n />\n )}\n\n {/* Overall rating */}\n {data.overall && (\n <div style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-faint)\",\n fontStyle: \"italic\",\n marginTop: 2,\n }}>\n Overall: {data.overall.replace(/_/g, \" \")}\n </div>\n )}\n </div>\n );\n}\n\nfunction CoachingSection({ icon, label, color, items }) {\n return (\n <div>\n {/* Section header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 5,\n marginBottom: 6,\n color,\n fontSize: \"var(--text-base)\",\n fontWeight: 650,\n letterSpacing: \"0.04em\",\n }}>\n {icon}\n {label}\n </div>\n\n {/* Items */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {items.map((item, i) => {\n const text = typeof item === \"string\" ? item : item?.text || \"\";\n const quote = typeof item === \"object\" ? item?.quote : null;\n\n return (\n <div key={i} style={{ paddingLeft: 14 }}>\n <div style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-base)\",\n lineHeight: 1.4,\n }}>\n • {text}\n </div>\n {quote && (\n <div style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 4,\n marginTop: 3,\n paddingLeft: 8,\n }}>\n <MessageSquareQuote\n size={10}\n style={{\n color: \"var(--text-faint)\",\n flexShrink: 0,\n marginTop: 2,\n }}\n />\n <span style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-muted)\",\n fontStyle: \"italic\",\n lineHeight: 1.35,\n }}>\n \"{quote}\"\n </span>\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport CardBase from '../../primitives/Card.jsx';\n\nfunction fmtDur(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nexport default function InteractionContext({ title, meta, callPurpose, classification, dimensions }) {\n const cp = callPurpose || {};\n const cls = classification || {};\n\n return (\n <CardBase variant=\"elevated\" padding=\"sm\">\n <div style={{ fontSize: 'var(--text-md)', fontWeight: 550, color: 'var(--text-strong)', lineHeight: 1.375, marginBottom: 6 }}>\n {title}\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '4px 12px', fontSize: 11, color: 'var(--text-muted)' }}>\n {meta.evaluated_dt && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Date</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{new Date(meta.evaluated_dt).toLocaleString()}</div></div>}\n {meta.duration_seconds != null && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Duration</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{fmtDur(meta.duration_seconds)}</div></div>}\n {meta.message_count && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Messages</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{meta.message_count}</div></div>}\n {cp.interaction_direction && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Direction</span><div style={{ color: 'var(--text-base)' }}>{cp.interaction_direction}</div></div>}\n {cp.interaction_driver && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Driver</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{cp.interaction_driver}</div></div>}\n {cp.customer_intent && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Intent</span><div style={{ color: 'var(--text-base)' }}>{cp.customer_intent}</div></div>}\n {cls.interaction_paradigm && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Paradigm</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{cls.interaction_paradigm}</div></div>}\n {dimensions.map((dim, i) => (\n <div key={i}><span style={{ fontSize: 10, color: 'var(--text-faint)' }}>{dim.label || dim.key}</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{dim.value}</div></div>\n ))}\n </div>\n {meta.session_id && (\n <div style={{ fontSize: 10, color: 'var(--text-faint)', fontFamily: 'var(--font-mono)', marginTop: 4, userSelect: 'all' }}>\n {meta.session_id}\n </div>\n )}\n </CardBase>\n );\n}","import React from 'react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\n\nexport default function InteractionScores({ scores }) {\n if (!scores?.length) return null;\n\n return (\n <DetailCard title=\"Scores\">\n <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>\n {scores.map((s, i) => {\n const val = s.value != null ? Math.round(s.value) : null;\n return (\n <div key={i} style={{ textAlign: 'center', minWidth: 48 }}>\n <div style={{ fontSize: 20, fontWeight: 700, color: 'var(--text-ink)' }}>{val ?? '—'}</div>\n <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)', marginTop: 2 }}>{s.label || s.key}</div>\n </div>\n );\n })}\n </div>\n </DetailCard>\n );\n}","import React, { useMemo } from 'react';\nimport { Target, CheckCircle, Lightbulb, Scale, Zap, MessageSquare, FileText, ChevronDown } from 'lucide-react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport SectionLabel from '../../primitives/SectionLabel.jsx';\nimport EvidenceItem from '../../common/EvidenceItem.jsx';\n\nconst GROUP_LABELS = {\n outcome: { label: 'Outcome', icon: <Target size={12} />, color: 'var(--rail-outcome)' },\n process: { label: 'Process & Protocol', icon: <FileText size={12} />, color: 'var(--rail-discovery)' },\n compliance: { label: 'Compliance', icon: <Scale size={12} />, color: 'var(--rail-compliance)' },\n customer_friction: { label: 'Customer Friction', icon: <Zap size={12} />, color: 'var(--rail-coral)' },\n experience: { label: 'Experience', icon: <MessageSquare size={12} />, color: 'var(--rail-teal)' },\n};\n\nconst KIND_COLORS = {\n risk: { icon: <Zap size={10} />, color: 'var(--rail-signal-churn)' },\n opportunity: { icon: <Lightbulb size={10} />, color: 'var(--state-unknown)' },\n excellence: { icon: <CheckCircle size={10} />, color: 'var(--rail-teal)' },\n};\n\nexport default function InteractionSignals({\n signals,\n expandedSignals,\n toggleSignal,\n playEvidence,\n timelinePlaying,\n currentTimeSeconds,\n highlightTurns,\n borderRadius\n}) {\n if (!signals?.signals?.length) return null;\n\n const grouped = useMemo(() => {\n const result = {};\n for (const s of signals.signals) {\n const g = s.group || 'experience';\n if (!result[g]) result[g] = [];\n result[g].push(s);\n }\n return result;\n }, [signals]);\n\n return (\n <DetailCard title={`Signals (${signals.present_count} present / ${signals.total_signals_evaluated} evaluated)`} borderRadius={borderRadius}>\n {Object.entries(grouped).map(([groupKey, groupSignals]) => {\n const info = GROUP_LABELS[groupKey] || GROUP_LABELS.experience;\n\n return (\n <div key={groupKey} style={{ marginBottom: 10 }}>\n <SectionLabel style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {info.icon}\n <span>{info.label}</span>\n </SectionLabel>\n\n <div style={{ marginTop: 4, display: 'flex', flexDirection: 'column', gap: 6 }}>\n {groupSignals.map((s, i) => {\n const name = s.display_name || s.key || '';\n const delta = s.baseline?.delta;\n const hasObs = s.observations?.length > 0;\n const isExpanded = expandedSignals.has(s.key);\n \n // Map signal group to Tag variant\n const getVariant = (group) => {\n switch (group) {\n case 'outcome': return 'phase';\n case 'process': return 'tool';\n case 'compliance': return 'policy';\n case 'customer_friction': return 'default';\n case 'experience': return 'global';\n default: return 'default';\n }\n };\n \n return (\n <div\n key={i}\n id={`signal-${s.key}`}\n style={{\n border: '1px solid var(--border, rgba(52, 58, 64, 0.12))',\n borderRadius: 'var(--radius-md, 8px)',\n background: 'var(--paper, rgba(255, 255, 255, 0.98))',\n overflow: 'hidden',\n }}\n >\n <button\n type=\"button\"\n onClick={(e) => {\n if (hasObs) {\n toggleSignal(s.key);\n e.currentTarget.blur();\n }\n }}\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '6px 10px',\n background: 'transparent',\n borderTop: '1px solid transparent',\n borderRight: '1px solid transparent',\n borderLeft: '1px solid transparent',\n borderBottom: '1px solid var(--border, rgba(52, 58, 64, 0.08))',\n cursor: hasObs ? 'pointer' : 'default',\n }}\n title={[\n s.confidence != null ? `Confidence: ${Math.round(s.confidence * 100)}%` : '',\n delta != null ? `Δ baseline: ${delta > 0 ? '+' : ''}${(delta * 100).toFixed(1)}%` : '',\n ].filter(Boolean).join(' · ')}\n >\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n whiteSpace: 'nowrap',\n }}\n >\n {KIND_COLORS[s.kind]?.icon}\n <span>{name}</span>\n {hasObs && (\n <span\n style={{\n marginLeft: 4,\n fontSize: 10,\n opacity: 0.6,\n }}\n >\n ({s.observations.length})\n </span>\n )}\n </span>\n {hasObs && (\n <ChevronDown\n size={14}\n style={{\n color: 'var(--text-muted)',\n flexShrink: 0,\n transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 0.16s ease',\n }}\n />\n )}\n </button>\n\n {isExpanded && s.observations && (\n <div style={{ width: '100%', margin: '0 0 6px' }}>\n {s.observations.map((obs, oi) => (\n <div key={oi} style={{ marginBottom: 6 }}>\n <div\n style={{\n display: 'flex',\n borderRadius: 'var(--radius-sm, 8px)',\n background: 'var(--paper, #fff)',\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n width: 3,\n background: info.color,\n }}\n />\n <div\n style={{\n flex: 1,\n fontSize: 'var(--text-sm)',\n color: 'var(--text-muted)',\n padding: '8px 12px',\n }}\n >\n <div\n style={{\n fontWeight: 600,\n color: 'var(--text-base)',\n marginBottom: 3,\n fontSize: 'var(--text-base)',\n }}\n >\n {obs.key || ''}\n </div>\n <div style={{ marginBottom: 6, lineHeight: 1.4 }}>\n {obs.reason || obs.explanation || ''}\n </div>\n {obs.evidence?.map((ev, ei) => {\n const startMs = ev.start_ms;\n const endMs = ev.end_ms;\n\n let isPlayingSegment = false;\n if (startMs != null && timelinePlaying) {\n const startSec = startMs / 1000;\n const endSec =\n endMs != null ? endMs / 1000 : startSec + 1;\n const cs = currentTimeSeconds ?? 0;\n isPlayingSegment =\n cs >= startSec && cs <= endSec + 0.25;\n }\n\n return (\n <EvidenceItem\n key={ei}\n ev={ev}\n isPlaying={isPlayingSegment}\n railColor={info.color}\n onPlay={(startMs, endMs) =>\n playEvidence?.(startMs, endMs, ev.turn_ids)\n }\n onHighlight={highlightTurns}\n />\n );\n })}\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </DetailCard>\n );\n}","import React from 'react';\nimport { CheckCircle, Lightbulb, Zap, CornerDownRight } from 'lucide-react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport EvidenceItem from '../../common/EvidenceItem.jsx';\n\nconst KIND_COLORS = {\n risk: { icon: <Zap size={10} />, color: 'var(--rail-signal-churn)' },\n opportunity: { icon: <Lightbulb size={10} />, color: 'var(--state-unknown)' },\n excellence: { icon: <CheckCircle size={10} />, color: 'var(--rail-teal)' },\n};\n\nexport default function InteractionGuidance({\n guidance,\n playEvidence,\n timelinePlaying,\n currentTimeSeconds,\n highlightTurns,\n borderRadius\n}) {\n if (!guidance?.items?.length) return null;\n\n return (\n <DetailCard title={`Guidance (${guidance.total_items} items)`} borderRadius={borderRadius}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {guidance.items.map((g, i) => {\n const ki = KIND_COLORS[g.guidance_kind] || KIND_COLORS.excellence;\n const ownerBadge = g.owner === 'organization'\n ? { bg: 'color-mix(in srgb, var(--rail-discovery) 15%, transparent)', color: 'var(--rail-discovery)', text: 'ORG' }\n : g.owner === 'shared'\n ? { bg: 'color-mix(in srgb, var(--state-unknown) 15%, transparent)', color: 'var(--state-unknown)', text: 'SHARED' }\n : { bg: 'color-mix(in srgb, var(--rail-teal) 10%, transparent)', color: 'var(--rail-teal)', text: 'AGENT' };\n return (\n <div key={i} style={{\n padding: '10px 12px', borderRadius: 'var(--radius)',\n background: 'var(--paper)', borderLeft: `3px solid ${ki.color}`,\n }}>\n <div style={{ fontSize: 'var(--text-base)', color: 'var(--text-strong)', display: 'flex', alignItems: 'center', gap: 5, fontWeight: 550 }}>\n {ki.icon} {g.title || ''}\n <span style={{\n fontSize: 9, padding: '1px 6px', borderRadius: 8, marginLeft: 4,\n background: ownerBadge.bg, color: ownerBadge.color, fontWeight: 600,\n }}>\n {ownerBadge.text}\n </span>\n </div>\n {g.detail && <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)', marginTop: 4, lineHeight: 1.4 }}>{g.detail}</div>}\n {/* Signal refs with evidence */}\n {g.signal_refs?.map((sr, si) => (\n <div key={si} style={{ marginTop: 6 }}>\n <div\n style={{\n fontSize: 10,\n color: 'var(--text-muted)',\n fontWeight: 600,\n marginBottom: 3,\n display: 'flex',\n alignItems: 'center',\n gap: 3,\n }}\n >\n <CornerDownRight size={10} /> {sr.display_name || sr.signal_key}\n {sr.confidence != null && (\n <span style={{ fontWeight: 400, opacity: 0.7 }}>\n {' '}\n ({Math.round(sr.confidence * 100)}%)\n </span>\n )}\n </div>\n {sr.evidence?.map((ev, ei) => {\n const startMs = ev.start_ms;\n const endMs = ev.end_ms;\n\n let isPlayingSegment = false;\n if (startMs != null && timelinePlaying) {\n const startSec = startMs / 1000;\n const endSec =\n endMs != null ? endMs / 1000 : startSec + 1;\n const cs = currentTimeSeconds ?? 0;\n isPlayingSegment =\n cs >= startSec && cs <= endSec + 0.25;\n }\n\n return (\n <EvidenceItem\n key={ei}\n ev={ev}\n isPlaying={isPlayingSegment}\n onPlay={(sMs, eMs) =>\n playEvidence?.(sMs, eMs, ev.turn_ids)\n }\n onHighlight={highlightTurns}\n />\n );\n })}\n </div>\n ))}\n </div>\n );\n })}\n </div>\n </DetailCard>\n );\n}","import React from 'react';\nimport { Target } from 'lucide-react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\n\nexport default function InteractionNBA({ nba }) {\n const items = nba?.recommendations || nba?.actions || [];\n if (!items.length) return null;\n\n return (\n <DetailCard title=\"Next Best Actions\">\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {items.slice(0, 8).map((r, i) => (\n <div key={i} style={{ fontSize: 11, color: 'var(--text-muted)', display: 'flex', alignItems: 'center', gap: 4 }}>\n <Target size={12} /> <strong style={{ color: 'var(--text-base)' }}>{r.action || r.title || ''}</strong>\n {r.rationale && ` — ${r.rationale}`}\n </div>\n ))}\n </div>\n </DetailCard>\n );\n}","import React from 'react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport Timeline from '../../media/Timeline.jsx';\n\nexport default function InteractionRecording({ \n audioUrl, \n timelineSegments, \n durationSeconds, \n currentTimeSeconds,\n timelinePlaying,\n playbackRate,\n onSeek,\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n audioRef\n}) {\n if (!audioUrl) return null;\n\n return (\n <DetailCard title=\"Recording\">\n <Timeline\n segments={timelineSegments}\n durationSeconds={durationSeconds || 0}\n currentTimeSeconds={currentTimeSeconds}\n onSeek={onSeek}\n showControls={true}\n hasRecording={true}\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n onTogglePlay={onTogglePlay}\n onSeekBack={onSeekBack}\n onSeekForward={onSeekForward}\n onSetPlaybackRate={onSetPlaybackRate}\n />\n {/* Hidden audio element for actual playback */}\n <audio ref={audioRef} preload=\"none\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n </DetailCard>\n );\n}","import React from 'react';\nimport TranscriptCard from '../../media/TranscriptCard.jsx';\n\nexport default function InteractionTranscript({ \n transcript, \n audioUrl,\n highlightedTurns,\n activeTurnIndex,\n timelinePlaying,\n turnObservations,\n setExpandedSignals,\n onTurnPlayPause,\n}) {\n if (!transcript?.messages?.length) return null;\n\n // Helper function to format time from ms to \"MM:SS–MM:SS\"\n const formatTimeRange = (startMs, endMs) => {\n if (startMs == null) return undefined;\n const formatTime = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n const start = formatTime(startMs);\n const end = endMs != null ? formatTime(endMs) : start;\n return `${start}–${end}`;\n };\n\n const turns = transcript.messages.map((m, i) => ({\n actor: m.actor === 'agent' ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer'),\n actorType: m.actor === 'agent' ? 'agent' : 'customer',\n text: m.text || '',\n timeRange: formatTimeRange(m.start ?? m.start_ms, m.end ?? m.end_ms),\n isHighlighted: highlightedTurns.has(i),\n highlightColor: (timelinePlaying && activeTurnIndex === i) \n ? (m.actor === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)')\n : undefined,\n observations: (turnObservations[i] || []).map(obs => ({\n ...obs,\n onClick: () => {\n // Expand the parent signal and scroll to it\n setExpandedSignals(prev => new Set([...prev, obs.signalKey]));\n setTimeout(() => {\n const el = document.getElementById(`signal-${obs.signalKey}`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 100);\n },\n })),\n }));\n\n return (\n <div id=\"transcript-container\">\n <TranscriptCard\n turns={turns}\n audioUrl={audioUrl}\n activeTurnIndex={activeTurnIndex}\n autoScrollActiveTurn={timelinePlaying}\n isExternalPlaying={timelinePlaying}\n onTurnPlayPause={onTurnPlayPause}\n />\n </div>\n );\n}","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Send, Clock, ChevronRight } from \"lucide-react\";\n\nconst messageActionButtonStyle = {\n padding: 0,\n border: \"none\",\n background: \"transparent\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.65)\",\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n};\n\n// Map author roles to consistent avatar background colors so that\n// supervisors, admins, and agents are visually distinct.\nconst roleColorMap = (role) => {\n if (!role) return null;\n const normalized = String(role).toLowerCase();\n if (normalized === \"supervisor\") return \"var(--rail-compliance)\";\n if (normalized === \"admin\" || normalized === \"administrator\")\n return \"var(--rail-discovery)\";\n if (normalized === \"agent\") return \"var(--rail-outcome)\";\n return null;\n};\n\n// Safely extract an array of messages/comments from a thread or payload,\n// tolerating different backend shapes (messages, comments, thread_messages, items, etc.).\nconst extractMessagesArray = (node) => {\n if (!node) return [];\n\n const directCandidates = [\n node.messages,\n node.comments,\n node.thread_messages,\n node.items,\n node.children,\n ];\n\n for (const candidate of directCandidates) {\n if (Array.isArray(candidate) && candidate.length) {\n return candidate;\n }\n }\n\n // Handle wrapped shapes like { messages: { data: [...] } }\n if (node.messages && Array.isArray(node.messages.data)) {\n return node.messages.data;\n }\n\n return [];\n};\n\n// Flatten a nested messages array (with optional replies) into a linear list\n// while preserving parent/child relationships via parentId and keeping\n// replies immediately after their parent.\nconst flattenMessages = (rawMessages, parentId = null, startIndex = 0) => {\n const out = [];\n\n (rawMessages || []).forEach((m, index) => {\n const author = m.author || {};\n const authorName = author.name || m.author_name || \"Unknown\";\n const initials =\n author.initials ||\n (authorName\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()) ||\n \"U\";\n const role = author.role || m.author_role;\n const roleColor = roleColorMap(role);\n const color = author.color || m.author_color || roleColor || \"#6B7C93\";\n\n const id = m.id || `msg-${startIndex + index}`;\n\n const baseMessage = {\n id,\n author: {\n name: authorName,\n initials,\n color,\n role,\n },\n content: m.content || m.text || \"\",\n timestamp: m.timestamp || m.created_at_display || m.created_at || \"\",\n type: m.type || \"comment\",\n isEdited: m.isEdited || m.is_edited || m.edited || false,\n references: m.references || [],\n parentId: m.parentId || m.parent_message_id || parentId || null,\n };\n\n out.push(baseMessage);\n\n if (Array.isArray(m.replies) && m.replies.length > 0) {\n out.push(\n ...flattenMessages(m.replies, id, startIndex + out.length)\n );\n }\n });\n\n return out;\n};\n\nconst formatTimestamp = (value) => {\n if (!value) return \"\";\n // If it's already a human-friendly string, just return as-is\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) return value;\n\n try {\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return value;\n\n const now = new Date();\n const sameDay =\n d.getFullYear() === now.getFullYear() &&\n d.getMonth() === now.getMonth() &&\n d.getDate() === now.getDate();\n\n const yesterday = new Date(now);\n yesterday.setDate(yesterday.getDate() - 1);\n const isYesterday =\n d.getFullYear() === yesterday.getFullYear() &&\n d.getMonth() === yesterday.getMonth() &&\n d.getDate() === yesterday.getDate();\n\n const timeStr = d.toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n });\n\n if (sameDay) {\n return `Today at ${timeStr}`;\n }\n\n if (isYesterday) {\n return `Yesterday at ${timeStr}`;\n }\n\n // Within last 7 days: show weekday name\n const diffMs = now.getTime() - d.getTime();\n const diffDays = diffMs / (1000 * 60 * 60 * 24);\n if (diffDays < 7 && diffDays > 0) {\n const weekday = d.toLocaleDateString(undefined, { weekday: \"long\" });\n return `${weekday} at ${timeStr}`;\n }\n\n // Older: fallback to short date\n const dateStr = d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: d.getFullYear() !== now.getFullYear() ? \"numeric\" : undefined,\n });\n\n return `${dateStr} at ${timeStr}`;\n } catch {\n return value;\n }\n};\n\n\n\n/**\n * MessageThread (common)\n *\n * Lightweight, UI-only message thread component for session discussion.\n * - Controlled via `messages` + `onSendMessage` (and optional reply/edit/delete callbacks)\n * - onSendMessage(payload) receives { content, parent_message_id } for API use\n * - onEditMessage({ id, content }): on API error return { success: false } or throw to keep edit UI open\n * - No data fetching or app-specific APIs – host app owns data + side effects\n *\n * `messages` items:\n * {\n * id: string;\n * author: { name: string; initials: string; color: string; role?: string };\n * content: string;\n * timestamp: string; // already formatted for display\n * type?: \"comment\" | \"system\";\n * isEdited?: boolean;\n * references?: Array<{ type: \"condition\" | \"timestamp\" | \"observation\"; label: string }>;\n * }\n *\n * When a structured `messageThread` payload is provided (for example from an\n * `interaction-message-thread` block), this component will normalize its\n * threads and messages into the same internal shape so existing threads and\n * comments render without the caller needing to reshape the data.\n */\nexport default function MessageThread({\n sessionTitle,\n sessionSubtitle,\n threadLabel,\n messages: initialMessages,\n messageThread,\n onSendMessage,\n onReplyMessage,\n onEditMessage,\n onDeleteMessage,\n onCreateNewThread, // optional: host can handle new thread creation\n onThreadSelect, // optional: host can react when a thread pill is selected\n currentUser,\n isLoading = false,\n}) {\n const [messageInput, setMessageInput] = useState(\"\");\n const [isFocused, setIsFocused] = useState(false);\n const [messages, setMessages] = useState(initialMessages || []);\n const [isSending, setIsSending] = useState(false);\n const [hoveredMessageId, setHoveredMessageId] = useState(null);\n // Thread tabs — start empty; callers or messageThread payload define them.\n const [threads, setThreads] = useState([]);\n const [activeThreadId, setActiveThreadId] = useState(null);\n const [replyingToMessageId, setReplyingToMessageId] = useState(null);\n const [replyDraft, setReplyDraft] = useState(\"\");\n const [editingMessageId, setEditingMessageId] = useState(null);\n const [editContent, setEditContent] = useState(\"\");\n const [deleteConfirmMessage, setDeleteConfirmMessage] = useState(null);\n const [showNewThreadCompose, setShowNewThreadCompose] = useState(false);\n const [newThreadInput, setNewThreadInput] = useState(\"\");\n const [isCreatingNewThread, setIsCreatingNewThread] = useState(false);\n const [expandedParentIds, setExpandedParentIds] = useState(new Set());\n\n const messagesEndRef = useRef(null);\n const messageInputRef = useRef(null);\n\n const normalizedRole =\n (currentUser && currentUser.role && String(currentUser.role).toLowerCase()) ||\n \"\";\n\n const displayCurrentUser = useMemo(() => {\n if (!currentUser) {\n return {\n name: \"You\",\n initials: \"YO\",\n color: \"#6B7C93\",\n };\n }\n\n const name = currentUser.name || \"You\";\n const initials =\n currentUser.initials ||\n (name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()) ||\n \"YO\";\n\n const role =\n currentUser.role && String(currentUser.role).toLowerCase();\n const roleColor = roleColorMap(role);\n\n const color = currentUser.color || roleColor || \"#6B7C93\";\n\n return {\n ...currentUser,\n name,\n initials,\n color,\n };\n }, [currentUser]);\n const canCreateNewThread =\n normalizedRole === \"supervisor\" || normalizedRole === \"admin\";\n\n const childrenByParentId = useMemo(() => {\n const map = {};\n (messages || []).forEach((m) => {\n if (!m.parentId) return;\n if (!map[m.parentId]) map[m.parentId] = [];\n map[m.parentId].push(m);\n });\n return map;\n }, [messages]);\n\n const topLevelMessages = useMemo(\n () => (messages || []).filter((m) => !m.parentId),\n [messages]\n );\n\n // Shared helpers so reply/edit/delete checks are consistent for\n // both top‑level messages and nested replies.\n const isChildReply = (id) => replyingToMessageId === id;\n const isChildEdit = (id) => editingMessageId === id;\n const isChildDelete = (id) =>\n deleteConfirmMessage && deleteConfirmMessage.id === id;\n\n const hasHeader = threadLabel || sessionTitle || sessionSubtitle;\n const replyingToMessage = replyingToMessageId\n ? messages.find((m) => m.id === replyingToMessageId)\n : null;\n\n useEffect(() => {\n // When caller passes explicit messages (and no structured messageThread),\n // keep internal state in sync. Avoid resetting when using messageThread.\n if (messageThread) return;\n if (!initialMessages) return;\n setMessages(initialMessages);\n }, [initialMessages, messageThread]);\n\n // Normalize an optional `messageThread` payload (e.g. from interaction-detail data)\n // into local threads + messages so existing backend data shows up in the UI.\n useEffect(() => {\n if (!messageThread) return;\n\n const rawThreads = Array.isArray(messageThread.threads)\n ? messageThread.threads\n : Array.isArray(messageThread.items)\n ? messageThread.items\n : [];\n\n // Case 1: multi-thread payload\n if (rawThreads.length > 0) {\n const normalizedThreads = rawThreads.map((t, index) => {\n const id = t.id || t.thread_id || `thread-${index + 1}`;\n const label =\n t.label ||\n t.title ||\n (index === 0 ? threadLabel || \"Session\" : `Thread ${index + 1}`);\n\n const rawMessagesForThread = extractMessagesArray(t);\n const messagesForThread = flattenMessages(rawMessagesForThread);\n\n return { id, label, messages: messagesForThread };\n });\n\n // Prefer payload threads; do not invent a default \"Session\" thread.\n setThreads(normalizedThreads);\n\n const firstWithMessages =\n normalizedThreads.find((t) => (t.messages || []).length > 0) ||\n normalizedThreads[0];\n\n const flatMessages = firstWithMessages?.messages || [];\n setMessages(flatMessages);\n // Start with all replies collapsed; user can expand per‑message.\n setExpandedParentIds(new Set());\n setActiveThreadId(firstWithMessages?.id || null);\n return;\n }\n\n // Case 2: single-thread payload with flat messages\n const rawFlat = extractMessagesArray(messageThread);\n if (rawFlat.length) {\n const mappedMessages = flattenMessages(rawFlat);\n\n setMessages(mappedMessages);\n // Start with all replies collapsed; user can expand per‑message.\n setExpandedParentIds(new Set());\n\n // Single-thread payload without an explicit threads array: create one\n // pill using the thread's own title so we don't show a generic \"Session\".\n const singleId = messageThread.id || \"thread-1\";\n const singleLabel =\n messageThread.title || threadLabel || \"Thread 1\";\n\n setThreads([\n {\n id: singleId,\n label: singleLabel,\n },\n ]);\n setActiveThreadId(singleId);\n }\n }, [messageThread, threadLabel]);\n useEffect(() => {\n // Keep the primary thread label aligned with the provided threadLabel\n if (!threadLabel) return;\n setThreads((prev) =>\n prev.map((thread, index) =>\n index === 0 ? { ...thread, label: threadLabel } : thread\n )\n );\n }, [threadLabel]);\n\n useEffect(() => {\n if (!messagesEndRef.current) return;\n if (!messages || messages.length === 0) return;\n // Keep the messages scrolled to the bottom *within* the thread container\n // without forcing the entire page to scroll.\n const container = messagesEndRef.current.parentElement;\n if (container) {\n container.scrollTop = container.scrollHeight;\n } else {\n messagesEndRef.current.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\n }\n }, [messages]);\n\n const handleNewThreadSubmit = async () => {\n const trimmed = newThreadInput.trim();\n if (!trimmed) return;\n setIsCreatingNewThread(true);\n try {\n const newId = `thread-${Date.now()}`;\n setThreads((prev) => [\n ...prev,\n {\n id: newId,\n label: trimmed.slice(0, 32) || `Thread ${prev.length + 1}`,\n },\n ]);\n setActiveThreadId(newId);\n await onCreateNewThread?.(trimmed);\n setNewThreadInput(\"\");\n setShowNewThreadCompose(false);\n } finally {\n setIsCreatingNewThread(false);\n }\n };\n\n const handleNewThreadCancel = () => {\n setShowNewThreadCompose(false);\n setNewThreadInput(\"\");\n };\n\n const handleSend = async () => {\n const trimmed = messageInput.trim();\n if (!trimmed) return;\n\n const content = trimmed;\n setMessageInput(\"\");\n\n const optimisticId = `temp-${Date.now()}`;\n const optimisticMessage = {\n id: optimisticId,\n author: displayCurrentUser,\n content,\n timestamp: \"Just now\",\n type: \"comment\",\n isOptimistic: true,\n parentId: replyingToMessageId || null,\n };\n\n setMessages((prev) => [...prev, optimisticMessage]);\n\n if (onSendMessage) {\n setIsSending(true);\n try {\n await onSendMessage({\n content,\n parent_message_id: replyingToMessageId || null,\n });\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === optimisticId ? { ...msg, isOptimistic: false } : msg\n )\n );\n } catch {\n setMessages((prev) => prev.filter((msg) => msg.id !== optimisticId));\n } finally {\n setIsSending(false);\n }\n setReplyingToMessageId(null);\n return;\n }\n\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === optimisticId ? { ...msg, isOptimistic: false } : msg\n )\n );\n setReplyingToMessageId(null);\n };\n\n const handleKeyPress = (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleReplyClick = (message) => {\n setReplyingToMessageId(message.id);\n setReplyDraft(\"\");\n setEditingMessageId(null);\n setEditContent(\"\");\n setHoveredMessageId(null);\n onReplyMessage?.(message);\n };\n\n const handleInlineReplySend = async (parentMessageId) => {\n const trimmed = replyDraft.trim();\n if (!trimmed) return;\n\n const optimisticId = `reply-${Date.now()}`;\n const optimisticReply = {\n id: optimisticId,\n author: displayCurrentUser,\n content: trimmed,\n timestamp: \"Just now\",\n type: \"comment\",\n isOptimistic: !onSendMessage,\n parentId: parentMessageId,\n };\n\n setMessages((prev) => [...prev, optimisticReply]);\n\n setIsSending(true);\n try {\n if (onSendMessage) {\n await onSendMessage({\n content: trimmed,\n parent_message_id: parentMessageId,\n });\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === optimisticId ? { ...msg, isOptimistic: false } : msg\n )\n );\n }\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n } catch {\n if (onSendMessage) {\n setMessages((prev) => prev.filter((msg) => msg.id !== optimisticId));\n }\n } finally {\n setIsSending(false);\n }\n };\n\n const handleEditClick = (message) => {\n setEditingMessageId(message.id);\n setEditContent(message.content || \"\");\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n setHoveredMessageId(null);\n };\n\n const handleEditSubmit = async () => {\n const trimmed = editContent.trim();\n if (!trimmed || !editingMessageId) return;\n try {\n const result = await onEditMessage?.({ id: editingMessageId, content: trimmed });\n // Keep edit UI open if host explicitly reports failure (e.g. API 500).\n // Host can return { success: false } or throw; either way we do not update or close.\n if (result && typeof result === \"object\" && result.success === false) {\n return;\n }\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === editingMessageId\n ? { ...msg, content: trimmed, isEdited: true }\n : msg\n )\n );\n setEditingMessageId(null);\n setEditContent(\"\");\n } catch (err) {\n // Keep edit textarea + Cancel + Save visible on error; host can show a toast.\n // eslint-disable-next-line no-console\n console.error(\"MessageThread edit failed:\", err);\n }\n };\n\n const handleEditCancel = () => {\n setEditingMessageId(null);\n setEditContent(\"\");\n };\n\n const handleDeleteClick = (message) => {\n setDeleteConfirmMessage(message);\n setHoveredMessageId(null);\n };\n\n const handleDeleteConfirm = async () => {\n if (!deleteConfirmMessage) return;\n const msg = deleteConfirmMessage;\n setDeleteConfirmMessage(null);\n setMessages((prev) => prev.filter((m) => m.id !== msg.id));\n await onDeleteMessage?.(msg);\n };\n\n // Recursive renderer for a single message + its children\nconst renderMessageTree = (message, depth = 0) => {\n const children = childrenByParentId[message.id] || [];\n const hasChildren = children.length > 0;\n const isExpanded = expandedParentIds.has(message.id);\n const isEditing = isChildEdit(message.id);\n const isReplying = isChildReply(message.id);\n\n return (\n <div key={message.id}>\n <div\n onMouseEnter={() =>\n message.type !== \"system\" && setHoveredMessageId(message.id)\n }\n onMouseLeave={() => setHoveredMessageId(null)}\n style={{\n display: \"flex\",\n gap: \"12px\",\n opacity: message.type === \"system\" ? 0.75 : 1,\n padding: \"4px 0\",\n margin: \"0 -4px\",\n borderRadius: \"8px\",\n marginLeft: depth > 0 ? 16 : 0,\n }}\n >\n {message.type !== \"system\" ? (\n <div\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n background: message.author.color,\n color: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"11px\",\n fontWeight: 650,\n flexShrink: 0,\n }}\n >\n {message.author.initials}\n </div>\n ) : (\n <div\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n background: \"rgba(30, 33, 37, 0.1)\",\n color: \"rgba(30, 33, 37, 0.55)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Clock size={16} />\n </div>\n )}\n\n <div style={{ flex: 1, minWidth: 0 }}>\n {/* header: name + time + role chip + hover actions */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"baseline\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n marginBottom: \"6px\",\n justifyContent: \"space-between\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"baseline\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n }}\n >\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 650,\n color: \"rgba(30, 33, 37, 0.9)\",\n }}\n >\n {message.author.name}\n </span>\n {message.timestamp && (\n <span\n style={{\n fontSize: \"10px\",\n fontFamily: \"var(--default-mono-font-family)\",\n color: \"rgba(30, 33, 37, 0.5)\",\n }}\n >\n {formatTimestamp(message.timestamp)}\n </span>\n )}\n {message.author?.role && (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n fontSize: \"10px\",\n color: \"rgba(30, 33, 37, 0.6)\",\n background: \"rgba(30, 33, 37, 0.08)\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n fontWeight: 600,\n }}\n >\n {String(message.author.role)}\n </span>\n )}\n {(message.isEdited || message.is_edited) && (\n <span\n style={{\n fontSize: \"10px\",\n color: \"rgba(30, 33, 37, 0.5)\",\n fontStyle: \"italic\",\n }}\n >\n (Edited)\n </span>\n )}\n </div>\n\n {message.type !== \"system\" &&\n hoveredMessageId === message.id && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n flexShrink: 0,\n }}\n >\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleReplyClick(message);\n }}\n style={messageActionButtonStyle}\n >\n Reply\n </button>\n {onEditMessage && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleEditClick(message);\n }}\n style={messageActionButtonStyle}\n >\n Edit\n </button>\n )}\n {onDeleteMessage && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleDeleteClick(message);\n }}\n style={{\n ...messageActionButtonStyle,\n color: \"rgba(198, 99, 99, 0.9)\",\n }}\n >\n Delete\n </button>\n )}\n </div>\n )}\n </div>\n\n {/* body: edit vs text */}\n {isEditing ? (\n <div style={{ marginTop: \"4px\" }}>\n <textarea\n value={editContent}\n onChange={(e) => setEditContent(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleEditSubmit();\n }\n if (e.key === \"Escape\") handleEditCancel();\n }}\n placeholder=\"Edit message...\"\n autoFocus\n style={{\n width: \"100%\",\n minHeight: \"56px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n background: \"white\",\n border: \"1px solid rgba(52, 58, 64, 0.2)\",\n borderRadius: \"6px\",\n resize: \"vertical\",\n outline: \"none\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n marginBottom: \"8px\",\n }}\n />\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n justifyContent: \"flex-end\",\n alignItems: \"center\",\n }}\n >\n <button\n type=\"button\"\n onClick={handleEditCancel}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.45)\",\n background: \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background =\n \"rgba(30, 33, 37, 0.15)\";\n e.currentTarget.style.color =\n \"rgba(30, 33, 37, 0.7)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background =\n \"rgba(30, 33, 37, 0.1)\";\n e.currentTarget.style.color =\n \"rgba(30, 33, 37, 0.45)\";\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleEditSubmit}\n disabled={!editContent?.trim()}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: editContent?.trim()\n ? \"white\"\n : \"rgba(30, 33, 37, 0.45)\",\n background: editContent?.trim()\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: editContent?.trim() ? \"pointer\" : \"not-allowed\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n if (editContent?.trim()) {\n e.currentTarget.style.background = \"#4d7290\";\n }\n }}\n onMouseLeave={(e) => {\n if (editContent?.trim()) {\n e.currentTarget.style.background = \"#5e88b0\";\n }\n }}\n >\n Save\n </button>\n </div>\n </div>\n ) : (\n <div\n style={{\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n lineHeight: 1.55,\n marginBottom: message.references?.length ? \"8px\" : 0,\n }}\n >\n {message.content}\n </div>\n )}\n\n {/* inline reply box when replying to this id */}\n {isReplying && (\n <div style={{ marginTop: \"12px\" }}>\n <textarea\n value={replyDraft}\n onChange={(e) => setReplyDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n }\n }}\n placeholder=\"Type your reply...\"\n disabled={isSending}\n autoFocus\n style={{\n width: \"100%\",\n minHeight: \"64px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n background: \"white\",\n border: \"1px solid rgba(52, 58, 64, 0.16)\",\n borderRadius: \"6px\",\n resize: \"vertical\",\n outline: \"none\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n marginBottom: \"10px\",\n }}\n />\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n justifyContent: \"flex-end\",\n alignItems: \"center\",\n }}\n >\n <button\n type=\"button\"\n onClick={() => {\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n }}\n disabled={isSending}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.45)\",\n background: \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: isSending ? \"not-allowed\" : \"pointer\",\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => handleInlineReplySend(message.id)}\n disabled={!replyDraft.trim() || isSending}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color:\n replyDraft.trim() && !isSending\n ? \"white\"\n : \"rgba(30, 33, 37, 0.45)\",\n background:\n replyDraft.trim() && !isSending\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.12)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor:\n replyDraft.trim() && !isSending\n ? \"pointer\"\n : \"not-allowed\",\n }}\n >\n Send\n </button>\n </div>\n </div>\n )}\n\n {/* references block (unchanged) */}\n {/* ... your existing references pills ... */}\n\n {/* children: collapse/expand replies */}\n {hasChildren && (\n <div style={{ marginTop: 8 }}>\n <button\n type=\"button\"\n onClick={() =>\n setExpandedParentIds((prev) => {\n const next = new Set(prev);\n next.has(message.id)\n ? next.delete(message.id)\n : next.add(message.id);\n return next;\n })\n }\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"4px 8px\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.6)\",\n background: \"transparent\",\n border: \"none\",\n borderRadius: 6,\n cursor: \"pointer\",\n }}\n title={isExpanded ? \"Collapse replies\" : \"Expand replies\"}\n >\n <ChevronRight\n size={14}\n style={{\n flexShrink: 0,\n transform: isExpanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.2s ease\",\n }}\n />\n <span>\n {children.length} {children.length === 1 ? \"reply\" : \"replies\"}\n </span>\n </button>\n\n {isExpanded && (\n <div\n style={{\n marginTop: 8,\n marginLeft: 16,\n paddingLeft: 16,\n borderLeft: \"2px solid rgba(52, 58, 64, 0.14)\",\n }}\n >\n {children.map((child) =>\n renderMessageTree(child, depth + 1)\n )}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n background: \"rgba(255, 255, 255, 0.98)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n position: \"relative\",\n }}\n >\n {/* Delete confirmation overlay */}\n {deleteConfirmMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 50,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(30, 33, 37, 0.35)\",\n borderRadius: \"12px\",\n }}\n onClick={() => setDeleteConfirmMessage(null)}\n >\n <div\n style={{\n background: \"white\",\n borderRadius: \"12px\",\n padding: \"20px 24px\",\n boxShadow: \"0 8px 24px rgba(30, 33, 37, 0.15)\",\n maxWidth: \"320px\",\n width: \"90%\",\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <p\n style={{\n margin: 0,\n marginBottom: \"20px\",\n fontSize: \"14px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.9)\",\n lineHeight: 1.45,\n }}\n >\n Do you really want to delete?\n </p>\n <div\n style={{\n display: \"flex\",\n gap: \"10px\",\n justifyContent: \"flex-end\",\n }}\n >\n <button\n type=\"button\"\n onClick={() => setDeleteConfirmMessage(null)}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.45)\",\n background: \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleDeleteConfirm}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"white\",\n background: \"#5e88b0\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n }}\n >\n Delete\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Header */}\n {hasHeader && (\n <div\n style={{\n padding: \"14px 16px\",\n borderBottom: \"1px solid rgba(52, 58, 64, 0.12)\",\n background: \"rgba(255, 255, 255, 0.98)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n >\n <div>\n <div\n style={{\n fontSize: \"14px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.95)\",\n marginBottom: \"4px\",\n }}\n >\n {threadLabel || \"Session Discussion\"}\n </div>\n {(sessionTitle || sessionSubtitle) && (\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.52)\",\n }}\n >\n {sessionTitle || sessionSubtitle}\n </div>\n )}\n {threads.length > 0 && (\n <div\n style={{\n marginTop: \"8px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n }}\n >\n {threads.map((thread) => {\n const isActive = thread.id === activeThreadId;\n return (\n <button\n key={thread.id}\n type=\"button\"\n onClick={() => {\n setActiveThreadId(thread.id);\n if (Array.isArray(thread.messages)) {\n setMessages(thread.messages);\n // On thread switch, start with replies collapsed.\n setExpandedParentIds(new Set());\n }\n setHoveredMessageId(null);\n setReplyingToMessageId(null);\n setEditingMessageId(null);\n onThreadSelect?.(thread);\n }}\n style={{\n padding: \"4px 10px\",\n borderRadius: \"999px\",\n border: \"1px solid rgba(184, 156, 106, 0.35)\",\n background: isActive\n ? \"rgba(184, 156, 106, 0.16)\"\n : \"rgba(255, 255, 255, 0.9)\",\n color: \"rgba(30, 33, 37, 0.85)\",\n fontSize: \"11px\",\n fontWeight: 500,\n cursor: \"pointer\",\n }}\n >\n {thread.label}\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* \"+ New thread\" – only for supervisor/admin roles */}\n {canCreateNewThread && (\n <button\n type=\"button\"\n onClick={() => {\n setShowNewThreadCompose((prev) => !prev);\n }}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"6px 12px\",\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.75)\",\n background: \"transparent\",\n border: \"1px solid rgba(30, 33, 37, 0.12)\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n transition: \"background 0.15s ease, color 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background =\n \"rgba(231, 212, 162, 0.12)\";\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.9)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.75)\";\n }}\n title=\"Start a new discussion thread\"\n >\n <span\n style={{\n fontSize: 16,\n lineHeight: 1,\n marginTop: -1,\n }}\n >\n +\n </span>\n New thread\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* Messages list */}\n <div\n style={{\n flex: 1,\n overflowY: \"auto\",\n padding: \"16px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"16px\",\n }}\n >\n {/* Inline \"new thread\" compose */}\n {showNewThreadCompose && (\n <div\n style={{\n marginBottom: \"16px\",\n padding: \"12px\",\n background: \"rgba(30, 33, 37, 0.04)\",\n border: \"1px solid rgba(52, 58, 64, 0.14)\",\n borderRadius: \"8px\",\n }}\n >\n <textarea\n value={newThreadInput}\n onChange={(e) => setNewThreadInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleNewThreadSubmit();\n }\n }}\n placeholder=\"Start a new thread...\"\n disabled={isCreatingNewThread}\n style={{\n width: \"100%\",\n minHeight: \"64px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n background: \"white\",\n border: \"1px solid rgba(52, 58, 64, 0.16)\",\n borderRadius: \"6px\",\n resize: \"vertical\",\n outline: \"none\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n marginBottom: \"10px\",\n }}\n />\n <div style={{ display: \"flex\", gap: \"8px\", justifyContent: \"flex-end\" }}>\n <button\n type=\"button\"\n onClick={handleNewThreadCancel}\n disabled={isCreatingNewThread}\n style={{\n padding: \"6px 14px\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.7)\",\n background: \"rgba(30, 33, 37, 0.08)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: isCreatingNewThread ? \"not-allowed\" : \"pointer\",\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleNewThreadSubmit}\n disabled={!newThreadInput.trim() || isCreatingNewThread}\n style={{\n padding: \"6px 14px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"white\",\n background:\n newThreadInput.trim() && !isCreatingNewThread\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.25)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor:\n newThreadInput.trim() && !isCreatingNewThread\n ? \"pointer\"\n : \"not-allowed\",\n }}\n >\n {isCreatingNewThread ? \"Sending...\" : \"Send\"}\n </button>\n </div>\n </div>\n )}\n {isLoading ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"40px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n }}\n >\n Loading messages...\n </div>\n ) : topLevelMessages.length === 0 ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"40px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n }}\n >\n No messages yet. Start the conversation!\n </div>\n ) : (\n // topLevelMessages.map((message) => (\n // <div\n // key={message.id}\n // onMouseEnter={() =>\n // message.type !== \"system\" && setHoveredMessageId(message.id)\n // }\n // onMouseLeave={() => setHoveredMessageId(null)}\n // style={{\n // display: \"flex\",\n // gap: \"12px\",\n // opacity: message.type === \"system\" ? 0.75 : 1,\n // padding: \"4px 0\",\n // margin: \"0 -4px\",\n // borderRadius: \"8px\",\n // }}\n // >\n // {message.type !== \"system\" ? (\n // <div\n // style={{\n // width: \"36px\",\n // height: \"36px\",\n // borderRadius: \"50%\",\n // background: message.author.color,\n // color: \"white\",\n // display: \"flex\",\n // alignItems: \"center\",\n // justifyContent: \"center\",\n // fontSize: \"11px\",\n // fontWeight: 650,\n // flexShrink: 0,\n // }}\n // >\n // {message.author.initials}\n // </div>\n // ) : (\n // <div\n // style={{\n // width: \"36px\",\n // height: \"36px\",\n // borderRadius: \"50%\",\n // background: \"rgba(30, 33, 37, 0.1)\",\n // color: \"rgba(30, 33, 37, 0.55)\",\n // display: \"flex\",\n // alignItems: \"center\",\n // justifyContent: \"center\",\n // flexShrink: 0,\n // }}\n // >\n // <Clock size={16} />\n // </div>\n // )}\n\n // <div style={{ flex: 1, minWidth: 0 }}>\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // marginBottom: \"6px\",\n // justifyContent: \"space-between\",\n // }}\n // >\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // }}\n // >\n // <span\n // style={{\n // fontSize: \"13px\",\n // fontWeight: 650,\n // color: \"rgba(30, 33, 37, 0.9)\",\n // }}\n // >\n // {message.author.name}\n // </span>\n // {message.timestamp && (\n // <span\n // style={{\n // fontSize: \"10px\",\n // fontFamily: \"var(--default-mono-font-family)\",\n // color: \"rgba(30, 33, 37, 0.5)\",\n // }}\n // >\n // {formatTimestamp(message.timestamp)}\n // </span>\n // )}\n // {message.author?.role && (\n // <span\n // style={{\n // display: \"inline-flex\",\n // alignItems: \"center\",\n // fontSize: \"10px\",\n // color: \"rgba(30, 33, 37, 0.6)\",\n // background: \"rgba(30, 33, 37, 0.08)\",\n // padding: \"3px 8px\",\n // borderRadius: \"6px\",\n // textTransform: \"uppercase\",\n // letterSpacing: \"0.04em\",\n // fontWeight: 600,\n // }}\n // >\n // {String(message.author.role)}\n // </span>\n // )}\n // </div>\n\n // {message.type !== \"system\" &&\n // hoveredMessageId === message.id && (\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"12px\",\n // flexShrink: 0,\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleReplyClick(message);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Reply\n // </button>\n // {onEditMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleEditClick(message);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Edit\n // </button>\n // )}\n // {onDeleteMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleDeleteClick(message);\n // }}\n // style={{\n // ...messageActionButtonStyle,\n // color: \"rgba(198, 99, 99, 0.9)\",\n // }}\n // >\n // Delete\n // </button>\n // )}\n // </div>\n // )}\n // </div>\n\n // {isChildEdit(message.id) ? (\n // <div style={{ marginTop: \"6px\" }}>\n // <textarea\n // value={editContent}\n // onChange={(e) => setEditContent(e.target.value)}\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }\n // }}\n // placeholder=\"Edit message...\"\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border: \"1px solid rgba(52, 58, 64, 0.2)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"8px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: \"rgba(30, 33, 37, 0.45)\",\n // background: \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: \"pointer\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={handleEditSubmit}\n // disabled={!editContent.trim()}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: editContent.trim()\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background: editContent.trim()\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: editContent.trim() ? \"pointer\" : \"not-allowed\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // Save\n // </button>\n // </div>\n // </div>\n // ) : (\n // <div\n // style={{\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // lineHeight: 1.55,\n // }}\n // >\n // {message.content}\n // </div>\n // )}\n\n // {isChildReply(message.id) && (\n // <div style={{ marginTop: \"12px\" }}>\n // <textarea\n // value={replyDraft}\n // onChange={(e) => setReplyDraft(e.target.value)}\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }\n // }}\n // placeholder=\"Type your reply...\"\n // disabled={isSending}\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border: \"1px solid rgba(52, 58, 64, 0.16)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"10px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }}\n // disabled={isSending}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: \"rgba(30, 33, 37, 0.45)\",\n // background: \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: isSending ? \"not-allowed\" : \"pointer\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={() => handleInlineReplySend(message.id)}\n // disabled={!replyDraft.trim() || isSending}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // replyDraft.trim() && !isSending\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background:\n // replyDraft.trim() && !isSending\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.12)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor:\n // replyDraft.trim() && !isSending\n // ? \"pointer\"\n // : \"not-allowed\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // {isSending ? \"Sending...\" : \"Send\"}\n // </button>\n // </div>\n // </div>\n // )}\n\n // {childrenByParentId[message.id]?.length ? (\n // <div style={{ marginTop: \"8px\" }}>\n // <button\n // type=\"button\"\n // onClick={() =>\n // setExpandedParentIds((prev) => {\n // const next = new Set(prev);\n // if (next.has(message.id)) next.delete(message.id);\n // else next.add(message.id);\n // return next;\n // })\n // }\n // style={{\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // padding: 0,\n // border: \"none\",\n // background: \"transparent\",\n // cursor: \"pointer\",\n // fontSize: \"12px\",\n // fontWeight: 500,\n // color: \"rgba(30, 33, 37, 0.55)\",\n // fontFamily: \"inherit\",\n // }}\n // >\n // <ChevronRight\n // size={14}\n // style={{\n // flexShrink: 0,\n // transition: \"transform 0.2s ease\",\n // transform: expandedParentIds.has(message.id)\n // ? \"rotate(90deg)\"\n // : \"rotate(0deg)\",\n // }}\n // />\n // <span>\n // {childrenByParentId[message.id].length}{\" \"}\n // {childrenByParentId[message.id].length === 1\n // ? \"reply\"\n // : \"replies\"}\n // </span>\n // </button>\n // {expandedParentIds.has(message.id) && (\n // <div\n // style={{\n // marginTop: \"8px\",\n // marginLeft: \"16px\",\n // paddingLeft: \"16px\",\n // borderLeft:\n // \"2px solid rgba(52, 58, 64, 0.14)\",\n // }}\n // >\n // {childrenByParentId[message.id].map((reply) => {\n // const isReplyEditing = isChildEdit(reply.id);\n // const isReplyBeingRepliedTo = isChildReply(reply.id);\n\n // return (\n // <div\n // key={reply.id}\n // onMouseEnter={() => {\n // if (reply.type !== \"system\") {\n // setHoveredMessageId(reply.id);\n // }\n // }}\n // onMouseLeave={() => setHoveredMessageId(null)}\n // style={{\n // display: \"flex\",\n // gap: \"12px\",\n // padding: \"4px 0\",\n // margin: \"0 -4px\",\n // borderRadius: \"8px\",\n // }}\n // >\n // <div\n // style={{\n // width: \"28px\",\n // height: \"28px\",\n // borderRadius: \"50%\",\n // background: reply.author.color,\n // color: \"white\",\n // display: \"flex\",\n // alignItems: \"center\",\n // justifyContent: \"center\",\n // fontSize: \"10px\",\n // fontWeight: 650,\n // flexShrink: 0,\n // }}\n // >\n // {reply.author.initials}\n // </div>\n // <div style={{ flex: 1, minWidth: 0 }}>\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // marginBottom: \"4px\",\n // justifyContent: \"space-between\",\n // }}\n // >\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // }}\n // >\n // <span\n // style={{\n // fontSize: \"13px\",\n // fontWeight: 650,\n // color: \"rgba(30, 33, 37, 0.9)\",\n // }}\n // >\n // {reply.author.name}\n // </span>\n // {reply.timestamp && (\n // <span\n // style={{\n // fontSize: \"10px\",\n // fontFamily:\n // \"var(--default-mono-font-family)\",\n // color:\n // \"rgba(30, 33, 37, 0.5)\",\n // }}\n // >\n // {formatTimestamp(\n // reply.timestamp\n // )}\n // </span>\n // )}\n // {reply.author?.role && (\n // <span\n // style={{\n // display: \"inline-flex\",\n // alignItems: \"center\",\n // gap: \"4px\",\n // fontSize: \"10px\",\n // color:\n // \"rgba(30, 33, 37, 0.6)\",\n // background:\n // \"rgba(30, 33, 37, 0.08)\",\n // padding: \"3px 8px\",\n // borderRadius: \"6px\",\n // textTransform: \"uppercase\",\n // letterSpacing: \"0.04em\",\n // fontWeight: 600,\n // }}\n // >\n // {reply.author.role}\n // </span>\n // )}\n // </div>\n\n // {reply.type !== \"system\" &&\n // hoveredMessageId === reply.id && (\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"12px\",\n // flexShrink: 0,\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleReplyClick(reply);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Reply\n // </button>\n // {onEditMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleEditClick(reply);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Edit\n // </button>\n // )}\n // {onDeleteMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleDeleteClick(reply);\n // }}\n // style={{\n // ...messageActionButtonStyle,\n // color:\n // \"rgba(198, 99, 99, 0.9)\",\n // }}\n // >\n // Delete\n // </button>\n // )}\n // </div>\n // )}\n // </div>\n\n // {isReplyEditing ? (\n // <div style={{ marginTop: \"6px\" }}>\n // <textarea\n // value={editContent}\n // onChange={(e) =>\n // setEditContent(e.target.value)\n // }\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }\n // }}\n // placeholder=\"Edit message...\"\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border:\n // \"1px solid rgba(52, 58, 64, 0.2)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"8px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // \"rgba(30, 33, 37, 0.45)\",\n // background:\n // \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: \"pointer\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={handleEditSubmit}\n // disabled={!editContent.trim()}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: editContent.trim()\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background: editContent.trim()\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: editContent.trim()\n // ? \"pointer\"\n // : \"not-allowed\",\n // }}\n // >\n // Save\n // </button>\n // </div>\n // </div>\n // ) : (\n // <div\n // style={{\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // lineHeight: 1.55,\n // }}\n // >\n // {reply.content}\n // </div>\n // )}\n\n // {isReplyBeingRepliedTo && (\n // <div style={{ marginTop: \"12px\" }}>\n // <textarea\n // value={replyDraft}\n // onChange={(e) =>\n // setReplyDraft(e.target.value)\n // }\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }\n // }}\n // placeholder=\"Type your reply...\"\n // disabled={isSending}\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border:\n // \"1px solid rgba(52, 58, 64, 0.16)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"10px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }}\n // disabled={isSending}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // \"rgba(30, 33, 37, 0.45)\",\n // background:\n // \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: isSending\n // ? \"not-allowed\"\n // : \"pointer\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={() =>\n // handleInlineReplySend(reply.id)\n // }\n // disabled={\n // !replyDraft.trim() || isSending\n // }\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // replyDraft.trim() && !isSending\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background:\n // replyDraft.trim() && !isSending\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.12)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor:\n // replyDraft.trim() && !isSending\n // ? \"pointer\"\n // : \"not-allowed\",\n // }}\n // >\n // {isSending ? \"Sending...\" : \"Send\"}\n // </button>\n // </div>\n // </div>\n // )}\n // </div>\n // </div>\n // );\n // })}\n // </div>\n // )}\n // </div>\n // ) : null}\n // </div>\n // </div>\n // ))\n topLevelMessages.map((message) => renderMessageTree(message, 0))\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input area */}\n <div\n style={{\n padding: \"12px\",\n borderTop: \"1px solid rgba(52, 58, 64, 0.12)\",\n background: \"rgba(255, 255, 255, 0.95)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n alignItems: \"flex-end\",\n }}\n >\n <div\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n background: displayCurrentUser.color,\n color: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"11px\",\n fontWeight: 650,\n flexShrink: 0,\n }}\n >\n {displayCurrentUser.initials}\n </div>\n\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"8px\",\n }}\n >\n <textarea\n ref={messageInputRef}\n value={messageInput}\n onChange={(e) => setMessageInput(e.target.value)}\n onKeyDown={handleKeyPress}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n placeholder={\n replyingToMessage ? \"Type your reply...\" : \"Add a comment...\"\n }\n style={{\n width: \"100%\",\n minHeight: \"38px\",\n maxHeight: \"120px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.85)\",\n background: \"white\",\n border: `1px solid ${\n isFocused\n ? \"rgba(94, 136, 176, 0.35)\"\n : \"rgba(52, 58, 64, 0.16)\"\n }`,\n borderRadius: \"8px\",\n resize: \"vertical\",\n outline: \"none\",\n transition: \"border-color 0.15s ease\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n }}\n />\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n }}\n >\n <button\n type=\"button\"\n onClick={handleSend}\n disabled={!messageInput.trim() || isSending}\n style={{\n padding: \"8px 16px\",\n background:\n messageInput.trim() && !isSending\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n color:\n messageInput.trim() && !isSending\n ? \"white\"\n : \"rgba(30, 33, 37, 0.45)\",\n fontSize: \"12px\",\n fontWeight: 600,\n cursor:\n messageInput.trim() && !isSending\n ? \"pointer\"\n : \"not-allowed\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n transition: \"all 0.15s ease\",\n }}\n >\n {isSending ? (\n <>\n <div\n style={{\n width: \"14px\",\n height: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.3)\",\n borderTopColor: \"white\",\n borderRadius: \"50%\",\n animation: \"spin 0.6s linear infinite\",\n }}\n />\n Sending...\n </>\n ) : (\n <>\n <Send size={14} />\n Send\n </>\n )}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n","\"use client\";\n\nimport React, { useState, useEffect, useLayoutEffect, useRef, useMemo } from 'react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport { Tabs } from '../../index.js';\nimport CoachingSynthesisCard from './CoachingSynthesisCard.jsx';\nimport InteractionContext from './InteractionContext.jsx';\nimport InteractionScores from './InteractionScores.jsx';\nimport AgentLiftCard from '../../common/AgentLiftCard.jsx';\nimport InteractionSignals from './InteractionSignals.jsx';\nimport InteractionGuidance from './InteractionGuidance.jsx';\nimport InteractionNBA from './InteractionNBA.jsx';\nimport InteractionRecording from './InteractionRecording.jsx';\nimport InteractionTranscript from './InteractionTranscript.jsx';\nimport MessageThread from '../../common/MessageThread.jsx';\n\nfunction findBlock(blocks, id) {\n return blocks.find((b) => b.block_id === id);\n}\n\nfunction InteractionDetailPanel({\n data,\n audioUrl,\n coachingData,\n messageThread,\n coachingLoading,\n coachingError,\n // Optional callbacks for host apps to wire MessageThread to real APIs.\n onThreadSendMessage,\n onThreadEditMessage,\n onThreadDeleteMessage,\n onThreadCreateNewThread,\n onThreadSelect,\n threadLoading,\n threadCurrentUser,\n}) {\n const blocks = data.blocks || [];\n const evidenceIndex = data.evidence_index || {};\n const audioRef = useRef(null);\n const segmentEndHandlerRef = useRef(null);\n const [highlightedTurns, setHighlightedTurns] = useState(new Set());\n const [expandedSignals, setExpandedSignals] = useState(new Set());\n\n // Timeline state for audio playback integration\n const [currentTimeSeconds, setCurrentTimeSeconds] = useState(0);\n const [timelinePlaying, setTimelinePlaying] = useState(false);\n const [playbackRate, setPlaybackRate] = useState(1);\n\n // Extract block data\n const meta = findBlock(blocks, 'interaction-metadata')?.payload || {};\n const ctx = findBlock(blocks, 'interaction-context')?.payload || {};\n const summary = findBlock(blocks, 'interaction-summary')?.payload || {};\n const scores = findBlock(blocks, 'interaction-scores')?.payload || {};\n const signals = findBlock(blocks, 'interaction-signals')?.payload || {};\n const guidance = findBlock(blocks, 'interaction-guidance')?.payload || {};\n const transcript = findBlock(blocks, 'interaction-transcript')?.payload || {};\n // const messageThread = findBlock(blocks, 'interaction-message-thread')?.payload || {};\n const nba = findBlock(blocks, 'interaction-nba')?.payload || {};\n const dimensionsBlock = findBlock(blocks, 'interaction-dimensions')?.payload || {};\n const dimensions = (dimensionsBlock.dimensions || []).filter(d => d.value);\n const outcomeLift = findBlock(blocks, 'interaction-outcome-lift')?.payload || {};\n\n // Build turn → observation pills map from signals data\n const turnObservations = useMemo(() => {\n const map = {}; // turnIndex → [{label, reason, color, signalKey}]\n const GROUP_LABELS = {\n outcome: { color: 'var(--rail-outcome)' },\n process: { color: 'var(--rail-discovery)' },\n compliance: { color: 'var(--rail-compliance)' },\n customer_friction: { color: 'var(--rail-coral)' },\n experience: { color: 'var(--rail-teal)' },\n };\n\n for (const signal of (signals.signals || [])) {\n const groupInfo = GROUP_LABELS[signal.group] || {};\n for (const obs of (signal.observations || [])) {\n for (const ev of (obs.evidence || [])) {\n if (ev.turn_ids?.length) {\n for (const tid of ev.turn_ids) {\n if (!map[tid]) map[tid] = [];\n // Deduplicate by observation key per turn\n if (!map[tid].some(o => o.label === (obs.key || signal.display_name || signal.key))) {\n map[tid].push({\n label: obs.key || signal.display_name || signal.key,\n reason: obs.reason || obs.explanation || '',\n color: groupInfo.color || 'var(--state-present)',\n signalKey: signal.key,\n });\n }\n }\n }\n }\n }\n }\n return map;\n }, [signals.signals]);\n\n // Build timeline segments from transcript messages\n const timelineSegments = transcript.messages?.map((m, i) => {\n const startTime = (m.start ?? m.start_ms) ? (m.start ?? m.start_ms) / 1000 : 0;\n const endTime = (m.end ?? m.end_ms) ? (m.end ?? m.end_ms) / 1000 : startTime + 1;\n const isAgent = m.actor === 'agent';\n const actorName = isAgent ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer');\n\n return {\n startTime,\n endTime,\n actor: actorName,\n actorColor: isAgent ? 'var(--rail-outcome)' : 'var(--rail-discovery)',\n };\n }) || [];\n\n // Compute active turn index based on current playback time\n const activeTurnIndex = useMemo(() => {\n if (!timelinePlaying && currentTimeSeconds === 0) return -1;\n const messages = transcript.messages || [];\n const currentMs = currentTimeSeconds * 1000;\n for (let i = messages.length - 1; i >= 0; i--) {\n const startMs = messages[i].start ?? messages[i].start_ms;\n if (startMs != null && currentMs >= startMs) return i;\n }\n return -1;\n }, [currentTimeSeconds, timelinePlaying, transcript.messages]);\n\n // Timeline event handlers\n const handleTimelineSeek = (seconds) => {\n if (audioRef.current) {\n audioRef.current.currentTime = seconds;\n setCurrentTimeSeconds(seconds);\n }\n };\n\n const handleTimelineTogglePlay = () => {\n if (audioRef.current) {\n if (timelinePlaying) {\n audioRef.current.pause();\n setTimelinePlaying(false);\n } else {\n const p = audioRef.current.play();\n if (p !== undefined) p.catch(() => { }); // ignore AbortError when pause() interrupts play()\n setTimelinePlaying(true);\n }\n }\n };\n\n const handleTimelineSeekBack = () => {\n if (audioRef.current) {\n audioRef.current.currentTime = Math.max(0, audioRef.current.currentTime - 15);\n }\n };\n\n const handleTimelineSeekForward = () => {\n if (audioRef.current) {\n const duration = meta.duration_seconds || audioRef.current.duration || 0;\n audioRef.current.currentTime = Math.min(duration, audioRef.current.currentTime + 15);\n }\n };\n\n const handleSetPlaybackRate = (rate) => {\n if (audioRef.current) {\n audioRef.current.playbackRate = rate;\n setPlaybackRate(rate);\n }\n };\n\n // Update currentTimeSeconds from audio element\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const updateTime = () => setCurrentTimeSeconds(audio.currentTime);\n const handlePlay = () => setTimelinePlaying(true);\n const handlePause = () => setTimelinePlaying(false);\n const handleEnded = () => setTimelinePlaying(false);\n\n audio.addEventListener('timeupdate', updateTime);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n audio.addEventListener('ended', handleEnded);\n\n return () => {\n audio.removeEventListener('timeupdate', updateTime);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.removeEventListener('ended', handleEnded);\n };\n }, [audioUrl]);\n\n const playAudio = (startMs, endMs) => {\n const player = audioRef.current;\n if (!player || startMs == null) return;\n\n const startSec = startMs / 1000;\n player.currentTime = startSec;\n setCurrentTimeSeconds(startSec);\n\n const p = player.play();\n if (p !== undefined) p.catch(() => { }); // ignore AbortError when pause() interrupts play()\n\n // Clear any previous segment end handler so only one is active\n if (segmentEndHandlerRef.current) {\n player.removeEventListener('timeupdate', segmentEndHandlerRef.current);\n segmentEndHandlerRef.current = null;\n }\n\n if (endMs != null) {\n const endSec = endMs / 1000;\n const handler = () => {\n if (player.currentTime >= endSec) {\n player.pause();\n if (segmentEndHandlerRef.current) {\n player.removeEventListener('timeupdate', segmentEndHandlerRef.current);\n segmentEndHandlerRef.current = null;\n }\n }\n };\n segmentEndHandlerRef.current = handler;\n player.addEventListener('timeupdate', handler);\n }\n };\n\n // Used by Signals evidence rows: toggle play/pause for a specific segment\n // and scroll the transcript container into view for the related turns.\n const handleEvidencePlayToggle = (startMs, endMs, turnIds) => {\n const player = audioRef.current;\n if (!player || startMs == null) return;\n\n const startSec = startMs / 1000;\n const endSec = endMs != null ? endMs / 1000 : startSec + 1;\n const currentSec = player.currentTime;\n\n const isInSegment =\n timelinePlaying &&\n currentSec >= startSec &&\n (endSec == null || currentSec <= endSec + 0.25);\n\n // If already playing this segment, pause instead of restarting\n if (isInSegment) {\n player.pause();\n return;\n }\n\n // Otherwise, play the requested segment and redirect to transcript\n playAudio(startMs, endMs);\n if (turnIds?.length) {\n highlightTurns(turnIds);\n }\n };\n\n const handleTranscriptTurnPlayPause = (turn, index) => {\n const messages = transcript.messages || [];\n const message = messages[index];\n const player = audioRef.current;\n\n if (!message || !player) return;\n\n const startMs = message.start ?? message.start_ms;\n const endMs = message.end ?? message.end_ms;\n\n // If this turn is already active and playing, pause playback\n if (timelinePlaying && activeTurnIndex === index) {\n player.pause();\n return;\n }\n\n if (startMs == null) return;\n playAudio(startMs, endMs);\n };\n\n const highlightTurns = (turnIds) => {\n setHighlightedTurns(new Set(turnIds));\n // TranscriptCard handles highlight styling via isHighlighted prop\n // Always scroll transcript container into view so highlights are visible\n const container = document.getElementById('transcript-container');\n if (container) {\n container.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n setTimeout(() => setHighlightedTurns(new Set()), 5000);\n };\n\n const toggleSignal = (key) => {\n setExpandedSignals(prev => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key); else next.add(key);\n return next;\n });\n };\n\n const title = ctx.call_purpose?.interaction_driver || summary.one_liner || 'Interaction Detail';\n\n const [rightTab, setRightTab] = useState('signals'); // 'signals' | 'guidance'\n const leftSummaryRef = useRef(null);\n const [rightRailHeight, setRightRailHeight] = useState(null);\n\n // After coaching summary data has loaded and layout has settled,\n // sync right rail height to match ONLY the summary block\n // (InteractionContext + AgentLiftCard + CoachingSummary), not extra padding.\n useLayoutEffect(() => {\n if (coachingLoading) return;\n if (!leftSummaryRef.current) return;\n\n const measure = () => {\n const h = leftSummaryRef.current?.offsetHeight || 0;\n if (h > 0) setRightRailHeight(h);\n };\n\n // Measure immediately and once more on the next frame to catch late layout.\n measure();\n const id = window.requestAnimationFrame(measure);\n return () => window.cancelAnimationFrame(id);\n }, [coachingLoading, coachingData, meta, ctx]);\n\n // MessageThread callbacks.\n // - For gallery: default to console logging\n // - For host apps: pass real handlers via props so APIs are called.\n const handleThreadSend = async (payload) => {\n // payload: { content, parent_message_id }\n if (onThreadSendMessage) {\n await onThreadSendMessage(payload);\n return;\n }\n };\n\n const handleThreadEdit = async (payload) => {\n if (onThreadEditMessage) {\n return onThreadEditMessage(payload);\n }\n };\n\n const handleThreadDelete = async (message) => {\n if (onThreadDeleteMessage) {\n await onThreadDeleteMessage(message);\n return;\n }\n };\n\n const handleCreateNewThread = async (titleText) => {\n if (onThreadCreateNewThread) {\n await onThreadCreateNewThread(titleText);\n return;\n }\n };\n\n // Pass through the host's messageThread as-is. No fallback sample — host apps\n // (e.g. Feedback module) must pass real thread data or leave undefined to show\n // MessageThread's empty state (\"No messages yet\"). Gallery/demos can pass\n // sample data explicitly via the messageThread prop.\n const effectiveMessageThread =\n messageThread && Object.keys(messageThread).length > 0\n ? messageThread\n : undefined;\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: '10px',\n flexWrap: 'wrap',\n }}\n >\n {/* Left rail: context → coaching summary */}\n <div ref={leftSummaryRef}\n style={{\n flex: '1 1 420px',\n minWidth: 320,\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n }}>\n {/* Context — metadata + call purpose + dimensions */}\n <InteractionContext\n title={title}\n meta={meta}\n callPurpose={ctx.call_purpose}\n classification={ctx.classification}\n dimensions={dimensions}\n />\n\n {/* Scores */}\n {/* <InteractionScores scores={scores.scores} /> */}\n\n {/* Agent Lift Analysis */}\n <AgentLiftCard outcomeLift={outcomeLift} />\n\n {/* Coaching Synthesis — only show if loading or has data */}\n {(coachingLoading || coachingData || coachingError) && (\n <DetailCard title=\"Coaching Summary\">\n <CoachingSynthesisCard\n data={coachingData}\n loading={coachingLoading}\n error={coachingError}\n />\n </DetailCard>\n )}\n </div>\n\n {/* Right rail: tabs → InteractionSignals/InteractionGuidance → InteractionNBA */}\n <div\n style={{\n flex: '1 1 420px',\n minWidth: 320,\n display: 'flex',\n flexDirection: 'column',\n height: rightRailHeight,\n }}\n >\n {/* Tabs: Signals / Guidance */}\n <Tabs\n tabs={[\n { key: 'signals', label: 'Signals' },\n { key: 'guidance', label: 'Guidance' },\n ]}\n active={rightTab}\n onSelect={setRightTab}\n size=\"compact\"\n borderTopRightRadius={12}\n borderTopLeftRadius={12}\n />\n\n <div\n className=\"custom-thin-scrollbar-library\"\n style={{\n flex: 1,\n overflowY: 'auto',\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n }}\n >\n {rightTab === 'signals' ? (\n <InteractionSignals\n signals={signals}\n expandedSignals={expandedSignals}\n toggleSignal={toggleSignal}\n playEvidence={handleEvidencePlayToggle}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n highlightTurns={highlightTurns}\n borderRadius={'0px 0px 12px 12px'}\n />\n ) : (\n <InteractionGuidance\n guidance={guidance}\n playEvidence={handleEvidencePlayToggle}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n highlightTurns={highlightTurns}\n borderRadius={'0px 0px 12px 12px'}\n />\n )}\n\n {/* NBA always visible below tabs */}\n <InteractionNBA nba={nba} />\n </div>\n </div>\n </div>\n {/* Recording / Timeline */}\n <InteractionRecording\n audioUrl={audioUrl}\n timelineSegments={timelineSegments}\n durationSeconds={meta.duration_seconds}\n currentTimeSeconds={currentTimeSeconds}\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n onSeek={handleTimelineSeek}\n onTogglePlay={handleTimelineTogglePlay}\n onSeekBack={handleTimelineSeekBack}\n onSeekForward={handleTimelineSeekForward}\n onSetPlaybackRate={handleSetPlaybackRate}\n audioRef={audioRef}\n />\n\n {/* Transcript */}\n <InteractionTranscript\n transcript={transcript}\n audioUrl={audioUrl}\n highlightedTurns={highlightedTurns}\n activeTurnIndex={activeTurnIndex}\n timelinePlaying={timelinePlaying}\n turnObservations={turnObservations}\n setExpandedSignals={setExpandedSignals}\n onTurnPlayPause={handleTranscriptTurnPlayPause}\n />\n\n {/* Message Thread — uses common design-system component.\n For gallery/testing, falls back to a sample payload that matches\n the real backend response shape. */}\n <MessageThread\n sessionTitle={title}\n messageThread={effectiveMessageThread}\n currentUser={threadCurrentUser}\n isLoading={threadLoading}\n onSendMessage={handleThreadSend}\n onEditMessage={handleThreadEdit}\n onDeleteMessage={handleThreadDelete}\n onCreateNewThread={handleCreateNewThread}\n onThreadSelect={onThreadSelect}\n />\n </div>\n );\n}\n\nclass ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { hasError: false };\n }\n static getDerivedStateFromError() {\n return { hasError: true };\n }\n componentDidCatch(error, info) {\n console.error('InteractionDetailPanel render error:', error, info?.componentStack);\n }\n render() {\n return this.state.hasError ? this.props.fallback : this.props.children;\n }\n}\n\nexport default function InteractionDetailPanelWrapper(props) {\n return (\n <ErrorBoundary fallback={\n <div style={{ padding: 16, color: 'var(--state-unknown)', fontSize: 12 }}>\n Error rendering detail.\n </div>\n }>\n <InteractionDetailPanel {...props} />\n </ErrorBoundary>\n );\n}","\"use client\";\n\nimport React, { useState } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\n\n/**\n * ExpandPatternComparison Component\n * Demonstrates three different expand/collapse patterns for signal cards.\n */\nexport default function ExpandPatternComparison({ pattern }) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const sampleSignal = {\n name: \"Customer Escalation Likelihood\",\n description:\n \"Based on observed patterns, this session shows indicators consistent with potential escalation.\",\n technicalKey: \"signal.escalation_likelihood\",\n probability: 0.68,\n confidence: 0.81,\n observations: 3,\n };\n\n if (pattern === \"text-link\") {\n return (\n <div\n style={{\n position: \"relative\",\n background: \"rgba(255, 255, 255, 0.82)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 2px 4px rgba(30, 33, 37, 0.06)\",\n }}\n >\n {/* Left rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"5px\",\n background: \"#6B7C93\",\n opacity: 0.6,\n }}\n />\n\n {/* Content - not clickable */}\n <div\n style={{\n padding: \"14px 16px 14px 21px\",\n }}\n >\n <div style={{ marginBottom: \"4px\" }}>\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 680,\n color: \"rgba(30, 33, 37, 0.92)\",\n lineHeight: 1.2,\n }}\n >\n {sampleSignal.name}\n </span>\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.65)\",\n lineHeight: 1.4,\n marginBottom: \"6px\",\n }}\n >\n {sampleSignal.description}\n </div>\n <div\n style={{\n fontSize: \"11px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n fontFamily: \"ui-monospace, monospace\",\n marginBottom: \"8px\",\n }}\n >\n {sampleSignal.technicalKey}\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n fontSize: \"11.5px\",\n marginBottom: \"10px\",\n }}\n >\n <span style={{ color: \"rgba(139, 157, 127, 0.65)\" }}>prob</span>\n <strong style={{ color: \"rgba(139, 157, 127, 0.85)\" }}>\n {sampleSignal.probability.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(184, 156, 106, 0.65)\" }}>conf</span>\n <strong style={{ color: \"rgba(184, 156, 106, 0.85)\" }}>\n {sampleSignal.confidence.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(30, 33, 37, 0.52)\" }}>\n {sampleSignal.observations} observations\n </span>\n </div>\n\n {/* Text link to expand */}\n {!isExpanded && (\n <button\n onClick={() => setIsExpanded(true)}\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.56)\",\n background: \"none\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n textDecoration: \"underline\",\n textDecorationColor: \"rgba(30, 33, 37, 0.2)\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.78)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.4)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.56)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.2)\";\n }}\n >\n View contributing observations\n </button>\n )}\n </div>\n\n {/* Expanded content */}\n {isExpanded && (\n <div\n style={{\n borderTop: \"1px solid rgba(52, 58, 64, 0.08)\",\n background: \"rgba(244, 241, 230, 0.25)\",\n padding: \"16px 16px 16px 21px\",\n }}\n >\n <div\n style={{\n fontSize: \"10px\",\n fontWeight: 650,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: \"rgba(30, 33, 37, 0.52)\",\n marginBottom: \"8px\",\n }}\n >\n Contributing Observations\n </div>\n <div style={{ fontSize: \"12px\", color: \"rgba(30, 33, 37, 0.62)\" }}>\n [Observations would appear here]\n </div>\n <button\n onClick={() => setIsExpanded(false)}\n style={{\n marginTop: \"10px\",\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.56)\",\n background: \"none\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n textDecoration: \"underline\",\n textDecorationColor: \"rgba(30, 33, 37, 0.2)\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.78)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.4)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.56)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.2)\";\n }}\n >\n Hide observations\n </button>\n </div>\n )}\n </div>\n );\n }\n\n if (pattern === \"rotating-chevron\") {\n return (\n <div\n style={{\n position: \"relative\",\n background: \"rgba(255, 255, 255, 0.82)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 2px 4px rgba(30, 33, 37, 0.06)\",\n }}\n >\n {/* Left rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"5px\",\n background: \"#6B7C93\",\n opacity: 0.6,\n }}\n />\n\n {/* Header - Clickable */}\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n width: \"100%\",\n padding: \"14px 16px 14px 21px\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n textAlign: \"left\",\n transition: \"background 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"rgba(231, 212, 162, 0.08)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"flex-start\", gap: \"12px\" }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ marginBottom: \"4px\" }}>\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 680,\n color: \"rgba(30, 33, 37, 0.92)\",\n lineHeight: 1.2,\n }}\n >\n {sampleSignal.name}\n </span>\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.65)\",\n lineHeight: 1.4,\n marginBottom: \"6px\",\n }}\n >\n {sampleSignal.description}\n </div>\n <div\n style={{\n fontSize: \"11px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n fontFamily: \"ui-monospace, monospace\",\n marginBottom: \"8px\",\n }}\n >\n {sampleSignal.technicalKey}\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n fontSize: \"11.5px\",\n }}\n >\n <span style={{ color: \"rgba(139, 157, 127, 0.65)\" }}>prob</span>\n <strong style={{ color: \"rgba(139, 157, 127, 0.85)\" }}>\n {sampleSignal.probability.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(184, 156, 106, 0.65)\" }}>conf</span>\n <strong style={{ color: \"rgba(184, 156, 106, 0.85)\" }}>\n {sampleSignal.confidence.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(30, 33, 37, 0.52)\" }}>\n {sampleSignal.observations} observations\n </span>\n </div>\n </div>\n\n {/* Rotating chevron on right */}\n <div\n style={{\n paddingTop: \"2px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n flexShrink: 0,\n transition: \"transform 0.2s ease\",\n }}\n >\n <ChevronDown\n size={18}\n style={{\n transform: isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.2s ease\",\n }}\n />\n </div>\n </div>\n </button>\n\n {/* Expanded content */}\n {isExpanded && (\n <div\n style={{\n borderTop: \"1px solid rgba(52, 58, 64, 0.08)\",\n background: \"rgba(244, 241, 230, 0.25)\",\n padding: \"16px 16px 16px 21px\",\n }}\n >\n <div\n style={{\n fontSize: \"10px\",\n fontWeight: 650,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: \"rgba(30, 33, 37, 0.52)\",\n marginBottom: \"8px\",\n }}\n >\n Contributing Observations\n </div>\n <div style={{ fontSize: \"12px\", color: \"rgba(30, 33, 37, 0.62)\" }}>\n [Observations would appear here]\n </div>\n </div>\n )}\n </div>\n );\n }\n\n // directional-chevron (current SignalCard pattern)\n return (\n <div\n style={{\n position: \"relative\",\n background: \"rgba(255, 255, 255, 0.82)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 2px 4px rgba(30, 33, 37, 0.06)\",\n }}\n >\n {/* Left rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"5px\",\n background: \"#6B7C93\",\n opacity: 0.6,\n }}\n />\n\n {/* Header - Clickable */}\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n width: \"100%\",\n padding: \"14px 16px 14px 21px\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n textAlign: \"left\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"12px\",\n transition: \"background 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"rgba(231, 212, 162, 0.08)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n {/* Directional chevron on left */}\n <div\n style={{\n paddingTop: \"2px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n flexShrink: 0,\n }}\n >\n {isExpanded ? (\n <ChevronDown size={16} />\n ) : (\n <ChevronRight size={16} />\n )}\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ marginBottom: \"4px\" }}>\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 680,\n color: \"rgba(30, 33, 37, 0.92)\",\n lineHeight: 1.2,\n }}\n >\n {sampleSignal.name}\n </span>\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.65)\",\n lineHeight: 1.4,\n marginBottom: \"6px\",\n }}\n >\n {sampleSignal.description}\n </div>\n <div\n style={{\n fontSize: \"11px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n fontFamily: \"ui-monospace, monospace\",\n marginBottom: \"8px\",\n }}\n >\n {sampleSignal.technicalKey}\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n fontSize: \"11.5px\",\n }}\n >\n <span style={{ color: \"rgba(139, 157, 127, 0.65)\" }}>prob</span>\n <strong style={{ color: \"rgba(139, 157, 127, 0.85)\" }}>\n {sampleSignal.probability.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(184, 156, 106, 0.65)\" }}>conf</span>\n <strong style={{ color: \"rgba(184, 156, 106, 0.85)\" }}>\n {sampleSignal.confidence.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(30, 33, 37, 0.52)\" }}>\n {sampleSignal.observations} observations\n </span>\n </div>\n </div>\n </button>\n\n {/* Expanded content */}\n {isExpanded && (\n <div\n style={{\n borderTop: \"1px solid rgba(52, 58, 64, 0.08)\",\n background: \"rgba(244, 241, 230, 0.25)\",\n padding: \"16px 16px 16px 21px\",\n }}\n >\n <div\n style={{\n fontSize: \"10px\",\n fontWeight: 650,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: \"rgba(30, 33, 37, 0.52)\",\n marginBottom: \"8px\",\n }}\n >\n Contributing Observations\n </div>\n <div style={{ fontSize: \"12px\", color: \"rgba(30, 33, 37, 0.62)\" }}>\n [Observations would appear here]\n </div>\n </div>\n )}\n </div>\n );\n}\n\n"],"names":["STYLE_ID","ensureKeyframes","style","CoachingSynthesisCard","data","loading","error","React","jsxs","jsx","w","i","strengths","improvements","organizational","oneLiner","_a","context","_b","CoachingSection","TrendingUp","Lightbulb","Building","icon","label","color","items","item","text","quote","MessageSquareQuote","fmtDur","seconds","m","InteractionContext","title","meta","callPurpose","classification","dimensions","cp","cls","CardBase","dim","InteractionScores","scores","DetailCard","s","val","GROUP_LABELS","Target","FileText","Scale","Zap","MessageSquare","KIND_COLORS","CheckCircle","InteractionSignals","signals","expandedSignals","toggleSignal","playEvidence","timelinePlaying","currentTimeSeconds","highlightTurns","borderRadius","grouped","useMemo","result","g","groupKey","groupSignals","info","SectionLabel","name","delta","hasObs","isExpanded","e","ChevronDown","obs","oi","ev","ei","startMs","endMs","isPlayingSegment","startSec","endSec","cs","EvidenceItem","InteractionGuidance","guidance","ki","ownerBadge","sr","si","CornerDownRight","sMs","eMs","InteractionNBA","nba","r","InteractionRecording","audioUrl","timelineSegments","durationSeconds","playbackRate","onSeek","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","audioRef","Timeline","InteractionTranscript","transcript","highlightedTurns","activeTurnIndex","turnObservations","setExpandedSignals","onTurnPlayPause","formatTimeRange","formatTime","ms","minutes","start","end","turns","prev","el","TranscriptCard","messageActionButtonStyle","roleColorMap","role","normalized","extractMessagesArray","node","directCandidates","candidate","flattenMessages","rawMessages","parentId","startIndex","out","index","author","authorName","initials","n","roleColor","id","baseMessage","formatTimestamp","value","d","now","sameDay","yesterday","isYesterday","timeStr","diffDays","MessageThread","sessionTitle","sessionSubtitle","threadLabel","initialMessages","messageThread","onSendMessage","onReplyMessage","onEditMessage","onDeleteMessage","onCreateNewThread","onThreadSelect","currentUser","isLoading","messageInput","setMessageInput","useState","isFocused","setIsFocused","messages","setMessages","isSending","setIsSending","hoveredMessageId","setHoveredMessageId","threads","setThreads","activeThreadId","setActiveThreadId","replyingToMessageId","setReplyingToMessageId","replyDraft","setReplyDraft","editingMessageId","setEditingMessageId","editContent","setEditContent","deleteConfirmMessage","setDeleteConfirmMessage","showNewThreadCompose","setShowNewThreadCompose","newThreadInput","setNewThreadInput","isCreatingNewThread","setIsCreatingNewThread","expandedParentIds","setExpandedParentIds","messagesEndRef","useRef","messageInputRef","normalizedRole","displayCurrentUser","canCreateNewThread","childrenByParentId","map","topLevelMessages","isChildReply","isChildEdit","hasHeader","replyingToMessage","useEffect","rawThreads","normalizedThreads","t","rawMessagesForThread","messagesForThread","firstWithMessages","flatMessages","rawFlat","mappedMessages","singleId","singleLabel","thread","container","handleNewThreadSubmit","trimmed","newId","handleNewThreadCancel","handleSend","content","optimisticId","optimisticMessage","msg","handleKeyPress","handleReplyClick","message","handleInlineReplySend","parentMessageId","optimisticReply","handleEditClick","handleEditSubmit","err","handleEditCancel","handleDeleteClick","handleDeleteConfirm","renderMessageTree","depth","children","hasChildren","isEditing","isReplying","Clock","next","ChevronRight","child","isActive","Fragment","Send","findBlock","blocks","b","InteractionDetailPanel","coachingData","coachingLoading","coachingError","onThreadSendMessage","onThreadEditMessage","onThreadDeleteMessage","onThreadCreateNewThread","threadLoading","threadCurrentUser","segmentEndHandlerRef","setHighlightedTurns","setCurrentTimeSeconds","setTimelinePlaying","setPlaybackRate","ctx","summary","_c","_d","_e","_f","_g","_h","_i","outcomeLift","_j","signal","groupInfo","tid","o","_k","startTime","endTime","isAgent","actorName","currentMs","handleTimelineSeek","handleTimelineTogglePlay","p","handleTimelineSeekBack","handleTimelineSeekForward","duration","handleSetPlaybackRate","rate","audio","updateTime","handlePlay","handlePause","handleEnded","playAudio","player","handler","handleEvidencePlayToggle","turnIds","currentSec","handleTranscriptTurnPlayPause","turn","key","_l","rightTab","setRightTab","leftSummaryRef","rightRailHeight","setRightRailHeight","useLayoutEffect","measure","h","handleThreadSend","payload","handleThreadEdit","handleThreadDelete","handleCreateNewThread","titleText","effectiveMessageThread","AgentLiftCard","Tabs","ErrorBoundary","props","InteractionDetailPanelWrapper","ExpandPatternComparison","pattern","setIsExpanded","sampleSignal"],"mappings":"qcAsBMA,GAAW,+BAEjB,SAASC,IAAkB,CAErB,GADA,OAAO,SAAa,KACpB,SAAS,eAAeD,EAAQ,EAAG,OACjC,MAAAE,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,GAAKF,GACXE,EAAM,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUX,SAAA,KAAK,YAAYA,CAAK,CACjC,CAEA,SAAwBC,GAAsB,CAAE,KAAAC,EAAM,QAAAC,EAAS,MAAAC,GAAS,SAItE,GAHAC,EAAM,UAAU,IAAM,CAAkBN,IAAG,EAAG,CAAE,CAAA,EAG5CI,EAEA,OAAAG,EAAA,KAAC,OAAI,MAAO,CACV,QAAS,SACT,QAAS,OACT,cAAe,SACf,IAAK,EAEL,EAAA,SAAA,CAAAA,OAAC,OAAI,MAAO,CACV,QAAS,OACT,WAAY,SACZ,IAAK,CAEL,EAAA,SAAA,CAAAC,MAAC,OAAI,MAAO,CACV,MAAO,EACP,OAAQ,EACR,aAAc,MACd,WAAY,mBACZ,UAAW,0CAAA,EACV,EACHA,MAAC,QAAK,MAAO,CACX,SAAU,mBACV,MAAO,mBACP,WAAY,mBACZ,WAAY,GAAA,EACX,SAEH,6CAAA,CAAA,EACF,EAEC,CAAC,IAAK,IAAK,GAAG,EAAE,IAAI,CAACC,EAAGC,IACvBF,EAAA,IAAC,MAAA,CAEC,MAAO,CACL,OAAQ,GACR,MAAOC,EACP,SAAU,OACV,aAAc,EACd,WAAY,4GACZ,eAAgB,YAChB,UAAW,6CACX,eAAgB,GAAGC,EAAI,EAAG,GAC5B,CAAA,EAVKA,CAAA,CAYR,CACH,CAAA,CAAA,EAKJ,GAAIL,EAEA,OAAAG,EAAA,IAAC,OAAI,MAAO,CACV,QAAS,SACT,SAAU,mBACV,MAAO,oBACP,WAAY,kBAAA,EACX,SAEH,sCAAA,CAAA,EAKJ,GAAI,CAACL,EAAa,OAAA,KAEZ,MAAAQ,EAAYR,EAAK,WAAa,GAC9BS,EAAeT,EAAK,cAAgB,GACpCU,EAAiBV,EAAK,gBAAkBA,EAAK,yBAA2B,CAAA,EACxEW,EAAW,OAAOX,EAAK,WAAc,SAAWA,EAAK,YAAYY,EAAAZ,EAAK,YAAL,YAAAY,EAAgB,OAAQ,GACzFC,EAAU,OAAOb,EAAK,SAAY,SAAWA,EAAK,UAAUc,EAAAd,EAAK,UAAL,YAAAc,EAAc,OAAQ,GAGtF,OAAAV,EAAA,KAAC,OAAI,MAAO,CACV,QAAS,OACT,cAAe,SACf,IAAK,GACL,WAAY,kBAGX,EAAA,SAAA,CACCO,GAAAN,EAAA,IAAC,OAAI,MAAO,CACV,SAAU,iBACV,WAAY,IACZ,MAAO,qBACP,WAAY,GAAA,EAEX,SACHM,EAAA,EAIDE,GACER,EAAA,IAAA,MAAA,CAAI,MAAO,CACV,SAAU,mBACV,MAAO,oBACP,WAAY,IAAA,EAEX,SACHQ,EAAA,EAIDL,EAAU,OAAS,GAClBH,EAAA,IAACU,GAAA,CACC,KAAMV,EAAAA,IAACW,EAAAA,WAAW,CAAA,KAAM,EAAI,CAAA,EAC5B,MAAM,YACN,MAAM,wBACN,MAAOR,CAAA,CACT,EAIDC,EAAa,OAAS,GACrBJ,EAAA,IAACU,GAAA,CACC,KAAMV,EAAAA,IAACY,EAAAA,UAAU,CAAA,KAAM,EAAI,CAAA,EAC3B,MAAM,eACN,MAAM,yBACN,MAAOR,CAAA,CACT,EAIDC,EAAe,OAAS,GACvBL,EAAA,IAACU,GAAA,CACC,KAAMV,EAAAA,IAACa,EAAAA,SAAS,CAAA,KAAM,EAAI,CAAA,EAC1B,MAAM,iBACN,MAAM,sBACN,MAAOR,CAAA,CACT,EAIDV,EAAK,SACHI,EAAAA,KAAA,MAAA,CAAI,MAAO,CACV,SAAU,mBACV,MAAO,oBACP,UAAW,SACX,UAAW,CACV,EAAA,SAAA,CAAA,YACSJ,EAAK,QAAQ,QAAQ,KAAM,GAAG,CAAA,EAC1C,CAEJ,CAAA,CAAA,CAEJ,CAEA,SAASe,GAAgB,CAAE,KAAAI,EAAM,MAAAC,EAAO,MAAAC,EAAO,MAAAC,GAAS,CACtD,cACG,MAEC,CAAA,SAAA,CAAAlB,OAAC,OAAI,MAAO,CACV,QAAS,OACT,WAAY,SACZ,IAAK,EACL,aAAc,EACd,MAAAiB,EACA,SAAU,mBACV,WAAY,IACZ,cAAe,QAEd,EAAA,SAAA,CAAAF,EACAC,CAAA,EACH,EAGCf,EAAA,IAAA,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,CAC1D,EAAA,SAAAiB,EAAM,IAAI,CAACC,EAAMhB,IAAM,CACtB,MAAMiB,EAAO,OAAOD,GAAS,SAAWA,GAAOA,GAAA,YAAAA,EAAM,OAAQ,GACvDE,EAAQ,OAAOF,GAAS,SAAWA,GAAA,YAAAA,EAAM,MAAQ,KAEvD,cACG,MAAY,CAAA,MAAO,CAAE,YAAa,EACjC,EAAA,SAAA,CAAAnB,OAAC,OAAI,MAAO,CACV,SAAU,mBACV,MAAO,mBACP,WAAY,GACX,EAAA,SAAA,CAAA,KACEoB,CAAA,EACL,EACCC,GACErB,EAAA,KAAA,MAAA,CAAI,MAAO,CACV,QAAS,OACT,WAAY,aACZ,IAAK,EACL,UAAW,EACX,YAAa,CAEb,EAAA,SAAA,CAAAC,EAAA,IAACqB,EAAA,mBAAA,CACC,KAAM,GACN,MAAO,CACL,MAAO,oBACP,WAAY,EACZ,UAAW,CACb,CAAA,CACF,EACAtB,OAAC,QAAK,MAAO,CACX,SAAU,mBACV,MAAO,oBACP,UAAW,SACX,WAAY,IACX,EAAA,SAAA,CAAA,IACCqB,EAAM,GAAA,EACV,CAAA,EACF,CAAA,CAAA,EAhCMlB,CAkCV,CAEH,CAAA,EACH,CACF,CAAA,CAAA,CAEJ,CC/PA,SAASoB,GAAOC,EAAS,CACvB,MAAMC,EAAI,KAAK,MAAMD,EAAU,EAAE,EAC3B,EAAI,KAAK,MAAMA,EAAU,EAAE,EAC1B,MAAA,GAAGC,CAAC,IAAI,EAAE,WAAW,SAAS,EAAG,GAAG,CAAC,EAC9C,CAEA,SAAwBC,GAAmB,CAAE,MAAAC,EAAO,KAAAC,EAAM,YAAAC,EAAa,eAAAC,EAAgB,WAAAC,GAAc,CAC7F,MAAAC,EAAKH,GAAe,GACpBI,EAAMH,GAAkB,GAE9B,OACG9B,EAAAA,KAAAkC,GAAAA,KAAA,CAAS,QAAQ,WAAW,QAAQ,KACnC,SAAA,CAAAjC,EAAA,IAAC,MAAI,CAAA,MAAO,CAAE,SAAU,iBAAkB,WAAY,IAAK,MAAO,qBAAsB,WAAY,MAAO,aAAc,GACtH,SACH0B,EAAA,EACC3B,EAAA,KAAA,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,oBAAqB,cAAe,IAAK,WAAY,SAAU,GAAI,MAAO,mBACtG,EAAA,SAAA,CAAK4B,EAAA,qBAAiB,MAAI,CAAA,SAAA,CAAC3B,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAI,MAAA,CAAA,EAAQA,EAAA,IAAA,MAAA,CAAI,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAmB,EAAI,aAAI,KAAK2B,EAAK,YAAY,EAAE,iBAAiB,CAAA,EAAM,EAC7MA,EAAK,kBAAoB,MAAQ5B,EAAA,KAAC,MAAI,CAAA,SAAA,CAACC,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAQ,UAAA,CAAA,EAAQA,EAAAA,IAAA,MAAA,CAAI,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAA,EAAuB,SAAAsB,GAAOK,EAAK,gBAAgB,CAAE,CAAA,CAAA,EAAM,EAC9MA,EAAK,eAAiB5B,EAAAA,KAAC,MAAI,CAAA,SAAA,CAACC,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAQ,UAAA,CAAA,EAAOA,EAAAA,IAAC,MAAI,CAAA,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAA,EAAuB,SAAA2B,EAAK,aAAc,CAAA,CAAA,EAAM,EACxLI,EAAG,uBAAyBhC,EAAAA,KAAC,MAAI,CAAA,SAAA,CAACC,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAS,WAAA,CAAA,EAAOA,MAAC,OAAI,MAAO,CAAE,MAAO,kBAAmB,EAAI,WAAG,sBAAsB,CAAA,EAAM,EACvL+B,EAAG,oBAAsBhC,EAAAA,KAAC,MAAI,CAAA,SAAA,CAACC,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAM,QAAA,CAAA,EAAOA,EAAAA,IAAC,MAAI,CAAA,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAA,EAAuB,SAAA+B,EAAG,kBAAmB,CAAA,CAAA,EAAM,EAC5LA,EAAG,iBAAmBhC,EAAAA,KAAC,MAAI,CAAA,SAAA,CAACC,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAM,QAAA,CAAA,EAAOA,MAAC,OAAI,MAAO,CAAE,MAAO,kBAAmB,EAAI,WAAG,gBAAgB,CAAA,EAAM,EACxKgC,EAAI,sBAAwBjC,EAAAA,KAAC,MAAI,CAAA,SAAA,CAACC,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAA,EAAuB,SAAQ,UAAA,CAAA,EAAOA,EAAAA,IAAC,MAAI,CAAA,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAA,EAAuB,SAAAgC,EAAI,oBAAqB,CAAA,CAAA,EAAM,EACpMF,EAAW,IAAI,CAACI,EAAKhC,WACnB,MAAY,CAAA,SAAA,CAACF,EAAAA,IAAA,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,MAAO,mBAAwB,EAAA,SAAAkC,EAAI,OAASA,EAAI,GAAI,CAAA,EAAOlC,EAAAA,IAAC,MAAI,CAAA,MAAO,CAAE,SAAU,GAAI,MAAO,kBAAA,EAAuB,SAAAkC,EAAI,KAAM,CAAA,CAAA,CAAA,EAA/JhC,CAAqK,CAChL,CAAA,EACH,EACCyB,EAAK,YACJ3B,EAAAA,IAAC,OAAI,MAAO,CAAE,SAAU,GAAI,MAAO,oBAAqB,WAAY,mBAAoB,UAAW,EAAG,WAAY,KAAM,EACrH,WAAK,WACR,CAEJ,CAAA,CAAA,CAEJ,CClCwB,SAAAmC,GAAkB,CAAE,OAAAC,GAAU,CACpD,OAAKA,GAAA,MAAAA,EAAQ,aAGVC,cAAW,CAAA,MAAM,SAChB,SAACrC,MAAA,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,IAAK,GAAI,SAAU,MAAO,EACtD,WAAO,IAAI,CAACsC,EAAGpC,IAAM,CACd,MAAAqC,EAAMD,EAAE,OAAS,KAAO,KAAK,MAAMA,EAAE,KAAK,EAAI,KAElD,OAAAvC,EAAA,KAAC,OAAY,MAAO,CAAE,UAAW,SAAU,SAAU,EACnD,EAAA,SAAA,CAACC,EAAAA,IAAA,MAAA,CAAI,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,MAAO,iBAAsB,EAAA,SAAAuC,GAAO,GAAI,CAAA,EACpFvC,EAAA,IAAA,MAAA,CAAI,MAAO,CAAE,SAAU,iBAAkB,MAAO,oBAAqB,UAAW,CAAE,EAAI,SAAEsC,EAAA,OAASA,EAAE,IAAI,CAAA,CAAA,EAFhGpC,CAGV,CAAA,CAEH,EACH,CACF,CAAA,EAf0B,IAiB9B,CCfA,MAAMsC,GAAe,CACnB,QAAS,CAAE,MAAO,UAAW,KAAOxC,EAAA,IAAAyC,SAAA,CAAO,KAAM,EAAA,CAAI,EAAI,MAAO,qBAAsB,EACtF,QAAS,CAAE,MAAO,qBAAsB,KAAOzC,EAAA,IAAA0C,WAAA,CAAS,KAAM,EAAA,CAAI,EAAI,MAAO,uBAAwB,EACrG,WAAY,CAAE,MAAO,aAAc,KAAO1C,EAAA,IAAA2C,QAAA,CAAM,KAAM,EAAA,CAAI,EAAI,MAAO,wBAAyB,EAC9F,kBAAmB,CAAE,MAAO,oBAAqB,KAAO3C,EAAA,IAAA4C,MAAA,CAAI,KAAM,EAAA,CAAI,EAAI,MAAO,mBAAoB,EACrG,WAAY,CAAE,MAAO,aAAc,KAAO5C,EAAA,IAAA6C,gBAAA,CAAc,KAAM,EAAA,CAAI,EAAI,MAAO,kBAAmB,CAClG,EAEMC,GAAc,CAClB,KAAM,CAAE,KAAM9C,EAAAA,IAAC4C,OAAI,KAAM,EAAI,CAAA,EAAI,MAAO,0BAA2B,EACnE,YAAa,CAAE,KAAM5C,EAAAA,IAACY,aAAU,KAAM,EAAI,CAAA,EAAI,MAAO,sBAAuB,EAC5E,WAAY,CAAE,KAAMZ,EAAAA,IAAC+C,eAAY,KAAM,EAAI,CAAA,EAAI,MAAO,kBAAmB,CAC3E,EAEA,SAAwBC,GAAmB,CACzC,QAAAC,EACA,gBAAAC,EACA,aAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,mBAAAC,EACA,eAAAC,EACA,aAAAC,CACF,EAAG,OACG,GAAA,GAACjD,EAAA0C,GAAA,YAAAA,EAAS,UAAT,MAAA1C,EAAkB,QAAe,OAAA,KAEhC,MAAAkD,EAAUC,EAAAA,QAAQ,IAAM,CAC5B,MAAMC,EAAS,CAAA,EACJ,UAAArB,KAAKW,EAAQ,QAAS,CACzB,MAAAW,EAAItB,EAAE,OAAS,aAChBqB,EAAOC,CAAC,IAAUD,EAAAC,CAAC,EAAI,IACrBD,EAAAC,CAAC,EAAE,KAAKtB,CAAC,CAClB,CACO,OAAAqB,CAAA,EACN,CAACV,CAAO,CAAC,EAGV,OAAAjD,EAAA,IAACqC,eAAW,MAAO,YAAYY,EAAQ,aAAa,cAAcA,EAAQ,uBAAuB,cAAe,aAAAO,EAC7G,SAAO,OAAA,QAAQC,CAAO,EAAE,IAAI,CAAC,CAACI,EAAUC,CAAY,IAAM,CACzD,MAAMC,EAAOvB,GAAaqB,CAAQ,GAAKrB,GAAa,WAEpD,cACG,MAAmB,CAAA,MAAO,CAAE,aAAc,EACzC,EAAA,SAAA,CAACzC,EAAAA,KAAAiE,GAAA,aAAA,CAAa,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,CAAA,EAChE,SAAA,CAAKD,EAAA,KACN/D,EAAAA,IAAC,OAAM,CAAA,SAAA+D,EAAK,KAAM,CAAA,CAAA,EACpB,QAEC,MAAI,CAAA,MAAO,CAAE,UAAW,EAAG,QAAS,OAAQ,cAAe,SAAU,IAAK,CAAE,EAC1E,WAAa,IAAI,CAACzB,EAAGpC,IAAM,WAC1B,MAAM+D,EAAO3B,EAAE,cAAgBA,EAAE,KAAO,GAClC4B,GAAQ3D,EAAA+B,EAAE,WAAF,YAAA/B,EAAY,MACpB4D,IAAS1D,EAAA6B,EAAE,eAAF,YAAA7B,EAAgB,QAAS,EAClC2D,EAAalB,EAAgB,IAAIZ,EAAE,GAAG,EAe1C,OAAAvC,EAAA,KAAC,MAAA,CAEC,GAAI,UAAUuC,EAAE,GAAG,GACnB,MAAO,CACL,OAAQ,kDACR,aAAc,wBACd,WAAY,0CACZ,SAAU,QACZ,EAEA,SAAA,CAAAvC,EAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAUsE,GAAM,CACVF,IACFhB,EAAab,EAAE,GAAG,EAClB+B,EAAE,cAAc,OAEpB,EACA,MAAO,CACL,MAAO,OACP,QAAS,OACT,WAAY,SACZ,eAAgB,gBAChB,QAAS,WACT,WAAY,cACZ,UAAW,wBACX,YAAa,wBACb,WAAY,wBACZ,aAAc,kDACd,OAAQF,EAAS,UAAY,SAC/B,EACA,MAAO,CACL7B,EAAE,YAAc,KAAO,eAAe,KAAK,MAAMA,EAAE,WAAa,GAAG,CAAC,IAAM,GAC1E4B,GAAS,KAAO,eAAeA,EAAQ,EAAI,IAAM,EAAE,IAAIA,EAAQ,KAAK,QAAQ,CAAC,CAAC,IAAM,EACpF,EAAA,OAAO,OAAO,EAAE,KAAK,KAAK,EAE5B,SAAA,CAAAnE,EAAA,KAAC,OAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,EACL,WAAY,QACd,EAEC,SAAA,EAAY+C,EAAAA,GAAAR,EAAE,IAAI,IAANQ,YAAAA,EAAS,KACtB9C,EAAAA,IAAC,QAAM,SAAKiE,CAAA,CAAA,EACXE,GACCpE,EAAA,KAAC,OAAA,CACC,MAAO,CACL,WAAY,EACZ,SAAU,GACV,QAAS,EACX,EACD,SAAA,CAAA,IACGuC,EAAE,aAAa,OAAO,GAAA,CAAA,CAC1B,CAAA,CAAA,CAEJ,EACC6B,GACCnE,EAAA,IAACsE,EAAA,YAAA,CACC,KAAM,GACN,MAAO,CACL,MAAO,oBACP,WAAY,EACZ,UAAWF,EAAa,iBAAmB,eAC3C,WAAY,sBACd,CAAA,CACF,CAAA,CAAA,CAEJ,EAECA,GAAc9B,EAAE,cACdtC,EAAAA,IAAA,MAAA,CAAI,MAAO,CAAE,MAAO,OAAQ,OAAQ,SAAU,EAC5C,WAAE,aAAa,IAAI,CAACuE,EAAKC,IACxBxE,OAAAA,OAAAA,EAAAA,IAAC,OAAa,MAAO,CAAE,aAAc,CACnC,EAAA,SAAAD,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,aAAc,wBACd,WAAY,qBACZ,SAAU,QACZ,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,EACP,WAAY+D,EAAK,KACnB,CAAA,CACF,EACAhE,EAAA,KAAC,MAAA,CACC,MAAO,CACL,KAAM,EACN,SAAU,iBACV,MAAO,oBACP,QAAS,UACX,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,IACZ,MAAO,mBACP,aAAc,EACd,SAAU,kBACZ,EAEC,WAAI,KAAO,EAAA,CACd,EACCA,EAAA,IAAA,MAAA,CAAI,MAAO,CAAE,aAAc,EAAG,WAAY,GAAA,EACxC,SAAAuE,EAAI,QAAUA,EAAI,aAAe,GACpC,GACChE,EAAAgE,EAAI,WAAJ,YAAAhE,EAAc,IAAI,CAACkE,EAAIC,IAAO,CAC7B,MAAMC,EAAUF,EAAG,SACbG,EAAQH,EAAG,OAEjB,IAAII,EAAmB,GACnB,GAAAF,GAAW,MAAQtB,EAAiB,CACtC,MAAMyB,EAAWH,EAAU,IACrBI,EACJH,GAAS,KAAOA,EAAQ,IAAOE,EAAW,EACtCE,EAAK1B,GAAsB,EAE/BuB,EAAAG,GAAMF,GAAYE,GAAMD,EAAS,GACrC,CAGE,OAAA/E,EAAA,IAACiF,GAAA,aAAA,CAEC,GAAAR,EACA,UAAWI,EACX,UAAWd,EAAK,MAChB,OAAQ,CAACY,EAASC,IAChBxB,GAAA,YAAAA,EAAeuB,EAASC,EAAOH,EAAG,UAEpC,YAAalB,CAAA,EAPRmB,CAAA,CAQP,EAEH,CAAA,CACH,CAAA,CAAA,CAAA,GA/DMF,CAiEV,EACD,EACH,CAAA,CAAA,EA5IGtE,CAAA,CAgJV,CAAA,EACH,CAAA,CAAA,EA5KQ2D,CA6KV,CAEH,CAAA,CACH,CAAA,CAEJ,CC7NA,MAAMf,GAAc,CAClB,KAAM,CAAE,KAAM9C,EAAAA,IAAC4C,OAAI,KAAM,EAAI,CAAA,EAAI,MAAO,0BAA2B,EACnE,YAAa,CAAE,KAAM5C,EAAAA,IAACY,aAAU,KAAM,EAAI,CAAA,EAAI,MAAO,sBAAuB,EAC5E,WAAY,CAAE,KAAMZ,EAAAA,IAAC+C,eAAY,KAAM,EAAI,CAAA,EAAI,MAAO,kBAAmB,CAC3E,EAEA,SAAwBmC,GAAoB,CAC1C,SAAAC,EACA,aAAA/B,EACA,gBAAAC,EACA,mBAAAC,EACA,eAAAC,EACA,aAAAC,CACF,EAAG,OACG,OAACjD,EAAA4E,GAAA,YAAAA,EAAU,QAAV,MAAA5E,EAAiB,OAGpBP,EAAA,IAACqC,GAAW,WAAA,CAAA,MAAO,aAAa8C,EAAS,WAAW,UAAW,aAAA3B,EAC7D,SAACxD,EAAAA,IAAA,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,CAAE,EAC5D,WAAS,MAAM,IAAI,CAAC4D,EAAG1D,IAAM,OAC5B,MAAMkF,EAAKtC,GAAYc,EAAE,aAAa,GAAKd,GAAY,WACjDuC,EAAazB,EAAE,QAAU,eAC3B,CAAE,GAAI,6DAA8D,MAAO,wBAAyB,KAAM,KAAM,EAChHA,EAAE,QAAU,SACZ,CAAE,GAAI,4DAA6D,MAAO,uBAAwB,KAAM,QACxG,EAAA,CAAE,GAAI,wDAAyD,MAAO,mBAAoB,KAAM,OAAQ,EAE1G,OAAA7D,EAAA,KAAC,OAAY,MAAO,CAClB,QAAS,YAAa,aAAc,gBACpC,WAAY,eAAgB,WAAY,aAAaqF,EAAG,KAAK,EAE7D,EAAA,SAAA,CAAArF,EAAA,KAAC,MAAI,CAAA,MAAO,CAAE,SAAU,mBAAoB,MAAO,qBAAsB,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,WAAY,GACjI,EAAA,SAAA,CAAGqF,EAAA,KAAK,IAAExB,EAAE,OAAS,GACtB5D,MAAC,QAAK,MAAO,CACX,SAAU,EAAG,QAAS,UAAW,aAAc,EAAG,WAAY,EAC9D,WAAYqF,EAAW,GAAI,MAAOA,EAAW,MAAO,WAAY,GAAA,EAE/D,WAAW,KACd,CAAA,EACF,EACCzB,EAAE,QAAU5D,MAAC,MAAI,CAAA,MAAO,CAAE,SAAU,iBAAkB,MAAO,oBAAqB,UAAW,EAAG,WAAY,GAAI,EAAI,WAAE,OAAO,GAE7HO,EAAAqD,EAAE,cAAF,YAAArD,EAAe,IAAI,CAAC+E,EAAIC,IACtBxF,OAAAA,OAAAA,EAAAA,KAAA,MAAA,CAAa,MAAO,CAAE,UAAW,CAAA,EAChC,SAAA,CAAAA,EAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,GACV,MAAO,oBACP,WAAY,IACZ,aAAc,EACd,QAAS,OACT,WAAY,SACZ,IAAK,CACP,EAEA,SAAA,CAACC,EAAAA,IAAAwF,EAAA,gBAAA,CAAgB,KAAM,EAAI,CAAA,EAAE,IAAEF,EAAG,cAAgBA,EAAG,WACpDA,EAAG,YAAc,MACfvF,EAAA,KAAA,OAAA,CAAK,MAAO,CAAE,WAAY,IAAK,QAAS,EAAA,EACtC,SAAA,CAAA,IAAI,IACH,KAAK,MAAMuF,EAAG,WAAa,GAAG,EAAE,IAAA,EACpC,CAAA,CAAA,CAEJ,GACC/E,EAAA+E,EAAG,WAAH,YAAA/E,EAAa,IAAI,CAACkE,EAAIC,IAAO,CAC5B,MAAMC,EAAUF,EAAG,SACbG,EAAQH,EAAG,OAEjB,IAAII,EAAmB,GACnB,GAAAF,GAAW,MAAQtB,EAAiB,CACtC,MAAMyB,EAAWH,EAAU,IACrBI,EACJH,GAAS,KAAOA,EAAQ,IAAOE,EAAW,EACtCE,EAAK1B,GAAsB,EAE/BuB,EAAAG,GAAMF,GAAYE,GAAMD,EAAS,GACrC,CAGE,OAAA/E,EAAA,IAACiF,GAAA,aAAA,CAEC,GAAAR,EACA,UAAWI,EACX,OAAQ,CAACY,EAAKC,IACZtC,GAAA,YAAAA,EAAeqC,EAAKC,EAAKjB,EAAG,UAE9B,YAAalB,CAAA,EANRmB,CAAA,CAOP,EAEH,CAAA,EA7COa,CA8CV,GACD,CAAA,EA/DOrF,CAgEV,CAAA,CAEH,EACH,CACF,CAAA,EAjFmC,IAmFvC,CClGwB,SAAAyF,GAAe,CAAE,IAAAC,GAAO,CAC9C,MAAM3E,GAAQ2E,GAAA,YAAAA,EAAK,mBAAmBA,GAAA,YAAAA,EAAK,UAAW,CAAA,EACtD,OAAK3E,EAAM,aAGRoB,GAAW,WAAA,CAAA,MAAM,oBAChB,SAAArC,EAAAA,IAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,GAC1D,SAAAiB,EAAM,MAAM,EAAG,CAAC,EAAE,IAAI,CAAC4E,EAAG3F,IACxBH,EAAAA,KAAA,MAAA,CAAY,MAAO,CAAE,SAAU,GAAI,MAAO,oBAAqB,QAAS,OAAQ,WAAY,SAAU,IAAK,CAC1G,EAAA,SAAA,CAACC,EAAAA,IAAAyC,EAAA,OAAA,CAAO,KAAM,EAAI,CAAA,EAAE,IAACzC,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,kBAAmB,EAAI,SAAE6F,EAAA,QAAUA,EAAE,OAAS,EAAG,CAAA,EAC7FA,EAAE,WAAa,MAAMA,EAAE,SAAS,EAFzB,CAAA,EAAA3F,CAGV,CACD,CACH,CAAA,CACF,CAAA,EAZwB,IAc5B,CChBA,SAAwB4F,GAAqB,CAC3C,SAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,mBAAA3C,EACA,gBAAAD,EACA,aAAA6C,EACA,OAAAC,EACA,aAAAC,EACA,WAAAC,EACA,cAAAC,EACA,kBAAAC,EACA,SAAAC,CACF,EAAG,CACD,OAAKT,EAGHhG,EAAA,KAACsC,GAAW,WAAA,CAAA,MAAM,YAChB,SAAA,CAAArC,EAAA,IAACyG,GAAA,SAAA,CACC,SAAUT,EACV,gBAAiBC,GAAmB,EACpC,mBAAA3C,EACA,OAAA6C,EACA,aAAc,GACd,aAAc,GACd,gBAAA9C,EACA,aAAA6C,EACA,aAAAE,EACA,WAAAC,EACA,cAAAC,EACA,kBAAAC,CAAA,CACF,QAEC,QAAM,CAAA,IAAKC,EAAU,QAAQ,OAAO,MAAO,CAAE,QAAS,QACrD,SAACxG,EAAAA,IAAA,SAAA,CAAO,IAAK+F,EAAU,KAAK,YAAa,CAAA,EAC3C,CACF,CAAA,CAAA,EAtBoB,IAwBxB,CCvCA,SAAwBW,GAAsB,CAC5C,WAAAC,EACA,SAAAZ,EACA,iBAAAa,EACA,gBAAAC,EACA,gBAAAxD,EACA,iBAAAyD,EACA,mBAAAC,EACA,gBAAAC,CACF,EAAG,OACG,GAAA,GAACzG,EAAAoG,GAAA,YAAAA,EAAY,WAAZ,MAAApG,EAAsB,QAAe,OAAA,KAGpC,MAAA0G,EAAkB,CAACtC,EAASC,IAAU,CAC1C,GAAID,GAAW,KAAa,OACtB,MAAAuC,EAAcC,GAAO,CACzB,MAAMC,EAAU,KAAK,MAAMD,EAAK,GAAK,EAC/B5F,EAAU,KAAK,MAAO4F,EAAK,IAAS,GAAI,EAC9C,MAAO,GAAGC,EAAQ,SAAS,EAAE,SAAS,EAAG,GAAG,CAAC,IAAI7F,EAAQ,SAAS,EAAE,SAAS,EAAG,GAAG,CAAC,EAAA,EAEhF8F,EAAQH,EAAWvC,CAAO,EAC1B2C,EAAM1C,GAAS,KAAOsC,EAAWtC,CAAK,EAAIyC,EACzC,MAAA,GAAGA,CAAK,IAAIC,CAAG,EAAA,EAGlBC,EAAQZ,EAAW,SAAS,IAAI,CAACnF,EAAGtB,IAAO,SAAA,OAC/C,MAAOsB,EAAE,QAAU,UAAWjB,EAAAoG,EAAW,YAAX,YAAApG,EAAsB,QAAS,UAAYE,EAAAkG,EAAW,YAAX,YAAAlG,EAAsB,WAAY,WAC3G,UAAWe,EAAE,QAAU,QAAU,QAAU,WAC3C,KAAMA,EAAE,MAAQ,GAChB,UAAWyF,EAAgBzF,EAAE,OAASA,EAAE,SAAUA,EAAE,KAAOA,EAAE,MAAM,EACnE,cAAeoF,EAAiB,IAAI1G,CAAC,EACrC,eAAiBmD,GAAmBwD,IAAoB3G,EACnDsB,EAAE,QAAU,QAAU,sBAAwB,wBAC/C,OACJ,cAAesF,EAAiB5G,CAAC,GAAK,CAAA,GAAI,IAAYqE,IAAA,CACpD,GAAGA,EACH,QAAS,IAAM,CAEMwC,EAAAS,OAAY,IAAI,CAAC,GAAGA,EAAMjD,EAAI,SAAS,CAAC,CAAC,EAC5D,WAAW,IAAM,CACf,MAAMkD,EAAK,SAAS,eAAe,UAAUlD,EAAI,SAAS,EAAE,EACxDkD,GAAIA,EAAG,eAAe,CAAE,SAAU,SAAU,MAAO,UAAW,GACjE,GAAG,CACR,CAAA,EACA,CACF,EAAA,EAGA,OAAAzH,EAAAA,IAAC,MAAI,CAAA,GAAG,uBACN,SAAAA,EAAA,IAAC0H,GAAA,eAAA,CACC,MAAAH,EACA,SAAAxB,EACA,gBAAAc,EACA,qBAAsBxD,EACtB,kBAAmBA,EACnB,gBAAA2D,CAAA,CAEJ,CAAA,CAAA,CAEJ,CCzDA,MAAMW,GAA2B,CAC/B,QAAS,EACT,OAAQ,OACR,WAAY,cACZ,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,OAAQ,UACR,WAAY,SACd,EAIMC,GAAgBC,GAAS,CAC7B,GAAI,CAACA,EAAa,OAAA,KAClB,MAAMC,EAAa,OAAOD,CAAI,EAAE,YAAY,EAC5C,OAAIC,IAAe,aAAqB,yBACpCA,IAAe,SAAWA,IAAe,gBACpC,wBACLA,IAAe,QAAgB,sBAC5B,IACT,EAIMC,GAAwBC,GAAS,CACrC,GAAI,CAACA,EAAM,MAAO,GAElB,MAAMC,EAAmB,CACvBD,EAAK,SACLA,EAAK,SACLA,EAAK,gBACLA,EAAK,MACLA,EAAK,QAAA,EAGP,UAAWE,KAAaD,EACtB,GAAI,MAAM,QAAQC,CAAS,GAAKA,EAAU,OACjC,OAAAA,EAKX,OAAIF,EAAK,UAAY,MAAM,QAAQA,EAAK,SAAS,IAAI,EAC5CA,EAAK,SAAS,KAGhB,EACT,EAKMG,GAAkB,CAACC,EAAaC,EAAW,KAAMC,EAAa,IAAM,CACxE,MAAMC,EAAM,CAAA,EAEZ,OAACH,GAAe,CAAC,GAAG,QAAQ,CAAC5G,EAAGgH,IAAU,CAClC,MAAAC,EAASjH,EAAE,QAAU,GACrBkH,EAAaD,EAAO,MAAQjH,EAAE,aAAe,UAC7CmH,EACJF,EAAO,UACNC,EACE,MAAM,GAAG,EACT,IAAKE,GAAMA,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,EACP,YACH,GAAA,IACIf,EAAOY,EAAO,MAAQjH,EAAE,YACxBqH,EAAYjB,GAAaC,CAAI,EAC7B7G,EAAQyH,EAAO,OAASjH,EAAE,cAAgBqH,GAAa,UAEvDC,EAAKtH,EAAE,IAAM,OAAO8G,EAAaE,CAAK,GAEtCO,EAAc,CAClB,GAAAD,EACA,OAAQ,CACN,KAAMJ,EACN,SAAAC,EACA,MAAA3H,EACA,KAAA6G,CACF,EACA,QAASrG,EAAE,SAAWA,EAAE,MAAQ,GAChC,UAAWA,EAAE,WAAaA,EAAE,oBAAsBA,EAAE,YAAc,GAClE,KAAMA,EAAE,MAAQ,UAChB,SAAUA,EAAE,UAAYA,EAAE,WAAaA,EAAE,QAAU,GACnD,WAAYA,EAAE,YAAc,CAAC,EAC7B,SAAUA,EAAE,UAAYA,EAAE,mBAAqB6G,GAAY,IAAA,EAG7DE,EAAI,KAAKQ,CAAW,EAEhB,MAAM,QAAQvH,EAAE,OAAO,GAAKA,EAAE,QAAQ,OAAS,GAC7C+G,EAAA,KACF,GAAGJ,GAAgB3G,EAAE,QAASsH,EAAIR,EAAaC,EAAI,MAAM,CAAA,CAE7D,CACD,EAEMA,CACT,EAEMS,GAAmBC,GAAU,CACjC,GAAI,CAACA,EAAc,MAAA,GAEf,GAAA,CAAC,sBAAsB,KAAKA,CAAK,EAAU,OAAAA,EAE3C,GAAA,CACI,MAAAC,EAAI,IAAI,KAAKD,CAAK,EACxB,GAAI,OAAO,MAAMC,EAAE,QAAA,CAAS,EAAU,OAAAD,EAEhC,MAAAE,MAAU,KACVC,EACJF,EAAE,YAAA,IAAkBC,EAAI,YACxB,GAAAD,EAAE,SAAS,IAAMC,EAAI,SAAS,GAC9BD,EAAE,QAAQ,IAAMC,EAAI,UAEhBE,EAAY,IAAI,KAAKF,CAAG,EAC9BE,EAAU,QAAQA,EAAU,QAAQ,EAAI,CAAC,EACzC,MAAMC,EACJJ,EAAE,YAAA,IAAkBG,EAAU,YAC9B,GAAAH,EAAE,SAAS,IAAMG,EAAU,SAAS,GACpCH,EAAE,QAAQ,IAAMG,EAAU,UAEtBE,EAAUL,EAAE,mBAAmB,OAAW,CAC9C,KAAM,UACN,OAAQ,UACR,OAAQ,EAAA,CACT,EAED,GAAIE,EACF,MAAO,YAAYG,CAAO,GAG5B,GAAID,EACF,MAAO,gBAAgBC,CAAO,GAKhC,MAAMC,GADSL,EAAI,QAAQ,EAAID,EAAE,QAAQ,IACd,IAAO,GAAK,GAAK,IACxC,OAAAM,EAAW,GAAKA,EAAW,EAEtB,GADSN,EAAE,mBAAmB,OAAW,CAAE,QAAS,OAAQ,CAClD,OAAOK,CAAO,GAU1B,GANSL,EAAE,mBAAmB,OAAW,CAC9C,MAAO,QACP,IAAK,UACL,KAAMA,EAAE,gBAAkBC,EAAI,cAAgB,UAAY,MAAA,CAC3D,CAEgB,OAAOI,CAAO,EAAA,MACzB,CACC,OAAAN,CACT,CACF,EA6BA,SAAwBQ,GAAc,CACpC,aAAAC,EACA,gBAAAC,EACA,YAAAC,EACA,SAAUC,EACV,cAAAC,EACA,cAAAC,EACA,eAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,kBAAAC,EACA,eAAAC,EACA,YAAAC,EACA,UAAAC,EAAY,EACd,EAAG,CACD,KAAM,CAACC,EAAcC,CAAe,EAAIC,WAAS,EAAE,EAC7C,CAACC,EAAWC,CAAY,EAAIF,WAAS,EAAK,EAC1C,CAACG,EAAUC,CAAW,EAAIJ,EAAAA,SAASZ,GAAmB,CAAA,CAAE,EACxD,CAACiB,EAAWC,CAAY,EAAIN,WAAS,EAAK,EAC1C,CAACO,EAAkBC,CAAmB,EAAIR,WAAS,IAAI,EAEvD,CAACS,EAASC,CAAU,EAAIV,EAAA,SAAS,CAAE,CAAA,EACnC,CAACW,EAAgBC,CAAiB,EAAIZ,WAAS,IAAI,EACnD,CAACa,EAAqBC,CAAsB,EAAId,WAAS,IAAI,EAC7D,CAACe,EAAYC,CAAa,EAAIhB,WAAS,EAAE,EACzC,CAACiB,EAAkBC,CAAmB,EAAIlB,WAAS,IAAI,EACvD,CAACmB,EAAaC,CAAc,EAAIpB,WAAS,EAAE,EAC3C,CAACqB,GAAsBC,EAAuB,EAAItB,WAAS,IAAI,EAC/D,CAACuB,GAAsBC,EAAuB,EAAIxB,WAAS,EAAK,EAChE,CAACyB,EAAgBC,EAAiB,EAAI1B,WAAS,EAAE,EACjD,CAAC2B,EAAqBC,EAAsB,EAAI5B,WAAS,EAAK,EAC9D,CAAC6B,GAAmBC,EAAoB,EAAI9B,EAAAA,SAAS,IAAI,GAAK,EAE9D+B,GAAiBC,SAAO,IAAI,EAC5BC,GAAkBD,SAAO,IAAI,EAE7BE,GACHtC,GAAeA,EAAY,MAAQ,OAAOA,EAAY,IAAI,EAAE,YAC7D,GAAA,GAEIuC,GAAqBlJ,EAAAA,QAAQ,IAAM,CACvC,GAAI,CAAC2G,EACI,MAAA,CACT,KAAM,MACN,SAAU,KACV,MAAO,SAAA,EAID,MAAApG,EAAOoG,EAAY,MAAQ,MAC3B1B,EACJ0B,EAAY,UACXpG,EACE,MAAM,GAAG,EACT,IAAK2E,GAAMA,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,EACP,YACH,GAAA,KAEIf,EACJwC,EAAY,MAAQ,OAAOA,EAAY,IAAI,EAAE,cACzCxB,EAAYjB,GAAaC,CAAI,EAE7B7G,EAAQqJ,EAAY,OAASxB,GAAa,UAEzC,MAAA,CACL,GAAGwB,EACH,KAAApG,EACA,SAAA0E,EACA,MAAA3H,CAAA,CACF,EACC,CAACqJ,CAAW,CAAC,EACVwC,GACJF,KAAmB,cAAgBA,KAAmB,QAElDG,GAAqBpJ,EAAAA,QAAQ,IAAM,CACvC,MAAMqJ,EAAM,CAAA,EACZ,OAACnC,GAAY,CAAA,GAAI,QAASpJ,GAAM,CACzBA,EAAE,WACFuL,EAAIvL,EAAE,QAAQ,IAAOuL,EAAAvL,EAAE,QAAQ,EAAI,IACxCuL,EAAIvL,EAAE,QAAQ,EAAE,KAAKA,CAAC,EAAA,CACvB,EACMuL,CAAA,EACN,CAACnC,CAAQ,CAAC,EAEPoC,GAAmBtJ,EAAA,QACvB,KAAOkH,GAAY,IAAI,OAAQpJ,GAAM,CAACA,EAAE,QAAQ,EAChD,CAACoJ,CAAQ,CAAA,EAKLqC,GAAgBnE,GAAOwC,IAAwBxC,EAC/CoE,GAAepE,GAAO4C,IAAqB5C,EAI3CqE,GAAYvD,GAAeF,GAAgBC,EAC3CyD,GAAoB9B,EACtBV,EAAS,KAAMpJ,GAAMA,EAAE,KAAO8J,CAAmB,EACjD,KAEJ+B,EAAAA,UAAU,IAAM,CAGVvD,GACCD,GACLgB,EAAYhB,CAAe,CAAA,EAC1B,CAACA,EAAiBC,CAAa,CAAC,EAInCuD,EAAAA,UAAU,IAAM,CACd,GAAI,CAACvD,EAAe,OAEpB,MAAMwD,EAAa,MAAM,QAAQxD,EAAc,OAAO,EAClDA,EAAc,QACd,MAAM,QAAQA,EAAc,KAAK,EACjCA,EAAc,MACd,GAGA,GAAAwD,EAAW,OAAS,EAAG,CACzB,MAAMC,EAAoBD,EAAW,IAAI,CAACE,EAAGhF,IAAU,CACrD,MAAMM,EAAK0E,EAAE,IAAMA,EAAE,WAAa,UAAUhF,EAAQ,CAAC,GAC/CzH,EACJyM,EAAE,OACFA,EAAE,QACDhF,IAAU,EAAIoB,GAAe,UAAY,UAAUpB,EAAQ,CAAC,IAEzDiF,EAAuB1F,GAAqByF,CAAC,EAC7CE,EAAoBvF,GAAgBsF,CAAoB,EAE9D,MAAO,CAAE,GAAA3E,EAAI,MAAA/H,EAAO,SAAU2M,CAAkB,CAAA,CACjD,EAGDvC,EAAWoC,CAAiB,EAE5B,MAAMI,EACJJ,EAAkB,KAAMC,IAAOA,EAAE,UAAY,CAAA,GAAI,OAAS,CAAC,GAC3DD,EAAkB,CAAC,EAEfK,GAAeD,GAAA,YAAAA,EAAmB,WAAY,GACpD9C,EAAY+C,CAAY,EAEHrB,GAAA,IAAI,GAAK,EACZlB,GAAAsC,GAAA,YAAAA,EAAmB,KAAM,IAAI,EAC/C,MACF,CAGM,MAAAE,EAAU9F,GAAqB+B,CAAa,EAClD,GAAI+D,EAAQ,OAAQ,CACZ,MAAAC,EAAiB3F,GAAgB0F,CAAO,EAE9ChD,EAAYiD,CAAc,EAELvB,GAAA,IAAI,GAAK,EAIxB,MAAAwB,EAAWjE,EAAc,IAAM,WAC/BkE,EACJlE,EAAc,OAASF,GAAe,WAE7BuB,EAAA,CACT,CACE,GAAI4C,EACJ,MAAOC,CACT,CAAA,CACD,EACD3C,EAAkB0C,CAAQ,CAC5B,CAAA,EACC,CAACjE,EAAeF,CAAW,CAAC,EAC/ByD,EAAAA,UAAU,IAAM,CAETzD,GACLuB,EAAY3D,GACVA,EAAK,IAAI,CAACyG,EAAQzF,IAChBA,IAAU,EAAI,CAAE,GAAGyF,EAAQ,MAAOrE,CAAA,EAAgBqE,CACpD,CAAA,CACF,EACC,CAACrE,CAAW,CAAC,EAEhByD,EAAAA,UAAU,IAAM,CAEV,GADA,CAACb,GAAe,SAChB,CAAC5B,GAAYA,EAAS,SAAW,EAAG,OAGlC,MAAAsD,EAAY1B,GAAe,QAAQ,cACrC0B,EACFA,EAAU,UAAYA,EAAU,aAEhC1B,GAAe,QAAQ,eAAe,CAAE,SAAU,SAAU,MAAO,MAAO,CAC5E,EACC,CAAC5B,CAAQ,CAAC,EAEb,MAAMuD,GAAwB,SAAY,CAClC,MAAAC,EAAUlC,EAAe,OAC/B,GAAKkC,EACL,CAAA/B,GAAuB,EAAI,EACvB,GAAA,CACF,MAAMgC,EAAQ,UAAU,KAAK,IAAA,CAAK,GAClClD,EAAY3D,GAAS,CACnB,GAAGA,EACH,CACE,GAAI6G,EACJ,MAAOD,EAAQ,MAAM,EAAG,EAAE,GAAK,UAAU5G,EAAK,OAAS,CAAC,EAC1D,CAAA,CACD,EACD6D,EAAkBgD,CAAK,EACvB,MAAMlE,GAAA,YAAAA,EAAoBiE,IAC1BjC,GAAkB,EAAE,EACpBF,GAAwB,EAAK,CAAA,QAC7B,CACAI,GAAuB,EAAK,CAC9B,EAAA,EAGIiC,GAAwB,IAAM,CAClCrC,GAAwB,EAAK,EAC7BE,GAAkB,EAAE,CAAA,EAGhBoC,GAAa,SAAY,CACvB,MAAAH,EAAU7D,EAAa,OAC7B,GAAI,CAAC6D,EAAS,OAEd,MAAMI,EAAUJ,EAChB5D,EAAgB,EAAE,EAElB,MAAMiE,EAAe,QAAQ,KAAK,IAAA,CAAK,GACjCC,EAAoB,CACxB,GAAID,EACJ,OAAQ7B,GACR,QAAA4B,EACA,UAAW,WACX,KAAM,UACN,aAAc,GACd,SAAUlD,GAAuB,IAAA,EAKnC,GAFAT,EAAarD,GAAS,CAAC,GAAGA,EAAMkH,CAAiB,CAAC,EAE9C3E,EAAe,CACjBgB,EAAa,EAAI,EACb,GAAA,CACF,MAAMhB,EAAc,CAClB,QAAAyE,EACA,kBAAmBlD,GAAuB,IAAA,CAC3C,EACDT,EAAarD,GACXA,EAAK,IAAKmH,GACRA,EAAI,KAAOF,EAAe,CAAE,GAAGE,EAAK,aAAc,EAAA,EAAUA,CAC9D,CAAA,CACF,MACM,CACM9D,EAACrD,GAASA,EAAK,OAAQmH,GAAQA,EAAI,KAAOF,CAAY,CAAC,CAAA,QACnE,CACA1D,EAAa,EAAK,CACpB,CACAQ,EAAuB,IAAI,EAC3B,MACF,CAEAV,EAAarD,GACXA,EAAK,IAAKmH,GACRA,EAAI,KAAOF,EAAe,CAAE,GAAGE,EAAK,aAAc,EAAA,EAAUA,CAC9D,CAAA,EAEFpD,EAAuB,IAAI,CAAA,EAGvBqD,GAAkBvK,GAAM,CACxBA,EAAE,MAAQ,SAAW,CAACA,EAAE,WAC1BA,EAAE,eAAe,EACNkK,KACb,EAGIM,GAAoBC,GAAY,CACpCvD,EAAuBuD,EAAQ,EAAE,EACjCrD,EAAc,EAAE,EAChBE,EAAoB,IAAI,EACxBE,EAAe,EAAE,EACjBZ,EAAoB,IAAI,EACxBjB,GAAA,MAAAA,EAAiB8E,EAAO,EAGpBC,GAAwB,MAAOC,GAAoB,CACjD,MAAAZ,EAAU5C,EAAW,OAC3B,GAAI,CAAC4C,EAAS,OAEd,MAAMK,EAAe,SAAS,KAAK,IAAA,CAAK,GAClCQ,EAAkB,CACtB,GAAIR,EACJ,OAAQ7B,GACR,QAASwB,EACT,UAAW,WACX,KAAM,UACN,aAAc,CAACrE,EACf,SAAUiF,CAAA,EAGZnE,EAAarD,GAAS,CAAC,GAAGA,EAAMyH,CAAe,CAAC,EAEhDlE,EAAa,EAAI,EACb,GAAA,CACEhB,IACF,MAAMA,EAAc,CAClB,QAASqE,EACT,kBAAmBY,CAAA,CACpB,EACDnE,EAAarD,GACXA,EAAK,IAAKmH,GACRA,EAAI,KAAOF,EAAe,CAAE,GAAGE,EAAK,aAAc,EAAA,EAAUA,CAC9D,CAAA,GAGJpD,EAAuB,IAAI,EAC3BE,EAAc,EAAE,CAAA,MACV,CACF1B,GACUc,EAACrD,GAASA,EAAK,OAAQmH,GAAQA,EAAI,KAAOF,CAAY,CAAC,CACrE,QACA,CACA1D,EAAa,EAAK,CACpB,CAAA,EAGImE,GAAmBJ,GAAY,CACnCnD,EAAoBmD,EAAQ,EAAE,EACfjD,EAAAiD,EAAQ,SAAW,EAAE,EACpCvD,EAAuB,IAAI,EAC3BE,EAAc,EAAE,EAChBR,EAAoB,IAAI,CAAA,EAGpBkE,GAAmB,SAAY,CAC7B,MAAAf,EAAUxC,EAAY,OACxB,GAAA,GAACwC,GAAW,CAAC1C,GACb,GAAA,CACI,MAAA/H,EAAS,MAAMsG,GAAA,YAAAA,EAAgB,CAAE,GAAIyB,EAAkB,QAAS0C,KAGtE,GAAIzK,GAAU,OAAOA,GAAW,UAAYA,EAAO,UAAY,GAC7D,OAEJkH,EAAarD,GACXA,EAAK,IAAKmH,GACRA,EAAI,KAAOjD,EACP,CAAE,GAAGiD,EAAK,QAASP,EAAS,SAAU,EACtC,EAAAO,CACN,CAAA,EAEAhD,EAAoB,IAAI,EACxBE,EAAe,EAAE,QACVuD,EAAK,CAGJ,QAAA,MAAM,6BAA8BA,CAAG,CACjD,CAAA,EAGIC,GAAmB,IAAM,CAC7B1D,EAAoB,IAAI,EACxBE,EAAe,EAAE,CAAA,EAGbyD,GAAqBR,GAAY,CACrC/C,GAAwB+C,CAAO,EAC/B7D,EAAoB,IAAI,CAAA,EAGpBsE,GAAsB,SAAY,CACtC,GAAI,CAACzD,GAAsB,OAC3B,MAAM6C,EAAM7C,GACZC,GAAwB,IAAI,EAChBlB,EAACrD,GAASA,EAAK,OAAQhG,GAAMA,EAAE,KAAOmN,EAAI,EAAE,CAAC,EACzD,MAAMzE,GAAA,YAAAA,EAAkByE,GAAG,EAIzBa,GAAoB,CAACV,EAASW,EAAQ,IAAM,SAChD,MAAMC,EAAW5C,GAAmBgC,EAAQ,EAAE,GAAK,CAAA,EAC7Ca,EAAcD,EAAS,OAAS,EAChCtL,EAAakI,GAAkB,IAAIwC,EAAQ,EAAE,EAC7Cc,EAAY1C,GAAY4B,EAAQ,EAAE,EAClCe,EAAa5C,GAAa6B,EAAQ,EAAE,EAE1C,aACG,MACC,CAAA,SAAA/O,EAAA,KAAC,MAAA,CACC,aAAc,IACZ+O,EAAQ,OAAS,UAAY7D,EAAoB6D,EAAQ,EAAE,EAE7D,aAAc,IAAM7D,EAAoB,IAAI,EAC5C,MAAO,CACL,QAAS,OACT,IAAK,OACL,QAAS6D,EAAQ,OAAS,SAAW,IAAO,EAC5C,QAAS,QACT,OAAQ,SACR,aAAc,MACd,WAAYW,EAAQ,EAAI,GAAK,CAC/B,EAEC,SAAA,CAAAX,EAAQ,OAAS,SAChB9O,EAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,aAAc,MACd,WAAY8O,EAAQ,OAAO,MAC3B,MAAO,QACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAU,OACV,WAAY,IACZ,WAAY,CACd,EAEC,WAAQ,OAAO,QAAA,CAAA,EAGlB9O,EAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,aAAc,MACd,WAAY,wBACZ,MAAO,yBACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,WAAY,CACd,EAEA,SAAAA,EAAAA,IAAC8P,EAAAA,MAAM,CAAA,KAAM,EAAI,CAAA,CAAA,CACnB,EAGF/P,OAAC,OAAI,MAAO,CAAE,KAAM,EAAG,SAAU,CAE/B,EAAA,SAAA,CAAAA,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,WACZ,SAAU,OACV,IAAK,MACL,aAAc,MACd,eAAgB,eAClB,EAEA,SAAA,CAAAA,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,WACZ,SAAU,OACV,IAAK,KACP,EAEA,SAAA,CAAAC,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,MAAO,uBACT,EAEC,WAAQ,OAAO,IAAA,CAClB,EACC8O,EAAQ,WACP9O,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,kCACZ,MAAO,uBACT,EAEC,SAAAgJ,GAAgB8F,EAAQ,SAAS,CAAA,CACpC,IAEDvO,EAAAuO,EAAQ,SAAR,YAAAvO,EAAgB,OACfP,EAAA,IAAC,OAAA,CACC,MAAO,CACL,QAAS,cACT,WAAY,SACZ,SAAU,OACV,MAAO,wBACP,WAAY,yBACZ,QAAS,UACT,aAAc,MACd,cAAe,YACf,cAAe,SACf,WAAY,GACd,EAEC,SAAA,OAAO8O,EAAQ,OAAO,IAAI,CAAA,CAC7B,GAEAA,EAAQ,UAAYA,EAAQ,YAC5B9O,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,wBACP,UAAW,QACb,EACD,SAAA,UAAA,CAED,CAAA,CAAA,CAEJ,EAEC8O,EAAQ,OAAS,UAChB9D,IAAqB8D,EAAQ,IAC3B/O,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,OACL,WAAY,CACd,EAEA,SAAA,CAAAC,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAUqE,GAAM,CACdA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBwK,GAAiBC,CAAO,CAC1B,EACA,MAAOnH,GACR,SAAA,OAAA,CAED,EACCsC,GACCjK,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAUqE,GAAM,CACdA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClB6K,GAAgBJ,CAAO,CACzB,EACA,MAAOnH,GACR,SAAA,MAAA,CAED,EAEDuC,GACClK,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAUqE,GAAM,CACdA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBiL,GAAkBR,CAAO,CAC3B,EACA,MAAO,CACL,GAAGnH,GACH,MAAO,wBACT,EACD,SAAA,QAAA,CAED,CAAA,CAAA,CAEJ,CAAA,CAAA,CAEN,EAGCiI,EACE7P,EAAAA,KAAA,MAAA,CAAI,MAAO,CAAE,UAAW,KACvB,EAAA,SAAA,CAAAC,EAAA,IAAC,WAAA,CACC,MAAO4L,EACP,SAAWvH,GAAMwH,EAAexH,EAAE,OAAO,KAAK,EAC9C,UAAYA,GAAM,CACZA,EAAE,MAAQ,SAAW,CAACA,EAAE,WAC1BA,EAAE,eAAe,EACA8K,MAEf9K,EAAE,MAAQ,UAA2BgL,IAC3C,EACA,YAAY,kBACZ,UAAS,GACT,MAAO,CACL,MAAO,OACP,UAAW,OACX,QAAS,WACT,SAAU,OACV,MAAO,yBACP,WAAY,QACZ,OAAQ,kCACR,aAAc,MACd,OAAQ,WACR,QAAS,OACT,WAAY,UACZ,WAAY,IACZ,aAAc,KAChB,CAAA,CACF,EACAtP,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,IAAK,MACL,eAAgB,WAChB,WAAY,QACd,EAEA,SAAA,CAAAC,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASqP,GACT,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,wBACZ,OAAQ,OACR,aAAc,MACd,OAAQ,UACR,QAAS,OACT,WAAY,SACZ,IAAK,MACL,WAAY,gBACd,EACA,aAAehL,GAAM,CACjBA,EAAA,cAAc,MAAM,WACpB,yBACAA,EAAA,cAAc,MAAM,MACpB,uBACJ,EACA,aAAeA,GAAM,CACjBA,EAAA,cAAc,MAAM,WACpB,wBACAA,EAAA,cAAc,MAAM,MACpB,wBACJ,EACD,SAAA,QAAA,CAED,EACArE,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASmP,GACT,SAAU,EAACvD,GAAA,MAAAA,EAAa,QACxB,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAOA,GAAA,MAAAA,EAAa,OAChB,QACA,yBACJ,WAAYA,GAAA,MAAAA,EAAa,OACrB,UACA,wBACJ,OAAQ,OACR,aAAc,MACd,OAAQA,GAAA,MAAAA,EAAa,OAAS,UAAY,cAC1C,QAAS,OACT,WAAY,SACZ,IAAK,MACL,WAAY,gBACd,EACA,aAAevH,GAAM,CACfuH,GAAA,MAAAA,EAAa,SACbvH,EAAA,cAAc,MAAM,WAAa,UAEvC,EACA,aAAeA,GAAM,CACfuH,GAAA,MAAAA,EAAa,SACbvH,EAAA,cAAc,MAAM,WAAa,UAEvC,EACD,SAAA,MAAA,CAED,CAAA,CAAA,CACF,CAAA,CAAA,CACF,EAEArE,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,KACZ,cAAcS,EAAAqO,EAAQ,aAAR,MAAArO,EAAoB,OAAS,MAAQ,CACrD,EAEC,SAAQqO,EAAA,OAAA,CACX,EAIDe,GACE9P,EAAAA,KAAA,MAAA,CAAI,MAAO,CAAE,UAAW,MACvB,EAAA,SAAA,CAAAC,EAAA,IAAC,WAAA,CACC,MAAOwL,EACP,SAAWnH,GAAMoH,EAAcpH,EAAE,OAAO,KAAK,EAC7C,UAAYA,GAAM,CACZA,EAAE,MAAQ,WACZkH,EAAuB,IAAI,EAC3BE,EAAc,EAAE,EAEpB,EACA,YAAY,qBACZ,SAAUX,EACV,UAAS,GACT,MAAO,CACL,MAAO,OACP,UAAW,OACX,QAAS,WACT,SAAU,OACV,MAAO,yBACP,WAAY,QACZ,OAAQ,mCACR,aAAc,MACd,OAAQ,WACR,QAAS,OACT,WAAY,UACZ,WAAY,IACZ,aAAc,MAChB,CAAA,CACF,EACA/K,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,IAAK,MACL,eAAgB,WAChB,WAAY,QACd,EAEA,SAAA,CAAAC,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,CACbuL,EAAuB,IAAI,EAC3BE,EAAc,EAAE,CAClB,EACA,SAAUX,EACV,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,wBACZ,OAAQ,OACR,aAAc,MACd,OAAQA,EAAY,cAAgB,SACtC,EACD,SAAA,QAAA,CAED,EACA9K,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM+O,GAAsBD,EAAQ,EAAE,EAC/C,SAAU,CAACtD,EAAW,KAAA,GAAUV,EAChC,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MACEU,EAAW,KAAA,GAAU,CAACV,EAClB,QACA,yBACN,WACEU,EAAW,KAAA,GAAU,CAACV,EAClB,UACA,yBACN,OAAQ,OACR,aAAc,MACd,OACEU,EAAW,KAAA,GAAU,CAACV,EAClB,UACA,aACR,EACD,SAAA,MAAA,CAED,CAAA,CAAA,CACF,CAAA,EACF,EAOD6E,GACE5P,EAAAA,KAAA,MAAA,CAAI,MAAO,CAAE,UAAW,CACvB,EAAA,SAAA,CAAAA,EAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IACPwM,GAAsB/E,GAAS,CACvB,MAAAuI,EAAO,IAAI,IAAIvI,CAAI,EACzB,OAAAuI,EAAK,IAAIjB,EAAQ,EAAE,EACfiB,EAAK,OAAOjB,EAAQ,EAAE,EACtBiB,EAAK,IAAIjB,EAAQ,EAAE,EAChBiB,CAAA,CACR,EAEH,MAAO,CACL,QAAS,cACT,WAAY,SACZ,IAAK,EACL,QAAS,UACT,SAAU,OACV,WAAY,IACZ,MAAO,wBACP,WAAY,cACZ,OAAQ,OACR,aAAc,EACd,OAAQ,SACV,EACA,MAAO3L,EAAa,mBAAqB,iBAEzC,SAAA,CAAApE,EAAA,IAACgQ,EAAA,aAAA,CACC,KAAM,GACN,MAAO,CACL,WAAY,EACZ,UAAW5L,EAAa,gBAAkB,eAC1C,WAAY,qBACd,CAAA,CACF,SACC,OACE,CAAA,SAAA,CAASsL,EAAA,OAAO,IAAEA,EAAS,SAAW,EAAI,QAAU,SAAA,EACvD,CAAA,CAAA,CACF,EAECtL,GACCpE,EAAA,IAAC,MAAA,CACC,MAAO,CACL,UAAW,EACX,WAAY,GACZ,YAAa,GACb,WAAY,kCACd,EAEC,SAAS0P,EAAA,IAAKO,GACbT,GAAkBS,EAAOR,EAAQ,CAAC,CACpC,CAAA,CACF,CAAA,EAEJ,CAAA,EAEJ,CAAA,CAAA,CAAA,GAhcMX,EAAQ,EAkclB,CAAA,EAKA,OAAA/O,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,cAAe,SACf,OAAQ,OACR,WAAY,4BACZ,OAAQ,mCACR,aAAc,OACd,SAAU,SACV,SAAU,UACZ,EAGC,SAAA,CACC+L,IAAA9L,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,EACP,OAAQ,GACR,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,WAAY,yBACZ,aAAc,MAChB,EACA,QAAS,IAAM+L,GAAwB,IAAI,EAE3C,SAAAhM,EAAA,KAAC,MAAA,CACC,MAAO,CACL,WAAY,QACZ,aAAc,OACd,QAAS,YACT,UAAW,oCACX,SAAU,QACV,MAAO,KACT,EACA,QAAUsE,GAAMA,EAAE,gBAAgB,EAElC,SAAA,CAAArE,EAAA,IAAC,IAAA,CACC,MAAO,CACL,OAAQ,EACR,aAAc,OACd,SAAU,OACV,WAAY,IACZ,MAAO,wBACP,WAAY,IACd,EACD,SAAA,+BAAA,CAED,EACAD,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,IAAK,OACL,eAAgB,UAClB,EAEA,SAAA,CAAAC,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM+L,GAAwB,IAAI,EAC3C,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,wBACZ,OAAQ,OACR,aAAc,MACd,OAAQ,SACV,EACD,SAAA,QAAA,CAED,EACA/L,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASuP,GACT,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,QACP,WAAY,UACZ,OAAQ,OACR,aAAc,MACd,OAAQ,SACV,EACD,SAAA,QAAA,CAED,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAIDpC,IACCnN,EAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,YACT,aAAc,mCACd,WAAY,2BACd,EAEA,SAAAD,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,eAAgB,gBAChB,WAAY,SACZ,IAAK,KACP,EAEA,SAAA,CAAAA,OAAC,MACC,CAAA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,aAAc,KAChB,EAEC,SAAe4J,GAAA,oBAAA,CAClB,GACEF,GAAgBC,IAChB3J,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,wBACT,EAEC,SAAgB0J,GAAAC,CAAA,CACnB,EAEDuB,EAAQ,OAAS,GAChBlL,EAAA,IAAC,MAAA,CACC,MAAO,CACL,UAAW,MACX,QAAS,OACT,SAAU,OACV,IAAK,KACP,EAEC,SAAAkL,EAAQ,IAAK+C,GAAW,CACjB,MAAAiC,EAAWjC,EAAO,KAAO7C,EAE7B,OAAApL,EAAA,IAAC,SAAA,CAEC,KAAK,SACL,QAAS,IAAM,CACbqL,EAAkB4C,EAAO,EAAE,EACvB,MAAM,QAAQA,EAAO,QAAQ,IAC/BpD,EAAYoD,EAAO,QAAQ,EAEN1B,GAAA,IAAI,GAAK,GAEhCtB,EAAoB,IAAI,EACxBM,EAAuB,IAAI,EAC3BI,EAAoB,IAAI,EACxBvB,GAAA,MAAAA,EAAiB6D,EACnB,EACA,MAAO,CACL,QAAS,WACT,aAAc,QACd,OAAQ,sCACR,WAAYiC,EACR,4BACA,2BACJ,MAAO,yBACP,SAAU,OACV,WAAY,IACZ,OAAQ,SACV,EAEC,SAAOjC,EAAA,KAAA,EA3BHA,EAAO,EAAA,CA4Bd,CAEH,CAAA,CACH,CAAA,EAEJ,EAGCpB,IACC9M,EAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,CACWkM,GAACzE,GAAS,CAACA,CAAI,CACzC,EACA,MAAO,CACL,QAAS,cACT,WAAY,SACZ,IAAK,MACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,cACZ,OAAQ,mCACR,aAAc,MACd,OAAQ,UACR,WAAY,yCACd,EACA,aAAenD,GAAM,CACjBA,EAAA,cAAc,MAAM,WACpB,4BACAA,EAAA,cAAc,MAAM,MAAQ,uBAChC,EACA,aAAeA,GAAM,CACjBA,EAAA,cAAc,MAAM,WAAa,cACjCA,EAAA,cAAc,MAAM,MAAQ,wBAChC,EACA,MAAM,gCAEN,SAAA,CAAArE,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,GACV,WAAY,EACZ,UAAW,EACb,EACD,SAAA,GAAA,CAED,EAAO,YAAA,CAAA,CAET,CAAA,CAAA,CAEJ,CAAA,CACF,EAIFD,EAAA,KAAC,MAAA,CACC,MAAO,CACL,KAAM,EACN,UAAW,OACX,QAAS,OACT,QAAS,OACT,cAAe,SACf,IAAK,MACP,EAGC,SAAA,CACCiM,IAAAjM,EAAA,KAAC,MAAA,CACC,MAAO,CACL,aAAc,OACd,QAAS,OACT,WAAY,yBACZ,OAAQ,mCACR,aAAc,KAChB,EAEA,SAAA,CAAAC,EAAA,IAAC,WAAA,CACC,MAAOkM,EACP,SAAW7H,GAAM8H,GAAkB9H,EAAE,OAAO,KAAK,EACjD,UAAYA,GAAM,CACZA,EAAE,MAAQ,SAAW,CAACA,EAAE,WAC1BA,EAAE,eAAe,EACK8J,KAE1B,EACA,YAAY,wBACZ,SAAU/B,EACV,MAAO,CACL,MAAO,OACP,UAAW,OACX,QAAS,WACT,SAAU,OACV,MAAO,yBACP,WAAY,QACZ,OAAQ,mCACR,aAAc,MACd,OAAQ,WACR,QAAS,OACT,WAAY,UACZ,WAAY,IACZ,aAAc,MAChB,CAAA,CACF,EACArM,EAAAA,KAAC,MAAI,CAAA,MAAO,CAAE,QAAS,OAAQ,IAAK,MAAO,eAAgB,UAAA,EACzD,SAAA,CAAAC,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASsO,GACT,SAAUlC,EACV,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,wBACP,WAAY,yBACZ,OAAQ,OACR,aAAc,MACd,OAAQA,EAAsB,cAAgB,SAChD,EACD,SAAA,QAAA,CAED,EACApM,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASmO,GACT,SAAU,CAACjC,EAAe,KAAA,GAAUE,EACpC,MAAO,CACL,QAAS,WACT,SAAU,OACV,WAAY,IACZ,MAAO,QACP,WACEF,EAAe,KAAA,GAAU,CAACE,EACtB,UACA,yBACN,OAAQ,OACR,aAAc,MACd,OACEF,EAAe,KAAA,GAAU,CAACE,EACtB,UACA,aACR,EAEC,WAAsB,aAAe,MAAA,CACxC,CAAA,EACF,CAAA,CAAA,CACF,EAED9B,EACCtK,EAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,QAAS,OACT,MAAO,wBACT,EACD,SAAA,qBAAA,CAAA,EAGCgN,GAAiB,SAAW,EAC9BhN,EAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,QAAS,OACT,MAAO,wBACT,EACD,SAAA,0CAAA,CAED,EA6wBAgN,GAAiB,IAAK8B,GAAYU,GAAkBV,EAAS,CAAC,CAAC,EAEjE9O,EAAAA,IAAC,MAAI,CAAA,IAAKwM,EAAgB,CAAA,CAAA,CAAA,CAC5B,EAGAxM,EAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,UAAW,mCACX,WAAY,2BACd,EAEA,SAAAD,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,IAAK,MACL,WAAY,UACd,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,aAAc,MACd,WAAY4M,GAAmB,MAC/B,MAAO,QACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAU,OACV,WAAY,IACZ,WAAY,CACd,EAEC,SAAmBA,GAAA,QAAA,CACtB,EAEA7M,EAAA,KAAC,MAAA,CACC,MAAO,CACL,KAAM,EACN,QAAS,OACT,cAAe,SACf,IAAK,KACP,EAEA,SAAA,CAAAC,EAAA,IAAC,WAAA,CACC,IAAK0M,GACL,MAAOnC,EACP,SAAWlG,GAAMmG,EAAgBnG,EAAE,OAAO,KAAK,EAC/C,UAAWuK,GACX,QAAS,IAAMjE,EAAa,EAAI,EAChC,OAAQ,IAAMA,EAAa,EAAK,EAChC,YACEyC,GAAoB,qBAAuB,mBAE7C,MAAO,CACL,MAAO,OACP,UAAW,OACX,UAAW,QACX,QAAS,WACT,SAAU,OACV,MAAO,yBACP,WAAY,QACZ,OAAQ,aACN1C,EACI,2BACA,wBACN,GACA,aAAc,MACd,OAAQ,WACR,QAAS,OACT,WAAY,0BACZ,WAAY,UACZ,WAAY,GACd,CAAA,CACF,EAEA1K,EAAA,IAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,UAClB,EAEA,SAAAA,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASuO,GACT,SAAU,CAAChE,EAAa,KAAA,GAAUO,EAClC,MAAO,CACL,QAAS,WACT,WACEP,EAAa,KAAA,GAAU,CAACO,EACpB,UACA,wBACN,OAAQ,OACR,aAAc,MACd,MACEP,EAAa,KAAA,GAAU,CAACO,EACpB,QACA,yBACN,SAAU,OACV,WAAY,IACZ,OACEP,EAAa,KAAA,GAAU,CAACO,EACpB,UACA,cACN,QAAS,OACT,WAAY,SACZ,IAAK,MACL,WAAY,gBACd,EAEC,WAEG/K,EAAAA,KAAAoQ,EAAA,SAAA,CAAA,SAAA,CAAAnQ,EAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,OAAQ,qCACR,eAAgB,QAChB,aAAc,MACd,UAAW,2BACb,CAAA,CACF,EAAE,YAAA,CAAA,CAEJ,EAGED,EAAAA,KAAAoQ,EAAA,SAAA,CAAA,SAAA,CAACnQ,EAAAA,IAAAoQ,EAAA,KAAA,CAAK,KAAM,EAAI,CAAA,EAAE,MAAA,EAEpB,CAAA,CAEJ,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CAAA,CAAA,CAGN,CC9uEA,SAASC,EAAUC,EAAQxH,EAAI,CAC7B,OAAOwH,EAAO,KAAMC,GAAMA,EAAE,WAAazH,CAAE,CAC7C,CAEA,SAAS0H,GAAuB,CAC9B,KAAA7Q,EACA,SAAAoG,EACA,aAAA0K,EACA,cAAA3G,EACA,gBAAA4G,EACA,cAAAC,EAEA,oBAAAC,EACA,oBAAAC,EACA,sBAAAC,EACA,wBAAAC,EACA,eAAA3G,EACA,cAAA4G,EACA,kBAAAC,CACF,EAAG,qCACK,MAAAX,EAAS3Q,EAAK,QAAU,GACRA,EAAK,eACrB,MAAA6G,EAAWiG,SAAO,IAAI,EACtByE,EAAuBzE,SAAO,IAAI,EAClC,CAAC7F,EAAkBuK,CAAmB,EAAI1G,EAAAA,SAAS,IAAI,GAAK,EAC5D,CAACvH,EAAiB6D,CAAkB,EAAI0D,EAAAA,SAAS,IAAI,GAAK,EAG1D,CAACnH,EAAoB8N,CAAqB,EAAI3G,WAAS,CAAC,EACxD,CAACpH,EAAiBgO,CAAkB,EAAI5G,WAAS,EAAK,EACtD,CAACvE,EAAcoL,CAAe,EAAI7G,WAAS,CAAC,EAG5C9I,IAAOpB,GAAA8P,EAAUC,EAAQ,sBAAsB,IAAxC,YAAA/P,GAA2C,UAAW,GAC7DgR,IAAM9Q,GAAA4P,EAAUC,EAAQ,qBAAqB,IAAvC,YAAA7P,GAA0C,UAAW,GAC3D+Q,IAAUC,GAAApB,EAAUC,EAAQ,qBAAqB,IAAvC,YAAAmB,GAA0C,UAAW,IACtDC,GAAArB,EAAUC,EAAQ,oBAAoB,IAAtC,MAAAoB,GAAyC,QACxD,MAAMzO,IAAU0O,GAAAtB,EAAUC,EAAQ,qBAAqB,IAAvC,YAAAqB,GAA0C,UAAW,GAC/DxM,IAAWyM,GAAAvB,EAAUC,EAAQ,sBAAsB,IAAxC,YAAAsB,GAA2C,UAAW,GACjEjL,IAAakL,GAAAxB,EAAUC,EAAQ,wBAAwB,IAA1C,YAAAuB,GAA6C,UAAW,GAErEjM,IAAMkM,GAAAzB,EAAUC,EAAQ,iBAAiB,IAAnC,YAAAwB,GAAsC,UAAW,GAEvDhQ,MADkBiQ,EAAA1B,EAAUC,EAAQ,wBAAwB,IAA1C,YAAAyB,EAA6C,UAAW,IAC5C,YAAc,CAAA,GAAI,OAAO7I,GAAKA,EAAE,KAAK,EACnE8I,KAAcC,EAAA5B,EAAUC,EAAQ,0BAA0B,IAA5C,YAAA2B,EAA+C,UAAW,GAGxEnL,GAAmBpD,EAAAA,QAAQ,IAAM,OACrC,MAAMqJ,EAAM,CAAA,EACNvK,EAAe,CACnB,QAAS,CAAE,MAAO,qBAAsB,EACxC,QAAS,CAAE,MAAO,uBAAwB,EAC1C,WAAY,CAAE,MAAO,wBAAyB,EAC9C,kBAAmB,CAAE,MAAO,mBAAoB,EAChD,WAAY,CAAE,MAAO,kBAAmB,CAAA,EAG1C,UAAW0P,KAAWjP,EAAQ,SAAW,CAAA,EAAK,CAC5C,MAAMkP,EAAY3P,EAAa0P,EAAO,KAAK,GAAK,CAAA,EAChD,UAAW3N,KAAQ2N,EAAO,cAAgB,CAAA,EACxC,UAAWzN,KAAOF,EAAI,UAAY,CAAA,EAC5B,IAAAhE,EAAAkE,EAAG,WAAH,MAAAlE,EAAa,OACJ,UAAA6R,KAAO3N,EAAG,SACdsI,EAAIqF,CAAG,IAAOrF,EAAAqF,CAAG,EAAI,IAErBrF,EAAIqF,CAAG,EAAE,KAAUC,IAAAA,GAAE,SAAW9N,EAAI,KAAO2N,EAAO,cAAgBA,EAAO,IAAI,GAC5EnF,EAAAqF,CAAG,EAAE,KAAK,CACZ,MAAO7N,EAAI,KAAO2N,EAAO,cAAgBA,EAAO,IAChD,OAAQ3N,EAAI,QAAUA,EAAI,aAAe,GACzC,MAAO4N,EAAU,OAAS,uBAC1B,UAAWD,EAAO,GAAA,CACnB,CAMb,CACO,OAAAnF,CAAA,EACN,CAAC9J,EAAQ,OAAO,CAAC,EAGd+C,KAAmBsM,EAAA3L,EAAW,WAAX,YAAA2L,EAAqB,IAAI,CAAC9Q,EAAGtB,IAAM,SACpD,MAAAqS,EAAa/Q,EAAE,OAASA,EAAE,UAAaA,EAAE,OAASA,EAAE,UAAY,IAAO,EACvEgR,EAAWhR,EAAE,KAAOA,EAAE,QAAWA,EAAE,KAAOA,EAAE,QAAU,IAAO+Q,EAAY,EACzEE,EAAUjR,EAAE,QAAU,QACtBkR,EAAYD,IAAWlS,EAAAoG,EAAW,YAAX,YAAApG,EAAsB,QAAS,UAAYE,EAAAkG,EAAW,YAAX,YAAAlG,EAAsB,WAAY,WAEnG,MAAA,CACL,UAAA8R,EACA,QAAAC,EACA,MAAOE,EACP,WAAYD,EAAU,sBAAwB,uBAAA,CAEjD,KAAK,CAAA,EAGA5L,GAAkBnD,EAAAA,QAAQ,IAAM,CAChC,GAAA,CAACL,GAAmBC,IAAuB,EAAU,MAAA,GACnD,MAAAsH,EAAWjE,EAAW,UAAY,GAClCgM,EAAYrP,EAAqB,IACvC,QAASpD,EAAI0K,EAAS,OAAS,EAAG1K,GAAK,EAAGA,IAAK,CAC7C,MAAMyE,EAAUiG,EAAS1K,CAAC,EAAE,OAAS0K,EAAS1K,CAAC,EAAE,SAC7C,GAAAyE,GAAW,MAAQgO,GAAahO,EAAgB,OAAAzE,CACtD,CACO,MAAA,IACN,CAACoD,EAAoBD,EAAiBsD,EAAW,QAAQ,CAAC,EAGvDiM,EAAsBrR,GAAY,CAClCiF,EAAS,UACXA,EAAS,QAAQ,YAAcjF,EAC/B6P,EAAsB7P,CAAO,EAC/B,EAGIsR,GAA2B,IAAM,CACrC,GAAIrM,EAAS,QACX,GAAInD,EACFmD,EAAS,QAAQ,QACjB6K,EAAmB,EAAK,MACnB,CACC,MAAAyB,EAAItM,EAAS,QAAQ,KAAK,EAC5BsM,IAAM,QAAWA,EAAE,MAAM,IAAM,CAAA,CAAG,EACtCzB,EAAmB,EAAI,CACzB,CACF,EAGI0B,EAAyB,IAAM,CAC/BvM,EAAS,UACFA,EAAA,QAAQ,YAAc,KAAK,IAAI,EAAGA,EAAS,QAAQ,YAAc,EAAE,EAC9E,EAGIwM,GAA4B,IAAM,CACtC,GAAIxM,EAAS,QAAS,CACpB,MAAMyM,EAAWtR,EAAK,kBAAoB6E,EAAS,QAAQ,UAAY,EAC9DA,EAAA,QAAQ,YAAc,KAAK,IAAIyM,EAAUzM,EAAS,QAAQ,YAAc,EAAE,CACrF,CAAA,EAGI0M,GAAyBC,GAAS,CAClC3M,EAAS,UACXA,EAAS,QAAQ,aAAe2M,EAChC7B,EAAgB6B,CAAI,EACtB,EAIF9F,EAAAA,UAAU,IAAM,CACd,MAAM+F,EAAQ5M,EAAS,QACvB,GAAI,CAAC4M,EAAO,OAEZ,MAAMC,EAAa,IAAMjC,EAAsBgC,EAAM,WAAW,EAC1DE,EAAa,IAAMjC,EAAmB,EAAI,EAC1CkC,EAAc,IAAMlC,EAAmB,EAAK,EAC5CmC,EAAc,IAAMnC,EAAmB,EAAK,EAE5C,OAAA+B,EAAA,iBAAiB,aAAcC,CAAU,EACzCD,EAAA,iBAAiB,OAAQE,CAAU,EACnCF,EAAA,iBAAiB,QAASG,CAAW,EACrCH,EAAA,iBAAiB,QAASI,CAAW,EAEpC,IAAM,CACLJ,EAAA,oBAAoB,aAAcC,CAAU,EAC5CD,EAAA,oBAAoB,OAAQE,CAAU,EACtCF,EAAA,oBAAoB,QAASG,CAAW,EACxCH,EAAA,oBAAoB,QAASI,CAAW,CAAA,CAChD,EACC,CAACzN,CAAQ,CAAC,EAEP,MAAA0N,GAAY,CAAC9O,EAASC,IAAU,CACpC,MAAM8O,EAASlN,EAAS,QACpB,GAAA,CAACkN,GAAU/O,GAAW,KAAM,OAEhC,MAAMG,EAAWH,EAAU,IAC3B+O,EAAO,YAAc5O,EACrBsM,EAAsBtM,CAAQ,EAExB,MAAAgO,EAAIY,EAAO,OASjB,GARIZ,IAAM,QAAWA,EAAE,MAAM,IAAM,CAAA,CAAG,EAGlC5B,EAAqB,UAChBwC,EAAA,oBAAoB,aAAcxC,EAAqB,OAAO,EACrEA,EAAqB,QAAU,MAG7BtM,GAAS,KAAM,CACjB,MAAMG,EAASH,EAAQ,IACjB+O,EAAU,IAAM,CAChBD,EAAO,aAAe3O,IACxB2O,EAAO,MAAM,EACTxC,EAAqB,UAChBwC,EAAA,oBAAoB,aAAcxC,EAAqB,OAAO,EACrEA,EAAqB,QAAU,MAEnC,EAEFA,EAAqB,QAAUyC,EACxBD,EAAA,iBAAiB,aAAcC,CAAO,CAC/C,CAAA,EAKIC,GAA2B,CAACjP,EAASC,EAAOiP,IAAY,CAC5D,MAAMH,EAASlN,EAAS,QACpB,GAAA,CAACkN,GAAU/O,GAAW,KAAM,OAEhC,MAAMG,EAAWH,EAAU,IACrBI,EAASH,GAAS,KAAOA,EAAQ,IAAOE,EAAW,EACnDgP,EAAaJ,EAAO,YAQ1B,GALErQ,GACAyQ,GAAchP,IACbC,GAAU,MAAQ+O,GAAc/O,EAAS,KAG3B,CACf2O,EAAO,MAAM,EACb,MACF,CAGAD,GAAU9O,EAASC,CAAK,EACpBiP,GAAA,MAAAA,EAAS,QACXtQ,GAAesQ,CAAO,CACxB,EAGIE,GAAgC,CAACC,EAAMxL,IAAU,CAE/C,MAAAsG,GADWnI,EAAW,UAAY,IACf6B,CAAK,EACxBkL,EAASlN,EAAS,QAEpB,GAAA,CAACsI,GAAW,CAAC4E,EAAQ,OAEnB,MAAA/O,EAAUmK,EAAQ,OAASA,EAAQ,SACnClK,EAAQkK,EAAQ,KAAOA,EAAQ,OAGjC,GAAAzL,GAAmBwD,KAAoB2B,EAAO,CAChDkL,EAAO,MAAM,EACb,MACF,CAEI/O,GAAW,MACf8O,GAAU9O,EAASC,CAAK,CAAA,EAGpBrB,GAAkBsQ,GAAY,CACd1C,EAAA,IAAI,IAAI0C,CAAO,CAAC,EAG9B,MAAA3F,EAAY,SAAS,eAAe,sBAAsB,EAC5DA,GACFA,EAAU,eAAe,CAAE,SAAU,SAAU,MAAO,UAAW,EAEnE,WAAW,IAAMiD,EAAoB,IAAI,GAAK,EAAG,GAAI,CAAA,EAGjDhO,GAAgB8Q,GAAQ,CAC5BlN,EAA2BS,GAAA,CACnB,MAAAuI,EAAO,IAAI,IAAIvI,CAAI,EACrB,OAAAuI,EAAK,IAAIkE,CAAG,EAAGlE,EAAK,OAAOkE,CAAG,EAAQlE,EAAK,IAAIkE,CAAG,EAC/ClE,CAAA,CACR,CAAA,EAGGrO,KAAQwS,EAAA3C,EAAI,eAAJ,YAAA2C,EAAkB,qBAAsB1C,EAAQ,WAAa,qBAErE,CAAC2C,GAAUC,EAAW,EAAI3J,WAAS,SAAS,EAC5C4J,GAAiB5H,SAAO,IAAI,EAC5B,CAAC6H,GAAiBC,EAAkB,EAAI9J,WAAS,IAAI,EAK3D+J,EAAAA,gBAAgB,IAAM,CAEpB,GADI9D,GACA,CAAC2D,GAAe,QAAS,OAE7B,MAAMI,EAAU,IAAM,OACd,MAAAC,IAAInU,EAAA8T,GAAe,UAAf,YAAA9T,EAAwB,eAAgB,EAC9CmU,EAAI,GAAGH,GAAmBG,CAAC,CAAA,EAIzBD,IACF,MAAA3L,EAAK,OAAO,sBAAsB2L,CAAO,EACxC,MAAA,IAAM,OAAO,qBAAqB3L,CAAE,GAC1C,CAAC4H,EAAiBD,EAAc9O,EAAM4P,CAAG,CAAC,EAKvC,MAAAoD,GAAmB,MAAOC,GAAY,CAE1C,GAAIhE,EAAqB,CACvB,MAAMA,EAAoBgE,CAAO,EACjC,MACF,CAAA,EAGIC,GAAmB,MAAOD,GAAY,CAC1C,GAAI/D,EACF,OAAOA,EAAoB+D,CAAO,CACpC,EAGIE,GAAqB,MAAOhG,GAAY,CAC5C,GAAIgC,EAAuB,CACzB,MAAMA,EAAsBhC,CAAO,EACnC,MACF,CAAA,EAGIiG,GAAwB,MAAOC,GAAc,CACjD,GAAIjE,EAAyB,CAC3B,MAAMA,EAAwBiE,CAAS,EACvC,MACF,CAAA,EAOIC,GACJnL,GAAiB,OAAO,KAAKA,CAAa,EAAE,OAAS,EACjDA,EACA,OAGJ,OAAA/J,OAAC,MAAI,CAAA,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,EAAA,EAC3D,SAAA,CAAAA,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,cAAe,MACf,WAAY,aACZ,IAAK,OACL,SAAU,MACZ,EAGA,SAAA,CAAAA,EAAA,KAAC,MAAA,CAAI,IAAKsU,GACR,MAAO,CACL,KAAM,YACN,SAAU,IACV,QAAS,OACT,cAAe,SACf,IAAK,EACP,EAEA,SAAA,CAAArU,EAAA,IAACyB,GAAA,CACC,MAAAC,GACA,KAAAC,EACA,YAAa4P,EAAI,aACjB,eAAgBA,EAAI,eACpB,WAAAzP,CAAA,CACF,EAMA9B,MAACkV,GAAAA,eAAc,YAAAlD,GAA0B,GAGvCtB,GAAmBD,GAAgBE,IAClC3Q,EAAA,IAAAqC,GAAA,WAAA,CAAW,MAAM,mBAChB,SAAArC,EAAA,IAACN,GAAA,CACC,KAAM+Q,EACN,QAASC,EACT,MAAOC,CAAA,CAAA,EAEX,CAAA,CAAA,CAEJ,EAGA5Q,EAAA,KAAC,MAAA,CACC,MAAO,CACL,KAAM,YACN,SAAU,IACV,QAAS,OACT,cAAe,SACf,OAAQuU,EACV,EAGA,SAAA,CAAAtU,EAAA,IAACmV,GAAA,KAAA,CACC,KAAM,CACJ,CAAE,IAAK,UAAW,MAAO,SAAU,EACnC,CAAE,IAAK,WAAY,MAAO,UAAW,CACvC,EACA,OAAQhB,GACR,SAAUC,GACV,KAAK,UACL,qBAAsB,GACtB,oBAAqB,EAAA,CACvB,EAEArU,EAAA,KAAC,MAAA,CACC,UAAU,gCACV,MAAO,CACL,KAAM,EACN,UAAW,OACX,QAAS,OACT,cAAe,SACf,IAAK,EACP,EAEC,SAAA,CAAAoU,KAAa,UACZnU,EAAA,IAACgD,GAAA,CACC,QAAAC,EACA,gBAAAC,EACA,aAAAC,GACA,aAAcyQ,GACd,gBAAAvQ,EACA,mBAAAC,EACA,eAAAC,GACA,aAAc,mBAAA,CAAA,EAGhBvD,EAAA,IAACkF,GAAA,CACC,SAAAC,EACA,aAAcyO,GACd,gBAAAvQ,EACA,mBAAAC,EACA,eAAAC,GACA,aAAc,mBAAA,CAChB,EAIFvD,MAAC2F,IAAe,IAAAC,EAAU,CAAA,CAAA,CAC5B,CAAA,CAAA,CACF,CAAA,CAAA,CACF,EAEA5F,EAAA,IAAC8F,GAAA,CACC,SAAAC,EACA,iBAAAC,GACA,gBAAiBrE,EAAK,iBACtB,mBAAA2B,EACA,gBAAAD,EACA,aAAA6C,EACA,OAAQ0M,EACR,aAAcC,GACd,WAAYE,EACZ,cAAeC,GACf,kBAAmBE,GACnB,SAAA1M,CAAA,CACF,EAGAxG,EAAA,IAAC0G,GAAA,CACC,WAAAC,EACA,SAAAZ,EACA,iBAAAa,EACA,gBAAAC,GACA,gBAAAxD,EACA,iBAAAyD,GACA,mBAAAC,EACA,gBAAiBgN,EAAA,CACnB,EAKA/T,EAAA,IAACyJ,GAAA,CACC,aAAc/H,GACd,cAAeuT,GACf,YAAahE,EACb,UAAWD,EACX,cAAe2D,GACf,cAAeE,GACf,gBAAiBC,GACjB,kBAAmBC,GACnB,eAAA3K,CAAA,CACF,CACF,CAAA,CAAA,CAEJ,CAEA,MAAMgL,WAAsBtV,EAAM,SAAU,CAC1C,YAAYuV,EAAO,CACjB,MAAMA,CAAK,EACN,KAAA,MAAQ,CAAE,SAAU,EAAM,CACjC,CACA,OAAO,0BAA2B,CACzB,MAAA,CAAE,SAAU,GACrB,CACA,kBAAkBxV,EAAOkE,EAAM,CAC7B,QAAQ,MAAM,uCAAwClE,EAAOkE,GAAA,YAAAA,EAAM,cAAc,CACnF,CACA,QAAS,CACP,OAAO,KAAK,MAAM,SAAW,KAAK,MAAM,SAAW,KAAK,MAAM,QAChE,CACF,CAEA,SAAwBuR,GAA8BD,EAAO,CAEzD,OAAArV,MAACoV,IAAc,SACbpV,EAAAA,IAAC,OAAI,MAAO,CAAE,QAAS,GAAI,MAAO,uBAAwB,SAAU,IAAM,SAE1E,yBAAA,CAAA,EAEA,eAACwQ,GAAwB,CAAA,GAAG6E,CAAO,CAAA,CACrC,CAAA,CAEJ,CC1gBwB,SAAAE,GAAwB,CAAE,QAAAC,GAAW,CAC3D,KAAM,CAACpR,EAAYqR,CAAa,EAAIhL,WAAS,EAAK,EAE5CiL,EAAe,CACnB,KAAM,iCACN,YACE,kGACF,aAAc,+BACd,YAAa,IACb,WAAY,IACZ,aAAc,CAAA,EAGhB,OAAIF,IAAY,YAEZzV,EAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,WAAY,4BACZ,OAAQ,mCACR,aAAc,OACd,SAAU,SACV,UAAW,kCACb,EAGA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,KAAM,EACN,IAAK,EACL,OAAQ,EACR,MAAO,MACP,WAAY,UACZ,QAAS,EACX,CAAA,CACF,EAGAD,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,qBACX,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAI,CAAA,MAAO,CAAE,aAAc,OAC1B,SAAAA,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,GACd,EAEC,SAAa0V,EAAA,IAAA,CAAA,EAElB,EACA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,IACZ,aAAc,KAChB,EAEC,SAAa0V,EAAA,WAAA,CAChB,EACA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,0BACZ,aAAc,KAChB,EAEC,SAAa0V,EAAA,YAAA,CAChB,EACA3V,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,OACL,SAAU,SACV,aAAc,MAChB,EAEA,SAAA,CAAAC,MAAC,QAAK,MAAO,CAAE,MAAO,6BAA+B,SAAI,OAAA,EACzDA,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,2BAA4B,EACjD,SAAa0V,EAAA,YAAY,QAAQ,CAAC,CACrC,CAAA,QACC,OAAK,CAAA,MAAO,CAAE,MAAO,0BAA4B,SAAC,IAAA,QAClD,OAAK,CAAA,MAAO,CAAE,MAAO,6BAA+B,SAAI,OAAA,EACzD1V,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,2BAA4B,EACjD,SAAa0V,EAAA,WAAW,QAAQ,CAAC,CACpC,CAAA,QACC,OAAK,CAAA,MAAO,CAAE,MAAO,0BAA4B,SAAC,IAAA,SAClD,OAAK,CAAA,MAAO,CAAE,MAAO,wBACnB,EAAA,SAAA,CAAaA,EAAA,aAAa,eAAA,EAC7B,CAAA,CAAA,CACF,EAGC,CAACtR,GACApE,EAAA,IAAC,SAAA,CACC,QAAS,IAAMyV,EAAc,EAAI,EACjC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,OACZ,OAAQ,OACR,QAAS,EACT,OAAQ,UACR,eAAgB,YAChB,oBAAqB,uBACvB,EACA,aAAepR,GAAM,CACjBA,EAAA,cAAc,MAAM,MAAQ,yBAC5BA,EAAA,cAAc,MAAM,oBACpB,uBACJ,EACA,aAAeA,GAAM,CACjBA,EAAA,cAAc,MAAM,MAAQ,yBAC5BA,EAAA,cAAc,MAAM,oBACpB,uBACJ,EACD,SAAA,gCAAA,CAED,CAAA,CAAA,CAEJ,EAGCD,GACCrE,EAAA,KAAC,MAAA,CACC,MAAO,CACL,UAAW,mCACX,WAAY,4BACZ,QAAS,qBACX,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,cAAe,SACf,cAAe,YACf,MAAO,yBACP,aAAc,KAChB,EACD,SAAA,2BAAA,CAED,EACAA,EAAAA,IAAC,OAAI,MAAO,CAAE,SAAU,OAAQ,MAAO,wBAAyB,EAAG,SAEnE,kCAAA,CAAA,EACAA,EAAA,IAAC,SAAA,CACC,QAAS,IAAMyV,EAAc,EAAK,EAClC,MAAO,CACL,UAAW,OACX,SAAU,OACV,MAAO,yBACP,WAAY,OACZ,OAAQ,OACR,QAAS,EACT,OAAQ,UACR,eAAgB,YAChB,oBAAqB,uBACvB,EACA,aAAepR,GAAM,CACjBA,EAAA,cAAc,MAAM,MAAQ,yBAC5BA,EAAA,cAAc,MAAM,oBACpB,uBACJ,EACA,aAAeA,GAAM,CACjBA,EAAA,cAAc,MAAM,MAAQ,yBAC5BA,EAAA,cAAc,MAAM,oBACpB,uBACJ,EACD,SAAA,mBAAA,CAED,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,EAMJmR,IAAY,mBAEZzV,EAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,WAAY,4BACZ,OAAQ,mCACR,aAAc,OACd,SAAU,SACV,UAAW,kCACb,EAGA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,KAAM,EACN,IAAK,EACL,OAAQ,EACR,MAAO,MACP,WAAY,UACZ,QAAS,EACX,CAAA,CACF,EAGAA,EAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMyV,EAAc,CAACrR,CAAU,EACxC,MAAO,CACL,MAAO,OACP,QAAS,sBACT,WAAY,cACZ,OAAQ,OACR,OAAQ,UACR,UAAW,OACX,WAAY,uBACd,EACA,aAAeC,GAAM,CACjBA,EAAA,cAAc,MAAM,WAAa,2BACrC,EACA,aAAeA,GAAM,CACjBA,EAAA,cAAc,MAAM,WAAa,aACrC,EAEA,SAAAtE,EAAAA,KAAC,MAAI,CAAA,MAAO,CAAE,QAAS,OAAQ,WAAY,aAAc,IAAK,MAAA,EAC5D,SAAA,CAAAA,OAAC,OAAI,MAAO,CAAE,KAAM,EAAG,SAAU,CAC/B,EAAA,SAAA,CAAAC,EAAA,IAAC,MAAI,CAAA,MAAO,CAAE,aAAc,OAC1B,SAAAA,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,GACd,EAEC,SAAa0V,EAAA,IAAA,CAAA,EAElB,EACA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,IACZ,aAAc,KAChB,EAEC,SAAa0V,EAAA,WAAA,CAChB,EACA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,0BACZ,aAAc,KAChB,EAEC,SAAa0V,EAAA,YAAA,CAChB,EACA3V,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,OACL,SAAU,QACZ,EAEA,SAAA,CAAAC,MAAC,QAAK,MAAO,CAAE,MAAO,6BAA+B,SAAI,OAAA,EACzDA,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,2BAA4B,EACjD,SAAa0V,EAAA,YAAY,QAAQ,CAAC,CACrC,CAAA,QACC,OAAK,CAAA,MAAO,CAAE,MAAO,0BAA4B,SAAC,IAAA,QAClD,OAAK,CAAA,MAAO,CAAE,MAAO,6BAA+B,SAAI,OAAA,EACzD1V,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,2BAA4B,EACjD,SAAa0V,EAAA,WAAW,QAAQ,CAAC,CACpC,CAAA,QACC,OAAK,CAAA,MAAO,CAAE,MAAO,0BAA4B,SAAC,IAAA,SAClD,OAAK,CAAA,MAAO,CAAE,MAAO,wBACnB,EAAA,SAAA,CAAaA,EAAA,aAAa,eAAA,EAC7B,CAAA,CAAA,CACF,CAAA,EACF,EAGA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,MACZ,MAAO,yBACP,WAAY,EACZ,WAAY,qBACd,EAEA,SAAAA,EAAA,IAACsE,EAAA,YAAA,CACC,KAAM,GACN,MAAO,CACL,UAAWF,EAAa,iBAAmB,eAC3C,WAAY,qBACd,CAAA,CACF,CAAA,CACF,CAAA,EACF,CAAA,CACF,EAGCA,GACCrE,EAAA,KAAC,MAAA,CACC,MAAO,CACL,UAAW,mCACX,WAAY,4BACZ,QAAS,qBACX,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,cAAe,SACf,cAAe,YACf,MAAO,yBACP,aAAc,KAChB,EACD,SAAA,2BAAA,CAED,EACAA,EAAAA,IAAC,OAAI,MAAO,CAAE,SAAU,OAAQ,MAAO,wBAAyB,EAAG,SAEnE,kCAAA,CAAA,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,EAQND,EAAA,KAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,WAAY,4BACZ,OAAQ,mCACR,aAAc,OACd,SAAU,SACV,UAAW,kCACb,EAGA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,KAAM,EACN,IAAK,EACL,OAAQ,EACR,MAAO,MACP,WAAY,UACZ,QAAS,EACX,CAAA,CACF,EAGAD,EAAA,KAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM0V,EAAc,CAACrR,CAAU,EACxC,MAAO,CACL,MAAO,OACP,QAAS,sBACT,WAAY,cACZ,OAAQ,OACR,OAAQ,UACR,UAAW,OACX,QAAS,OACT,WAAY,aACZ,IAAK,OACL,WAAY,uBACd,EACA,aAAeC,GAAM,CACjBA,EAAA,cAAc,MAAM,WAAa,2BACrC,EACA,aAAeA,GAAM,CACjBA,EAAA,cAAc,MAAM,WAAa,aACrC,EAGA,SAAA,CAAArE,EAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,MACZ,MAAO,yBACP,WAAY,CACd,EAEC,SAAAoE,QACEE,EAAY,YAAA,CAAA,KAAM,GAAI,EAEvBtE,EAAA,IAACgQ,EAAa,aAAA,CAAA,KAAM,EAAI,CAAA,CAAA,CAE5B,EACAjQ,OAAC,OAAI,MAAO,CAAE,KAAM,EAAG,SAAU,CAC/B,EAAA,SAAA,CAAAC,EAAA,IAAC,MAAI,CAAA,MAAO,CAAE,aAAc,OAC1B,SAAAA,EAAA,IAAC,OAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,MAAO,yBACP,WAAY,GACd,EAEC,SAAa0V,EAAA,IAAA,CAAA,EAElB,EACA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,IACZ,aAAc,KAChB,EAEC,SAAa0V,EAAA,WAAA,CAChB,EACA1V,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,MAAO,yBACP,WAAY,0BACZ,aAAc,KAChB,EAEC,SAAa0V,EAAA,YAAA,CAChB,EACA3V,EAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,OACL,SAAU,QACZ,EAEA,SAAA,CAAAC,MAAC,QAAK,MAAO,CAAE,MAAO,6BAA+B,SAAI,OAAA,EACzDA,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,2BAA4B,EACjD,SAAa0V,EAAA,YAAY,QAAQ,CAAC,CACrC,CAAA,QACC,OAAK,CAAA,MAAO,CAAE,MAAO,0BAA4B,SAAC,IAAA,QAClD,OAAK,CAAA,MAAO,CAAE,MAAO,6BAA+B,SAAI,OAAA,EACzD1V,EAAAA,IAAC,SAAO,CAAA,MAAO,CAAE,MAAO,2BAA4B,EACjD,SAAa0V,EAAA,WAAW,QAAQ,CAAC,CACpC,CAAA,QACC,OAAK,CAAA,MAAO,CAAE,MAAO,0BAA4B,SAAC,IAAA,SAClD,OAAK,CAAA,MAAO,CAAE,MAAO,wBACnB,EAAA,SAAA,CAAaA,EAAA,aAAa,eAAA,EAC7B,CAAA,CAAA,CACF,CAAA,EACF,CAAA,CAAA,CACF,EAGCtR,GACCrE,EAAA,KAAC,MAAA,CACC,MAAO,CACL,UAAW,mCACX,WAAY,4BACZ,QAAS,qBACX,EAEA,SAAA,CAAAC,EAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,OACV,WAAY,IACZ,cAAe,SACf,cAAe,YACf,MAAO,yBACP,aAAc,KAChB,EACD,SAAA,2BAAA,CAED,EACAA,EAAAA,IAAC,OAAI,MAAO,CAAE,SAAU,OAAQ,MAAO,wBAAyB,EAAG,SAEnE,kCAAA,CAAA,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CAIR"}
1
+ {"version":3,"file":"interactionDetails.cjs.js","sources":["../../src/components/pages/interactionDetails/CoachingSynthesisCard.jsx","../../src/components/pages/interactionDetails/InteractionContext.jsx","../../src/components/pages/interactionDetails/InteractionScores.jsx","../../src/components/pages/interactionDetails/InteractionSignals.jsx","../../src/components/pages/interactionDetails/InteractionGuidance.jsx","../../src/components/pages/interactionDetails/InteractionNBA.jsx","../../src/components/pages/interactionDetails/InteractionRecording.jsx","../../src/components/pages/interactionDetails/InteractionTranscript.jsx","../../src/components/common/MessageThread.jsx","../../src/components/pages/interactionDetails/InteractionDetailPanel.jsx","../../src/components/pages/interactionDetails/ExpandPatternComparison.jsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { TrendingUp, Lightbulb, Building, MessageSquareQuote } from \"lucide-react\";\n\n/**\n * CoachingSynthesisCard — displays LLM-generated coaching synthesis from Compass.\n *\n * Props:\n * - data object Coaching synthesis response (see shape below)\n * - loading boolean Show shimmer loading state\n * - error string Error message to display\n *\n * Data shape (from compass/summaries/coaching.py):\n * - one_liner string One-sentence summary\n * - context string Situational factors\n * - strengths Array<{ text: string, quote?: string }>\n * - improvements Array<{ text: string, quote?: string }>\n * - organizational Array<{ text: string, quote?: string }> (alias: organizational_insights)\n * - overall string \"effective\" | \"strong\" | \"needs_improvement\" | \"mixed\"\n */\n\nconst STYLE_ID = \"coaching-synthesis-keyframes\";\n\nfunction ensureKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n @keyframes coaching-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n @keyframes coaching-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n }\n `;\n document.head.appendChild(style);\n}\n\nexport default function CoachingSynthesisCard({ data, loading, error }) {\n React.useEffect(() => { ensureKeyframes(); }, []);\n\n // Loading state\n if (loading) {\n return (\n <div style={{\n padding: \"20px 0\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n }}>\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n }}>\n <div style={{\n width: 6,\n height: 6,\n borderRadius: \"50%\",\n background: \"var(--rail-tone)\",\n animation: \"coaching-pulse 1.5s ease-in-out infinite\",\n }} />\n <span style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--rail-tone)\",\n fontFamily: \"var(--font-sans)\",\n fontWeight: 500,\n }}>\n Compass is synthesizing coaching insights…\n </span>\n </div>\n {/* Shimmer lines */}\n {[180, 260, 220].map((w, i) => (\n <div\n key={i}\n style={{\n height: 10,\n width: w,\n maxWidth: \"100%\",\n borderRadius: 4,\n background: \"linear-gradient(90deg, var(--hover-warm-subtle) 25%, var(--hover-warm) 50%, var(--hover-warm-subtle) 75%)\",\n backgroundSize: \"200% 100%\",\n animation: `coaching-shimmer 1.8s ease-in-out infinite`,\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div style={{\n padding: \"16px 0\",\n fontSize: \"var(--text-base)\",\n color: \"var(--text-faint)\",\n fontFamily: \"var(--font-sans)\",\n }}>\n Unable to generate coaching summary.\n </div>\n );\n }\n\n // No data\n if (!data) return null;\n\n const strengths = data.strengths || [];\n const improvements = data.improvements || [];\n const organizational = data.organizational || data.organizational_insights || [];\n const oneLiner = typeof data.one_liner === \"string\" ? data.one_liner : data.one_liner?.text || \"\";\n const context = typeof data.context === \"string\" ? data.context : data.context?.text || \"\";\n\n return (\n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 14,\n fontFamily: \"var(--font-sans)\",\n }}>\n {/* One-liner */}\n {oneLiner && (\n <div style={{\n fontSize: \"var(--text-lg)\",\n fontWeight: 600,\n color: \"var(--text-strong)\",\n lineHeight: 1.4,\n }}>\n {oneLiner}\n </div>\n )}\n\n {/* Context */}\n {context && (\n <div style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-muted)\",\n lineHeight: 1.45,\n }}>\n {context}\n </div>\n )}\n\n {/* Strengths */}\n {strengths.length > 0 && (\n <CoachingSection\n icon={<TrendingUp size={13} />}\n label=\"Strengths\"\n color=\"var(--rail-discovery)\"\n items={strengths}\n />\n )}\n\n {/* Improvements */}\n {improvements.length > 0 && (\n <CoachingSection\n icon={<Lightbulb size={13} />}\n label=\"Improvements\"\n color=\"var(--rail-compliance)\"\n items={improvements}\n />\n )}\n\n {/* Organizational */}\n {organizational.length > 0 && (\n <CoachingSection\n icon={<Building size={13} />}\n label=\"Organizational\"\n color=\"var(--rail-outcome)\"\n items={organizational}\n />\n )}\n\n {/* Overall rating */}\n {data.overall && (\n <div style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-faint)\",\n fontStyle: \"italic\",\n marginTop: 2,\n }}>\n Overall: {data.overall.replace(/_/g, \" \")}\n </div>\n )}\n </div>\n );\n}\n\nfunction CoachingSection({ icon, label, color, items }) {\n return (\n <div>\n {/* Section header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 5,\n marginBottom: 6,\n color,\n fontSize: \"var(--text-base)\",\n fontWeight: 650,\n letterSpacing: \"0.04em\",\n }}>\n {icon}\n {label}\n </div>\n\n {/* Items */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {items.map((item, i) => {\n const text = typeof item === \"string\" ? item : item?.text || \"\";\n const quote = typeof item === \"object\" ? item?.quote : null;\n\n return (\n <div key={i} style={{ paddingLeft: 14 }}>\n <div style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-base)\",\n lineHeight: 1.4,\n }}>\n • {text}\n </div>\n {quote && (\n <div style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 4,\n marginTop: 3,\n paddingLeft: 8,\n }}>\n <MessageSquareQuote\n size={10}\n style={{\n color: \"var(--text-faint)\",\n flexShrink: 0,\n marginTop: 2,\n }}\n />\n <span style={{\n fontSize: \"var(--text-base)\",\n color: \"var(--text-muted)\",\n fontStyle: \"italic\",\n lineHeight: 1.35,\n }}>\n \"{quote}\"\n </span>\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport CardBase from '../../primitives/Card.jsx';\n\nfunction fmtDur(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nexport default function InteractionContext({ title, meta, callPurpose, classification, dimensions }) {\n const cp = callPurpose || {};\n const cls = classification || {};\n\n return (\n <CardBase variant=\"elevated\" padding=\"sm\">\n <div style={{ fontSize: 'var(--text-md)', fontWeight: 550, color: 'var(--text-strong)', lineHeight: 1.375, marginBottom: 6 }}>\n {title}\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '4px 12px', fontSize: 11, color: 'var(--text-muted)' }}>\n {meta.evaluated_dt && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Date</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{new Date(meta.evaluated_dt).toLocaleString()}</div></div>}\n {meta.duration_seconds != null && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Duration</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{fmtDur(meta.duration_seconds)}</div></div>}\n {meta.message_count && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Messages</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{meta.message_count}</div></div>}\n {cp.interaction_direction && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Direction</span><div style={{ color: 'var(--text-base)' }}>{cp.interaction_direction}</div></div>}\n {cp.interaction_driver && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Driver</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{cp.interaction_driver}</div></div>}\n {cp.customer_intent && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Intent</span><div style={{ color: 'var(--text-base)' }}>{cp.customer_intent}</div></div>}\n {cls.interaction_paradigm && <div><span style={{ fontSize: 11, color: 'var(--text-faint)' }}>Paradigm</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{cls.interaction_paradigm}</div></div>}\n {dimensions.map((dim, i) => (\n <div key={i}><span style={{ fontSize: 10, color: 'var(--text-faint)' }}>{dim.label || dim.key}</span><div style={{ fontSize: 12, color: 'var(--text-base)' }}>{dim.value}</div></div>\n ))}\n </div>\n {meta.session_id && (\n <div style={{ fontSize: 10, color: 'var(--text-faint)', fontFamily: 'var(--font-mono)', marginTop: 4, userSelect: 'all' }}>\n {meta.session_id}\n </div>\n )}\n </CardBase>\n );\n}","import React from 'react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\n\nexport default function InteractionScores({ scores }) {\n if (!scores?.length) return null;\n\n return (\n <DetailCard title=\"Scores\">\n <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>\n {scores.map((s, i) => {\n const val = s.value != null ? Math.round(s.value) : null;\n return (\n <div key={i} style={{ textAlign: 'center', minWidth: 48 }}>\n <div style={{ fontSize: 20, fontWeight: 700, color: 'var(--text-ink)' }}>{val ?? '—'}</div>\n <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)', marginTop: 2 }}>{s.label || s.key}</div>\n </div>\n );\n })}\n </div>\n </DetailCard>\n );\n}","import React, { useMemo } from 'react';\nimport { Target, CheckCircle, Lightbulb, Scale, Zap, MessageSquare, FileText, ChevronDown } from 'lucide-react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport SectionLabel from '../../primitives/SectionLabel.jsx';\nimport EvidenceItem from '../../common/EvidenceItem.jsx';\n\nconst GROUP_LABELS = {\n outcome: { label: 'Outcome', icon: <Target size={12} />, color: 'var(--rail-outcome)' },\n process: { label: 'Process & Protocol', icon: <FileText size={12} />, color: 'var(--rail-discovery)' },\n compliance: { label: 'Compliance', icon: <Scale size={12} />, color: 'var(--rail-compliance)' },\n customer_friction: { label: 'Customer Friction', icon: <Zap size={12} />, color: 'var(--rail-coral)' },\n experience: { label: 'Experience', icon: <MessageSquare size={12} />, color: 'var(--rail-teal)' },\n};\n\nconst KIND_COLORS = {\n risk: { icon: <Zap size={10} />, color: 'var(--rail-signal-churn)' },\n opportunity: { icon: <Lightbulb size={10} />, color: 'var(--state-unknown)' },\n excellence: { icon: <CheckCircle size={10} />, color: 'var(--rail-teal)' },\n};\n\nexport default function InteractionSignals({\n signals,\n expandedSignals,\n toggleSignal,\n playEvidence,\n timelinePlaying,\n currentTimeSeconds,\n highlightTurns,\n borderRadius\n}) {\n if (!signals?.signals?.length) return null;\n\n const grouped = useMemo(() => {\n const result = {};\n for (const s of signals.signals) {\n const g = s.group || 'experience';\n if (!result[g]) result[g] = [];\n result[g].push(s);\n }\n return result;\n }, [signals]);\n\n return (\n <DetailCard title={`Signals (${signals.present_count} present / ${signals.total_signals_evaluated} evaluated)`} borderRadius={borderRadius}>\n {Object.entries(grouped).map(([groupKey, groupSignals]) => {\n const info = GROUP_LABELS[groupKey] || GROUP_LABELS.experience;\n\n return (\n <div key={groupKey} style={{ marginBottom: 10 }}>\n <SectionLabel style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {info.icon}\n <span>{info.label}</span>\n </SectionLabel>\n\n <div style={{ marginTop: 4, display: 'flex', flexDirection: 'column', gap: 6 }}>\n {groupSignals.map((s, i) => {\n const name = s.display_name || s.key || '';\n const delta = s.baseline?.delta;\n const hasObs = s.observations?.length > 0;\n const isExpanded = expandedSignals.has(s.key);\n \n // Map signal group to Tag variant\n const getVariant = (group) => {\n switch (group) {\n case 'outcome': return 'phase';\n case 'process': return 'tool';\n case 'compliance': return 'policy';\n case 'customer_friction': return 'default';\n case 'experience': return 'global';\n default: return 'default';\n }\n };\n \n return (\n <div\n key={i}\n id={`signal-${s.key}`}\n style={{\n border: '1px solid var(--border, rgba(52, 58, 64, 0.12))',\n borderRadius: 'var(--radius-md, 8px)',\n background: 'var(--paper, rgba(255, 255, 255, 0.98))',\n overflow: 'hidden',\n }}\n >\n <button\n type=\"button\"\n onClick={(e) => {\n if (hasObs) {\n toggleSignal(s.key);\n e.currentTarget.blur();\n }\n }}\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '6px 10px',\n background: 'transparent',\n borderTop: '1px solid transparent',\n borderRight: '1px solid transparent',\n borderLeft: '1px solid transparent',\n borderBottom: '1px solid var(--border, rgba(52, 58, 64, 0.08))',\n cursor: hasObs ? 'pointer' : 'default',\n }}\n title={[\n s.confidence != null ? `Confidence: ${Math.round(s.confidence * 100)}%` : '',\n delta != null ? `Δ baseline: ${delta > 0 ? '+' : ''}${(delta * 100).toFixed(1)}%` : '',\n ].filter(Boolean).join(' · ')}\n >\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n whiteSpace: 'nowrap',\n }}\n >\n {KIND_COLORS[s.kind]?.icon}\n <span>{name}</span>\n {hasObs && (\n <span\n style={{\n marginLeft: 4,\n fontSize: 10,\n opacity: 0.6,\n }}\n >\n ({s.observations.length})\n </span>\n )}\n </span>\n {hasObs && (\n <ChevronDown\n size={14}\n style={{\n color: 'var(--text-muted)',\n flexShrink: 0,\n transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 0.16s ease',\n }}\n />\n )}\n </button>\n\n {isExpanded && s.observations && (\n <div style={{ width: '100%', margin: '0 0 6px' }}>\n {s.observations.map((obs, oi) => (\n <div key={oi} style={{ marginBottom: 6 }}>\n <div\n style={{\n display: 'flex',\n borderRadius: 'var(--radius-sm, 8px)',\n background: 'var(--paper, #fff)',\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n width: 3,\n background: info.color,\n }}\n />\n <div\n style={{\n flex: 1,\n fontSize: 'var(--text-sm)',\n color: 'var(--text-muted)',\n padding: '8px 12px',\n }}\n >\n <div\n style={{\n fontWeight: 600,\n color: 'var(--text-base)',\n marginBottom: 3,\n fontSize: 'var(--text-base)',\n }}\n >\n {obs.key || ''}\n </div>\n <div style={{ marginBottom: 6, lineHeight: 1.4 }}>\n {obs.reason || obs.explanation || ''}\n </div>\n {obs.evidence?.map((ev, ei) => {\n const startMs = ev.start_ms;\n const endMs = ev.end_ms;\n\n let isPlayingSegment = false;\n if (startMs != null && timelinePlaying) {\n const startSec = startMs / 1000;\n const endSec =\n endMs != null ? endMs / 1000 : startSec + 1;\n const cs = currentTimeSeconds ?? 0;\n isPlayingSegment =\n cs >= startSec && cs <= endSec + 0.25;\n }\n\n return (\n <EvidenceItem\n key={ei}\n ev={ev}\n isPlaying={isPlayingSegment}\n railColor={info.color}\n onPlay={(startMs, endMs) =>\n playEvidence?.(startMs, endMs, ev.turn_ids)\n }\n onHighlight={highlightTurns}\n />\n );\n })}\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </DetailCard>\n );\n}","import React from 'react';\nimport { CheckCircle, Lightbulb, Zap, CornerDownRight } from 'lucide-react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport EvidenceItem from '../../common/EvidenceItem.jsx';\n\nconst KIND_COLORS = {\n risk: { icon: <Zap size={10} />, color: 'var(--rail-signal-churn)' },\n opportunity: { icon: <Lightbulb size={10} />, color: 'var(--state-unknown)' },\n excellence: { icon: <CheckCircle size={10} />, color: 'var(--rail-teal)' },\n};\n\nexport default function InteractionGuidance({\n guidance,\n playEvidence,\n timelinePlaying,\n currentTimeSeconds,\n highlightTurns,\n borderRadius\n}) {\n if (!guidance?.items?.length) return null;\n\n return (\n <DetailCard title={`Guidance (${guidance.total_items} items)`} borderRadius={borderRadius}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {guidance.items.map((g, i) => {\n const ki = KIND_COLORS[g.guidance_kind] || KIND_COLORS.excellence;\n const ownerBadge = g.owner === 'organization'\n ? { bg: 'color-mix(in srgb, var(--rail-discovery) 15%, transparent)', color: 'var(--rail-discovery)', text: 'ORG' }\n : g.owner === 'shared'\n ? { bg: 'color-mix(in srgb, var(--state-unknown) 15%, transparent)', color: 'var(--state-unknown)', text: 'SHARED' }\n : { bg: 'color-mix(in srgb, var(--rail-teal) 10%, transparent)', color: 'var(--rail-teal)', text: 'AGENT' };\n return (\n <div key={i} style={{\n padding: '10px 12px', borderRadius: 'var(--radius)',\n background: 'var(--paper)', borderLeft: `3px solid ${ki.color}`,\n }}>\n <div style={{ fontSize: 'var(--text-base)', color: 'var(--text-strong)', display: 'flex', alignItems: 'center', gap: 5, fontWeight: 550 }}>\n {ki.icon} {g.title || ''}\n <span style={{\n fontSize: 9, padding: '1px 6px', borderRadius: 8, marginLeft: 4,\n background: ownerBadge.bg, color: ownerBadge.color, fontWeight: 600,\n }}>\n {ownerBadge.text}\n </span>\n </div>\n {g.detail && <div style={{ fontSize: 'var(--text-sm)', color: 'var(--text-muted)', marginTop: 4, lineHeight: 1.4 }}>{g.detail}</div>}\n {/* Signal refs with evidence */}\n {g.signal_refs?.map((sr, si) => (\n <div key={si} style={{ marginTop: 6 }}>\n <div\n style={{\n fontSize: 10,\n color: 'var(--text-muted)',\n fontWeight: 600,\n marginBottom: 3,\n display: 'flex',\n alignItems: 'center',\n gap: 3,\n }}\n >\n <CornerDownRight size={10} /> {sr.display_name || sr.signal_key}\n {sr.confidence != null && (\n <span style={{ fontWeight: 400, opacity: 0.7 }}>\n {' '}\n ({Math.round(sr.confidence * 100)}%)\n </span>\n )}\n </div>\n {sr.evidence?.map((ev, ei) => {\n const startMs = ev.start_ms;\n const endMs = ev.end_ms;\n\n let isPlayingSegment = false;\n if (startMs != null && timelinePlaying) {\n const startSec = startMs / 1000;\n const endSec =\n endMs != null ? endMs / 1000 : startSec + 1;\n const cs = currentTimeSeconds ?? 0;\n isPlayingSegment =\n cs >= startSec && cs <= endSec + 0.25;\n }\n\n return (\n <EvidenceItem\n key={ei}\n ev={ev}\n isPlaying={isPlayingSegment}\n onPlay={(sMs, eMs) =>\n playEvidence?.(sMs, eMs, ev.turn_ids)\n }\n onHighlight={highlightTurns}\n />\n );\n })}\n </div>\n ))}\n </div>\n );\n })}\n </div>\n </DetailCard>\n );\n}","import React from 'react';\nimport { Target } from 'lucide-react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\n\nexport default function InteractionNBA({ nba }) {\n const items = nba?.recommendations || nba?.actions || [];\n if (!items.length) return null;\n\n return (\n <DetailCard title=\"Next Best Actions\">\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {items.slice(0, 8).map((r, i) => (\n <div key={i} style={{ fontSize: 11, color: 'var(--text-muted)', display: 'flex', alignItems: 'center', gap: 4 }}>\n <Target size={12} /> <strong style={{ color: 'var(--text-base)' }}>{r.action || r.title || ''}</strong>\n {r.rationale && ` — ${r.rationale}`}\n </div>\n ))}\n </div>\n </DetailCard>\n );\n}","import React from 'react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport Timeline from '../../media/Timeline.jsx';\n\nexport default function InteractionRecording({ \n audioUrl, \n timelineSegments, \n durationSeconds, \n currentTimeSeconds,\n timelinePlaying,\n playbackRate,\n onSeek,\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n audioRef\n}) {\n if (!audioUrl) return null;\n\n return (\n <DetailCard title=\"Recording\">\n <Timeline\n segments={timelineSegments}\n durationSeconds={durationSeconds || 0}\n currentTimeSeconds={currentTimeSeconds}\n onSeek={onSeek}\n showControls={true}\n hasRecording={true}\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n onTogglePlay={onTogglePlay}\n onSeekBack={onSeekBack}\n onSeekForward={onSeekForward}\n onSetPlaybackRate={onSetPlaybackRate}\n />\n {/* Hidden audio element for actual playback */}\n <audio ref={audioRef} preload=\"none\" style={{ display: 'none' }}>\n <source src={audioUrl} type=\"audio/mpeg\" />\n </audio>\n </DetailCard>\n );\n}","import React from 'react';\nimport TranscriptCard from '../../media/TranscriptCard.jsx';\n\nexport default function InteractionTranscript({ \n transcript, \n audioUrl,\n highlightedTurns,\n activeTurnIndex,\n timelinePlaying,\n turnObservations,\n setExpandedSignals,\n onTurnPlayPause,\n}) {\n if (!transcript?.messages?.length) return null;\n\n // Helper function to format time from ms to \"MM:SS–MM:SS\"\n const formatTimeRange = (startMs, endMs) => {\n if (startMs == null) return undefined;\n const formatTime = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n const start = formatTime(startMs);\n const end = endMs != null ? formatTime(endMs) : start;\n return `${start}–${end}`;\n };\n\n const turns = transcript.messages.map((m, i) => ({\n actor: m.actor === 'agent' ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer'),\n actorType: m.actor === 'agent' ? 'agent' : 'customer',\n text: m.text || '',\n timeRange: formatTimeRange(m.start ?? m.start_ms, m.end ?? m.end_ms),\n isHighlighted: highlightedTurns.has(i),\n highlightColor: (timelinePlaying && activeTurnIndex === i) \n ? (m.actor === 'agent' ? 'var(--rail-outcome)' : 'var(--rail-discovery)')\n : undefined,\n observations: (turnObservations[i] || []).map(obs => ({\n ...obs,\n onClick: () => {\n // Expand the parent signal and scroll to it\n setExpandedSignals(prev => new Set([...prev, obs.signalKey]));\n setTimeout(() => {\n const el = document.getElementById(`signal-${obs.signalKey}`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 100);\n },\n })),\n }));\n\n return (\n <div id=\"transcript-container\">\n <TranscriptCard\n turns={turns}\n audioUrl={audioUrl}\n activeTurnIndex={activeTurnIndex}\n autoScrollActiveTurn={timelinePlaying}\n isExternalPlaying={timelinePlaying}\n onTurnPlayPause={onTurnPlayPause}\n />\n </div>\n );\n}","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Send, Clock, ChevronRight } from \"lucide-react\";\n\nconst messageActionButtonStyle = {\n padding: 0,\n border: \"none\",\n background: \"transparent\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.65)\",\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n};\n\n// Map author roles to consistent avatar background colors so that\n// supervisors, admins, and agents are visually distinct.\nconst roleColorMap = (role) => {\n if (!role) return null;\n const normalized = String(role).toLowerCase();\n if (normalized === \"supervisor\") return \"var(--rail-compliance)\";\n if (normalized === \"admin\" || normalized === \"administrator\")\n return \"var(--rail-discovery)\";\n if (normalized === \"agent\") return \"var(--rail-outcome)\";\n return null;\n};\n\n// Safely extract an array of messages/comments from a thread or payload,\n// tolerating different backend shapes (messages, comments, thread_messages, items, etc.).\nconst extractMessagesArray = (node) => {\n if (!node) return [];\n\n const directCandidates = [\n node.messages,\n node.comments,\n node.thread_messages,\n node.items,\n node.children,\n ];\n\n for (const candidate of directCandidates) {\n if (Array.isArray(candidate) && candidate.length) {\n return candidate;\n }\n }\n\n // Handle wrapped shapes like { messages: { data: [...] } }\n if (node.messages && Array.isArray(node.messages.data)) {\n return node.messages.data;\n }\n\n return [];\n};\n\n// Flatten a nested messages array (with optional replies) into a linear list\n// while preserving parent/child relationships via parentId and keeping\n// replies immediately after their parent.\nconst flattenMessages = (rawMessages, parentId = null, startIndex = 0) => {\n const out = [];\n\n (rawMessages || []).forEach((m, index) => {\n const author = m.author || {};\n const authorName = author.name || m.author_name || \"Unknown\";\n const initials =\n author.initials ||\n (authorName\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()) ||\n \"U\";\n const role = author.role || m.author_role;\n const roleColor = roleColorMap(role);\n const color = author.color || m.author_color || roleColor || \"#6B7C93\";\n\n const id = m.id || `msg-${startIndex + index}`;\n\n const baseMessage = {\n id,\n author: {\n name: authorName,\n initials,\n color,\n role,\n },\n content: m.content || m.text || \"\",\n timestamp: m.timestamp || m.created_at_display || m.created_at || \"\",\n type: m.type || \"comment\",\n isEdited: m.isEdited || m.is_edited || m.edited || false,\n references: m.references || [],\n parentId: m.parentId || m.parent_message_id || parentId || null,\n };\n\n out.push(baseMessage);\n\n if (Array.isArray(m.replies) && m.replies.length > 0) {\n out.push(\n ...flattenMessages(m.replies, id, startIndex + out.length)\n );\n }\n });\n\n return out;\n};\n\nconst formatTimestamp = (value) => {\n if (!value) return \"\";\n // If it's already a human-friendly string, just return as-is\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) return value;\n\n try {\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return value;\n\n const now = new Date();\n const sameDay =\n d.getFullYear() === now.getFullYear() &&\n d.getMonth() === now.getMonth() &&\n d.getDate() === now.getDate();\n\n const yesterday = new Date(now);\n yesterday.setDate(yesterday.getDate() - 1);\n const isYesterday =\n d.getFullYear() === yesterday.getFullYear() &&\n d.getMonth() === yesterday.getMonth() &&\n d.getDate() === yesterday.getDate();\n\n const timeStr = d.toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n });\n\n if (sameDay) {\n return `Today at ${timeStr}`;\n }\n\n if (isYesterday) {\n return `Yesterday at ${timeStr}`;\n }\n\n // Within last 7 days: show weekday name\n const diffMs = now.getTime() - d.getTime();\n const diffDays = diffMs / (1000 * 60 * 60 * 24);\n if (diffDays < 7 && diffDays > 0) {\n const weekday = d.toLocaleDateString(undefined, { weekday: \"long\" });\n return `${weekday} at ${timeStr}`;\n }\n\n // Older: fallback to short date\n const dateStr = d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: d.getFullYear() !== now.getFullYear() ? \"numeric\" : undefined,\n });\n\n return `${dateStr} at ${timeStr}`;\n } catch {\n return value;\n }\n};\n\n\n\n/**\n * MessageThread (common)\n *\n * Lightweight, UI-only message thread component for session discussion.\n * - Controlled via `messages` + `onSendMessage` (and optional reply/edit/delete callbacks)\n * - onSendMessage(payload) receives { content, parent_message_id } for API use\n * - onEditMessage({ id, content }): on API error return { success: false } or throw to keep edit UI open\n * - No data fetching or app-specific APIs – host app owns data + side effects\n *\n * `messages` items:\n * {\n * id: string;\n * author: { name: string; initials: string; color: string; role?: string };\n * content: string;\n * timestamp: string; // already formatted for display\n * type?: \"comment\" | \"system\";\n * isEdited?: boolean;\n * references?: Array<{ type: \"condition\" | \"timestamp\" | \"observation\"; label: string }>;\n * }\n *\n * When a structured `messageThread` payload is provided (for example from an\n * `interaction-message-thread` block), this component will normalize its\n * threads and messages into the same internal shape so existing threads and\n * comments render without the caller needing to reshape the data.\n */\nexport default function MessageThread({\n sessionTitle,\n sessionSubtitle,\n threadLabel,\n messages: initialMessages,\n messageThread,\n onSendMessage,\n onReplyMessage,\n onEditMessage,\n onDeleteMessage,\n onCreateNewThread, // optional: host can handle new thread creation\n onThreadSelect, // optional: host can react when a thread pill is selected\n currentUser,\n isLoading = false,\n}) {\n const [messageInput, setMessageInput] = useState(\"\");\n const [isFocused, setIsFocused] = useState(false);\n const [messages, setMessages] = useState(initialMessages || []);\n const [isSending, setIsSending] = useState(false);\n const [hoveredMessageId, setHoveredMessageId] = useState(null);\n // Thread tabs — start empty; callers or messageThread payload define them.\n const [threads, setThreads] = useState([]);\n const [activeThreadId, setActiveThreadId] = useState(null);\n const [replyingToMessageId, setReplyingToMessageId] = useState(null);\n const [replyDraft, setReplyDraft] = useState(\"\");\n const [editingMessageId, setEditingMessageId] = useState(null);\n const [editContent, setEditContent] = useState(\"\");\n const [deleteConfirmMessage, setDeleteConfirmMessage] = useState(null);\n const [showNewThreadCompose, setShowNewThreadCompose] = useState(false);\n const [newThreadInput, setNewThreadInput] = useState(\"\");\n const [isCreatingNewThread, setIsCreatingNewThread] = useState(false);\n const [expandedParentIds, setExpandedParentIds] = useState(new Set());\n\n const messagesEndRef = useRef(null);\n const messageInputRef = useRef(null);\n\n const normalizedRole =\n (currentUser && currentUser.role && String(currentUser.role).toLowerCase()) ||\n \"\";\n\n const displayCurrentUser = useMemo(() => {\n if (!currentUser) {\n return {\n name: \"You\",\n initials: \"YO\",\n color: \"#6B7C93\",\n };\n }\n\n const name = currentUser.name || \"You\";\n const initials =\n currentUser.initials ||\n (name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()) ||\n \"YO\";\n\n const role =\n currentUser.role && String(currentUser.role).toLowerCase();\n const roleColor = roleColorMap(role);\n\n const color = currentUser.color || roleColor || \"#6B7C93\";\n\n return {\n ...currentUser,\n name,\n initials,\n color,\n };\n }, [currentUser]);\n const canCreateNewThread =\n normalizedRole === \"supervisor\" || normalizedRole === \"admin\";\n\n const childrenByParentId = useMemo(() => {\n const map = {};\n (messages || []).forEach((m) => {\n if (!m.parentId) return;\n if (!map[m.parentId]) map[m.parentId] = [];\n map[m.parentId].push(m);\n });\n return map;\n }, [messages]);\n\n const topLevelMessages = useMemo(\n () => (messages || []).filter((m) => !m.parentId),\n [messages]\n );\n\n // Shared helpers so reply/edit/delete checks are consistent for\n // both top‑level messages and nested replies.\n const isChildReply = (id) => replyingToMessageId === id;\n const isChildEdit = (id) => editingMessageId === id;\n const isChildDelete = (id) =>\n deleteConfirmMessage && deleteConfirmMessage.id === id;\n\n const hasHeader = threadLabel || sessionTitle || sessionSubtitle;\n const replyingToMessage = replyingToMessageId\n ? messages.find((m) => m.id === replyingToMessageId)\n : null;\n\n useEffect(() => {\n // When caller passes explicit messages (and no structured messageThread),\n // keep internal state in sync. Avoid resetting when using messageThread.\n if (messageThread) return;\n if (!initialMessages) return;\n setMessages(initialMessages);\n }, [initialMessages, messageThread]);\n\n // Normalize an optional `messageThread` payload (e.g. from interaction-detail data)\n // into local threads + messages so existing backend data shows up in the UI.\n useEffect(() => {\n if (!messageThread) return;\n\n const rawThreads = Array.isArray(messageThread.threads)\n ? messageThread.threads\n : Array.isArray(messageThread.items)\n ? messageThread.items\n : [];\n\n // Case 1: multi-thread payload\n if (rawThreads.length > 0) {\n const normalizedThreads = rawThreads.map((t, index) => {\n const id = t.id || t.thread_id || `thread-${index + 1}`;\n const label =\n t.label ||\n t.title ||\n (index === 0 ? threadLabel || \"Session\" : `Thread ${index + 1}`);\n\n const rawMessagesForThread = extractMessagesArray(t);\n const messagesForThread = flattenMessages(rawMessagesForThread);\n\n return { id, label, messages: messagesForThread };\n });\n\n // Prefer payload threads; do not invent a default \"Session\" thread.\n setThreads(normalizedThreads);\n\n const firstWithMessages =\n normalizedThreads.find((t) => (t.messages || []).length > 0) ||\n normalizedThreads[0];\n\n const flatMessages = firstWithMessages?.messages || [];\n setMessages(flatMessages);\n // Start with all replies collapsed; user can expand per‑message.\n setExpandedParentIds(new Set());\n setActiveThreadId(firstWithMessages?.id || null);\n return;\n }\n\n // Case 2: single-thread payload with flat messages\n const rawFlat = extractMessagesArray(messageThread);\n if (rawFlat.length) {\n const mappedMessages = flattenMessages(rawFlat);\n\n setMessages(mappedMessages);\n // Start with all replies collapsed; user can expand per‑message.\n setExpandedParentIds(new Set());\n\n // Single-thread payload without an explicit threads array: create one\n // pill using the thread's own title so we don't show a generic \"Session\".\n const singleId = messageThread.id || \"thread-1\";\n const singleLabel =\n messageThread.title || threadLabel || \"Thread 1\";\n\n setThreads([\n {\n id: singleId,\n label: singleLabel,\n },\n ]);\n setActiveThreadId(singleId);\n }\n }, [messageThread, threadLabel]);\n useEffect(() => {\n // Keep the primary thread label aligned with the provided threadLabel\n if (!threadLabel) return;\n setThreads((prev) =>\n prev.map((thread, index) =>\n index === 0 ? { ...thread, label: threadLabel } : thread\n )\n );\n }, [threadLabel]);\n\n useEffect(() => {\n if (!messagesEndRef.current) return;\n if (!messages || messages.length === 0) return;\n // Keep the messages scrolled to the bottom *within* the thread container\n // without forcing the entire page to scroll.\n const container = messagesEndRef.current.parentElement;\n if (container) {\n container.scrollTop = container.scrollHeight;\n } else {\n messagesEndRef.current.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\n }\n }, [messages]);\n\n const handleNewThreadSubmit = async () => {\n const trimmed = newThreadInput.trim();\n if (!trimmed) return;\n setIsCreatingNewThread(true);\n try {\n const newId = `thread-${Date.now()}`;\n setThreads((prev) => [\n ...prev,\n {\n id: newId,\n label: trimmed.slice(0, 32) || `Thread ${prev.length + 1}`,\n },\n ]);\n setActiveThreadId(newId);\n await onCreateNewThread?.(trimmed);\n setNewThreadInput(\"\");\n setShowNewThreadCompose(false);\n } finally {\n setIsCreatingNewThread(false);\n }\n };\n\n const handleNewThreadCancel = () => {\n setShowNewThreadCompose(false);\n setNewThreadInput(\"\");\n };\n\n const handleSend = async () => {\n const trimmed = messageInput.trim();\n if (!trimmed) return;\n\n const content = trimmed;\n setMessageInput(\"\");\n\n const optimisticId = `temp-${Date.now()}`;\n const optimisticMessage = {\n id: optimisticId,\n author: displayCurrentUser,\n content,\n timestamp: \"Just now\",\n type: \"comment\",\n isOptimistic: true,\n parentId: replyingToMessageId || null,\n };\n\n setMessages((prev) => [...prev, optimisticMessage]);\n\n if (onSendMessage) {\n setIsSending(true);\n try {\n await onSendMessage({\n content,\n parent_message_id: replyingToMessageId || null,\n });\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === optimisticId ? { ...msg, isOptimistic: false } : msg\n )\n );\n } catch {\n setMessages((prev) => prev.filter((msg) => msg.id !== optimisticId));\n } finally {\n setIsSending(false);\n }\n setReplyingToMessageId(null);\n return;\n }\n\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === optimisticId ? { ...msg, isOptimistic: false } : msg\n )\n );\n setReplyingToMessageId(null);\n };\n\n const handleKeyPress = (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleReplyClick = (message) => {\n setReplyingToMessageId(message.id);\n setReplyDraft(\"\");\n setEditingMessageId(null);\n setEditContent(\"\");\n setHoveredMessageId(null);\n onReplyMessage?.(message);\n };\n\n const handleInlineReplySend = async (parentMessageId) => {\n const trimmed = replyDraft.trim();\n if (!trimmed) return;\n\n const optimisticId = `reply-${Date.now()}`;\n const optimisticReply = {\n id: optimisticId,\n author: displayCurrentUser,\n content: trimmed,\n timestamp: \"Just now\",\n type: \"comment\",\n isOptimistic: !onSendMessage,\n parentId: parentMessageId,\n };\n\n setMessages((prev) => [...prev, optimisticReply]);\n\n setIsSending(true);\n try {\n if (onSendMessage) {\n await onSendMessage({\n content: trimmed,\n parent_message_id: parentMessageId,\n });\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === optimisticId ? { ...msg, isOptimistic: false } : msg\n )\n );\n }\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n } catch {\n if (onSendMessage) {\n setMessages((prev) => prev.filter((msg) => msg.id !== optimisticId));\n }\n } finally {\n setIsSending(false);\n }\n };\n\n const handleEditClick = (message) => {\n setEditingMessageId(message.id);\n setEditContent(message.content || \"\");\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n setHoveredMessageId(null);\n };\n\n const handleEditSubmit = async () => {\n const trimmed = editContent.trim();\n if (!trimmed || !editingMessageId) return;\n try {\n const result = await onEditMessage?.({ id: editingMessageId, content: trimmed });\n // Keep edit UI open if host explicitly reports failure (e.g. API 500).\n // Host can return { success: false } or throw; either way we do not update or close.\n if (result && typeof result === \"object\" && result.success === false) {\n return;\n }\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === editingMessageId\n ? { ...msg, content: trimmed, isEdited: true }\n : msg\n )\n );\n setEditingMessageId(null);\n setEditContent(\"\");\n } catch (err) {\n // Keep edit textarea + Cancel + Save visible on error; host can show a toast.\n // eslint-disable-next-line no-console\n console.error(\"MessageThread edit failed:\", err);\n }\n };\n\n const handleEditCancel = () => {\n setEditingMessageId(null);\n setEditContent(\"\");\n };\n\n const handleDeleteClick = (message) => {\n setDeleteConfirmMessage(message);\n setHoveredMessageId(null);\n };\n\n const handleDeleteConfirm = async () => {\n if (!deleteConfirmMessage) return;\n const msg = deleteConfirmMessage;\n setDeleteConfirmMessage(null);\n setMessages((prev) => prev.filter((m) => m.id !== msg.id));\n await onDeleteMessage?.(msg);\n };\n\n // Recursive renderer for a single message + its children\nconst renderMessageTree = (message, depth = 0) => {\n const children = childrenByParentId[message.id] || [];\n const hasChildren = children.length > 0;\n const isExpanded = expandedParentIds.has(message.id);\n const isEditing = isChildEdit(message.id);\n const isReplying = isChildReply(message.id);\n\n return (\n <div key={message.id}>\n <div\n onMouseEnter={() =>\n message.type !== \"system\" && setHoveredMessageId(message.id)\n }\n onMouseLeave={() => setHoveredMessageId(null)}\n style={{\n display: \"flex\",\n gap: \"12px\",\n opacity: message.type === \"system\" ? 0.75 : 1,\n padding: \"4px 0\",\n margin: \"0 -4px\",\n borderRadius: \"8px\",\n marginLeft: depth > 0 ? 16 : 0,\n }}\n >\n {message.type !== \"system\" ? (\n <div\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n background: message.author.color,\n color: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"11px\",\n fontWeight: 650,\n flexShrink: 0,\n }}\n >\n {message.author.initials}\n </div>\n ) : (\n <div\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n background: \"rgba(30, 33, 37, 0.1)\",\n color: \"rgba(30, 33, 37, 0.55)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Clock size={16} />\n </div>\n )}\n\n <div style={{ flex: 1, minWidth: 0 }}>\n {/* header: name + time + role chip + hover actions */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"baseline\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n marginBottom: \"6px\",\n justifyContent: \"space-between\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"baseline\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n }}\n >\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 650,\n color: \"rgba(30, 33, 37, 0.9)\",\n }}\n >\n {message.author.name}\n </span>\n {message.timestamp && (\n <span\n style={{\n fontSize: \"10px\",\n fontFamily: \"var(--default-mono-font-family)\",\n color: \"rgba(30, 33, 37, 0.5)\",\n }}\n >\n {formatTimestamp(message.timestamp)}\n </span>\n )}\n {message.author?.role && (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n fontSize: \"10px\",\n color: \"rgba(30, 33, 37, 0.6)\",\n background: \"rgba(30, 33, 37, 0.08)\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n fontWeight: 600,\n }}\n >\n {String(message.author.role)}\n </span>\n )}\n {(message.isEdited || message.is_edited) && (\n <span\n style={{\n fontSize: \"10px\",\n color: \"rgba(30, 33, 37, 0.5)\",\n fontStyle: \"italic\",\n }}\n >\n (Edited)\n </span>\n )}\n </div>\n\n {message.type !== \"system\" &&\n hoveredMessageId === message.id && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n flexShrink: 0,\n }}\n >\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleReplyClick(message);\n }}\n style={messageActionButtonStyle}\n >\n Reply\n </button>\n {onEditMessage && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleEditClick(message);\n }}\n style={messageActionButtonStyle}\n >\n Edit\n </button>\n )}\n {onDeleteMessage && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleDeleteClick(message);\n }}\n style={{\n ...messageActionButtonStyle,\n color: \"rgba(198, 99, 99, 0.9)\",\n }}\n >\n Delete\n </button>\n )}\n </div>\n )}\n </div>\n\n {/* body: edit vs text */}\n {isEditing ? (\n <div style={{ marginTop: \"4px\" }}>\n <textarea\n value={editContent}\n onChange={(e) => setEditContent(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleEditSubmit();\n }\n if (e.key === \"Escape\") handleEditCancel();\n }}\n placeholder=\"Edit message...\"\n autoFocus\n style={{\n width: \"100%\",\n minHeight: \"56px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n background: \"white\",\n border: \"1px solid rgba(52, 58, 64, 0.2)\",\n borderRadius: \"6px\",\n resize: \"vertical\",\n outline: \"none\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n marginBottom: \"8px\",\n }}\n />\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n justifyContent: \"flex-end\",\n alignItems: \"center\",\n }}\n >\n <button\n type=\"button\"\n onClick={handleEditCancel}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.45)\",\n background: \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background =\n \"rgba(30, 33, 37, 0.15)\";\n e.currentTarget.style.color =\n \"rgba(30, 33, 37, 0.7)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background =\n \"rgba(30, 33, 37, 0.1)\";\n e.currentTarget.style.color =\n \"rgba(30, 33, 37, 0.45)\";\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleEditSubmit}\n disabled={!editContent?.trim()}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: editContent?.trim()\n ? \"white\"\n : \"rgba(30, 33, 37, 0.45)\",\n background: editContent?.trim()\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: editContent?.trim() ? \"pointer\" : \"not-allowed\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n if (editContent?.trim()) {\n e.currentTarget.style.background = \"#4d7290\";\n }\n }}\n onMouseLeave={(e) => {\n if (editContent?.trim()) {\n e.currentTarget.style.background = \"#5e88b0\";\n }\n }}\n >\n Save\n </button>\n </div>\n </div>\n ) : (\n <div\n style={{\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n lineHeight: 1.55,\n marginBottom: message.references?.length ? \"8px\" : 0,\n }}\n >\n {message.content}\n </div>\n )}\n\n {/* inline reply box when replying to this id */}\n {isReplying && (\n <div style={{ marginTop: \"12px\" }}>\n <textarea\n value={replyDraft}\n onChange={(e) => setReplyDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n }\n }}\n placeholder=\"Type your reply...\"\n disabled={isSending}\n autoFocus\n style={{\n width: \"100%\",\n minHeight: \"64px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n background: \"white\",\n border: \"1px solid rgba(52, 58, 64, 0.16)\",\n borderRadius: \"6px\",\n resize: \"vertical\",\n outline: \"none\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n marginBottom: \"10px\",\n }}\n />\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n justifyContent: \"flex-end\",\n alignItems: \"center\",\n }}\n >\n <button\n type=\"button\"\n onClick={() => {\n setReplyingToMessageId(null);\n setReplyDraft(\"\");\n }}\n disabled={isSending}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.45)\",\n background: \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: isSending ? \"not-allowed\" : \"pointer\",\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => handleInlineReplySend(message.id)}\n disabled={!replyDraft.trim() || isSending}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color:\n replyDraft.trim() && !isSending\n ? \"white\"\n : \"rgba(30, 33, 37, 0.45)\",\n background:\n replyDraft.trim() && !isSending\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.12)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor:\n replyDraft.trim() && !isSending\n ? \"pointer\"\n : \"not-allowed\",\n }}\n >\n Send\n </button>\n </div>\n </div>\n )}\n\n {/* references block (unchanged) */}\n {/* ... your existing references pills ... */}\n\n {/* children: collapse/expand replies */}\n {hasChildren && (\n <div style={{ marginTop: 8 }}>\n <button\n type=\"button\"\n onClick={() =>\n setExpandedParentIds((prev) => {\n const next = new Set(prev);\n next.has(message.id)\n ? next.delete(message.id)\n : next.add(message.id);\n return next;\n })\n }\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"4px 8px\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.6)\",\n background: \"transparent\",\n border: \"none\",\n borderRadius: 6,\n cursor: \"pointer\",\n }}\n title={isExpanded ? \"Collapse replies\" : \"Expand replies\"}\n >\n <ChevronRight\n size={14}\n style={{\n flexShrink: 0,\n transform: isExpanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.2s ease\",\n }}\n />\n <span>\n {children.length} {children.length === 1 ? \"reply\" : \"replies\"}\n </span>\n </button>\n\n {isExpanded && (\n <div\n style={{\n marginTop: 8,\n marginLeft: 16,\n paddingLeft: 16,\n borderLeft: \"2px solid rgba(52, 58, 64, 0.14)\",\n }}\n >\n {children.map((child) =>\n renderMessageTree(child, depth + 1)\n )}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n background: \"rgba(255, 255, 255, 0.98)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n position: \"relative\",\n }}\n >\n {/* Delete confirmation overlay */}\n {deleteConfirmMessage && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 50,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(30, 33, 37, 0.35)\",\n borderRadius: \"12px\",\n }}\n onClick={() => setDeleteConfirmMessage(null)}\n >\n <div\n style={{\n background: \"white\",\n borderRadius: \"12px\",\n padding: \"20px 24px\",\n boxShadow: \"0 8px 24px rgba(30, 33, 37, 0.15)\",\n maxWidth: \"320px\",\n width: \"90%\",\n }}\n onClick={(e) => e.stopPropagation()}\n >\n <p\n style={{\n margin: 0,\n marginBottom: \"20px\",\n fontSize: \"14px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.9)\",\n lineHeight: 1.45,\n }}\n >\n Do you really want to delete?\n </p>\n <div\n style={{\n display: \"flex\",\n gap: \"10px\",\n justifyContent: \"flex-end\",\n }}\n >\n <button\n type=\"button\"\n onClick={() => setDeleteConfirmMessage(null)}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.45)\",\n background: \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleDeleteConfirm}\n style={{\n padding: \"8px 16px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"white\",\n background: \"#5e88b0\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n }}\n >\n Delete\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Header */}\n {hasHeader && (\n <div\n style={{\n padding: \"14px 16px\",\n borderBottom: \"1px solid rgba(52, 58, 64, 0.12)\",\n background: \"rgba(255, 255, 255, 0.98)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n >\n <div>\n <div\n style={{\n fontSize: \"14px\",\n fontWeight: 600,\n color: \"rgba(30, 33, 37, 0.95)\",\n marginBottom: \"4px\",\n }}\n >\n {threadLabel || \"Session Discussion\"}\n </div>\n {(sessionTitle || sessionSubtitle) && (\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.52)\",\n }}\n >\n {sessionTitle || sessionSubtitle}\n </div>\n )}\n {threads.length > 0 && (\n <div\n style={{\n marginTop: \"8px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n }}\n >\n {threads.map((thread) => {\n const isActive = thread.id === activeThreadId;\n return (\n <button\n key={thread.id}\n type=\"button\"\n onClick={() => {\n setActiveThreadId(thread.id);\n if (Array.isArray(thread.messages)) {\n setMessages(thread.messages);\n // On thread switch, start with replies collapsed.\n setExpandedParentIds(new Set());\n }\n setHoveredMessageId(null);\n setReplyingToMessageId(null);\n setEditingMessageId(null);\n onThreadSelect?.(thread);\n }}\n style={{\n padding: \"4px 10px\",\n borderRadius: \"999px\",\n border: \"1px solid rgba(184, 156, 106, 0.35)\",\n background: isActive\n ? \"rgba(184, 156, 106, 0.16)\"\n : \"rgba(255, 255, 255, 0.9)\",\n color: \"rgba(30, 33, 37, 0.85)\",\n fontSize: \"11px\",\n fontWeight: 500,\n cursor: \"pointer\",\n }}\n >\n {thread.label}\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* \"+ New thread\" – only for supervisor/admin roles */}\n {canCreateNewThread && (\n <button\n type=\"button\"\n onClick={() => {\n setShowNewThreadCompose((prev) => !prev);\n }}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"6px 12px\",\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.75)\",\n background: \"transparent\",\n border: \"1px solid rgba(30, 33, 37, 0.12)\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n transition: \"background 0.15s ease, color 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background =\n \"rgba(231, 212, 162, 0.12)\";\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.9)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.75)\";\n }}\n title=\"Start a new discussion thread\"\n >\n <span\n style={{\n fontSize: 16,\n lineHeight: 1,\n marginTop: -1,\n }}\n >\n +\n </span>\n New thread\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* Messages list */}\n <div\n style={{\n flex: 1,\n overflowY: \"auto\",\n padding: \"16px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"16px\",\n }}\n >\n {/* Inline \"new thread\" compose */}\n {showNewThreadCompose && (\n <div\n style={{\n marginBottom: \"16px\",\n padding: \"12px\",\n background: \"rgba(30, 33, 37, 0.04)\",\n border: \"1px solid rgba(52, 58, 64, 0.14)\",\n borderRadius: \"8px\",\n }}\n >\n <textarea\n value={newThreadInput}\n onChange={(e) => setNewThreadInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleNewThreadSubmit();\n }\n }}\n placeholder=\"Start a new thread...\"\n disabled={isCreatingNewThread}\n style={{\n width: \"100%\",\n minHeight: \"64px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.88)\",\n background: \"white\",\n border: \"1px solid rgba(52, 58, 64, 0.16)\",\n borderRadius: \"6px\",\n resize: \"vertical\",\n outline: \"none\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n marginBottom: \"10px\",\n }}\n />\n <div style={{ display: \"flex\", gap: \"8px\", justifyContent: \"flex-end\" }}>\n <button\n type=\"button\"\n onClick={handleNewThreadCancel}\n disabled={isCreatingNewThread}\n style={{\n padding: \"6px 14px\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"rgba(30, 33, 37, 0.7)\",\n background: \"rgba(30, 33, 37, 0.08)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor: isCreatingNewThread ? \"not-allowed\" : \"pointer\",\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleNewThreadSubmit}\n disabled={!newThreadInput.trim() || isCreatingNewThread}\n style={{\n padding: \"6px 14px\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"white\",\n background:\n newThreadInput.trim() && !isCreatingNewThread\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.25)\",\n border: \"none\",\n borderRadius: \"6px\",\n cursor:\n newThreadInput.trim() && !isCreatingNewThread\n ? \"pointer\"\n : \"not-allowed\",\n }}\n >\n {isCreatingNewThread ? \"Sending...\" : \"Send\"}\n </button>\n </div>\n </div>\n )}\n {isLoading ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"40px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n }}\n >\n Loading messages...\n </div>\n ) : topLevelMessages.length === 0 ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"40px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n }}\n >\n No messages yet. Start the conversation!\n </div>\n ) : (\n // topLevelMessages.map((message) => (\n // <div\n // key={message.id}\n // onMouseEnter={() =>\n // message.type !== \"system\" && setHoveredMessageId(message.id)\n // }\n // onMouseLeave={() => setHoveredMessageId(null)}\n // style={{\n // display: \"flex\",\n // gap: \"12px\",\n // opacity: message.type === \"system\" ? 0.75 : 1,\n // padding: \"4px 0\",\n // margin: \"0 -4px\",\n // borderRadius: \"8px\",\n // }}\n // >\n // {message.type !== \"system\" ? (\n // <div\n // style={{\n // width: \"36px\",\n // height: \"36px\",\n // borderRadius: \"50%\",\n // background: message.author.color,\n // color: \"white\",\n // display: \"flex\",\n // alignItems: \"center\",\n // justifyContent: \"center\",\n // fontSize: \"11px\",\n // fontWeight: 650,\n // flexShrink: 0,\n // }}\n // >\n // {message.author.initials}\n // </div>\n // ) : (\n // <div\n // style={{\n // width: \"36px\",\n // height: \"36px\",\n // borderRadius: \"50%\",\n // background: \"rgba(30, 33, 37, 0.1)\",\n // color: \"rgba(30, 33, 37, 0.55)\",\n // display: \"flex\",\n // alignItems: \"center\",\n // justifyContent: \"center\",\n // flexShrink: 0,\n // }}\n // >\n // <Clock size={16} />\n // </div>\n // )}\n\n // <div style={{ flex: 1, minWidth: 0 }}>\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // marginBottom: \"6px\",\n // justifyContent: \"space-between\",\n // }}\n // >\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // }}\n // >\n // <span\n // style={{\n // fontSize: \"13px\",\n // fontWeight: 650,\n // color: \"rgba(30, 33, 37, 0.9)\",\n // }}\n // >\n // {message.author.name}\n // </span>\n // {message.timestamp && (\n // <span\n // style={{\n // fontSize: \"10px\",\n // fontFamily: \"var(--default-mono-font-family)\",\n // color: \"rgba(30, 33, 37, 0.5)\",\n // }}\n // >\n // {formatTimestamp(message.timestamp)}\n // </span>\n // )}\n // {message.author?.role && (\n // <span\n // style={{\n // display: \"inline-flex\",\n // alignItems: \"center\",\n // fontSize: \"10px\",\n // color: \"rgba(30, 33, 37, 0.6)\",\n // background: \"rgba(30, 33, 37, 0.08)\",\n // padding: \"3px 8px\",\n // borderRadius: \"6px\",\n // textTransform: \"uppercase\",\n // letterSpacing: \"0.04em\",\n // fontWeight: 600,\n // }}\n // >\n // {String(message.author.role)}\n // </span>\n // )}\n // </div>\n\n // {message.type !== \"system\" &&\n // hoveredMessageId === message.id && (\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"12px\",\n // flexShrink: 0,\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleReplyClick(message);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Reply\n // </button>\n // {onEditMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleEditClick(message);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Edit\n // </button>\n // )}\n // {onDeleteMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleDeleteClick(message);\n // }}\n // style={{\n // ...messageActionButtonStyle,\n // color: \"rgba(198, 99, 99, 0.9)\",\n // }}\n // >\n // Delete\n // </button>\n // )}\n // </div>\n // )}\n // </div>\n\n // {isChildEdit(message.id) ? (\n // <div style={{ marginTop: \"6px\" }}>\n // <textarea\n // value={editContent}\n // onChange={(e) => setEditContent(e.target.value)}\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }\n // }}\n // placeholder=\"Edit message...\"\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border: \"1px solid rgba(52, 58, 64, 0.2)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"8px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: \"rgba(30, 33, 37, 0.45)\",\n // background: \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: \"pointer\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={handleEditSubmit}\n // disabled={!editContent.trim()}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: editContent.trim()\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background: editContent.trim()\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: editContent.trim() ? \"pointer\" : \"not-allowed\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // Save\n // </button>\n // </div>\n // </div>\n // ) : (\n // <div\n // style={{\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // lineHeight: 1.55,\n // }}\n // >\n // {message.content}\n // </div>\n // )}\n\n // {isChildReply(message.id) && (\n // <div style={{ marginTop: \"12px\" }}>\n // <textarea\n // value={replyDraft}\n // onChange={(e) => setReplyDraft(e.target.value)}\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }\n // }}\n // placeholder=\"Type your reply...\"\n // disabled={isSending}\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border: \"1px solid rgba(52, 58, 64, 0.16)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"10px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }}\n // disabled={isSending}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: \"rgba(30, 33, 37, 0.45)\",\n // background: \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: isSending ? \"not-allowed\" : \"pointer\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={() => handleInlineReplySend(message.id)}\n // disabled={!replyDraft.trim() || isSending}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // replyDraft.trim() && !isSending\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background:\n // replyDraft.trim() && !isSending\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.12)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor:\n // replyDraft.trim() && !isSending\n // ? \"pointer\"\n // : \"not-allowed\",\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // transition: \"all 0.15s ease\",\n // }}\n // >\n // {isSending ? \"Sending...\" : \"Send\"}\n // </button>\n // </div>\n // </div>\n // )}\n\n // {childrenByParentId[message.id]?.length ? (\n // <div style={{ marginTop: \"8px\" }}>\n // <button\n // type=\"button\"\n // onClick={() =>\n // setExpandedParentIds((prev) => {\n // const next = new Set(prev);\n // if (next.has(message.id)) next.delete(message.id);\n // else next.add(message.id);\n // return next;\n // })\n // }\n // style={{\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"6px\",\n // padding: 0,\n // border: \"none\",\n // background: \"transparent\",\n // cursor: \"pointer\",\n // fontSize: \"12px\",\n // fontWeight: 500,\n // color: \"rgba(30, 33, 37, 0.55)\",\n // fontFamily: \"inherit\",\n // }}\n // >\n // <ChevronRight\n // size={14}\n // style={{\n // flexShrink: 0,\n // transition: \"transform 0.2s ease\",\n // transform: expandedParentIds.has(message.id)\n // ? \"rotate(90deg)\"\n // : \"rotate(0deg)\",\n // }}\n // />\n // <span>\n // {childrenByParentId[message.id].length}{\" \"}\n // {childrenByParentId[message.id].length === 1\n // ? \"reply\"\n // : \"replies\"}\n // </span>\n // </button>\n // {expandedParentIds.has(message.id) && (\n // <div\n // style={{\n // marginTop: \"8px\",\n // marginLeft: \"16px\",\n // paddingLeft: \"16px\",\n // borderLeft:\n // \"2px solid rgba(52, 58, 64, 0.14)\",\n // }}\n // >\n // {childrenByParentId[message.id].map((reply) => {\n // const isReplyEditing = isChildEdit(reply.id);\n // const isReplyBeingRepliedTo = isChildReply(reply.id);\n\n // return (\n // <div\n // key={reply.id}\n // onMouseEnter={() => {\n // if (reply.type !== \"system\") {\n // setHoveredMessageId(reply.id);\n // }\n // }}\n // onMouseLeave={() => setHoveredMessageId(null)}\n // style={{\n // display: \"flex\",\n // gap: \"12px\",\n // padding: \"4px 0\",\n // margin: \"0 -4px\",\n // borderRadius: \"8px\",\n // }}\n // >\n // <div\n // style={{\n // width: \"28px\",\n // height: \"28px\",\n // borderRadius: \"50%\",\n // background: reply.author.color,\n // color: \"white\",\n // display: \"flex\",\n // alignItems: \"center\",\n // justifyContent: \"center\",\n // fontSize: \"10px\",\n // fontWeight: 650,\n // flexShrink: 0,\n // }}\n // >\n // {reply.author.initials}\n // </div>\n // <div style={{ flex: 1, minWidth: 0 }}>\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // marginBottom: \"4px\",\n // justifyContent: \"space-between\",\n // }}\n // >\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"baseline\",\n // flexWrap: \"wrap\",\n // gap: \"8px\",\n // }}\n // >\n // <span\n // style={{\n // fontSize: \"13px\",\n // fontWeight: 650,\n // color: \"rgba(30, 33, 37, 0.9)\",\n // }}\n // >\n // {reply.author.name}\n // </span>\n // {reply.timestamp && (\n // <span\n // style={{\n // fontSize: \"10px\",\n // fontFamily:\n // \"var(--default-mono-font-family)\",\n // color:\n // \"rgba(30, 33, 37, 0.5)\",\n // }}\n // >\n // {formatTimestamp(\n // reply.timestamp\n // )}\n // </span>\n // )}\n // {reply.author?.role && (\n // <span\n // style={{\n // display: \"inline-flex\",\n // alignItems: \"center\",\n // gap: \"4px\",\n // fontSize: \"10px\",\n // color:\n // \"rgba(30, 33, 37, 0.6)\",\n // background:\n // \"rgba(30, 33, 37, 0.08)\",\n // padding: \"3px 8px\",\n // borderRadius: \"6px\",\n // textTransform: \"uppercase\",\n // letterSpacing: \"0.04em\",\n // fontWeight: 600,\n // }}\n // >\n // {reply.author.role}\n // </span>\n // )}\n // </div>\n\n // {reply.type !== \"system\" &&\n // hoveredMessageId === reply.id && (\n // <div\n // style={{\n // display: \"flex\",\n // alignItems: \"center\",\n // gap: \"12px\",\n // flexShrink: 0,\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleReplyClick(reply);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Reply\n // </button>\n // {onEditMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleEditClick(reply);\n // }}\n // style={messageActionButtonStyle}\n // >\n // Edit\n // </button>\n // )}\n // {onDeleteMessage && (\n // <button\n // type=\"button\"\n // onClick={(e) => {\n // e.preventDefault();\n // e.stopPropagation();\n // handleDeleteClick(reply);\n // }}\n // style={{\n // ...messageActionButtonStyle,\n // color:\n // \"rgba(198, 99, 99, 0.9)\",\n // }}\n // >\n // Delete\n // </button>\n // )}\n // </div>\n // )}\n // </div>\n\n // {isReplyEditing ? (\n // <div style={{ marginTop: \"6px\" }}>\n // <textarea\n // value={editContent}\n // onChange={(e) =>\n // setEditContent(e.target.value)\n // }\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }\n // }}\n // placeholder=\"Edit message...\"\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border:\n // \"1px solid rgba(52, 58, 64, 0.2)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"8px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setEditingMessageId(null);\n // setEditContent(\"\");\n // }}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // \"rgba(30, 33, 37, 0.45)\",\n // background:\n // \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: \"pointer\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={handleEditSubmit}\n // disabled={!editContent.trim()}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color: editContent.trim()\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background: editContent.trim()\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: editContent.trim()\n // ? \"pointer\"\n // : \"not-allowed\",\n // }}\n // >\n // Save\n // </button>\n // </div>\n // </div>\n // ) : (\n // <div\n // style={{\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // lineHeight: 1.55,\n // }}\n // >\n // {reply.content}\n // </div>\n // )}\n\n // {isReplyBeingRepliedTo && (\n // <div style={{ marginTop: \"12px\" }}>\n // <textarea\n // value={replyDraft}\n // onChange={(e) =>\n // setReplyDraft(e.target.value)\n // }\n // onKeyDown={(e) => {\n // if (e.key === \"Escape\") {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }\n // }}\n // placeholder=\"Type your reply...\"\n // disabled={isSending}\n // autoFocus\n // style={{\n // width: \"100%\",\n // minHeight: \"64px\",\n // padding: \"8px 12px\",\n // fontSize: \"13px\",\n // color: \"rgba(30, 33, 37, 0.88)\",\n // background: \"white\",\n // border:\n // \"1px solid rgba(52, 58, 64, 0.16)\",\n // borderRadius: \"6px\",\n // resize: \"vertical\",\n // outline: \"none\",\n // fontFamily: \"inherit\",\n // lineHeight: 1.5,\n // marginBottom: \"10px\",\n // }}\n // />\n // <div\n // style={{\n // display: \"flex\",\n // gap: \"8px\",\n // justifyContent: \"flex-end\",\n // alignItems: \"center\",\n // }}\n // >\n // <button\n // type=\"button\"\n // onClick={() => {\n // setReplyingToMessageId(null);\n // setReplyDraft(\"\");\n // }}\n // disabled={isSending}\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // \"rgba(30, 33, 37, 0.45)\",\n // background:\n // \"rgba(30, 33, 37, 0.1)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor: isSending\n // ? \"not-allowed\"\n // : \"pointer\",\n // }}\n // >\n // Cancel\n // </button>\n // <button\n // type=\"button\"\n // onClick={() =>\n // handleInlineReplySend(reply.id)\n // }\n // disabled={\n // !replyDraft.trim() || isSending\n // }\n // style={{\n // padding: \"8px 16px\",\n // fontSize: \"12px\",\n // fontWeight: 600,\n // color:\n // replyDraft.trim() && !isSending\n // ? \"white\"\n // : \"rgba(30, 33, 37, 0.45)\",\n // background:\n // replyDraft.trim() && !isSending\n // ? \"#5e88b0\"\n // : \"rgba(30, 33, 37, 0.12)\",\n // border: \"none\",\n // borderRadius: \"6px\",\n // cursor:\n // replyDraft.trim() && !isSending\n // ? \"pointer\"\n // : \"not-allowed\",\n // }}\n // >\n // {isSending ? \"Sending...\" : \"Send\"}\n // </button>\n // </div>\n // </div>\n // )}\n // </div>\n // </div>\n // );\n // })}\n // </div>\n // )}\n // </div>\n // ) : null}\n // </div>\n // </div>\n // ))\n topLevelMessages.map((message) => renderMessageTree(message, 0))\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input area */}\n <div\n style={{\n padding: \"12px\",\n borderTop: \"1px solid rgba(52, 58, 64, 0.12)\",\n background: \"rgba(255, 255, 255, 0.95)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n alignItems: \"flex-end\",\n }}\n >\n <div\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n background: displayCurrentUser.color,\n color: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"11px\",\n fontWeight: 650,\n flexShrink: 0,\n }}\n >\n {displayCurrentUser.initials}\n </div>\n\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"8px\",\n }}\n >\n <textarea\n ref={messageInputRef}\n value={messageInput}\n onChange={(e) => setMessageInput(e.target.value)}\n onKeyDown={handleKeyPress}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n placeholder={\n replyingToMessage ? \"Type your reply...\" : \"Add a comment...\"\n }\n style={{\n width: \"100%\",\n minHeight: \"38px\",\n maxHeight: \"120px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"rgba(30, 33, 37, 0.85)\",\n background: \"white\",\n border: `1px solid ${\n isFocused\n ? \"rgba(94, 136, 176, 0.35)\"\n : \"rgba(52, 58, 64, 0.16)\"\n }`,\n borderRadius: \"8px\",\n resize: \"vertical\",\n outline: \"none\",\n transition: \"border-color 0.15s ease\",\n fontFamily: \"inherit\",\n lineHeight: 1.5,\n }}\n />\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n }}\n >\n <button\n type=\"button\"\n onClick={handleSend}\n disabled={!messageInput.trim() || isSending}\n style={{\n padding: \"8px 16px\",\n background:\n messageInput.trim() && !isSending\n ? \"#5e88b0\"\n : \"rgba(30, 33, 37, 0.1)\",\n border: \"none\",\n borderRadius: \"6px\",\n color:\n messageInput.trim() && !isSending\n ? \"white\"\n : \"rgba(30, 33, 37, 0.45)\",\n fontSize: \"12px\",\n fontWeight: 600,\n cursor:\n messageInput.trim() && !isSending\n ? \"pointer\"\n : \"not-allowed\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n transition: \"all 0.15s ease\",\n }}\n >\n {isSending ? (\n <>\n <div\n style={{\n width: \"14px\",\n height: \"14px\",\n border: \"2px solid rgba(255, 255, 255, 0.3)\",\n borderTopColor: \"white\",\n borderRadius: \"50%\",\n animation: \"spin 0.6s linear infinite\",\n }}\n />\n Sending...\n </>\n ) : (\n <>\n <Send size={14} />\n Send\n </>\n )}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n","\"use client\";\n\nimport React, { useState, useEffect, useLayoutEffect, useRef, useMemo } from 'react';\nimport DetailCard from '../../primitives/DetailCard.jsx';\nimport { Tabs } from '../../index.js';\nimport CoachingSynthesisCard from './CoachingSynthesisCard.jsx';\nimport InteractionContext from './InteractionContext.jsx';\nimport InteractionScores from './InteractionScores.jsx';\nimport AgentLiftCard from '../../common/AgentLiftCard.jsx';\nimport InteractionSignals from './InteractionSignals.jsx';\nimport InteractionGuidance from './InteractionGuidance.jsx';\nimport InteractionNBA from './InteractionNBA.jsx';\nimport InteractionRecording from './InteractionRecording.jsx';\nimport InteractionTranscript from './InteractionTranscript.jsx';\nimport MessageThread from '../../common/MessageThread.jsx';\n\nfunction findBlock(blocks, id) {\n return blocks.find((b) => b.block_id === id);\n}\n\nfunction InteractionDetailPanel({\n data,\n audioUrl,\n coachingData,\n messageThread,\n coachingLoading,\n coachingError,\n // Optional callbacks for host apps to wire MessageThread to real APIs.\n onThreadSendMessage,\n onThreadEditMessage,\n onThreadDeleteMessage,\n onThreadCreateNewThread,\n onThreadSelect,\n threadLoading,\n threadCurrentUser,\n}) {\n const blocks = data.blocks || [];\n const evidenceIndex = data.evidence_index || {};\n const audioRef = useRef(null);\n const segmentEndHandlerRef = useRef(null);\n const [highlightedTurns, setHighlightedTurns] = useState(new Set());\n const [expandedSignals, setExpandedSignals] = useState(new Set());\n\n // Timeline state for audio playback integration\n const [currentTimeSeconds, setCurrentTimeSeconds] = useState(0);\n const [timelinePlaying, setTimelinePlaying] = useState(false);\n const [playbackRate, setPlaybackRate] = useState(1);\n\n // Extract block data\n const meta = findBlock(blocks, 'interaction-metadata')?.payload || {};\n const ctx = findBlock(blocks, 'interaction-context')?.payload || {};\n const summary = findBlock(blocks, 'interaction-summary')?.payload || {};\n const scores = findBlock(blocks, 'interaction-scores')?.payload || {};\n const signals = findBlock(blocks, 'interaction-signals')?.payload || {};\n const guidance = findBlock(blocks, 'interaction-guidance')?.payload || {};\n const transcript = findBlock(blocks, 'interaction-transcript')?.payload || {};\n // const messageThread = findBlock(blocks, 'interaction-message-thread')?.payload || {};\n const nba = findBlock(blocks, 'interaction-nba')?.payload || {};\n const dimensionsBlock = findBlock(blocks, 'interaction-dimensions')?.payload || {};\n const dimensions = (dimensionsBlock.dimensions || []).filter(d => d.value);\n const outcomeLift = findBlock(blocks, 'interaction-outcome-lift')?.payload || {};\n\n // Build turn → observation pills map from signals data\n const turnObservations = useMemo(() => {\n const map = {}; // turnIndex → [{label, reason, color, signalKey}]\n const GROUP_LABELS = {\n outcome: { color: 'var(--rail-outcome)' },\n process: { color: 'var(--rail-discovery)' },\n compliance: { color: 'var(--rail-compliance)' },\n customer_friction: { color: 'var(--rail-coral)' },\n experience: { color: 'var(--rail-teal)' },\n };\n\n for (const signal of (signals.signals || [])) {\n const groupInfo = GROUP_LABELS[signal.group] || {};\n for (const obs of (signal.observations || [])) {\n for (const ev of (obs.evidence || [])) {\n if (ev.turn_ids?.length) {\n for (const tid of ev.turn_ids) {\n if (!map[tid]) map[tid] = [];\n // Deduplicate by observation key per turn\n if (!map[tid].some(o => o.label === (obs.key || signal.display_name || signal.key))) {\n map[tid].push({\n label: obs.key || signal.display_name || signal.key,\n reason: obs.reason || obs.explanation || '',\n color: groupInfo.color || 'var(--state-present)',\n signalKey: signal.key,\n });\n }\n }\n }\n }\n }\n }\n return map;\n }, [signals.signals]);\n\n // Build timeline segments from transcript messages\n const timelineSegments = transcript.messages?.map((m, i) => {\n const startTime = (m.start ?? m.start_ms) ? (m.start ?? m.start_ms) / 1000 : 0;\n const endTime = (m.end ?? m.end_ms) ? (m.end ?? m.end_ms) / 1000 : startTime + 1;\n const isAgent = m.actor === 'agent';\n const actorName = isAgent ? (transcript.actor_map?.agent || 'Agent') : (transcript.actor_map?.customer || 'Customer');\n\n return {\n startTime,\n endTime,\n actor: actorName,\n actorColor: isAgent ? 'var(--rail-outcome)' : 'var(--rail-discovery)',\n };\n }) || [];\n\n // Compute active turn index based on current playback time\n const activeTurnIndex = useMemo(() => {\n if (!timelinePlaying && currentTimeSeconds === 0) return -1;\n const messages = transcript.messages || [];\n const currentMs = currentTimeSeconds * 1000;\n for (let i = messages.length - 1; i >= 0; i--) {\n const startMs = messages[i].start ?? messages[i].start_ms;\n if (startMs != null && currentMs >= startMs) return i;\n }\n return -1;\n }, [currentTimeSeconds, timelinePlaying, transcript.messages]);\n\n // Timeline event handlers\n const handleTimelineSeek = (seconds) => {\n if (audioRef.current) {\n audioRef.current.currentTime = seconds;\n setCurrentTimeSeconds(seconds);\n }\n };\n\n const handleTimelineTogglePlay = () => {\n if (audioRef.current) {\n if (timelinePlaying) {\n audioRef.current.pause();\n setTimelinePlaying(false);\n } else {\n const p = audioRef.current.play();\n if (p !== undefined) p.catch(() => { }); // ignore AbortError when pause() interrupts play()\n setTimelinePlaying(true);\n }\n }\n };\n\n const handleTimelineSeekBack = () => {\n if (audioRef.current) {\n audioRef.current.currentTime = Math.max(0, audioRef.current.currentTime - 15);\n }\n };\n\n const handleTimelineSeekForward = () => {\n if (audioRef.current) {\n const duration = meta.duration_seconds || audioRef.current.duration || 0;\n audioRef.current.currentTime = Math.min(duration, audioRef.current.currentTime + 15);\n }\n };\n\n const handleSetPlaybackRate = (rate) => {\n if (audioRef.current) {\n audioRef.current.playbackRate = rate;\n setPlaybackRate(rate);\n }\n };\n\n // Update currentTimeSeconds from audio element\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const updateTime = () => setCurrentTimeSeconds(audio.currentTime);\n const handlePlay = () => setTimelinePlaying(true);\n const handlePause = () => setTimelinePlaying(false);\n const handleEnded = () => setTimelinePlaying(false);\n\n audio.addEventListener('timeupdate', updateTime);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n audio.addEventListener('ended', handleEnded);\n\n return () => {\n audio.removeEventListener('timeupdate', updateTime);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.removeEventListener('ended', handleEnded);\n };\n }, [audioUrl]);\n\n const playAudio = (startMs, endMs) => {\n const player = audioRef.current;\n if (!player || startMs == null) return;\n\n const startSec = startMs / 1000;\n player.currentTime = startSec;\n setCurrentTimeSeconds(startSec);\n\n const p = player.play();\n if (p !== undefined) p.catch(() => { }); // ignore AbortError when pause() interrupts play()\n\n // Clear any previous segment end handler so only one is active\n if (segmentEndHandlerRef.current) {\n player.removeEventListener('timeupdate', segmentEndHandlerRef.current);\n segmentEndHandlerRef.current = null;\n }\n\n if (endMs != null) {\n const endSec = endMs / 1000;\n const handler = () => {\n if (player.currentTime >= endSec) {\n player.pause();\n if (segmentEndHandlerRef.current) {\n player.removeEventListener('timeupdate', segmentEndHandlerRef.current);\n segmentEndHandlerRef.current = null;\n }\n }\n };\n segmentEndHandlerRef.current = handler;\n player.addEventListener('timeupdate', handler);\n }\n };\n\n // Used by Signals evidence rows: toggle play/pause for a specific segment\n // and scroll the transcript container into view for the related turns.\n const handleEvidencePlayToggle = (startMs, endMs, turnIds) => {\n const player = audioRef.current;\n if (!player || startMs == null) return;\n\n const startSec = startMs / 1000;\n const endSec = endMs != null ? endMs / 1000 : startSec + 1;\n const currentSec = player.currentTime;\n\n const isInSegment =\n timelinePlaying &&\n currentSec >= startSec &&\n (endSec == null || currentSec <= endSec + 0.25);\n\n // If already playing this segment, pause instead of restarting\n if (isInSegment) {\n player.pause();\n return;\n }\n\n // Otherwise, play the requested segment and redirect to transcript\n playAudio(startMs, endMs);\n if (turnIds?.length) {\n highlightTurns(turnIds);\n }\n };\n\n const handleTranscriptTurnPlayPause = (turn, index) => {\n const messages = transcript.messages || [];\n const message = messages[index];\n const player = audioRef.current;\n\n if (!message || !player) return;\n\n const startMs = message.start ?? message.start_ms;\n const endMs = message.end ?? message.end_ms;\n\n // If this turn is already active and playing, pause playback\n if (timelinePlaying && activeTurnIndex === index) {\n player.pause();\n return;\n }\n\n if (startMs == null) return;\n playAudio(startMs, endMs);\n };\n\n const highlightTurns = (turnIds) => {\n setHighlightedTurns(new Set(turnIds));\n // TranscriptCard handles highlight styling via isHighlighted prop\n // Always scroll transcript container into view so highlights are visible\n const container = document.getElementById('transcript-container');\n if (container) {\n container.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n setTimeout(() => setHighlightedTurns(new Set()), 5000);\n };\n\n const toggleSignal = (key) => {\n setExpandedSignals(prev => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key); else next.add(key);\n return next;\n });\n };\n\n const title = ctx.call_purpose?.interaction_driver || summary.one_liner || 'Interaction Detail';\n\n const [rightTab, setRightTab] = useState('signals'); // 'signals' | 'guidance'\n const leftSummaryRef = useRef(null);\n const [rightRailHeight, setRightRailHeight] = useState(null);\n\n // After coaching summary data has loaded and layout has settled,\n // sync right rail height to match ONLY the summary block\n // (InteractionContext + AgentLiftCard + CoachingSummary), not extra padding.\n useLayoutEffect(() => {\n if (coachingLoading) return;\n if (!leftSummaryRef.current) return;\n\n const measure = () => {\n const h = leftSummaryRef.current?.offsetHeight || 0;\n if (h > 0) setRightRailHeight(h);\n };\n\n // Measure immediately and once more on the next frame to catch late layout.\n measure();\n const id = window.requestAnimationFrame(measure);\n return () => window.cancelAnimationFrame(id);\n }, [coachingLoading, coachingData, meta, ctx]);\n\n // MessageThread callbacks.\n // - For gallery: default to console logging\n // - For host apps: pass real handlers via props so APIs are called.\n const handleThreadSend = async (payload) => {\n // payload: { content, parent_message_id }\n if (onThreadSendMessage) {\n await onThreadSendMessage(payload);\n return;\n }\n };\n\n const handleThreadEdit = async (payload) => {\n if (onThreadEditMessage) {\n return onThreadEditMessage(payload);\n }\n };\n\n const handleThreadDelete = async (message) => {\n if (onThreadDeleteMessage) {\n await onThreadDeleteMessage(message);\n return;\n }\n };\n\n const handleCreateNewThread = async (titleText) => {\n if (onThreadCreateNewThread) {\n await onThreadCreateNewThread(titleText);\n return;\n }\n };\n\n // Pass through the host's messageThread as-is. No fallback sample — host apps\n // (e.g. Feedback module) must pass real thread data or leave undefined to show\n // MessageThread's empty state (\"No messages yet\"). Gallery/demos can pass\n // sample data explicitly via the messageThread prop.\n const effectiveMessageThread =\n messageThread && Object.keys(messageThread).length > 0\n ? messageThread\n : undefined;\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: '10px',\n flexWrap: 'wrap',\n }}\n >\n {/* Left rail: context → coaching summary */}\n <div ref={leftSummaryRef}\n style={{\n flex: '1 1 420px',\n minWidth: 320,\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n }}>\n {/* Context — metadata + call purpose + dimensions */}\n <InteractionContext\n title={title}\n meta={meta}\n callPurpose={ctx.call_purpose}\n classification={ctx.classification}\n dimensions={dimensions}\n />\n\n {/* Scores */}\n {/* <InteractionScores scores={scores.scores} /> */}\n\n {/* Agent Lift Analysis */}\n <AgentLiftCard outcomeLift={outcomeLift} />\n\n {/* Coaching Synthesis — only show if loading or has data */}\n {(coachingLoading || coachingData || coachingError) && (\n <DetailCard title=\"Coaching Summary\">\n <CoachingSynthesisCard\n data={coachingData}\n loading={coachingLoading}\n error={coachingError}\n />\n </DetailCard>\n )}\n </div>\n\n {/* Right rail: tabs → InteractionSignals/InteractionGuidance → InteractionNBA */}\n <div\n style={{\n flex: '1 1 420px',\n minWidth: 320,\n display: 'flex',\n flexDirection: 'column',\n height: rightRailHeight,\n }}\n >\n {/* Tabs: Signals / Guidance */}\n <Tabs\n tabs={[\n { key: 'signals', label: 'Signals' },\n { key: 'guidance', label: 'Guidance' },\n ]}\n active={rightTab}\n onSelect={setRightTab}\n size=\"compact\"\n borderTopRightRadius={12}\n borderTopLeftRadius={12}\n />\n\n <div\n className=\"custom-thin-scrollbar-library\"\n style={{\n flex: 1,\n overflowY: 'auto',\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n }}\n >\n {rightTab === 'signals' ? (\n <InteractionSignals\n signals={signals}\n expandedSignals={expandedSignals}\n toggleSignal={toggleSignal}\n playEvidence={handleEvidencePlayToggle}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n highlightTurns={highlightTurns}\n borderRadius={'0px 0px 12px 12px'}\n />\n ) : (\n <InteractionGuidance\n guidance={guidance}\n playEvidence={handleEvidencePlayToggle}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n highlightTurns={highlightTurns}\n borderRadius={'0px 0px 12px 12px'}\n />\n )}\n\n {/* NBA always visible below tabs */}\n <InteractionNBA nba={nba} />\n </div>\n </div>\n </div>\n {/* Recording / Timeline */}\n <InteractionRecording\n audioUrl={audioUrl}\n timelineSegments={timelineSegments}\n durationSeconds={meta.duration_seconds}\n currentTimeSeconds={currentTimeSeconds}\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n onSeek={handleTimelineSeek}\n onTogglePlay={handleTimelineTogglePlay}\n onSeekBack={handleTimelineSeekBack}\n onSeekForward={handleTimelineSeekForward}\n onSetPlaybackRate={handleSetPlaybackRate}\n audioRef={audioRef}\n />\n\n {/* Transcript */}\n <InteractionTranscript\n transcript={transcript}\n audioUrl={audioUrl}\n highlightedTurns={highlightedTurns}\n activeTurnIndex={activeTurnIndex}\n timelinePlaying={timelinePlaying}\n turnObservations={turnObservations}\n setExpandedSignals={setExpandedSignals}\n onTurnPlayPause={handleTranscriptTurnPlayPause}\n />\n\n {/* Message Thread — uses common design-system component.\n For gallery/testing, falls back to a sample payload that matches\n the real backend response shape. */}\n <MessageThread\n sessionTitle={title}\n messageThread={effectiveMessageThread}\n currentUser={threadCurrentUser}\n isLoading={threadLoading}\n onSendMessage={handleThreadSend}\n onEditMessage={handleThreadEdit}\n onDeleteMessage={handleThreadDelete}\n onCreateNewThread={handleCreateNewThread}\n onThreadSelect={onThreadSelect}\n />\n </div>\n );\n}\n\nclass ErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = { hasError: false };\n }\n static getDerivedStateFromError() {\n return { hasError: true };\n }\n componentDidCatch(error, info) {\n console.error('InteractionDetailPanel render error:', error, info?.componentStack);\n }\n render() {\n return this.state.hasError ? this.props.fallback : this.props.children;\n }\n}\n\nexport default function InteractionDetailPanelWrapper(props) {\n return (\n <ErrorBoundary fallback={\n <div style={{ padding: 16, color: 'var(--state-unknown)', fontSize: 12 }}>\n Error rendering detail.\n </div>\n }>\n <InteractionDetailPanel {...props} />\n </ErrorBoundary>\n );\n}","\"use client\";\n\nimport React, { useState } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\n\n/**\n * ExpandPatternComparison Component\n * Demonstrates three different expand/collapse patterns for signal cards.\n */\nexport default function ExpandPatternComparison({ pattern }) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const sampleSignal = {\n name: \"Customer Escalation Likelihood\",\n description:\n \"Based on observed patterns, this session shows indicators consistent with potential escalation.\",\n technicalKey: \"signal.escalation_likelihood\",\n probability: 0.68,\n confidence: 0.81,\n observations: 3,\n };\n\n if (pattern === \"text-link\") {\n return (\n <div\n style={{\n position: \"relative\",\n background: \"rgba(255, 255, 255, 0.82)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 2px 4px rgba(30, 33, 37, 0.06)\",\n }}\n >\n {/* Left rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"5px\",\n background: \"#6B7C93\",\n opacity: 0.6,\n }}\n />\n\n {/* Content - not clickable */}\n <div\n style={{\n padding: \"14px 16px 14px 21px\",\n }}\n >\n <div style={{ marginBottom: \"4px\" }}>\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 680,\n color: \"rgba(30, 33, 37, 0.92)\",\n lineHeight: 1.2,\n }}\n >\n {sampleSignal.name}\n </span>\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.65)\",\n lineHeight: 1.4,\n marginBottom: \"6px\",\n }}\n >\n {sampleSignal.description}\n </div>\n <div\n style={{\n fontSize: \"11px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n fontFamily: \"ui-monospace, monospace\",\n marginBottom: \"8px\",\n }}\n >\n {sampleSignal.technicalKey}\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n fontSize: \"11.5px\",\n marginBottom: \"10px\",\n }}\n >\n <span style={{ color: \"rgba(139, 157, 127, 0.65)\" }}>prob</span>\n <strong style={{ color: \"rgba(139, 157, 127, 0.85)\" }}>\n {sampleSignal.probability.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(184, 156, 106, 0.65)\" }}>conf</span>\n <strong style={{ color: \"rgba(184, 156, 106, 0.85)\" }}>\n {sampleSignal.confidence.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(30, 33, 37, 0.52)\" }}>\n {sampleSignal.observations} observations\n </span>\n </div>\n\n {/* Text link to expand */}\n {!isExpanded && (\n <button\n onClick={() => setIsExpanded(true)}\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.56)\",\n background: \"none\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n textDecoration: \"underline\",\n textDecorationColor: \"rgba(30, 33, 37, 0.2)\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.78)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.4)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.56)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.2)\";\n }}\n >\n View contributing observations\n </button>\n )}\n </div>\n\n {/* Expanded content */}\n {isExpanded && (\n <div\n style={{\n borderTop: \"1px solid rgba(52, 58, 64, 0.08)\",\n background: \"rgba(244, 241, 230, 0.25)\",\n padding: \"16px 16px 16px 21px\",\n }}\n >\n <div\n style={{\n fontSize: \"10px\",\n fontWeight: 650,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: \"rgba(30, 33, 37, 0.52)\",\n marginBottom: \"8px\",\n }}\n >\n Contributing Observations\n </div>\n <div style={{ fontSize: \"12px\", color: \"rgba(30, 33, 37, 0.62)\" }}>\n [Observations would appear here]\n </div>\n <button\n onClick={() => setIsExpanded(false)}\n style={{\n marginTop: \"10px\",\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.56)\",\n background: \"none\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n textDecoration: \"underline\",\n textDecorationColor: \"rgba(30, 33, 37, 0.2)\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.78)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.4)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = \"rgba(30, 33, 37, 0.56)\";\n e.currentTarget.style.textDecorationColor =\n \"rgba(30, 33, 37, 0.2)\";\n }}\n >\n Hide observations\n </button>\n </div>\n )}\n </div>\n );\n }\n\n if (pattern === \"rotating-chevron\") {\n return (\n <div\n style={{\n position: \"relative\",\n background: \"rgba(255, 255, 255, 0.82)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 2px 4px rgba(30, 33, 37, 0.06)\",\n }}\n >\n {/* Left rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"5px\",\n background: \"#6B7C93\",\n opacity: 0.6,\n }}\n />\n\n {/* Header - Clickable */}\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n width: \"100%\",\n padding: \"14px 16px 14px 21px\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n textAlign: \"left\",\n transition: \"background 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"rgba(231, 212, 162, 0.08)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"flex-start\", gap: \"12px\" }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ marginBottom: \"4px\" }}>\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 680,\n color: \"rgba(30, 33, 37, 0.92)\",\n lineHeight: 1.2,\n }}\n >\n {sampleSignal.name}\n </span>\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.65)\",\n lineHeight: 1.4,\n marginBottom: \"6px\",\n }}\n >\n {sampleSignal.description}\n </div>\n <div\n style={{\n fontSize: \"11px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n fontFamily: \"ui-monospace, monospace\",\n marginBottom: \"8px\",\n }}\n >\n {sampleSignal.technicalKey}\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n fontSize: \"11.5px\",\n }}\n >\n <span style={{ color: \"rgba(139, 157, 127, 0.65)\" }}>prob</span>\n <strong style={{ color: \"rgba(139, 157, 127, 0.85)\" }}>\n {sampleSignal.probability.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(184, 156, 106, 0.65)\" }}>conf</span>\n <strong style={{ color: \"rgba(184, 156, 106, 0.85)\" }}>\n {sampleSignal.confidence.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(30, 33, 37, 0.52)\" }}>\n {sampleSignal.observations} observations\n </span>\n </div>\n </div>\n\n {/* Rotating chevron on right */}\n <div\n style={{\n paddingTop: \"2px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n flexShrink: 0,\n transition: \"transform 0.2s ease\",\n }}\n >\n <ChevronDown\n size={18}\n style={{\n transform: isExpanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.2s ease\",\n }}\n />\n </div>\n </div>\n </button>\n\n {/* Expanded content */}\n {isExpanded && (\n <div\n style={{\n borderTop: \"1px solid rgba(52, 58, 64, 0.08)\",\n background: \"rgba(244, 241, 230, 0.25)\",\n padding: \"16px 16px 16px 21px\",\n }}\n >\n <div\n style={{\n fontSize: \"10px\",\n fontWeight: 650,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: \"rgba(30, 33, 37, 0.52)\",\n marginBottom: \"8px\",\n }}\n >\n Contributing Observations\n </div>\n <div style={{ fontSize: \"12px\", color: \"rgba(30, 33, 37, 0.62)\" }}>\n [Observations would appear here]\n </div>\n </div>\n )}\n </div>\n );\n }\n\n // directional-chevron (current SignalCard pattern)\n return (\n <div\n style={{\n position: \"relative\",\n background: \"rgba(255, 255, 255, 0.82)\",\n border: \"1px solid rgba(52, 58, 64, 0.12)\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 2px 4px rgba(30, 33, 37, 0.06)\",\n }}\n >\n {/* Left rail */}\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: \"5px\",\n background: \"#6B7C93\",\n opacity: 0.6,\n }}\n />\n\n {/* Header - Clickable */}\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n width: \"100%\",\n padding: \"14px 16px 14px 21px\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n textAlign: \"left\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"12px\",\n transition: \"background 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"rgba(231, 212, 162, 0.08)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n {/* Directional chevron on left */}\n <div\n style={{\n paddingTop: \"2px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n flexShrink: 0,\n }}\n >\n {isExpanded ? (\n <ChevronDown size={16} />\n ) : (\n <ChevronRight size={16} />\n )}\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ marginBottom: \"4px\" }}>\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 680,\n color: \"rgba(30, 33, 37, 0.92)\",\n lineHeight: 1.2,\n }}\n >\n {sampleSignal.name}\n </span>\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"rgba(30, 33, 37, 0.65)\",\n lineHeight: 1.4,\n marginBottom: \"6px\",\n }}\n >\n {sampleSignal.description}\n </div>\n <div\n style={{\n fontSize: \"11px\",\n color: \"rgba(30, 33, 37, 0.42)\",\n fontFamily: \"ui-monospace, monospace\",\n marginBottom: \"8px\",\n }}\n >\n {sampleSignal.technicalKey}\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n fontSize: \"11.5px\",\n }}\n >\n <span style={{ color: \"rgba(139, 157, 127, 0.65)\" }}>prob</span>\n <strong style={{ color: \"rgba(139, 157, 127, 0.85)\" }}>\n {sampleSignal.probability.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(184, 156, 106, 0.65)\" }}>conf</span>\n <strong style={{ color: \"rgba(184, 156, 106, 0.85)\" }}>\n {sampleSignal.confidence.toFixed(2)}\n </strong>\n <span style={{ color: \"rgba(30, 33, 37, 0.24)\" }}>·</span>\n <span style={{ color: \"rgba(30, 33, 37, 0.52)\" }}>\n {sampleSignal.observations} observations\n </span>\n </div>\n </div>\n </button>\n\n {/* Expanded content */}\n {isExpanded && (\n <div\n style={{\n borderTop: \"1px solid rgba(52, 58, 64, 0.08)\",\n background: \"rgba(244, 241, 230, 0.25)\",\n padding: \"16px 16px 16px 21px\",\n }}\n >\n <div\n style={{\n fontSize: \"10px\",\n fontWeight: 650,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: \"rgba(30, 33, 37, 0.52)\",\n marginBottom: \"8px\",\n }}\n >\n Contributing Observations\n </div>\n <div style={{ fontSize: \"12px\", color: \"rgba(30, 33, 37, 0.62)\" }}>\n [Observations would appear here]\n </div>\n </div>\n )}\n </div>\n );\n}\n\n"],"names":["STYLE_ID","ensureKeyframes","style","CoachingSynthesisCard","data","loading","error","React","jsxs","jsx","w","i","strengths","improvements","organizational","oneLiner","_a","context","_b","CoachingSection","TrendingUp","Lightbulb","Building","icon","label","color","items","item","text","quote","MessageSquareQuote","fmtDur","seconds","m","InteractionContext","title","meta","callPurpose","classification","dimensions","cp","cls","CardBase","dim","InteractionScores","scores","DetailCard","s","val","GROUP_LABELS","Target","FileText","Scale","Zap","MessageSquare","KIND_COLORS","CheckCircle","InteractionSignals","signals","expandedSignals","toggleSignal","playEvidence","timelinePlaying","currentTimeSeconds","highlightTurns","borderRadius","grouped","useMemo","result","g","groupKey","groupSignals","info","SectionLabel","name","delta","hasObs","isExpanded","e","ChevronDown","obs","oi","ev","ei","startMs","endMs","isPlayingSegment","startSec","endSec","cs","EvidenceItem","InteractionGuidance","guidance","ki","ownerBadge","sr","si","CornerDownRight","sMs","eMs","InteractionNBA","nba","r","InteractionRecording","audioUrl","timelineSegments","durationSeconds","playbackRate","onSeek","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","audioRef","Timeline","InteractionTranscript","transcript","highlightedTurns","activeTurnIndex","turnObservations","setExpandedSignals","onTurnPlayPause","formatTimeRange","formatTime","ms","minutes","start","end","turns","prev","el","TranscriptCard","messageActionButtonStyle","roleColorMap","role","normalized","extractMessagesArray","node","directCandidates","candidate","flattenMessages","rawMessages","parentId","startIndex","out","index","author","authorName","initials","n","roleColor","id","baseMessage","formatTimestamp","value","d","now","sameDay","yesterday","isYesterday","timeStr","diffDays","MessageThread","sessionTitle","sessionSubtitle","threadLabel","initialMessages","messageThread","onSendMessage","onReplyMessage","onEditMessage","onDeleteMessage","onCreateNewThread","onThreadSelect","currentUser","isLoading","messageInput","setMessageInput","useState","isFocused","setIsFocused","messages","setMessages","isSending","setIsSending","hoveredMessageId","setHoveredMessageId","threads","setThreads","activeThreadId","setActiveThreadId","replyingToMessageId","setReplyingToMessageId","replyDraft","setReplyDraft","editingMessageId","setEditingMessageId","editContent","setEditContent","deleteConfirmMessage","setDeleteConfirmMessage","showNewThreadCompose","setShowNewThreadCompose","newThreadInput","setNewThreadInput","isCreatingNewThread","setIsCreatingNewThread","expandedParentIds","setExpandedParentIds","messagesEndRef","useRef","messageInputRef","normalizedRole","displayCurrentUser","canCreateNewThread","childrenByParentId","map","topLevelMessages","isChildReply","isChildEdit","hasHeader","replyingToMessage","useEffect","rawThreads","normalizedThreads","t","rawMessagesForThread","messagesForThread","firstWithMessages","flatMessages","rawFlat","mappedMessages","singleId","singleLabel","thread","container","handleNewThreadSubmit","trimmed","newId","handleNewThreadCancel","handleSend","content","optimisticId","optimisticMessage","msg","handleKeyPress","handleReplyClick","message","handleInlineReplySend","parentMessageId","optimisticReply","handleEditClick","handleEditSubmit","err","handleEditCancel","handleDeleteClick","handleDeleteConfirm","renderMessageTree","depth","children","hasChildren","isEditing","isReplying","Clock","next","ChevronRight","child","isActive","Fragment","Send","findBlock","blocks","b","InteractionDetailPanel","coachingData","coachingLoading","coachingError","onThreadSendMessage","onThreadEditMessage","onThreadDeleteMessage","onThreadCreateNewThread","threadLoading","threadCurrentUser","segmentEndHandlerRef","setHighlightedTurns","setCurrentTimeSeconds","setTimelinePlaying","setPlaybackRate","ctx","summary","_c","_d","_e","_f","_g","_h","_i","outcomeLift","_j","signal","groupInfo","tid","o","_k","startTime","endTime","isAgent","actorName","currentMs","handleTimelineSeek","handleTimelineTogglePlay","p","handleTimelineSeekBack","handleTimelineSeekForward","duration","handleSetPlaybackRate","rate","audio","updateTime","handlePlay","handlePause","handleEnded","playAudio","player","handler","handleEvidencePlayToggle","turnIds","currentSec","handleTranscriptTurnPlayPause","turn","key","_l","rightTab","setRightTab","leftSummaryRef","rightRailHeight","setRightRailHeight","useLayoutEffect","measure","h","handleThreadSend","payload","handleThreadEdit","handleThreadDelete","handleCreateNewThread","titleText","effectiveMessageThread","AgentLiftCard","Tabs","ErrorBoundary","props","InteractionDetailPanelWrapper","ExpandPatternComparison","pattern","setIsExpanded","sampleSignal"],"mappings":"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"}