@ai-matrx/office 0.8.48 → 0.8.49

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../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/tools.ts","../src/pdf/shortcuts.ts","../src/pdf/tool-icons.tsx"],"sourcesContent":["\"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, 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 { PdfRunRequest, PdfRunResult, PdfWorkspaceHost } from \"./ports\";\nimport { canRedo, canUndo, pushStep, redo, redoLabel, startHistory, undo, undoLabel, type History } from \"./session-history\";\nimport { PDF_SHORTCUTS, formatKeys, matchShortcut, type PdfActionId } from \"./shortcuts\";\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, onPick }: { tool: PdfToolId; onPick(id: PdfToolId): void }) {\n return (\n <>\n {PDF_TOOLS.filter((t) => t.id !== \"browse\").map((t) => {\n const Icon = PDF_TOOL_ICONS[t.id];\n return (\n <li key={t.id} role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-current={t.id === tool ? \"true\" : undefined}\n className={cn(\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\", t.id === tool && \"bg-accent\")}\n onClick={() => onPick(t.id)}\n >\n <Icon className=\"size-4 shrink-0\" />\n <span className=\"flex-1 whitespace-nowrap\">{t.label}</span>\n {t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : null}\n </button>\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 [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\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) => setHistory((h) => pushStep(h, label, next)), []);\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) void runTool({ tool: \"apply-pages\", ops });\n }, [decisions, runTool]);\n const discard = useCallback(() => setHistory(startHistory(freshDecisions(pageCount))), [pageCount]);\n\n // ── tools ───────────────────────────────────────────────────────────────\n const chooseTool = useCallback(\n (id: string) => {\n const def = pdfTool(id);\n if (!def) return;\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\") 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 groups[2]!.push({ id: ALL_TOOLS, label: \"All tools\", icon: MoreHorizontalIcon });\n return groups.filter((g) => g.length);\n }, []);\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 setHistory((h) => undo(h));\n case \"redo\": return setHistory((h) => redo(h));\n case \"save\": return 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],\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 const action = matchShortcut(e.nativeEvent, typing);\n if (!action) 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 runAction(action);\n };\n\n // ── pieces ──────────────────────────────────────────────────────────────\n const saveState = !online ? \"Offline\" : busy ? \"Saving\" : error && dirty ? \"Not saved\" : dirty ? \"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 = toolQuery.trim()\n ? PDF_TOOLS.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 className=\"min-w-0 max-w-[16rem] truncate rounded-md px-2 text-sm font-medium text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\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 = (\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 <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 </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 const viewer = useMemo(\n () => (\n <Fragment key={reloadKey}>\n {host.renderViewer({ zoom, spread, rotations: decisions.turns, reloadKey, onDocumentLoad, onPageSize })}\n </Fragment>\n ),\n [host, reloadKey, zoom, spread, decisions.turns, onDocumentLoad, onPageSize],\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 <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-md px-2 py-1 text-left text-xs hover:bg-accent\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => { chooseTool(t.id); setToolQuery(\"\"); setPop(null); }}\n >\n <span>{t.label}</span>\n {t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : null}\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n ) : null}\n {iconBtn(undoLabel(history) ? `Undo ${undoLabel(history)}` : \"Undo\", <Undo2Icon />, () => runAction(\"undo\"), { disabled: !canUndo(history) })}\n {iconBtn(redoLabel(history) ? `Redo ${redoLabel(history)}` : \"Redo\", <Undo2Icon className=\"-scale-x-100\" />, () => runAction(\"redo\"), { disabled: !canRedo(history) })}\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 : tool} 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 {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=\"w-72 shrink-0 border-l border-border bg-background\" 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={tool} 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 </div>\n ) : null}\n\n {compact && sheet ? (\n <>\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={tool} 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 {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 } from \"@ai-matrx/design-system/controls\";\nimport { PageRangeInput, formatPageRanges, parsePageRanges } from \"@ai-matrx/design-system/controls\";\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) => t.rows.map((r) => r.map((c) => `\"${c.replace(/\"/g, '\"\"')}\"`).join(\",\")).join(\"\\n\")).join(\"\\n\\n\")\n : \"\",\n [result],\n );\n const copy = async (text: string) => {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\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 className=\"h-48 w-full resize-none rounded-md border border-border bg-background p-2 text-xs text-foreground\"\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} onClick={() => p.onRun({ tool: \"extract-text\" })}>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 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\";\n\nexport type PdfToolId =\n | \"browse\"\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: \"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 text and swap images right on the page.\",\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};\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\";\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\";\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: \"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\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","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 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 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":["Fragment","useEffect","useMemo","useRef","useState","Button","Field","PageRangeInput","SegmentedControl","parsePageRanges","Columns2Icon","useEffect","useState","SegmentedControl","jsx","jsxs","useState","useEffect","SegmentedControl","Fragment","jsx","jsxs","useState","useRef","useMemo","useEffect","Button","Field","SegmentedControl","Columns2Icon","PageRangeInput","parsePageRanges"]}
1
+ {"version":3,"sources":["../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/tools.ts","../src/pdf/shortcuts.ts","../src/pdf/tool-icons.tsx"],"sourcesContent":["\"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, 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_SHORTCUTS, formatKeys, matchShortcut, type PdfActionId } from \"./shortcuts\";\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 }: { tool: string; hostTools: readonly PdfHostTool[]; onPick(id: string): void }) {\n return (\n <>\n {hostTools.map((t) => (\n <li key={`host:${t.id}`} role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-current={tool === `host:${t.id}` ? \"true\" : undefined}\n className={cn(\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\", tool === `host:${t.id}` && \"bg-accent\")}\n onClick={() => onPick(`host:${t.id}`)}\n >\n <t.icon className=\"size-4 shrink-0\" />\n <span className=\"flex-1 whitespace-nowrap\">{t.label}</span>\n </button>\n </li>\n ))}\n {PDF_TOOLS.filter((t) => t.id !== \"browse\").map((t) => {\n const Icon = PDF_TOOL_ICONS[t.id];\n return (\n <li key={t.id} role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n aria-current={t.id === tool ? \"true\" : undefined}\n className={cn(\"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\", t.id === tool && \"bg-accent\")}\n onClick={() => onPick(t.id)}\n >\n <Icon className=\"size-4 shrink-0\" />\n <span className=\"flex-1 whitespace-nowrap\">{t.label}</span>\n {t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : null}\n </button>\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\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) => setHistory((h) => pushStep(h, label, next)), []);\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) void runTool({ tool: \"apply-pages\", ops });\n }, [decisions, runTool]);\n const discard = useCallback(() => setHistory(startHistory(freshDecisions(pageCount))), [pageCount]);\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) 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\") 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]);\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 setHistory((h) => undo(h));\n case \"redo\": return setHistory((h) => redo(h));\n case \"save\": return 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],\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 const action = matchShortcut(e.nativeEvent, typing);\n if (!action) 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 runAction(action);\n };\n\n // ── pieces ──────────────────────────────────────────────────────────────\n const saveState = !online ? \"Offline\" : busy ? \"Saving\" : error && dirty ? \"Not saved\" : dirty ? \"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 className=\"min-w-0 max-w-[16rem] truncate rounded-md px-2 text-sm font-medium text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\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 <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 </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 })}\n </Fragment>\n ),\n [host, reloadKey, zoom, spread, decisions.turns, viewerPage, onDocumentLoad, onPageSize],\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 <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-md px-2 py-1 text-left text-xs hover:bg-accent\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => { chooseTool(t.id); setToolQuery(\"\"); setPop(null); }}\n >\n <span>{t.label}</span>\n {t.status === \"soon\" ? <span className=\"text-muted-foreground\">Coming soon</span> : null}\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n ) : null}\n {iconBtn(undoLabel(history) ? `Undo ${undoLabel(history)}` : \"Undo\", <Undo2Icon />, () => runAction(\"undo\"), { disabled: !canUndo(history) })}\n {iconBtn(redoLabel(history) ? `Redo ${redoLabel(history)}` : \"Redo\", <Undo2Icon className=\"-scale-x-100\" />, () => runAction(\"redo\"), { disabled: !canRedo(history) })}\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 {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} 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 </div>\n ) : null}\n\n {compact && sheet ? (\n <>\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} 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 {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 } from \"@ai-matrx/design-system/controls\";\nimport { PageRangeInput, formatPageRanges, parsePageRanges } from \"@ai-matrx/design-system/controls\";\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) => t.rows.map((r) => r.map((c) => `\"${c.replace(/\"/g, '\"\"')}\"`).join(\",\")).join(\"\\n\")).join(\"\\n\\n\")\n : \"\",\n [result],\n );\n const copy = async (text: string) => {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\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 className=\"h-48 w-full resize-none rounded-md border border-border bg-background p-2 text-xs text-foreground\"\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} onClick={() => p.onRun({ tool: \"extract-text\" })}>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 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\";\n\nexport type PdfToolId =\n | \"browse\"\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: \"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 text and swap images right on the page.\",\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};\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\";\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\";\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: \"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\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","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 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 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":["Fragment","useEffect","useMemo","useRef","useState","Button","Field","PageRangeInput","SegmentedControl","parsePageRanges","Columns2Icon","useEffect","useState","SegmentedControl","jsx","jsxs","useState","useEffect","SegmentedControl","Fragment","jsx","jsxs","useState","useRef","useMemo","useEffect","Button","Field","SegmentedControl","Columns2Icon","PageRangeInput","parsePageRanges"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/office",
3
- "version": "0.8.48",
3
+ "version": "0.8.49",
4
4
  "description": "The AI Matrx Office layer: the editors' shared command and menu model, the Google and Microsoft ribbon model, page setup, the Office record types and the configured product hosts. The Univer glue shared by Sheets and Docs. Sheets, Docs and the other products arrive as sections of this one package.",
5
5
  "type": "module",
6
6
  "main": "./dist/core.cjs",
@@ -206,13 +206,13 @@
206
206
  "yjs": "^13.6.33",
207
207
  "@ai-matrx/alchemy": "latest",
208
208
  "@ai-matrx/auth": "latest",
209
+ "@ai-matrx/api": "latest",
209
210
  "@ai-matrx/content-ir": "latest",
210
- "@ai-matrx/kit": "latest",
211
211
  "@ai-matrx/data": "latest",
212
+ "@ai-matrx/design-system": "latest",
213
+ "@ai-matrx/kit": "latest",
212
214
  "@ai-matrx/print": "latest",
213
215
  "@ai-matrx/records": "latest",
214
- "@ai-matrx/design-system": "latest",
215
- "@ai-matrx/api": "latest",
216
216
  "@ai-matrx/rich-content": "latest"
217
217
  },
218
218
  "peerDependencies": {
@@ -278,5 +278,5 @@
278
278
  "fuzz:sheets": "SHEET_FUZZ_SEEDS=${SHEET_FUZZ_SEEDS:-4000} CHAIN_FUZZ_SEEDS=${CHAIN_FUZZ_SEEDS:-4000} SHEET_FUZZ_HEAP_MB=${SHEET_FUZZ_HEAP_MB:-12288} NODE_OPTIONS=--max-old-space-size=16384 vitest run src/collab/sheets/transform/sheet-transform-fuzz.test.ts src/collab/sheets/transform/sheet-transform-chain-fuzz.test.ts",
279
279
  "verify:tarball": "node ./scripts/verify-tarball.mjs"
280
280
  },
281
- "gitHead": "184cfc8959ef4e79c4755b5cdd85e37e0c6165bc"
281
+ "gitHead": "90e2be3bbc11d2126bf10fba53e49ba898a3a6ae"
282
282
  }