@ai-matrx/office 0.8.64 → 0.8.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pdf.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pdf/index.ts","../src/pdf/PdfWorkspace.tsx","../src/pdf/page-decisions.ts","../src/pdf/left-panel.tsx","../src/pdf/panels.tsx","../src/pdf/session-history.ts","../src/pdf/markup.ts","../src/pdf/tools.ts","../src/pdf/shortcuts.ts","../src/pdf/markup-panel.tsx","../src/pdf/tool-icons.tsx"],"sourcesContent":["export { PdfWorkspace, type PdfWorkspaceProps } from \"./PdfWorkspace\";\nexport type { PdfViewerState, PdfWorkspaceHost } from \"./model\";\nexport * from \"./model\";\n","\"use client\";\n\n/**\n * PdfWorkspace — the Acrobat-style shell for one PDF: top bar (name, save state, tools search, undo,\n * share, download, print), tools rail, page panel (thumbnails, layers), the windowed viewer in the\n * middle, a properties panel on the right, a find bar, a keyboard map and a reading mode.\n *\n * The package owns the chrome and the session (page decisions with undo/redo, zoom, selection). The\n * host injects the viewer and every server call through `PdfWorkspaceHost`. Overlays (find, print,\n * shortcuts, tool search, sheets) are absolutely positioned inside the shell, so opening one never\n * moves the page; every bar has a fixed height and every panel a fixed width.\n */\nimport { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { Button, Field, PageRangeInput, SegmentedControl, Tile, ToolRail, parsePageRanges, type ToolRailItem } from \"@ai-matrx/design-system/controls\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DownloadIcon,\n KeyboardIcon,\n MinusIcon,\n MoreHorizontalIcon,\n PanelLeftIcon,\n PanelRightIcon,\n PlusIcon,\n PrinterIcon,\n RotateCcwIcon,\n RotateCwIcon,\n SearchIcon,\n Share2Icon,\n Trash2Icon,\n Undo2Icon,\n XIcon,\n Columns2Icon,\n ExpandIcon,\n} from \"@ai-matrx/design-system/icons\";\nimport { RenderedFindBar } from \"@ai-matrx/rich-content/rich-document/search/RenderedFindBar\";\nimport { compilePageOps, deletePages, freshDecisions, isDirty, reorderPages, restorePages, turnPages, type PageDecisions } from \"./page-decisions\";\nimport { LeftPanel, type LeftTab } from \"./left-panel\";\nimport { ToolPanel } from \"./panels\";\nimport type { PdfHostTool, PdfRunRequest, PdfRunResult, PdfWorkspaceHost } from \"./ports\";\nimport { canRedo, canUndo, pushStep, redo, redoLabel, startHistory, undo, undoLabel, type History } from \"./session-history\";\nimport { PDF_MARKUP_SHORTCUTS, PDF_SHORTCUTS, formatKeys, matchMarkupKey, matchShortcut, type PdfActionId } from \"./shortcuts\";\nimport { MarkupFloatingToolbar, MarkupPanel } from \"./markup-panel\";\nimport { dropOrigin, emptyTimeline, markupRedoneElsewhere, markupUndoneElsewhere, nextRedo, nextUndo, pdfMarkupTool, recordStep, stepBack, stepForward, type PdfMarkupToolId, type SessionTimeline } from \"./markup\";\nimport type { PdfMarkupEngine, PdfMarkupSnapshot } from \"./markup-engine-port\";\nimport { PDF_TOOL_ICONS } from \"./tool-icons\";\nimport { PDF_TOOLS, comingSoonIdOf, pdfTool, type PdfToolDef, type PdfToolId } from \"./tools\";\n\nconst ZOOM_STEPS = [0.5, 0.75, 1, 1.25, 1.5, 2, 3] as const;\nconst COMPACT_BELOW_PX = 768;\nconst BAR = \"flex h-10 shrink-0 items-center gap-1 border-b border-border bg-background px-2\";\n\ntype ZoomMode = \"fit-width\" | \"fit-page\" | \"custom\";\ntype Sheet = \"tools\" | \"pages\" | null;\ntype Pop = \"print\" | \"shortcuts\" | \"tool-search\" | \"all-tools\" | null;\nconst ALL_TOOLS = \"all-tools\";\n\nconst isMac = () => typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\nconst clampZoom = (z: number) => Math.min(3, Math.max(0.5, z));\n\nasync function announceSoon(id: string) {\n const { announceComingSoon } = await import(\"@ai-matrx/kit/coming-soon\");\n await announceComingSoon(id);\n}\n\nfunction useWidth(ref: React.RefObject<HTMLElement | null>) {\n const [size, setSize] = useState({ w: 1200, h: 800 });\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) return undefined;\n const measure = () => setSize({ w: node.clientWidth || 1200, h: node.clientHeight || 800 });\n measure();\n if (typeof ResizeObserver === \"undefined\") return undefined;\n const ro = new ResizeObserver(measure);\n ro.observe(node);\n return () => ro.disconnect();\n }, [ref]);\n return size;\n}\n\n/** The tool list shared by the \"All tools\" menu and the phone sheet: a glyph, the name, and \"Coming soon\" where it is not built. */\nfunction ToolRows({ tool, hostTools, onPick, canMarkup = false }: { tool: string; hostTools: readonly PdfHostTool[]; onPick(id: string): void; canMarkup?: boolean }) {\n return (\n <>\n {hostTools.map((t) => (\n <li key={`host:${t.id}`} role=\"none\">\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n role=\"menuitem\"\n aria-current={tool === `host:${t.id}` ? \"true\" : undefined}\n title={t.label}\n icon={<t.icon />}\n className=\"w-full\"\n onClick={() => onPick(`host:${t.id}`)}\n />\n </li>\n ))}\n {PDF_TOOLS.filter((t) => t.id !== \"browse\" && (t.id !== \"markup\" || canMarkup)).map((t) => {\n const Icon = PDF_TOOL_ICONS[t.id];\n return (\n <li key={t.id} role=\"none\">\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n role=\"menuitem\"\n aria-current={t.id === tool ? \"true\" : undefined}\n title={t.label}\n icon={<Icon />}\n end={t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : undefined}\n className=\"w-full\"\n onClick={() => onPick(t.id)}\n />\n </li>\n );\n })}\n </>\n );\n}\n\nexport interface PdfWorkspaceProps {\n host: PdfWorkspaceHost;\n className?: string;\n}\n\nexport function PdfWorkspace({ host, className }: PdfWorkspaceProps) {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const scrollerRef = useRef<HTMLDivElement | null>(null);\n const rootSize = useWidth(rootRef);\n const viewSize = useWidth(scrollerRef);\n const compact = rootSize.w < COMPACT_BELOW_PX;\n const online = host.online !== false;\n\n const [pageCount, setPageCount] = useState(0);\n const [history, setHistory] = useState<History<PageDecisions>>(() => startHistory(freshDecisions(0)));\n const decisions = history.present.value;\n const dirty = isDirty(decisions);\n const [tool, setTool] = useState<PdfToolId>(\"browse\");\n const [hostToolId, setHostToolId] = useState<string | null>(null);\n const hostTools = useMemo<readonly PdfHostTool[]>(() => host.tools ?? [], [host.tools]);\n const hostTool = hostToolId ? hostTools.find((t) => t.id === hostToolId) ?? null : null;\n const activeToolKey = hostTool ? `host:${hostTool.id}` : tool;\n const [leftOpen, setLeftOpen] = useState(true);\n const [rightOpen, setRightOpen] = useState(true);\n const [leftTab, setLeftTab] = useState<LeftTab>(\"pages\");\n const [read, setRead] = useState(false);\n const [spread, setSpread] = useState<\"single\" | \"two-up\">(\"single\");\n const [zoomMode, setZoomMode] = useState<ZoomMode>(\"fit-width\");\n const [customZoom, setCustomZoom] = useState(1);\n const [selected, setSelected] = useState<string[]>([]);\n const [currentPage, setCurrentPage] = useState(1);\n const [pageDraft, setPageDraft] = useState(\"1\");\n const [findOpen, setFindOpen] = useState(false);\n const [findFocus, setFindFocus] = useState(0);\n const [pop, setPop] = useState<Pop>(null);\n const [sheet, setSheet] = useState<Sheet>(null);\n const [toolQuery, setToolQuery] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<PdfRunResult | null>(null);\n const [reloadKey, setReloadKey] = useState(0);\n const [sizeVersion, setSizeVersion] = useState(0);\n const sizes = useRef(new Map<number, { w: number; h: number }>());\n const [editingName, setEditingName] = useState(false);\n const [nameDraft, setNameDraft] = useState(host.file.name);\n const [printMode, setPrintMode] = useState<\"all\" | \"pages\">(\"all\");\n const [printRange, setPrintRange] = useState(\"\");\n // ── markup: PDF.js's editors in the viewer, one history with the page decisions ──\n const canMarkup = Boolean(host.saveMarkup);\n const [engine, setEngine] = useState<PdfMarkupEngine | null>(null);\n const [snap, setSnap] = useState<PdfMarkupSnapshot | null>(null);\n const [timeline, setTimeline] = useState<SessionTimeline>(emptyTimeline);\n const [markupTool, setMarkupTool] = useState<PdfMarkupToolId>(\"highlight\");\n const [markupBusy, setMarkupBusy] = useState(false);\n const [markupError, setMarkupError] = useState<string | null>(null);\n const markupPending = snap?.pending ?? 0;\n\n const selectedPages = useMemo(() => selected.map(Number).sort((a, b) => a - b), [selected]);\n const toolDef = pdfTool(tool) as PdfToolDef;\n\n // ── zoom ────────────────────────────────────────────────────────────────\n const first = sizes.current.get(1);\n const fitPage = useMemo(() => {\n void sizeVersion;\n if (!first) return 1;\n const ratio = first.h / first.w;\n const cols = spread === \"two-up\" ? 2 : 1;\n const availH = Math.max(120, viewSize.h - 32);\n return clampZoom((availH * cols) / (Math.max(1, viewSize.w) * ratio) );\n }, [first, spread, viewSize.h, viewSize.w, sizeVersion]);\n const zoom = zoomMode === \"fit-width\" ? 1 : zoomMode === \"fit-page\" ? fitPage : customZoom;\n const stepZoom = useCallback(\n (dir: 1 | -1) => {\n const cur = zoomMode === \"fit-width\" ? 1 : zoomMode === \"fit-page\" ? fitPage : customZoom;\n const next = dir > 0 ? ZOOM_STEPS.find((s) => s > cur + 0.01) : [...ZOOM_STEPS].reverse().find((s) => s < cur - 0.01);\n if (next === undefined) return;\n setCustomZoom(next);\n setZoomMode(\"custom\");\n },\n [zoomMode, fitPage, customZoom],\n );\n\n // ── pages ───────────────────────────────────────────────────────────────\n const goToPage = useCallback(\n (n: number) => {\n const page = Math.min(Math.max(1, Math.round(n)), Math.max(1, pageCount));\n setCurrentPage(page);\n setPageDraft(String(page));\n const el = scrollerRef.current?.querySelector<HTMLElement>(`[data-pdf-page=\"${page}\"]`);\n el?.scrollIntoView?.({ block: \"start\" });\n },\n [pageCount],\n );\n useEffect(() => {\n const node = scrollerRef.current;\n if (!node) return undefined;\n let raf = 0;\n const onScroll = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const top = node.getBoundingClientRect().top + 8;\n const els = node.querySelectorAll<HTMLElement>(\"[data-pdf-page]\");\n let lo = 0;\n let hi = els.length - 1;\n // Pages are in reading order: the current page is the last one whose top is above the view's top.\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (els[mid]!.getBoundingClientRect().top <= top) lo = mid;\n else hi = mid - 1;\n }\n const n = Number(els[lo]?.dataset.pdfPage ?? 1);\n setCurrentPage((prev) => (prev === n ? prev : n));\n setPageDraft(String(n));\n });\n };\n node.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => {\n node.removeEventListener(\"scroll\", onScroll);\n cancelAnimationFrame(raf);\n };\n }, [pageCount]);\n\n // ── decisions and the session stack ─────────────────────────────────────\n const commit = useCallback((label: string, next: PageDecisions) => {\n setHistory((h) => pushStep(h, label, next));\n setTimeline((t) => recordStep(t, \"page\", label));\n }, []);\n const targets = useCallback(() => (selectedPages.length ? selectedPages : [currentPage]), [selectedPages, currentPage]);\n const turn = useCallback(\n (by: 90 | -90) => {\n const t = targets();\n commit(`Rotate ${t.length === 1 ? `page ${t[0]}` : `${t.length} pages`}`, turnPages(decisions, t, by));\n },\n [targets, commit, decisions],\n );\n const del = useCallback(() => {\n const t = targets();\n commit(`Delete ${t.length === 1 ? `page ${t[0]}` : `${t.length} pages`}`, deletePages(decisions, t));\n }, [targets, commit, decisions]);\n const restore = useCallback(() => {\n const t = targets();\n commit(`Restore ${t.length === 1 ? `page ${t[0]}` : `${t.length} pages`}`, restorePages(decisions, t));\n }, [targets, commit, decisions]);\n\n const onDocumentLoad = useCallback((n: number) => {\n setPageCount(n);\n setHistory((h) => (h.present.value.order.length === n ? h : startHistory(freshDecisions(n))));\n }, []);\n const onPageSize = useCallback((page: number, w: number, h: number) => {\n const prev = sizes.current.get(page);\n if (prev && prev.w === w && prev.h === h) return;\n sizes.current.set(page, { w, h });\n // The viewer reports sizes while it renders: never set state in that call stack.\n if (page === 1) queueMicrotask(() => setSizeVersion((v) => v + 1));\n }, []);\n\n // ── running things on the server ────────────────────────────────────────\n const fail = useCallback(\n (e: unknown) => {\n const message = e instanceof Error ? e.message : \"That did not work.\";\n setError(message);\n host.notify?.(message, \"error\");\n },\n [host],\n );\n const runTool = useCallback(\n async (request: PdfRunRequest) => {\n if (!online) {\n setError(\"You are offline. Changes are not queued; try again when you are back online.\");\n return;\n }\n setBusy(true);\n setError(null);\n setResult(null);\n try {\n const out = await host.run(request);\n setResult(out);\n if (out.kind === \"replaced\") {\n setHistory(startHistory(freshDecisions(pageCount)));\n setSelected([]);\n sizes.current.clear();\n setReloadKey((k) => k + 1);\n }\n } catch (e) {\n fail(e);\n } finally {\n setBusy(false);\n }\n },\n [host, online, pageCount, fail],\n );\n const apply = useCallback(() => {\n const ops = compilePageOps(decisions);\n if (!ops.length) return;\n if (markupPending) {\n setError(\"Save or discard your markup first: applying page changes reloads the file.\");\n return;\n }\n setTimeline((t) => dropOrigin(t, \"page\"));\n void runTool({ tool: \"apply-pages\", ops });\n }, [decisions, runTool, markupPending]);\n const discard = useCallback(() => {\n setHistory(startHistory(freshDecisions(pageCount)));\n setTimeline((t) => dropOrigin(t, \"page\"));\n }, [pageCount]);\n\n // ── markup session ──────────────────────────────────────────────────────\n const onMarkupEngine = useCallback((e: PdfMarkupEngine | null) => {\n setEngine(e);\n setSnap(e ? e.getSnapshot() : null);\n }, []);\n useEffect(() => {\n if (!engine) return undefined;\n const offSnap = engine.subscribe(setSnap);\n const offHistory = engine.onHistory((ev) => {\n if (ev.type === \"step\") setTimeline((t) => recordStep(t, \"markup\", ev.label));\n else if (ev.external) setTimeline((t) => (ev.type === \"undo\" ? markupUndoneElsewhere(t) : markupRedoneElsewhere(t)));\n });\n return () => { offSnap(); offHistory(); };\n }, [engine]);\n // The editors follow the tool: on while \"Comment and mark up\" is open, off (markup still shown) otherwise.\n const markupOn = tool === \"markup\" && !hostTool && !dirty;\n const markupEngineTool = pdfMarkupTool(markupTool)?.engineTool ?? \"highlight\";\n useEffect(() => {\n if (engine) void engine.setTool(markupOn ? markupEngineTool : \"none\");\n }, [engine, markupOn, markupEngineTool]);\n useEffect(() => { engine?.setCurrentPage(currentPage); }, [engine, currentPage]);\n const saveMarkup = useCallback(async () => {\n if (!engine || !host.saveMarkup || !markupPending || markupBusy) return;\n if (!online) {\n setMarkupError(\"You are offline. Your markup is kept here; save when you are back online.\");\n return;\n }\n setMarkupBusy(true);\n setMarkupError(null);\n try {\n const summary = engine.getSnapshot().summary;\n const bytes = await engine.save();\n const out = await host.saveMarkup(bytes, summary);\n setResult(out);\n setTimeline((t) => dropOrigin(t, \"markup\"));\n sizes.current.clear();\n setReloadKey((k) => k + 1);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"The markup was not saved.\";\n setMarkupError(message);\n host.notify?.(message, \"error\");\n } finally {\n setMarkupBusy(false);\n }\n }, [engine, host, markupPending, markupBusy, online]);\n const discardMarkup = useCallback(() => {\n // The editors live on the open document: opening it again drops every unsaved piece.\n setTimeline((t) => dropOrigin(t, \"markup\"));\n setMarkupError(null);\n setReloadKey((k) => k + 1);\n }, []);\n // Leaving the page with unsaved markup asks first (the deck autosave's guard; markup is never saved silently).\n useEffect(() => {\n if (!markupPending) return undefined;\n const onBeforeUnload = (event: BeforeUnloadEvent) => {\n event.preventDefault();\n event.returnValue = \"\";\n };\n window.addEventListener(\"beforeunload\", onBeforeUnload);\n return () => window.removeEventListener(\"beforeunload\", onBeforeUnload);\n }, [markupPending]);\n const undoAll = useCallback(() => {\n const step = nextUndo(timeline);\n if (step?.origin === \"markup\" && engine) {\n setTimeline(stepBack);\n engine.undo();\n return;\n }\n if (step) setTimeline(stepBack);\n setHistory((h) => undo(h));\n }, [timeline, engine]);\n const redoAll = useCallback(() => {\n const step = nextRedo(timeline);\n if (step?.origin === \"markup\" && engine) {\n setTimeline(stepForward);\n engine.redo();\n return;\n }\n if (step) setTimeline(stepForward);\n setHistory((h) => redo(h));\n }, [timeline, engine]);\n const undoStep = nextUndo(timeline);\n const redoStep = nextRedo(timeline);\n const undoText = undoStep ? `Undo ${undoStep.label}` : undoLabel(history) ? `Undo ${undoLabel(history)}` : \"Undo\";\n const redoText = redoStep ? `Redo ${redoStep.label}` : redoLabel(history) ? `Redo ${redoLabel(history)}` : \"Redo\";\n const canUndoAll = Boolean(undoStep) || canUndo(history);\n const canRedoAll = Boolean(redoStep) || canRedo(history);\n\n // ── tools ───────────────────────────────────────────────────────────────\n const chooseTool = useCallback(\n (id: string) => {\n if (id.startsWith(\"host:\")) {\n setHostToolId(id.slice(5));\n setResult(null);\n setError(null);\n setRightOpen(true);\n if (compact) setSheet(\"tools\");\n return;\n }\n const def = pdfTool(id);\n if (!def || (def.id === \"markup\" && !host.saveMarkup)) return;\n setHostToolId(null);\n if (def.status === \"soon\") {\n announceSoon(comingSoonIdOf(def.id)).catch(fail);\n return;\n }\n if (def.opens === \"page\") {\n host.openTool(def.id === \"scan\" ? \"scan\" : \"sign\");\n return;\n }\n setTool(def.id);\n setResult(null);\n setError(null);\n setRightOpen(true);\n if (compact) setSheet(\"tools\");\n },\n [host, compact, fail],\n );\n const railGroups = useMemo<ToolRailItem[][]>(() => {\n // The rail holds the tools that work today; the ones not built yet live in \"All tools\", marked as coming soon.\n const groups: ToolRailItem[][] = [[], [], []];\n for (const t of PDF_TOOLS) {\n if (t.status !== \"ready\" || (t.id === \"markup\" && !canMarkup)) continue;\n groups[t.group]!.push({ id: t.id, label: t.label, icon: PDF_TOOL_ICONS[t.id], ...(t.key ? { shortcut: t.key.toUpperCase() } : null) });\n }\n for (const t of hostTools) groups[t.group ?? 1]!.push({ id: `host:${t.id}`, label: t.label, icon: t.icon });\n groups[2]!.push({ id: ALL_TOOLS, label: \"All tools\", icon: MoreHorizontalIcon });\n return groups.filter((g) => g.length);\n }, [hostTools, canMarkup]);\n\n // ── actions and the one key handler ─────────────────────────────────────\n const runAction = useCallback(\n (action: PdfActionId) => {\n if (action.startsWith(\"tool:\")) return chooseTool(action.slice(5));\n switch (action) {\n case \"undo\": return undoAll();\n case \"redo\": return redoAll();\n case \"save\": return markupPending ? void saveMarkup() : apply();\n case \"find\": setFindOpen(true); setFindFocus((n) => n + 1); return;\n case \"print\": return host.print ? setPop(\"print\") : undefined;\n case \"zoom-in\": return stepZoom(1);\n case \"zoom-out\": return stepZoom(-1);\n case \"zoom-fit-width\": return setZoomMode(\"fit-width\");\n case \"zoom-fit-page\": return setZoomMode(\"fit-page\");\n case \"page-next\": return goToPage(currentPage + 1);\n case \"page-prev\": return goToPage(currentPage - 1);\n case \"page-first\": return goToPage(1);\n case \"page-last\": return goToPage(pageCount);\n case \"rotate-right\": return turn(90);\n case \"rotate-left\": return turn(-90);\n case \"delete-pages\": return del();\n case \"select-all-pages\": return setSelected(decisions.order.map(String));\n case \"toggle-pages\": return setLeftOpen((v) => !v);\n case \"toggle-properties\": return setRightOpen((v) => !v);\n case \"read-mode\": return setRead((v) => !v);\n case \"two-up\": return setSpread((s) => (s === \"two-up\" ? \"single\" : \"two-up\"));\n case \"shortcuts\": return setPop((p) => (p === \"shortcuts\" ? null : \"shortcuts\"));\n default: return undefined;\n }\n },\n [chooseTool, apply, host.print, stepZoom, goToPage, currentPage, pageCount, turn, del, decisions.order, undoAll, redoAll, markupPending, saveMarkup],\n );\n const onKeyDown = (e: React.KeyboardEvent) => {\n const t = e.target as HTMLElement;\n const typing = t.tagName === \"INPUT\" || t.tagName === \"TEXTAREA\" || t.tagName === \"SELECT\" || t.isContentEditable;\n if (e.key === \"Escape\") {\n if (pop) setPop(null);\n else if (findOpen) setFindOpen(false);\n else if (read) setRead(false);\n else if (sheet) setSheet(null);\n return;\n }\n if (markupOn) {\n // Markup open: its letters pick a tool; Delete, arrows, Escape and Select all belong to the selected markup (PDF.js handles them).\n const pick = matchMarkupKey(e.nativeEvent, typing);\n if (pick && pdfMarkupTool(pick)?.status === \"ready\" && (pick !== \"signature\" || host.signaturePad)) {\n e.preventDefault();\n setMarkupTool(pick);\n return;\n }\n }\n const action = matchShortcut(e.nativeEvent, typing);\n if (!action) return;\n if (markupOn && t.closest(\"[data-pdf-thumbnails]\") === null && (action === \"delete-pages\" || action === \"page-next\" || action === \"page-prev\" || action === \"select-all-pages\")) return;\n // Arrow keys page the document only when focus is on the canvas, never on a control.\n if ((action === \"page-next\" || action === \"page-prev\") && t !== scrollerRef.current && t !== rootRef.current) return;\n if (action === \"delete-pages\" && t.closest(\"[data-pdf-thumbnails]\") === null && t !== scrollerRef.current) return;\n e.preventDefault();\n // Undo and redo are the session's one stack: PDF.js (listening on the window) must not take them too.\n if (action === \"undo\" || action === \"redo\") e.stopPropagation();\n runAction(action);\n };\n\n // Reading mode hides the button that opened it, so focus would fall to <body> and Escape (handled on\n // this root) would never arrive: the page takes focus on entry, and while reading, an Escape pressed\n // anywhere outside the workspace exits too. Guard: pdf-workspace.test.tsx \"Escape leaves reading mode\".\n useEffect(() => {\n if (!read) return undefined;\n scrollerRef.current?.focus({ preventScroll: true });\n const onWindowKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented) return;\n if (rootRef.current?.contains(e.target as Node)) return; // the root's own handler has it\n setRead(false);\n };\n window.addEventListener(\"keydown\", onWindowKey);\n return () => window.removeEventListener(\"keydown\", onWindowKey);\n }, [read]);\n\n // ── pieces ──────────────────────────────────────────────────────────────\n const unsaved = dirty || markupPending > 0;\n const saveState = !online ? \"Offline\" : busy || markupBusy ? \"Saving\" : (error && dirty) || (markupError && markupPending) ? \"Not saved\" : unsaved ? \"Unsaved\" : \"Saved\";\n const savePill = (\n <span\n role=\"status\"\n className={cn(\n \"inline-flex h-6 shrink-0 items-center justify-center whitespace-nowrap rounded-full border px-2 text-xs\",\n saveState === \"Unsaved\" || saveState === \"Offline\" || saveState === \"Not saved\" ? \"border-border text-foreground\" : \"border-border text-muted-foreground\",\n busy && \"animate-pulse\",\n )}\n >\n {saveState}\n </span>\n );\n const iconBtn = (label: string, icon: React.ReactNode, onClick: () => void, opts?: { disabled?: boolean; pressed?: boolean }) => (\n <Button variant=\"quiet\" icon={icon} aria-label={label} title={label} onClick={onClick} {...(opts?.disabled !== undefined ? { disabled: opts.disabled } : null)} {...(opts?.pressed !== undefined ? { pressed: opts.pressed } : null)} />\n );\n const toolHits: Array<{ id: string; label: string; status: \"ready\" | \"soon\" }> = toolQuery.trim()\n ? [\n ...hostTools.map((t) => ({ id: `host:${t.id}`, label: t.label, status: \"ready\" as const })),\n ...PDF_TOOLS,\n ].filter((t) => t.label.toLowerCase().includes(toolQuery.trim().toLowerCase()))\n : [];\n const nameNode = editingName && host.rename ? (\n <Field\n autoFocus\n value={nameDraft}\n aria-label=\"File name\"\n onChange={(e) => setNameDraft(e.target.value)}\n onBlur={() => {\n setEditingName(false);\n if (nameDraft.trim() && nameDraft !== host.file.name) host.rename!(nameDraft.trim()).catch(fail);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") (e.target as HTMLInputElement).blur();\n if (e.key === \"Escape\") { setNameDraft(host.file.name); setEditingName(false); }\n }}\n width=\"lg\"\n />\n ) : (\n <Button\n type=\"button\"\n variant=\"quiet\"\n className=\"min-w-0 max-w-[16rem]\"\n title={host.rename ? \"Rename\" : host.file.name}\n onClick={() => host.rename && (setNameDraft(host.file.name), setEditingName(true))}\n >\n {host.file.name}\n </Button>\n );\n\n const rightPanel = hostTool ? (\n <div className=\"flex h-full min-h-0 flex-col\" data-pdf-host-tool={hostTool.id}>\n <div className=\"shrink-0 border-b border-border px-3 py-2\">\n <div className=\"text-sm font-medium\">{hostTool.label}</div>\n {hostTool.hint ? <div className=\"text-xs text-muted-foreground\">{hostTool.hint}</div> : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n {hostTool.render({ currentPage, pageCount, selected: selectedPages, goToPage, reload: () => setReloadKey((k) => k + 1) })}\n </div>\n </div>\n ) : (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"shrink-0 border-b border-border px-3 py-2\">\n <div className=\"text-sm font-medium\">{toolDef.label}</div>\n {toolDef.hint ? <div className=\"text-xs text-muted-foreground\">{toolDef.hint}</div> : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto p-3\">\n {tool === \"markup\" ? (\n <MarkupPanel\n host={host}\n engine={engine}\n snapshot={snap}\n active={markupTool}\n onPick={setMarkupTool}\n blocked={dirty ? \"Apply or discard the page changes first.\" : null}\n busy={markupBusy}\n online={online}\n error={markupError}\n onSave={() => void saveMarkup()}\n onDiscard={discardMarkup}\n onSoon={(id) => void announceSoon(id).catch(fail)}\n goToPage={goToPage}\n reloadKey={reloadKey}\n />\n ) : (\n <ToolPanel\n tool={toolDef}\n host={host}\n pageCount={pageCount}\n selected={selectedPages}\n currentPage={currentPage}\n pageSize={(p) => sizes.current.get(p)}\n decisions={decisions}\n dirty={dirty}\n busy={busy}\n online={online}\n result={result}\n error={error}\n onRun={(r) => void runTool(r)}\n onApply={apply}\n onDiscard={discard}\n onTurn={turn}\n onDelete={del}\n onRestore={restore}\n />\n )}\n </div>\n </div>\n );\n const leftPanel = (\n <LeftPanel\n host={host}\n tab={leftTab}\n onTab={setLeftTab}\n decisions={decisions}\n selectedIds={selected}\n currentPage={currentPage}\n onSelect={(ids) => {\n setSelected(ids);\n if (ids.length === 1) goToPage(Number(ids[0]));\n }}\n onReorder={(order) => commit(\"Move pages\", reorderPages(decisions, order))}\n onOpenPage={goToPage}\n onLayersSoon={() => void announceSoon(\"pdf.layers\").catch(fail)}\n />\n );\n\n // Memoized: scrolling changes the current page many times a second, and the viewer must not redraw for it.\n // The page number reaches the viewer only while a host tool asks to follow it, so scrolling never redraws a windowed viewer.\n const viewerPage = hostTool?.followsPage ? currentPage : 1;\n const viewer = useMemo(\n () => (\n <Fragment key={reloadKey}>\n {host.renderViewer({ zoom, spread, rotations: decisions.turns, reloadKey, currentPage: viewerPage, onDocumentLoad, onPageSize, ...(canMarkup ? { onMarkupEngine } : null) })}\n </Fragment>\n ),\n [host, reloadKey, zoom, spread, decisions.turns, viewerPage, onDocumentLoad, onPageSize, canMarkup, onMarkupEngine],\n );\n\n const showChrome = !read;\n const popCard = \"absolute right-2 top-11 z-30 rounded-lg border border-border bg-popover p-3 text-popover-foreground shadow-lg\";\n\n return (\n <div\n ref={rootRef}\n tabIndex={-1}\n data-pdf-workspace=\"\"\n data-compact={compact ? \"\" : undefined}\n onKeyDown={onKeyDown}\n className={cn(\"relative flex h-full min-h-0 w-full flex-col overflow-hidden bg-background text-foreground outline-none\", className)}\n >\n {showChrome ? (\n <div className={BAR} data-pdf-topbar=\"\">\n {iconBtn(\"Page thumbnails\", <PanelLeftIcon />, () => (compact ? setSheet(\"pages\") : setLeftOpen((v) => !v)), { pressed: !compact && leftOpen })}\n {nameNode}\n {savePill}\n <div className=\"flex-1\" />\n {!compact ? (\n <div className=\"relative w-56\">\n <Field\n icon={<SearchIcon />}\n value={toolQuery}\n aria-label=\"Search tools\"\n placeholder=\"Search tools\"\n onFocus={() => setPop(\"tool-search\")}\n onChange={(e) => { setToolQuery(e.target.value); setPop(\"tool-search\"); }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && toolHits[0]) { chooseTool(toolHits[0].id); setToolQuery(\"\"); setPop(null); }\n }}\n />\n {pop === \"tool-search\" && toolHits.length ? (\n <ul role=\"listbox\" className=\"absolute left-0 right-0 top-9 z-30 rounded-lg border border-border bg-popover p-1 shadow-lg\">\n {toolHits.map((t) => (\n <li key={t.id} role=\"option\" aria-selected={false}>\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n title={t.label}\n end={t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : undefined}\n className=\"w-full\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => { chooseTool(t.id); setToolQuery(\"\"); setPop(null); }}\n />\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n ) : null}\n {iconBtn(undoText, <Undo2Icon />, () => runAction(\"undo\"), { disabled: !canUndoAll })}\n {iconBtn(redoText, <Undo2Icon className=\"-scale-x-100\" />, () => runAction(\"redo\"), { disabled: !canRedoAll })}\n {!compact && iconBtn(\"Find\", <SearchIcon />, () => runAction(\"find\"), { pressed: findOpen })}\n {host.share && !compact ? iconBtn(\"Share\", <Share2Icon />, () => host.share!()) : null}\n {iconBtn(\"Download\", <DownloadIcon />, () => host.download())}\n {host.print && !compact ? iconBtn(\"Print\", <PrinterIcon />, () => setPop(pop === \"print\" ? null : \"print\"), { pressed: pop === \"print\" }) : null}\n {!compact ? iconBtn(\"Keyboard shortcuts\", <KeyboardIcon />, () => runAction(\"shortcuts\"), { pressed: pop === \"shortcuts\" }) : null}\n {compact ? <Button variant=\"outline\" onClick={() => setSheet(\"tools\")}>Tools</Button> : iconBtn(\"Properties panel\", <PanelRightIcon />, () => setRightOpen((v) => !v), { pressed: rightOpen })}\n </div>\n ) : null}\n\n {showChrome ? (\n <div className={BAR} data-pdf-viewbar=\"\">\n {iconBtn(\"Previous page\", <ChevronLeftIcon />, () => goToPage(currentPage - 1), { disabled: currentPage <= 1 })}\n <Field\n type=\"number\"\n min={1}\n max={Math.max(1, pageCount)}\n value={pageDraft}\n aria-label=\"Page\"\n onChange={(e) => setPageDraft(e.target.value)}\n onBlur={() => goToPage(Number(pageDraft) || currentPage)}\n onKeyDown={(e) => e.key === \"Enter\" && goToPage(Number(pageDraft) || currentPage)}\n className={compact ? \"w-12\" : \"w-16\"}\n />\n <span className=\"whitespace-nowrap text-xs text-muted-foreground\">of {pageCount || \"-\"}</span>\n {iconBtn(\"Next page\", <ChevronRightIcon />, () => goToPage(currentPage + 1), { disabled: currentPage >= pageCount })}\n <div className=\"mx-1 h-5 w-px bg-border\" />\n {iconBtn(\"Zoom out\", <MinusIcon />, () => stepZoom(-1))}\n <span className={cn(\"min-w-[3rem] text-center text-xs tabular-nums\", compact && \"hidden\")} data-pdf-zoom=\"\">\n {`${Math.round(zoom * 100)}%`}\n </span>\n {iconBtn(\"Zoom in\", <PlusIcon />, () => stepZoom(1))}\n {!compact ? (\n <SegmentedControl\n value={zoomMode === \"custom\" ? null : zoomMode}\n onValueChange={(v) => setZoomMode(v)}\n data={[{ value: \"fit-width\", label: \"Width\" }, { value: \"fit-page\", label: \"Page\" }]}\n aria-label=\"Fit\"\n />\n ) : null}\n <div className=\"flex-1\" />\n {!compact ? (\n <>\n {iconBtn(\"Rotate left\", <RotateCcwIcon />, () => turn(-90))}\n {iconBtn(\"Rotate right\", <RotateCwIcon />, () => turn(90))}\n {iconBtn(\"Delete page\", <Trash2Icon />, del, { disabled: decisions.order.length - decisions.deleted.length <= 1 })}\n <div className=\"mx-1 h-5 w-px bg-border\" />\n {iconBtn(\"Two pages side by side\", <Columns2Icon />, () => runAction(\"two-up\"), { pressed: spread === \"two-up\" })}\n </>\n ) : null}\n {iconBtn(\"Reading mode\", <ExpandIcon />, () => setRead(true))}\n </div>\n ) : null}\n\n <div className=\"relative flex min-h-0 flex-1\">\n {showChrome && !compact ? (\n <div className=\"flex w-10 shrink-0 flex-col items-center border-r border-border bg-background py-2\" data-pdf-rail=\"\">\n <ToolRail groups={railGroups} value={pop === \"all-tools\" ? ALL_TOOLS : activeToolKey} onValueChange={(id) => (id === ALL_TOOLS ? setPop((p) => (p === \"all-tools\" ? null : \"all-tools\")) : id && chooseTool(id))} aria-label=\"PDF tools\" />\n </div>\n ) : null}\n {showChrome && !compact && leftOpen ? (\n <aside className=\"w-56 shrink-0 border-r border-border bg-background\" aria-label=\"Pages\" data-pdf-left=\"\">\n {leftPanel}\n </aside>\n ) : null}\n <main className=\"relative flex min-w-0 flex-1 flex-col\">\n {findOpen ? (\n <div className=\"absolute right-4 top-2 z-20\">\n <RenderedFindBar rootRef={scrollerRef} onClose={() => setFindOpen(false)} label=\"Find in document\" focusRequest={findFocus} compact />\n </div>\n ) : null}\n <div ref={scrollerRef} tabIndex={0} data-pdf-scroller=\"\" className=\"min-h-0 flex-1 overflow-auto bg-muted outline-none\">\n {viewer}\n </div>\n <MarkupFloatingToolbar engine={engine} snapshot={snap} enabled={markupOn && !read} onDone={() => scrollerRef.current?.focus({ preventScroll: true })} />\n {read ? (\n <div className=\"absolute right-3 top-3 z-20\">\n <Button variant=\"outline\" icon={<XIcon />} onClick={() => setRead(false)}>Exit reading mode</Button>\n </div>\n ) : null}\n </main>\n {showChrome && !compact && rightOpen ? (\n <aside className={cn(\"shrink-0 border-l border-border bg-background\", hostTool?.wide ? \"w-[28rem]\" : \"w-72\")} aria-label=\"Properties\" data-pdf-right=\"\">\n {rightPanel}\n </aside>\n ) : null}\n\n {pop === \"all-tools\" ? (\n <ul role=\"menu\" aria-label=\"All tools\" className=\"absolute left-12 top-2 z-30 w-72 rounded-lg border border-border bg-popover p-1 shadow-lg\" data-pdf-all-tools=\"\">\n <ToolRows tool={activeToolKey} hostTools={hostTools} canMarkup={canMarkup} onPick={(id) => { setPop(null); chooseTool(id); }} />\n </ul>\n ) : null}\n {pop === \"print\" && host.print ? (\n <div className={cn(popCard, \"w-72\")} role=\"dialog\" aria-label=\"Print\">\n <div className=\"flex flex-col gap-3\">\n <SegmentedControl fill value={printMode} onValueChange={setPrintMode} data={[{ value: \"all\", label: \"All pages\" }, { value: \"pages\", label: \"Pages\" }]} aria-label=\"What to print\" />\n {printMode === \"pages\" ? <PageRangeInput value={printRange} onChange={(t) => setPrintRange(t)} pageCount={pageCount} /> : null}\n <Button\n variant=\"primary\"\n disabled={busy || (printMode === \"pages\" && !parsePageRanges(printRange, pageCount).valid)}\n onClick={() => {\n const pages = printMode === \"pages\" ? parsePageRanges(printRange, pageCount).pages : null;\n setBusy(true);\n host.print!(pages).then(() => setPop(null), fail).finally(() => setBusy(false));\n }}\n >\n Print\n </Button>\n </div>\n </div>\n ) : null}\n {pop === \"shortcuts\" ? (\n <div className={cn(popCard, \"max-h-[70%] w-80 overflow-y-auto\")} role=\"dialog\" aria-label=\"Keyboard shortcuts\" data-pdf-shortcuts=\"\">\n {([\"Edit\", \"View\", \"Pages\", \"Tools\"] as const).map((section) => (\n <div key={section} className=\"mb-3 last:mb-0\">\n <div className=\"mb-1 text-xs font-medium text-muted-foreground\">{section}</div>\n {PDF_SHORTCUTS.filter((s) => s.section === section).map((s) => (\n <div key={s.action} className=\"flex justify-between gap-2 py-0.5 text-xs\">\n <span>{s.label}</span>\n <kbd className=\"rounded border border-border px-1 text-muted-foreground\">{formatKeys(s.keys, isMac())}</kbd>\n </div>\n ))}\n </div>\n ))}\n {canMarkup ? (\n <div className=\"mb-0\">\n <div className=\"mb-1 text-xs font-medium text-muted-foreground\">Markup</div>\n {PDF_MARKUP_SHORTCUTS.filter((s) => s.tool !== \"signature\" || host.signaturePad).map((s) => (\n <div key={s.tool} className=\"flex justify-between gap-2 py-0.5 text-xs\">\n <span>{s.label}</span>\n <kbd className=\"rounded border border-border px-1 text-muted-foreground\">{s.keys}</kbd>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {compact && sheet ? (\n <>\n {/* ui-exception: Full-screen mobile sheet backdrop dismisses the modal; locked controls cannot cover the viewport. */}\n <button type=\"button\" aria-label=\"Close\" className=\"absolute inset-0 z-30 bg-background/60\" onClick={() => setSheet(null)} />\n <div className=\"absolute inset-x-0 bottom-0 z-40 flex max-h-[75%] flex-col rounded-t-xl border-t border-border bg-background\" role=\"dialog\" aria-label={sheet === \"pages\" ? \"Pages\" : \"Tools\"}>\n {sheet === \"pages\" ? (\n <div className=\"h-[60vh] min-h-0\">{leftPanel}</div>\n ) : (\n <div className=\"flex min-h-0 flex-col overflow-y-auto\">\n <ul className=\"p-2\" role=\"menu\" aria-label=\"Tools\"><ToolRows tool={activeToolKey} hostTools={hostTools} canMarkup={canMarkup} onPick={chooseTool} /></ul>\n <div className=\"border-t border-border\">{rightPanel}</div>\n </div>\n )}\n </div>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n","/**\n * The page decisions of one workspace session: which pages are turned, left out, or moved. Pure.\n *\n * Decisions are PENDING: the viewer and the page grid show them at once, and \"Apply\" sends them\n * to the server as the smallest list of page operations (`compilePageOps`). Pages are named by\n * their ORIGINAL 1-based number everywhere, so a decision survives any later move.\n */\n\nexport type Turn = 0 | 90 | 180 | 270;\n\nexport interface PageDecisions {\n /** Original page numbers in the order the person wants them (deleted pages stay in the list). */\n order: number[];\n /** Extra clockwise turn per original page; absent = 0. */\n turns: Record<number, Turn>;\n /** Original page numbers left out. */\n deleted: number[];\n}\n\nexport function freshDecisions(pageCount: number): PageDecisions {\n return { order: Array.from({ length: Math.max(0, pageCount) }, (_, i) => i + 1), turns: {}, deleted: [] };\n}\n\nconst norm = (t: number): Turn => ((((t % 360) + 360) % 360) as Turn);\n\nexport function turnPages(d: PageDecisions, pages: readonly number[], by: 90 | -90 | 180): PageDecisions {\n const turns = { ...d.turns };\n for (const p of pages) {\n const next = norm((turns[p] ?? 0) + by);\n if (next === 0) delete turns[p];\n else turns[p] = next;\n }\n return { ...d, turns };\n}\n\nexport function deletePages(d: PageDecisions, pages: readonly number[]): PageDecisions {\n const set = new Set([...d.deleted, ...pages.filter((p) => d.order.includes(p))]);\n // A document with no page left is not a document: the last page cannot be deleted.\n if (set.size >= d.order.length) return d;\n return { ...d, deleted: [...set].sort((a, b) => a - b) };\n}\n\nexport function restorePages(d: PageDecisions, pages: readonly number[]): PageDecisions {\n const gone = new Set(pages);\n return { ...d, deleted: d.deleted.filter((p) => !gone.has(p)) };\n}\n\n/** The new order, as the grid reports it (a list of original page numbers). */\nexport function reorderPages(d: PageDecisions, order: readonly number[]): PageDecisions {\n if (order.length !== d.order.length || [...order].sort((a, b) => a - b).some((p, i) => p !== i + 1)) return d;\n return { ...d, order: [...order] };\n}\n\nexport function isDirty(d: PageDecisions): boolean {\n const moved = d.order.some((p, i) => p !== i + 1);\n return moved || d.deleted.length > 0 || Object.keys(d.turns).length > 0;\n}\n\n/** The pages that will remain, in their new order. */\nexport function keptOrder(d: PageDecisions): number[] {\n const gone = new Set(d.deleted);\n return d.order.filter((p) => !gone.has(p));\n}\n\nexport type PageOp =\n | { kind: \"rotate\"; pages: number[]; rotation: 90 | 180 | 270 }\n | { kind: \"delete\"; pages: number[] }\n | { kind: \"reorder\"; newOrder: number[] };\n\n/**\n * The server operations that make the document match the decisions, in the order they must run:\n * turns (original numbering), deletions (original numbering), then one reorder over what remains\n * (renumbered 1..n). Nothing is emitted for a decision that changes nothing.\n */\nexport function compilePageOps(d: PageDecisions): PageOp[] {\n const ops: PageOp[] = [];\n const gone = new Set(d.deleted);\n for (const rotation of [90, 180, 270] as const) {\n const pages = Object.entries(d.turns)\n .filter(([p, t]) => t === rotation && !gone.has(Number(p)))\n .map(([p]) => Number(p))\n .sort((a, b) => a - b);\n if (pages.length) ops.push({ kind: \"rotate\", pages, rotation });\n }\n if (d.deleted.length) ops.push({ kind: \"delete\", pages: [...d.deleted] });\n const kept = keptOrder(d);\n const renumber = new Map([...kept].sort((a, b) => a - b).map((p, i) => [p, i + 1] as const));\n const newOrder = kept.map((p) => renumber.get(p)!);\n if (newOrder.some((p, i) => p !== i + 1)) ops.push({ kind: \"reorder\", newOrder });\n return ops;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { SegmentedControl, Switch } from \"@ai-matrx/design-system/controls\";\nimport { ThumbnailGrid } from \"@ai-matrx/design-system/thumbnail-grid\";\nimport type { PdfWorkspaceHost } from \"./ports\";\nimport type { PageDecisions } from \"./page-decisions\";\n\nexport type LeftTab = \"pages\" | \"layers\";\n\nexport interface LeftPanelProps {\n host: PdfWorkspaceHost;\n tab: LeftTab;\n onTab(tab: LeftTab): void;\n decisions: PageDecisions;\n selectedIds: string[];\n currentPage: number;\n onSelect(ids: string[]): void;\n onReorder(order: number[]): void;\n onOpenPage(page: number): void;\n /** Announce the registered \"layers\" promise (the host has no layer port). */\n onLayersSoon(): void;\n}\n\nconst THUMB_W = 88;\n\nexport function LeftPanel(p: LeftPanelProps) {\n const items = p.decisions.order.map((n) => ({ id: String(n) }));\n const gone = new Set(p.decisions.deleted);\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col\">\n <div className=\"shrink-0 border-b border-border p-2\">\n <SegmentedControl\n fill\n value={p.tab}\n onValueChange={(v) => (v === \"layers\" && !p.host.layers ? p.onLayersSoon() : p.onTab(v))}\n data={[\n { value: \"pages\", label: \"Pages\" },\n { value: \"layers\", label: \"Layers\" },\n ]}\n aria-label=\"Left panel\"\n />\n </div>\n {p.tab === \"pages\" ? (\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\" data-pdf-thumbnails=\"\">\n <ThumbnailGrid\n aria-label=\"Pages\"\n items={items}\n columns={2}\n aspectRatio=\"3 / 4\"\n selectedIds={p.selectedIds}\n onSelectedIdsChange={p.onSelect}\n onReorder={(ids) => p.onReorder(ids.map(Number))}\n onOpen={(item) => p.onOpenPage(Number(item.id))}\n itemLabel={(item) => `Page ${item.id}${gone.has(Number(item.id)) ? \", deleted\" : \"\"}`}\n renderCaption={(item) => <span className={Number(item.id) === p.currentPage ? \"font-medium text-foreground\" : \"text-muted-foreground\"}>{item.id}</span>}\n renderItem={(item) => {\n const page = Number(item.id);\n const turn = p.decisions.turns[page] ?? 0;\n return (\n <div className=\"relative flex h-full w-full items-center justify-center overflow-hidden bg-card\">\n <div style={{ transform: turn ? `rotate(${turn}deg)` : undefined }} className=\"flex h-full w-full items-center justify-center\">\n {p.host.renderThumbnail ? p.host.renderThumbnail(page, THUMB_W) : <span className=\"text-xs text-muted-foreground\">{page}</span>}\n </div>\n {p.host.renderPageBadge ? <span className=\"pointer-events-none absolute right-1 top-1 z-10\" data-pdf-page-badge={page}>{p.host.renderPageBadge(page)}</span> : null}\n {page === p.currentPage ? <span className=\"pointer-events-none absolute inset-0 border-2 border-primary\" /> : null}\n {gone.has(page) ? (\n <span className=\"absolute inset-0 flex items-center justify-center bg-background/80 text-xs font-medium text-destructive\">Deleted</span>\n ) : null}\n </div>\n );\n }}\n />\n </div>\n ) : (\n <LayersList host={p.host} />\n )}\n </div>\n );\n}\n\nfunction LayersList({ host }: { host: PdfWorkspaceHost }) {\n const [layers, setLayers] = useState<Array<{ id: string; name: string; visible: boolean }> | null>(null);\n const [error, setError] = useState<string | null>(null);\n useEffect(() => {\n host.layers?.list().then(setLayers, (e: unknown) => setError(e instanceof Error ? e.message : \"The layers did not load.\"));\n }, [host]);\n if (error) return <p role=\"alert\" className=\"p-3 text-xs text-destructive\">{error}</p>;\n if (!layers) return <div className=\"p-3 text-xs text-muted-foreground\" aria-busy=\"true\">Loading</div>;\n if (!layers.length) return <p className=\"p-3 text-xs text-muted-foreground\">This document has no layers.</p>;\n return (\n <ul className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {layers.map((l) => (\n <li key={l.id} className=\"flex items-center justify-between gap-2 py-1 text-xs\">\n <span className=\"truncate\">{l.name}</span>\n <Switch\n checked={l.visible}\n aria-label={`Show ${l.name}`}\n onCheckedChange={(v) => {\n setLayers((prev) => prev?.map((x) => (x.id === l.id ? { ...x, visible: v } : x)) ?? prev);\n host.layers!.set(l.id, v).catch((e: unknown) => {\n setLayers((prev) => prev?.map((x) => (x.id === l.id ? { ...x, visible: !v } : x)) ?? prev);\n setError(e instanceof Error ? e.message : \"The layer did not change.\");\n });\n }}\n />\n </li>\n ))}\n </ul>\n );\n}\n","\"use client\";\n\n/**\n * The right-hand properties panel: one small form per ready tool. Every form is built from the design\n * system's controls, submits one `PdfRunRequest` through the host, and shows what came back. Forms\n * never decide anything the server owns (levels, patterns, ranges are validated there too).\n */\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Button, Field, SegmentedControl, Select, Textarea } from \"@ai-matrx/design-system/controls\";\nimport { PageRangeInput, formatPageRanges, parsePageRanges } from \"@ai-matrx/design-system/controls\";\nimport { copyText } from \"@ai-matrx/kit/clipboard\";\nimport { toDelimited } from \"@ai-matrx/kit/delimited\";\nimport type { PdfRunRequest, PdfRunResult, PdfWorkspaceHost } from \"./ports\";\nimport type { PdfToolDef } from \"./tools\";\nimport { keptOrder, type PageDecisions } from \"./page-decisions\";\n\nexport interface ToolPanelProps {\n tool: PdfToolDef;\n host: PdfWorkspaceHost;\n pageCount: number;\n /** Original page numbers selected in the page panel. */\n selected: number[];\n currentPage: number;\n /** Size of a page in PDF points once the viewer measured it. */\n pageSize(page: number): { w: number; h: number } | undefined;\n decisions: PageDecisions;\n dirty: boolean;\n busy: boolean;\n online: boolean;\n result: PdfRunResult | null;\n error: string | null;\n onRun(request: PdfRunRequest): void;\n onApply(): void;\n onDiscard(): void;\n onTurn(by: 90 | -90): void;\n onDelete(): void;\n onRestore(): void;\n}\n\nfunction Row({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-muted-foreground\">{label}</span>\n {children}\n </div>\n );\n}\n\n/** A page-range field that follows the page selection until the person types in it. */\nfunction useRangeText(selected: number[], currentPage: number): [string, (v: string) => void] {\n const synced = useRef(\"\");\n const [text, setText] = useState(\"\");\n const follow = selected.length ? formatPageRanges(selected) : String(currentPage);\n useEffect(() => {\n setText((prev) => (prev === synced.current ? follow : prev));\n synced.current = follow;\n }, [follow]);\n return [text, setText];\n}\n\nfunction RunButton({ busy, online, disabled, children, onClick }: { busy: boolean; online: boolean; disabled?: boolean; children: React.ReactNode; onClick(): void }) {\n return (\n <Button variant=\"primary\" disabled={busy || !online || disabled} onClick={onClick}>\n {busy ? \"Working\" : children}\n </Button>\n );\n}\n\nfunction Result({ result, host, error }: { result: PdfRunResult | null; host: PdfWorkspaceHost; error: string | null }) {\n const [copied, setCopied] = useState(false);\n const csv = useMemo(\n () =>\n result?.kind === \"tables\"\n ? result.tables.map((t) => toDelimited(t.rows, { format: \"csv\" })).join(\"\\n\\n\")\n : \"\",\n [result],\n );\n const copy = async (text: string) => {\n if (await copyText(text)) {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }\n };\n return (\n <div className=\"flex min-h-[3rem] flex-col gap-2\" aria-live=\"polite\">\n {error ? (\n <p role=\"alert\" className=\"rounded-md border border-destructive bg-destructive/10 p-2 text-xs text-destructive\">\n {error}\n </p>\n ) : null}\n {result?.kind === \"replaced\" ? <p className=\"text-xs text-muted-foreground\">Saved as a new version of this file.</p> : null}\n {result?.kind === \"file\" ? (\n <Button variant=\"outline\" onClick={() => host.openFile(result.fileId)}>\n Open {result.name ?? \"the new file\"}\n </Button>\n ) : null}\n {result?.kind === \"text\" ? (\n <>\n <Textarea\n readOnly\n value={result.text}\n aria-label=\"Extracted text\"\n minHeight={192}\n maxHeight={192}\n className=\"w-full resize-none\"\n />\n <Button variant=\"outline\" onClick={() => void copy(result.text)}>\n {copied ? \"Copied\" : \"Copy text\"}\n </Button>\n </>\n ) : null}\n {result?.kind === \"tables\" ? (\n result.tables.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">No tables found on these pages.</p>\n ) : (\n <>\n <div className=\"flex max-h-48 flex-col gap-2 overflow-auto\">\n {result.tables.map((t, i) => (\n <div key={i} className=\"rounded-md border border-border\">\n <div className=\"border-b border-border px-2 py-1 text-xs font-medium\">Page {t.page}</div>\n <table className=\"w-full text-xs\">\n <tbody>\n {t.rows.slice(0, 12).map((r, ri) => (\n <tr key={ri} className=\"border-b border-border last:border-b-0\">\n {r.map((c, ci) => (\n <td key={ci} className=\"px-2 py-1\">{c}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ))}\n </div>\n <Button variant=\"outline\" onClick={() => void copy(csv)}>\n {copied ? \"Copied\" : \"Copy as CSV\"}\n </Button>\n </>\n )\n ) : null}\n </div>\n );\n}\n\nconst LEVELS = [\n { value: \"1\", label: \"1\" },\n { value: \"2\", label: \"2\" },\n { value: \"3\", label: \"3\" },\n { value: \"4\", label: \"4\" },\n { value: \"5\", label: \"5\" },\n] as const;\n\nexport function ToolPanel(p: ToolPanelProps) {\n const [range, setRange] = useRangeText(p.selected, p.currentPage);\n const parsed = useMemo(() => parsePageRanges(range, p.pageCount), [range, p.pageCount]);\n const [perPart, setPerPart] = useState(\"10\");\n const [margins, setMargins] = useState({ top: \"0\", right: \"0\", bottom: \"0\", left: \"0\" });\n const [pattern, setPattern] = useState(\"\");\n const [reason, setReason] = useState(\"\");\n const [level, setLevel] = useState<\"1\" | \"2\" | \"3\" | \"4\" | \"5\">(\"3\");\n const [patterns, setPatterns] = useState<Array<{ id: string; label: string }> | null>(null);\n const [patternsError, setPatternsError] = useState<string | null>(null);\n const loadPatterns = p.host.redactPatterns;\n useEffect(() => {\n if (p.tool.id !== \"redact\" || !loadPatterns || patterns) return;\n loadPatterns().then(setPatterns, (e: unknown) => setPatternsError(e instanceof Error ? e.message : \"The pattern list did not load.\"));\n }, [p.tool.id, loadPatterns, patterns]);\n\n const rangeField = (\n <Row label=\"Pages\">\n <PageRangeInput value={range} onChange={(t) => setRange(t)} pageCount={p.pageCount} aria-label=\"Pages\" />\n </Row>\n );\n const cropBox = () => {\n const n = (s: string) => Math.max(0, Number(s) || 0);\n const groups = new Map<string, { pages: number[]; box: { x0: number; y0: number; x1: number; y1: number } }>();\n for (const page of parsed.pages) {\n const size = p.pageSize(page);\n if (!size) continue;\n const box = { x0: n(margins.left), y0: n(margins.top), x1: size.w - n(margins.right), y1: size.h - n(margins.bottom) };\n const key = `${box.x0}:${box.y0}:${box.x1}:${box.y1}`;\n const g = groups.get(key) ?? { pages: [], box };\n g.pages.push(page);\n groups.set(key, g);\n }\n return [...groups.values()];\n };\n\n let body: React.ReactNode = null;\n switch (p.tool.id) {\n case \"browse\": {\n const kept = keptOrder(p.decisions).length;\n body = (\n <div className=\"flex flex-col gap-1 text-xs\">\n <div className=\"flex justify-between\"><span className=\"text-muted-foreground\">Pages</span><span>{kept}</span></div>\n <div className=\"flex justify-between\"><span className=\"text-muted-foreground\">Selected</span><span>{p.selected.length}</span></div>\n <div className=\"flex justify-between\"><span className=\"text-muted-foreground\">Unsaved changes</span><span>{p.dirty ? \"Yes\" : \"None\"}</span></div>\n </div>\n );\n break;\n }\n case \"organize\":\n body = (\n <div className=\"flex flex-col gap-3\">\n <div className=\"grid grid-cols-2 gap-2\">\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={() => p.onTurn(-90)}>Rotate left</Button>\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={() => p.onTurn(90)}>Rotate right</Button>\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={p.onDelete}>Delete</Button>\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={p.onRestore}>Restore</Button>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"primary\" disabled={!p.dirty || p.busy || !p.online} onClick={p.onApply}>\n {p.busy ? \"Working\" : \"Apply changes\"}\n </Button>\n <Button variant=\"outline\" disabled={!p.dirty || p.busy} onClick={p.onDiscard}>Discard</Button>\n </div>\n </div>\n );\n break;\n case \"extract-pages\":\n body = (\n <>\n {rangeField}\n <RunButton busy={p.busy} online={p.online} disabled={!parsed.valid} onClick={() => p.onRun({ tool: \"extract-pages\", pages: parsed.pages })}>\n Extract to a new file\n </RunButton>\n </>\n );\n break;\n case \"split\":\n body = (\n <>\n <Row label=\"Pages in each part\">\n <Field type=\"number\" min={1} value={perPart} onChange={(e) => setPerPart(e.target.value)} aria-label=\"Pages in each part\" />\n </Row>\n <RunButton busy={p.busy} online={p.online} disabled={!(Number(perPart) >= 1)} onClick={() => p.onRun({ tool: \"split\", maxPagesPerPart: Math.floor(Number(perPart)) })}>\n Split into new files\n </RunButton>\n </>\n );\n break;\n case \"crop\": {\n const groups = cropBox();\n body = (\n <>\n {rangeField}\n <div className=\"grid grid-cols-2 gap-2\">\n {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((side) => (\n <Row key={side} label={side[0]!.toUpperCase() + side.slice(1)}>\n <Field type=\"number\" min={0} value={margins[side]} onChange={(e) => setMargins((m) => ({ ...m, [side]: e.target.value }))} aria-label={`Crop ${side}`} />\n </Row>\n ))}\n </div>\n <RunButton\n busy={p.busy}\n online={p.online}\n disabled={!parsed.valid || groups.length === 0}\n onClick={() => {\n for (const g of groups) p.onRun({ tool: \"crop\", pages: g.pages, box: g.box });\n }}\n >\n Crop to a new file\n </RunButton>\n </>\n );\n break;\n }\n case \"redact\":\n body = (\n <>\n <Row label=\"Find\">\n {patterns ? (\n <Select\n value={pattern}\n onValueChange={setPattern}\n options={patterns.map((x) => ({ value: x.id, label: x.label }))}\n aria-label=\"What to redact\"\n />\n ) : (\n <Field value={pattern} onChange={(e) => setPattern(e.target.value)} aria-label=\"What to redact\" />\n )}\n {patternsError ? <span className=\"text-xs text-destructive\">{patternsError}</span> : null}\n </Row>\n <Row label=\"Reason\">\n <Field value={reason} onChange={(e) => setReason(e.target.value)} aria-label=\"Reason\" />\n </Row>\n <RunButton busy={p.busy} online={p.online} disabled={!pattern.trim() || !reason.trim()} onClick={() => p.onRun({ tool: \"redact\", pattern: pattern.trim(), reason: reason.trim() })}>\n Redact to a new file\n </RunButton>\n </>\n );\n break;\n case \"compress\":\n body = (\n <>\n <Row label=\"Strength\">\n <SegmentedControl fill value={level} onValueChange={setLevel} data={LEVELS} aria-label=\"Compression strength\" />\n </Row>\n <RunButton busy={p.busy} online={p.online} onClick={() => p.onRun({ tool: \"compress\", level: Number(level) as 1 | 2 | 3 | 4 | 5 })}>\n Compress to a new file\n </RunButton>\n </>\n );\n break;\n case \"extract-data\":\n body = (\n <>\n {rangeField}\n <div className=\"grid grid-cols-2 gap-2\">\n <Button variant=\"outline\" disabled={p.busy || !p.online || !parsed.valid} onClick={() => p.onRun({ tool: \"extract-text\", pages: parsed.pages })}>Get text</Button>\n <Button variant=\"outline\" disabled={p.busy || !p.online || !parsed.valid} onClick={() => p.onRun({ tool: \"extract-tables\", pages: parsed.pages })}>Get tables</Button>\n </div>\n </>\n );\n break;\n default:\n body = null;\n }\n\n return (\n <div className=\"flex flex-col gap-3\">\n {body}\n {p.tool.id !== \"browse\" ? <Result result={p.result} host={p.host} error={p.error} /> : null}\n </div>\n );\n}\n","/**\n * The session's one undo/redo stack. Pure and generic: the workspace keeps page decisions and tool\n * form values in it, each step with the label the menu shows (\"Undo Rotate 3 pages\"). A new step\n * clears what was undone; the stack holds at most `limit` steps. Saved versions of the file are the\n * durable undo: applying changes empties this stack.\n */\nexport interface History<T> {\n past: Array<{ label: string; value: T }>;\n present: { label: string; value: T };\n future: Array<{ label: string; value: T }>;\n}\n\nexport const HISTORY_LIMIT = 100;\n\nexport function startHistory<T>(value: T): History<T> {\n return { past: [], present: { label: \"\", value }, future: [] };\n}\n\nexport function pushStep<T>(h: History<T>, label: string, value: T, limit = HISTORY_LIMIT): History<T> {\n if (Object.is(h.present.value, value)) return h;\n const past = [...h.past, h.present].slice(-limit);\n return { past, present: { label, value }, future: [] };\n}\n\nexport function undo<T>(h: History<T>): History<T> {\n const prev = h.past[h.past.length - 1];\n if (!prev) return h;\n return { past: h.past.slice(0, -1), present: prev, future: [h.present, ...h.future] };\n}\n\nexport function redo<T>(h: History<T>): History<T> {\n const next = h.future[0];\n if (!next) return h;\n return { past: [...h.past, h.present], present: next, future: h.future.slice(1) };\n}\n\nexport const canUndo = (h: History<unknown>) => h.past.length > 0;\nexport const canRedo = (h: History<unknown>) => h.future.length > 0;\n/** The label of the step Undo would take back. */\nexport const undoLabel = (h: History<unknown>) => h.present.label;\nexport const redoLabel = (h: History<unknown>) => h.future[0]?.label ?? \"\";\n","/**\n * The workspace's markup model (PDF-PLAN U10). Pure: the markup tools as data (which are built,\n * which are coming and why), their keys, the palette, and the ONE session history that holds both\n * page decisions and markup steps, so Undo takes back whichever came last.\n *\n * What is built rides PDF.js's own annotation editors (highlight, text box, draw, image; a\n * signature is an image made on the platform's signature pad; a comment is the note on a piece of\n * markup). What PDF.js's writer cannot make yet is a \"Coming soon\" row with its reason, never a\n * dead button: underline and strike-out, shapes, a free-standing sticky note, links, editing the\n * page's own text.\n */\nimport type { ComingSoonEntry } from \"@ai-matrx/kit/coming-soon\";\nimport type { PdfMarkupKind, PdfMarkupStyle, PdfMarkupTool } from \"./markup-engine-port\";\n\nexport type PdfMarkupToolId = \"highlight\" | \"freetext\" | \"ink\" | \"image\" | \"signature\" | \"underline\" | \"shapes\" | \"note\" | \"links\" | \"edit-text\";\n\nexport interface PdfMarkupToolDef {\n id: PdfMarkupToolId;\n label: string;\n /** Single key, while the markup tool is open. */\n key?: string;\n status: \"ready\" | \"soon\";\n /** The PDF.js editor a ready tool turns on. */\n engineTool?: Exclude<PdfMarkupTool, \"none\">;\n /** Ready only when the host brings this port. */\n needs?: \"signaturePad\";\n /** Why a coming tool is not built (shown under its name, and in its Coming-soon promise). */\n reason?: string;\n}\n\nexport const PDF_MARKUP_TOOLS: readonly PdfMarkupToolDef[] = [\n { id: \"highlight\", label: \"Highlight\", key: \"h\", status: \"ready\", engineTool: \"highlight\" },\n { id: \"freetext\", label: \"Text box\", key: \"x\", status: \"ready\", engineTool: \"freetext\" },\n { id: \"ink\", label: \"Draw\", key: \"d\", status: \"ready\", engineTool: \"ink\" },\n { id: \"image\", label: \"Image\", key: \"i\", status: \"ready\", engineTool: \"stamp\" },\n { id: \"signature\", label: \"Signature\", key: \"g\", status: \"ready\", engineTool: \"stamp\", needs: \"signaturePad\" },\n { id: \"underline\", label: \"Underline and strike out\", status: \"soon\", reason: \"The PDF writer we use makes highlights only.\" },\n { id: \"shapes\", label: \"Shapes\", status: \"soon\", reason: \"Rectangles, ovals and arrows need their own writer.\" },\n { id: \"note\", label: \"Sticky note\", status: \"soon\", reason: \"Comment on a highlight, text box or drawing for now.\" },\n { id: \"links\", label: \"Links\", status: \"soon\", reason: \"The PDF writer we use cannot add or change links.\" },\n { id: \"edit-text\", label: \"Edit page text\", status: \"soon\", reason: \"Changing the page's own text needs a server edit with a before-and-after check.\" },\n];\n\nexport const pdfMarkupTool = (id: string): PdfMarkupToolDef | undefined => PDF_MARKUP_TOOLS.find((t) => t.id === id);\n\n/** The palette markup offers (Acrobat's comment colors). Literal colors are data: they are written into the PDF. */\nexport const MARKUP_SWATCHES: ReadonlyArray<{ value: string; label: string }> = [\n { value: \"#ffd400\", label: \"Yellow\" },\n { value: \"#5fe36b\", label: \"Green\" },\n { value: \"#4cc9f0\", label: \"Blue\" },\n { value: \"#ff6fb5\", label: \"Pink\" },\n { value: \"#ff4d4d\", label: \"Red\" },\n { value: \"#1f2937\", label: \"Black\" },\n];\n\n/** Which look controls a kind of markup has (the floating toolbar and the panel show only these). */\nexport const MARKUP_STYLE_FIELDS: Record<PdfMarkupKind, ReadonlyArray<keyof PdfMarkupStyle>> = {\n highlight: [\"color\"],\n freetext: [\"color\", \"size\"],\n ink: [\"color\", \"opacity\", \"size\"],\n stamp: [],\n signature: [],\n};\n\n/** Sizes offered: font sizes for a text box, stroke widths for a drawing (PDF points). */\nexport const MARKUP_SIZES: Record<\"freetext\" | \"ink\", readonly number[]> = {\n freetext: [8, 10, 12, 14, 18, 24, 36],\n ink: [1, 2, 3, 5, 8, 12],\n};\n\nexport const MARKUP_KIND_LABEL: Record<PdfMarkupKind, string> = {\n highlight: \"Highlight\",\n freetext: \"Text box\",\n ink: \"Drawing\",\n stamp: \"Image\",\n signature: \"Signature\",\n};\n\nconst MARKUP_PROMISES: Record<string, string> = {\n underline: \"Underline or strike out text, with the same colors as highlights.\",\n shapes: \"Draw rectangles, ovals, lines and arrows on a page.\",\n note: \"Pin a sticky note anywhere on a page.\",\n links: \"Add, change and remove links to a page or a web address.\",\n \"edit-text\": \"Change the page's own text, see a before-and-after view, then save.\",\n};\n\nexport const markupComingSoonId = (id: PdfMarkupToolId): string => (id === \"links\" ? \"pdf.links\" : id === \"edit-text\" ? \"pdf.edit-text\" : `pdf.markup.${id}`);\n\n/** One Coming-soon row per markup tool not built yet (merged into `PDF_COMING_SOON`). */\nexport const PDF_MARKUP_COMING_SOON: Record<string, ComingSoonEntry> = Object.fromEntries(\n PDF_MARKUP_TOOLS.filter((t) => t.status === \"soon\").map((t): [string, ComingSoonEntry] => {\n const id = markupComingSoonId(t.id);\n return [id, { id, label: t.label, owner: \"pdf\", promise: MARKUP_PROMISES[t.id] ?? \"\", stage: \"planned\", surfaces: [\"PDF workspace markup panel\"] }];\n }),\n);\n\n// ── the session's one history: which kind of step Undo takes back next ──────────────────────\n\nexport type StepOrigin = \"page\" | \"markup\";\nexport interface SessionTimeline {\n past: Array<{ origin: StepOrigin; label: string }>;\n future: Array<{ origin: StepOrigin; label: string }>;\n}\nexport const TIMELINE_LIMIT = 100;\nexport const emptyTimeline = (): SessionTimeline => ({ past: [], future: [] });\n\nexport function recordStep(t: SessionTimeline, origin: StepOrigin, label: string): SessionTimeline {\n return { past: [...t.past, { origin, label }].slice(-TIMELINE_LIMIT), future: [] };\n}\n/** The step Undo would take back, or null. */\nexport const nextUndo = (t: SessionTimeline) => t.past[t.past.length - 1] ?? null;\nexport const nextRedo = (t: SessionTimeline) => t.future[0] ?? null;\nexport function stepBack(t: SessionTimeline): SessionTimeline {\n const last = t.past[t.past.length - 1];\n return last ? { past: t.past.slice(0, -1), future: [last, ...t.future] } : t;\n}\nexport function stepForward(t: SessionTimeline): SessionTimeline {\n const next = t.future[0];\n return next ? { past: [...t.past, next], future: t.future.slice(1) } : t;\n}\n/** PDF.js undid a markup step on its own (its keys, focus outside the workspace): move the newest markup step back. */\nexport function markupUndoneElsewhere(t: SessionTimeline): SessionTimeline {\n for (let i = t.past.length - 1; i >= 0; i--) {\n if (t.past[i]!.origin === \"markup\") return { past: [...t.past.slice(0, i), ...t.past.slice(i + 1)], future: [t.past[i]!, ...t.future] };\n }\n return t;\n}\nexport function markupRedoneElsewhere(t: SessionTimeline): SessionTimeline {\n const i = t.future.findIndex((s) => s.origin === \"markup\");\n if (i < 0) return t;\n return { past: [...t.past, t.future[i]!], future: [...t.future.slice(0, i), ...t.future.slice(i + 1)] };\n}\n/** Saving (or discarding) one kind of change ends its steps: the file's versions are the durable undo. */\nexport function dropOrigin(t: SessionTimeline, origin: StepOrigin): SessionTimeline {\n return { past: t.past.filter((s) => s.origin !== origin), future: t.future.filter((s) => s.origin !== origin) };\n}\n","/**\n * The PDF workspace's tool rail, as data. Pure (no React, no icons): the host registers the\n * Coming-soon rows from here (`PDF_COMING_SOON`), the shell draws the rail from it, and the tests\n * check that the two agree.\n *\n * A tool is `ready` only where a real capability stands behind it today (`capability` names the\n * server operation or app route). Anything else is `soon`: the rail shows it plainly marked, and\n * choosing it announces its registered promise through `@ai-matrx/kit/coming-soon`. There is no\n * third state, so no dead button.\n */\nimport type { ComingSoonEntry } from \"@ai-matrx/kit/coming-soon\";\nimport { PDF_MARKUP_COMING_SOON } from \"./markup\";\n\nexport type PdfToolId =\n | \"browse\"\n | \"markup\"\n | \"organize\"\n | \"extract-pages\"\n | \"split\"\n | \"crop\"\n | \"redact\"\n | \"compress\"\n | \"scan\"\n | \"sign\"\n | \"extract-data\"\n | \"edit\"\n | \"forms\"\n | \"protect\"\n | \"ocr\"\n | \"convert\"\n | \"compare\"\n | \"stamp\";\n\nexport interface PdfToolDef {\n id: PdfToolId;\n label: string;\n /** Single-key shortcut that picks the tool (shown in the tooltip and the shortcut map). */\n key?: string;\n status: \"ready\" | \"soon\";\n /** The server operation or route behind a ready tool; the wiring test reads it. */\n capability?: string;\n /** What choosing a ready tool does: show its panel, or leave for another page. */\n opens: \"panel\" | \"page\" | \"none\";\n group: 0 | 1 | 2;\n /** One short line under the panel title. */\n hint?: string;\n}\n\nexport const PDF_TOOLS: readonly PdfToolDef[] = [\n { id: \"browse\", label: \"Browse\", key: \"v\", status: \"ready\", opens: \"none\", group: 0 },\n { id: \"markup\", label: \"Comment and mark up\", key: \"m\", status: \"ready\", capability: \"client:pdfjs-annotation-editors,save-new-version\", opens: \"panel\", group: 0, hint: \"Highlight, write, draw, sign. Saves a new version.\" },\n { id: \"organize\", label: \"Organize pages\", key: \"o\", status: \"ready\", capability: \"rotate-pages,delete-pages,reorder-pages\", opens: \"panel\", group: 0 },\n { id: \"extract-pages\", label: \"Extract pages\", key: \"e\", status: \"ready\", capability: \"extract-pages\", opens: \"panel\", group: 0 },\n { id: \"split\", label: \"Split\", key: \"s\", status: \"ready\", capability: \"split\", opens: \"panel\", group: 0 },\n { id: \"crop\", label: \"Crop pages\", key: \"c\", status: \"ready\", capability: \"crop-pages\", opens: \"panel\", group: 0 },\n { id: \"redact\", label: \"Redact\", key: \"r\", status: \"ready\", capability: \"redact-pattern\", opens: \"panel\", group: 1 },\n { id: \"compress\", label: \"Compress\", key: \"z\", status: \"ready\", capability: \"compress\", opens: \"panel\", group: 1 },\n { id: \"extract-data\", label: \"Text and tables\", key: \"t\", status: \"ready\", capability: \"extract-text-remote,extract-tables\", opens: \"panel\", group: 1 },\n { id: \"scan\", label: \"Scan\", status: \"ready\", capability: \"route:/tools/scanner\", opens: \"page\", group: 1 },\n { id: \"sign\", label: \"Sign\", status: \"ready\", capability: \"route:/esign/new\", opens: \"page\", group: 1 },\n { id: \"edit\", label: \"Edit text and images\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"forms\", label: \"Fill forms\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"protect\", label: \"Protect\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"ocr\", label: \"Recognize text\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"convert\", label: \"Convert\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"compare\", label: \"Compare\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"stamp\", label: \"Stamp and number\", status: \"soon\", opens: \"none\", group: 2 },\n];\n\nexport const pdfTool = (id: string): PdfToolDef | undefined => PDF_TOOLS.find((t) => t.id === id);\n\n/** The Coming-soon id of an unbuilt tool. */\nexport const comingSoonIdOf = (id: PdfToolId): string => `pdf.${id}`;\n\nconst PROMISES: Record<string, string> = {\n edit: \"Change the page's own text and swap images, with a before-and-after view.\",\n forms: \"Fill in a form and keep the values in the file.\",\n protect: \"Lock a PDF with a password and limit what others can do.\",\n ocr: \"Turn a scanned PDF into one you can search and copy from.\",\n convert: \"Turn a PDF into Word, Excel or PowerPoint, and back.\",\n compare: \"Put two versions side by side and see what changed.\",\n stamp: \"Add watermarks, page numbers and Bates numbers.\",\n};\n\nconst PANEL_PROMISES: Record<string, ComingSoonEntry> = {\n \"pdf.layers\": {\n id: \"pdf.layers\",\n label: \"Layers\",\n owner: \"pdf\",\n promise: \"Show or hide the layers inside a PDF.\",\n stage: \"planned\",\n surfaces: [\"PDF workspace page panel\"],\n },\n};\n\n/** One row per unbuilt tool, ready for `registerComingSoon` or the host's registry table. */\nexport const PDF_COMING_SOON: Record<string, ComingSoonEntry> = {\n ...Object.fromEntries(\n PDF_TOOLS.filter((t) => t.status === \"soon\").map((t): [string, ComingSoonEntry] => {\n const id = comingSoonIdOf(t.id);\n return [id, { id, label: t.label, owner: \"pdf\", promise: PROMISES[t.id] ?? \"\", stage: \"planned\", surfaces: [\"PDF workspace tool rail\"] }];\n }),\n ),\n ...PANEL_PROMISES,\n ...PDF_MARKUP_COMING_SOON,\n};\n","/**\n * The PDF workspace's one keyboard map. A shortcut is data: the shell mounts ONE key handler that\n * asks `matchShortcut` for the action, and the shortcuts popover lists the same rows, so the map\n * on screen and the keys that work cannot drift (the test fires every documented key).\n */\nimport { PDF_TOOLS } from \"./tools\";\nimport { PDF_MARKUP_TOOLS, type PdfMarkupToolId } from \"./markup\";\n\nexport type PdfActionId =\n | \"undo\" | \"redo\" | \"find\" | \"print\" | \"save\"\n | \"zoom-in\" | \"zoom-out\" | \"zoom-fit-width\" | \"zoom-fit-page\"\n | \"page-next\" | \"page-prev\" | \"page-first\" | \"page-last\"\n | \"rotate-right\" | \"rotate-left\" | \"delete-pages\" | \"select-all-pages\"\n | \"toggle-pages\" | \"toggle-properties\" | \"read-mode\" | \"two-up\" | \"shortcuts\"\n | `tool:${string}`;\n\nexport interface PdfShortcut {\n action: PdfActionId;\n label: string;\n /** Display keys: \"Mod+Z\" shows as Cmd+Z on a Mac and Ctrl+Z elsewhere. */\n keys: string;\n section: \"Edit\" | \"View\" | \"Pages\" | \"Tools\" | \"Markup\";\n}\n\nexport const PDF_SHORTCUTS: readonly PdfShortcut[] = [\n { action: \"undo\", label: \"Undo\", keys: \"Mod+Z\", section: \"Edit\" },\n { action: \"redo\", label: \"Redo\", keys: \"Mod+Shift+Z\", section: \"Edit\" },\n { action: \"save\", label: \"Save markup or apply page changes\", keys: \"Mod+S\", section: \"Edit\" },\n { action: \"find\", label: \"Find\", keys: \"Mod+F\", section: \"Edit\" },\n { action: \"print\", label: \"Print\", keys: \"Mod+P\", section: \"Edit\" },\n { action: \"zoom-in\", label: \"Zoom in\", keys: \"Mod+=\", section: \"View\" },\n { action: \"zoom-out\", label: \"Zoom out\", keys: \"Mod+-\", section: \"View\" },\n { action: \"zoom-fit-width\", label: \"Fit width\", keys: \"Mod+1\", section: \"View\" },\n { action: \"zoom-fit-page\", label: \"Fit page\", keys: \"Mod+0\", section: \"View\" },\n { action: \"two-up\", label: \"Two pages side by side\", keys: \"Mod+Shift+2\", section: \"View\" },\n { action: \"read-mode\", label: \"Reading mode\", keys: \"Mod+Shift+H\", section: \"View\" },\n { action: \"toggle-pages\", label: \"Page thumbnails\", keys: \"Mod+Shift+T\", section: \"View\" },\n { action: \"toggle-properties\", label: \"Properties panel\", keys: \"Mod+Shift+P\", section: \"View\" },\n { action: \"shortcuts\", label: \"Keyboard shortcuts\", keys: \"?\", section: \"View\" },\n { action: \"page-next\", label: \"Next page\", keys: \"ArrowRight\", section: \"Pages\" },\n { action: \"page-prev\", label: \"Previous page\", keys: \"ArrowLeft\", section: \"Pages\" },\n { action: \"page-first\", label: \"First page\", keys: \"Home\", section: \"Pages\" },\n { action: \"page-last\", label: \"Last page\", keys: \"End\", section: \"Pages\" },\n { action: \"select-all-pages\", label: \"Select all pages\", keys: \"Mod+A\", section: \"Pages\" },\n { action: \"rotate-right\", label: \"Rotate selected pages right\", keys: \"Mod+]\", section: \"Pages\" },\n { action: \"rotate-left\", label: \"Rotate selected pages left\", keys: \"Mod+[\", section: \"Pages\" },\n { action: \"delete-pages\", label: \"Delete selected pages\", keys: \"Delete\", section: \"Pages\" },\n ...PDF_TOOLS.filter((t) => t.key && t.status === \"ready\").map((t): PdfShortcut => ({\n action: `tool:${t.id}`,\n label: t.label,\n keys: t.key!.toUpperCase(),\n section: \"Tools\",\n })),\n];\n\n/**\n * Keys that work only while \"Comment and mark up\" is open (they pick a markup tool). Listed in the\n * shortcut map under Markup; Delete, the arrows and Escape act on the selected markup there.\n */\nexport const PDF_MARKUP_SHORTCUTS: ReadonlyArray<{ tool: PdfMarkupToolId; label: string; keys: string }> = PDF_MARKUP_TOOLS.filter(\n (t) => t.status === \"ready\" && t.key,\n).map((t) => ({ tool: t.id, label: t.label, keys: t.key!.toUpperCase() }));\n\n/** The markup tool a plain key picks while markup is open, or null. */\nexport function matchMarkupKey(e: KeyLike, typing: boolean): PdfMarkupToolId | null {\n if (typing || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.key.length !== 1) return null;\n const k = e.key.toLowerCase();\n return PDF_MARKUP_SHORTCUTS.find((s) => s.keys.toLowerCase() === k)?.tool ?? null;\n}\n\nexport interface KeyLike {\n key: string;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n}\n\nfunction parse(keys: string) {\n const parts = keys.split(\"+\");\n const key = parts[parts.length - 1] === \"\" ? \"+\" : parts[parts.length - 1]!;\n return { mod: parts.includes(\"Mod\"), shift: parts.includes(\"Shift\"), key };\n}\n\nconst TYPING_PASSES = new Set<PdfActionId>([\"find\", \"save\", \"print\"]);\n\n/** The action a key press means, or null. Never matches while `typing` (a text field has the key). */\nexport function matchShortcut(e: KeyLike, typing: boolean): PdfActionId | null {\n const mod = e.ctrlKey || e.metaKey;\n const pressed = e.key.length === 1 ? e.key.toLowerCase() : e.key;\n for (const s of PDF_SHORTCUTS) {\n const want = parse(s.keys);\n const wantKey = want.key.length === 1 ? want.key.toLowerCase() : want.key;\n if (want.mod !== mod || e.altKey) continue;\n // \"?\" is typed with Shift; every other plain key must have no Shift unless the map says so.\n const shiftOk = want.key === \"?\" ? true : want.shift === e.shiftKey || (want.key === \"=\" && e.shiftKey && pressed === \"+\");\n if (!shiftOk) continue;\n if (pressed === wantKey || (want.key === \"=\" && pressed === \"+\")) {\n // A text field keeps its own keys (typing, its own undo, select all); only these still reach the shell.\n if (typing && !TYPING_PASSES.has(s.action)) return null;\n return s.action;\n }\n }\n return null;\n}\n\n/** \"Mod+Shift+Z\" → \"⌘⇧Z\" on a Mac, \"Ctrl+Shift+Z\" elsewhere. */\nexport function formatKeys(keys: string, mac: boolean): string {\n return keys\n .split(\"+\")\n .map((k) => (k === \"Mod\" ? (mac ? \"⌘\" : \"Ctrl\") : k === \"Shift\" ? (mac ? \"⇧\" : \"Shift\") : k === \"ArrowRight\" ? \"→\" : k === \"ArrowLeft\" ? \"←\" : k))\n .join(mac ? \"\" : \"+\");\n}\n","\"use client\";\n\n/**\n * Markup chrome (PDF-PLAN U10): the \"Comment and mark up\" panel and the floating toolbar over the\n * selected piece of markup. Both drive the viewer's PDF.js editors through `PdfMarkupEngine`; the\n * shell owns saving, undo and the leave-page guard.\n *\n * Panel: the tools (built ones pick an editor; coming ones announce their promise and say why\n * they wait), the look of the next piece, what is pending with Save and Discard, and the\n * annotations already in the file. Floating toolbar: the design system's AnchoredToolbar (portaled,\n * positioned fixed, so it never moves the page) with color, opacity, size, a comment and Delete.\n */\nimport { useEffect, useState } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { AnchoredToolbar, Button, ColorSwatchRow, Field, OpacitySlider, Select, Tile } from \"@ai-matrx/design-system/controls\";\nimport {\n HighlighterIcon,\n ImageIcon,\n Link2Icon,\n MessageSquareIcon,\n PencilIcon,\n PenToolIcon,\n ProportionsIcon,\n StickyNoteIcon,\n Trash2Icon,\n TypeIcon,\n WrapTextIcon,\n} from \"@ai-matrx/design-system/icons\";\nimport type { PdfMarkupEngine, PdfMarkupSnapshot, PdfMarkupStyle } from \"./markup-engine-port\";\nimport { MARKUP_KIND_LABEL, MARKUP_SIZES, MARKUP_STYLE_FIELDS, MARKUP_SWATCHES, PDF_MARKUP_TOOLS, markupComingSoonId, type PdfMarkupToolDef, type PdfMarkupToolId } from \"./markup\";\nimport type { PdfWorkspaceHost } from \"./ports\";\n\ntype Glyph = React.ComponentType<{ className?: string }>;\nconst MARKUP_ICONS: Record<PdfMarkupToolId, Glyph> = {\n highlight: HighlighterIcon,\n freetext: TypeIcon,\n ink: PencilIcon,\n image: ImageIcon,\n signature: PenToolIcon,\n underline: WrapTextIcon,\n shapes: ProportionsIcon,\n note: StickyNoteIcon,\n links: Link2Icon,\n \"edit-text\": TypeIcon,\n};\n\nfunction Section({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">{label}</span>\n {children}\n </div>\n );\n}\n\n/** The look controls for one kind of markup (shared by the panel and the floating toolbar). */\nfunction StyleControls({ kind, style, onChange, compact }: { kind: keyof typeof MARKUP_STYLE_FIELDS; style: PdfMarkupStyle; onChange(patch: Partial<PdfMarkupStyle>): void; compact?: boolean }) {\n const fields = MARKUP_STYLE_FIELDS[kind];\n if (!fields.length) return null;\n const sizes = kind === \"freetext\" ? MARKUP_SIZES.freetext : kind === \"ink\" ? MARKUP_SIZES.ink : null;\n return (\n <div className={cn(\"flex gap-2\", compact ? \"items-center\" : \"flex-col\")}>\n {fields.includes(\"color\") ? <ColorSwatchRow colors={MARKUP_SWATCHES} value={style.color} onChange={(color) => onChange({ color })} aria-label=\"Color\" /> : null}\n {fields.includes(\"opacity\") ? (\n <div className={compact ? \"w-52 shrink-0\" : \"w-full min-w-0\"}>\n <OpacitySlider value={style.opacity} onChange={(opacity) => onChange({ opacity })} className=\"w-full\" />\n </div>\n ) : null}\n {fields.includes(\"size\") && sizes ? (\n <div className={compact ? \"w-24 shrink-0\" : undefined}>\n <Select\n aria-label={kind === \"freetext\" ? \"Font size\" : \"Line width\"}\n value={String(sizes.includes(style.size) ? style.size : sizes[0])}\n onValueChange={(v: string) => onChange({ size: Number(v) })}\n options={sizes.map((n) => ({ value: String(n), label: `${n} pt` }))}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface MarkupPanelProps {\n host: PdfWorkspaceHost;\n engine: PdfMarkupEngine | null;\n snapshot: PdfMarkupSnapshot | null;\n active: PdfMarkupToolId;\n onPick(tool: PdfMarkupToolId): void;\n /** A ready-tool row was blocked (page changes pending): the sentence to show. */\n blocked: string | null;\n busy: boolean;\n online: boolean;\n error: string | null;\n onSave(): void;\n onDiscard(): void;\n onSoon(id: string): void;\n goToPage(n: number): void;\n reloadKey: number;\n}\n\nexport function MarkupPanel({ host, engine, snapshot, active, onPick, blocked, busy, online, error, onSave, onDiscard, onSoon, goToPage, reloadKey }: MarkupPanelProps) {\n const [confirmDiscard, setConfirmDiscard] = useState(false);\n const [signature, setSignature] = useState<string | null>(null);\n const [existing, setExisting] = useState<Awaited<ReturnType<NonNullable<PdfWorkspaceHost[\"existingAnnotations\"]>>> | null>(null);\n const pending = snapshot?.pending ?? 0;\n const tools = PDF_MARKUP_TOOLS.filter((t) => t.needs !== \"signaturePad\" || host.signaturePad);\n const ready = tools.filter((t) => t.status === \"ready\");\n const soon = tools.filter((t) => t.status === \"soon\");\n const def = tools.find((t) => t.id === active);\n const styleKind = def?.engineTool && def.engineTool !== \"stamp\" ? def.engineTool : null;\n const Pad = host.signaturePad;\n\n useEffect(() => {\n let live = true;\n host.existingAnnotations?.().then((list) => live && setExisting(list), () => live && setExisting([]));\n return () => { live = false; };\n }, [host, reloadKey]);\n useEffect(() => { if (!pending) setConfirmDiscard(false); }, [pending]);\n\n const pickImage = () => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/png,image/jpeg,image/webp,image/gif,image/svg+xml\";\n input.onchange = () => {\n const f = input.files?.[0];\n if (f && engine) void engine.addImage(f, \"stamp\");\n };\n input.click();\n };\n const row = (t: PdfMarkupToolDef) => {\n const Icon = MARKUP_ICONS[t.id];\n const on = t.id === active;\n return (\n <li key={t.id}>\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n title={t.label}\n icon={<Icon />}\n end={t.status === \"soon\" ? <span className=\"shrink-0 whitespace-nowrap text-muted-foreground\">Soon</span> : <kbd className=\"text-muted-foreground\">{t.key?.toUpperCase()}</kbd>}\n {...(t.status === \"ready\" ? { selected: on } : {})}\n disabled={t.status === \"ready\" && (!engine || Boolean(blocked))}\n onClick={() => (t.status === \"soon\" ? onSoon(markupComingSoonId(t.id)) : onPick(t.id))}\n className=\"w-full\"\n />\n {t.status === \"soon\" && t.reason ? <div className=\"pl-8 pr-2 text-xs text-muted-foreground\">{t.reason}</div> : null}\n </li>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-4\" data-pdf-markup-panel=\"\">\n {blocked ? <div role=\"status\" className=\"rounded-md border border-border px-2 py-1.5 text-xs\">{blocked}</div> : null}\n {!engine && !blocked ? <div className=\"text-xs text-muted-foreground\">Opening the document…</div> : null}\n <ul className=\"flex flex-col\" aria-label=\"Markup tools\">{ready.map(row)}</ul>\n\n {styleKind && snapshot ? (\n <Section label=\"Look\">\n <StyleControls kind={styleKind} style={snapshot.styles[styleKind]} onChange={(p) => engine?.setStyle(p)} />\n </Section>\n ) : null}\n {active === \"highlight\" ? <div className=\"text-xs text-muted-foreground\">Select text on the page to highlight it.</div> : null}\n {active === \"freetext\" ? <div className=\"text-xs text-muted-foreground\">Click on the page, then type.</div> : null}\n {active === \"ink\" ? <div className=\"text-xs text-muted-foreground\">Drag on the page to draw.</div> : null}\n {active === \"image\" ? (\n <Button variant=\"outline\" icon={<ImageIcon />} disabled={!engine} onClick={pickImage}>Choose an image</Button>\n ) : null}\n {active === \"signature\" && Pad ? (\n <Section label=\"Signature\">\n <Pad value={signature} onChange={setSignature} />\n <Button variant=\"outline\" icon={<PenToolIcon />} disabled={!engine || !signature} onClick={() => signature && engine && void engine.addImage(signature, \"signature\")}>\n Place on page\n </Button>\n </Section>\n ) : null}\n\n <Section label=\"Changes\">\n <div className=\"text-xs\" role=\"status\" data-pdf-markup-pending=\"\">{pending ? `Not saved: ${snapshot?.summary}` : \"No unsaved markup\"}</div>\n {error ? <div role=\"alert\" className=\"text-xs text-destructive\">{error}</div> : null}\n {!online ? <div className=\"text-xs text-muted-foreground\">You are offline. Markup is kept here until you are back online.</div> : null}\n <div className=\"flex gap-2\">\n <Button variant=\"primary\" disabled={!pending || busy || !online} onClick={onSave}>{busy ? \"Saving\" : \"Save\"}</Button>\n {confirmDiscard ? (\n <>\n <Button variant=\"outline\" onClick={() => { setConfirmDiscard(false); onDiscard(); }}>Discard {pending}</Button>\n <Button variant=\"quiet\" onClick={() => setConfirmDiscard(false)}>Keep</Button>\n </>\n ) : (\n <Button variant=\"outline\" disabled={!pending || busy} onClick={() => setConfirmDiscard(true)}>Discard</Button>\n )}\n </div>\n </Section>\n\n {host.existingAnnotations ? (\n <Section label=\"In this file\">\n {existing === null ? (\n <div className=\"text-xs text-muted-foreground\">Reading…</div>\n ) : existing.filter((a) => a.subtype !== \"Link\" && a.subtype !== \"Widget\").length === 0 ? (\n <div className=\"text-xs text-muted-foreground\">No comments or markup yet</div>\n ) : (\n <ul className=\"flex flex-col\" aria-label=\"Annotations in this file\">\n {existing.filter((a) => a.subtype !== \"Link\" && a.subtype !== \"Widget\").map((a, i) => (\n <li key={`${a.page}-${i}`}>\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n title={`${a.subtype}${a.author ? ` · ${a.author}` : \"\"}`}\n line={a.contents}\n icon={<span className=\"w-8 shrink-0 tabular-nums text-muted-foreground\">p. {a.page}</span>}\n className=\"w-full\"\n onClick={() => goToPage(a.page)}\n />\n </li>\n ))}\n </ul>\n )}\n <div className=\"text-xs text-muted-foreground\">Markup already saved shows on the page; changing it in place is coming.</div>\n </Section>\n ) : null}\n\n <Section label=\"Coming soon\">\n <ul className=\"flex flex-col\" aria-label=\"Markup coming soon\">{soon.map(row)}</ul>\n </Section>\n </div>\n );\n}\n\n/** The floating toolbar over the selected piece of markup. */\nexport function MarkupFloatingToolbar({ engine, snapshot, enabled, onDone }: { engine: PdfMarkupEngine | null; snapshot: PdfMarkupSnapshot | null; enabled: boolean; onDone(): void }) {\n const sel = snapshot?.selection ?? null;\n const [commenting, setCommenting] = useState(false);\n const [draft, setDraft] = useState(\"\");\n const selKey = sel ? `${sel.kind}:${Math.round(sel.rect.x)}:${Math.round(sel.rect.y)}` : \"\";\n useEffect(() => {\n setCommenting(false);\n setDraft(sel?.comment ?? \"\");\n // A new selection starts closed, with its own comment.\n }, [selKey]); // eslint-disable-line react-hooks/exhaustive-deps\n if (!engine || !enabled || !sel) return null;\n return (\n <AnchoredToolbar open rect={sel.rect} aria-label={`${MARKUP_KIND_LABEL[sel.kind]} options`}>\n <div className=\"flex items-center gap-2\" data-pdf-markup-toolbar=\"\">\n <StyleControls compact kind={sel.kind} style={sel.style} onChange={(p) => engine.setStyle(p)} />\n {commenting ? (\n <Field\n autoFocus\n value={draft}\n aria-label=\"Comment\"\n placeholder=\"Comment\"\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n // Focus goes back to the page, so the workspace's keys (Save, Undo) keep working.\n if (e.key === \"Enter\") { engine.setComment(draft); setCommenting(false); onDone(); }\n if (e.key === \"Escape\") { e.stopPropagation(); setCommenting(false); onDone(); }\n }}\n onBlur={() => { engine.setComment(draft); setCommenting(false); }}\n width=\"md\"\n />\n ) : (\n <Button variant=\"quiet\" icon={<MessageSquareIcon />} aria-label={sel.comment ? \"Edit comment\" : \"Add comment\"} title={sel.comment || \"Add comment\"} pressed={Boolean(sel.comment)} onClick={() => setCommenting(true)} />\n )}\n <Button variant=\"quiet\" icon={<Trash2Icon />} aria-label=\"Delete\" title=\"Delete\" onClick={() => engine.deleteSelected()} />\n </div>\n </AnchoredToolbar>\n );\n}\n","import type { ComponentType } from \"react\";\nimport {\n ArrowLeftRightIcon,\n ArrowUpFromLineIcon,\n CameraIcon,\n CaptionsIcon,\n ChevronsDownUpIcon,\n Columns2Icon,\n EraserIcon,\n FlagIcon,\n HandIcon,\n LayoutGridIcon,\n ListChecksIcon,\n LockIcon,\n MessageSquareIcon,\n PencilIcon,\n PenToolIcon,\n ProportionsIcon,\n SplitIcon,\n TypeIcon,\n} from \"@ai-matrx/design-system/icons\";\nimport type { PdfToolId } from \"./tools\";\n\ntype Glyph = ComponentType<{ className?: string }>;\n\n/** One glyph per rail tool, from the design system's glyph home (sized by the control, not here). */\nexport const PDF_TOOL_ICONS: Record<PdfToolId, Glyph> = {\n browse: HandIcon,\n markup: MessageSquareIcon,\n organize: LayoutGridIcon,\n \"extract-pages\": ArrowUpFromLineIcon,\n split: SplitIcon,\n crop: ProportionsIcon,\n redact: EraserIcon,\n compress: ChevronsDownUpIcon,\n scan: CameraIcon,\n sign: PenToolIcon,\n \"extract-data\": TypeIcon,\n edit: PencilIcon,\n forms: ListChecksIcon,\n protect: LockIcon,\n ocr: CaptionsIcon,\n convert: ArrowLeftRightIcon,\n compare: Columns2Icon,\n stamp: FlagIcon,\n};\n"],"mappings":"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","names":["import_react","import_cn","import_controls","import_icons","import_react","import_controls","import_jsx_runtime","import_react","import_controls","import_jsx_runtime","import_icons","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/pdf/index.ts","../src/pdf/PdfWorkspace.tsx","../src/pdf/page-decisions.ts","../src/pdf/left-panel.tsx","../src/pdf/panels.tsx","../src/pdf/session-history.ts","../src/pdf/markup.ts","../src/pdf/tools.ts","../src/pdf/shortcuts.ts","../src/pdf/markup-panel.tsx","../src/pdf/tool-icons.tsx"],"sourcesContent":["\"use client\";\n\nexport { PdfWorkspace, type PdfWorkspaceProps } from \"./PdfWorkspace\";\nexport type { PdfViewerState, PdfWorkspaceHost } from \"./model\";\nexport * from \"./model\";\n","\"use client\";\n\n/**\n * PdfWorkspace — the Acrobat-style shell for one PDF: top bar (name, save state, tools search, undo,\n * share, download, print), tools rail, page panel (thumbnails, layers), the windowed viewer in the\n * middle, a properties panel on the right, a find bar, a keyboard map and a reading mode.\n *\n * The package owns the chrome and the session (page decisions with undo/redo, zoom, selection). The\n * host injects the viewer and every server call through `PdfWorkspaceHost`. Overlays (find, print,\n * shortcuts, tool search, sheets) are absolutely positioned inside the shell, so opening one never\n * moves the page; every bar has a fixed height and every panel a fixed width.\n */\nimport { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { Button, Field, PageRangeInput, SegmentedControl, Tile, ToolRail, parsePageRanges, type ToolRailItem } from \"@ai-matrx/design-system/controls\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DownloadIcon,\n KeyboardIcon,\n MinusIcon,\n MoreHorizontalIcon,\n PanelLeftIcon,\n PanelRightIcon,\n PlusIcon,\n PrinterIcon,\n RotateCcwIcon,\n RotateCwIcon,\n SearchIcon,\n Share2Icon,\n Trash2Icon,\n Undo2Icon,\n XIcon,\n Columns2Icon,\n ExpandIcon,\n} from \"@ai-matrx/design-system/icons\";\nimport { RenderedFindBar } from \"@ai-matrx/rich-content/rich-document/search/RenderedFindBar\";\nimport { compilePageOps, deletePages, freshDecisions, isDirty, reorderPages, restorePages, turnPages, type PageDecisions } from \"./page-decisions\";\nimport { LeftPanel, type LeftTab } from \"./left-panel\";\nimport { ToolPanel } from \"./panels\";\nimport type { PdfHostTool, PdfRunRequest, PdfRunResult, PdfWorkspaceHost } from \"./ports\";\nimport { canRedo, canUndo, pushStep, redo, redoLabel, startHistory, undo, undoLabel, type History } from \"./session-history\";\nimport { PDF_MARKUP_SHORTCUTS, PDF_SHORTCUTS, formatKeys, matchMarkupKey, matchShortcut, type PdfActionId } from \"./shortcuts\";\nimport { MarkupFloatingToolbar, MarkupPanel } from \"./markup-panel\";\nimport { dropOrigin, emptyTimeline, markupRedoneElsewhere, markupUndoneElsewhere, nextRedo, nextUndo, pdfMarkupTool, recordStep, stepBack, stepForward, type PdfMarkupToolId, type SessionTimeline } from \"./markup\";\nimport type { PdfMarkupEngine, PdfMarkupSnapshot } from \"./markup-engine-port\";\nimport { PDF_TOOL_ICONS } from \"./tool-icons\";\nimport { PDF_TOOLS, comingSoonIdOf, pdfTool, type PdfToolDef, type PdfToolId } from \"./tools\";\n\nconst ZOOM_STEPS = [0.5, 0.75, 1, 1.25, 1.5, 2, 3] as const;\nconst COMPACT_BELOW_PX = 768;\nconst BAR = \"flex h-10 shrink-0 items-center gap-1 border-b border-border bg-background px-2\";\n\ntype ZoomMode = \"fit-width\" | \"fit-page\" | \"custom\";\ntype Sheet = \"tools\" | \"pages\" | null;\ntype Pop = \"print\" | \"shortcuts\" | \"tool-search\" | \"all-tools\" | null;\nconst ALL_TOOLS = \"all-tools\";\n\nconst isMac = () => typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\nconst clampZoom = (z: number) => Math.min(3, Math.max(0.5, z));\n\nasync function announceSoon(id: string) {\n const { announceComingSoon } = await import(\"@ai-matrx/kit/coming-soon\");\n await announceComingSoon(id);\n}\n\nfunction useWidth(ref: React.RefObject<HTMLElement | null>) {\n const [size, setSize] = useState({ w: 1200, h: 800 });\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) return undefined;\n const measure = () => setSize({ w: node.clientWidth || 1200, h: node.clientHeight || 800 });\n measure();\n if (typeof ResizeObserver === \"undefined\") return undefined;\n const ro = new ResizeObserver(measure);\n ro.observe(node);\n return () => ro.disconnect();\n }, [ref]);\n return size;\n}\n\n/** The tool list shared by the \"All tools\" menu and the phone sheet: a glyph, the name, and \"Coming soon\" where it is not built. */\nfunction ToolRows({ tool, hostTools, onPick, canMarkup = false }: { tool: string; hostTools: readonly PdfHostTool[]; onPick(id: string): void; canMarkup?: boolean }) {\n return (\n <>\n {hostTools.map((t) => (\n <li key={`host:${t.id}`} role=\"none\">\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n role=\"menuitem\"\n aria-current={tool === `host:${t.id}` ? \"true\" : undefined}\n title={t.label}\n icon={<t.icon />}\n className=\"w-full\"\n onClick={() => onPick(`host:${t.id}`)}\n />\n </li>\n ))}\n {PDF_TOOLS.filter((t) => t.id !== \"browse\" && (t.id !== \"markup\" || canMarkup)).map((t) => {\n const Icon = PDF_TOOL_ICONS[t.id];\n return (\n <li key={t.id} role=\"none\">\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n role=\"menuitem\"\n aria-current={t.id === tool ? \"true\" : undefined}\n title={t.label}\n icon={<Icon />}\n end={t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : undefined}\n className=\"w-full\"\n onClick={() => onPick(t.id)}\n />\n </li>\n );\n })}\n </>\n );\n}\n\nexport interface PdfWorkspaceProps {\n host: PdfWorkspaceHost;\n className?: string;\n}\n\nexport function PdfWorkspace({ host, className }: PdfWorkspaceProps) {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const scrollerRef = useRef<HTMLDivElement | null>(null);\n const rootSize = useWidth(rootRef);\n const viewSize = useWidth(scrollerRef);\n const compact = rootSize.w < COMPACT_BELOW_PX;\n const online = host.online !== false;\n\n const [pageCount, setPageCount] = useState(0);\n const [history, setHistory] = useState<History<PageDecisions>>(() => startHistory(freshDecisions(0)));\n const decisions = history.present.value;\n const dirty = isDirty(decisions);\n const [tool, setTool] = useState<PdfToolId>(\"browse\");\n const [hostToolId, setHostToolId] = useState<string | null>(null);\n const hostTools = useMemo<readonly PdfHostTool[]>(() => host.tools ?? [], [host.tools]);\n const hostTool = hostToolId ? hostTools.find((t) => t.id === hostToolId) ?? null : null;\n const activeToolKey = hostTool ? `host:${hostTool.id}` : tool;\n const [leftOpen, setLeftOpen] = useState(true);\n const [rightOpen, setRightOpen] = useState(true);\n const [leftTab, setLeftTab] = useState<LeftTab>(\"pages\");\n const [read, setRead] = useState(false);\n const [spread, setSpread] = useState<\"single\" | \"two-up\">(\"single\");\n const [zoomMode, setZoomMode] = useState<ZoomMode>(\"fit-width\");\n const [customZoom, setCustomZoom] = useState(1);\n const [selected, setSelected] = useState<string[]>([]);\n const [currentPage, setCurrentPage] = useState(1);\n const [pageDraft, setPageDraft] = useState(\"1\");\n const [findOpen, setFindOpen] = useState(false);\n const [findFocus, setFindFocus] = useState(0);\n const [pop, setPop] = useState<Pop>(null);\n const [sheet, setSheet] = useState<Sheet>(null);\n const [toolQuery, setToolQuery] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<PdfRunResult | null>(null);\n const [reloadKey, setReloadKey] = useState(0);\n const [sizeVersion, setSizeVersion] = useState(0);\n const sizes = useRef(new Map<number, { w: number; h: number }>());\n const [editingName, setEditingName] = useState(false);\n const [nameDraft, setNameDraft] = useState(host.file.name);\n const [printMode, setPrintMode] = useState<\"all\" | \"pages\">(\"all\");\n const [printRange, setPrintRange] = useState(\"\");\n // ── markup: PDF.js's editors in the viewer, one history with the page decisions ──\n const canMarkup = Boolean(host.saveMarkup);\n const [engine, setEngine] = useState<PdfMarkupEngine | null>(null);\n const [snap, setSnap] = useState<PdfMarkupSnapshot | null>(null);\n const [timeline, setTimeline] = useState<SessionTimeline>(emptyTimeline);\n const [markupTool, setMarkupTool] = useState<PdfMarkupToolId>(\"highlight\");\n const [markupBusy, setMarkupBusy] = useState(false);\n const [markupError, setMarkupError] = useState<string | null>(null);\n const markupPending = snap?.pending ?? 0;\n\n const selectedPages = useMemo(() => selected.map(Number).sort((a, b) => a - b), [selected]);\n const toolDef = pdfTool(tool) as PdfToolDef;\n\n // ── zoom ────────────────────────────────────────────────────────────────\n const first = sizes.current.get(1);\n const fitPage = useMemo(() => {\n void sizeVersion;\n if (!first) return 1;\n const ratio = first.h / first.w;\n const cols = spread === \"two-up\" ? 2 : 1;\n const availH = Math.max(120, viewSize.h - 32);\n return clampZoom((availH * cols) / (Math.max(1, viewSize.w) * ratio) );\n }, [first, spread, viewSize.h, viewSize.w, sizeVersion]);\n const zoom = zoomMode === \"fit-width\" ? 1 : zoomMode === \"fit-page\" ? fitPage : customZoom;\n const stepZoom = useCallback(\n (dir: 1 | -1) => {\n const cur = zoomMode === \"fit-width\" ? 1 : zoomMode === \"fit-page\" ? fitPage : customZoom;\n const next = dir > 0 ? ZOOM_STEPS.find((s) => s > cur + 0.01) : [...ZOOM_STEPS].reverse().find((s) => s < cur - 0.01);\n if (next === undefined) return;\n setCustomZoom(next);\n setZoomMode(\"custom\");\n },\n [zoomMode, fitPage, customZoom],\n );\n\n // ── pages ───────────────────────────────────────────────────────────────\n const goToPage = useCallback(\n (n: number) => {\n const page = Math.min(Math.max(1, Math.round(n)), Math.max(1, pageCount));\n setCurrentPage(page);\n setPageDraft(String(page));\n const el = scrollerRef.current?.querySelector<HTMLElement>(`[data-pdf-page=\"${page}\"]`);\n el?.scrollIntoView?.({ block: \"start\" });\n },\n [pageCount],\n );\n useEffect(() => {\n const node = scrollerRef.current;\n if (!node) return undefined;\n let raf = 0;\n const onScroll = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const top = node.getBoundingClientRect().top + 8;\n const els = node.querySelectorAll<HTMLElement>(\"[data-pdf-page]\");\n let lo = 0;\n let hi = els.length - 1;\n // Pages are in reading order: the current page is the last one whose top is above the view's top.\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (els[mid]!.getBoundingClientRect().top <= top) lo = mid;\n else hi = mid - 1;\n }\n const n = Number(els[lo]?.dataset.pdfPage ?? 1);\n setCurrentPage((prev) => (prev === n ? prev : n));\n setPageDraft(String(n));\n });\n };\n node.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => {\n node.removeEventListener(\"scroll\", onScroll);\n cancelAnimationFrame(raf);\n };\n }, [pageCount]);\n\n // ── decisions and the session stack ─────────────────────────────────────\n const commit = useCallback((label: string, next: PageDecisions) => {\n setHistory((h) => pushStep(h, label, next));\n setTimeline((t) => recordStep(t, \"page\", label));\n }, []);\n const targets = useCallback(() => (selectedPages.length ? selectedPages : [currentPage]), [selectedPages, currentPage]);\n const turn = useCallback(\n (by: 90 | -90) => {\n const t = targets();\n commit(`Rotate ${t.length === 1 ? `page ${t[0]}` : `${t.length} pages`}`, turnPages(decisions, t, by));\n },\n [targets, commit, decisions],\n );\n const del = useCallback(() => {\n const t = targets();\n commit(`Delete ${t.length === 1 ? `page ${t[0]}` : `${t.length} pages`}`, deletePages(decisions, t));\n }, [targets, commit, decisions]);\n const restore = useCallback(() => {\n const t = targets();\n commit(`Restore ${t.length === 1 ? `page ${t[0]}` : `${t.length} pages`}`, restorePages(decisions, t));\n }, [targets, commit, decisions]);\n\n const onDocumentLoad = useCallback((n: number) => {\n setPageCount(n);\n setHistory((h) => (h.present.value.order.length === n ? h : startHistory(freshDecisions(n))));\n }, []);\n const onPageSize = useCallback((page: number, w: number, h: number) => {\n const prev = sizes.current.get(page);\n if (prev && prev.w === w && prev.h === h) return;\n sizes.current.set(page, { w, h });\n // The viewer reports sizes while it renders: never set state in that call stack.\n if (page === 1) queueMicrotask(() => setSizeVersion((v) => v + 1));\n }, []);\n\n // ── running things on the server ────────────────────────────────────────\n const fail = useCallback(\n (e: unknown) => {\n const message = e instanceof Error ? e.message : \"That did not work.\";\n setError(message);\n host.notify?.(message, \"error\");\n },\n [host],\n );\n const runTool = useCallback(\n async (request: PdfRunRequest) => {\n if (!online) {\n setError(\"You are offline. Changes are not queued; try again when you are back online.\");\n return;\n }\n setBusy(true);\n setError(null);\n setResult(null);\n try {\n const out = await host.run(request);\n setResult(out);\n if (out.kind === \"replaced\") {\n setHistory(startHistory(freshDecisions(pageCount)));\n setSelected([]);\n sizes.current.clear();\n setReloadKey((k) => k + 1);\n }\n } catch (e) {\n fail(e);\n } finally {\n setBusy(false);\n }\n },\n [host, online, pageCount, fail],\n );\n const apply = useCallback(() => {\n const ops = compilePageOps(decisions);\n if (!ops.length) return;\n if (markupPending) {\n setError(\"Save or discard your markup first: applying page changes reloads the file.\");\n return;\n }\n setTimeline((t) => dropOrigin(t, \"page\"));\n void runTool({ tool: \"apply-pages\", ops });\n }, [decisions, runTool, markupPending]);\n const discard = useCallback(() => {\n setHistory(startHistory(freshDecisions(pageCount)));\n setTimeline((t) => dropOrigin(t, \"page\"));\n }, [pageCount]);\n\n // ── markup session ──────────────────────────────────────────────────────\n const onMarkupEngine = useCallback((e: PdfMarkupEngine | null) => {\n setEngine(e);\n setSnap(e ? e.getSnapshot() : null);\n }, []);\n useEffect(() => {\n if (!engine) return undefined;\n const offSnap = engine.subscribe(setSnap);\n const offHistory = engine.onHistory((ev) => {\n if (ev.type === \"step\") setTimeline((t) => recordStep(t, \"markup\", ev.label));\n else if (ev.external) setTimeline((t) => (ev.type === \"undo\" ? markupUndoneElsewhere(t) : markupRedoneElsewhere(t)));\n });\n return () => { offSnap(); offHistory(); };\n }, [engine]);\n // The editors follow the tool: on while \"Comment and mark up\" is open, off (markup still shown) otherwise.\n const markupOn = tool === \"markup\" && !hostTool && !dirty;\n const markupEngineTool = pdfMarkupTool(markupTool)?.engineTool ?? \"highlight\";\n useEffect(() => {\n if (engine) void engine.setTool(markupOn ? markupEngineTool : \"none\");\n }, [engine, markupOn, markupEngineTool]);\n useEffect(() => { engine?.setCurrentPage(currentPage); }, [engine, currentPage]);\n const saveMarkup = useCallback(async () => {\n if (!engine || !host.saveMarkup || !markupPending || markupBusy) return;\n if (!online) {\n setMarkupError(\"You are offline. Your markup is kept here; save when you are back online.\");\n return;\n }\n setMarkupBusy(true);\n setMarkupError(null);\n try {\n const summary = engine.getSnapshot().summary;\n const bytes = await engine.save();\n const out = await host.saveMarkup(bytes, summary);\n setResult(out);\n setTimeline((t) => dropOrigin(t, \"markup\"));\n sizes.current.clear();\n setReloadKey((k) => k + 1);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"The markup was not saved.\";\n setMarkupError(message);\n host.notify?.(message, \"error\");\n } finally {\n setMarkupBusy(false);\n }\n }, [engine, host, markupPending, markupBusy, online]);\n const discardMarkup = useCallback(() => {\n // The editors live on the open document: opening it again drops every unsaved piece.\n setTimeline((t) => dropOrigin(t, \"markup\"));\n setMarkupError(null);\n setReloadKey((k) => k + 1);\n }, []);\n // Leaving the page with unsaved markup asks first (the deck autosave's guard; markup is never saved silently).\n useEffect(() => {\n if (!markupPending) return undefined;\n const onBeforeUnload = (event: BeforeUnloadEvent) => {\n event.preventDefault();\n event.returnValue = \"\";\n };\n window.addEventListener(\"beforeunload\", onBeforeUnload);\n return () => window.removeEventListener(\"beforeunload\", onBeforeUnload);\n }, [markupPending]);\n const undoAll = useCallback(() => {\n const step = nextUndo(timeline);\n if (step?.origin === \"markup\" && engine) {\n setTimeline(stepBack);\n engine.undo();\n return;\n }\n if (step) setTimeline(stepBack);\n setHistory((h) => undo(h));\n }, [timeline, engine]);\n const redoAll = useCallback(() => {\n const step = nextRedo(timeline);\n if (step?.origin === \"markup\" && engine) {\n setTimeline(stepForward);\n engine.redo();\n return;\n }\n if (step) setTimeline(stepForward);\n setHistory((h) => redo(h));\n }, [timeline, engine]);\n const undoStep = nextUndo(timeline);\n const redoStep = nextRedo(timeline);\n const undoText = undoStep ? `Undo ${undoStep.label}` : undoLabel(history) ? `Undo ${undoLabel(history)}` : \"Undo\";\n const redoText = redoStep ? `Redo ${redoStep.label}` : redoLabel(history) ? `Redo ${redoLabel(history)}` : \"Redo\";\n const canUndoAll = Boolean(undoStep) || canUndo(history);\n const canRedoAll = Boolean(redoStep) || canRedo(history);\n\n // ── tools ───────────────────────────────────────────────────────────────\n const chooseTool = useCallback(\n (id: string) => {\n if (id.startsWith(\"host:\")) {\n setHostToolId(id.slice(5));\n setResult(null);\n setError(null);\n setRightOpen(true);\n if (compact) setSheet(\"tools\");\n return;\n }\n const def = pdfTool(id);\n if (!def || (def.id === \"markup\" && !host.saveMarkup)) return;\n setHostToolId(null);\n if (def.status === \"soon\") {\n announceSoon(comingSoonIdOf(def.id)).catch(fail);\n return;\n }\n if (def.opens === \"page\") {\n host.openTool(def.id === \"scan\" ? \"scan\" : \"sign\");\n return;\n }\n setTool(def.id);\n setResult(null);\n setError(null);\n setRightOpen(true);\n if (compact) setSheet(\"tools\");\n },\n [host, compact, fail],\n );\n const railGroups = useMemo<ToolRailItem[][]>(() => {\n // The rail holds the tools that work today; the ones not built yet live in \"All tools\", marked as coming soon.\n const groups: ToolRailItem[][] = [[], [], []];\n for (const t of PDF_TOOLS) {\n if (t.status !== \"ready\" || (t.id === \"markup\" && !canMarkup)) continue;\n groups[t.group]!.push({ id: t.id, label: t.label, icon: PDF_TOOL_ICONS[t.id], ...(t.key ? { shortcut: t.key.toUpperCase() } : null) });\n }\n for (const t of hostTools) groups[t.group ?? 1]!.push({ id: `host:${t.id}`, label: t.label, icon: t.icon });\n groups[2]!.push({ id: ALL_TOOLS, label: \"All tools\", icon: MoreHorizontalIcon });\n return groups.filter((g) => g.length);\n }, [hostTools, canMarkup]);\n\n // ── actions and the one key handler ─────────────────────────────────────\n const runAction = useCallback(\n (action: PdfActionId) => {\n if (action.startsWith(\"tool:\")) return chooseTool(action.slice(5));\n switch (action) {\n case \"undo\": return undoAll();\n case \"redo\": return redoAll();\n case \"save\": return markupPending ? void saveMarkup() : apply();\n case \"find\": setFindOpen(true); setFindFocus((n) => n + 1); return;\n case \"print\": return host.print ? setPop(\"print\") : undefined;\n case \"zoom-in\": return stepZoom(1);\n case \"zoom-out\": return stepZoom(-1);\n case \"zoom-fit-width\": return setZoomMode(\"fit-width\");\n case \"zoom-fit-page\": return setZoomMode(\"fit-page\");\n case \"page-next\": return goToPage(currentPage + 1);\n case \"page-prev\": return goToPage(currentPage - 1);\n case \"page-first\": return goToPage(1);\n case \"page-last\": return goToPage(pageCount);\n case \"rotate-right\": return turn(90);\n case \"rotate-left\": return turn(-90);\n case \"delete-pages\": return del();\n case \"select-all-pages\": return setSelected(decisions.order.map(String));\n case \"toggle-pages\": return setLeftOpen((v) => !v);\n case \"toggle-properties\": return setRightOpen((v) => !v);\n case \"read-mode\": return setRead((v) => !v);\n case \"two-up\": return setSpread((s) => (s === \"two-up\" ? \"single\" : \"two-up\"));\n case \"shortcuts\": return setPop((p) => (p === \"shortcuts\" ? null : \"shortcuts\"));\n default: return undefined;\n }\n },\n [chooseTool, apply, host.print, stepZoom, goToPage, currentPage, pageCount, turn, del, decisions.order, undoAll, redoAll, markupPending, saveMarkup],\n );\n const onKeyDown = (e: React.KeyboardEvent) => {\n const t = e.target as HTMLElement;\n const typing = t.tagName === \"INPUT\" || t.tagName === \"TEXTAREA\" || t.tagName === \"SELECT\" || t.isContentEditable;\n if (e.key === \"Escape\") {\n if (pop) setPop(null);\n else if (findOpen) setFindOpen(false);\n else if (read) setRead(false);\n else if (sheet) setSheet(null);\n return;\n }\n if (markupOn) {\n // Markup open: its letters pick a tool; Delete, arrows, Escape and Select all belong to the selected markup (PDF.js handles them).\n const pick = matchMarkupKey(e.nativeEvent, typing);\n if (pick && pdfMarkupTool(pick)?.status === \"ready\" && (pick !== \"signature\" || host.signaturePad)) {\n e.preventDefault();\n setMarkupTool(pick);\n return;\n }\n }\n const action = matchShortcut(e.nativeEvent, typing);\n if (!action) return;\n if (markupOn && t.closest(\"[data-pdf-thumbnails]\") === null && (action === \"delete-pages\" || action === \"page-next\" || action === \"page-prev\" || action === \"select-all-pages\")) return;\n // Arrow keys page the document only when focus is on the canvas, never on a control.\n if ((action === \"page-next\" || action === \"page-prev\") && t !== scrollerRef.current && t !== rootRef.current) return;\n if (action === \"delete-pages\" && t.closest(\"[data-pdf-thumbnails]\") === null && t !== scrollerRef.current) return;\n e.preventDefault();\n // Undo and redo are the session's one stack: PDF.js (listening on the window) must not take them too.\n if (action === \"undo\" || action === \"redo\") e.stopPropagation();\n runAction(action);\n };\n\n // Reading mode hides the button that opened it, so focus would fall to <body> and Escape (handled on\n // this root) would never arrive: the page takes focus on entry, and while reading, an Escape pressed\n // anywhere outside the workspace exits too. Guard: pdf-workspace.test.tsx \"Escape leaves reading mode\".\n useEffect(() => {\n if (!read) return undefined;\n scrollerRef.current?.focus({ preventScroll: true });\n const onWindowKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented) return;\n if (rootRef.current?.contains(e.target as Node)) return; // the root's own handler has it\n setRead(false);\n };\n window.addEventListener(\"keydown\", onWindowKey);\n return () => window.removeEventListener(\"keydown\", onWindowKey);\n }, [read]);\n\n // ── pieces ──────────────────────────────────────────────────────────────\n const unsaved = dirty || markupPending > 0;\n const saveState = !online ? \"Offline\" : busy || markupBusy ? \"Saving\" : (error && dirty) || (markupError && markupPending) ? \"Not saved\" : unsaved ? \"Unsaved\" : \"Saved\";\n const savePill = (\n <span\n role=\"status\"\n className={cn(\n \"inline-flex h-6 shrink-0 items-center justify-center whitespace-nowrap rounded-full border px-2 text-xs\",\n saveState === \"Unsaved\" || saveState === \"Offline\" || saveState === \"Not saved\" ? \"border-border text-foreground\" : \"border-border text-muted-foreground\",\n busy && \"animate-pulse\",\n )}\n >\n {saveState}\n </span>\n );\n const iconBtn = (label: string, icon: React.ReactNode, onClick: () => void, opts?: { disabled?: boolean; pressed?: boolean }) => (\n <Button variant=\"quiet\" icon={icon} aria-label={label} title={label} onClick={onClick} {...(opts?.disabled !== undefined ? { disabled: opts.disabled } : null)} {...(opts?.pressed !== undefined ? { pressed: opts.pressed } : null)} />\n );\n const toolHits: Array<{ id: string; label: string; status: \"ready\" | \"soon\" }> = toolQuery.trim()\n ? [\n ...hostTools.map((t) => ({ id: `host:${t.id}`, label: t.label, status: \"ready\" as const })),\n ...PDF_TOOLS,\n ].filter((t) => t.label.toLowerCase().includes(toolQuery.trim().toLowerCase()))\n : [];\n const nameNode = editingName && host.rename ? (\n <Field\n autoFocus\n value={nameDraft}\n aria-label=\"File name\"\n onChange={(e) => setNameDraft(e.target.value)}\n onBlur={() => {\n setEditingName(false);\n if (nameDraft.trim() && nameDraft !== host.file.name) host.rename!(nameDraft.trim()).catch(fail);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") (e.target as HTMLInputElement).blur();\n if (e.key === \"Escape\") { setNameDraft(host.file.name); setEditingName(false); }\n }}\n width=\"lg\"\n />\n ) : (\n <Button\n type=\"button\"\n variant=\"quiet\"\n className=\"min-w-0 max-w-[16rem]\"\n title={host.rename ? \"Rename\" : host.file.name}\n onClick={() => host.rename && (setNameDraft(host.file.name), setEditingName(true))}\n >\n {host.file.name}\n </Button>\n );\n\n const rightPanel = hostTool ? (\n <div className=\"flex h-full min-h-0 flex-col\" data-pdf-host-tool={hostTool.id}>\n <div className=\"shrink-0 border-b border-border px-3 py-2\">\n <div className=\"text-sm font-medium\">{hostTool.label}</div>\n {hostTool.hint ? <div className=\"text-xs text-muted-foreground\">{hostTool.hint}</div> : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n {hostTool.render({ currentPage, pageCount, selected: selectedPages, goToPage, reload: () => setReloadKey((k) => k + 1) })}\n </div>\n </div>\n ) : (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"shrink-0 border-b border-border px-3 py-2\">\n <div className=\"text-sm font-medium\">{toolDef.label}</div>\n {toolDef.hint ? <div className=\"text-xs text-muted-foreground\">{toolDef.hint}</div> : null}\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto p-3\">\n {tool === \"markup\" ? (\n <MarkupPanel\n host={host}\n engine={engine}\n snapshot={snap}\n active={markupTool}\n onPick={setMarkupTool}\n blocked={dirty ? \"Apply or discard the page changes first.\" : null}\n busy={markupBusy}\n online={online}\n error={markupError}\n onSave={() => void saveMarkup()}\n onDiscard={discardMarkup}\n onSoon={(id) => void announceSoon(id).catch(fail)}\n goToPage={goToPage}\n reloadKey={reloadKey}\n />\n ) : (\n <ToolPanel\n tool={toolDef}\n host={host}\n pageCount={pageCount}\n selected={selectedPages}\n currentPage={currentPage}\n pageSize={(p) => sizes.current.get(p)}\n decisions={decisions}\n dirty={dirty}\n busy={busy}\n online={online}\n result={result}\n error={error}\n onRun={(r) => void runTool(r)}\n onApply={apply}\n onDiscard={discard}\n onTurn={turn}\n onDelete={del}\n onRestore={restore}\n />\n )}\n </div>\n </div>\n );\n const leftPanel = (\n <LeftPanel\n host={host}\n tab={leftTab}\n onTab={setLeftTab}\n decisions={decisions}\n selectedIds={selected}\n currentPage={currentPage}\n onSelect={(ids) => {\n setSelected(ids);\n if (ids.length === 1) goToPage(Number(ids[0]));\n }}\n onReorder={(order) => commit(\"Move pages\", reorderPages(decisions, order))}\n onOpenPage={goToPage}\n onLayersSoon={() => void announceSoon(\"pdf.layers\").catch(fail)}\n />\n );\n\n // Memoized: scrolling changes the current page many times a second, and the viewer must not redraw for it.\n // The page number reaches the viewer only while a host tool asks to follow it, so scrolling never redraws a windowed viewer.\n const viewerPage = hostTool?.followsPage ? currentPage : 1;\n const viewer = useMemo(\n () => (\n <Fragment key={reloadKey}>\n {host.renderViewer({ zoom, spread, rotations: decisions.turns, reloadKey, currentPage: viewerPage, onDocumentLoad, onPageSize, ...(canMarkup ? { onMarkupEngine } : null) })}\n </Fragment>\n ),\n [host, reloadKey, zoom, spread, decisions.turns, viewerPage, onDocumentLoad, onPageSize, canMarkup, onMarkupEngine],\n );\n\n const showChrome = !read;\n const popCard = \"absolute right-2 top-11 z-30 rounded-lg border border-border bg-popover p-3 text-popover-foreground shadow-lg\";\n\n return (\n <div\n ref={rootRef}\n tabIndex={-1}\n data-pdf-workspace=\"\"\n data-compact={compact ? \"\" : undefined}\n onKeyDown={onKeyDown}\n className={cn(\"relative flex h-full min-h-0 w-full flex-col overflow-hidden bg-background text-foreground outline-none\", className)}\n >\n {showChrome ? (\n <div className={BAR} data-pdf-topbar=\"\">\n {iconBtn(\"Page thumbnails\", <PanelLeftIcon />, () => (compact ? setSheet(\"pages\") : setLeftOpen((v) => !v)), { pressed: !compact && leftOpen })}\n {nameNode}\n {savePill}\n <div className=\"flex-1\" />\n {!compact ? (\n <div className=\"relative w-56\">\n <Field\n icon={<SearchIcon />}\n value={toolQuery}\n aria-label=\"Search tools\"\n placeholder=\"Search tools\"\n onFocus={() => setPop(\"tool-search\")}\n onChange={(e) => { setToolQuery(e.target.value); setPop(\"tool-search\"); }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && toolHits[0]) { chooseTool(toolHits[0].id); setToolQuery(\"\"); setPop(null); }\n }}\n />\n {pop === \"tool-search\" && toolHits.length ? (\n <ul role=\"listbox\" className=\"absolute left-0 right-0 top-9 z-30 rounded-lg border border-border bg-popover p-1 shadow-lg\">\n {toolHits.map((t) => (\n <li key={t.id} role=\"option\" aria-selected={false}>\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n title={t.label}\n end={t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : undefined}\n className=\"w-full\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => { chooseTool(t.id); setToolQuery(\"\"); setPop(null); }}\n />\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n ) : null}\n {iconBtn(undoText, <Undo2Icon />, () => runAction(\"undo\"), { disabled: !canUndoAll })}\n {iconBtn(redoText, <Undo2Icon className=\"-scale-x-100\" />, () => runAction(\"redo\"), { disabled: !canRedoAll })}\n {!compact && iconBtn(\"Find\", <SearchIcon />, () => runAction(\"find\"), { pressed: findOpen })}\n {host.share && !compact ? iconBtn(\"Share\", <Share2Icon />, () => host.share!()) : null}\n {iconBtn(\"Download\", <DownloadIcon />, () => host.download())}\n {host.print && !compact ? iconBtn(\"Print\", <PrinterIcon />, () => setPop(pop === \"print\" ? null : \"print\"), { pressed: pop === \"print\" }) : null}\n {!compact ? iconBtn(\"Keyboard shortcuts\", <KeyboardIcon />, () => runAction(\"shortcuts\"), { pressed: pop === \"shortcuts\" }) : null}\n {compact ? <Button variant=\"outline\" onClick={() => setSheet(\"tools\")}>Tools</Button> : iconBtn(\"Properties panel\", <PanelRightIcon />, () => setRightOpen((v) => !v), { pressed: rightOpen })}\n </div>\n ) : null}\n\n {showChrome ? (\n <div className={BAR} data-pdf-viewbar=\"\">\n {iconBtn(\"Previous page\", <ChevronLeftIcon />, () => goToPage(currentPage - 1), { disabled: currentPage <= 1 })}\n <Field\n type=\"number\"\n min={1}\n max={Math.max(1, pageCount)}\n value={pageDraft}\n aria-label=\"Page\"\n onChange={(e) => setPageDraft(e.target.value)}\n onBlur={() => goToPage(Number(pageDraft) || currentPage)}\n onKeyDown={(e) => e.key === \"Enter\" && goToPage(Number(pageDraft) || currentPage)}\n className={compact ? \"w-12\" : \"w-16\"}\n />\n <span className=\"whitespace-nowrap text-xs text-muted-foreground\">of {pageCount || \"-\"}</span>\n {iconBtn(\"Next page\", <ChevronRightIcon />, () => goToPage(currentPage + 1), { disabled: currentPage >= pageCount })}\n <div className=\"mx-1 h-5 w-px bg-border\" />\n {iconBtn(\"Zoom out\", <MinusIcon />, () => stepZoom(-1))}\n <span className={cn(\"min-w-[3rem] text-center text-xs tabular-nums\", compact && \"hidden\")} data-pdf-zoom=\"\">\n {`${Math.round(zoom * 100)}%`}\n </span>\n {iconBtn(\"Zoom in\", <PlusIcon />, () => stepZoom(1))}\n {!compact ? (\n <SegmentedControl\n value={zoomMode === \"custom\" ? null : zoomMode}\n onValueChange={(v) => setZoomMode(v)}\n data={[{ value: \"fit-width\", label: \"Width\" }, { value: \"fit-page\", label: \"Page\" }]}\n aria-label=\"Fit\"\n />\n ) : null}\n <div className=\"flex-1\" />\n {!compact ? (\n <>\n {iconBtn(\"Rotate left\", <RotateCcwIcon />, () => turn(-90))}\n {iconBtn(\"Rotate right\", <RotateCwIcon />, () => turn(90))}\n {iconBtn(\"Delete page\", <Trash2Icon />, del, { disabled: decisions.order.length - decisions.deleted.length <= 1 })}\n <div className=\"mx-1 h-5 w-px bg-border\" />\n {iconBtn(\"Two pages side by side\", <Columns2Icon />, () => runAction(\"two-up\"), { pressed: spread === \"two-up\" })}\n </>\n ) : null}\n {iconBtn(\"Reading mode\", <ExpandIcon />, () => setRead(true))}\n </div>\n ) : null}\n\n <div className=\"relative flex min-h-0 flex-1\">\n {showChrome && !compact ? (\n <div className=\"flex w-10 shrink-0 flex-col items-center border-r border-border bg-background py-2\" data-pdf-rail=\"\">\n <ToolRail groups={railGroups} value={pop === \"all-tools\" ? ALL_TOOLS : activeToolKey} onValueChange={(id) => (id === ALL_TOOLS ? setPop((p) => (p === \"all-tools\" ? null : \"all-tools\")) : id && chooseTool(id))} aria-label=\"PDF tools\" />\n </div>\n ) : null}\n {showChrome && !compact && leftOpen ? (\n <aside className=\"w-56 shrink-0 border-r border-border bg-background\" aria-label=\"Pages\" data-pdf-left=\"\">\n {leftPanel}\n </aside>\n ) : null}\n <main className=\"relative flex min-w-0 flex-1 flex-col\">\n {findOpen ? (\n <div className=\"absolute right-4 top-2 z-20\">\n <RenderedFindBar rootRef={scrollerRef} onClose={() => setFindOpen(false)} label=\"Find in document\" focusRequest={findFocus} compact />\n </div>\n ) : null}\n <div ref={scrollerRef} tabIndex={0} data-pdf-scroller=\"\" className=\"min-h-0 flex-1 overflow-auto bg-muted outline-none\">\n {viewer}\n </div>\n <MarkupFloatingToolbar engine={engine} snapshot={snap} enabled={markupOn && !read} onDone={() => scrollerRef.current?.focus({ preventScroll: true })} />\n {read ? (\n <div className=\"absolute right-3 top-3 z-20\">\n <Button variant=\"outline\" icon={<XIcon />} onClick={() => setRead(false)}>Exit reading mode</Button>\n </div>\n ) : null}\n </main>\n {showChrome && !compact && rightOpen ? (\n <aside className={cn(\"shrink-0 border-l border-border bg-background\", hostTool?.wide ? \"w-[28rem]\" : \"w-72\")} aria-label=\"Properties\" data-pdf-right=\"\">\n {rightPanel}\n </aside>\n ) : null}\n\n {pop === \"all-tools\" ? (\n <ul role=\"menu\" aria-label=\"All tools\" className=\"absolute left-12 top-2 z-30 w-72 rounded-lg border border-border bg-popover p-1 shadow-lg\" data-pdf-all-tools=\"\">\n <ToolRows tool={activeToolKey} hostTools={hostTools} canMarkup={canMarkup} onPick={(id) => { setPop(null); chooseTool(id); }} />\n </ul>\n ) : null}\n {pop === \"print\" && host.print ? (\n <div className={cn(popCard, \"w-72\")} role=\"dialog\" aria-label=\"Print\">\n <div className=\"flex flex-col gap-3\">\n <SegmentedControl fill value={printMode} onValueChange={setPrintMode} data={[{ value: \"all\", label: \"All pages\" }, { value: \"pages\", label: \"Pages\" }]} aria-label=\"What to print\" />\n {printMode === \"pages\" ? <PageRangeInput value={printRange} onChange={(t) => setPrintRange(t)} pageCount={pageCount} /> : null}\n <Button\n variant=\"primary\"\n disabled={busy || (printMode === \"pages\" && !parsePageRanges(printRange, pageCount).valid)}\n onClick={() => {\n const pages = printMode === \"pages\" ? parsePageRanges(printRange, pageCount).pages : null;\n setBusy(true);\n host.print!(pages).then(() => setPop(null), fail).finally(() => setBusy(false));\n }}\n >\n Print\n </Button>\n </div>\n </div>\n ) : null}\n {pop === \"shortcuts\" ? (\n <div className={cn(popCard, \"max-h-[70%] w-80 overflow-y-auto\")} role=\"dialog\" aria-label=\"Keyboard shortcuts\" data-pdf-shortcuts=\"\">\n {([\"Edit\", \"View\", \"Pages\", \"Tools\"] as const).map((section) => (\n <div key={section} className=\"mb-3 last:mb-0\">\n <div className=\"mb-1 text-xs font-medium text-muted-foreground\">{section}</div>\n {PDF_SHORTCUTS.filter((s) => s.section === section).map((s) => (\n <div key={s.action} className=\"flex justify-between gap-2 py-0.5 text-xs\">\n <span>{s.label}</span>\n <kbd className=\"rounded border border-border px-1 text-muted-foreground\">{formatKeys(s.keys, isMac())}</kbd>\n </div>\n ))}\n </div>\n ))}\n {canMarkup ? (\n <div className=\"mb-0\">\n <div className=\"mb-1 text-xs font-medium text-muted-foreground\">Markup</div>\n {PDF_MARKUP_SHORTCUTS.filter((s) => s.tool !== \"signature\" || host.signaturePad).map((s) => (\n <div key={s.tool} className=\"flex justify-between gap-2 py-0.5 text-xs\">\n <span>{s.label}</span>\n <kbd className=\"rounded border border-border px-1 text-muted-foreground\">{s.keys}</kbd>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {compact && sheet ? (\n <>\n {/* ui-exception: Full-screen mobile sheet backdrop dismisses the modal; locked controls cannot cover the viewport. */}\n <button type=\"button\" aria-label=\"Close\" className=\"absolute inset-0 z-30 bg-background/60\" onClick={() => setSheet(null)} />\n <div className=\"absolute inset-x-0 bottom-0 z-40 flex max-h-[75%] flex-col rounded-t-xl border-t border-border bg-background\" role=\"dialog\" aria-label={sheet === \"pages\" ? \"Pages\" : \"Tools\"}>\n {sheet === \"pages\" ? (\n <div className=\"h-[60vh] min-h-0\">{leftPanel}</div>\n ) : (\n <div className=\"flex min-h-0 flex-col overflow-y-auto\">\n <ul className=\"p-2\" role=\"menu\" aria-label=\"Tools\"><ToolRows tool={activeToolKey} hostTools={hostTools} canMarkup={canMarkup} onPick={chooseTool} /></ul>\n <div className=\"border-t border-border\">{rightPanel}</div>\n </div>\n )}\n </div>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n","/**\n * The page decisions of one workspace session: which pages are turned, left out, or moved. Pure.\n *\n * Decisions are PENDING: the viewer and the page grid show them at once, and \"Apply\" sends them\n * to the server as the smallest list of page operations (`compilePageOps`). Pages are named by\n * their ORIGINAL 1-based number everywhere, so a decision survives any later move.\n */\n\nexport type Turn = 0 | 90 | 180 | 270;\n\nexport interface PageDecisions {\n /** Original page numbers in the order the person wants them (deleted pages stay in the list). */\n order: number[];\n /** Extra clockwise turn per original page; absent = 0. */\n turns: Record<number, Turn>;\n /** Original page numbers left out. */\n deleted: number[];\n}\n\nexport function freshDecisions(pageCount: number): PageDecisions {\n return { order: Array.from({ length: Math.max(0, pageCount) }, (_, i) => i + 1), turns: {}, deleted: [] };\n}\n\nconst norm = (t: number): Turn => ((((t % 360) + 360) % 360) as Turn);\n\nexport function turnPages(d: PageDecisions, pages: readonly number[], by: 90 | -90 | 180): PageDecisions {\n const turns = { ...d.turns };\n for (const p of pages) {\n const next = norm((turns[p] ?? 0) + by);\n if (next === 0) delete turns[p];\n else turns[p] = next;\n }\n return { ...d, turns };\n}\n\nexport function deletePages(d: PageDecisions, pages: readonly number[]): PageDecisions {\n const set = new Set([...d.deleted, ...pages.filter((p) => d.order.includes(p))]);\n // A document with no page left is not a document: the last page cannot be deleted.\n if (set.size >= d.order.length) return d;\n return { ...d, deleted: [...set].sort((a, b) => a - b) };\n}\n\nexport function restorePages(d: PageDecisions, pages: readonly number[]): PageDecisions {\n const gone = new Set(pages);\n return { ...d, deleted: d.deleted.filter((p) => !gone.has(p)) };\n}\n\n/** The new order, as the grid reports it (a list of original page numbers). */\nexport function reorderPages(d: PageDecisions, order: readonly number[]): PageDecisions {\n if (order.length !== d.order.length || [...order].sort((a, b) => a - b).some((p, i) => p !== i + 1)) return d;\n return { ...d, order: [...order] };\n}\n\nexport function isDirty(d: PageDecisions): boolean {\n const moved = d.order.some((p, i) => p !== i + 1);\n return moved || d.deleted.length > 0 || Object.keys(d.turns).length > 0;\n}\n\n/** The pages that will remain, in their new order. */\nexport function keptOrder(d: PageDecisions): number[] {\n const gone = new Set(d.deleted);\n return d.order.filter((p) => !gone.has(p));\n}\n\nexport type PageOp =\n | { kind: \"rotate\"; pages: number[]; rotation: 90 | 180 | 270 }\n | { kind: \"delete\"; pages: number[] }\n | { kind: \"reorder\"; newOrder: number[] };\n\n/**\n * The server operations that make the document match the decisions, in the order they must run:\n * turns (original numbering), deletions (original numbering), then one reorder over what remains\n * (renumbered 1..n). Nothing is emitted for a decision that changes nothing.\n */\nexport function compilePageOps(d: PageDecisions): PageOp[] {\n const ops: PageOp[] = [];\n const gone = new Set(d.deleted);\n for (const rotation of [90, 180, 270] as const) {\n const pages = Object.entries(d.turns)\n .filter(([p, t]) => t === rotation && !gone.has(Number(p)))\n .map(([p]) => Number(p))\n .sort((a, b) => a - b);\n if (pages.length) ops.push({ kind: \"rotate\", pages, rotation });\n }\n if (d.deleted.length) ops.push({ kind: \"delete\", pages: [...d.deleted] });\n const kept = keptOrder(d);\n const renumber = new Map([...kept].sort((a, b) => a - b).map((p, i) => [p, i + 1] as const));\n const newOrder = kept.map((p) => renumber.get(p)!);\n if (newOrder.some((p, i) => p !== i + 1)) ops.push({ kind: \"reorder\", newOrder });\n return ops;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { SegmentedControl, Switch } from \"@ai-matrx/design-system/controls\";\nimport { ThumbnailGrid } from \"@ai-matrx/design-system/thumbnail-grid\";\nimport type { PdfWorkspaceHost } from \"./ports\";\nimport type { PageDecisions } from \"./page-decisions\";\n\nexport type LeftTab = \"pages\" | \"layers\";\n\nexport interface LeftPanelProps {\n host: PdfWorkspaceHost;\n tab: LeftTab;\n onTab(tab: LeftTab): void;\n decisions: PageDecisions;\n selectedIds: string[];\n currentPage: number;\n onSelect(ids: string[]): void;\n onReorder(order: number[]): void;\n onOpenPage(page: number): void;\n /** Announce the registered \"layers\" promise (the host has no layer port). */\n onLayersSoon(): void;\n}\n\nconst THUMB_W = 88;\n\nexport function LeftPanel(p: LeftPanelProps) {\n const items = p.decisions.order.map((n) => ({ id: String(n) }));\n const gone = new Set(p.decisions.deleted);\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col\">\n <div className=\"shrink-0 border-b border-border p-2\">\n <SegmentedControl\n fill\n value={p.tab}\n onValueChange={(v) => (v === \"layers\" && !p.host.layers ? p.onLayersSoon() : p.onTab(v))}\n data={[\n { value: \"pages\", label: \"Pages\" },\n { value: \"layers\", label: \"Layers\" },\n ]}\n aria-label=\"Left panel\"\n />\n </div>\n {p.tab === \"pages\" ? (\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\" data-pdf-thumbnails=\"\">\n <ThumbnailGrid\n aria-label=\"Pages\"\n items={items}\n columns={2}\n aspectRatio=\"3 / 4\"\n selectedIds={p.selectedIds}\n onSelectedIdsChange={p.onSelect}\n onReorder={(ids) => p.onReorder(ids.map(Number))}\n onOpen={(item) => p.onOpenPage(Number(item.id))}\n itemLabel={(item) => `Page ${item.id}${gone.has(Number(item.id)) ? \", deleted\" : \"\"}`}\n renderCaption={(item) => <span className={Number(item.id) === p.currentPage ? \"font-medium text-foreground\" : \"text-muted-foreground\"}>{item.id}</span>}\n renderItem={(item) => {\n const page = Number(item.id);\n const turn = p.decisions.turns[page] ?? 0;\n return (\n <div className=\"relative flex h-full w-full items-center justify-center overflow-hidden bg-card\">\n <div style={{ transform: turn ? `rotate(${turn}deg)` : undefined }} className=\"flex h-full w-full items-center justify-center\">\n {p.host.renderThumbnail ? p.host.renderThumbnail(page, THUMB_W) : <span className=\"text-xs text-muted-foreground\">{page}</span>}\n </div>\n {p.host.renderPageBadge ? <span className=\"pointer-events-none absolute right-1 top-1 z-10\" data-pdf-page-badge={page}>{p.host.renderPageBadge(page)}</span> : null}\n {page === p.currentPage ? <span className=\"pointer-events-none absolute inset-0 border-2 border-primary\" /> : null}\n {gone.has(page) ? (\n <span className=\"absolute inset-0 flex items-center justify-center bg-background/80 text-xs font-medium text-destructive\">Deleted</span>\n ) : null}\n </div>\n );\n }}\n />\n </div>\n ) : (\n <LayersList host={p.host} />\n )}\n </div>\n );\n}\n\nfunction LayersList({ host }: { host: PdfWorkspaceHost }) {\n const [layers, setLayers] = useState<Array<{ id: string; name: string; visible: boolean }> | null>(null);\n const [error, setError] = useState<string | null>(null);\n useEffect(() => {\n host.layers?.list().then(setLayers, (e: unknown) => setError(e instanceof Error ? e.message : \"The layers did not load.\"));\n }, [host]);\n if (error) return <p role=\"alert\" className=\"p-3 text-xs text-destructive\">{error}</p>;\n if (!layers) return <div className=\"p-3 text-xs text-muted-foreground\" aria-busy=\"true\">Loading</div>;\n if (!layers.length) return <p className=\"p-3 text-xs text-muted-foreground\">This document has no layers.</p>;\n return (\n <ul className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {layers.map((l) => (\n <li key={l.id} className=\"flex items-center justify-between gap-2 py-1 text-xs\">\n <span className=\"truncate\">{l.name}</span>\n <Switch\n checked={l.visible}\n aria-label={`Show ${l.name}`}\n onCheckedChange={(v) => {\n setLayers((prev) => prev?.map((x) => (x.id === l.id ? { ...x, visible: v } : x)) ?? prev);\n host.layers!.set(l.id, v).catch((e: unknown) => {\n setLayers((prev) => prev?.map((x) => (x.id === l.id ? { ...x, visible: !v } : x)) ?? prev);\n setError(e instanceof Error ? e.message : \"The layer did not change.\");\n });\n }}\n />\n </li>\n ))}\n </ul>\n );\n}\n","\"use client\";\n\n/**\n * The right-hand properties panel: one small form per ready tool. Every form is built from the design\n * system's controls, submits one `PdfRunRequest` through the host, and shows what came back. Forms\n * never decide anything the server owns (levels, patterns, ranges are validated there too).\n */\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Button, Field, SegmentedControl, Select, Textarea } from \"@ai-matrx/design-system/controls\";\nimport { PageRangeInput, formatPageRanges, parsePageRanges } from \"@ai-matrx/design-system/controls\";\nimport { copyText } from \"@ai-matrx/kit/clipboard\";\nimport { toDelimited } from \"@ai-matrx/kit/delimited\";\nimport type { PdfRunRequest, PdfRunResult, PdfWorkspaceHost } from \"./ports\";\nimport type { PdfToolDef } from \"./tools\";\nimport { keptOrder, type PageDecisions } from \"./page-decisions\";\n\nexport interface ToolPanelProps {\n tool: PdfToolDef;\n host: PdfWorkspaceHost;\n pageCount: number;\n /** Original page numbers selected in the page panel. */\n selected: number[];\n currentPage: number;\n /** Size of a page in PDF points once the viewer measured it. */\n pageSize(page: number): { w: number; h: number } | undefined;\n decisions: PageDecisions;\n dirty: boolean;\n busy: boolean;\n online: boolean;\n result: PdfRunResult | null;\n error: string | null;\n onRun(request: PdfRunRequest): void;\n onApply(): void;\n onDiscard(): void;\n onTurn(by: 90 | -90): void;\n onDelete(): void;\n onRestore(): void;\n}\n\nfunction Row({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-xs font-medium text-muted-foreground\">{label}</span>\n {children}\n </div>\n );\n}\n\n/** A page-range field that follows the page selection until the person types in it. */\nfunction useRangeText(selected: number[], currentPage: number): [string, (v: string) => void] {\n const synced = useRef(\"\");\n const [text, setText] = useState(\"\");\n const follow = selected.length ? formatPageRanges(selected) : String(currentPage);\n useEffect(() => {\n setText((prev) => (prev === synced.current ? follow : prev));\n synced.current = follow;\n }, [follow]);\n return [text, setText];\n}\n\nfunction RunButton({ busy, online, disabled, children, onClick }: { busy: boolean; online: boolean; disabled?: boolean; children: React.ReactNode; onClick(): void }) {\n return (\n <Button variant=\"primary\" disabled={busy || !online || disabled} onClick={onClick}>\n {busy ? \"Working\" : children}\n </Button>\n );\n}\n\nfunction Result({ result, host, error }: { result: PdfRunResult | null; host: PdfWorkspaceHost; error: string | null }) {\n const [copied, setCopied] = useState(false);\n const csv = useMemo(\n () =>\n result?.kind === \"tables\"\n ? result.tables.map((t) => toDelimited(t.rows, { format: \"csv\" })).join(\"\\n\\n\")\n : \"\",\n [result],\n );\n const copy = async (text: string) => {\n if (await copyText(text)) {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }\n };\n return (\n <div className=\"flex min-h-[3rem] flex-col gap-2\" aria-live=\"polite\">\n {error ? (\n <p role=\"alert\" className=\"rounded-md border border-destructive bg-destructive/10 p-2 text-xs text-destructive\">\n {error}\n </p>\n ) : null}\n {result?.kind === \"replaced\" ? <p className=\"text-xs text-muted-foreground\">Saved as a new version of this file.</p> : null}\n {result?.kind === \"file\" ? (\n <Button variant=\"outline\" onClick={() => host.openFile(result.fileId)}>\n Open {result.name ?? \"the new file\"}\n </Button>\n ) : null}\n {result?.kind === \"text\" ? (\n <>\n <Textarea\n readOnly\n value={result.text}\n aria-label=\"Extracted text\"\n minHeight={192}\n maxHeight={192}\n className=\"w-full resize-none\"\n />\n <Button variant=\"outline\" onClick={() => void copy(result.text)}>\n {copied ? \"Copied\" : \"Copy text\"}\n </Button>\n </>\n ) : null}\n {result?.kind === \"tables\" ? (\n result.tables.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">No tables found on these pages.</p>\n ) : (\n <>\n <div className=\"flex max-h-48 flex-col gap-2 overflow-auto\">\n {result.tables.map((t, i) => (\n <div key={i} className=\"rounded-md border border-border\">\n <div className=\"border-b border-border px-2 py-1 text-xs font-medium\">Page {t.page}</div>\n <table className=\"w-full text-xs\">\n <tbody>\n {t.rows.slice(0, 12).map((r, ri) => (\n <tr key={ri} className=\"border-b border-border last:border-b-0\">\n {r.map((c, ci) => (\n <td key={ci} className=\"px-2 py-1\">{c}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ))}\n </div>\n <Button variant=\"outline\" onClick={() => void copy(csv)}>\n {copied ? \"Copied\" : \"Copy as CSV\"}\n </Button>\n </>\n )\n ) : null}\n </div>\n );\n}\n\nconst LEVELS = [\n { value: \"1\", label: \"1\" },\n { value: \"2\", label: \"2\" },\n { value: \"3\", label: \"3\" },\n { value: \"4\", label: \"4\" },\n { value: \"5\", label: \"5\" },\n] as const;\n\nexport function ToolPanel(p: ToolPanelProps) {\n const [range, setRange] = useRangeText(p.selected, p.currentPage);\n const parsed = useMemo(() => parsePageRanges(range, p.pageCount), [range, p.pageCount]);\n const [perPart, setPerPart] = useState(\"10\");\n const [margins, setMargins] = useState({ top: \"0\", right: \"0\", bottom: \"0\", left: \"0\" });\n const [pattern, setPattern] = useState(\"\");\n const [reason, setReason] = useState(\"\");\n const [level, setLevel] = useState<\"1\" | \"2\" | \"3\" | \"4\" | \"5\">(\"3\");\n const [patterns, setPatterns] = useState<Array<{ id: string; label: string }> | null>(null);\n const [patternsError, setPatternsError] = useState<string | null>(null);\n const loadPatterns = p.host.redactPatterns;\n useEffect(() => {\n if (p.tool.id !== \"redact\" || !loadPatterns || patterns) return;\n loadPatterns().then(setPatterns, (e: unknown) => setPatternsError(e instanceof Error ? e.message : \"The pattern list did not load.\"));\n }, [p.tool.id, loadPatterns, patterns]);\n\n const rangeField = (\n <Row label=\"Pages\">\n <PageRangeInput value={range} onChange={(t) => setRange(t)} pageCount={p.pageCount} aria-label=\"Pages\" />\n </Row>\n );\n const cropBox = () => {\n const n = (s: string) => Math.max(0, Number(s) || 0);\n const groups = new Map<string, { pages: number[]; box: { x0: number; y0: number; x1: number; y1: number } }>();\n for (const page of parsed.pages) {\n const size = p.pageSize(page);\n if (!size) continue;\n const box = { x0: n(margins.left), y0: n(margins.top), x1: size.w - n(margins.right), y1: size.h - n(margins.bottom) };\n const key = `${box.x0}:${box.y0}:${box.x1}:${box.y1}`;\n const g = groups.get(key) ?? { pages: [], box };\n g.pages.push(page);\n groups.set(key, g);\n }\n return [...groups.values()];\n };\n\n let body: React.ReactNode = null;\n switch (p.tool.id) {\n case \"browse\": {\n const kept = keptOrder(p.decisions).length;\n body = (\n <div className=\"flex flex-col gap-1 text-xs\">\n <div className=\"flex justify-between\"><span className=\"text-muted-foreground\">Pages</span><span>{kept}</span></div>\n <div className=\"flex justify-between\"><span className=\"text-muted-foreground\">Selected</span><span>{p.selected.length}</span></div>\n <div className=\"flex justify-between\"><span className=\"text-muted-foreground\">Unsaved changes</span><span>{p.dirty ? \"Yes\" : \"None\"}</span></div>\n </div>\n );\n break;\n }\n case \"organize\":\n body = (\n <div className=\"flex flex-col gap-3\">\n <div className=\"grid grid-cols-2 gap-2\">\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={() => p.onTurn(-90)}>Rotate left</Button>\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={() => p.onTurn(90)}>Rotate right</Button>\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={p.onDelete}>Delete</Button>\n <Button variant=\"outline\" disabled={!p.selected.length} onClick={p.onRestore}>Restore</Button>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"primary\" disabled={!p.dirty || p.busy || !p.online} onClick={p.onApply}>\n {p.busy ? \"Working\" : \"Apply changes\"}\n </Button>\n <Button variant=\"outline\" disabled={!p.dirty || p.busy} onClick={p.onDiscard}>Discard</Button>\n </div>\n </div>\n );\n break;\n case \"extract-pages\":\n body = (\n <>\n {rangeField}\n <RunButton busy={p.busy} online={p.online} disabled={!parsed.valid} onClick={() => p.onRun({ tool: \"extract-pages\", pages: parsed.pages })}>\n Extract to a new file\n </RunButton>\n </>\n );\n break;\n case \"split\":\n body = (\n <>\n <Row label=\"Pages in each part\">\n <Field type=\"number\" min={1} value={perPart} onChange={(e) => setPerPart(e.target.value)} aria-label=\"Pages in each part\" />\n </Row>\n <RunButton busy={p.busy} online={p.online} disabled={!(Number(perPart) >= 1)} onClick={() => p.onRun({ tool: \"split\", maxPagesPerPart: Math.floor(Number(perPart)) })}>\n Split into new files\n </RunButton>\n </>\n );\n break;\n case \"crop\": {\n const groups = cropBox();\n body = (\n <>\n {rangeField}\n <div className=\"grid grid-cols-2 gap-2\">\n {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((side) => (\n <Row key={side} label={side[0]!.toUpperCase() + side.slice(1)}>\n <Field type=\"number\" min={0} value={margins[side]} onChange={(e) => setMargins((m) => ({ ...m, [side]: e.target.value }))} aria-label={`Crop ${side}`} />\n </Row>\n ))}\n </div>\n <RunButton\n busy={p.busy}\n online={p.online}\n disabled={!parsed.valid || groups.length === 0}\n onClick={() => {\n for (const g of groups) p.onRun({ tool: \"crop\", pages: g.pages, box: g.box });\n }}\n >\n Crop to a new file\n </RunButton>\n </>\n );\n break;\n }\n case \"redact\":\n body = (\n <>\n <Row label=\"Find\">\n {patterns ? (\n <Select\n value={pattern}\n onValueChange={setPattern}\n options={patterns.map((x) => ({ value: x.id, label: x.label }))}\n aria-label=\"What to redact\"\n />\n ) : (\n <Field value={pattern} onChange={(e) => setPattern(e.target.value)} aria-label=\"What to redact\" />\n )}\n {patternsError ? <span className=\"text-xs text-destructive\">{patternsError}</span> : null}\n </Row>\n <Row label=\"Reason\">\n <Field value={reason} onChange={(e) => setReason(e.target.value)} aria-label=\"Reason\" />\n </Row>\n <RunButton busy={p.busy} online={p.online} disabled={!pattern.trim() || !reason.trim()} onClick={() => p.onRun({ tool: \"redact\", pattern: pattern.trim(), reason: reason.trim() })}>\n Redact to a new file\n </RunButton>\n </>\n );\n break;\n case \"compress\":\n body = (\n <>\n <Row label=\"Strength\">\n <SegmentedControl fill value={level} onValueChange={setLevel} data={LEVELS} aria-label=\"Compression strength\" />\n </Row>\n <RunButton busy={p.busy} online={p.online} onClick={() => p.onRun({ tool: \"compress\", level: Number(level) as 1 | 2 | 3 | 4 | 5 })}>\n Compress to a new file\n </RunButton>\n </>\n );\n break;\n case \"extract-data\":\n body = (\n <>\n {rangeField}\n <div className=\"grid grid-cols-2 gap-2\">\n <Button variant=\"outline\" disabled={p.busy || !p.online || !parsed.valid} onClick={() => p.onRun({ tool: \"extract-text\", pages: parsed.pages })}>Get text</Button>\n <Button variant=\"outline\" disabled={p.busy || !p.online || !parsed.valid} onClick={() => p.onRun({ tool: \"extract-tables\", pages: parsed.pages })}>Get tables</Button>\n </div>\n </>\n );\n break;\n default:\n body = null;\n }\n\n return (\n <div className=\"flex flex-col gap-3\">\n {body}\n {p.tool.id !== \"browse\" ? <Result result={p.result} host={p.host} error={p.error} /> : null}\n </div>\n );\n}\n","/**\n * The session's one undo/redo stack. Pure and generic: the workspace keeps page decisions and tool\n * form values in it, each step with the label the menu shows (\"Undo Rotate 3 pages\"). A new step\n * clears what was undone; the stack holds at most `limit` steps. Saved versions of the file are the\n * durable undo: applying changes empties this stack.\n */\nexport interface History<T> {\n past: Array<{ label: string; value: T }>;\n present: { label: string; value: T };\n future: Array<{ label: string; value: T }>;\n}\n\nexport const HISTORY_LIMIT = 100;\n\nexport function startHistory<T>(value: T): History<T> {\n return { past: [], present: { label: \"\", value }, future: [] };\n}\n\nexport function pushStep<T>(h: History<T>, label: string, value: T, limit = HISTORY_LIMIT): History<T> {\n if (Object.is(h.present.value, value)) return h;\n const past = [...h.past, h.present].slice(-limit);\n return { past, present: { label, value }, future: [] };\n}\n\nexport function undo<T>(h: History<T>): History<T> {\n const prev = h.past[h.past.length - 1];\n if (!prev) return h;\n return { past: h.past.slice(0, -1), present: prev, future: [h.present, ...h.future] };\n}\n\nexport function redo<T>(h: History<T>): History<T> {\n const next = h.future[0];\n if (!next) return h;\n return { past: [...h.past, h.present], present: next, future: h.future.slice(1) };\n}\n\nexport const canUndo = (h: History<unknown>) => h.past.length > 0;\nexport const canRedo = (h: History<unknown>) => h.future.length > 0;\n/** The label of the step Undo would take back. */\nexport const undoLabel = (h: History<unknown>) => h.present.label;\nexport const redoLabel = (h: History<unknown>) => h.future[0]?.label ?? \"\";\n","/**\n * The workspace's markup model (PDF-PLAN U10). Pure: the markup tools as data (which are built,\n * which are coming and why), their keys, the palette, and the ONE session history that holds both\n * page decisions and markup steps, so Undo takes back whichever came last.\n *\n * What is built rides PDF.js's own annotation editors (highlight, text box, draw, image; a\n * signature is an image made on the platform's signature pad; a comment is the note on a piece of\n * markup). What PDF.js's writer cannot make yet is a \"Coming soon\" row with its reason, never a\n * dead button: underline and strike-out, shapes, a free-standing sticky note, links, editing the\n * page's own text.\n */\nimport type { ComingSoonEntry } from \"@ai-matrx/kit/coming-soon\";\nimport type { PdfMarkupKind, PdfMarkupStyle, PdfMarkupTool } from \"./markup-engine-port\";\n\nexport type PdfMarkupToolId = \"highlight\" | \"freetext\" | \"ink\" | \"image\" | \"signature\" | \"underline\" | \"shapes\" | \"note\" | \"links\" | \"edit-text\";\n\nexport interface PdfMarkupToolDef {\n id: PdfMarkupToolId;\n label: string;\n /** Single key, while the markup tool is open. */\n key?: string;\n status: \"ready\" | \"soon\";\n /** The PDF.js editor a ready tool turns on. */\n engineTool?: Exclude<PdfMarkupTool, \"none\">;\n /** Ready only when the host brings this port. */\n needs?: \"signaturePad\";\n /** Why a coming tool is not built (shown under its name, and in its Coming-soon promise). */\n reason?: string;\n}\n\nexport const PDF_MARKUP_TOOLS: readonly PdfMarkupToolDef[] = [\n { id: \"highlight\", label: \"Highlight\", key: \"h\", status: \"ready\", engineTool: \"highlight\" },\n { id: \"freetext\", label: \"Text box\", key: \"x\", status: \"ready\", engineTool: \"freetext\" },\n { id: \"ink\", label: \"Draw\", key: \"d\", status: \"ready\", engineTool: \"ink\" },\n { id: \"image\", label: \"Image\", key: \"i\", status: \"ready\", engineTool: \"stamp\" },\n { id: \"signature\", label: \"Signature\", key: \"g\", status: \"ready\", engineTool: \"stamp\", needs: \"signaturePad\" },\n { id: \"underline\", label: \"Underline and strike out\", status: \"soon\", reason: \"The PDF writer we use makes highlights only.\" },\n { id: \"shapes\", label: \"Shapes\", status: \"soon\", reason: \"Rectangles, ovals and arrows need their own writer.\" },\n { id: \"note\", label: \"Sticky note\", status: \"soon\", reason: \"Comment on a highlight, text box or drawing for now.\" },\n { id: \"links\", label: \"Links\", status: \"soon\", reason: \"The PDF writer we use cannot add or change links.\" },\n { id: \"edit-text\", label: \"Edit page text\", status: \"soon\", reason: \"Changing the page's own text needs a server edit with a before-and-after check.\" },\n];\n\nexport const pdfMarkupTool = (id: string): PdfMarkupToolDef | undefined => PDF_MARKUP_TOOLS.find((t) => t.id === id);\n\n/** The palette markup offers (Acrobat's comment colors). Literal colors are data: they are written into the PDF. */\nexport const MARKUP_SWATCHES: ReadonlyArray<{ value: string; label: string }> = [\n { value: \"#ffd400\", label: \"Yellow\" },\n { value: \"#5fe36b\", label: \"Green\" },\n { value: \"#4cc9f0\", label: \"Blue\" },\n { value: \"#ff6fb5\", label: \"Pink\" },\n { value: \"#ff4d4d\", label: \"Red\" },\n { value: \"#1f2937\", label: \"Black\" },\n];\n\n/** Which look controls a kind of markup has (the floating toolbar and the panel show only these). */\nexport const MARKUP_STYLE_FIELDS: Record<PdfMarkupKind, ReadonlyArray<keyof PdfMarkupStyle>> = {\n highlight: [\"color\"],\n freetext: [\"color\", \"size\"],\n ink: [\"color\", \"opacity\", \"size\"],\n stamp: [],\n signature: [],\n};\n\n/** Sizes offered: font sizes for a text box, stroke widths for a drawing (PDF points). */\nexport const MARKUP_SIZES: Record<\"freetext\" | \"ink\", readonly number[]> = {\n freetext: [8, 10, 12, 14, 18, 24, 36],\n ink: [1, 2, 3, 5, 8, 12],\n};\n\nexport const MARKUP_KIND_LABEL: Record<PdfMarkupKind, string> = {\n highlight: \"Highlight\",\n freetext: \"Text box\",\n ink: \"Drawing\",\n stamp: \"Image\",\n signature: \"Signature\",\n};\n\nconst MARKUP_PROMISES: Record<string, string> = {\n underline: \"Underline or strike out text, with the same colors as highlights.\",\n shapes: \"Draw rectangles, ovals, lines and arrows on a page.\",\n note: \"Pin a sticky note anywhere on a page.\",\n links: \"Add, change and remove links to a page or a web address.\",\n \"edit-text\": \"Change the page's own text, see a before-and-after view, then save.\",\n};\n\nexport const markupComingSoonId = (id: PdfMarkupToolId): string => (id === \"links\" ? \"pdf.links\" : id === \"edit-text\" ? \"pdf.edit-text\" : `pdf.markup.${id}`);\n\n/** One Coming-soon row per markup tool not built yet (merged into `PDF_COMING_SOON`). */\nexport const PDF_MARKUP_COMING_SOON: Record<string, ComingSoonEntry> = Object.fromEntries(\n PDF_MARKUP_TOOLS.filter((t) => t.status === \"soon\").map((t): [string, ComingSoonEntry] => {\n const id = markupComingSoonId(t.id);\n return [id, { id, label: t.label, owner: \"pdf\", promise: MARKUP_PROMISES[t.id] ?? \"\", stage: \"planned\", surfaces: [\"PDF workspace markup panel\"] }];\n }),\n);\n\n// ── the session's one history: which kind of step Undo takes back next ──────────────────────\n\nexport type StepOrigin = \"page\" | \"markup\";\nexport interface SessionTimeline {\n past: Array<{ origin: StepOrigin; label: string }>;\n future: Array<{ origin: StepOrigin; label: string }>;\n}\nexport const TIMELINE_LIMIT = 100;\nexport const emptyTimeline = (): SessionTimeline => ({ past: [], future: [] });\n\nexport function recordStep(t: SessionTimeline, origin: StepOrigin, label: string): SessionTimeline {\n return { past: [...t.past, { origin, label }].slice(-TIMELINE_LIMIT), future: [] };\n}\n/** The step Undo would take back, or null. */\nexport const nextUndo = (t: SessionTimeline) => t.past[t.past.length - 1] ?? null;\nexport const nextRedo = (t: SessionTimeline) => t.future[0] ?? null;\nexport function stepBack(t: SessionTimeline): SessionTimeline {\n const last = t.past[t.past.length - 1];\n return last ? { past: t.past.slice(0, -1), future: [last, ...t.future] } : t;\n}\nexport function stepForward(t: SessionTimeline): SessionTimeline {\n const next = t.future[0];\n return next ? { past: [...t.past, next], future: t.future.slice(1) } : t;\n}\n/** PDF.js undid a markup step on its own (its keys, focus outside the workspace): move the newest markup step back. */\nexport function markupUndoneElsewhere(t: SessionTimeline): SessionTimeline {\n for (let i = t.past.length - 1; i >= 0; i--) {\n if (t.past[i]!.origin === \"markup\") return { past: [...t.past.slice(0, i), ...t.past.slice(i + 1)], future: [t.past[i]!, ...t.future] };\n }\n return t;\n}\nexport function markupRedoneElsewhere(t: SessionTimeline): SessionTimeline {\n const i = t.future.findIndex((s) => s.origin === \"markup\");\n if (i < 0) return t;\n return { past: [...t.past, t.future[i]!], future: [...t.future.slice(0, i), ...t.future.slice(i + 1)] };\n}\n/** Saving (or discarding) one kind of change ends its steps: the file's versions are the durable undo. */\nexport function dropOrigin(t: SessionTimeline, origin: StepOrigin): SessionTimeline {\n return { past: t.past.filter((s) => s.origin !== origin), future: t.future.filter((s) => s.origin !== origin) };\n}\n","/**\n * The PDF workspace's tool rail, as data. Pure (no React, no icons): the host registers the\n * Coming-soon rows from here (`PDF_COMING_SOON`), the shell draws the rail from it, and the tests\n * check that the two agree.\n *\n * A tool is `ready` only where a real capability stands behind it today (`capability` names the\n * server operation or app route). Anything else is `soon`: the rail shows it plainly marked, and\n * choosing it announces its registered promise through `@ai-matrx/kit/coming-soon`. There is no\n * third state, so no dead button.\n */\nimport type { ComingSoonEntry } from \"@ai-matrx/kit/coming-soon\";\nimport { PDF_MARKUP_COMING_SOON } from \"./markup\";\n\nexport type PdfToolId =\n | \"browse\"\n | \"markup\"\n | \"organize\"\n | \"extract-pages\"\n | \"split\"\n | \"crop\"\n | \"redact\"\n | \"compress\"\n | \"scan\"\n | \"sign\"\n | \"extract-data\"\n | \"edit\"\n | \"forms\"\n | \"protect\"\n | \"ocr\"\n | \"convert\"\n | \"compare\"\n | \"stamp\";\n\nexport interface PdfToolDef {\n id: PdfToolId;\n label: string;\n /** Single-key shortcut that picks the tool (shown in the tooltip and the shortcut map). */\n key?: string;\n status: \"ready\" | \"soon\";\n /** The server operation or route behind a ready tool; the wiring test reads it. */\n capability?: string;\n /** What choosing a ready tool does: show its panel, or leave for another page. */\n opens: \"panel\" | \"page\" | \"none\";\n group: 0 | 1 | 2;\n /** One short line under the panel title. */\n hint?: string;\n}\n\nexport const PDF_TOOLS: readonly PdfToolDef[] = [\n { id: \"browse\", label: \"Browse\", key: \"v\", status: \"ready\", opens: \"none\", group: 0 },\n { id: \"markup\", label: \"Comment and mark up\", key: \"m\", status: \"ready\", capability: \"client:pdfjs-annotation-editors,save-new-version\", opens: \"panel\", group: 0, hint: \"Highlight, write, draw, sign. Saves a new version.\" },\n { id: \"organize\", label: \"Organize pages\", key: \"o\", status: \"ready\", capability: \"rotate-pages,delete-pages,reorder-pages\", opens: \"panel\", group: 0 },\n { id: \"extract-pages\", label: \"Extract pages\", key: \"e\", status: \"ready\", capability: \"extract-pages\", opens: \"panel\", group: 0 },\n { id: \"split\", label: \"Split\", key: \"s\", status: \"ready\", capability: \"split\", opens: \"panel\", group: 0 },\n { id: \"crop\", label: \"Crop pages\", key: \"c\", status: \"ready\", capability: \"crop-pages\", opens: \"panel\", group: 0 },\n { id: \"redact\", label: \"Redact\", key: \"r\", status: \"ready\", capability: \"redact-pattern\", opens: \"panel\", group: 1 },\n { id: \"compress\", label: \"Compress\", key: \"z\", status: \"ready\", capability: \"compress\", opens: \"panel\", group: 1 },\n { id: \"extract-data\", label: \"Text and tables\", key: \"t\", status: \"ready\", capability: \"extract-text-remote,extract-tables\", opens: \"panel\", group: 1 },\n { id: \"scan\", label: \"Scan\", status: \"ready\", capability: \"route:/tools/scanner\", opens: \"page\", group: 1 },\n { id: \"sign\", label: \"Sign\", status: \"ready\", capability: \"route:/esign/new\", opens: \"page\", group: 1 },\n { id: \"edit\", label: \"Edit text and images\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"forms\", label: \"Fill forms\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"protect\", label: \"Protect\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"ocr\", label: \"Recognize text\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"convert\", label: \"Convert\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"compare\", label: \"Compare\", status: \"soon\", opens: \"none\", group: 2 },\n { id: \"stamp\", label: \"Stamp and number\", status: \"soon\", opens: \"none\", group: 2 },\n];\n\nexport const pdfTool = (id: string): PdfToolDef | undefined => PDF_TOOLS.find((t) => t.id === id);\n\n/** The Coming-soon id of an unbuilt tool. */\nexport const comingSoonIdOf = (id: PdfToolId): string => `pdf.${id}`;\n\nconst PROMISES: Record<string, string> = {\n edit: \"Change the page's own text and swap images, with a before-and-after view.\",\n forms: \"Fill in a form and keep the values in the file.\",\n protect: \"Lock a PDF with a password and limit what others can do.\",\n ocr: \"Turn a scanned PDF into one you can search and copy from.\",\n convert: \"Turn a PDF into Word, Excel or PowerPoint, and back.\",\n compare: \"Put two versions side by side and see what changed.\",\n stamp: \"Add watermarks, page numbers and Bates numbers.\",\n};\n\nconst PANEL_PROMISES: Record<string, ComingSoonEntry> = {\n \"pdf.layers\": {\n id: \"pdf.layers\",\n label: \"Layers\",\n owner: \"pdf\",\n promise: \"Show or hide the layers inside a PDF.\",\n stage: \"planned\",\n surfaces: [\"PDF workspace page panel\"],\n },\n};\n\n/** One row per unbuilt tool, ready for `registerComingSoon` or the host's registry table. */\nexport const PDF_COMING_SOON: Record<string, ComingSoonEntry> = {\n ...Object.fromEntries(\n PDF_TOOLS.filter((t) => t.status === \"soon\").map((t): [string, ComingSoonEntry] => {\n const id = comingSoonIdOf(t.id);\n return [id, { id, label: t.label, owner: \"pdf\", promise: PROMISES[t.id] ?? \"\", stage: \"planned\", surfaces: [\"PDF workspace tool rail\"] }];\n }),\n ),\n ...PANEL_PROMISES,\n ...PDF_MARKUP_COMING_SOON,\n};\n","/**\n * The PDF workspace's one keyboard map. A shortcut is data: the shell mounts ONE key handler that\n * asks `matchShortcut` for the action, and the shortcuts popover lists the same rows, so the map\n * on screen and the keys that work cannot drift (the test fires every documented key).\n */\nimport { PDF_TOOLS } from \"./tools\";\nimport { PDF_MARKUP_TOOLS, type PdfMarkupToolId } from \"./markup\";\n\nexport type PdfActionId =\n | \"undo\" | \"redo\" | \"find\" | \"print\" | \"save\"\n | \"zoom-in\" | \"zoom-out\" | \"zoom-fit-width\" | \"zoom-fit-page\"\n | \"page-next\" | \"page-prev\" | \"page-first\" | \"page-last\"\n | \"rotate-right\" | \"rotate-left\" | \"delete-pages\" | \"select-all-pages\"\n | \"toggle-pages\" | \"toggle-properties\" | \"read-mode\" | \"two-up\" | \"shortcuts\"\n | `tool:${string}`;\n\nexport interface PdfShortcut {\n action: PdfActionId;\n label: string;\n /** Display keys: \"Mod+Z\" shows as Cmd+Z on a Mac and Ctrl+Z elsewhere. */\n keys: string;\n section: \"Edit\" | \"View\" | \"Pages\" | \"Tools\" | \"Markup\";\n}\n\nexport const PDF_SHORTCUTS: readonly PdfShortcut[] = [\n { action: \"undo\", label: \"Undo\", keys: \"Mod+Z\", section: \"Edit\" },\n { action: \"redo\", label: \"Redo\", keys: \"Mod+Shift+Z\", section: \"Edit\" },\n { action: \"save\", label: \"Save markup or apply page changes\", keys: \"Mod+S\", section: \"Edit\" },\n { action: \"find\", label: \"Find\", keys: \"Mod+F\", section: \"Edit\" },\n { action: \"print\", label: \"Print\", keys: \"Mod+P\", section: \"Edit\" },\n { action: \"zoom-in\", label: \"Zoom in\", keys: \"Mod+=\", section: \"View\" },\n { action: \"zoom-out\", label: \"Zoom out\", keys: \"Mod+-\", section: \"View\" },\n { action: \"zoom-fit-width\", label: \"Fit width\", keys: \"Mod+1\", section: \"View\" },\n { action: \"zoom-fit-page\", label: \"Fit page\", keys: \"Mod+0\", section: \"View\" },\n { action: \"two-up\", label: \"Two pages side by side\", keys: \"Mod+Shift+2\", section: \"View\" },\n { action: \"read-mode\", label: \"Reading mode\", keys: \"Mod+Shift+H\", section: \"View\" },\n { action: \"toggle-pages\", label: \"Page thumbnails\", keys: \"Mod+Shift+T\", section: \"View\" },\n { action: \"toggle-properties\", label: \"Properties panel\", keys: \"Mod+Shift+P\", section: \"View\" },\n { action: \"shortcuts\", label: \"Keyboard shortcuts\", keys: \"?\", section: \"View\" },\n { action: \"page-next\", label: \"Next page\", keys: \"ArrowRight\", section: \"Pages\" },\n { action: \"page-prev\", label: \"Previous page\", keys: \"ArrowLeft\", section: \"Pages\" },\n { action: \"page-first\", label: \"First page\", keys: \"Home\", section: \"Pages\" },\n { action: \"page-last\", label: \"Last page\", keys: \"End\", section: \"Pages\" },\n { action: \"select-all-pages\", label: \"Select all pages\", keys: \"Mod+A\", section: \"Pages\" },\n { action: \"rotate-right\", label: \"Rotate selected pages right\", keys: \"Mod+]\", section: \"Pages\" },\n { action: \"rotate-left\", label: \"Rotate selected pages left\", keys: \"Mod+[\", section: \"Pages\" },\n { action: \"delete-pages\", label: \"Delete selected pages\", keys: \"Delete\", section: \"Pages\" },\n ...PDF_TOOLS.filter((t) => t.key && t.status === \"ready\").map((t): PdfShortcut => ({\n action: `tool:${t.id}`,\n label: t.label,\n keys: t.key!.toUpperCase(),\n section: \"Tools\",\n })),\n];\n\n/**\n * Keys that work only while \"Comment and mark up\" is open (they pick a markup tool). Listed in the\n * shortcut map under Markup; Delete, the arrows and Escape act on the selected markup there.\n */\nexport const PDF_MARKUP_SHORTCUTS: ReadonlyArray<{ tool: PdfMarkupToolId; label: string; keys: string }> = PDF_MARKUP_TOOLS.filter(\n (t) => t.status === \"ready\" && t.key,\n).map((t) => ({ tool: t.id, label: t.label, keys: t.key!.toUpperCase() }));\n\n/** The markup tool a plain key picks while markup is open, or null. */\nexport function matchMarkupKey(e: KeyLike, typing: boolean): PdfMarkupToolId | null {\n if (typing || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.key.length !== 1) return null;\n const k = e.key.toLowerCase();\n return PDF_MARKUP_SHORTCUTS.find((s) => s.keys.toLowerCase() === k)?.tool ?? null;\n}\n\nexport interface KeyLike {\n key: string;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n altKey: boolean;\n}\n\nfunction parse(keys: string) {\n const parts = keys.split(\"+\");\n const key = parts[parts.length - 1] === \"\" ? \"+\" : parts[parts.length - 1]!;\n return { mod: parts.includes(\"Mod\"), shift: parts.includes(\"Shift\"), key };\n}\n\nconst TYPING_PASSES = new Set<PdfActionId>([\"find\", \"save\", \"print\"]);\n\n/** The action a key press means, or null. Never matches while `typing` (a text field has the key). */\nexport function matchShortcut(e: KeyLike, typing: boolean): PdfActionId | null {\n const mod = e.ctrlKey || e.metaKey;\n const pressed = e.key.length === 1 ? e.key.toLowerCase() : e.key;\n for (const s of PDF_SHORTCUTS) {\n const want = parse(s.keys);\n const wantKey = want.key.length === 1 ? want.key.toLowerCase() : want.key;\n if (want.mod !== mod || e.altKey) continue;\n // \"?\" is typed with Shift; every other plain key must have no Shift unless the map says so.\n const shiftOk = want.key === \"?\" ? true : want.shift === e.shiftKey || (want.key === \"=\" && e.shiftKey && pressed === \"+\");\n if (!shiftOk) continue;\n if (pressed === wantKey || (want.key === \"=\" && pressed === \"+\")) {\n // A text field keeps its own keys (typing, its own undo, select all); only these still reach the shell.\n if (typing && !TYPING_PASSES.has(s.action)) return null;\n return s.action;\n }\n }\n return null;\n}\n\n/** \"Mod+Shift+Z\" → \"⌘⇧Z\" on a Mac, \"Ctrl+Shift+Z\" elsewhere. */\nexport function formatKeys(keys: string, mac: boolean): string {\n return keys\n .split(\"+\")\n .map((k) => (k === \"Mod\" ? (mac ? \"⌘\" : \"Ctrl\") : k === \"Shift\" ? (mac ? \"⇧\" : \"Shift\") : k === \"ArrowRight\" ? \"→\" : k === \"ArrowLeft\" ? \"←\" : k))\n .join(mac ? \"\" : \"+\");\n}\n","\"use client\";\n\n/**\n * Markup chrome (PDF-PLAN U10): the \"Comment and mark up\" panel and the floating toolbar over the\n * selected piece of markup. Both drive the viewer's PDF.js editors through `PdfMarkupEngine`; the\n * shell owns saving, undo and the leave-page guard.\n *\n * Panel: the tools (built ones pick an editor; coming ones announce their promise and say why\n * they wait), the look of the next piece, what is pending with Save and Discard, and the\n * annotations already in the file. Floating toolbar: the design system's AnchoredToolbar (portaled,\n * positioned fixed, so it never moves the page) with color, opacity, size, a comment and Delete.\n */\nimport { useEffect, useState } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { AnchoredToolbar, Button, ColorSwatchRow, Field, OpacitySlider, Select, Tile } from \"@ai-matrx/design-system/controls\";\nimport {\n HighlighterIcon,\n ImageIcon,\n Link2Icon,\n MessageSquareIcon,\n PencilIcon,\n PenToolIcon,\n ProportionsIcon,\n StickyNoteIcon,\n Trash2Icon,\n TypeIcon,\n WrapTextIcon,\n} from \"@ai-matrx/design-system/icons\";\nimport type { PdfMarkupEngine, PdfMarkupSnapshot, PdfMarkupStyle } from \"./markup-engine-port\";\nimport { MARKUP_KIND_LABEL, MARKUP_SIZES, MARKUP_STYLE_FIELDS, MARKUP_SWATCHES, PDF_MARKUP_TOOLS, markupComingSoonId, type PdfMarkupToolDef, type PdfMarkupToolId } from \"./markup\";\nimport type { PdfWorkspaceHost } from \"./ports\";\n\ntype Glyph = React.ComponentType<{ className?: string }>;\nconst MARKUP_ICONS: Record<PdfMarkupToolId, Glyph> = {\n highlight: HighlighterIcon,\n freetext: TypeIcon,\n ink: PencilIcon,\n image: ImageIcon,\n signature: PenToolIcon,\n underline: WrapTextIcon,\n shapes: ProportionsIcon,\n note: StickyNoteIcon,\n links: Link2Icon,\n \"edit-text\": TypeIcon,\n};\n\nfunction Section({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">{label}</span>\n {children}\n </div>\n );\n}\n\n/** The look controls for one kind of markup (shared by the panel and the floating toolbar). */\nfunction StyleControls({ kind, style, onChange, compact }: { kind: keyof typeof MARKUP_STYLE_FIELDS; style: PdfMarkupStyle; onChange(patch: Partial<PdfMarkupStyle>): void; compact?: boolean }) {\n const fields = MARKUP_STYLE_FIELDS[kind];\n if (!fields.length) return null;\n const sizes = kind === \"freetext\" ? MARKUP_SIZES.freetext : kind === \"ink\" ? MARKUP_SIZES.ink : null;\n return (\n <div className={cn(\"flex gap-2\", compact ? \"items-center\" : \"flex-col\")}>\n {fields.includes(\"color\") ? <ColorSwatchRow colors={MARKUP_SWATCHES} value={style.color} onChange={(color) => onChange({ color })} aria-label=\"Color\" /> : null}\n {fields.includes(\"opacity\") ? (\n <div className={compact ? \"w-52 shrink-0\" : \"w-full min-w-0\"}>\n <OpacitySlider value={style.opacity} onChange={(opacity) => onChange({ opacity })} className=\"w-full\" />\n </div>\n ) : null}\n {fields.includes(\"size\") && sizes ? (\n <div className={compact ? \"w-24 shrink-0\" : undefined}>\n <Select\n aria-label={kind === \"freetext\" ? \"Font size\" : \"Line width\"}\n value={String(sizes.includes(style.size) ? style.size : sizes[0])}\n onValueChange={(v: string) => onChange({ size: Number(v) })}\n options={sizes.map((n) => ({ value: String(n), label: `${n} pt` }))}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface MarkupPanelProps {\n host: PdfWorkspaceHost;\n engine: PdfMarkupEngine | null;\n snapshot: PdfMarkupSnapshot | null;\n active: PdfMarkupToolId;\n onPick(tool: PdfMarkupToolId): void;\n /** A ready-tool row was blocked (page changes pending): the sentence to show. */\n blocked: string | null;\n busy: boolean;\n online: boolean;\n error: string | null;\n onSave(): void;\n onDiscard(): void;\n onSoon(id: string): void;\n goToPage(n: number): void;\n reloadKey: number;\n}\n\nexport function MarkupPanel({ host, engine, snapshot, active, onPick, blocked, busy, online, error, onSave, onDiscard, onSoon, goToPage, reloadKey }: MarkupPanelProps) {\n const [confirmDiscard, setConfirmDiscard] = useState(false);\n const [signature, setSignature] = useState<string | null>(null);\n const [existing, setExisting] = useState<Awaited<ReturnType<NonNullable<PdfWorkspaceHost[\"existingAnnotations\"]>>> | null>(null);\n const pending = snapshot?.pending ?? 0;\n const tools = PDF_MARKUP_TOOLS.filter((t) => t.needs !== \"signaturePad\" || host.signaturePad);\n const ready = tools.filter((t) => t.status === \"ready\");\n const soon = tools.filter((t) => t.status === \"soon\");\n const def = tools.find((t) => t.id === active);\n const styleKind = def?.engineTool && def.engineTool !== \"stamp\" ? def.engineTool : null;\n const Pad = host.signaturePad;\n\n useEffect(() => {\n let live = true;\n host.existingAnnotations?.().then((list) => live && setExisting(list), () => live && setExisting([]));\n return () => { live = false; };\n }, [host, reloadKey]);\n useEffect(() => { if (!pending) setConfirmDiscard(false); }, [pending]);\n\n const pickImage = () => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/png,image/jpeg,image/webp,image/gif,image/svg+xml\";\n input.onchange = () => {\n const f = input.files?.[0];\n if (f && engine) void engine.addImage(f, \"stamp\");\n };\n input.click();\n };\n const row = (t: PdfMarkupToolDef) => {\n const Icon = MARKUP_ICONS[t.id];\n const on = t.id === active;\n return (\n <li key={t.id}>\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n title={t.label}\n icon={<Icon />}\n end={t.status === \"soon\" ? <span className=\"shrink-0 whitespace-nowrap text-muted-foreground\">Soon</span> : <kbd className=\"text-muted-foreground\">{t.key?.toUpperCase()}</kbd>}\n {...(t.status === \"ready\" ? { selected: on } : {})}\n disabled={t.status === \"ready\" && (!engine || Boolean(blocked))}\n onClick={() => (t.status === \"soon\" ? onSoon(markupComingSoonId(t.id)) : onPick(t.id))}\n className=\"w-full\"\n />\n {t.status === \"soon\" && t.reason ? <div className=\"pl-8 pr-2 text-xs text-muted-foreground\">{t.reason}</div> : null}\n </li>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-4\" data-pdf-markup-panel=\"\">\n {blocked ? <div role=\"status\" className=\"rounded-md border border-border px-2 py-1.5 text-xs\">{blocked}</div> : null}\n {!engine && !blocked ? <div className=\"text-xs text-muted-foreground\">Opening the document…</div> : null}\n <ul className=\"flex flex-col\" aria-label=\"Markup tools\">{ready.map(row)}</ul>\n\n {styleKind && snapshot ? (\n <Section label=\"Look\">\n <StyleControls kind={styleKind} style={snapshot.styles[styleKind]} onChange={(p) => engine?.setStyle(p)} />\n </Section>\n ) : null}\n {active === \"highlight\" ? <div className=\"text-xs text-muted-foreground\">Select text on the page to highlight it.</div> : null}\n {active === \"freetext\" ? <div className=\"text-xs text-muted-foreground\">Click on the page, then type.</div> : null}\n {active === \"ink\" ? <div className=\"text-xs text-muted-foreground\">Drag on the page to draw.</div> : null}\n {active === \"image\" ? (\n <Button variant=\"outline\" icon={<ImageIcon />} disabled={!engine} onClick={pickImage}>Choose an image</Button>\n ) : null}\n {active === \"signature\" && Pad ? (\n <Section label=\"Signature\">\n <Pad value={signature} onChange={setSignature} />\n <Button variant=\"outline\" icon={<PenToolIcon />} disabled={!engine || !signature} onClick={() => signature && engine && void engine.addImage(signature, \"signature\")}>\n Place on page\n </Button>\n </Section>\n ) : null}\n\n <Section label=\"Changes\">\n <div className=\"text-xs\" role=\"status\" data-pdf-markup-pending=\"\">{pending ? `Not saved: ${snapshot?.summary}` : \"No unsaved markup\"}</div>\n {error ? <div role=\"alert\" className=\"text-xs text-destructive\">{error}</div> : null}\n {!online ? <div className=\"text-xs text-muted-foreground\">You are offline. Markup is kept here until you are back online.</div> : null}\n <div className=\"flex gap-2\">\n <Button variant=\"primary\" disabled={!pending || busy || !online} onClick={onSave}>{busy ? \"Saving\" : \"Save\"}</Button>\n {confirmDiscard ? (\n <>\n <Button variant=\"outline\" onClick={() => { setConfirmDiscard(false); onDiscard(); }}>Discard {pending}</Button>\n <Button variant=\"quiet\" onClick={() => setConfirmDiscard(false)}>Keep</Button>\n </>\n ) : (\n <Button variant=\"outline\" disabled={!pending || busy} onClick={() => setConfirmDiscard(true)}>Discard</Button>\n )}\n </div>\n </Section>\n\n {host.existingAnnotations ? (\n <Section label=\"In this file\">\n {existing === null ? (\n <div className=\"text-xs text-muted-foreground\">Reading…</div>\n ) : existing.filter((a) => a.subtype !== \"Link\" && a.subtype !== \"Widget\").length === 0 ? (\n <div className=\"text-xs text-muted-foreground\">No comments or markup yet</div>\n ) : (\n <ul className=\"flex flex-col\" aria-label=\"Annotations in this file\">\n {existing.filter((a) => a.subtype !== \"Link\" && a.subtype !== \"Widget\").map((a, i) => (\n <li key={`${a.page}-${i}`}>\n <Tile\n type=\"button\"\n dense\n variant=\"quiet\"\n title={`${a.subtype}${a.author ? ` · ${a.author}` : \"\"}`}\n line={a.contents}\n icon={<span className=\"w-8 shrink-0 tabular-nums text-muted-foreground\">p. {a.page}</span>}\n className=\"w-full\"\n onClick={() => goToPage(a.page)}\n />\n </li>\n ))}\n </ul>\n )}\n <div className=\"text-xs text-muted-foreground\">Markup already saved shows on the page; changing it in place is coming.</div>\n </Section>\n ) : null}\n\n <Section label=\"Coming soon\">\n <ul className=\"flex flex-col\" aria-label=\"Markup coming soon\">{soon.map(row)}</ul>\n </Section>\n </div>\n );\n}\n\n/** The floating toolbar over the selected piece of markup. */\nexport function MarkupFloatingToolbar({ engine, snapshot, enabled, onDone }: { engine: PdfMarkupEngine | null; snapshot: PdfMarkupSnapshot | null; enabled: boolean; onDone(): void }) {\n const sel = snapshot?.selection ?? null;\n const [commenting, setCommenting] = useState(false);\n const [draft, setDraft] = useState(\"\");\n const selKey = sel ? `${sel.kind}:${Math.round(sel.rect.x)}:${Math.round(sel.rect.y)}` : \"\";\n useEffect(() => {\n setCommenting(false);\n setDraft(sel?.comment ?? \"\");\n // A new selection starts closed, with its own comment.\n }, [selKey]); // eslint-disable-line react-hooks/exhaustive-deps\n if (!engine || !enabled || !sel) return null;\n return (\n <AnchoredToolbar open rect={sel.rect} aria-label={`${MARKUP_KIND_LABEL[sel.kind]} options`}>\n <div className=\"flex items-center gap-2\" data-pdf-markup-toolbar=\"\">\n <StyleControls compact kind={sel.kind} style={sel.style} onChange={(p) => engine.setStyle(p)} />\n {commenting ? (\n <Field\n autoFocus\n value={draft}\n aria-label=\"Comment\"\n placeholder=\"Comment\"\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n // Focus goes back to the page, so the workspace's keys (Save, Undo) keep working.\n if (e.key === \"Enter\") { engine.setComment(draft); setCommenting(false); onDone(); }\n if (e.key === \"Escape\") { e.stopPropagation(); setCommenting(false); onDone(); }\n }}\n onBlur={() => { engine.setComment(draft); setCommenting(false); }}\n width=\"md\"\n />\n ) : (\n <Button variant=\"quiet\" icon={<MessageSquareIcon />} aria-label={sel.comment ? \"Edit comment\" : \"Add comment\"} title={sel.comment || \"Add comment\"} pressed={Boolean(sel.comment)} onClick={() => setCommenting(true)} />\n )}\n <Button variant=\"quiet\" icon={<Trash2Icon />} aria-label=\"Delete\" title=\"Delete\" onClick={() => engine.deleteSelected()} />\n </div>\n </AnchoredToolbar>\n );\n}\n","import type { ComponentType } from \"react\";\nimport {\n ArrowLeftRightIcon,\n ArrowUpFromLineIcon,\n CameraIcon,\n CaptionsIcon,\n ChevronsDownUpIcon,\n Columns2Icon,\n EraserIcon,\n FlagIcon,\n HandIcon,\n LayoutGridIcon,\n ListChecksIcon,\n LockIcon,\n MessageSquareIcon,\n PencilIcon,\n PenToolIcon,\n ProportionsIcon,\n SplitIcon,\n TypeIcon,\n} from \"@ai-matrx/design-system/icons\";\nimport type { PdfToolId } from \"./tools\";\n\ntype Glyph = ComponentType<{ className?: string }>;\n\n/** One glyph per rail tool, from the design system's glyph home (sized by the control, not here). */\nexport const PDF_TOOL_ICONS: Record<PdfToolId, Glyph> = {\n browse: HandIcon,\n markup: MessageSquareIcon,\n organize: LayoutGridIcon,\n \"extract-pages\": ArrowUpFromLineIcon,\n split: SplitIcon,\n crop: ProportionsIcon,\n redact: EraserIcon,\n compress: ChevronsDownUpIcon,\n scan: CameraIcon,\n sign: PenToolIcon,\n \"extract-data\": TypeIcon,\n edit: PencilIcon,\n forms: ListChecksIcon,\n protect: LockIcon,\n ocr: CaptionsIcon,\n convert: ArrowLeftRightIcon,\n compare: Columns2Icon,\n stamp: FlagIcon,\n};\n"],"mappings":"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","names":["import_react","import_cn","import_controls","import_icons","import_react","import_controls","import_jsx_runtime","import_react","import_controls","import_jsx_runtime","import_icons","import_jsx_runtime"]}