@embedpdf/viewer-chrome 3.0.0-next.0 → 3.0.0-next.10
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/chrome.cjs +8 -1
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +1 -0
- package/dist/chrome.d.ts +1 -0
- package/dist/chrome.js +8 -1
- package/dist/chrome.js.map +1 -1
- package/dist/commands.cjs +38 -8
- package/dist/commands.cjs.map +1 -1
- package/dist/commands.js +39 -9
- package/dist/commands.js.map +1 -1
- package/dist/{es-C5084JO6.cjs → es-B7b8KjR3.cjs} +44 -1
- package/dist/es-B7b8KjR3.cjs.map +1 -0
- package/dist/{es-D0PzYE9Z.js → es-aQlZ3hcL.js} +44 -1
- package/dist/es-aQlZ3hcL.js.map +1 -0
- package/dist/index.cjs +723 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +728 -141
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/es-C5084JO6.cjs.map +0 -1
- package/dist/es-D0PzYE9Z.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["InteractionToken","CommandsToken","StageToken","RedactionToken","AnnotationToken","SearchToken","StageToken","ShellToken","chromeHelpers","validateChrome"],"sources":["../src/config/stage.ts","../src/config/demo-tools.plugin.ts","../src/locales/en.ts","../src/config-context.tsx","../src/handle.ts","../src/ui/icons.tsx","../src/ui/theme.tsx","../src/ui/menu.tsx","../src/ui/toolbar.tsx","../src/ui/annotation-strip.tsx","../src/ui/tab-bar.tsx","../src/ui/tool-cursor.tsx","../src/ui/annotation-flags.tsx","../src/ui/annotation-style.tsx","../src/ui/redaction-panel.tsx","../src/ui/search-panel.tsx","../src/ui/panels.tsx","../src/ui/redact-confirm.tsx","../src/ui/document-boot.tsx","../src/Shell.tsx","../src/viewer.tsx"],"sourcesContent":["/**\n * The Stage is a LENS: one document can be viewed through several at once. The\n * thumbnail sidebar is a second lens over the SAME document — a single-column,\n * fixed-zoom grid with its own camera, fully independent of the main view.\n *\n * The token lives here (not in App.tsx) because two places need it: App wires the\n * `stagePlugin` lens with it, and the sidebar renders `<Stage token={...}>` off it.\n */\nimport { createCapabilityToken } from '@embedpdf/react/runtime';\nimport type { StageCapability } from '@embedpdf/react/stage';\n\nexport const ThumbsStageToken = createCapabilityToken<StageCapability>('stage-thumbs');\n","import { definePlugin } from '@embedpdf/react/runtime';\nimport { InteractionToken } from '@embedpdf/react/interaction';\n\n/**\n * Example-only: register the insert / redact authoring tools as INERT\n * interaction tools. v3 doesn't yet ship signature or redaction plugins, but\n * this is a CHROME demo — its job is selection state and layout, not the\n * tool's effect. Registering them as real (behaviourless) tools lets every\n * tool button in every mode band go through the SAME path\n * (`InteractionToken.activateTool`), so `active` is uniform and honest: the\n * button really is the active tool; it just has no handler behind it.\n *\n * The annotate + shapes tools are NOT here — those are real tools the\n * annotation plugin registers (highlight, ink, square, circle, …) — and\n * neither are the form palette tools (the form plugin's draw-to-place).\n */\nconst INERT_TOOLS: ReadonlyArray<{ id: string; cursor: string }> = [\n // insert mode (redact is REAL now — plugin-annotation ships the composed\n // tool and plugin-redaction the destructive apply)\n { id: 'signature', cursor: 'copy' },\n { id: 'image', cursor: 'copy' },\n];\n\nexport const demoToolsPlugin = () =>\n definePlugin({\n id: 'demo-tools',\n scope: 'document',\n requires: [InteractionToken],\n init: (ctx) => {\n const interaction = ctx.get(InteractionToken);\n for (const tool of INERT_TOOLS) {\n // No `enables` → no gesture/handler wakes up: the tool is selectable\n // (cursor + active state) but behaviourless. Exactly what a chrome demo\n // needs from form/redact/signature tools v3 doesn't ship yet.\n interaction.registerTool({ id: tool.id, cursor: tool.cursor, enables: new Set<string>() });\n }\n },\n });\n","import type { Locale } from '@embedpdf/react/i18n';\n\n/**\n * English pack. Strings belong to the PRODUCT, not the plugins — the\n * `commands.*` namespace mirrors the v2 snippet packs so translations carry\n * over; `demo.*` is this example's own chrome.\n */\nexport const en: Locale = {\n code: 'en',\n name: 'English',\n translations: {\n commands: {\n zoom: {\n in: 'Zoom In',\n out: 'Zoom Out',\n fitPage: 'Fit to Page',\n fitWidth: 'Fit to Width',\n automatic: 'Automatic',\n menu: 'Zoom',\n level: 'Zoom Level',\n p50: '50%',\n p100: '100%',\n p150: '150%',\n p200: '200%',\n p400: '400%',\n },\n pan: 'Pan',\n pointer: 'Pointer',\n sidebar: 'Sidebar',\n search: 'Search',\n comment: 'Comment',\n style: 'Style',\n menu: 'Menu',\n viewControls: 'View Controls',\n download: 'Download',\n print: 'Print',\n fullscreen: 'Full Screen',\n spread: { group: 'Page Layout', none: 'Single Page', odd: 'Two Page', even: 'Cover Page' },\n scroll: { group: 'Scrolling', vertical: 'Vertical', horizontal: 'Horizontal' },\n rotate: {\n group: 'Rotate',\n clockwise: 'Rotate Clockwise',\n counterclockwise: 'Rotate Counter-Clockwise',\n },\n mode: {\n group: 'Mode',\n view: 'View',\n annotate: 'Annotate',\n shapes: 'Shapes',\n insert: 'Insert',\n form: 'Form',\n redact: 'Redact',\n },\n annotate: {\n highlight: 'Highlight',\n strikeout: 'Strikeout',\n underline: 'Underline',\n squiggly: 'Squiggly',\n ink: 'Draw',\n inkHighlight: 'Ink Highlighter',\n text: 'Text',\n insertText: 'Insert Text',\n replaceText: 'Replace Text',\n callout: 'Callout',\n note: 'Comment',\n link: 'Link',\n gotoLink: 'Go to link',\n removeLink: 'Remove link',\n delete: 'Delete',\n group: 'Group',\n ungroup: 'Ungroup',\n strip: 'Annotation actions',\n },\n shapes: {\n rectangle: 'Rectangle',\n circle: 'Circle',\n line: 'Line',\n arrow: 'Arrow',\n polygon: 'Polygon',\n polyline: 'Polyline',\n },\n insert: {\n stamp: 'Rubber Stamp',\n attachment: 'Attach File',\n signature: 'Signature',\n image: 'Image',\n },\n form: {\n textfield: 'Text Field',\n checkbox: 'Checkbox',\n radio: 'Radio Button',\n select: 'Dropdown',\n listbox: 'List Box',\n },\n redact: {\n mark: 'Mark for Redaction',\n applyAll: 'Apply Redactions',\n clearAll: 'Clear Marks',\n panel: 'Redactions',\n },\n undo: 'Undo',\n redo: 'Redo',\n },\n passwordPrompt: {\n title: 'Password required',\n required: 'This document is password protected. Enter the password to open it.',\n incorrect: 'The password was incorrect. Please try again.',\n incorrectWarning: 'Incorrect password',\n label: 'Password',\n placeholder: 'Enter password',\n cancel: 'Cancel',\n open: 'Open',\n opening: 'Opening…',\n },\n documentError: {\n title: 'Couldn’t open document',\n unknown: 'The document could not be opened.',\n close: 'Close document',\n },\n demo: {\n starting: 'Starting viewer…',\n opening: 'Opening document…',\n more: 'More',\n thumbnails: 'Thumbnails',\n outline: 'Outline',\n searchPlaceholder: 'Search document…',\n searchTitle: 'Search',\n searchCaseSensitive: 'Case sensitive',\n searchWholeWord: 'Whole word',\n searchRegex: 'Regular expression',\n searchSearching: 'Searching…',\n searchResults: '{count} results found',\n searchNoResults: 'No results',\n searchPage: 'Page {page}',\n commentsTitle: 'Comments',\n styleTitle: 'Style',\n empty: 'Nothing here yet in this demo panel.',\n page: 'Page {current} of {total}',\n cancel: 'Cancel',\n pageBadge: 'p. {page}',\n redactionTitle: 'Redactions',\n redactionEmpty: 'No pending redactions. Use the Redact tool to mark text or areas.',\n redactionArea: 'Area mark',\n redactionText: 'Text mark',\n redactionRemove: 'Remove mark',\n redactConfirmTitle: 'Apply redactions?',\n redactConfirmBody:\n 'Permanently remove the content under {count} redaction marks. This cannot be undone.',\n redactConfirmCollateral: '{count} other annotations will also be removed.',\n redactApply: 'Apply',\n redactApplying: 'Applying…',\n redactLabelTitle: 'Redaction label',\n redactLabelPlaceholder: 'e.g. REDACTED',\n redactLabelRepeat: 'Repeat label across region',\n },\n },\n};\n","/**\n * The resolved customization, as React context. The chrome schema and the\n * user's extra icons are RESOLVED ONCE in <FullViewer> and read here by the\n * shell, menus, and strips — no component imports the default schema value\n * directly, so \"the host replaced the chrome\" is invisible below this line.\n *\n * The default context value is the default config: components render correctly\n * in tests and stories without a provider.\n */\nimport { createContext, useContext } from 'react';\nimport type { BarSchema, ChromeSchema, MenuSchema } from '@embedpdf/react/toolbar';\nimport { defaultChrome, getMenu, getModeBar, getStrip } from './config/chrome';\nimport type { IconDef } from './ui/icons';\n\nexport interface ResolvedViewerConfig {\n readonly chrome: ChromeSchema;\n /** User-registered icons — additive over the built-in set. */\n readonly icons: Readonly<Record<string, IconDef>>;\n}\n\nconst DEFAULT_CONFIG: ResolvedViewerConfig = { chrome: defaultChrome, icons: {} };\n\nconst ViewerConfigContext = createContext<ResolvedViewerConfig>(DEFAULT_CONFIG);\n\nexport const ViewerConfigProvider = ViewerConfigContext.Provider;\n\nexport function useChromeSchema(): ChromeSchema {\n return useContext(ViewerConfigContext).chrome;\n}\n\nexport function useMenuSchema(id: string): MenuSchema | undefined {\n return getMenu(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useModeBarSchema(id: string): BarSchema | undefined {\n return getModeBar(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useStripSchema(id: string): BarSchema | undefined {\n return getStrip(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useCustomIcons(): Readonly<Record<string, IconDef>> {\n return useContext(ViewerConfigContext).icons;\n}\n","/**\n * The viewer handle — `el.viewer`, the DRIVE door of the customization model.\n *\n * Deliberately a THIN SKIN over the kernel: `get()` returns each plugin's\n * PUBLIC capability lens exactly as the plugin defined it (the internal/public\n * two-lens split in the plugins IS the curation — this file adds no facade,\n * no second vocabulary, no second write path). `watch()` is the kernel's one\n * change stream, selector-shaped — `useSelector` without React. The command\n * trio is the UI altitude of the same system, for anything button-shaped.\n *\n * Rule of thumb (docs): buttons speak commands; code speaks capabilities.\n *\n * The chrome itself runs on these exact primitives (customer #1), so parity\n * between \"what our UI can do\" and \"what el.viewer can do\" is structural.\n */\nimport type {\n CapabilityToken,\n DocumentsCapability,\n Kernel,\n Unsubscribe,\n} from '@embedpdf/react/runtime';\nimport { CommandsToken, resolvedCommandsEqual } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\n\n/** `get`/`tryGet` bound to one document (see {@link ViewerHandle.forDocument}). */\nexport interface ScopedViewerHandle {\n get<T>(token: CapabilityToken<T>): T;\n tryGet<T>(token: CapabilityToken<T>): T | null;\n}\n\nexport interface ViewerHandle extends ScopedViewerHandle {\n /** The document registry — the tab model: list/open/close/setActive/…. */\n readonly documents: DocumentsCapability;\n\n /** `get`/`tryGet` with document-scoped tokens bound to `documentId`\n * instead of the active document. */\n forDocument(documentId: string): ScopedViewerHandle;\n\n /**\n * Re-run `select` on every kernel change; call `cb` when the selected value\n * really changed (`isEqual`, default `Object.is` — capability getters return\n * stable references between model changes, so identity works). Returns the\n * unsubscribe. This is the ONLY reactivity primitive; DOM events on the\n * element are sugar over it.\n */\n watch<T>(\n select: () => T,\n cb: (value: T, previous: T) => void,\n isEqual?: (a: T, b: T) => boolean,\n ): Unsubscribe;\n\n // ── commands: the UI vocabulary layered on the same capabilities ──────────\n execute(id: string, documentId?: string): void;\n resolve(id: string, documentId?: string): ResolvedCommand | null;\n /** `watch` sugar for one command's resolved state (label/icon/enabled/active). */\n watchCommand(id: string, cb: (cmd: ResolvedCommand | null) => void): Unsubscribe;\n}\n\nexport function createViewerHandle(kernel: Kernel): ViewerHandle {\n const watch = <T>(\n select: () => T,\n cb: (value: T, previous: T) => void,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): Unsubscribe => {\n let previous = select();\n return kernel.subscribe(() => {\n const next = select();\n if (isEqual(previous, next)) return;\n const before = previous;\n previous = next;\n cb(next, before);\n });\n };\n\n const commands = () => kernel.capability(CommandsToken);\n\n return {\n documents: kernel.documents,\n get: (token) => kernel.capability(token),\n tryGet: (token) => kernel.tryCapability(token),\n forDocument: (documentId) => ({\n get: (token) => kernel.capability(token, documentId),\n tryGet: (token) => kernel.tryCapability(token, documentId),\n }),\n watch,\n execute: (id, documentId) => commands().execute(id, documentId),\n resolve: (id, documentId) => commands().resolve(id, documentId) ?? null,\n watchCommand: (id, cb) =>\n watch(() => commands().resolve(id) ?? null, cb, resolvedCommandsEqual),\n };\n}\n","/**\n * Icon set — the snippet's Tabler-style stroke icons, extracted to path data\n * (from viewers/snippet/src/components/icons) and rendered by one <Icon>\n * component. Names match the snippet's icon registry so command `icon` ids\n * carry over verbatim. Stroke-based (currentColor); a few glyphs carry filled\n * sub-paths, marked `fill: true`.\n *\n * ACCENT SLOTS: a tool glyph tags the sub-paths that preview the tool's\n * drawing defaults — `stroke`/`fill: 'primary' | 'secondary'` paint from the\n * command's resolved `iconAccent` (slot placement ported 1:1 from the v2\n * hand-authored components). With no accent, a slotted stroke inherits\n * currentColor and a slotted fill renders nothing — pixel-identical to the\n * untagged glyph, so non-tool surfaces never change.\n *\n * GENERATED by scratchpad/extract-icons.mjs — 93 icons (slot tags by hand).\n */\nimport * as React from 'react';\nimport { useCustomIcons } from '../config-context';\n\nexport type PathSpec =\n | string\n | {\n d: string;\n /** Fill paint: `true` = currentColor (a filled glyph part); a slot\n * name = that accent color (nothing when the accent is absent). */\n fill?: boolean | 'primary' | 'secondary';\n /** Stroke paint: a slot name = that accent color (currentColor when\n * the accent is absent). */\n stroke?: 'primary' | 'secondary';\n };\n\n/** A registrable icon: 24×24 stroke path data (Tabler/Lucide-style), exactly\n * the shape of the built-in set — user icons are not a lesser kind. */\nexport type IconDef = readonly PathSpec[];\n\n/** The two tintable slots — structurally identical to plugin-commands'\n * IconAccent, kept local so the icon set stays dependency-free. */\nexport interface IconAccent {\n primary?: string;\n secondary?: string;\n}\n\nexport const ICON_PATHS: Record<string, readonly PathSpec[]> = {\n alertTriangle: [\n 'M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z',\n ],\n alignBottom: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 17h2',\n 'M9 14h6',\n 'M10 11h4',\n ],\n alignCenter: ['M4 6l16 0', 'M8 12l8 0', 'M6 18l12 0'],\n alignLeft: ['M4 6l16 0', 'M4 12l10 0', 'M4 18l14 0'],\n alignMiddle: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 15h2',\n 'M9 12h6',\n 'M10 9h4',\n ],\n alignRight: ['M4 6l16 0', 'M10 12l10 0', 'M6 18l14 0'],\n alignTop: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 13h2',\n 'M9 10h6',\n 'M10 7h4',\n ],\n arrowBackUp: ['M9 14l-4 -4l4 -4', 'M5 10h11a4 4 0 1 1 0 8h-1'],\n arrowForwardUp: ['M15 14l4 -4l-4 -4', 'M19 10h-11a4 4 0 1 0 0 8h1'],\n bold: ['M7 5h6a3.5 3.5 0 0 1 0 7h-6z', 'M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7'],\n book: [\n 'M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0',\n 'M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0',\n 'M3 6l0 13',\n 'M12 6l0 13',\n 'M21 6l0 13',\n ],\n book2: [\n 'M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z',\n 'M19 16h-12a2 2 0 0 0 -2 2',\n 'M9 8h6',\n ],\n callout: [\n {\n d: 'M20 6v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1',\n stroke: 'primary',\n fill: 'secondary',\n },\n { d: 'M17 11v6h-9', stroke: 'primary' },\n { d: 'M8 15l-2 2l2 2', stroke: 'primary' },\n ],\n check: ['M5 12l5 5l10 -10'],\n chevronDown: ['M6 9l6 6l6 -6'],\n chevronLeft: ['M15 6l-6 6l6 6'],\n chevronRight: ['M9 6l6 6l-6 6'],\n circle: [\n { d: 'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', stroke: 'primary', fill: 'secondary' },\n ],\n comment: [\n 'M12 11v.01',\n 'M8 11v.01',\n 'M16 11v.01',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3z',\n ],\n copy: [\n 'M7 7m0 2.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z',\n 'M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1',\n ],\n deviceFloppy: [\n 'M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2',\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M14 4l0 4l-6 0l0 -4',\n ],\n dots: [\n 'M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n ],\n doublePage: [\n 'M3 3m0 1a1 1 0 0 1 1 -1h16a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1zm9 -1v18',\n ],\n download: ['M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2', 'M7 11l5 5l5 -5', 'M12 4l0 12'],\n externalLink: [\n 'M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6',\n 'M11 13l9 -9',\n 'M15 4h5v5',\n ],\n eye: ['M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'],\n file: ['M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'],\n fileImport: [\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M5 13v-8a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-5.5m-9.5 -2h7m-3 -3l3 3l-3 3',\n ],\n fitToPage: [\n 'M12 20h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6',\n 'M18 14v7',\n 'M18 3v7',\n 'M15 18l3 3l3 -3',\n 'M15 6l3 -3l3 3',\n ],\n fitToWidth: [\n 'M4 12v-6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v6',\n 'M10 18h-7',\n 'M21 18h-7',\n 'M6 15l-3 3l3 3',\n 'M18 15l3 3l-3 3',\n ],\n formCheckbox: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M9 12l2 2l4 -4',\n ],\n formListbox: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M11 8h6',\n 'M11 12h6',\n 'M11 16h6',\n 'M7 8l0 .01',\n 'M7 12l0 .01',\n 'M7 16l0 .01',\n ],\n formRadio: [\n { d: 'M9 12a2 2 0 1 0 6 0a2 2 0 1 0 -6 0', fill: true },\n 'M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0',\n ],\n formSelect: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M9 11l3 3l3 -3',\n ],\n formTextfield: [\n 'M12 3a3 3 0 0 0 -3 3v12a3 3 0 0 0 3 3',\n 'M6 3a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3',\n 'M13 7h7a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-7',\n 'M5 7h-1a1 1 0 0 0 -1 1v8a1 1 0 0 0 1 1h1',\n 'M17 12h.01',\n 'M13 12h.01',\n ],\n freeText: [\n { d: 'M4 7v-2h12v2', stroke: 'primary' },\n { d: 'M10 5v14', stroke: 'primary' },\n { d: 'M12 19h-4', stroke: 'primary' },\n { d: 'M15 13v-1h6v1', stroke: 'primary' },\n { d: 'M18 12v7', stroke: 'primary' },\n { d: 'M17 19h2', stroke: 'primary' },\n ],\n fullscreen: [\n 'M4 8v-2a2 2 0 0 1 2 -2h2',\n 'M4 16v2a2 2 0 0 0 2 2h2',\n 'M16 4h2a2 2 0 0 1 2 2v2',\n 'M16 20h2a2 2 0 0 0 2 -2v-2',\n ],\n fullscreenExit: [\n 'M4 8v-2c0 -.551 .223 -1.05 .584 -1.412',\n 'M4 16v2a2 2 0 0 0 2 2h2',\n 'M16 4h2a2 2 0 0 1 2 2v2',\n 'M16 20h2c.545 0 1.04 -.218 1.4 -.572',\n 'M3 3l18 18',\n ],\n group: [\n 'M3 5a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M17 5a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M3 19a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M17 19a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M5 7v10',\n 'M19 7v10',\n 'M7 5h10',\n 'M7 19h10',\n 'M8 8H12.8V11.2H16V16H11.2V12.8H8V8Z',\n ],\n hand: [\n 'M8 13v-7.5a1.5 1.5 0 0 1 3 0v6.5',\n 'M11 5.5v-2a1.5 1.5 0 1 1 3 0v8.5',\n 'M14 5.5a1.5 1.5 0 0 1 3 0v6.5',\n 'M17 7.5a1.5 1.5 0 0 1 3 0v8.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47',\n ],\n highlight: [\n // the v2 marker block behind the \"A\" — visible only when accented\n {\n d: 'M4 6h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2H4a2 2 0 0 1 -2 -2V8a2 2 0 0 1 2 -2z',\n fill: 'primary',\n },\n 'M8 16v-8a4 4 0 1 1 8 0v8',\n 'M8 10h8',\n ],\n horizontal: ['M7 8l-4 4l4 4', 'M17 8l4 4l-4 4', 'M3 12l18 0'],\n inkHighlighter: [\n 'M3 19h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4',\n 'M12.5 5.5l4 4',\n 'M4.5 13.5l4 4',\n { d: 'M21 15v4h-8l4 -4l4 0', stroke: 'primary', fill: 'primary' },\n ],\n insertText: [\n { d: 'M3 7v-2h12v2', stroke: 'primary' },\n { d: 'M9 5v14', stroke: 'primary' },\n { d: 'M7 19h4', stroke: 'primary' },\n { d: 'M18 15l2 2h-5', stroke: 'primary' },\n { d: 'M18 19l2 -2', stroke: 'primary' },\n ],\n italic: ['M11 5l6 0', 'M7 19l6 0', 'M14 5l-4 14'],\n line: [{ d: 'M20 4l-16 16', stroke: 'primary' }],\n // Both strokes tag the `primary` accent slot so the arrow glyph previews the\n // tool's stroke colour (like the plain `line` icon); with no accent they render\n // as currentColor — identical to the untagged glyph.\n lineArrow: [\n { d: 'M20 4l-16 16', stroke: 'primary' },\n { d: 'M16 3h5v5', stroke: 'primary' },\n ],\n link: [\n 'M9 15l6 -6',\n 'M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464',\n 'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',\n ],\n linkOff: [\n 'M9 15l3 -3m2 -2l1 -1',\n 'M11 6l.463 -.536a5 5 0 0 1 7.072 7.071l-.534 .464',\n 'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',\n 'M3 3l18 18',\n ],\n listTree: ['M9 6h11', 'M12 12h8', 'M15 18h5', 'M5 6v.01', 'M8 12v.01', 'M11 18v.01'],\n lock: [\n 'M5 11h14a2 2 0 0 1 2 2v7a2 2 0 0 1 -2 2H5a2 2 0 0 1 -2 -2v-7a2 2 0 0 1 2 -2z',\n 'M7 11V7a5 5 0 0 1 10 0v4',\n ],\n marqueeSelect: [\n 'M17 20h6',\n 'M20 17v6',\n 'M4 13v-2',\n 'M4 6v-1a1 1 0 0 1 1 -1h1',\n 'M6 20h-1a1 1 0 0 1 -1 -1v-1',\n 'M11 4h2',\n 'M11 20h2',\n 'M18 4h1a1 1 0 0 1 1 1v1',\n 'M20 11v2',\n ],\n menu: ['M4 8l16 0', 'M4 16l16 0'],\n message: [\n 'M8 9h8',\n 'M8 13h6',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12',\n ],\n palette: [\n 'M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25',\n 'M8.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M12.5 7.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M16.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n ],\n paperclip: [\n 'M15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3l6.5 -6.5a3 3 0 0 0 -6 -6l-6.5 6.5a4.5 4.5 0 0 0 9 9l6.5 -6.5',\n ],\n pencilMarker: [\n 'm9.109 16.275 8.856-8.097c.812-.743.87-2.014.127-2.826s-2.014-.869-2.826-.127L6.41 13.322l-.127 2.826zM13.79 6.575l2.7 2.952',\n {\n d: 'M19.375 20.125c.569.063-4.05-.562-6.412-.437s-4.759 1.229-6.857 1.625c-1.764.687-3.404-.938-1.981-2.5',\n stroke: 'primary',\n },\n ],\n photo: [\n 'M15 8h.01',\n 'M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12z',\n 'M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5',\n 'M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3',\n ],\n // hand-added: the v2 file draws <line> primitives the extractor skips\n plus: ['M12 5l0 14', 'M5 12l14 0'],\n pointer: [\n 'M7.904 17.563a1.2 1.2 0 0 0 2.228 .308l2.09 -3.093l4.907 4.907a1.067 1.067 0 0 0 1.509 0l1.047 -1.047a1.067 1.067 0 0 0 0 -1.509l-4.907 -4.907l3.113 -2.09a1.2 1.2 0 0 0 -.309 -2.228l-13.582 -3.904l3.904 13.563z',\n ],\n polygon: [\n {\n d: 'M13.163 2.168l8.021 5.828c.694 .504 .984 1.397 .719 2.212l-3.064 9.43a1.978 1.978 0 0 1 -1.881 1.367h-9.916a1.978 1.978 0 0 1 -1.881 -1.367l-3.064 -9.43a1.978 1.978 0 0 1 .719 -2.212l8.021 -5.828a1.978 1.978 0 0 1 2.326 0z',\n stroke: 'primary',\n fill: 'secondary',\n },\n ],\n print: [\n 'M17 17h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-14a2 2 0 0 0 -2 2v4a2 2 0 0 0 2 2h2',\n 'M17 9v-4a2 2 0 0 0 -2 -2h-6a2 2 0 0 0 -2 2v4',\n 'M7 13m0 2a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v4a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z',\n ],\n redact: [\n 'M7 4h10',\n 'M12 4v8',\n 'M-7 24l12 -12',\n 'M-3 24l12 -12',\n 'M1 24l12 -12',\n 'M5 24l12 -12',\n 'M9 24l12 -12',\n 'M13 24l12 -12',\n 'M17 24l12 -12',\n 'M21 24l12 -12',\n 'M25 24l12 -12',\n ],\n // v2 parity: dashed frame + a SMALL rounded hatched box (v2 clips the\n // hatch via <clipPath>; this icon system is plain paths, so the hatch\n // segments are pre-clipped to the 10..22 box analytically).\n redactArea: [\n 'M6 20h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 13v-3',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h3',\n 'M17 3h1a2 2 0 0 1 2 2v1',\n 'M12 10h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2z',\n 'M10 12l2 -2',\n 'M10 16l6 -6',\n 'M10 20l10 -10',\n 'M12 22l10 -10',\n 'M16 22l6 -6',\n 'M20 22l2 -2',\n ],\n redactCombined: [\n 'M6 20h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 13v-3',\n 'M20 13v-3',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h3',\n 'M17 3h1a2 2 0 0 1 2 2v1',\n 'M8 8h8',\n 'M12 8v7',\n 'M6 19l12 -12',\n 'M6 23l12 -12',\n 'M10 23l12 -12',\n 'M14 27l12 -12',\n 'M14 23l12 -12',\n ],\n redactionSidebar: [\n 'M4 6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M15 4v16',\n 'M7 8h5',\n 'M7 11h5',\n 'M7 14h4',\n ],\n replaceText: [\n { d: 'M3 7v-2h12v2', stroke: 'primary' },\n { d: 'M9 5v14', stroke: 'primary' },\n { d: 'M7 19h4', stroke: 'primary' },\n { d: 'M20 14l2 2h-3', stroke: 'primary' },\n { d: 'M20 18l2 -2', stroke: 'primary' },\n { d: 'M19 16a3 3 0 1 0 2 5.236', stroke: 'primary' },\n ],\n rotateClockwise: ['M4.05 11a8 8 0 1 1 .5 4m-.5 5v-5h5'],\n rotateCounterClockwise: ['M19.95 11a8 8 0 1 0 -.5 4m.5 5v-5h-5'],\n rubberStamp: [\n 'M21 17.85h-18c0 -4.05 1.421 -4.05 3.79 -4.05c5.21 0 1.21 -4.59 1.21 -6.8a4 4 0 1 1 8 0c0 2.21 -4 6.8 1.21 6.8c2.369 0 3.79 0 3.79 4.05',\n 'M5 21h14',\n ],\n rubberStampPlus: [\n 'M21 17.85h-18c0 -4.05 1.421 -4.05 3.79 -4.05c5.21 0 1.21 -4.59 1.21 -6.8a4 4 0 0 1 4.9 -4.1',\n 'M16 10c0 1.2 -4 3.8 1.21 3.8c2.369 0 3.79 0 3.79 4.05',\n 'M5 21h14',\n 'M16 5h6',\n 'M19 2v6',\n ],\n save: [\n 'M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2',\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M14 4l0 4l-6 0l0 -4',\n ],\n screenshot: [\n 'M7 19a2 2 0 0 1 -2 -2',\n 'M5 13v-2',\n 'M5 7a2 2 0 0 1 2 -2',\n 'M11 5h2',\n 'M17 5a2 2 0 0 1 2 2',\n 'M19 11v2',\n 'M19 17v4',\n 'M21 19h-4',\n 'M13 19h-2',\n ],\n search: ['M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0', 'M21 21l-6 -6'],\n settings: [\n 'M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z',\n 'M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0',\n ],\n sidebar: [\n 'M4 18v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M10 18v-12a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z',\n ],\n signature: [\n 'M3 17c3.333 -3.333 5 -6 5 -8c0 -3 -1 -3 -2 -3s-2.032 1.085 -2 3c.034 2.048 1.658 4.877 2.5 6c1.5 2 2.5 2.5 3.5 1l2 -3c.333 2.667 1.333 4 3 4c.53 0 2.639 -2 3 -2c.517 0 1.517 .667 3 2',\n ],\n singlePage: ['M5 3m0 1a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1z'],\n square: [\n {\n d: 'M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n stroke: 'primary',\n fill: 'secondary',\n },\n ],\n squares: [\n 'M8 10a2 2 0 0 1 2 -2h9a2 2 0 0 1 2 2v9a2 2 0 0 1 -2 2h-9a2 2 0 0 1 -2 -2z',\n 'M16 8v-3a2 2 0 0 0 -2 -2h-9a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h3',\n ],\n squiggly: [\n 'M8 16v-8a4 4 0 1 1 8 0v8',\n 'M8 10h8',\n { d: 'M4 20c1.5 -1.5 3.5 -1.5 5 0s3.5 1.5 5 0 3.5 -1.5 5 0', stroke: 'primary' },\n ],\n strikethrough: ['M8 16v-8a4 4 0 1 1 8 0v8', { d: 'M4 10h16', stroke: 'primary' }],\n text: [\n 'M6.5 15.5m-3.5 0a3.5 3.5 0 1 0 7 0a3.5 3.5 0 1 0 -7 0',\n 'M14 19v-10.5a3.5 3.5 0 0 1 7 0v10.5',\n 'M14 13h7',\n 'M10 12v7',\n ],\n trash: [\n 'M4 7l16 0',\n 'M10 11l0 6',\n 'M14 11l0 6',\n 'M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12',\n 'M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3',\n ],\n underline: [{ d: 'M4 20h16', stroke: 'primary' }, 'M8 16v-8a4 4 0 1 1 8 0v8', 'M8 10h8'],\n // the v2 ungroup glyph: two separated rounded rects\n ungroup: [\n 'M4 5a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z',\n 'M13 14a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z',\n ],\n unlock: ['M7 11V7a5 5 0 0 1 9.9-1'],\n vertical: ['M8 7l4 -4l4 4', 'M8 17l4 4l4 -4', 'M12 3l0 18'],\n viewSettings: [\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M12 10.5v1.5',\n 'M12 16v1.5',\n 'M15.031 12.25l-1.299 .75',\n 'M10.268 15l-1.3 .75',\n 'M15 15.803l-1.285 -.773',\n 'M10.285 12.97l-1.285 -.773',\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',\n ],\n widgetEdit: [\n 'M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1',\n 'M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415',\n 'M16 5l3 3',\n ],\n x: ['M18 6l-12 12', 'M6 6l12 12'],\n zigzag: [{ d: 'M12 2.4L21.36 11.76L2.64 12.24L12 21.6', stroke: 'primary' }],\n zoomIn: ['M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0', 'M9 12h6', 'M12 9v6'],\n zoomInArea: [\n 'M15 13v4',\n 'M13 15h4',\n 'M15 15m-5 0a5 5 0 1 0 10 0a5 5 0 1 0 -10 0',\n 'M22 22l-3 -3',\n 'M6 18h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 11v-1',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h1',\n 'M15 3h1a2 2 0 0 1 2 2v1',\n ],\n zoomOut: ['M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M9 12l6 0'],\n};\n\nexport type IconName = keyof typeof ICON_PATHS;\n\nexport interface IconProps {\n name: string;\n size?: number;\n strokeWidth?: number;\n className?: string;\n title?: string;\n /** Paints the glyph's slot-tagged sub-paths (a tool previewing its\n * drawing defaults). Absent → the plain, untinted glyph. */\n accent?: IconAccent;\n}\n\n/** One SVG renderer for every icon. Unknown names render nothing (caller shows\n * a text fallback), so a missing glyph never throws. */\nexport function Icon({ name, size = 20, strokeWidth = 2, className, title, accent }: IconProps) {\n // Registry semantics: user icons are additive and a colliding name WINS —\n // re-skinning a built-in glyph is a supported move, not an accident.\n const custom = useCustomIcons();\n const paths = custom[name] ?? ICON_PATHS[name];\n if (!paths) return null;\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n role=\"img\"\n aria-hidden={title ? undefined : true}\n aria-label={title}\n >\n {paths.map((p, i) => {\n if (typeof p === 'string') return <path key={i} d={p} />;\n const fill = p.fill === true ? 'currentColor' : p.fill ? accent?.[p.fill] : undefined;\n // a stroke slot paints from the accent, inheriting currentColor\n // without one; a fill-ONLY path never gets an outline (the v2 look)\n const stroke = p.stroke ? accent?.[p.stroke] : p.fill ? 'none' : undefined;\n return <path key={i} d={p.d} fill={fill ?? 'none'} stroke={stroke} />;\n })}\n </svg>\n );\n}\n\nexport const hasIcon = (name: string): boolean => name in ICON_PATHS;\n","/**\n * Light/dark theme — one class, and the CSS variables in styles.css do the\n * rest (both toolbars, sidebars, popovers, and the canvas re-theme from it).\n * The mode comes from the embedder's `theme` preference; the chrome ships no\n * switch of its own, so a host that wants one drives this through `set`. The\n * class lands on <html> by default; a delivery that must not touch the page\n * (the <embedpdf-viewer> shadow root) passes `target` and the class stays\n * inside its own subtree. An explicit preference outranks the OS setting.\n */\nimport { createContext, useContext, useEffect, useMemo, useState } from 'react';\n\nexport type ThemeMode = 'light' | 'dark';\nexport type ThemePreference = ThemeMode | 'system';\n\nconst ThemeCtx = createContext<{\n mode: ThemeMode;\n toggle: () => void;\n set: (m: ThemeMode) => void;\n} | null>(null);\n\nconst systemMode = (): ThemeMode =>\n typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light';\n\nexport function ThemeProvider({\n children,\n preference = 'system',\n target,\n}: {\n children: React.ReactNode;\n /** Initial mode; 'system' (default) follows the OS setting. */\n preference?: ThemePreference;\n /** Where the `.dark` class goes. Default: document.documentElement. */\n target?: HTMLElement | null;\n}) {\n const [mode, setMode] = useState<ThemeMode>(() =>\n preference === 'system' ? systemMode() : preference,\n );\n useEffect(() => {\n (target ?? document.documentElement).classList.toggle('dark', mode === 'dark');\n }, [mode, target]);\n const value = useMemo(\n () => ({ mode, toggle: () => setMode((m) => (m === 'dark' ? 'light' : 'dark')), set: setMode }),\n [mode],\n );\n return <ThemeCtx.Provider value={value}>{children}</ThemeCtx.Provider>;\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeCtx);\n if (!ctx) throw new Error('useTheme must be used within <ThemeProvider>');\n return ctx;\n}\n","/**\n * Menu rendering — a MenuSchema (a tree of command ids) rendered as rows.\n * Reused by the toolbar dropdowns (document / zoom / page-settings) AND by the\n * overflow menu's inline submenu expansion, so a command's menu form is\n * identical wherever it surfaces. Rows resolve live through the command\n * registry: label, icon, active tick, enabled state.\n */\nimport { useState } from 'react';\nimport { useCommand, useCommands } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport type { MenuSchema } from '@embedpdf/react/toolbar';\nimport { Icon } from './icons';\nimport { useMenuSchema } from '../config-context';\n\nexport function MenuRow({ commandId, onRun }: { commandId: string; onRun?: () => void }) {\n const cmd = useCommand(commandId);\n const commands = useCommands();\n if (!cmd || !cmd.visible) return null;\n return (\n <button\n type=\"button\"\n role={cmd.active ? 'menuitemradio' : 'menuitem'}\n part={cmd.active ? 'menu-item menu-item-active' : 'menu-item'}\n aria-checked={cmd.active || undefined}\n disabled={!cmd.enabled}\n onClick={() => {\n commands.execute(commandId);\n onRun?.();\n }}\n // v2 shows selection as a blue-tinted row (bg-interactive-selected +\n // text-accent), never a checkmark — the icon column stays the command's\n // own icon.\n className={`flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors disabled:pointer-events-none disabled:opacity-40 ${\n cmd.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {cmd.icon && (\n <Icon\n name={cmd.icon}\n size={16}\n accent={cmd.iconAccent}\n className={cmd.active ? '' : 'text-fg-muted'}\n />\n )}\n <span className=\"flex-1 truncate\">{cmd.label}</span>\n </button>\n );\n}\n\n/** One section-separated menu, by schema id. */\nexport function MenuBody({ menuId, onRun }: { menuId: string; onRun?: () => void }) {\n const t = useT();\n const menu: MenuSchema | undefined = useMenuSchema(menuId);\n if (!menu) return null;\n return (\n <div className=\"min-w-52 p-1\">\n {menu.sections.map((section, i) => (\n <div key={i}>\n {i > 0 && <div className=\"bg-border-subtle my-1 h-px\" />}\n {section.labelKey && (\n <div className=\"text-fg-muted px-2.5 pb-1 pt-1.5 text-[11px] font-semibold uppercase tracking-wide\">\n {t(section.labelKey)}\n </div>\n )}\n {section.items.map((id) => (\n <MenuRow key={id} commandId={id} onRun={onRun} />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\n/** The popover shell: a floating surface + click-away scrim. */\nexport function Popover({\n children,\n onClose,\n align = 'start',\n}: {\n children: React.ReactNode;\n onClose: () => void;\n align?: 'start' | 'end';\n}) {\n return (\n <>\n <div className=\"fixed inset-0 z-40\" onClick={onClose} />\n <div\n part=\"menu\"\n className={`border-border-subtle bg-elevated absolute top-full z-50 mt-1 rounded-lg border shadow-xl ${\n align === 'end' ? 'right-0' : 'left-0'\n }`}\n >\n {children}\n </div>\n </>\n );\n}\n\n/** A menu dropdown that expands inline (used inside the overflow menu, where a\n * submenu can't anchor to an off-screen trigger). */\nexport function InlineSubmenu({ menuId, label }: { menuId: string; label: string }) {\n const [open, setOpen] = useState(false);\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className=\"text-fg-secondary hover:bg-hover flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm\"\n >\n <span className=\"flex-1 truncate\">{label}</span>\n <Icon name={open ? 'chevronDown' : 'chevronRight'} size={16} />\n </button>\n {open && (\n <div className=\"border-border-subtle ml-3 border-l pl-1\">\n <MenuBody menuId={menuId} />\n </div>\n )}\n </div>\n );\n}\n","/**\n * The app's toolbar look — Tailwind render props over the headless <Toolbar>.\n * The app owns the pixels; ui-core owns the physics (measure → solve →\n * overflow). Nothing here knows about breakpoints or widths.\n *\n * Styling is a 1:1 port of the v2 snippet's components:\n * Button → viewers/snippet/src/components/ui/button.tsx\n * TabButton → viewers/snippet/src/components/ui/tab-button.tsx (underline)\n * zoom widget → viewers/snippet/src/components/custom-zoom-toolbar.tsx\n * mode select → viewers/snippet/src/components/mode-select-button.tsx\n */\nimport { useEffect, useState } from 'react';\nimport { useOptionalCapability, useOptionalSelector } from '@embedpdf/react/runtime';\nimport { Toolbar } from '@embedpdf/react/toolbar';\nimport type {\n BarSchema,\n CollapsedGroupView,\n GroupDisclosureView,\n OverflowMenuView,\n} from '@embedpdf/react/toolbar';\nimport { useCommands } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport { useMenus } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { StageToken } from '@embedpdf/react/stage';\nimport { Icon } from './icons';\nimport { MenuBody, Popover, InlineSubmenu } from './menu';\n\n// ── the v2 Button recipe ──────────────────────────────────────────────────────\nconst BTN_BASE =\n 'flex h-8 w-auto min-w-8 cursor-pointer items-center justify-center rounded-md p-[5px] transition-colors';\nconst BTN_HOVER = 'hover:bg-hover hover:ring hover:ring-accent';\nconst BTN_ACTIVE = 'border-none bg-selected text-accent shadow ring ring-accent';\nconst BTN_DISABLED = 'cursor-not-allowed opacity-50 hover:bg-transparent hover:ring-0';\n\nexport const buttonClass = (active: boolean, enabled = true): string =>\n `${BTN_BASE} ${active ? BTN_ACTIVE : BTN_HOVER} ${enabled ? '' : BTN_DISABLED}`;\n\n// ── the v2 TabButton recipe (the underline) ───────────────────────────────────\nconst TAB_BASE =\n 'flex h-8 w-auto min-w-8 cursor-pointer items-center justify-center rounded-none border-b-2 px-2 py-1 text-sm transition-colors hover:bg-transparent hover:border-b-fg-muted';\nconst TAB_ACTIVE = 'border-b-accent text-accent hover:border-b-accent';\nconst TAB_INACTIVE = 'border-b-transparent';\n\nconst tabClass = (active: boolean, enabled = true): string =>\n `${TAB_BASE} ${active ? TAB_ACTIVE : TAB_INACTIVE} ${enabled ? '' : 'cursor-not-allowed opacity-50'}`;\n\n// ── a single command button (icon / icon+label / label=tab) ──────────────────\nfunction CommandButton({\n cmd,\n variant,\n run,\n}: {\n cmd: ResolvedCommand;\n variant: string;\n run: () => void;\n}) {\n const isTab = variant === 'label';\n\n // v2 buttons carry NO caret — a menu command is a plain icon button; the\n // `menu:` declaration still drives aria-haspopup and the anchored popover.\n const button = (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.active || undefined}\n aria-haspopup={cmd.menu ? 'menu' : undefined}\n aria-label={cmd.label}\n title={cmd.label}\n // Shadow parts — the RESTYLE door: page CSS reaches these via\n // `embedpdf-viewer::part(toolbar-button)` etc. Part names are public\n // API; the vocabulary is deliberately small (see README).\n part={\n isTab\n ? `mode-tab${cmd.active ? ' mode-tab-active' : ''}`\n : `toolbar-button${cmd.active ? ' toolbar-button-active' : ''}`\n }\n className={isTab ? tabClass(cmd.active, cmd.enabled) : buttonClass(cmd.active, cmd.enabled)}\n >\n {isTab ? (\n <span className=\"whitespace-nowrap px-1\">{cmd.label}</span>\n ) : variant === 'icon+label' ? (\n <span className=\"flex items-center whitespace-nowrap text-sm\">\n {cmd.icon && (\n <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} className=\"mr-1.5 shrink-0\" />\n )}\n <span>{cmd.label}</span>\n </span>\n ) : cmd.icon ? (\n <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />\n ) : (\n <span className=\"text-sm\">{cmd.label}</span>\n )}\n </button>\n );\n\n if (!cmd.menu) return button;\n return <MenuAnchoredButton cmd={cmd}>{button}</MenuAnchoredButton>;\n}\n\nfunction MenuAnchoredButton({\n cmd,\n children,\n}: {\n cmd: ResolvedCommand;\n children: React.ReactNode;\n}) {\n const menus = useMenus();\n const open = cmd.menu ? menus.isOpen(cmd.menu) : false;\n return (\n <span className=\"relative inline-flex\">\n {children}\n {open && cmd.menu && (\n <Popover onClose={() => menus.close(cmd.menu!)}>\n <MenuBody menuId={cmd.menu} onRun={() => menus.close(cmd.menu!)} />\n </Popover>\n )}\n </span>\n );\n}\n\n// ── the inline zoom widget — v2's custom-zoom-toolbar, 1:1 ───────────────────\nfunction ZoomControls() {\n const commands = useCommands();\n const menus = useMenus();\n const stage = useOptionalCapability(StageToken);\n // Null-safe: the zoom strip is main-toolbar chrome, mounted before any\n // document exists — it reads 100% until a Stage is there to ask.\n const level = useOptionalSelector(StageToken, (c) => c.zoomLevel(), 1);\n const pct = Math.round((level ?? 1) * 100);\n const [inputValue, setInputValue] = useState(String(pct));\n useEffect(() => setInputValue(String(pct)), [pct]);\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n const value = parseFloat(inputValue);\n if (!isNaN(value) && value > 0) stage?.zoomTo({ level: value / 100 });\n };\n\n return (\n <div className=\"relative\">\n <div className=\"bg-hover flex items-center rounded\">\n {/* editable zoom percentage */}\n <form\n onSubmit={submit}\n className=\"flex min-w-0 flex-nowrap items-center overflow-hidden whitespace-nowrap\"\n >\n <input\n name=\"zoom\"\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"\\d*\"\n aria-label=\"Set zoom\"\n className=\"h-6 w-8 min-w-0 shrink border-0 bg-transparent p-0 text-right text-sm outline-none focus:outline-none\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value.replace(/[^0-9]/g, ''))}\n onBlur={() => {\n if (!inputValue || parseFloat(inputValue) <= 0) setInputValue(String(pct));\n }}\n />\n <span className=\"shrink-0 text-sm\">%</span>\n </form>\n {/* zoom menu chevron */}\n <button\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-expanded={menus.isOpen('zoom')}\n title=\"Zoom options\"\n className={buttonClass(false)}\n onClick={() => menus.toggle('zoom')}\n >\n <Icon name=\"chevronDown\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Zoom out\"\n className={buttonClass(false)}\n onClick={() => commands.execute('zoom:out')}\n >\n <Icon name=\"zoomOut\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Zoom in\"\n className={buttonClass(false)}\n onClick={() => commands.execute('zoom:in')}\n >\n <Icon name=\"zoomIn\" size={20} />\n </button>\n </div>\n {menus.isOpen('zoom') && (\n <Popover onClose={() => menus.close('zoom')}>\n <MenuBody menuId=\"zoom\" onRun={() => menus.close('zoom')} />\n </Popover>\n )}\n </div>\n );\n}\n\n/** The 'button' variant of the zoom slot — a single icon that opens the menu. */\nfunction ZoomButton() {\n const menus = useMenus();\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n title=\"Zoom\"\n aria-haspopup=\"menu\"\n aria-expanded={menus.isOpen('zoom')}\n className={buttonClass(menus.isOpen('zoom'))}\n onClick={() => menus.toggle('zoom')}\n >\n <Icon name=\"zoomIn\" size={20} />\n </button>\n {menus.isOpen('zoom') && (\n <Popover onClose={() => menus.close('zoom')}>\n <MenuBody menuId=\"zoom\" onRun={() => menus.close('zoom')} />\n </Popover>\n )}\n </span>\n );\n}\n\n// ── a shed group's in-strip disclosure (v2's overflow-tabs-button, derived) ──\nfunction GroupTrigger({ view }: { view: GroupDisclosureView }) {\n const [open, setOpen] = useState(false);\n // The active tab may be hiding behind the chevron — hint at it, tab-style.\n const activeHidden = view.commands.some((c) => c.active);\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className={tabClass(activeHidden)}\n >\n <Icon name=\"chevronDown\" size={18} />\n </button>\n {open && (\n <Popover onClose={() => setOpen(false)}>\n <div className=\"min-w-44 p-1\">\n {view.commands.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n role={view.role === 'tabs' ? 'menuitemradio' : 'menuitem'}\n aria-checked={view.role === 'tabs' ? c.active : undefined}\n disabled={!c.enabled}\n onClick={() => {\n view.execute(c.id);\n setOpen(false);\n }}\n className={`flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm disabled:cursor-not-allowed disabled:opacity-50 ${\n c.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {c.label}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </span>\n );\n}\n\n// ── the collapsed modes group — v2's mode-select-button, 1:1 ─────────────────\nfunction CollapsedModes({ view }: { view: CollapsedGroupView }) {\n const [open, setOpen] = useState(false);\n const active = view.commands.find((c) => c.active) ?? view.commands[0];\n // v2 highlights the control whenever a non-default mode is active.\n const isActive = Boolean(active?.active && active.id !== 'mode:view');\n return (\n <div style={{ width: 100 }} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className=\"bg-surface hover:bg-hover flex w-full cursor-pointer appearance-none items-center rounded-md py-1.5 pl-3 pr-2 text-[13px] transition-colors\"\n >\n <span\n className={`min-w-0 flex-1 truncate text-left ${isActive ? 'text-accent' : 'text-fg'}`}\n >\n {active?.label}\n </span>\n <Icon\n name=\"chevronDown\"\n size={16}\n className={isActive ? 'text-accent' : 'text-fg-secondary'}\n />\n </button>\n {open && (\n <Popover onClose={() => setOpen(false)}>\n <div className=\"min-w-44 p-1\">\n {view.commands.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={c.active}\n onClick={() => {\n view.execute(c.id);\n setOpen(false);\n }}\n className={`flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm ${\n c.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {c.label}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </div>\n );\n}\n\n// ── the derived overflow menu ────────────────────────────────────────────────\nfunction OverflowMenu({ view }: { view: OverflowMenuView }) {\n const t = useT();\n if (!view.isOpen) return null;\n return (\n <Popover onClose={view.close} align=\"end\">\n <div className=\"min-w-56 p-1\">\n {view.sections.map((section, i) => (\n <div key={i}>\n {i > 0 && <div className=\"bg-border-subtle my-1 h-px\" />}\n {section.labelKey && (\n <div className=\"text-fg-muted px-2.5 pb-1 pt-1.5 text-[11px] font-semibold uppercase tracking-wide\">\n {t(section.labelKey)}\n </div>\n )}\n {section.rows.map((row) => {\n const cmd = view.resolve(row.command);\n if (!cmd) return null;\n if (row.type === 'submenu') {\n return <InlineSubmenu key={row.command} menuId={row.menu} label={cmd.label} />;\n }\n return (\n <button\n key={row.command}\n type=\"button\"\n role={section.role === 'radio' ? 'menuitemradio' : 'menuitem'}\n aria-checked={section.role === 'radio' ? cmd.active : undefined}\n disabled={!cmd.enabled}\n onClick={() => {\n view.execute(row.command);\n view.close();\n }}\n // Same blue-highlight selection as the dropdown menus — no\n // checkmark; the icon column stays the command's own icon.\n className={`flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${\n cmd.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {cmd.icon && (\n <Icon name={cmd.icon} size={16} className={cmd.active ? '' : 'text-fg-muted'} />\n )}\n <span className=\"flex-1 truncate\">{cmd.label}</span>\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </Popover>\n );\n}\n\nfunction OverflowTrigger({ isOpen, toggle }: { isOpen: boolean; toggle: () => void }) {\n const t = useT();\n return (\n <button\n type=\"button\"\n onClick={toggle}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen}\n title={t('demo.more')}\n className={buttonClass(isOpen)}\n >\n <Icon name=\"dots\" size={20} />\n </button>\n );\n}\n\n// ── the assembled toolbar ────────────────────────────────────────────────────\nexport function AppToolbar({ bar, className }: { bar: BarSchema; className?: string }) {\n return (\n <Toolbar\n bar={bar}\n gap={8} // v2 toolbar gap-2\n separatorWidth={1}\n className={className}\n renderCommand={(cmd, variant, run) => <CommandButton cmd={cmd} variant={variant} run={run} />}\n renderCustom={{\n 'zoom-controls': (variant) => (variant === 'inline' ? <ZoomControls /> : <ZoomButton />),\n }}\n renderCollapsed={(view) => (view.id === 'modes' ? <CollapsedModes view={view} /> : undefined)}\n renderGroupTrigger={(view) => <GroupTrigger view={view} />}\n renderSeparator={() => <span className=\"bg-border h-6 w-px self-center\" />}\n renderOverflowTrigger={(isOpen, toggle) => (\n <OverflowTrigger isOpen={isOpen} toggle={toggle} />\n )}\n renderOverflowMenu={(view) => <OverflowMenu view={view} />}\n />\n );\n}\n","/**\n * The annotation selection strip — v2's floating \"selection menu\" rebuilt as\n * chrome. Three parties, none of them this file's business to compute:\n *\n * config/chrome.ts `strips.annotation` declares WHAT may appear\n * each command's visible/enabled decides WHICH items show\n * <AnnotationMenu> solves WHERE (camera transform,\n * rotate-knob dodging, pointer isolation)\n *\n * useStripView is the live intersection: hidden commands drop out, empty\n * groups vanish, null when nothing applies. This file only draws pixels.\n * Mounted in the Stage `overlay` slot.\n */\nimport { Fragment } from 'react';\nimport { AnnotationMenu } from '@embedpdf/react/annotation-menu';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStripSchema } from '../config-context';\nimport { buttonClass } from './toolbar';\nimport { Icon } from './icons';\n\nfunction StripButton({ cmd, run }: { cmd: ResolvedCommand; run: () => void }) {\n return (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.active || undefined}\n aria-label={cmd.label}\n title={cmd.label}\n className={buttonClass(cmd.active, cmd.enabled)}\n >\n {cmd.icon && <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />}\n </button>\n );\n}\n\nexport function AnnotationStrip() {\n const t = useT();\n const view = useStripView(useStripSchema('annotation'));\n if (!view) return null;\n return (\n <AnnotationMenu placement=\"bottom\" gap={15}>\n {() => (\n <div\n role=\"toolbar\"\n aria-label={t('commands.annotate.strip')}\n className=\"border-border-subtle bg-elevated flex items-center gap-1 rounded-lg border p-1 shadow-xl\"\n >\n {view.groups.map((g, i) => (\n <Fragment key={g.id}>\n {i > 0 && <span aria-hidden className=\"bg-border h-5 w-px\" />}\n {g.commands.map((cmd) => (\n <StripButton key={cmd.id} cmd={cmd} run={() => view.execute(cmd.id)} />\n ))}\n </Fragment>\n ))}\n </div>\n )}\n </AnnotationMenu>\n );\n}\n","/**\n * The document tab bar — a 1:1 port of v2's tab-bar.tsx\n * (viewers/snippet/src/components/tab-bar.tsx): rounded-top tabs on the\n * surface-alt strip, the active tab merging into the toolbar surface below,\n * close-× on the active tab, and a + button opening a real file dialog.\n *\n * v2 needed a DocumentManager capability; here the kernel's document registry\n * (useDocuments) already is the tab model — open/close/setActive, reactive.\n */\nimport { useRef } from 'react';\nimport { useDocuments } from '@embedpdf/react/runtime';\nimport type { OpenInput } from '@embedpdf/react/runtime';\nimport { Icon } from './icons';\n\nexport type TabBarVisibility = 'always' | 'multiple' | 'never';\n\nexport function TabBar({\n visibility = 'always',\n allowOpenFile = true,\n}: {\n visibility?: TabBarVisibility;\n allowOpenFile?: boolean;\n}) {\n const { docs, activeId, setActive, close, open } = useDocuments();\n const fileInput = useRef<HTMLInputElement>(null);\n\n const shouldShow = visibility === 'always' || (visibility === 'multiple' && docs.length > 1);\n if (!shouldShow) return null;\n\n const openFile = async (file: File) => {\n const bytes = new Uint8Array(await file.arrayBuffer());\n const source: OpenInput = { kind: 'bytes', id: `${file.name}-${Date.now()}`, bytes };\n await open(source, { name: file.name });\n };\n\n return (\n <div className=\"bg-surface-alt flex items-end pr-2 pt-2\">\n <div className=\"flex flex-1 items-end overflow-x-auto pl-4\">\n {docs.map((doc) => {\n const isActive = activeId === doc.id;\n return (\n <div\n key={doc.id}\n onClick={() => setActive(doc.id)}\n role=\"tab\"\n part={isActive ? 'tab tab-active' : 'tab'}\n tabIndex={0}\n aria-selected={isActive}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setActive(doc.id);\n }\n }}\n className={`group relative flex min-w-[120px] max-w-[240px] cursor-pointer items-center gap-2 rounded-t-lg px-4 py-2 text-sm font-medium transition-all ${\n isActive\n ? 'bg-surface text-fg z-10'\n : 'bg-surface-alt text-fg-secondary hover:bg-hover hover:text-fg'\n }`}\n >\n {/* lifecycle glyphs — the tab exists from the moment open()\n was called; these show what its document is doing */}\n {doc.status === 'loading' && (\n <span\n className=\"border-border-subtle border-t-accent h-3 w-3 flex-shrink-0 animate-spin rounded-full border\"\n aria-label=\"Loading\"\n />\n )}\n {doc.status === 'locked' && (\n <Icon name=\"lock\" size={13} className=\"text-fg-muted flex-shrink-0\" />\n )}\n {doc.status === 'error' && (\n <Icon name=\"alertTriangle\" size={13} className=\"flex-shrink-0 text-red-500\" />\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {doc.name ?? `Document ${doc.id.slice(0, 8)}`}\n </span>\n\n {/* close — on the active tab, and never the last document\n (an empty workspace is designable, but not this demo's goal) */}\n {isActive && docs.length > 1 && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void close(doc.id);\n }}\n aria-label={`Close ${doc.name ?? 'document'}`}\n className=\"hover:bg-hover flex-shrink-0 cursor-pointer rounded-full p-1 opacity-100 transition-all\"\n >\n <Icon name=\"x\" size={14} />\n </button>\n )}\n </div>\n );\n })}\n\n {allowOpenFile && (\n <>\n <button\n type=\"button\"\n onClick={() => fileInput.current?.click()}\n aria-label=\"Open File\"\n title=\"Open File\"\n className=\"text-fg-secondary hover:bg-hover hover:text-fg mb-1.5 ml-1 flex-shrink-0 cursor-pointer rounded p-1.5 transition-colors\"\n >\n <Icon name=\"plus\" size={14} />\n </button>\n <input\n ref={fileInput}\n type=\"file\"\n accept=\".pdf,application/pdf\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) void openFile(file);\n e.target.value = '';\n }}\n />\n </>\n )}\n </div>\n </div>\n );\n}\n","/**\n * THIS viewer's armed-tool cursor: the toolbar's own icon riding the pointer\n * as a real CSS cursor (OS-composited — zero lag, unlike any DOM follower).\n * The library owns arbitration (unmapped hover claims win, page gaps fall\n * back to the arrow — see `useToolCursor`); this module only decides what the\n * cursor LOOKS like. It reuses the SAME icon set and the SAME accent\n * derivation as the toolbar buttons (TOOL_ICONS is recorded by the command\n * definitions), so the cursor is pixel-identical to the button the user just\n * pressed — recolor the tool and both follow. A tool without a command icon\n * keeps its declared keyword cursor.\n *\n * ONE table decides the shape ({@link GLYPHS}): cursor KEYWORDS are the\n * affordances — a tool declares its base ('crosshair' to draw, 'copy' to\n * place), the selection handler claims 'text' over text — and each mapped\n * keyword is redrawn as its glyph + the tool's icon. Keywords the table omits\n * stay native: a markup tool's 'default' base is the bare arrow (identity\n * appears exactly where the action is possible — over text), a foreign 'move'\n * over an annotation drops the icon. A new tool gets the right cursor from\n * what it declares; nothing tool-specific lives here.\n *\n * The image: a white-haloed glyph at the hotspot (readable on any page color)\n * with the icon at its top right — 40px, under the 128px cursor ceiling;\n * Chromium may briefly show the default arrow when a >32px cursor would\n * overlap browser UI (anti-spoofing), which is fine mid-viewport.\n */\nimport { useToolCursor, useTool } from '@embedpdf/react/interaction';\nimport { useAnnotationDefaults } from '@embedpdf/react/annotation';\nimport { TOOL_ICONS } from '../config/commands';\nimport { ICON_PATHS } from './icons';\nimport type { IconAccent } from './icons';\n\nconst SIZE = 40;\nconst HOTSPOT = { x: 8, y: 28 };\nconst INK = '#1a1a1a';\nconst HALO = '#ffffff';\n/** The drag-and-drop \"will place a copy\" green (Chrome's DnD badge). */\nconst PLACE_GREEN = '#34a853';\n\n/** The icon's paths as SVG markup — the string twin of `<Icon>`'s render loop\n * (same fill/stroke slot rules), with a white halo pass underneath so the\n * glyph stays readable over page content. */\nfunction iconGlyph(name: string, accent?: IconAccent): string | null {\n const paths = ICON_PATHS[name];\n if (!paths) return null;\n const halo: string[] = [];\n const draw: string[] = [];\n for (const p of paths) {\n const spec = typeof p === 'string' ? { d: p, fill: undefined, stroke: undefined } : p;\n // Slot rules, mirrored from <Icon>: a fill slot paints from the accent\n // (nothing without one), a stroke slot falls back to the ink, and a\n // fill-only path never gets an outline.\n const fill = spec.fill === true ? INK : spec.fill ? accent?.[spec.fill] : undefined;\n const stroke = spec.stroke ? (accent?.[spec.stroke] ?? INK) : spec.fill ? 'none' : INK;\n halo.push(`<path d=\"${spec.d}\" fill=\"none\" stroke=\"${HALO}\" stroke-width=\"3.5\"/>`);\n draw.push(`<path d=\"${spec.d}\" fill=\"${fill ?? 'none'}\" stroke=\"${stroke}\"/>`);\n }\n return halo.join('') + draw.join('');\n}\n\n/** The action glyph drawn at the hotspot: what a click DOES here. */\ntype Glyph = 'crosshair' | 'ibeam' | 'plus';\n\nconst haloed = (x1: number, y1: number, x2: number, y2: number): string =>\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${HALO}\" stroke-width=\"3\"/>` +\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${INK}\" stroke-width=\"1.25\"/>`;\n\nfunction actionGlyph(glyph: Glyph): string {\n const { x, y } = HOTSPOT;\n if (glyph === 'crosshair') {\n return haloed(x, y - 6, x, y + 6) + haloed(x - 6, y, x + 6, y);\n }\n if (glyph === 'ibeam') {\n return (\n haloed(x, y - 6.5, x, y + 6.5) +\n haloed(x - 2.5, y - 6.5, x + 2.5, y - 6.5) +\n haloed(x - 2.5, y + 6.5, x + 2.5, y + 6.5)\n );\n }\n // plus: the DnD copy affordance — green disc, white plus.\n return (\n `<circle cx=\"${x}\" cy=\"${y}\" r=\"7.5\" fill=\"${PLACE_GREEN}\" stroke=\"${HALO}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${x}\" y1=\"${y - 3.5}\" x2=\"${x}\" y2=\"${y + 3.5}\" stroke=\"${HALO}\" stroke-width=\"2\"/>` +\n `<line x1=\"${x - 3.5}\" y1=\"${y}\" x2=\"${x + 3.5}\" y2=\"${y}\" stroke=\"${HALO}\" stroke-width=\"2\"/>`\n );\n}\n\nfunction cursorSvg(glyph: Glyph, icon: string, accent?: IconAccent): string {\n const g = iconGlyph(icon, accent);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${SIZE}\" height=\"${SIZE}\" ` +\n `viewBox=\"0 0 ${SIZE} ${SIZE}\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">` +\n actionGlyph(glyph) +\n (g\n ? `<g transform=\"translate(17 3) scale(${(20 / 24).toFixed(4)})\" stroke-width=\"2\">${g}</g>`\n : '') +\n `</svg>`\n );\n}\n\n/** keyword → glyph: how each affordance is drawn when a tool icon rides\n * along. Draw tools declare 'crosshair', place tools (stamp/signature/image)\n * declare 'copy', and the selection handler claims 'text' over text — which\n * keywords ever SHOW is decided by those declarations and claims, never\n * here. 'default' is deliberately absent: the bare arrow means \"no action\n * here\", so it never carries an icon. */\nconst GLYPHS: Record<string, Glyph> = {\n crosshair: 'crosshair',\n text: 'ibeam',\n copy: 'plus',\n};\n\n/** Mount once (renders nothing): keeps the armed tool's cursor skin in sync\n * with its toolbar icon + live defaults. */\nexport function ArmedToolCursor() {\n const { activeToolId } = useTool();\n // Live accent: a `setDefaults` recolor re-renders us and rebuilds the cursor.\n const d = useAnnotationDefaults(activeToolId);\n const entry = TOOL_ICONS[activeToolId];\n const accent = entry?.accent\n ? {\n primary: d[entry.accent.primary] ?? undefined,\n secondary: entry.accent.secondary ? (d[entry.accent.secondary] ?? undefined) : undefined,\n }\n : undefined;\n useToolCursor(\n entry\n ? {\n toolId: activeToolId,\n cursors: Object.fromEntries(\n Object.entries(GLYPHS).map(([keyword, glyph]) => [\n keyword,\n { svg: cursorSvg(glyph, entry.icon, accent), hotspot: HOTSPOT },\n ]),\n ),\n }\n : null,\n );\n return null;\n}\n","/**\n * The annotation FLAGS section — a live test surface for `/F` (ISO 32000\n * Table 167). Select any annotation(s) and toggle flags; the writes go through\n * the plugin's `updateSelectionFlags` (optimistic, flags-only engine patch),\n * and the reads come from `useSelectionFlags` (per-flag value, `null` when the\n * selection disagrees → indeterminate checkbox).\n *\n * Things to try:\n * - `locked`: the selection keeps its outline but loses handles/knob; move,\n * restyle and delete are refused; unchecking it here still works.\n * - `hidden` / `noView`: the annotation disappears (it stays selected, so\n * this panel can bring it back).\n * - `readOnly`: visible but no longer clickable — deselect and try.\n * - `noZoom` / `noRotate`: zoom or rotate the page; the body keeps its\n * screen size / stays upright, anchored at its top-left corner.\n * - `print`: flip it off and print/flatten elsewhere — the annotation is\n * excluded (viewer rendering is unaffected).\n */\nimport { useAnnotation, useSelectionFlags, type AnnotationFlags } from '@embedpdf/react/annotation';\nimport { useEffect, useRef } from 'react';\n\nconst FLAG_ROWS: { key: keyof AnnotationFlags; label: string; hint: string }[] = [\n { key: 'print', label: 'Print', hint: 'Include when the page is printed' },\n { key: 'hidden', label: 'Hidden', hint: 'Gone everywhere: screen, clicks, print' },\n { key: 'noView', label: 'No view', hint: 'Hidden on screen, may still print' },\n {\n key: 'toggleNoView',\n label: 'Toggle no view',\n hint: 'Reveal a no-view annotation while selected',\n },\n { key: 'readOnly', label: 'Read only', hint: 'Visible but not clickable' },\n { key: 'locked', label: 'Locked', hint: 'No move / resize / delete / restyle' },\n { key: 'lockedContents', label: 'Locked contents', hint: 'Text cannot change; geometry can' },\n { key: 'noZoom', label: 'No zoom', hint: 'Screen-constant size (anchored top-left)' },\n { key: 'noRotate', label: 'No rotate', hint: 'Stays upright when the page rotates' },\n { key: 'invisible', label: 'Invisible', hint: 'Legacy: hide unknown subtypes' },\n];\n\nfunction FlagRow({\n label,\n hint,\n value,\n onToggle,\n}: {\n label: string;\n hint: string;\n value: boolean | null;\n onToggle: (next: boolean) => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n // `null` = the selected annotations disagree → the native indeterminate state.\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = value === null;\n }, [value]);\n return (\n <label className=\"hover:bg-hover flex cursor-pointer items-start gap-2.5 rounded px-1.5 py-1.5\">\n <input\n ref={ref}\n type=\"checkbox\"\n className=\"accent-accent mt-0.5\"\n checked={value === true}\n onChange={() => onToggle(value !== true)}\n />\n <span className=\"min-w-0\">\n <span className=\"text-fg block text-sm leading-tight\">{label}</span>\n <span className=\"text-fg-muted block text-xs leading-tight\">{hint}</span>\n </span>\n </label>\n );\n}\n\n/** The `/F` flags of the current selection, live-editable. Renders nothing\n * when nothing is selected (the style panel shows its tool defaults then). */\nexport function AnnotationFlagsSection() {\n const annotation = useAnnotation();\n const flags = useSelectionFlags();\n if (!flags) return null;\n return (\n <section className=\"border-border mt-2 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n Flags (/F)\n </p>\n <div className=\"flex flex-col\">\n {FLAG_ROWS.map((row) => (\n <FlagRow\n key={row.key}\n label={row.label}\n hint={row.hint}\n value={flags[row.key]}\n onToggle={(next) => annotation.updateSelectionFlags({ [row.key]: next })}\n />\n ))}\n </div>\n </section>\n );\n}\n","/**\n * The annotation style panel — the v2 snippet's style sidebar, rebuilt the v3\n * way. The plugin owns the schema AND the state; this file owns only how each\n * PropSpec renders and the flat patch it writes back. There is NO per-subtype\n * branching here: a new annotation kind that declares its `PropSpec[]` in the\n * kind table gets a working style panel for free.\n *\n * Data flow (mirrors examples/react's AnnotationSidebar):\n * selection present → useSelectionProps() specs/values, write updateSelection()\n * nothing selected → propsForTool(tool) specs + useAnnotationDefaults(tool)\n * values, write setDefaults(tool, …)\n *\n * The look is ported 1:1 from viewers/snippet's annotation-sidebar (six-column\n * swatch grid, range slider, SVG stroke / line-ending dropdowns, font-size\n * combo, align toggles), retinted from v2's `bg-bg-input`/`text-fg-primary`\n * tokens to this app's semantic ones (bg-surface / text-fg / border-border …).\n */\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport {\n useAnnotation,\n useSelectionProps,\n useAnnotationDefaults,\n useAnnotationSelected,\n type PropSpec,\n type AnnotationPropsPatch,\n type Border,\n type BlendMode,\n type LineEnding,\n type LineEndings,\n type TextAlign,\n} from '@embedpdf/react/annotation';\nimport { useTool } from '@embedpdf/react/interaction';\nimport { useKernel, useOptionalCapability } from '@embedpdf/react/runtime';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { LinkToken, type PdfLinkTarget } from '@embedpdf/react/link';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { AnnotationFlagsSection } from './annotation-flags';\n\n// ── app-level vocabulary (a viewer's decision, like v2's color presets) ──────\n// The engine schema says WHICH controls to show; these lists say what the app\n// offers inside a color / font / stroke picker.\nconst PRESET_COLORS = [\n '#000000',\n '#5f6368',\n '#e44234',\n '#ff8b00',\n '#ffd500',\n '#00cc66',\n '#00b8d9',\n '#4a90e2',\n '#9b51e0',\n '#f272c8',\n '#a0522d',\n '#ffffff',\n];\n\nconst FONT_OPTIONS: { v: string; label: string }[] = [\n { v: 'helvetica', label: 'Helvetica' },\n { v: 'helvetica-bold', label: 'Helvetica Bold' },\n { v: 'times-roman', label: 'Times Roman' },\n { v: 'courier', label: 'Courier' },\n];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 24, 36, 48, 72];\n\nconst BORDER_OPTS: { key: string; make: () => Border }[] = [\n { key: 'solid', make: () => ({ kind: 'solid' }) },\n { key: 'dashed-6-2', make: () => ({ kind: 'dashed', dash: [6, 2] }) },\n { key: 'dashed-3-3', make: () => ({ kind: 'dashed', dash: [3, 3] }) },\n { key: 'dashed-1-2', make: () => ({ kind: 'dashed', dash: [1, 2] }) },\n { key: 'cloudy-1', make: () => ({ kind: 'cloudy', intensity: 1 }) },\n { key: 'cloudy-2', make: () => ({ kind: 'cloudy', intensity: 2 }) },\n];\nconst borderKey = (b: Border): string =>\n b.kind === 'cloudy'\n ? `cloudy-${b.intensity >= 2 ? 2 : 1}`\n : b.kind === 'dashed'\n ? `dashed-${b.dash.join('-')}`\n : 'solid';\n\nconst LINE_ENDINGS: { v: LineEnding; label: string }[] = [\n { v: 'none', label: 'None' },\n { v: 'open-arrow', label: 'Open arrow' },\n { v: 'closed-arrow', label: 'Closed arrow' },\n { v: 'r-open-arrow', label: 'Reverse open' },\n { v: 'r-closed-arrow', label: 'Reverse closed' },\n { v: 'circle', label: 'Circle' },\n { v: 'square', label: 'Square' },\n { v: 'diamond', label: 'Diamond' },\n { v: 'butt', label: 'Butt' },\n { v: 'slash', label: 'Slash' },\n];\n\nconst BLEND_MODES: { v: BlendMode; label: string }[] = [\n { v: 'normal', label: 'Normal' },\n { v: 'multiply', label: 'Multiply' },\n { v: 'screen', label: 'Screen' },\n { v: 'overlay', label: 'Overlay' },\n { v: 'darken', label: 'Darken' },\n { v: 'lighten', label: 'Lighten' },\n { v: 'color-dodge', label: 'Color Dodge' },\n { v: 'color-burn', label: 'Color Burn' },\n { v: 'hard-light', label: 'Hard Light' },\n { v: 'soft-light', label: 'Soft Light' },\n { v: 'difference', label: 'Difference' },\n { v: 'exclusion', label: 'Exclusion' },\n { v: 'hue', label: 'Hue' },\n { v: 'saturation', label: 'Saturation' },\n { v: 'color', label: 'Color' },\n { v: 'luminosity', label: 'Luminosity' },\n];\n\n// ── layout primitives ────────────────────────────────────────────────────────\nfunction Field({\n label,\n mixed,\n children,\n}: {\n label: string;\n mixed?: boolean;\n children: ReactNode;\n}) {\n return (\n <section className=\"mb-5\">\n <label className=\"text-fg mb-2 block text-sm font-medium\">\n {label}\n {mixed && <span className=\"text-fg-muted ml-1.5 text-xs font-normal\">(mixed)</span>}\n </label>\n {children}\n </section>\n );\n}\n\n// ── color swatch grid ────────────────────────────────────────────────────────\nconst isTransparent = (c: string | null) =>\n c == null ||\n c === 'transparent' ||\n (/^#([0-9a-f]{8})$/i.test(c) && c.slice(-2).toLowerCase() === '00');\n\nfunction Swatch({\n color,\n active,\n onSelect,\n}: {\n color: string;\n active: boolean;\n onSelect: (c: string) => void;\n}) {\n const style = isTransparent(color)\n ? {\n backgroundColor: '#fff',\n backgroundImage:\n 'linear-gradient(45deg, transparent 40%, #ef4444 40%, #ef4444 60%, transparent 60%)',\n backgroundSize: '100% 100%',\n }\n : { backgroundColor: color };\n return (\n <button\n type=\"button\"\n title={color}\n onClick={() => onSelect(color)}\n className={`border-border-strong h-5 w-5 rounded-full border ${active ? 'outline-accent outline outline-2 outline-offset-2' : ''}`}\n style={style}\n />\n );\n}\n\nfunction SwatchGrid({\n value,\n onSelect,\n allowTransparent,\n}: {\n value: string | null | undefined;\n onSelect: (c: string) => void;\n allowTransparent?: boolean;\n}) {\n const active = (c: string) => c.toLowerCase() === (value ?? '').toLowerCase();\n return (\n <div className=\"grid grid-cols-6 gap-x-1 gap-y-3\">\n {PRESET_COLORS.map((c) => (\n <Swatch key={c} color={c} active={active(c)} onSelect={onSelect} />\n ))}\n {allowTransparent && (\n <Swatch color=\"transparent\" active={isTransparent(value ?? null)} onSelect={onSelect} />\n )}\n </div>\n );\n}\n\n// ── range slider ─────────────────────────────────────────────────────────────\nfunction RangeSlider({\n value,\n min,\n max,\n step,\n onChange,\n}: {\n value: number;\n min: number;\n max: number;\n step: number;\n onChange: (n: number) => void;\n}) {\n return (\n <input\n type=\"range\"\n className=\"accent-accent mb-1.5 h-1 w-full cursor-pointer\"\n value={value}\n min={min}\n max={max}\n step={step}\n onChange={(e) => onChange(parseFloat(e.target.value))}\n />\n );\n}\n\n// ── dropdown shell (open state, outside-click, trigger + panel) ───────────────\nfunction useOutsideClose(open: boolean, close: () => void) {\n const rootRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!open) return;\n const onDoc = (e: MouseEvent) => {\n // composedPath, NOT contains(e.target): at the document level an event\n // from inside the viewer's shadow root retargets to the host element, so\n // contains() reads every inside click as outside and unmounts the panel\n // on mousedown — before the option's click can fire.\n if (rootRef.current && !e.composedPath().includes(rootRef.current)) close();\n };\n document.addEventListener('mousedown', onDoc);\n return () => document.removeEventListener('mousedown', onDoc);\n }, [open, close]);\n return rootRef;\n}\n\nfunction DropdownShell({\n trigger,\n children,\n}: {\n trigger: ReactNode;\n children: (close: () => void) => ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className=\"border-border bg-surface text-fg flex w-full items-center justify-between gap-2 rounded border px-3 py-1.5\"\n >\n {trigger}\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary shrink-0\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-60 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {children(() => setOpen(false))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OptionRow({\n selected,\n onClick,\n children,\n}: {\n selected: boolean;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={`hover:bg-hover flex w-full items-center rounded px-2 py-1.5 text-left text-sm ${selected ? 'bg-selected text-accent' : 'text-fg'}`}\n >\n {children}\n </button>\n );\n}\n\n// ── stroke / border preview + picker ─────────────────────────────────────────\nfunction borderSvg(b: Border): ReactNode {\n if (b.kind === 'cloudy') {\n const r = b.intensity >= 2 ? 5 : 3;\n const n = Math.ceil(80 / (r * 2));\n const step = 80 / n;\n const baseline = r + 1;\n const viewH = r * 2 + 2;\n const parts = [`M 0 ${baseline}`];\n for (let i = 0; i < n; i++) parts.push(`A ${r} ${r} 0 0 1 ${step * (i + 1)} ${baseline}`);\n return (\n <svg width=\"80\" height={viewH} viewBox={`0 0 80 ${viewH}`}>\n <path\n d={parts.join(' ')}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n }\n const dash = b.kind === 'dashed' ? b.dash.join(' ') : undefined;\n return (\n <svg width=\"80\" height=\"8\" viewBox=\"0 0 80 8\">\n <line\n x1=\"0\"\n y1=\"4\"\n x2=\"80\"\n y2=\"4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeDasharray={dash}\n />\n </svg>\n );\n}\n\nfunction BorderSelect({\n value,\n cloudy,\n onChange,\n}: {\n value: Border;\n cloudy: boolean;\n onChange: (b: Border) => void;\n}) {\n const opts = cloudy ? BORDER_OPTS : BORDER_OPTS.filter((o) => !o.key.startsWith('cloudy'));\n return (\n <DropdownShell trigger={<span className=\"text-fg-secondary\">{borderSvg(value)}</span>}>\n {(close) =>\n opts.map((o) => {\n const b = o.make();\n return (\n <OptionRow\n key={o.key}\n selected={borderKey(value) === o.key}\n onClick={() => {\n onChange(b);\n close();\n }}\n >\n <span className=\"text-fg-secondary\">{borderSvg(b)}</span>\n </OptionRow>\n );\n })\n }\n </DropdownShell>\n );\n}\n\n// ── line-ending preview + picker ─────────────────────────────────────────────\nconst LE_MARKERS: Partial<Record<LineEnding, ReactNode>> = {\n square: <path d=\"M68 -4 L76 -4 L76 4 L68 4 Z\" />,\n circle: <circle cx=\"72\" cy=\"0\" r=\"4\" />,\n diamond: <path d=\"M72 -5 L77 0 L72 5 L67 0 Z\" />,\n 'open-arrow': <path d=\"M67 -5 L77 0 L67 5\" fill=\"none\" />,\n 'closed-arrow': <path d=\"M67 -5 L77 0 L67 5 Z\" />,\n 'r-open-arrow': <path d=\"M77 -5 L67 0 L77 5\" fill=\"none\" />,\n 'r-closed-arrow': <path d=\"M77 -5 L67 0 L77 5 Z\" />,\n butt: <path d=\"M72 -5 L72 5\" fill=\"none\" />,\n slash: <path d=\"M67 -5 L77 5\" fill=\"none\" />,\n};\nconst LE_LINE_END: Partial<Record<LineEnding, number>> = {\n square: 68,\n circle: 68,\n diamond: 67,\n 'open-arrow': 76,\n 'closed-arrow': 67,\n 'r-open-arrow': 67,\n 'r-closed-arrow': 67,\n butt: 72,\n slash: 72,\n};\n\nfunction LineEndingPreview({ name, side }: { name: LineEnding; side: 'start' | 'end' }) {\n const marker = LE_MARKERS[name];\n const lineEndX = LE_LINE_END[name] ?? 77;\n const transform = side === 'start' ? 'rotate(180 40 10)' : undefined;\n return (\n <svg width=\"80\" height=\"20\" viewBox=\"0 0 80 20\" className=\"text-fg\">\n <g transform={transform}>\n <line x1=\"4\" y1=\"10\" x2={lineEndX} y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n {marker && (\n <g\n transform=\"translate(0, 10)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n {marker}\n </g>\n )}\n </g>\n </svg>\n );\n}\n\nfunction LineEndingSelect({\n side,\n value,\n onChange,\n}: {\n side: 'start' | 'end';\n value: LineEnding;\n onChange: (v: LineEnding) => void;\n}) {\n return (\n <DropdownShell trigger={<LineEndingPreview name={value} side={side} />}>\n {(close) =>\n LINE_ENDINGS.map((o) => (\n <OptionRow\n key={o.v}\n selected={value === o.v}\n onClick={() => {\n onChange(o.v);\n close();\n }}\n >\n <LineEndingPreview name={o.v} side={side} />\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font family picker ───────────────────────────────────────────────────────\nfunction FontFamilySelect({ value, onChange }: { value: string; onChange: (v: string) => void }) {\n const current = FONT_OPTIONS.find((o) => o.v === value);\n return (\n <DropdownShell trigger={<span className=\"text-fg text-sm\">{current?.label ?? value}</span>}>\n {(close) =>\n FONT_OPTIONS.map((o) => (\n <OptionRow\n key={o.v}\n selected={o.v === value}\n onClick={() => {\n onChange(o.v);\n close();\n }}\n >\n {o.label}\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font-size combo (number input + preset dropdown) ─────────────────────────\nfunction FontSizeCombo({ value, onChange }: { value: number; onChange: (n: number) => void }) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <input\n type=\"number\"\n min={1}\n value={value}\n onChange={(e) => {\n const n = parseInt(e.target.value, 10);\n if (Number.isFinite(n) && n > 0) onChange(n);\n }}\n onClick={() => setOpen(true)}\n className=\"border-border bg-surface text-fg w-full rounded border px-2 py-1.5 pr-7 text-sm\"\n />\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={() => setOpen((o) => !o)}\n className=\"absolute inset-y-0 right-1 flex items-center\"\n >\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-48 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {FONT_SIZES.map((sz) => (\n <OptionRow\n key={sz}\n selected={sz === value}\n onClick={() => {\n onChange(sz);\n setOpen(false);\n }}\n >\n {sz}\n </OptionRow>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction BlendModeSelect({\n value,\n onChange,\n}: {\n value: BlendMode;\n onChange: (mode: BlendMode) => void;\n}) {\n return (\n <select\n value={value}\n onChange={(event) => onChange(event.target.value as BlendMode)}\n className=\"border-border bg-surface text-fg w-full rounded border px-3 py-1.5 text-sm\"\n >\n {BLEND_MODES.map((mode) => (\n <option key={mode.v} value={mode.v}>\n {mode.label}\n </option>\n ))}\n </select>\n );\n}\n\n// ── align toggle ─────────────────────────────────────────────────────────────\nfunction Toggle({\n active,\n title,\n onClick,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n className={`flex h-9 w-9 items-center justify-center rounded border transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\n/**\n * The link-target editor — v2's \"Link / Go to link / Remove link\" menu items,\n * rebuilt on the schema: any kind whose table declares the `link` spec gets\n * this control, and every write is the ONE `updateSelection({ link })` path\n * (the plugin materializes/retargets/deletes the attached children).\n */\nfunction LinkTargetControl({\n label,\n value,\n mixed,\n onChange,\n}: {\n label: string;\n value: PdfLinkTarget | null;\n mixed: boolean;\n onChange: (patch: AnnotationPropsPatch) => void;\n}) {\n const kernel = useKernel();\n const link = useOptionalCapability(LinkToken);\n const [mode, setMode] = useState<'uri' | 'page'>(value?.kind === 'goto' ? 'page' : 'uri');\n const [uri, setUri] = useState(value?.kind === 'uri' ? value.uri : '');\n const [pageNo, setPageNo] = useState('1');\n\n // Adopt the selection's current target whenever it changes under us.\n useEffect(() => {\n setMode(value?.kind === 'goto' ? 'page' : 'uri');\n if (value?.kind === 'uri') setUri(value.uri);\n }, [value]);\n\n const apply = () => {\n if (mode === 'uri') {\n const trimmed = uri.trim();\n if (trimmed) onChange({ link: { kind: 'uri', uri: trimmed } });\n return;\n }\n // Page number (1-based) → the page's OBJECT NUMBER (stable across moves).\n const activeId = kernel.documents.activeId();\n const meta = activeId ? kernel.getState().core.documents[activeId] : null;\n const layout = meta?.pages[Math.max(0, Number(pageNo) - 1)];\n if (layout) {\n onChange({\n link: {\n kind: 'goto',\n destination: { kind: 'fit', pageObjectNumber: layout.pageObjectNumber },\n },\n });\n }\n };\n\n const inputCls = 'border-border bg-surface text-fg w-full rounded border px-3 py-1.5 text-sm';\n return (\n <Field label={label} mixed={mixed}>\n {value != null && (\n <div className=\"mb-2 flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"border-border bg-surface text-fg flex-1 rounded border px-2 py-1.5 text-sm\"\n onClick={() => link?.activate(value)}\n >\n Go to link\n </button>\n <button\n type=\"button\"\n className=\"border-border bg-surface text-fg flex-1 rounded border px-2 py-1.5 text-sm\"\n onClick={() => onChange({ link: null })}\n >\n Remove link\n </button>\n </div>\n )}\n <div className=\"mb-2 flex gap-2\">\n <Toggle title=\"Link to a URL\" active={mode === 'uri'} onClick={() => setMode('uri')}>\n URL\n </Toggle>\n <Toggle title=\"Link to a page\" active={mode === 'page'} onClick={() => setMode('page')}>\n Page\n </Toggle>\n </div>\n {mode === 'uri' ? (\n <input\n type=\"url\"\n className={inputCls}\n placeholder=\"https://…\"\n value={uri}\n onChange={(e) => setUri(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && apply()}\n />\n ) : (\n <input\n type=\"number\"\n min={1}\n className={inputCls}\n placeholder=\"Page number\"\n value={pageNo}\n onChange={(e) => setPageNo(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && apply()}\n />\n )}\n <button\n type=\"button\"\n className=\"border-border bg-surface text-fg mt-2 w-full rounded border px-2 py-1.5 text-sm font-medium\"\n onClick={apply}\n >\n {value == null ? 'Add link' : 'Update link'}\n </button>\n </Field>\n );\n}\n\n// ── one control per PropSpec — the entire surface an app customizes ──────────\nfunction PropControl({\n spec,\n value,\n mixed,\n onChange,\n}: {\n spec: PropSpec;\n value: unknown;\n mixed: boolean;\n onChange: (patch: AnnotationPropsPatch) => void;\n}) {\n switch (spec.key) {\n case 'color':\n case 'fontColor':\n return (\n <Field label={spec.label} mixed={mixed}>\n <SwatchGrid\n value={value as string}\n onSelect={(c) => onChange({ [spec.key]: c } as AnnotationPropsPatch)}\n />\n </Field>\n );\n case 'interiorColor':\n return (\n <Field label={spec.label} mixed={mixed}>\n <SwatchGrid\n value={value as string | null}\n allowTransparent\n onSelect={(c) => onChange({ interiorColor: c === 'transparent' ? null : c })}\n />\n </Field>\n );\n case 'opacity': {\n const v = (value as number) ?? 1;\n return (\n <Field label={spec.label} mixed={mixed}>\n <RangeSlider\n value={v}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(n) => onChange({ opacity: n })}\n />\n <span className=\"text-fg-muted text-xs\">{Math.round(v * 100)}%</span>\n </Field>\n );\n }\n case 'strokeWidth': {\n const v = (value as number) ?? spec.min;\n return (\n <Field label={spec.label} mixed={mixed}>\n <RangeSlider\n value={v}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(n) => onChange({ strokeWidth: n })}\n />\n <span className=\"text-fg-muted text-xs\">{v}px</span>\n </Field>\n );\n }\n case 'fontSize':\n return (\n <Field label={spec.label} mixed={mixed}>\n <FontSizeCombo\n value={(value as number) ?? 12}\n onChange={(n) => onChange({ fontSize: n })}\n />\n </Field>\n );\n case 'border':\n return (\n <Field label={spec.label} mixed={mixed}>\n <BorderSelect\n value={(value as Border) ?? { kind: 'solid' }}\n cloudy={spec.cloudy}\n onChange={(b) => onChange({ border: b })}\n />\n </Field>\n );\n case 'lineEndings': {\n const le = (value as LineEndings) ?? { start: 'none', end: 'none' };\n return (\n <Field label={spec.label} mixed={mixed}>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">Start</div>\n <LineEndingSelect\n side=\"start\"\n value={le.start}\n onChange={(v) => onChange({ lineEndings: { start: v } })}\n />\n </div>\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">End</div>\n <LineEndingSelect\n side=\"end\"\n value={le.end}\n onChange={(v) => onChange({ lineEndings: { end: v } })}\n />\n </div>\n </div>\n </Field>\n );\n }\n case 'fontFamily':\n return (\n <Field label={spec.label} mixed={mixed}>\n <FontFamilySelect\n value={(value as string) ?? 'helvetica'}\n onChange={(v) => onChange({ fontFamily: v })}\n />\n </Field>\n );\n case 'textAlign': {\n const alignIcon: Record<TextAlign, string> = {\n left: 'alignLeft',\n center: 'alignCenter',\n right: 'alignRight',\n };\n return (\n <Field label={spec.label} mixed={mixed}>\n <div className=\"flex gap-2\">\n {(['left', 'center', 'right'] as TextAlign[]).map((al) => (\n <Toggle\n key={al}\n title={`Align ${al}`}\n active={value === al}\n onClick={() => onChange({ textAlign: al })}\n >\n <Icon name={alignIcon[al]} size={18} />\n </Toggle>\n ))}\n </div>\n </Field>\n );\n }\n case 'blendMode':\n return (\n <Field label={spec.label} mixed={mixed}>\n <BlendModeSelect\n value={(value as BlendMode) ?? 'normal'}\n onChange={(blendMode) => onChange({ blendMode })}\n />\n </Field>\n );\n case 'link':\n return (\n <LinkTargetControl\n label={spec.label}\n value={(value as PdfLinkTarget | null) ?? null}\n mixed={mixed}\n onChange={onChange}\n />\n );\n default:\n return null;\n }\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nfunction EmptyState() {\n return (\n <div className=\"text-fg-muted flex flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n <Icon name=\"palette\" size={40} className=\"text-fg-disabled\" />\n <p className=\"max-w-[180px] text-sm\">\n Pick a draw tool or select an annotation to edit its style.\n </p>\n </div>\n );\n}\n\n/**\n * The schema-driven style panel. Rendered inside the right sidebar's\n * `annotation-style` surface (see ui/panels.tsx). Owns its own scroll.\n */\nexport function AnnotationStylePanel() {\n const annotation = useAnnotation();\n const { activeToolId } = useTool();\n const sel = useSelectionProps();\n const defaults = useAnnotationDefaults(activeToolId);\n const selected = useAnnotationSelected();\n\n const hasSel = sel.specs.length > 0;\n const specs = hasSel ? sel.specs : annotation.propsForTool(activeToolId);\n const values = hasSel ? sel.values : defaults;\n const write = (patch: AnnotationPropsPatch) =>\n hasSel ? annotation.updateSelection(patch) : annotation.setDefaults(activeToolId, patch);\n\n // A selection with no editable props (e.g. a stamp, or a LOCKED annotation —\n // its style is frozen) still shows its flags: that's how you unlock it.\n if (specs.length === 0 && selected.length === 0) return <EmptyState />;\n\n const context = hasSel ? `${selected.length} selected` : `${activeToolId} defaults`;\n\n return (\n <div className=\"flex-1 overflow-y-auto p-4\">\n <p className=\"text-fg-muted mb-4 text-[11px] font-semibold uppercase tracking-wide\">\n {context}\n </p>\n {specs.map((spec) => (\n <PropControl\n key={spec.key}\n spec={spec}\n value={values[spec.key]}\n mixed={hasSel && sel.mixed.includes(spec.key)}\n onChange={write}\n />\n ))}\n {/* Redaction label (`/OverlayText` + `/Repeat`) — kind content, not a\n style prop, so it writes through the redaction plugin's setLabel. */}\n <RedactionLabelSection />\n {/* `/F` flags for whatever is selected — the live flags test surface. */}\n <AnnotationFlagsSection />\n </div>\n );\n}\n\n/**\n * Label editor shown when exactly one redaction mark is selected. The text is\n * what the destructive apply paints over the region (white-on-black by the\n * tool defaults); `repeat` tiles it. Writes ride the annotation update verb\n * via the redaction plugin, which preserves the label's `/DA` styling.\n */\nfunction RedactionLabelSection() {\n const t = useT();\n const redaction = useOptionalCapability(RedactionToken);\n const selected = useAnnotationSelected();\n const mark = selected.length === 1 && selected[0]!.subtype === 'redact' ? selected[0]! : null;\n const [draft, setDraft] = useState<string | null>(null);\n useEffect(() => setDraft(null), [mark?.ref && refKeyOfRedact(mark.ref)]);\n if (!redaction || !mark || mark.subtype !== 'redact') return null;\n\n const value = draft ?? mark.overlayText ?? '';\n const commit = () => {\n if (draft === null) return;\n void redaction.setLabel(mark.ref, { overlayText: draft.length > 0 ? draft : null });\n setDraft(null);\n };\n\n return (\n <div className=\"border-border-subtle mt-4 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('demo.redactLabelTitle')}\n </p>\n <input\n type=\"text\"\n value={value}\n placeholder={t('demo.redactLabelPlaceholder')}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commit}\n onKeyDown={(e) => e.key === 'Enter' && commit()}\n className=\"border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm\"\n />\n <label className=\"text-fg mt-2 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={mark.repeat}\n onChange={(e) => void redaction.setLabel(mark.ref, { repeat: e.target.checked })}\n />\n {t('demo.redactLabelRepeat')}\n </label>\n </div>\n );\n}\n\n/** Stable key for the effect dep — mirrors the annotation model's ref keys. */\nfunction refKeyOfRedact(ref: { kind: string } & Record<string, unknown>): string {\n return JSON.stringify(ref);\n}\n","import { useEffect } from 'react';\nimport { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a LIVE view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n // The annotation plane loads lazily per page; pull every page in so the\n // panel shows marks on pages never scrolled to.\n useEffect(() => {\n void redaction.preparePending();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={item.id}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.select(item.ref)}\n onKeyDown={(e) => e.key === 'Enter' && anno.select(item.ref)}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || redaction.applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The search panel — the v2 snippet's search sidebar on the v3 plugin-search\n * capability. ONE shape end to end: the flat `SearchQuery` {text, regex,\n * matchCase, wholeWord} is what the engine matches, what the plugin stores\n * (document-scoped, survives the sidebar closing), and what this box renders.\n * The panel keeps only a DRAFT of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeIndex (reactive)\n * useSelector(SearchToken, c => c.hits()) → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look is ported 1:1 from viewers/snippet's search-sidebar (magnifier\n * input with clear button, option checkboxes, results-found counter with\n * prev/next, per-page grouped snippet list with the match bolded and the\n * active hit accented), retinted to this app's semantic tokens. The regex\n * toggle is new in v3 (v2 had no pattern search); matchDiacritics exists in\n * the engine but is deliberately not exposed here — v2 parity.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchState,\n validateSearchQuery,\n SearchToken,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useSelector } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (a: SearchQuery | null, b: SearchQuery) =>\n a != null &&\n a.text === b.text &&\n !!a.regex === !!b.regex &&\n !!a.matchCase === !!b.matchCase &&\n !!a.wholeWord === !!b.wholeWord;\n\n// ── option checkbox (v2's peer-checked custom box) ───────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (v: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent peer h-4 w-4 shrink-0 appearance-none rounded-[3px] border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(s: SearchSnippet | undefined) {\n if (!s) return null;\n const end = s.matchStart + s.matchLength;\n return (\n <>\n {s.text.slice(0, s.matchStart)}\n <span className=\"text-accent font-semibold\">{s.text.slice(s.matchStart, end)}</span>\n {s.text.slice(end)}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeIndex } = useSearchState();\n const hits = useSelector(SearchToken, (c) => c.hits());\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that STARTS from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // The draft IS a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((a, b) => a[0] - b[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(e) => setDraft(e.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pl-8 pr-9 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 right-0 flex items-center pr-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title=\"Previous\"\n className={buttonClass(false)}\n onClick={() => search.prev()}\n >\n <Icon name=\"chevronLeft\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Next\"\n className={buttonClass(false)}\n onClick={() => search.next()}\n >\n <Icon name=\"chevronRight\" size={20} />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeIndex}\n onClick={() => search.goTo(index)}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","/**\n * The static chrome around the toolbars: the left/right sidebars (shell\n * surfaces) and the bottom page-controls overlay. Deliberately minimal —\n * chrome-parity scope. Panels read their open state from plugin-shell; the\n * app owns their DOM.\n *\n * There is no built-in header: branding, a locale picker and a theme switch\n * are the EMBEDDER's chrome, not the viewer's. The frame keeps a `header`\n * socket for a slotted one (see Shell).\n */\nimport { useEffect } from 'react';\nimport { useSelector, useDocumentId } from '@embedpdf/react/runtime';\nimport { Stage, StageToken, usePages } from '@embedpdf/react/stage';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { ThumbsStageToken } from '../config/stage';\nimport { Icon } from './icons';\nimport { AnnotationStylePanel } from './annotation-style';\nimport { RedactionPanel } from './redaction-panel';\nimport { SearchPanel } from './search-panel';\n\n// ── left sidebar (thumbnails / outline tabs) ─────────────────────────────────\nexport function LeftSidebar() {\n const t = useT();\n const sidebar = useSurface('sidebar');\n if (!sidebar.isOpen) return null;\n return (\n <aside className=\"border-border-subtle bg-surface flex w-60 shrink-0 flex-col border-r\">\n <div className=\"border-border-subtle flex items-center gap-1 border-b p-2\">\n <span className=\"bg-accent-light text-accent rounded-md px-2 py-1 text-xs font-medium\">\n {t('demo.thumbnails')}\n </span>\n <span className=\"text-fg-muted rounded-md px-2 py-1 text-xs font-medium\">\n {t('demo.outline')}\n </span>\n <div className=\"flex-1\" />\n <button\n type=\"button\"\n onClick={sidebar.close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n <ThumbnailList />\n </aside>\n );\n}\n\n// The thumbnail rail: the SAME document through the thumbnail Stage lens (a\n// single-column, fixed-zoom grid — see App's `stage-thumbs` plugin). Click a\n// thumb to navigate the MAIN lens; the rail follows the main view. Read-only —\n// no page edits (rotate/move/delete), just the page bitmap and its number.\nfunction ThumbnailList() {\n const { currentPage, goToPage } = usePages(); // the MAIN lens\n const { reveal } = usePages(ThumbsStageToken); // the SIDEBAR lens\n // Follow the main view: when its current page changes, make that thumb visible —\n // minimal movement, zero when it's already on screen.\n useEffect(() => reveal(currentPage), [currentPage, reveal]);\n return (\n <Stage\n token={ThumbsStageToken}\n zoomGestures={false} // fixed-magnification rail: cmd+wheel/pinch scrolls, never zooms\n className=\"flex-1\"\n style={{ position: 'relative' }}\n pageChrome={(page) => (\n <>\n {/* BOX-SPACE chrome: the click target + selection border hug the page\n box; the number sits in the reserved bottom band. Neither rotates. */}\n <button\n type=\"button\"\n onClick={() => goToPage(page.pageIndex)}\n title={`Page ${page.pageIndex + 1}`}\n style={{\n position: 'absolute',\n top: page.frame.top,\n left: page.frame.left,\n right: page.frame.right,\n bottom: page.frame.bottom,\n cursor: 'pointer',\n boxSizing: 'border-box',\n borderRadius: 4,\n border:\n page.pageIndex === currentPage\n ? '2px solid var(--ep-accent)'\n : '1px solid var(--ep-border-subtle)',\n boxShadow:\n page.pageIndex === currentPage ? '0 0 0 2px var(--ep-accent-light)' : 'none',\n }}\n />\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: page.frame.bottom,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 11,\n color: 'var(--ep-fg-muted)',\n pointerEvents: 'none',\n }}\n >\n {page.pageIndex + 1}\n </div>\n </>\n )}\n >\n {/* page-space content: the bitmap, which rotates with the page */}\n {() => <RenderLayer />}\n </Stage>\n );\n}\n\n// ── right sidebar (search / comment / style) ─────────────────────────────────\nexport function RightSidebar() {\n const t = useT();\n // Keys the SearchPanel below: the panel seeds its query box from the active\n // document's search state on mount, so it must remount when the active\n // document changes (switching tabs with the sidebar open) to re-seed.\n const documentId = useDocumentId();\n const search = useSurface('search');\n const comment = useSurface('comment');\n const style = useSurface('annotation-style');\n const redaction = useSurface('redaction');\n const active = search.isOpen\n ? 'search'\n : comment.isOpen\n ? 'comment'\n : style.isOpen\n ? 'style'\n : redaction.isOpen\n ? 'redaction'\n : null;\n if (!active) return null;\n\n const titleKey =\n active === 'search'\n ? 'demo.searchTitle'\n : active === 'comment'\n ? 'demo.commentsTitle'\n : active === 'redaction'\n ? 'demo.redactionTitle'\n : 'demo.styleTitle';\n const close =\n active === 'search'\n ? search.close\n : active === 'comment'\n ? comment.close\n : active === 'redaction'\n ? redaction.close\n : style.close;\n\n return (\n <aside className=\"border-border-subtle bg-surface flex w-72 shrink-0 flex-col border-l\">\n <div className=\"border-border-subtle flex items-center justify-between border-b p-3\">\n <span className=\"text-fg text-sm font-semibold\">{t(titleKey)}</span>\n <button\n type=\"button\"\n onClick={close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n {active === 'style' ? (\n <AnnotationStylePanel />\n ) : active === 'search' ? (\n <SearchPanel key={documentId ?? 'none'} />\n ) : active === 'redaction' ? (\n <RedactionPanel />\n ) : (\n <div className=\"p-3\">\n <p className=\"text-fg-muted text-sm\">{t('demo.empty')}</p>\n </div>\n )}\n </aside>\n );\n}\n\n// ── bottom page-controls overlay ─────────────────────────────────────────────\nexport function PageControls() {\n const t = useT();\n // the Stage cursor is a 0-based display index; people count from 1\n const current = useSelector(StageToken, (c) => c.currentPage() + 1);\n const total = useSelector(StageToken, (c) => c.pageCount());\n if (!total) return null;\n return (\n <div className=\"pointer-events-none absolute inset-x-0 bottom-5 flex justify-center\">\n <div className=\"border-border-subtle bg-elevated/95 text-fg-secondary pointer-events-auto rounded-full border px-4 py-1.5 text-sm shadow-lg backdrop-blur\">\n {t('demo.page', { params: { current, total } })}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * CLIENT-SIDE collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n if (!surface.isOpen) return null;\n\n const count = redaction.pendingCount();\n const collateral = redaction.estimateCollateral();\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/40\">\n <div className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\">\n <h2 className=\"text-fg text-base font-semibold\">{t('demo.redactConfirmTitle')}</h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Boot-state panes for the document area — what renders INSTEAD of the Stage\n * while the selected tab's document isn't ready:\n *\n * `locked` → <PasswordPrompt/> (per-tab, v2's document-password-prompt port)\n * `error` → <DocumentError/>\n *\n * Both are per-TAB, not modal: several tabs can be locked/broken at once and\n * switching tabs stays free. The prompt drives ONE call —\n * `documents.unlock(id, { password })` — identical on the local (worker loads\n * the parked bytes) and cloud (/access grant) engines. The \"incorrect\" copy\n * keys on a real rejection: either this session's failed attempt, or\n * `passwordProvided` (a config-supplied password the engine already rejected).\n */\nimport { useState } from 'react';\nimport { useDocumentId, useDocuments } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\nexport function PasswordPrompt() {\n const docId = useDocumentId();\n const { docs, unlock, close } = useDocuments();\n const t = useT();\n const [password, setPassword] = useState('');\n const [rejected, setRejected] = useState(false);\n const [busy, setBusy] = useState(false);\n\n const doc = docs.find((d) => d.id === docId);\n if (!docId || !doc) return null;\n const incorrect = rejected || doc.passwordProvided === true;\n\n const submit = async () => {\n if (busy || !password.trim()) return;\n setBusy(true);\n try {\n await unlock(docId, { password });\n // success → the tab promotes to ready and this pane unmounts\n } catch {\n setRejected(true);\n setPassword('');\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border w-full max-w-sm rounded-xl border p-6 shadow-lg\">\n <div className=\"flex flex-col items-center text-center\">\n <div className=\"bg-accent-light mb-4 rounded-full p-4\">\n <Icon name=\"lock\" size={28} className=\"text-accent\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('passwordPrompt.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n </div>\n\n <p className=\"text-fg-secondary mt-4 text-center text-sm\">\n {incorrect ? t('passwordPrompt.incorrect') : t('passwordPrompt.required')}\n </p>\n\n <div className=\"mt-5\">\n <label className=\"text-fg mb-1.5 block text-sm font-medium\" htmlFor=\"doc-password\">\n {t('passwordPrompt.label')}\n </label>\n <input\n id=\"doc-password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && void submit()}\n disabled={busy}\n placeholder={t('passwordPrompt.placeholder')}\n className=\"bg-surface border-border focus:border-accent focus:ring-accent text-fg placeholder:text-fg-muted block w-full rounded-md border px-3 py-2.5 text-sm focus:outline-none focus:ring-1 disabled:opacity-50\"\n autoFocus\n />\n </div>\n\n {incorrect && (\n <div className=\"mt-3 flex items-center gap-2 rounded-md border border-red-500/40 bg-red-500/10 p-3\">\n <Icon name=\"alertTriangle\" size={16} className=\"flex-shrink-0 text-red-500\" />\n <p className=\"text-sm text-red-500\">{t('passwordPrompt.incorrectWarning')}</p>\n </div>\n )}\n\n <div className=\"mt-6 flex gap-3\">\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n disabled={busy}\n className=\"border-border text-fg-secondary hover:bg-hover flex-1 cursor-pointer rounded-md border px-4 py-2.5 text-sm font-medium transition-colors disabled:opacity-50\"\n >\n {t('passwordPrompt.cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => void submit()}\n disabled={busy || !password.trim()}\n className=\"bg-accent text-on-accent flex-1 cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {busy ? t('passwordPrompt.opening') : t('passwordPrompt.open')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport function DocumentError() {\n const docId = useDocumentId();\n const { docs, close } = useDocuments();\n const t = useT();\n const doc = docs.find((d) => d.id === docId);\n if (!docId || !doc) return null;\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border flex max-w-sm flex-col items-center rounded-xl border p-6 text-center shadow-lg\">\n <div className=\"mb-4 rounded-full bg-red-500/10 p-4\">\n <Icon name=\"alertTriangle\" size={28} className=\"text-red-500\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('documentError.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n <p className=\"text-fg-secondary mt-2 text-sm\">{t('documentError.unknown')}</p>\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n className=\"bg-accent text-on-accent mt-5 w-full cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90\"\n >\n {t('documentError.close')}\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The viewer shell — the snippet's layout, driven entirely by the v3 commands\n * + measured-toolbar system.\n *\n * ── header socket (empty unless a child fills it) ─────────\n * ── main toolbar (measured; auto-overflows) ───────────────\n * ── mode band (DERIVED from the shell's open mode surface) ─\n * left sidebar │ Stage (pages) │ right sidebar\n * ──────────── page-controls overlay ──────────────────────\n *\n * The workspace/document split is structural: header + toolbars are\n * workspace-scoped and render at t≈0 (translated, measured) while the wasm\n * engine still boots; everything document-scoped sits inside <DocumentGate>,\n * whose fallback is the empty-workspace state (v2's loader, but UNDER a live\n * toolbar instead of replacing the whole app).\n *\n * Which mode band shows is not stored anywhere: it's a projection of\n * plugin-shell's exclusive 'mode' surface, read null-safely so the band simply\n * doesn't exist without a document.\n */\nimport { useMemo, type ReactNode } from 'react';\nimport {\n DocumentGate,\n useDocumentId,\n useDocumentStatus,\n useOptionalSelector,\n} from '@embedpdf/react/runtime';\nimport { Stage } from '@embedpdf/react/stage';\nimport { Scrollbar } from '@embedpdf/react/scrollbar';\nimport { RenderLayer, TileLayer } from '@embedpdf/react/render';\nimport { SelectionLayer } from '@embedpdf/react/selection';\nimport { AnnotationLayer, useFilePickerProvider } from '@embedpdf/react/annotation';\nimport { LinkLayer } from '@embedpdf/react/link';\nimport type { AnnotationRenderer } from '@embedpdf/react/annotation';\nimport { formWidgetRenderer, useFormScriptingProvider } from '@embedpdf/react/form';\nimport { SearchLayer } from '@embedpdf/react/search';\nimport { useCommandShortcuts } from '@embedpdf/react/commands';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { getModeBar } from './config/chrome';\nimport { useChromeSchema } from './config-context';\nimport { AppToolbar } from './ui/toolbar';\nimport { AnnotationStrip } from './ui/annotation-strip';\nimport { TabBar } from './ui/tab-bar';\nimport { ArmedToolCursor } from './ui/tool-cursor';\nimport { LeftSidebar, RightSidebar, PageControls } from './ui/panels';\nimport { RedactConfirmModal } from './ui/redact-confirm';\nimport { DocumentError, PasswordPrompt } from './ui/document-boot';\n\n// Annotation renderers — module scope, per the AnnotationRenderer identity\n// rule. One entry today: form widgets render as fill controls while the form\n// plugin's Behavior is engaged.\nconst ANNOTATION_RENDERERS: AnnotationRenderer[] = [formWidgetRenderer];\n\nfunction ModeBand({ edge }: { edge: 'top' | 'bottom' }) {\n const schema = useChromeSchema();\n // The mode list is DERIVED from the chrome's modeBars keys — adding a custom\n // mode is one command + one bar schema in config, not a shell change.\n const modeSurfaces = useMemo(() => Object.keys(schema.modeBars ?? {}), [schema]);\n const activeMode = useOptionalSelector(\n ShellToken,\n (s) => modeSurfaces.find((m) => s.isOpen(m)) ?? null,\n null,\n );\n if (!activeMode) return null;\n const bar = getModeBar(schema, activeMode);\n if (!bar) return null;\n return (\n <div\n className={`border-border bg-surface-alt flex shrink-0 items-center px-4 py-2 ${\n edge === 'top' ? 'border-b' : 'border-t'\n }`}\n >\n <AppToolbar bar={bar} className=\"w-full\" />\n </div>\n );\n}\n\n/** The empty-workspace state: shown while the initial documents (and the\n * engine behind them) are still loading — or if the user closes every tab. */\nfunction OpeningDocuments() {\n const t = useT();\n return (\n <div className=\"grid h-full w-full place-items-center\">\n <div className=\"text-fg-muted flex flex-col items-center gap-3\">\n <div className=\"border-border-subtle border-t-accent h-8 w-8 animate-spin rounded-full border-2\" />\n <div className=\"text-sm\">{t('demo.opening')}</div>\n </div>\n </div>\n );\n}\n\n/**\n * The document area's lifecycle switch. A `locked` tab shows its password\n * prompt, an `error` tab its error pane — per TAB (keyed by document), so\n * several can coexist and tab switching stays free. Everything else is the\n * ready-gated Stage; the gate's fallback covers `loading`.\n */\nfunction DocumentArea({ children }: { children: ReactNode }) {\n const docId = useDocumentId();\n const status = useDocumentStatus();\n if (status === 'locked') return <PasswordPrompt key={docId} />;\n if (status === 'error') return <DocumentError key={docId} />;\n return <DocumentGate fallback={<OpeningDocuments />}>{children}</DocumentGate>;\n}\n\nexport function Shell() {\n useCommandShortcuts();\n // Click-then-pick tools (stamp, file attachment) → click a page → file dialog\n // opens → the file lands where you clicked. One line: the default provider is\n // the built-in file picker honouring each tool's `accept` filter (swap it for\n // a custom picker, or pass null to disable). The plugin stays DOM-free.\n useFilePickerProvider();\n // Form scripts stay inside the isolated form pipeline; this hook fulfils the\n // resulting alert, page-navigation, and print UI requests in the React shell.\n useFormScriptingProvider();\n const schema = useChromeSchema();\n\n // The FRAME: region arrangement & visibility from the chrome value (see\n // FrameSchema). Regions render as named <slot> sockets with the built-ins\n // as fallback — light-DOM children of <embedpdf-viewer> replace them; in\n // plain light DOM a slot just displays its fallback (UA display:contents),\n // so this package's direct React consumers see no difference. A region\n // hidden by the frame hides its socket too: visibility outranks content.\n const frame = schema.frame ?? {};\n const toolbarEdge = frame.toolbar ?? 'top';\n\n // main toolbar — measured; degrades + overflows with zero config.\n // Deliberately OUTSIDE the gate: chrome renders before any document.\n // Bar id 'main' is the shell's one structural expectation — an owned\n // chrome without it simply has no main toolbar. Its mode band rides the\n // CONTENT side, whichever edge the frame picked.\n const toolbarBand = schema.bars.main && (\n <div\n part=\"toolbar\"\n className={`border-border bg-surface flex shrink-0 items-center px-4 py-2 ${\n toolbarEdge === 'top' ? 'border-b' : 'border-t'\n }`}\n >\n <AppToolbar bar={schema.bars.main} className=\"w-full\" />\n </div>\n );\n\n return (\n <div className=\"bg-app text-fg flex h-full flex-col\">\n {/* The header socket. The chrome ships NO header of its own — branding,\n locale pickers and theme switches are the embedder's chrome, not the\n viewer's — so this renders nothing until a child fills the slot. */}\n {(frame.header ?? true) && <slot name=\"header\" />}\n\n {/* the v2 document tab bar — the kernel's document registry IS the tab model */}\n {(frame.tabs ?? 'always') !== 'never' && (\n <slot name=\"tabs\">\n <TabBar visibility={frame.tabs ?? 'always'} />\n </slot>\n )}\n\n {toolbarEdge === 'top' && (\n <>\n {toolbarBand}\n <ModeBand edge=\"top\" />\n </>\n )}\n\n <div className=\"relative flex min-h-0 flex-1\">\n <DocumentArea>\n <LeftSidebar />\n <div className=\"relative min-w-0 flex-1\">\n {/* the armed tool's cursor: its toolbar icon as a real CSS cursor\n (zero-lag; the hub hides it over annotations/fields/gaps) */}\n <ArmedToolCursor />\n <Stage\n interaction\n overlay={\n <>\n <AnnotationStrip />\n {/* headless scrollbars: geometry/behavior from the stage's\n scroller contract; the look is index.css (data-attrs) */}\n <Scrollbar axis=\"y\" />\n <Scrollbar axis=\"x\" />\n </>\n }\n className=\"h-full w-full\"\n style={{ background: 'var(--ep-canvas)' }}\n >\n {() => (\n <>\n <RenderLayer annotations={false} />\n {/* Deep-zoom tiles ABOVE the base rung — main lens only\n (the thumbnail rail composes without per-view tiling).\n Engages by demand\n arithmetic when the deployment lattice caps the base. */}\n <TileLayer annotations={false} />\n <SelectionLayer />\n <SearchLayer />\n {/* Clickable links (nav plane): anchors under the default\n pointer/pan tools; stands down whenever an authoring\n tool is active (the annotation plane owns links then).\n Below the AnnotationLayer so an editing free-text box\n wins pointer hits; the annotation layer's own surface\n is pointer-events: none, so clicks fall through to the\n anchors everywhere else. */}\n <LinkLayer />\n {/* Form widgets plug into the annotation stack: engaged\n (fill mode) they render as fill controls over the baked\n appearance; under the Form tab they're plain editable\n annotations. */}\n <AnnotationLayer renderers={ANNOTATION_RENDERERS} />\n </>\n )}\n </Stage>\n <PageControls />\n </div>\n <RightSidebar />\n <RedactConfirmModal />\n </DocumentArea>\n </div>\n\n {toolbarEdge === 'bottom' && (\n <>\n <ModeBand edge=\"bottom\" />\n {toolbarBand}\n </>\n )}\n </div>\n );\n}\n","/**\n * The full viewer, as a component — and the customization CONTRACT. The\n * `ViewerCustomization` surface here is the exact shape that later powers\n * `EmbedPDF.init({...})` and every framework wrapper, because all of it is\n * plain data (see README.md).\n *\n * Two semantics, on purpose:\n * - REGISTRIES (commands / icons / strings) merge ADDITIVELY over the\n * defaults by id; a colliding id overrides.\n * - STRUCTURE (chrome) is an owned VALUE: the default, a transform of it,\n * or the host's own schema — never merged.\n *\n * The engine stays a prop — choosing local-wasm vs cloud is the host's\n * decision, and each delivery wires its own. The chrome —\n * toolbars, translations, theme — renders at t≈0; only the pages wait on\n * the engine. Customization is mount-time (exactly like v2's init config);\n * changing these props on a mounted viewer does not rebuild the workspace.\n */\n// One import line per feature: each subpath carries the\n// plugin AND its UI; delete a line and the feature leaves the bundle.\nimport { useEffect, useState, type ReactNode } from 'react';\nimport { Viewer, useKernel } from '@embedpdf/react/runtime';\nimport type { Engine, EngineFactory, InitialDocument } from '@embedpdf/react/runtime';\nimport { stagePlugin } from '@embedpdf/react/stage';\nimport { renderPlugin } from '@embedpdf/react/render';\nimport { pageEditPlugin } from '@embedpdf/react/page-edit';\nimport { interactionPlugin } from '@embedpdf/react/interaction';\nimport { selectionPlugin } from '@embedpdf/react/selection';\nimport { annotationPlugin } from '@embedpdf/react/annotation';\nimport { redactionPlugin } from '@embedpdf/react/redaction';\nimport { formPlugin } from '@embedpdf/react/form';\nimport { linkPlugin } from '@embedpdf/react/link';\nimport { searchPlugin } from '@embedpdf/react/search';\nimport { i18nPlugin, negotiateLocale, useT } from '@embedpdf/react/i18n';\nimport type { Locale, TranslationDictionary } from '@embedpdf/react/i18n';\nimport { commandsPlugin } from '@embedpdf/react/commands';\nimport type { CommandDef } from '@embedpdf/react/commands';\nimport { shellPlugin } from '@embedpdf/react/shell';\nimport { chromeHelpers, validateChrome } from '@embedpdf/react/toolbar';\nimport type { ChromeHelpers, ChromeSchema } from '@embedpdf/react/toolbar';\nimport { ThumbsStageToken } from './config/stage';\nimport { defaultChrome } from './config/chrome';\nimport { defaultCommands } from './config/commands';\nimport { demoToolsPlugin } from './config/demo-tools.plugin';\nimport { en } from './locales/en';\nimport { ViewerConfigProvider, type ResolvedViewerConfig } from './config-context';\nimport { createViewerHandle, type ViewerHandle } from './handle';\nimport { ICON_PATHS, type IconDef } from './ui/icons';\nimport { ThemeProvider, type ThemePreference } from './ui/theme';\nimport { Shell } from './Shell';\n\n/** Lazy built-in packs — a strings override for one of these wraps its loader. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<Locale>> = {\n es: () => import('./locales/es').then((m) => m.es),\n};\n\nconst isDict = (v: unknown): v is TranslationDictionary => typeof v === 'object' && v !== null;\n\n/**\n * Deep-merge `over` into `base` (immutably), expanding dotted keys —\n * `{ 'acme.send': 'X' }` and `{ acme: { send: 'X' } }` are the same override.\n */\nfunction mergeTranslations(\n base: TranslationDictionary,\n over: TranslationDictionary,\n): TranslationDictionary {\n const out: Record<string, string | TranslationDictionary> = { ...base };\n for (const [key, value] of Object.entries(over)) {\n const path = key.split('.');\n let node = out;\n for (let i = 0; i < path.length - 1; i++) {\n const prev = node[path[i]];\n node = (node[path[i]] = isDict(prev) ? { ...prev } : {}) as Record<\n string,\n string | TranslationDictionary\n >;\n }\n const leaf = path[path.length - 1];\n const prev = node[leaf];\n node[leaf] =\n typeof value === 'string' ? value : mergeTranslations(isDict(prev) ? prev : {}, value);\n }\n return out;\n}\n\nconst mergeLocale = (pack: Locale, over?: TranslationDictionary): Locale =>\n over ? { ...pack, translations: mergeTranslations(pack.translations, over) } : pack;\n\n/**\n * The customization surface — identical in the vanilla snippet and every\n * framework wrapper. See README.md for the ladder this implements.\n */\nexport interface ViewerCustomization {\n /** ADDITIVE over the default vocabulary; a colliding id overrides. */\n commands?: readonly CommandDef[];\n /** ADDITIVE 24×24 stroke icons by name; a colliding name overrides. */\n icons?: Readonly<Record<string, IconDef>>;\n /** Per-locale translation overrides/additions; dotted keys expand. A code\n * with no built-in pack becomes a new locale (falls back to English). */\n strings?: Readonly<Record<string, TranslationDictionary>>;\n /** 'auto' (default) negotiates from the browser languages. */\n locale?: 'auto' | (string & {});\n /** Feature gating: a disabled category vanishes from every surface. */\n disabledCategories?: readonly string[];\n /** The structure — a value you OWN: the default (pass nothing), a transform\n * of it, or your own schema. Never merged. */\n chrome?: ChromeSchema | ((base: ChromeSchema, helpers: ChromeHelpers) => ChromeSchema);\n /** Light/dark preference (string shorthand), or the full theme config with\n * `--ep-*` token overrides. Tokens are applied by the DELIVERY (the custom\n * element adopts them into its shadow root); direct consumers of this\n * package set the `--ep-*` variables in their own CSS instead. */\n theme?: ThemePreference | ThemeConfig;\n}\n\n/** Token overrides — names WITHOUT the `--ep-` prefix ('accent', 'surface'…). */\nexport type ThemeTokens = Readonly<Record<string, string>>;\n\nexport interface ThemeConfig {\n /** 'system' (default) follows the OS. */\n preference?: ThemePreference;\n /** Applied in BOTH modes (a later sheet: wins over the defaults). */\n tokens?: ThemeTokens;\n /** Dark-mode-only overrides, applied over `tokens`. */\n dark?: ThemeTokens;\n}\n\n/** Normalize the shorthand — deliveries use this to read one shape. */\nexport const themeConfigOf = (theme: ThemePreference | ThemeConfig | undefined): ThemeConfig =>\n typeof theme === 'string' ? { preference: theme } : (theme ?? {});\n\nexport interface FullViewerProps extends ViewerCustomization {\n /** Instance (borrowed) or thunk (viewer-owned) — the Viewer's own contract. */\n engine: Engine | EngineFactory;\n /** Documents to open at mount; more arrive via the tab bar's open button. */\n initialDocuments?: InitialDocument[];\n /** Shown while the workspace boots. Default: a translated pulse line. */\n fallback?: ReactNode;\n /** Where the theme's `.dark` class goes — a DELIVERY concern, not user\n * config: the custom element passes its shadow wrapper so theming never\n * touches the host page. Default: document.documentElement. */\n themeTarget?: HTMLElement | null;\n /** Called once the workspace kernel is live, with the viewer handle — the\n * DRIVE surface (`el.viewer` on the custom element, `onReady` on the\n * wrappers). Capabilities resolve from the moment this fires; document-\n * scoped calls simply await their document. */\n onViewer?: (viewer: ViewerHandle) => void;\n}\n\n/** Inside <Viewer>: mints the handle from the live kernel, reports it up. */\nfunction HandleBridge({ onViewer }: { onViewer: (viewer: ViewerHandle) => void }) {\n const kernel = useKernel();\n useEffect(() => {\n onViewer(createViewerHandle(kernel));\n // Init-only like everything else: re-fires only if the KERNEL changes\n // (a remount), never because the callback prop identity churned.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [kernel]);\n return null;\n}\n\nfunction Booting() {\n const t = useT();\n return (\n <div className=\"bg-app text-fg-muted grid h-full place-items-center\">\n <div className=\"animate-pulse text-sm\">{t('demo.starting')}</div>\n </div>\n );\n}\n\nexport function FullViewer({\n engine,\n initialDocuments,\n fallback,\n commands,\n icons,\n strings,\n locale = 'auto',\n disabledCategories,\n chrome,\n theme,\n themeTarget,\n onViewer,\n}: FullViewerProps) {\n // Customization is INIT-ONLY, exactly like v2's `EmbedPDF.init` (and like\n // the Viewer's own engine/plugins contract): the whole config resolves ONCE\n // from the mount-time props, so inline literals — the idiomatic way to pass\n // it — never churn plugin identities. Later prop changes are ignored.\n const [resolved] = useState(() => {\n // ── registries: additive, user wins by id ───────────────────────────────\n const byId = new Map(defaultCommands.map((c) => [c.id, c]));\n for (const c of commands ?? []) byId.set(c.id, c);\n const resolvedCommands = [...byId.values()];\n\n // ── structure: an owned value (default | transform | replacement) ───────\n const resolvedChrome =\n typeof chrome === 'function'\n ? chrome(defaultChrome, chromeHelpers)\n : (chrome ?? defaultChrome);\n\n // ── locale packs: overrides merge into built-ins; unknown codes become\n // new locales that fall back to English ──────────────────────────────\n const overrides = strings ?? {};\n const locales: Locale[] = [mergeLocale(en, overrides.en)];\n const loaders: Record<string, () => Promise<Locale>> = {};\n for (const [code, load] of Object.entries(BUILTIN_LOADERS)) {\n const over = overrides[code];\n loaders[code] = over ? () => load().then((pack) => mergeLocale(pack, over)) : load;\n }\n for (const [code, over] of Object.entries(overrides)) {\n if (code === 'en' || code in BUILTIN_LOADERS) continue;\n locales.push({ code, name: code, translations: mergeTranslations({}, over) });\n }\n const codes = [...new Set(['en', ...Object.keys(BUILTIN_LOADERS), ...Object.keys(overrides)])];\n const initial =\n locale === 'auto'\n ? (negotiateLocale(codes, typeof navigator !== 'undefined' ? navigator.languages : []) ??\n 'en')\n : locale;\n\n return {\n commands: resolvedCommands,\n chrome: resolvedChrome,\n icons: icons ?? {},\n i18n: { locales, loaders, initial },\n };\n });\n\n // Dev guardrail: every id the chrome references must exist; every icon a\n // command names must resolve. Warnings name the exact id (README promise).\n useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n const ids = new Set(resolved.commands.map((c) => c.id));\n for (const problem of validateChrome(resolved.chrome, ids)) {\n console.warn(`[embedpdf] chrome: ${problem}`);\n }\n for (const c of resolved.commands) {\n if (c.icon && !(c.icon in ICON_PATHS) && !(c.icon in resolved.icons)) {\n console.warn(`[embedpdf] command \"${c.id}\": unknown icon \"${c.icon}\"`);\n }\n }\n }, [resolved]);\n\n const [plugins] = useState(() => [\n stagePlugin({ layout: 'vertical', interaction: true }), // main lens; drives the interaction hub\n // Thumbnail lens over the SAME document: a single-column grid at a fixed small\n // zoom, its own camera. Click a thumb to navigate the main lens; the sidebar\n // follows the main view (see ui/panels ThumbnailList).\n stagePlugin({\n id: 'stage-thumbs',\n token: ThumbsStageToken,\n layout: 'grid',\n columns: 1, // single column, like the v2 snippet's thumbnail rail\n sizing: 'uniform', // equalize pages so the pixel target hits every thumb\n zoom: { pageWidth: 150 }, // thumbs are 150 SCREEN px wide — for ANY document\n padding: 12,\n gap: { px: 16 }, // UI-stable spacing between thumbs\n pageFrame: { top: 0, right: 0, bottom: 20, left: 0 }, // reserved label band (screen px)\n fitAlign: { x: 'center', y: 'start' }, // few pages? thumbs hug the TOP\n scrollBehavior: 'instant',\n }),\n renderPlugin(),\n pageEditPlugin(),\n interactionPlugin({ defaultTool: 'pointer' }),\n selectionPlugin(),\n // The arrow tool is a `line` preset — same subtype, an arrowhead default. This is\n // the whole integration for a new tool: one `tools` entry + a command/toolbar\n // slot (see config/commands.ts + config/chrome.ts).\n annotationPlugin({\n tools: [\n {\n id: 'arrow',\n extends: 'line',\n defaults: { lineEndings: { start: 'none', end: 'open-arrow' } },\n },\n ],\n }),\n // Forms: fillable under the default pointer/pan (widgets render as fill\n // controls), editable under the Form tab's 'form-edit' + palette tools.\n formPlugin({ scripting: { enabled: true } }),\n // Links: navigable under the default pointer/pan ('link-nav'), editable\n // under the link tool — the annotation plane then owns them (select, move,\n // retarget via the style panel's Link control).\n linkPlugin(),\n // Redaction: marking is the annotation plane's composed `redact` tool; this\n // plugin adds the pending-queue view + the destructive apply.\n redactionPlugin(),\n searchPlugin(),\n demoToolsPlugin(),\n i18nPlugin({\n locale: resolved.i18n.initial,\n fallbackLocale: 'en',\n locales: resolved.i18n.locales,\n loaders: resolved.i18n.loaders,\n }),\n commandsPlugin({\n commands: resolved.commands,\n disabledCategories: disabledCategories ? [...disabledCategories] : undefined,\n }),\n shellPlugin(),\n ]);\n\n // Structural subset of `resolved`, identity-stable across renders.\n const config: ResolvedViewerConfig = resolved;\n\n return (\n <ThemeProvider preference={themeConfigOf(theme).preference} target={themeTarget}>\n <Viewer\n engine={engine}\n plugins={plugins}\n initialDocuments={initialDocuments}\n fallback={fallback ?? <Booting />}\n >\n <ViewerConfigProvider value={config}>\n {onViewer && <HandleBridge onViewer={onViewer} />}\n <Shell />\n </ViewerConfigProvider>\n </Viewer>\n </ThemeProvider>\n );\n}\n"],"mappings":"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EAAW,MAAM;CAAY,CAC1F;CACA,SAAS;EACP;EACA;EACA;EACA;CACF;CACA,MAAM,CACJ,gKACA,+FACF;CACA,cAAc;EACZ;EACA;EACA;CACF;CACA,MAAM;EACJ;EACA;EACA;CACF;CACA,YAAY,CACV,yFACF;CACA,UAAU;EAAC;EAA8C;EAAkB;CAAY;CACvF,cAAc;EACZ;EACA;EACA;CACF;CACA,KAAK,CAAC,8CAA8C;CACpD,MAAM,CAAC,4DAA4D;CACnE,YAAY,CACV,2BACA,+EACF;CACA,WAAW;EACT;EACA;EACA;EACA;EACA;CACF;CACA,YAAY;EACV;EACA;EACA;EACA;EACA;CACF;CACA,cAAc,CACZ,kFACA,gBACF;CACA,aAAa;EACX;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,WAAW,CACT;EAAE,GAAG;EAAsC,MAAM;CAAK,GACtD,sCACF;CACA,YAAY,CACV,kFACA,gBACF;CACA,eAAe;EACb;EACA;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;EACR;GAAE,GAAG;GAAgB,QAAQ;EAAU;EACvC;GAAE,GAAG;GAAY,QAAQ;EAAU;EACnC;GAAE,GAAG;GAAa,QAAQ;EAAU;EACpC;GAAE,GAAG;GAAiB,QAAQ;EAAU;EACxC;GAAE,GAAG;GAAY,QAAQ;EAAU;EACnC;GAAE,GAAG;GAAY,QAAQ;EAAU;CACrC;CACA,YAAY;EACV;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd;EACA;EACA;EACA;EACA;CACF;CACA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM;EACJ;EACA;EACA;EACA;CACF;CACA,WAAW;EAET;GACE,GAAG;GACH,MAAM;EACR;EACA;EACA;CACF;CACA,YAAY;EAAC;EAAiB;EAAkB;CAAY;CAC5D,gBAAgB;EACd;EACA;EACA;EACA;GAAE,GAAG;GAAwB,QAAQ;GAAW,MAAM;EAAU;CAClE;CACA,YAAY;EACV;GAAE,GAAG;GAAgB,QAAQ;EAAU;EACvC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAiB,QAAQ;EAAU;EACxC;GAAE,GAAG;GAAe,QAAQ;EAAU;CACxC;CACA,QAAQ;EAAC;EAAa;EAAa;CAAa;CAChD,MAAM,CAAC;EAAE,GAAG;EAAgB,QAAQ;CAAU,CAAC;CAI/C,WAAW,CACT;EAAE,GAAG;EAAgB,QAAQ;CAAU,GACvC;EAAE,GAAG;EAAa,QAAQ;CAAU,CACtC;CACA,MAAM;EACJ;EACA;EACA;CACF;CACA,SAAS;EACP;EACA;EACA;EACA;CACF;CACA,UAAU;EAAC;EAAW;EAAY;EAAY;EAAY;EAAa;CAAY;CACnF,MAAM,CACJ,gFACA,0BACF;CACA,eAAe;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,CAAC,aAAa,YAAY;CAChC,SAAS;EACP;EACA;EACA;CACF;CACA,SAAS;EACP;EACA;EACA;EACA;CACF;CACA,WAAW,CACT,+FACF;CACA,cAAc,CACZ,gIACA;EACE,GAAG;EACH,QAAQ;CACV,CACF;CACA,OAAO;EACL;EACA;EACA;EACA;CACF;CAEA,MAAM,CAAC,cAAc,YAAY;CACjC,SAAS,CACP,oNACF;CACA,SAAS,CACP;EACE,GAAG;EACH,QAAQ;EACR,MAAM;CACR,CACF;CACA,OAAO;EACL;EACA;EACA;CACF;CACA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAIA,YAAY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kBAAkB;EAChB;EACA;EACA;EACA;EACA;CACF;CACA,aAAa;EACX;GAAE,GAAG;GAAgB,QAAQ;EAAU;EACvC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAiB,QAAQ;EAAU;EACxC;GAAE,GAAG;GAAe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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["InteractionToken","CommandsToken","StageToken","RedactionToken","AnnotationToken","StageToken","AnnotationToken","SearchToken","StageToken","ShellToken","chromeHelpers","validateChrome"],"sources":["../src/config/stage.ts","../src/config/demo-tools.plugin.ts","../src/locales/en.ts","../src/config-context.tsx","../src/handle.ts","../src/ui/icons.tsx","../src/ui/theme.tsx","../src/ui/menu.tsx","../src/ui/toolbar.tsx","../src/ui/link-editor.tsx","../src/ui/strip-bar.tsx","../src/ui/annotation-strip.tsx","../src/ui/selection-strip.tsx","../src/ui/tab-bar.tsx","../src/ui/tool-cursor.tsx","../src/ui/annotation-flags.tsx","../src/ui/annotation-style.tsx","../src/ui/comment-config.ts","../src/ui/comments-panel.tsx","../src/ui/redaction-panel.tsx","../src/ui/search-panel.tsx","../src/ui/panels.tsx","../src/ui/redact-confirm.tsx","../src/ui/document-boot.tsx","../src/Shell.tsx","../src/viewer.tsx"],"sourcesContent":["/**\n * The Stage is a LENS: one document can be viewed through several at once. The\n * thumbnail sidebar is a second lens over the SAME document — a single-column,\n * fixed-zoom grid with its own camera, fully independent of the main view.\n *\n * The token lives here (not in App.tsx) because two places need it: App wires the\n * `stagePlugin` lens with it, and the sidebar renders `<Stage token={...}>` off it.\n */\nimport { createCapabilityToken } from '@embedpdf/react/runtime';\nimport type { StageCapability } from '@embedpdf/react/stage';\n\nexport const ThumbsStageToken = createCapabilityToken<StageCapability>('stage-thumbs');\n","import { definePlugin } from '@embedpdf/react/runtime';\nimport { InteractionToken } from '@embedpdf/react/interaction';\n\n/**\n * Example-only: register the insert / redact authoring tools as INERT\n * interaction tools. v3 doesn't yet ship signature or redaction plugins, but\n * this is a CHROME demo — its job is selection state and layout, not the\n * tool's effect. Registering them as real (behaviourless) tools lets every\n * tool button in every mode band go through the SAME path\n * (`InteractionToken.activateTool`), so `active` is uniform and honest: the\n * button really is the active tool; it just has no handler behind it.\n *\n * The annotate + shapes tools are NOT here — those are real tools the\n * annotation plugin registers (highlight, ink, square, circle, …) — and\n * neither are the form palette tools (the form plugin's draw-to-place).\n */\nconst INERT_TOOLS: ReadonlyArray<{ id: string; cursor: string }> = [\n // insert mode (redact is REAL now — plugin-annotation ships the composed\n // tool and plugin-redaction the destructive apply)\n { id: 'signature', cursor: 'copy' },\n { id: 'image', cursor: 'copy' },\n];\n\nexport const demoToolsPlugin = () =>\n definePlugin({\n id: 'demo-tools',\n scope: 'document',\n requires: [InteractionToken],\n init: (ctx) => {\n const interaction = ctx.get(InteractionToken);\n for (const tool of INERT_TOOLS) {\n // No `enables` → no gesture/handler wakes up: the tool is selectable\n // (cursor + active state) but behaviourless. Exactly what a chrome demo\n // needs from form/redact/signature tools v3 doesn't ship yet.\n interaction.registerTool({ id: tool.id, cursor: tool.cursor, enables: new Set<string>() });\n }\n },\n });\n","import type { Locale } from '@embedpdf/react/i18n';\n\n/**\n * English pack. Strings belong to the PRODUCT, not the plugins — the\n * `commands.*` namespace mirrors the v2 snippet packs so translations carry\n * over; `demo.*` is this example's own chrome.\n */\nexport const en: Locale = {\n code: 'en',\n name: 'English',\n translations: {\n commands: {\n zoom: {\n in: 'Zoom In',\n out: 'Zoom Out',\n fitPage: 'Fit to Page',\n fitWidth: 'Fit to Width',\n automatic: 'Automatic',\n menu: 'Zoom',\n level: 'Zoom Level',\n p50: '50%',\n p100: '100%',\n p150: '150%',\n p200: '200%',\n p400: '400%',\n },\n pan: 'Pan',\n pointer: 'Pointer',\n sidebar: 'Sidebar',\n search: 'Search',\n comment: 'Comment',\n style: 'Style',\n menu: 'Menu',\n viewControls: 'View Controls',\n download: 'Download',\n print: 'Print',\n fullscreen: 'Full Screen',\n spread: { group: 'Page Layout', none: 'Single Page', odd: 'Two Page', even: 'Cover Page' },\n scroll: { group: 'Scrolling', vertical: 'Vertical', horizontal: 'Horizontal' },\n rotate: {\n group: 'Rotate',\n clockwise: 'Rotate Clockwise',\n counterclockwise: 'Rotate Counter-Clockwise',\n },\n mode: {\n group: 'Mode',\n view: 'View',\n annotate: 'Annotate',\n shapes: 'Shapes',\n insert: 'Insert',\n form: 'Form',\n redact: 'Redact',\n },\n annotate: {\n highlight: 'Highlight',\n strikeout: 'Strikeout',\n underline: 'Underline',\n squiggly: 'Squiggly',\n ink: 'Draw',\n inkHighlight: 'Ink Highlighter',\n text: 'Text',\n insertText: 'Insert Text',\n replaceText: 'Replace Text',\n callout: 'Callout',\n note: 'Comment',\n link: 'Link',\n gotoLink: 'Go to link',\n removeLink: 'Remove link',\n delete: 'Delete',\n group: 'Group',\n ungroup: 'Ungroup',\n strip: 'Annotation actions',\n },\n selection: {\n copy: 'Copy',\n strip: 'Text selection actions',\n },\n shapes: {\n rectangle: 'Rectangle',\n circle: 'Circle',\n line: 'Line',\n arrow: 'Arrow',\n polygon: 'Polygon',\n polyline: 'Polyline',\n },\n insert: {\n stamp: 'Rubber Stamp',\n attachment: 'Attach File',\n signature: 'Signature',\n image: 'Image',\n },\n form: {\n textfield: 'Text Field',\n checkbox: 'Checkbox',\n radio: 'Radio Button',\n select: 'Dropdown',\n listbox: 'List Box',\n },\n redact: {\n mark: 'Mark for Redaction',\n applyAll: 'Apply Redactions',\n clearAll: 'Clear Marks',\n panel: 'Redactions',\n },\n undo: 'Undo',\n redo: 'Redo',\n },\n passwordPrompt: {\n title: 'Password required',\n required: 'This document is password protected. Enter the password to open it.',\n incorrect: 'The password was incorrect. Please try again.',\n incorrectWarning: 'Incorrect password',\n label: 'Password',\n placeholder: 'Enter password',\n cancel: 'Cancel',\n open: 'Open',\n opening: 'Opening…',\n },\n documentError: {\n title: 'Couldn’t open document',\n unknown: 'The document could not be opened.',\n close: 'Close document',\n },\n // Annotation type names — the comment sidebar's icon tooltips. Keys carry\n // over from the v2 packs so existing translations still resolve.\n annotation: {\n comment: 'Comment',\n highlight: 'Highlight',\n underline: 'Underline',\n squiggly: 'Squiggly',\n strikeout: 'Strikethrough',\n square: 'Square',\n circle: 'Circle',\n line: 'Line',\n polygon: 'Polygon',\n polyline: 'Polyline',\n ink: 'Ink',\n freeText: 'Text',\n stamp: 'Stamp',\n caret: 'Caret',\n redact: 'Redact',\n fileAttachment: 'Attachment',\n },\n demo: {\n starting: 'Starting viewer…',\n opening: 'Opening document…',\n more: 'More',\n thumbnails: 'Thumbnails',\n outline: 'Outline',\n searchPlaceholder: 'Search document…',\n searchTitle: 'Search',\n searchCaseSensitive: 'Case sensitive',\n searchWholeWord: 'Whole word',\n searchRegex: 'Regular expression',\n searchSearching: 'Searching…',\n searchResults: '{count} results found',\n searchNoResults: 'No results',\n searchPage: 'Page {page}',\n commentsTitle: 'Comments',\n commentsForbidden: 'You don\\u2019t have access to comments on this document.',\n commentsLoading: 'Loading comments…',\n commentsError: 'Comments failed to load.',\n commentsRetry: 'Retry',\n commentsEmpty: 'No comments yet. Use the note tool to start a thread.',\n commentsAnonymous: 'Unknown',\n commentsPage: 'Page {page}',\n commentCount: '{count} comment',\n commentCountPlural: '{count} comments',\n commentsReply: 'Reply',\n commentsReplyPlaceholder: 'Reply…',\n commentsAddPlaceholder: 'Add a comment…',\n commentsDelete: 'Delete comment',\n commentsDeleteThread: 'Delete thread',\n commentsEdit: 'Edit comment',\n commentsStatus: 'Status',\n commentsStatusNone: 'No status',\n commentsStatusAccepted: 'Accepted',\n commentsStatusRejected: 'Rejected',\n commentsStatusCancelled: 'Cancelled',\n commentsStatusCompleted: 'Completed',\n styleTitle: 'Style',\n empty: 'Nothing here yet in this demo panel.',\n page: 'Page {current} of {total}',\n cancel: 'Cancel',\n pageBadge: 'p. {page}',\n redactionTitle: 'Redactions',\n redactionEmpty: 'No pending redactions. Use the Redact tool to mark text or areas.',\n redactionArea: 'Area mark',\n redactionText: 'Text mark',\n redactionRemove: 'Remove mark',\n redactConfirmTitle: 'Apply redactions?',\n redactConfirmBody:\n 'Permanently remove the content under {count} redaction marks. This cannot be undone.',\n redactConfirmCollateral: '{count} other annotations will also be removed.',\n redactApply: 'Apply',\n redactApplying: 'Applying…',\n redactLabelTitle: 'Redaction label',\n redactLabelPlaceholder: 'e.g. REDACTED',\n redactLabelRepeat: 'Repeat label across region',\n },\n },\n};\n","/**\n * The resolved customization, as React context. The chrome schema and the\n * user's extra icons are RESOLVED ONCE in <FullViewer> and read here by the\n * shell, menus, and strips — no component imports the default schema value\n * directly, so \"the host replaced the chrome\" is invisible below this line.\n *\n * The default context value is the default config: components render correctly\n * in tests and stories without a provider.\n */\nimport { createContext, useContext } from 'react';\nimport type { BarSchema, ChromeSchema, MenuSchema } from '@embedpdf/react/toolbar';\nimport { defaultChrome, getMenu, getModeBar, getStrip } from './config/chrome';\nimport type { IconDef } from './ui/icons';\n\nexport interface ResolvedViewerConfig {\n readonly chrome: ChromeSchema;\n /** User-registered icons — additive over the built-in set. */\n readonly icons: Readonly<Record<string, IconDef>>;\n}\n\nconst DEFAULT_CONFIG: ResolvedViewerConfig = { chrome: defaultChrome, icons: {} };\n\nconst ViewerConfigContext = createContext<ResolvedViewerConfig>(DEFAULT_CONFIG);\n\nexport const ViewerConfigProvider = ViewerConfigContext.Provider;\n\nexport function useChromeSchema(): ChromeSchema {\n return useContext(ViewerConfigContext).chrome;\n}\n\nexport function useMenuSchema(id: string): MenuSchema | undefined {\n return getMenu(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useModeBarSchema(id: string): BarSchema | undefined {\n return getModeBar(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useStripSchema(id: string): BarSchema | undefined {\n return getStrip(useContext(ViewerConfigContext).chrome, id);\n}\n\nexport function useCustomIcons(): Readonly<Record<string, IconDef>> {\n return useContext(ViewerConfigContext).icons;\n}\n","/**\n * The viewer handle — `el.viewer`, the DRIVE door of the customization model.\n *\n * Deliberately a THIN SKIN over the kernel: `get()` returns each plugin's\n * PUBLIC capability lens exactly as the plugin defined it (the internal/public\n * two-lens split in the plugins IS the curation — this file adds no facade,\n * no second vocabulary, no second write path). `watch()` is the kernel's one\n * change stream, selector-shaped — `useSelector` without React. The command\n * trio is the UI altitude of the same system, for anything button-shaped.\n *\n * Rule of thumb (docs): buttons speak commands; code speaks capabilities.\n *\n * The chrome itself runs on these exact primitives (customer #1), so parity\n * between \"what our UI can do\" and \"what el.viewer can do\" is structural.\n */\nimport type {\n CapabilityToken,\n DocumentsCapability,\n Kernel,\n Unsubscribe,\n} from '@embedpdf/react/runtime';\nimport { CommandsToken, resolvedCommandsEqual } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\n\n/** `get`/`tryGet` bound to one document (see {@link ViewerHandle.forDocument}). */\nexport interface ScopedViewerHandle {\n get<T>(token: CapabilityToken<T>): T;\n tryGet<T>(token: CapabilityToken<T>): T | null;\n}\n\nexport interface ViewerHandle extends ScopedViewerHandle {\n /** The document registry — the tab model: list/open/close/setActive/…. */\n readonly documents: DocumentsCapability;\n\n /** `get`/`tryGet` with document-scoped tokens bound to `documentId`\n * instead of the active document. */\n forDocument(documentId: string): ScopedViewerHandle;\n\n /**\n * Re-run `select` on every kernel change; call `cb` when the selected value\n * really changed (`isEqual`, default `Object.is` — capability getters return\n * stable references between model changes, so identity works). Returns the\n * unsubscribe. This is the ONLY reactivity primitive; DOM events on the\n * element are sugar over it.\n */\n watch<T>(\n select: () => T,\n cb: (value: T, previous: T) => void,\n isEqual?: (a: T, b: T) => boolean,\n ): Unsubscribe;\n\n // ── commands: the UI vocabulary layered on the same capabilities ──────────\n execute(id: string, documentId?: string): void;\n resolve(id: string, documentId?: string): ResolvedCommand | null;\n /** `watch` sugar for one command's resolved state (label/icon/enabled/active). */\n watchCommand(id: string, cb: (cmd: ResolvedCommand | null) => void): Unsubscribe;\n}\n\nexport function createViewerHandle(kernel: Kernel): ViewerHandle {\n const watch = <T>(\n select: () => T,\n cb: (value: T, previous: T) => void,\n isEqual: (a: T, b: T) => boolean = Object.is,\n ): Unsubscribe => {\n let previous = select();\n return kernel.subscribe(() => {\n const next = select();\n if (isEqual(previous, next)) return;\n const before = previous;\n previous = next;\n cb(next, before);\n });\n };\n\n const commands = () => kernel.capability(CommandsToken);\n\n return {\n documents: kernel.documents,\n get: (token) => kernel.capability(token),\n tryGet: (token) => kernel.tryCapability(token),\n forDocument: (documentId) => ({\n get: (token) => kernel.capability(token, documentId),\n tryGet: (token) => kernel.tryCapability(token, documentId),\n }),\n watch,\n execute: (id, documentId) => commands().execute(id, documentId),\n resolve: (id, documentId) => commands().resolve(id, documentId) ?? null,\n watchCommand: (id, cb) =>\n watch(() => commands().resolve(id) ?? null, cb, resolvedCommandsEqual),\n };\n}\n","/**\n * Icon set — the snippet's Tabler-style stroke icons, extracted to path data\n * (from viewers/snippet/src/components/icons) and rendered by one <Icon>\n * component. Names match the snippet's icon registry so command `icon` ids\n * carry over verbatim. Stroke-based (currentColor); a few glyphs carry filled\n * sub-paths, marked `fill: true`.\n *\n * ACCENT SLOTS: a tool glyph tags the sub-paths that preview the tool's\n * drawing defaults — `stroke`/`fill: 'primary' | 'secondary'` paint from the\n * command's resolved `iconAccent` (slot placement ported 1:1 from the v2\n * hand-authored components). With no accent, a slotted stroke inherits\n * currentColor and a slotted fill renders nothing — pixel-identical to the\n * untagged glyph, so non-tool surfaces never change.\n *\n * GENERATED by scratchpad/extract-icons.mjs — 93 icons (slot tags by hand).\n */\nimport * as React from 'react';\nimport { useCustomIcons } from '../config-context';\n\nexport type PathSpec =\n | string\n | {\n d: string;\n /** Fill paint: `true` = currentColor (a filled glyph part); a slot\n * name = that accent color (nothing when the accent is absent). */\n fill?: boolean | 'primary' | 'secondary';\n /** Stroke paint: a slot name = that accent color (currentColor when\n * the accent is absent). */\n stroke?: 'primary' | 'secondary';\n };\n\n/** A registrable icon: 24×24 stroke path data (Tabler/Lucide-style), exactly\n * the shape of the built-in set — user icons are not a lesser kind. */\nexport type IconDef = readonly PathSpec[];\n\n/** The two tintable slots — structurally identical to plugin-commands'\n * IconAccent, kept local so the icon set stays dependency-free. */\nexport interface IconAccent {\n primary?: string;\n secondary?: string;\n}\n\nexport const ICON_PATHS: Record<string, readonly PathSpec[]> = {\n alertTriangle: [\n 'M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z',\n ],\n alignBottom: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 17h2',\n 'M9 14h6',\n 'M10 11h4',\n ],\n alignCenter: ['M4 6l16 0', 'M8 12l8 0', 'M6 18l12 0'],\n alignLeft: ['M4 6l16 0', 'M4 12l10 0', 'M4 18l14 0'],\n alignMiddle: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 15h2',\n 'M9 12h6',\n 'M10 9h4',\n ],\n alignRight: ['M4 6l16 0', 'M10 12l10 0', 'M6 18l14 0'],\n alignTop: [\n 'M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n 'M11 13h2',\n 'M9 10h6',\n 'M10 7h4',\n ],\n arrowBackUp: ['M9 14l-4 -4l4 -4', 'M5 10h11a4 4 0 1 1 0 8h-1'],\n arrowForwardUp: ['M15 14l4 -4l-4 -4', 'M19 10h-11a4 4 0 1 0 0 8h1'],\n bold: ['M7 5h6a3.5 3.5 0 0 1 0 7h-6z', 'M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7'],\n book: [\n 'M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0',\n 'M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0',\n 'M3 6l0 13',\n 'M12 6l0 13',\n 'M21 6l0 13',\n ],\n book2: [\n 'M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z',\n 'M19 16h-12a2 2 0 0 0 -2 2',\n 'M9 8h6',\n ],\n callout: [\n {\n d: 'M20 6v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1',\n stroke: 'primary',\n fill: 'secondary',\n },\n { d: 'M17 11v6h-9', stroke: 'primary' },\n { d: 'M8 15l-2 2l2 2', stroke: 'primary' },\n ],\n check: ['M5 12l5 5l10 -10'],\n chevronDown: ['M6 9l6 6l6 -6'],\n chevronLeft: ['M15 6l-6 6l6 6'],\n chevronRight: ['M9 6l6 6l-6 6'],\n circle: [\n { d: 'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', stroke: 'primary', fill: 'secondary' },\n ],\n comment: [\n 'M12 11v.01',\n 'M8 11v.01',\n 'M16 11v.01',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3z',\n ],\n copy: [\n 'M7 7m0 2.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z',\n 'M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1',\n ],\n deviceFloppy: [\n 'M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2',\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M14 4l0 4l-6 0l0 -4',\n ],\n dots: [\n 'M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n ],\n doublePage: [\n 'M3 3m0 1a1 1 0 0 1 1 -1h16a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1zm9 -1v18',\n ],\n download: ['M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2', 'M7 11l5 5l5 -5', 'M12 4l0 12'],\n externalLink: [\n 'M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6',\n 'M11 13l9 -9',\n 'M15 4h5v5',\n ],\n eye: ['M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'],\n file: ['M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'],\n fileImport: [\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M5 13v-8a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-5.5m-9.5 -2h7m-3 -3l3 3l-3 3',\n ],\n fitToPage: [\n 'M12 20h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h6',\n 'M18 14v7',\n 'M18 3v7',\n 'M15 18l3 3l3 -3',\n 'M15 6l3 -3l3 3',\n ],\n fitToWidth: [\n 'M4 12v-6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v6',\n 'M10 18h-7',\n 'M21 18h-7',\n 'M6 15l-3 3l3 3',\n 'M18 15l3 3l-3 3',\n ],\n formCheckbox: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M9 12l2 2l4 -4',\n ],\n formListbox: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M11 8h6',\n 'M11 12h6',\n 'M11 16h6',\n 'M7 8l0 .01',\n 'M7 12l0 .01',\n 'M7 16l0 .01',\n ],\n formRadio: [\n { d: 'M9 12a2 2 0 1 0 6 0a2 2 0 1 0 -6 0', fill: true },\n 'M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0',\n ],\n formSelect: [\n 'M3 5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-14',\n 'M9 11l3 3l3 -3',\n ],\n formTextfield: [\n 'M12 3a3 3 0 0 0 -3 3v12a3 3 0 0 0 3 3',\n 'M6 3a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3',\n 'M13 7h7a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-7',\n 'M5 7h-1a1 1 0 0 0 -1 1v8a1 1 0 0 0 1 1h1',\n 'M17 12h.01',\n 'M13 12h.01',\n ],\n freeText: [\n { d: 'M4 7v-2h12v2', stroke: 'primary' },\n { d: 'M10 5v14', stroke: 'primary' },\n { d: 'M12 19h-4', stroke: 'primary' },\n { d: 'M15 13v-1h6v1', stroke: 'primary' },\n { d: 'M18 12v7', stroke: 'primary' },\n { d: 'M17 19h2', stroke: 'primary' },\n ],\n fullscreen: [\n 'M4 8v-2a2 2 0 0 1 2 -2h2',\n 'M4 16v2a2 2 0 0 0 2 2h2',\n 'M16 4h2a2 2 0 0 1 2 2v2',\n 'M16 20h2a2 2 0 0 0 2 -2v-2',\n ],\n fullscreenExit: [\n 'M4 8v-2c0 -.551 .223 -1.05 .584 -1.412',\n 'M4 16v2a2 2 0 0 0 2 2h2',\n 'M16 4h2a2 2 0 0 1 2 2v2',\n 'M16 20h2c.545 0 1.04 -.218 1.4 -.572',\n 'M3 3l18 18',\n ],\n group: [\n 'M3 5a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M17 5a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M3 19a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M17 19a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M5 7v10',\n 'M19 7v10',\n 'M7 5h10',\n 'M7 19h10',\n 'M8 8H12.8V11.2H16V16H11.2V12.8H8V8Z',\n ],\n hand: [\n 'M8 13v-7.5a1.5 1.5 0 0 1 3 0v6.5',\n 'M11 5.5v-2a1.5 1.5 0 1 1 3 0v8.5',\n 'M14 5.5a1.5 1.5 0 0 1 3 0v6.5',\n 'M17 7.5a1.5 1.5 0 0 1 3 0v8.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47',\n ],\n highlight: [\n // the v2 marker block behind the \"A\" — visible only when accented\n {\n d: 'M4 6h16a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2H4a2 2 0 0 1 -2 -2V8a2 2 0 0 1 2 -2z',\n fill: 'primary',\n },\n 'M8 16v-8a4 4 0 1 1 8 0v8',\n 'M8 10h8',\n ],\n horizontal: ['M7 8l-4 4l4 4', 'M17 8l4 4l-4 4', 'M3 12l18 0'],\n inkHighlighter: [\n 'M3 19h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4',\n 'M12.5 5.5l4 4',\n 'M4.5 13.5l4 4',\n { d: 'M21 15v4h-8l4 -4l4 0', stroke: 'primary', fill: 'primary' },\n ],\n insertText: [\n { d: 'M3 7v-2h12v2', stroke: 'primary' },\n { d: 'M9 5v14', stroke: 'primary' },\n { d: 'M7 19h4', stroke: 'primary' },\n { d: 'M18 15l2 2h-5', stroke: 'primary' },\n { d: 'M18 19l2 -2', stroke: 'primary' },\n ],\n italic: ['M11 5l6 0', 'M7 19l6 0', 'M14 5l-4 14'],\n line: [{ d: 'M20 4l-16 16', stroke: 'primary' }],\n // Both strokes tag the `primary` accent slot so the arrow glyph previews the\n // tool's stroke colour (like the plain `line` icon); with no accent they render\n // as currentColor — identical to the untagged glyph.\n lineArrow: [\n { d: 'M20 4l-16 16', stroke: 'primary' },\n { d: 'M16 3h5v5', stroke: 'primary' },\n ],\n link: [\n 'M9 15l6 -6',\n 'M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464',\n 'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',\n ],\n linkOff: [\n 'M9 15l3 -3m2 -2l1 -1',\n 'M11 6l.463 -.536a5 5 0 0 1 7.072 7.071l-.534 .464',\n 'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',\n 'M3 3l18 18',\n ],\n listTree: ['M9 6h11', 'M12 12h8', 'M15 18h5', 'M5 6v.01', 'M8 12v.01', 'M11 18v.01'],\n lock: [\n 'M5 11h14a2 2 0 0 1 2 2v7a2 2 0 0 1 -2 2H5a2 2 0 0 1 -2 -2v-7a2 2 0 0 1 2 -2z',\n 'M7 11V7a5 5 0 0 1 10 0v4',\n ],\n marqueeSelect: [\n 'M17 20h6',\n 'M20 17v6',\n 'M4 13v-2',\n 'M4 6v-1a1 1 0 0 1 1 -1h1',\n 'M6 20h-1a1 1 0 0 1 -1 -1v-1',\n 'M11 4h2',\n 'M11 20h2',\n 'M18 4h1a1 1 0 0 1 1 1v1',\n 'M20 11v2',\n ],\n menu: ['M4 8l16 0', 'M4 16l16 0'],\n message: [\n 'M8 9h8',\n 'M8 13h6',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12',\n ],\n palette: [\n 'M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25',\n 'M8.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M12.5 7.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M16.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n ],\n paperclip: [\n 'M15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3l6.5 -6.5a3 3 0 0 0 -6 -6l-6.5 6.5a4.5 4.5 0 0 0 9 9l6.5 -6.5',\n ],\n pencilMarker: [\n 'm9.109 16.275 8.856-8.097c.812-.743.87-2.014.127-2.826s-2.014-.869-2.826-.127L6.41 13.322l-.127 2.826zM13.79 6.575l2.7 2.952',\n {\n d: 'M19.375 20.125c.569.063-4.05-.562-6.412-.437s-4.759 1.229-6.857 1.625c-1.764.687-3.404-.938-1.981-2.5',\n stroke: 'primary',\n },\n ],\n photo: [\n 'M15 8h.01',\n 'M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12z',\n 'M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5',\n 'M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3',\n ],\n // hand-added: the v2 file draws <line> primitives the extractor skips\n plus: ['M12 5l0 14', 'M5 12l14 0'],\n pointer: [\n 'M7.904 17.563a1.2 1.2 0 0 0 2.228 .308l2.09 -3.093l4.907 4.907a1.067 1.067 0 0 0 1.509 0l1.047 -1.047a1.067 1.067 0 0 0 0 -1.509l-4.907 -4.907l3.113 -2.09a1.2 1.2 0 0 0 -.309 -2.228l-13.582 -3.904l3.904 13.563z',\n ],\n polygon: [\n {\n d: 'M13.163 2.168l8.021 5.828c.694 .504 .984 1.397 .719 2.212l-3.064 9.43a1.978 1.978 0 0 1 -1.881 1.367h-9.916a1.978 1.978 0 0 1 -1.881 -1.367l-3.064 -9.43a1.978 1.978 0 0 1 .719 -2.212l8.021 -5.828a1.978 1.978 0 0 1 2.326 0z',\n stroke: 'primary',\n fill: 'secondary',\n },\n ],\n print: [\n 'M17 17h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-14a2 2 0 0 0 -2 2v4a2 2 0 0 0 2 2h2',\n 'M17 9v-4a2 2 0 0 0 -2 -2h-6a2 2 0 0 0 -2 2v4',\n 'M7 13m0 2a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v4a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z',\n ],\n redact: [\n 'M7 4h10',\n 'M12 4v8',\n 'M-7 24l12 -12',\n 'M-3 24l12 -12',\n 'M1 24l12 -12',\n 'M5 24l12 -12',\n 'M9 24l12 -12',\n 'M13 24l12 -12',\n 'M17 24l12 -12',\n 'M21 24l12 -12',\n 'M25 24l12 -12',\n ],\n // v2 parity: dashed frame + a SMALL rounded hatched box (v2 clips the\n // hatch via <clipPath>; this icon system is plain paths, so the hatch\n // segments are pre-clipped to the 10..22 box analytically).\n redactArea: [\n 'M6 20h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 13v-3',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h3',\n 'M17 3h1a2 2 0 0 1 2 2v1',\n 'M12 10h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2z',\n 'M10 12l2 -2',\n 'M10 16l6 -6',\n 'M10 20l10 -10',\n 'M12 22l10 -10',\n 'M16 22l6 -6',\n 'M20 22l2 -2',\n ],\n redactCombined: [\n 'M6 20h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 13v-3',\n 'M20 13v-3',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h3',\n 'M17 3h1a2 2 0 0 1 2 2v1',\n 'M8 8h8',\n 'M12 8v7',\n 'M6 19l12 -12',\n 'M6 23l12 -12',\n 'M10 23l12 -12',\n 'M14 27l12 -12',\n 'M14 23l12 -12',\n ],\n redactionSidebar: [\n 'M4 6a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M15 4v16',\n 'M7 8h5',\n 'M7 11h5',\n 'M7 14h4',\n ],\n replaceText: [\n { d: 'M3 7v-2h12v2', stroke: 'primary' },\n { d: 'M9 5v14', stroke: 'primary' },\n { d: 'M7 19h4', stroke: 'primary' },\n { d: 'M20 14l2 2h-3', stroke: 'primary' },\n { d: 'M20 18l2 -2', stroke: 'primary' },\n { d: 'M19 16a3 3 0 1 0 2 5.236', stroke: 'primary' },\n ],\n rotateClockwise: ['M4.05 11a8 8 0 1 1 .5 4m-.5 5v-5h5'],\n rotateCounterClockwise: ['M19.95 11a8 8 0 1 0 -.5 4m.5 5v-5h-5'],\n rubberStamp: [\n 'M21 17.85h-18c0 -4.05 1.421 -4.05 3.79 -4.05c5.21 0 1.21 -4.59 1.21 -6.8a4 4 0 1 1 8 0c0 2.21 -4 6.8 1.21 6.8c2.369 0 3.79 0 3.79 4.05',\n 'M5 21h14',\n ],\n rubberStampPlus: [\n 'M21 17.85h-18c0 -4.05 1.421 -4.05 3.79 -4.05c5.21 0 1.21 -4.59 1.21 -6.8a4 4 0 0 1 4.9 -4.1',\n 'M16 10c0 1.2 -4 3.8 1.21 3.8c2.369 0 3.79 0 3.79 4.05',\n 'M5 21h14',\n 'M16 5h6',\n 'M19 2v6',\n ],\n save: [\n 'M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2',\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M14 4l0 4l-6 0l0 -4',\n ],\n screenshot: [\n 'M7 19a2 2 0 0 1 -2 -2',\n 'M5 13v-2',\n 'M5 7a2 2 0 0 1 2 -2',\n 'M11 5h2',\n 'M17 5a2 2 0 0 1 2 2',\n 'M19 11v2',\n 'M19 17v4',\n 'M21 19h-4',\n 'M13 19h-2',\n ],\n search: ['M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0', 'M21 21l-6 -6'],\n settings: [\n 'M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z',\n 'M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0',\n ],\n sidebar: [\n 'M4 18v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M10 18v-12a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2z',\n ],\n signature: [\n 'M3 17c3.333 -3.333 5 -6 5 -8c0 -3 -1 -3 -2 -3s-2.032 1.085 -2 3c.034 2.048 1.658 4.877 2.5 6c1.5 2 2.5 2.5 3.5 1l2 -3c.333 2.667 1.333 4 3 4c.53 0 2.639 -2 3 -2c.517 0 1.517 .667 3 2',\n ],\n singlePage: ['M5 3m0 1a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1z'],\n square: [\n {\n d: 'M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z',\n stroke: 'primary',\n fill: 'secondary',\n },\n ],\n squares: [\n 'M8 10a2 2 0 0 1 2 -2h9a2 2 0 0 1 2 2v9a2 2 0 0 1 -2 2h-9a2 2 0 0 1 -2 -2z',\n 'M16 8v-3a2 2 0 0 0 -2 -2h-9a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h3',\n ],\n squiggly: [\n 'M8 16v-8a4 4 0 1 1 8 0v8',\n 'M8 10h8',\n { d: 'M4 20c1.5 -1.5 3.5 -1.5 5 0s3.5 1.5 5 0 3.5 -1.5 5 0', stroke: 'primary' },\n ],\n strikethrough: ['M8 16v-8a4 4 0 1 1 8 0v8', { d: 'M4 10h16', stroke: 'primary' }],\n text: [\n 'M6.5 15.5m-3.5 0a3.5 3.5 0 1 0 7 0a3.5 3.5 0 1 0 -7 0',\n 'M14 19v-10.5a3.5 3.5 0 0 1 7 0v10.5',\n 'M14 13h7',\n 'M10 12v7',\n ],\n trash: [\n 'M4 7l16 0',\n 'M10 11l0 6',\n 'M14 11l0 6',\n 'M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12',\n 'M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3',\n ],\n underline: [{ d: 'M4 20h16', stroke: 'primary' }, 'M8 16v-8a4 4 0 1 1 8 0v8', 'M8 10h8'],\n // the v2 ungroup glyph: two separated rounded rects\n ungroup: [\n 'M4 5a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z',\n 'M13 14a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z',\n ],\n unlock: ['M7 11V7a5 5 0 0 1 9.9-1'],\n vertical: ['M8 7l4 -4l4 4', 'M8 17l4 4l4 -4', 'M12 3l0 18'],\n viewSettings: [\n 'M12 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0',\n 'M12 10.5v1.5',\n 'M12 16v1.5',\n 'M15.031 12.25l-1.299 .75',\n 'M10.268 15l-1.3 .75',\n 'M15 15.803l-1.285 -.773',\n 'M10.285 12.97l-1.285 -.773',\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',\n ],\n widgetEdit: [\n 'M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1',\n 'M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415',\n 'M16 5l3 3',\n ],\n x: ['M18 6l-12 12', 'M6 6l12 12'],\n zigzag: [{ d: 'M12 2.4L21.36 11.76L2.64 12.24L12 21.6', stroke: 'primary' }],\n zoomIn: ['M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0', 'M9 12h6', 'M12 9v6'],\n zoomInArea: [\n 'M15 13v4',\n 'M13 15h4',\n 'M15 15m-5 0a5 5 0 1 0 10 0a5 5 0 1 0 -10 0',\n 'M22 22l-3 -3',\n 'M6 18h-1a2 2 0 0 1 -2 -2v-1',\n 'M3 11v-1',\n 'M3 6v-1a2 2 0 0 1 2 -2h1',\n 'M10 3h1',\n 'M15 3h1a2 2 0 0 1 2 2v1',\n ],\n zoomOut: ['M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M9 12l6 0'],\n};\n\nexport type IconName = keyof typeof ICON_PATHS;\n\nexport interface IconProps {\n name: string;\n size?: number;\n strokeWidth?: number;\n className?: string;\n title?: string;\n /** Paints the glyph's slot-tagged sub-paths (a tool previewing its\n * drawing defaults). Absent → the plain, untinted glyph. */\n accent?: IconAccent;\n}\n\n/** One SVG renderer for every icon. Unknown names render nothing (caller shows\n * a text fallback), so a missing glyph never throws. */\nexport function Icon({ name, size = 20, strokeWidth = 2, className, title, accent }: IconProps) {\n // Registry semantics: user icons are additive and a colliding name WINS —\n // re-skinning a built-in glyph is a supported move, not an accident.\n const custom = useCustomIcons();\n const paths = custom[name] ?? ICON_PATHS[name];\n if (!paths) return null;\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n role=\"img\"\n aria-hidden={title ? undefined : true}\n aria-label={title}\n >\n {paths.map((p, i) => {\n if (typeof p === 'string') return <path key={i} d={p} />;\n const fill = p.fill === true ? 'currentColor' : p.fill ? accent?.[p.fill] : undefined;\n // a stroke slot paints from the accent, inheriting currentColor\n // without one; a fill-ONLY path never gets an outline (the v2 look)\n const stroke = p.stroke ? accent?.[p.stroke] : p.fill ? 'none' : undefined;\n return <path key={i} d={p.d} fill={fill ?? 'none'} stroke={stroke} />;\n })}\n </svg>\n );\n}\n\nexport const hasIcon = (name: string): boolean => name in ICON_PATHS;\n","/**\n * Light/dark theme — one class, and the CSS variables in styles.css do the\n * rest (both toolbars, sidebars, popovers, and the canvas re-theme from it).\n * The mode comes from the embedder's `theme` preference; the chrome ships no\n * switch of its own, so a host that wants one drives this through `set`. The\n * class lands on <html> by default; a delivery that must not touch the page\n * (the <embedpdf-viewer> shadow root) passes `target` and the class stays\n * inside its own subtree. An explicit preference outranks the OS setting.\n */\nimport { createContext, useContext, useEffect, useMemo, useState } from 'react';\n\nexport type ThemeMode = 'light' | 'dark';\nexport type ThemePreference = ThemeMode | 'system';\n\nconst ThemeCtx = createContext<{\n mode: ThemeMode;\n toggle: () => void;\n set: (m: ThemeMode) => void;\n} | null>(null);\n\nconst systemMode = (): ThemeMode =>\n typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light';\n\nexport function ThemeProvider({\n children,\n preference = 'system',\n target,\n}: {\n children: React.ReactNode;\n /** Initial mode; 'system' (default) follows the OS setting. */\n preference?: ThemePreference;\n /** Where the `.dark` class goes. Default: document.documentElement. */\n target?: HTMLElement | null;\n}) {\n const [mode, setMode] = useState<ThemeMode>(() =>\n preference === 'system' ? systemMode() : preference,\n );\n useEffect(() => {\n (target ?? document.documentElement).classList.toggle('dark', mode === 'dark');\n }, [mode, target]);\n const value = useMemo(\n () => ({ mode, toggle: () => setMode((m) => (m === 'dark' ? 'light' : 'dark')), set: setMode }),\n [mode],\n );\n return <ThemeCtx.Provider value={value}>{children}</ThemeCtx.Provider>;\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeCtx);\n if (!ctx) throw new Error('useTheme must be used within <ThemeProvider>');\n return ctx;\n}\n","/**\n * Menu rendering — a MenuSchema (a tree of command ids) rendered as rows.\n * Reused by the toolbar dropdowns (document / zoom / page-settings) AND by the\n * overflow menu's inline submenu expansion, so a command's menu form is\n * identical wherever it surfaces. Rows resolve live through the command\n * registry: label, icon, active tick, enabled state.\n */\nimport { useState } from 'react';\nimport { useCommand, useCommands } from '@embedpdf/react/commands';\nimport { useT } from '@embedpdf/react/i18n';\nimport type { MenuSchema } from '@embedpdf/react/toolbar';\nimport { Icon } from './icons';\nimport { useMenuSchema } from '../config-context';\n\nexport function MenuRow({ commandId, onRun }: { commandId: string; onRun?: () => void }) {\n const cmd = useCommand(commandId);\n const commands = useCommands();\n if (!cmd || !cmd.visible) return null;\n return (\n <button\n type=\"button\"\n role={cmd.active ? 'menuitemradio' : 'menuitem'}\n part={cmd.active ? 'menu-item menu-item-active' : 'menu-item'}\n aria-checked={cmd.active || undefined}\n disabled={!cmd.enabled}\n onClick={() => {\n commands.execute(commandId);\n onRun?.();\n }}\n // v2 shows selection as a blue-tinted row (bg-interactive-selected +\n // text-accent), never a checkmark — the icon column stays the command's\n // own icon.\n className={`flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors disabled:pointer-events-none disabled:opacity-40 ${\n cmd.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {cmd.icon && (\n <Icon\n name={cmd.icon}\n size={16}\n accent={cmd.iconAccent}\n className={cmd.active ? '' : 'text-fg-muted'}\n />\n )}\n <span className=\"flex-1 truncate\">{cmd.label}</span>\n </button>\n );\n}\n\n/** One section-separated menu, by schema id. */\nexport function MenuBody({ menuId, onRun }: { menuId: string; onRun?: () => void }) {\n const t = useT();\n const menu: MenuSchema | undefined = useMenuSchema(menuId);\n if (!menu) return null;\n return (\n <div className=\"min-w-52 p-1\">\n {menu.sections.map((section, i) => (\n <div key={i}>\n {i > 0 && <div className=\"bg-border-subtle my-1 h-px\" />}\n {section.labelKey && (\n <div className=\"text-fg-muted px-2.5 pb-1 pt-1.5 text-[11px] font-semibold uppercase tracking-wide\">\n {t(section.labelKey)}\n </div>\n )}\n {section.items.map((id) => (\n <MenuRow key={id} commandId={id} onRun={onRun} />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\n/** The popover shell: a floating surface + click-away scrim. */\nexport function Popover({\n children,\n onClose,\n align = 'start',\n}: {\n children: React.ReactNode;\n onClose: () => void;\n align?: 'start' | 'end';\n}) {\n return (\n <>\n <div className=\"fixed inset-0 z-40\" onClick={onClose} />\n <div\n part=\"menu\"\n className={`border-border-subtle bg-elevated absolute top-full z-50 mt-1 rounded-lg border shadow-xl ${\n align === 'end' ? 'right-0' : 'left-0'\n }`}\n >\n {children}\n </div>\n </>\n );\n}\n\n/** A menu dropdown that expands inline (used inside the overflow menu, where a\n * submenu can't anchor to an off-screen trigger). */\nexport function InlineSubmenu({ menuId, label }: { menuId: string; label: string }) {\n const [open, setOpen] = useState(false);\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className=\"text-fg-secondary hover:bg-hover flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm\"\n >\n <span className=\"flex-1 truncate\">{label}</span>\n <Icon name={open ? 'chevronDown' : 'chevronRight'} size={16} />\n </button>\n {open && (\n <div className=\"border-border-subtle ml-3 border-l pl-1\">\n <MenuBody menuId={menuId} />\n </div>\n )}\n </div>\n );\n}\n","/**\n * The app's toolbar look — Tailwind render props over the headless <Toolbar>.\n * The app owns the pixels; ui-core owns the physics (measure → solve →\n * overflow). Nothing here knows about breakpoints or widths.\n *\n * Styling is a 1:1 port of the v2 snippet's components:\n * Button → viewers/snippet/src/components/ui/button.tsx\n * TabButton → viewers/snippet/src/components/ui/tab-button.tsx (underline)\n * zoom widget → viewers/snippet/src/components/custom-zoom-toolbar.tsx\n * mode select → viewers/snippet/src/components/mode-select-button.tsx\n */\nimport { useEffect, useState } from 'react';\nimport { useOptionalCapability, useOptionalSelector } from '@embedpdf/react/runtime';\nimport { Toolbar } from '@embedpdf/react/toolbar';\nimport type {\n BarSchema,\n CollapsedGroupView,\n GroupDisclosureView,\n OverflowMenuView,\n} from '@embedpdf/react/toolbar';\nimport { useCommands } from '@embedpdf/react/commands';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport { useMenus } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { StageToken } from '@embedpdf/react/stage';\nimport { Icon } from './icons';\nimport { MenuBody, Popover, InlineSubmenu } from './menu';\n\n// ── the v2 Button recipe ──────────────────────────────────────────────────────\nconst BTN_BASE =\n 'flex h-8 w-auto min-w-8 cursor-pointer items-center justify-center rounded-md p-[5px] transition-colors';\nconst BTN_HOVER = 'hover:bg-hover hover:ring hover:ring-accent';\nconst BTN_ACTIVE = 'border-none bg-selected text-accent shadow ring ring-accent';\nconst BTN_DISABLED = 'cursor-not-allowed opacity-50 hover:bg-transparent hover:ring-0';\n\nexport const buttonClass = (active: boolean, enabled = true): string =>\n `${BTN_BASE} ${active ? BTN_ACTIVE : BTN_HOVER} ${enabled ? '' : BTN_DISABLED}`;\n\n// ── the v2 TabButton recipe (the underline) ───────────────────────────────────\nconst TAB_BASE =\n 'flex h-8 w-auto min-w-8 cursor-pointer items-center justify-center rounded-none border-b-2 px-2 py-1 text-sm transition-colors hover:bg-transparent hover:border-b-fg-muted';\nconst TAB_ACTIVE = 'border-b-accent text-accent hover:border-b-accent';\nconst TAB_INACTIVE = 'border-b-transparent';\n\nconst tabClass = (active: boolean, enabled = true): string =>\n `${TAB_BASE} ${active ? TAB_ACTIVE : TAB_INACTIVE} ${enabled ? '' : 'cursor-not-allowed opacity-50'}`;\n\n// ── a single command button (icon / icon+label / label=tab) ──────────────────\nfunction CommandButton({\n cmd,\n variant,\n run,\n}: {\n cmd: ResolvedCommand;\n variant: string;\n run: () => void;\n}) {\n const isTab = variant === 'label';\n\n // v2 buttons carry NO caret — a menu command is a plain icon button; the\n // `menu:` declaration still drives aria-haspopup and the anchored popover.\n const button = (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.active || undefined}\n aria-haspopup={cmd.menu ? 'menu' : undefined}\n aria-label={cmd.label}\n title={cmd.label}\n // Shadow parts — the RESTYLE door: page CSS reaches these via\n // `embedpdf-viewer::part(toolbar-button)` etc. Part names are public\n // API; the vocabulary is deliberately small (see README).\n part={\n isTab\n ? `mode-tab${cmd.active ? ' mode-tab-active' : ''}`\n : `toolbar-button${cmd.active ? ' toolbar-button-active' : ''}`\n }\n className={isTab ? tabClass(cmd.active, cmd.enabled) : buttonClass(cmd.active, cmd.enabled)}\n >\n {isTab ? (\n <span className=\"whitespace-nowrap px-1\">{cmd.label}</span>\n ) : variant === 'icon+label' ? (\n <span className=\"flex items-center whitespace-nowrap text-sm\">\n {cmd.icon && (\n <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} className=\"mr-1.5 shrink-0\" />\n )}\n <span>{cmd.label}</span>\n </span>\n ) : cmd.icon ? (\n <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />\n ) : (\n <span className=\"text-sm\">{cmd.label}</span>\n )}\n </button>\n );\n\n if (!cmd.menu) return button;\n return <MenuAnchoredButton cmd={cmd}>{button}</MenuAnchoredButton>;\n}\n\nfunction MenuAnchoredButton({\n cmd,\n children,\n}: {\n cmd: ResolvedCommand;\n children: React.ReactNode;\n}) {\n const menus = useMenus();\n const open = cmd.menu ? menus.isOpen(cmd.menu) : false;\n return (\n <span className=\"relative inline-flex\">\n {children}\n {open && cmd.menu && (\n <Popover onClose={() => menus.close(cmd.menu!)}>\n <MenuBody menuId={cmd.menu} onRun={() => menus.close(cmd.menu!)} />\n </Popover>\n )}\n </span>\n );\n}\n\n// ── the inline zoom widget — v2's custom-zoom-toolbar, 1:1 ───────────────────\nfunction ZoomControls() {\n const commands = useCommands();\n const menus = useMenus();\n const stage = useOptionalCapability(StageToken);\n // Null-safe: the zoom strip is main-toolbar chrome, mounted before any\n // document exists — it reads 100% until a Stage is there to ask.\n const level = useOptionalSelector(StageToken, (c) => c.zoomLevel(), 1);\n const pct = Math.round((level ?? 1) * 100);\n const [inputValue, setInputValue] = useState(String(pct));\n useEffect(() => setInputValue(String(pct)), [pct]);\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n const value = parseFloat(inputValue);\n if (!isNaN(value) && value > 0) stage?.zoomTo({ level: value / 100 });\n };\n\n return (\n <div className=\"relative\">\n <div className=\"bg-hover flex items-center rounded\">\n {/* editable zoom percentage */}\n <form\n onSubmit={submit}\n className=\"flex min-w-0 flex-nowrap items-center overflow-hidden whitespace-nowrap\"\n >\n <input\n name=\"zoom\"\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"\\d*\"\n aria-label=\"Set zoom\"\n className=\"h-6 w-8 min-w-0 shrink border-0 bg-transparent p-0 text-right text-sm outline-none focus:outline-none\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value.replace(/[^0-9]/g, ''))}\n onBlur={() => {\n if (!inputValue || parseFloat(inputValue) <= 0) setInputValue(String(pct));\n }}\n />\n <span className=\"shrink-0 text-sm\">%</span>\n </form>\n {/* zoom menu chevron */}\n <button\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-expanded={menus.isOpen('zoom')}\n title=\"Zoom options\"\n className={buttonClass(false)}\n onClick={() => menus.toggle('zoom')}\n >\n <Icon name=\"chevronDown\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Zoom out\"\n className={buttonClass(false)}\n onClick={() => commands.execute('zoom:out')}\n >\n <Icon name=\"zoomOut\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Zoom in\"\n className={buttonClass(false)}\n onClick={() => commands.execute('zoom:in')}\n >\n <Icon name=\"zoomIn\" size={20} />\n </button>\n </div>\n {menus.isOpen('zoom') && (\n <Popover onClose={() => menus.close('zoom')}>\n <MenuBody menuId=\"zoom\" onRun={() => menus.close('zoom')} />\n </Popover>\n )}\n </div>\n );\n}\n\n/** The 'button' variant of the zoom slot — a single icon that opens the menu. */\nfunction ZoomButton() {\n const menus = useMenus();\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n title=\"Zoom\"\n aria-haspopup=\"menu\"\n aria-expanded={menus.isOpen('zoom')}\n className={buttonClass(menus.isOpen('zoom'))}\n onClick={() => menus.toggle('zoom')}\n >\n <Icon name=\"zoomIn\" size={20} />\n </button>\n {menus.isOpen('zoom') && (\n <Popover onClose={() => menus.close('zoom')}>\n <MenuBody menuId=\"zoom\" onRun={() => menus.close('zoom')} />\n </Popover>\n )}\n </span>\n );\n}\n\n// ── a shed group's in-strip disclosure (v2's overflow-tabs-button, derived) ──\nfunction GroupTrigger({ view }: { view: GroupDisclosureView }) {\n const [open, setOpen] = useState(false);\n // The active tab may be hiding behind the chevron — hint at it, tab-style.\n const activeHidden = view.commands.some((c) => c.active);\n return (\n <span className=\"relative inline-flex\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className={tabClass(activeHidden)}\n >\n <Icon name=\"chevronDown\" size={18} />\n </button>\n {open && (\n <Popover onClose={() => setOpen(false)}>\n <div className=\"min-w-44 p-1\">\n {view.commands.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n role={view.role === 'tabs' ? 'menuitemradio' : 'menuitem'}\n aria-checked={view.role === 'tabs' ? c.active : undefined}\n disabled={!c.enabled}\n onClick={() => {\n view.execute(c.id);\n setOpen(false);\n }}\n className={`flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm disabled:cursor-not-allowed disabled:opacity-50 ${\n c.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {c.label}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </span>\n );\n}\n\n// ── the collapsed modes group — v2's mode-select-button, 1:1 ─────────────────\nfunction CollapsedModes({ view }: { view: CollapsedGroupView }) {\n const [open, setOpen] = useState(false);\n const active = view.commands.find((c) => c.active) ?? view.commands[0];\n // v2 highlights the control whenever a non-default mode is active.\n const isActive = Boolean(active?.active && active.id !== 'mode:view');\n return (\n <div style={{ width: 100 }} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className=\"bg-surface hover:bg-hover flex w-full cursor-pointer appearance-none items-center rounded-md py-1.5 pl-3 pr-2 text-[13px] transition-colors\"\n >\n <span\n className={`min-w-0 flex-1 truncate text-left ${isActive ? 'text-accent' : 'text-fg'}`}\n >\n {active?.label}\n </span>\n <Icon\n name=\"chevronDown\"\n size={16}\n className={isActive ? 'text-accent' : 'text-fg-secondary'}\n />\n </button>\n {open && (\n <Popover onClose={() => setOpen(false)}>\n <div className=\"min-w-44 p-1\">\n {view.commands.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={c.active}\n onClick={() => {\n view.execute(c.id);\n setOpen(false);\n }}\n className={`flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm ${\n c.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {c.label}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </div>\n );\n}\n\n// ── the derived overflow menu ────────────────────────────────────────────────\nfunction OverflowMenu({ view }: { view: OverflowMenuView }) {\n const t = useT();\n if (!view.isOpen) return null;\n return (\n <Popover onClose={view.close} align=\"end\">\n <div className=\"min-w-56 p-1\">\n {view.sections.map((section, i) => (\n <div key={i}>\n {i > 0 && <div className=\"bg-border-subtle my-1 h-px\" />}\n {section.labelKey && (\n <div className=\"text-fg-muted px-2.5 pb-1 pt-1.5 text-[11px] font-semibold uppercase tracking-wide\">\n {t(section.labelKey)}\n </div>\n )}\n {section.rows.map((row) => {\n const cmd = view.resolve(row.command);\n if (!cmd) return null;\n if (row.type === 'submenu') {\n return <InlineSubmenu key={row.command} menuId={row.menu} label={cmd.label} />;\n }\n return (\n <button\n key={row.command}\n type=\"button\"\n role={section.role === 'radio' ? 'menuitemradio' : 'menuitem'}\n aria-checked={section.role === 'radio' ? cmd.active : undefined}\n disabled={!cmd.enabled}\n onClick={() => {\n view.execute(row.command);\n view.close();\n }}\n // Same blue-highlight selection as the dropdown menus — no\n // checkmark; the icon column stays the command's own icon.\n className={`flex w-full items-center gap-3 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${\n cmd.active ? 'bg-selected text-accent' : 'text-fg-secondary hover:bg-hover'\n }`}\n >\n {cmd.icon && (\n <Icon name={cmd.icon} size={16} className={cmd.active ? '' : 'text-fg-muted'} />\n )}\n <span className=\"flex-1 truncate\">{cmd.label}</span>\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </Popover>\n );\n}\n\nfunction OverflowTrigger({ isOpen, toggle }: { isOpen: boolean; toggle: () => void }) {\n const t = useT();\n return (\n <button\n type=\"button\"\n onClick={toggle}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen}\n title={t('demo.more')}\n className={buttonClass(isOpen)}\n >\n <Icon name=\"dots\" size={20} />\n </button>\n );\n}\n\n// ── the assembled toolbar ────────────────────────────────────────────────────\nexport function AppToolbar({ bar, className }: { bar: BarSchema; className?: string }) {\n return (\n <Toolbar\n bar={bar}\n gap={8} // v2 toolbar gap-2\n separatorWidth={1}\n className={className}\n renderCommand={(cmd, variant, run) => <CommandButton cmd={cmd} variant={variant} run={run} />}\n renderCustom={{\n 'zoom-controls': (variant) => (variant === 'inline' ? <ZoomControls /> : <ZoomButton />),\n }}\n renderCollapsed={(view) => (view.id === 'modes' ? <CollapsedModes view={view} /> : undefined)}\n renderGroupTrigger={(view) => <GroupTrigger view={view} />}\n renderSeparator={() => <span className=\"bg-border h-6 w-px self-center\" />}\n renderOverflowTrigger={(isOpen, toggle) => (\n <OverflowTrigger isOpen={isOpen} toggle={toggle} />\n )}\n renderOverflowMenu={(view) => <OverflowMenu view={view} />}\n />\n );\n}\n","/**\n * The link editor POPOVER — v2's \"add a link\" popup, reborn. It rides the\n * SAME selection anchor as the action strip (`<AnnotationMenu>` solves\n * WHERE), opening from the strip's link icon (`annotation:link` toggles the\n * `link-editor` shell surface) and rendering IN PLACE of the strip while\n * open — one anchored card at a time.\n *\n * Reads the selection's current target from selection props (the `linkOf`\n * lens — parents derive from their committed child annotations) and writes\n * through the ONE `updateSelection({ link })` path; the plugin's reconciler\n * materializes/retargets the attached children. Links are a VERB on the\n * selection, not a style — which is why this is a popover, not a sidebar\n * section.\n */\nimport { useState, type ReactNode } from 'react';\nimport { useAnnotation, useSelectionProps } from '@embedpdf/react/annotation';\nimport type { PdfLinkTarget } from '@embedpdf/react/link';\nimport { useKernel } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\nfunction ModeToggle({\n active,\n title,\n onClick,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n className={`rounded border px-2.5 py-1 text-xs font-medium transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\nexport function LinkEditorCard({ onClose }: { onClose: () => void }) {\n const t = useT();\n const kernel = useKernel();\n const anno = useAnnotation();\n const props = useSelectionProps();\n const value = (props.values.link ?? null) as PdfLinkTarget | null;\n const [mode, setMode] = useState<'uri' | 'page'>(value?.kind === 'goto' ? 'page' : 'uri');\n const [uri, setUri] = useState(value?.kind === 'uri' ? value.uri : '');\n const [pageNo, setPageNo] = useState('1');\n\n const apply = () => {\n if (mode === 'uri') {\n const trimmed = uri.trim();\n if (!trimmed) return;\n anno.updateSelection({ link: { kind: 'uri', uri: trimmed } });\n onClose();\n return;\n }\n // Page number (1-based) → the page's OBJECT NUMBER (stable across moves).\n const activeId = kernel.documents.activeId();\n const meta = activeId ? kernel.getState().core.documents[activeId] : null;\n const layout = meta?.pages[Math.max(0, Number(pageNo) - 1)];\n if (!layout) return;\n anno.updateSelection({\n link: { kind: 'goto', destination: { kind: 'fit', pageObjectNumber: layout.pageObjectNumber } },\n });\n onClose();\n };\n\n const inputCls =\n 'border-border bg-surface text-fg focus:border-accent w-full rounded border px-2.5 py-1.5 text-sm outline-none';\n return (\n <div className=\"border-border bg-surface w-64 rounded-lg border p-3 shadow-lg\">\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-fg text-sm font-semibold\">{t('commands.annotate.link')}</span>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-fg-muted hover:bg-hover grid h-6 w-6 place-items-center rounded\"\n >\n <Icon name=\"x\" size={14} />\n </button>\n </div>\n <div className=\"mb-2 flex gap-1.5\">\n <ModeToggle title=\"Link to a URL\" active={mode === 'uri'} onClick={() => setMode('uri')}>\n URL\n </ModeToggle>\n <ModeToggle title=\"Link to a page\" active={mode === 'page'} onClick={() => setMode('page')}>\n Page\n </ModeToggle>\n </div>\n {mode === 'uri' ? (\n <input\n type=\"url\"\n className={inputCls}\n placeholder=\"https://…\"\n autoFocus\n value={uri}\n onChange={(e) => setUri(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && apply()}\n />\n ) : (\n <input\n type=\"number\"\n min={1}\n className={inputCls}\n placeholder=\"Page number\"\n autoFocus\n value={pageNo}\n onChange={(e) => setPageNo(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && apply()}\n />\n )}\n <button\n type=\"button\"\n className=\"bg-accent text-on-accent mt-2.5 w-full rounded px-2 py-1.5 text-sm font-medium\"\n onClick={apply}\n >\n {value == null ? 'Add link' : 'Update link'}\n </button>\n </div>\n );\n}\n","/**\n * The floating strip's PIXELS, shared by every contextual strip (annotation\n * selection, text selection, …): a rounded toolbar of command buttons with\n * derived group separators. The WHERE is each strip's menu component\n * (`<AnnotationMenu>`, `<SelectionMenu>`); the WHICH is the commands'\n * `visible`/`enabled` derivations via `useStripView`. This file only draws.\n */\nimport { Fragment } from 'react';\nimport type { ResolvedCommand } from '@embedpdf/react/commands';\nimport type { useStripView } from '@embedpdf/react/toolbar';\nimport { buttonClass } from './toolbar';\nimport { Icon } from './icons';\n\nfunction StripButton({ cmd, run }: { cmd: ResolvedCommand; run: () => void }) {\n return (\n <button\n type=\"button\"\n onClick={run}\n disabled={!cmd.enabled}\n aria-pressed={cmd.active || undefined}\n aria-label={cmd.label}\n title={cmd.label}\n className={buttonClass(cmd.active, cmd.enabled)}\n >\n {cmd.icon && <Icon name={cmd.icon} size={20} accent={cmd.iconAccent} />}\n </button>\n );\n}\n\nexport function StripBar({\n view,\n label,\n}: {\n view: NonNullable<ReturnType<typeof useStripView>>;\n label: string;\n}) {\n return (\n <div\n role=\"toolbar\"\n aria-label={label}\n className=\"border-border-subtle bg-elevated flex items-center gap-1 rounded-lg border p-1 shadow-xl\"\n >\n {view.groups.map((g, i) => (\n <Fragment key={g.id}>\n {i > 0 && <span aria-hidden className=\"bg-border h-5 w-px\" />}\n {g.commands.map((cmd) => (\n <StripButton key={cmd.id} cmd={cmd} run={() => view.execute(cmd.id)} />\n ))}\n </Fragment>\n ))}\n </div>\n );\n}\n","/**\n * The ANNOTATION-selection floating strip:\n *\n * config/chrome.ts `strips.annotation` declares WHAT may appear\n * each command's visible/enabled decides WHICH items show\n * <AnnotationMenu> solves WHERE (camera transform,\n * rotate-knob dodging, pointer isolation)\n *\n * useStripView is the live intersection: hidden commands drop out, empty\n * groups vanish, null when nothing applies. Mounted in the Stage `overlay`\n * slot. The pixels are the shared <StripBar>.\n */\nimport { useEffect } from 'react';\nimport { AnnotationMenu } from '@embedpdf/react/annotation-menu';\nimport { useAnnotationSelection } from '@embedpdf/react/annotation';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStripSchema } from '../config-context';\nimport { LinkEditorCard } from './link-editor';\nimport { StripBar } from './strip-bar';\n\nexport function AnnotationStrip() {\n const t = useT();\n const view = useStripView(useStripSchema('annotation'));\n // The link editor popover rides the SAME anchor and REPLACES the strip\n // while open — one anchored card at a time (v2's popup, on the projector).\n const editor = useSurface('link-editor');\n const selection = useAnnotationSelection();\n // A stale editor never outlives its selection.\n useEffect(() => {\n if (!selection.length && editor.isOpen) editor.close();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selection.length, editor.isOpen]);\n if (!view) return null;\n return (\n <AnnotationMenu placement=\"bottom\" gap={15}>\n {editor.isOpen ? (\n <LinkEditorCard onClose={editor.close} />\n ) : (\n <StripBar view={view} label={t('commands.annotate.strip')} />\n )}\n </AnnotationMenu>\n );\n}\n","/**\n * The TEXT-SELECTION floating strip:\n *\n * config/chrome.ts `strips.selection` declares WHAT may appear\n * each command's visible/enabled decides WHICH items show\n * <SelectionMenu> solves WHERE (settles on pointer-up,\n * camera transform, pointer isolation)\n *\n * `useStripView` is the live intersection: with copy denied (no\n * doc.text.copy) every command drops out and this renders nothing — no\n * empty bubble. Mounted in the Stage `overlay` slot.\n */\nimport { SelectionMenu } from '@embedpdf/react/selection';\nimport { useStripView } from '@embedpdf/react/toolbar';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useStripSchema } from '../config-context';\nimport { StripBar } from './strip-bar';\n\nexport function SelectionStrip() {\n const t = useT();\n const view = useStripView(useStripSchema('selection'));\n if (!view) return null;\n return (\n <SelectionMenu placement=\"bottom\" gap={12}>\n <StripBar view={view} label={t('commands.selection.strip')} />\n </SelectionMenu>\n );\n}\n","/**\n * The document tab bar — a 1:1 port of v2's tab-bar.tsx\n * (viewers/snippet/src/components/tab-bar.tsx): rounded-top tabs on the\n * surface-alt strip, the active tab merging into the toolbar surface below,\n * close-× on the active tab, and a + button opening a real file dialog.\n *\n * v2 needed a DocumentManager capability; here the kernel's document registry\n * (useDocuments) already is the tab model — open/close/setActive, reactive.\n */\nimport { useRef } from 'react';\nimport { useDocuments } from '@embedpdf/react/runtime';\nimport type { OpenInput } from '@embedpdf/react/runtime';\nimport { Icon } from './icons';\n\nexport type TabBarVisibility = 'always' | 'multiple' | 'never';\n\nexport function TabBar({\n visibility = 'always',\n allowOpenFile = true,\n}: {\n visibility?: TabBarVisibility;\n allowOpenFile?: boolean;\n}) {\n const { docs, activeId, setActive, close, open } = useDocuments();\n const fileInput = useRef<HTMLInputElement>(null);\n\n const shouldShow = visibility === 'always' || (visibility === 'multiple' && docs.length > 1);\n if (!shouldShow) return null;\n\n const openFile = async (file: File) => {\n const bytes = new Uint8Array(await file.arrayBuffer());\n const source: OpenInput = { kind: 'bytes', id: `${file.name}-${Date.now()}`, bytes };\n await open(source, { name: file.name });\n };\n\n return (\n <div className=\"bg-surface-alt flex items-end pr-2 pt-2\">\n <div className=\"flex flex-1 items-end overflow-x-auto pl-4\">\n {docs.map((doc) => {\n const isActive = activeId === doc.id;\n return (\n <div\n key={doc.id}\n onClick={() => setActive(doc.id)}\n role=\"tab\"\n part={isActive ? 'tab tab-active' : 'tab'}\n tabIndex={0}\n aria-selected={isActive}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setActive(doc.id);\n }\n }}\n className={`group relative flex min-w-[120px] max-w-[240px] cursor-pointer items-center gap-2 rounded-t-lg px-4 py-2 text-sm font-medium transition-all ${\n isActive\n ? 'bg-surface text-fg z-10'\n : 'bg-surface-alt text-fg-secondary hover:bg-hover hover:text-fg'\n }`}\n >\n {/* lifecycle glyphs — the tab exists from the moment open()\n was called; these show what its document is doing */}\n {doc.status === 'loading' && (\n <span\n className=\"border-border-subtle border-t-accent h-3 w-3 flex-shrink-0 animate-spin rounded-full border\"\n aria-label=\"Loading\"\n />\n )}\n {doc.status === 'locked' && (\n <Icon name=\"lock\" size={13} className=\"text-fg-muted flex-shrink-0\" />\n )}\n {doc.status === 'error' && (\n <Icon name=\"alertTriangle\" size={13} className=\"flex-shrink-0 text-red-500\" />\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {doc.name ?? `Document ${doc.id.slice(0, 8)}`}\n </span>\n\n {/* close — on the active tab, and never the last document\n (an empty workspace is designable, but not this demo's goal) */}\n {isActive && docs.length > 1 && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void close(doc.id);\n }}\n aria-label={`Close ${doc.name ?? 'document'}`}\n className=\"hover:bg-hover flex-shrink-0 cursor-pointer rounded-full p-1 opacity-100 transition-all\"\n >\n <Icon name=\"x\" size={14} />\n </button>\n )}\n </div>\n );\n })}\n\n {allowOpenFile && (\n <>\n <button\n type=\"button\"\n onClick={() => fileInput.current?.click()}\n aria-label=\"Open File\"\n title=\"Open File\"\n className=\"text-fg-secondary hover:bg-hover hover:text-fg mb-1.5 ml-1 flex-shrink-0 cursor-pointer rounded p-1.5 transition-colors\"\n >\n <Icon name=\"plus\" size={14} />\n </button>\n <input\n ref={fileInput}\n type=\"file\"\n accept=\".pdf,application/pdf\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) void openFile(file);\n e.target.value = '';\n }}\n />\n </>\n )}\n </div>\n </div>\n );\n}\n","/**\n * THIS viewer's armed-tool cursor: the toolbar's own icon riding the pointer\n * as a real CSS cursor (OS-composited — zero lag, unlike any DOM follower).\n * The library owns arbitration (unmapped hover claims win, page gaps fall\n * back to the arrow — see `useToolCursor`); this module only decides what the\n * cursor LOOKS like. It reuses the SAME icon set and the SAME accent\n * derivation as the toolbar buttons (TOOL_ICONS is recorded by the command\n * definitions), so the cursor is pixel-identical to the button the user just\n * pressed — recolor the tool and both follow. A tool without a command icon\n * keeps its declared keyword cursor.\n *\n * ONE table decides the shape ({@link GLYPHS}): cursor KEYWORDS are the\n * affordances — a tool declares its base ('crosshair' to draw, 'copy' to\n * place), the selection handler claims 'text' over text — and each mapped\n * keyword is redrawn as its glyph + the tool's icon. Keywords the table omits\n * stay native: a markup tool's 'default' base is the bare arrow (identity\n * appears exactly where the action is possible — over text), a foreign 'move'\n * over an annotation drops the icon. A new tool gets the right cursor from\n * what it declares; nothing tool-specific lives here.\n *\n * The image: a white-haloed glyph at the hotspot (readable on any page color)\n * with the icon at its top right — 40px, under the 128px cursor ceiling;\n * Chromium may briefly show the default arrow when a >32px cursor would\n * overlap browser UI (anti-spoofing), which is fine mid-viewport.\n */\nimport { useToolCursor, useTool } from '@embedpdf/react/interaction';\nimport { useAnnotationDefaults } from '@embedpdf/react/annotation';\nimport { TOOL_ICONS } from '../config/commands';\nimport { ICON_PATHS } from './icons';\nimport type { IconAccent } from './icons';\n\nconst SIZE = 40;\nconst HOTSPOT = { x: 8, y: 28 };\nconst INK = '#1a1a1a';\nconst HALO = '#ffffff';\n/** The drag-and-drop \"will place a copy\" green (Chrome's DnD badge). */\nconst PLACE_GREEN = '#34a853';\n\n/** The icon's paths as SVG markup — the string twin of `<Icon>`'s render loop\n * (same fill/stroke slot rules), with a white halo pass underneath so the\n * glyph stays readable over page content. */\nfunction iconGlyph(name: string, accent?: IconAccent): string | null {\n const paths = ICON_PATHS[name];\n if (!paths) return null;\n const halo: string[] = [];\n const draw: string[] = [];\n for (const p of paths) {\n const spec = typeof p === 'string' ? { d: p, fill: undefined, stroke: undefined } : p;\n // Slot rules, mirrored from <Icon>: a fill slot paints from the accent\n // (nothing without one), a stroke slot falls back to the ink, and a\n // fill-only path never gets an outline.\n const fill = spec.fill === true ? INK : spec.fill ? accent?.[spec.fill] : undefined;\n const stroke = spec.stroke ? (accent?.[spec.stroke] ?? INK) : spec.fill ? 'none' : INK;\n halo.push(`<path d=\"${spec.d}\" fill=\"none\" stroke=\"${HALO}\" stroke-width=\"3.5\"/>`);\n draw.push(`<path d=\"${spec.d}\" fill=\"${fill ?? 'none'}\" stroke=\"${stroke}\"/>`);\n }\n return halo.join('') + draw.join('');\n}\n\n/** The action glyph drawn at the hotspot: what a click DOES here. */\ntype Glyph = 'crosshair' | 'ibeam' | 'plus';\n\nconst haloed = (x1: number, y1: number, x2: number, y2: number): string =>\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${HALO}\" stroke-width=\"3\"/>` +\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${INK}\" stroke-width=\"1.25\"/>`;\n\nfunction actionGlyph(glyph: Glyph): string {\n const { x, y } = HOTSPOT;\n if (glyph === 'crosshair') {\n return haloed(x, y - 6, x, y + 6) + haloed(x - 6, y, x + 6, y);\n }\n if (glyph === 'ibeam') {\n return (\n haloed(x, y - 6.5, x, y + 6.5) +\n haloed(x - 2.5, y - 6.5, x + 2.5, y - 6.5) +\n haloed(x - 2.5, y + 6.5, x + 2.5, y + 6.5)\n );\n }\n // plus: the DnD copy affordance — green disc, white plus.\n return (\n `<circle cx=\"${x}\" cy=\"${y}\" r=\"7.5\" fill=\"${PLACE_GREEN}\" stroke=\"${HALO}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${x}\" y1=\"${y - 3.5}\" x2=\"${x}\" y2=\"${y + 3.5}\" stroke=\"${HALO}\" stroke-width=\"2\"/>` +\n `<line x1=\"${x - 3.5}\" y1=\"${y}\" x2=\"${x + 3.5}\" y2=\"${y}\" stroke=\"${HALO}\" stroke-width=\"2\"/>`\n );\n}\n\nfunction cursorSvg(glyph: Glyph, icon: string, accent?: IconAccent): string {\n const g = iconGlyph(icon, accent);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${SIZE}\" height=\"${SIZE}\" ` +\n `viewBox=\"0 0 ${SIZE} ${SIZE}\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">` +\n actionGlyph(glyph) +\n (g\n ? `<g transform=\"translate(17 3) scale(${(20 / 24).toFixed(4)})\" stroke-width=\"2\">${g}</g>`\n : '') +\n `</svg>`\n );\n}\n\n/** keyword → glyph: how each affordance is drawn when a tool icon rides\n * along. Draw tools declare 'crosshair', place tools (stamp/signature/image)\n * declare 'copy', and the selection handler claims 'text' over text — which\n * keywords ever SHOW is decided by those declarations and claims, never\n * here. 'default' is deliberately absent: the bare arrow means \"no action\n * here\", so it never carries an icon. */\nconst GLYPHS: Record<string, Glyph> = {\n crosshair: 'crosshair',\n text: 'ibeam',\n copy: 'plus',\n};\n\n/** Mount once (renders nothing): keeps the armed tool's cursor skin in sync\n * with its toolbar icon + live defaults. */\nexport function ArmedToolCursor() {\n const { activeToolId } = useTool();\n // Live accent: a `setDefaults` recolor re-renders us and rebuilds the cursor.\n const d = useAnnotationDefaults(activeToolId);\n const entry = TOOL_ICONS[activeToolId];\n const accent = entry?.accent\n ? {\n primary: d[entry.accent.primary] ?? undefined,\n secondary: entry.accent.secondary ? (d[entry.accent.secondary] ?? undefined) : undefined,\n }\n : undefined;\n useToolCursor(\n entry\n ? {\n toolId: activeToolId,\n cursors: Object.fromEntries(\n Object.entries(GLYPHS).map(([keyword, glyph]) => [\n keyword,\n { svg: cursorSvg(glyph, entry.icon, accent), hotspot: HOTSPOT },\n ]),\n ),\n }\n : null,\n );\n return null;\n}\n","/**\n * The annotation FLAGS section — a live test surface for `/F` (ISO 32000\n * Table 167). Select any annotation(s) and toggle flags; the writes go through\n * the plugin's `updateSelectionFlags` (optimistic, flags-only engine patch),\n * and the reads come from `useSelectionFlags` (per-flag value, `null` when the\n * selection disagrees → indeterminate checkbox).\n *\n * Things to try:\n * - `locked`: the selection keeps its outline but loses handles/knob; move,\n * restyle and delete are refused; unchecking it here still works.\n * - `hidden` / `noView`: the annotation disappears (it stays selected, so\n * this panel can bring it back).\n * - `readOnly`: visible but no longer clickable — deselect and try.\n * - `noZoom` / `noRotate`: zoom or rotate the page; the body keeps its\n * screen size / stays upright, anchored at its top-left corner.\n * - `print`: flip it off and print/flatten elsewhere — the annotation is\n * excluded (viewer rendering is unaffected).\n */\nimport { useAnnotation, useSelectionFlags, type AnnotationFlags } from '@embedpdf/react/annotation';\nimport { useEffect, useRef } from 'react';\n\nconst FLAG_ROWS: { key: keyof AnnotationFlags; label: string; hint: string }[] = [\n { key: 'print', label: 'Print', hint: 'Include when the page is printed' },\n { key: 'hidden', label: 'Hidden', hint: 'Gone everywhere: screen, clicks, print' },\n { key: 'noView', label: 'No view', hint: 'Hidden on screen, may still print' },\n {\n key: 'toggleNoView',\n label: 'Toggle no view',\n hint: 'Reveal a no-view annotation while selected',\n },\n { key: 'readOnly', label: 'Read only', hint: 'Visible but not clickable' },\n { key: 'locked', label: 'Locked', hint: 'No move / resize / delete / restyle' },\n { key: 'lockedContents', label: 'Locked contents', hint: 'Text cannot change; geometry can' },\n { key: 'noZoom', label: 'No zoom', hint: 'Screen-constant size (anchored top-left)' },\n { key: 'noRotate', label: 'No rotate', hint: 'Stays upright when the page rotates' },\n { key: 'invisible', label: 'Invisible', hint: 'Legacy: hide unknown subtypes' },\n];\n\nfunction FlagRow({\n label,\n hint,\n value,\n onToggle,\n}: {\n label: string;\n hint: string;\n value: boolean | null;\n onToggle: (next: boolean) => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n // `null` = the selected annotations disagree → the native indeterminate state.\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = value === null;\n }, [value]);\n return (\n <label className=\"hover:bg-hover flex cursor-pointer items-start gap-2.5 rounded px-1.5 py-1.5\">\n <input\n ref={ref}\n type=\"checkbox\"\n className=\"accent-accent mt-0.5\"\n checked={value === true}\n onChange={() => onToggle(value !== true)}\n />\n <span className=\"min-w-0\">\n <span className=\"text-fg block text-sm leading-tight\">{label}</span>\n <span className=\"text-fg-muted block text-xs leading-tight\">{hint}</span>\n </span>\n </label>\n );\n}\n\n/** The `/F` flags of the current selection, live-editable. Renders nothing\n * when nothing is selected (the style panel shows its tool defaults then). */\nexport function AnnotationFlagsSection() {\n const annotation = useAnnotation();\n const flags = useSelectionFlags();\n if (!flags) return null;\n return (\n <section className=\"border-border mt-2 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n Flags (/F)\n </p>\n <div className=\"flex flex-col\">\n {FLAG_ROWS.map((row) => (\n <FlagRow\n key={row.key}\n label={row.label}\n hint={row.hint}\n value={flags[row.key]}\n onToggle={(next) => annotation.updateSelectionFlags({ [row.key]: next })}\n />\n ))}\n </div>\n </section>\n );\n}\n","/**\n * The annotation style panel — the v2 snippet's style sidebar, rebuilt the v3\n * way. The plugin owns the schema AND the state; this file owns only how each\n * PropSpec renders and the flat patch it writes back. There is NO per-subtype\n * branching here: a new annotation kind that declares its `PropSpec[]` in the\n * kind table gets a working style panel for free.\n *\n * Data flow (mirrors examples/react's AnnotationSidebar):\n * selection present → useSelectionProps() specs/values, write updateSelection()\n * nothing selected → propsForTool(tool) specs + useAnnotationDefaults(tool)\n * values, write setDefaults(tool, …)\n *\n * The look is ported 1:1 from viewers/snippet's annotation-sidebar (six-column\n * swatch grid, range slider, SVG stroke / line-ending dropdowns, font-size\n * combo, align toggles), retinted from v2's `bg-bg-input`/`text-fg-primary`\n * tokens to this app's semantic ones (bg-surface / text-fg / border-border …).\n */\nimport { useEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport {\n useAnnotation,\n useSelectionProps,\n useAnnotationDefaults,\n useAnnotationSelected,\n type PropSpec,\n type AnnotationPropsPatch,\n type Border,\n type BlendMode,\n type LineEnding,\n type LineEndings,\n type TextAlign,\n} from '@embedpdf/react/annotation';\nimport { useTool } from '@embedpdf/react/interaction';\nimport { useOptionalCapability } from '@embedpdf/react/runtime';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { AnnotationFlagsSection } from './annotation-flags';\n\n// ── app-level vocabulary (a viewer's decision, like v2's color presets) ──────\n// The engine schema says WHICH controls to show; these lists say what the app\n// offers inside a color / font / stroke picker.\nconst PRESET_COLORS = [\n '#000000',\n '#5f6368',\n '#e44234',\n '#ff8b00',\n '#ffd500',\n '#00cc66',\n '#00b8d9',\n '#4a90e2',\n '#9b51e0',\n '#f272c8',\n '#a0522d',\n '#ffffff',\n];\n\nconst FONT_OPTIONS: { v: string; label: string }[] = [\n { v: 'helvetica', label: 'Helvetica' },\n { v: 'helvetica-bold', label: 'Helvetica Bold' },\n { v: 'times-roman', label: 'Times Roman' },\n { v: 'courier', label: 'Courier' },\n];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 24, 36, 48, 72];\n\nconst BORDER_OPTS: { key: string; make: () => Border }[] = [\n { key: 'solid', make: () => ({ kind: 'solid' }) },\n { key: 'dashed-6-2', make: () => ({ kind: 'dashed', dash: [6, 2] }) },\n { key: 'dashed-3-3', make: () => ({ kind: 'dashed', dash: [3, 3] }) },\n { key: 'dashed-1-2', make: () => ({ kind: 'dashed', dash: [1, 2] }) },\n { key: 'cloudy-1', make: () => ({ kind: 'cloudy', intensity: 1 }) },\n { key: 'cloudy-2', make: () => ({ kind: 'cloudy', intensity: 2 }) },\n];\nconst borderKey = (b: Border): string =>\n b.kind === 'cloudy'\n ? `cloudy-${b.intensity >= 2 ? 2 : 1}`\n : b.kind === 'dashed'\n ? `dashed-${b.dash.join('-')}`\n : 'solid';\n\nconst LINE_ENDINGS: { v: LineEnding; label: string }[] = [\n { v: 'none', label: 'None' },\n { v: 'open-arrow', label: 'Open arrow' },\n { v: 'closed-arrow', label: 'Closed arrow' },\n { v: 'r-open-arrow', label: 'Reverse open' },\n { v: 'r-closed-arrow', label: 'Reverse closed' },\n { v: 'circle', label: 'Circle' },\n { v: 'square', label: 'Square' },\n { v: 'diamond', label: 'Diamond' },\n { v: 'butt', label: 'Butt' },\n { v: 'slash', label: 'Slash' },\n];\n\nconst BLEND_MODES: { v: BlendMode; label: string }[] = [\n { v: 'normal', label: 'Normal' },\n { v: 'multiply', label: 'Multiply' },\n { v: 'screen', label: 'Screen' },\n { v: 'overlay', label: 'Overlay' },\n { v: 'darken', label: 'Darken' },\n { v: 'lighten', label: 'Lighten' },\n { v: 'color-dodge', label: 'Color Dodge' },\n { v: 'color-burn', label: 'Color Burn' },\n { v: 'hard-light', label: 'Hard Light' },\n { v: 'soft-light', label: 'Soft Light' },\n { v: 'difference', label: 'Difference' },\n { v: 'exclusion', label: 'Exclusion' },\n { v: 'hue', label: 'Hue' },\n { v: 'saturation', label: 'Saturation' },\n { v: 'color', label: 'Color' },\n { v: 'luminosity', label: 'Luminosity' },\n];\n\n// ── layout primitives ────────────────────────────────────────────────────────\nfunction Field({\n label,\n mixed,\n children,\n}: {\n label: string;\n mixed?: boolean;\n children: ReactNode;\n}) {\n return (\n <section className=\"mb-5\">\n <label className=\"text-fg mb-2 block text-sm font-medium\">\n {label}\n {mixed && <span className=\"text-fg-muted ml-1.5 text-xs font-normal\">(mixed)</span>}\n </label>\n {children}\n </section>\n );\n}\n\n// ── color swatch grid ────────────────────────────────────────────────────────\nconst isTransparent = (c: string | null) =>\n c == null ||\n c === 'transparent' ||\n (/^#([0-9a-f]{8})$/i.test(c) && c.slice(-2).toLowerCase() === '00');\n\nfunction Swatch({\n color,\n active,\n onSelect,\n}: {\n color: string;\n active: boolean;\n onSelect: (c: string) => void;\n}) {\n const style = isTransparent(color)\n ? {\n backgroundColor: '#fff',\n backgroundImage:\n 'linear-gradient(45deg, transparent 40%, #ef4444 40%, #ef4444 60%, transparent 60%)',\n backgroundSize: '100% 100%',\n }\n : { backgroundColor: color };\n return (\n <button\n type=\"button\"\n title={color}\n onClick={() => onSelect(color)}\n className={`border-border-strong h-5 w-5 rounded-full border ${active ? 'outline-accent outline outline-2 outline-offset-2' : ''}`}\n style={style}\n />\n );\n}\n\nfunction SwatchGrid({\n value,\n onSelect,\n allowTransparent,\n}: {\n value: string | null | undefined;\n onSelect: (c: string) => void;\n allowTransparent?: boolean;\n}) {\n const active = (c: string) => c.toLowerCase() === (value ?? '').toLowerCase();\n return (\n <div className=\"grid grid-cols-6 gap-x-1 gap-y-3\">\n {PRESET_COLORS.map((c) => (\n <Swatch key={c} color={c} active={active(c)} onSelect={onSelect} />\n ))}\n {allowTransparent && (\n <Swatch color=\"transparent\" active={isTransparent(value ?? null)} onSelect={onSelect} />\n )}\n </div>\n );\n}\n\n// ── range slider ─────────────────────────────────────────────────────────────\nfunction RangeSlider({\n value,\n min,\n max,\n step,\n onChange,\n}: {\n value: number;\n min: number;\n max: number;\n step: number;\n onChange: (n: number) => void;\n}) {\n return (\n <input\n type=\"range\"\n className=\"accent-accent mb-1.5 h-1 w-full cursor-pointer\"\n value={value}\n min={min}\n max={max}\n step={step}\n onChange={(e) => onChange(parseFloat(e.target.value))}\n />\n );\n}\n\n// ── dropdown shell (open state, outside-click, trigger + panel) ───────────────\nfunction useOutsideClose(open: boolean, close: () => void) {\n const rootRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!open) return;\n const onDoc = (e: MouseEvent) => {\n // composedPath, NOT contains(e.target): at the document level an event\n // from inside the viewer's shadow root retargets to the host element, so\n // contains() reads every inside click as outside and unmounts the panel\n // on mousedown — before the option's click can fire.\n if (rootRef.current && !e.composedPath().includes(rootRef.current)) close();\n };\n document.addEventListener('mousedown', onDoc);\n return () => document.removeEventListener('mousedown', onDoc);\n }, [open, close]);\n return rootRef;\n}\n\nfunction DropdownShell({\n trigger,\n children,\n}: {\n trigger: ReactNode;\n children: (close: () => void) => ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className=\"border-border bg-surface text-fg flex w-full items-center justify-between gap-2 rounded border px-3 py-1.5\"\n >\n {trigger}\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary shrink-0\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-60 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {children(() => setOpen(false))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OptionRow({\n selected,\n onClick,\n children,\n}: {\n selected: boolean;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={`hover:bg-hover flex w-full items-center rounded px-2 py-1.5 text-left text-sm ${selected ? 'bg-selected text-accent' : 'text-fg'}`}\n >\n {children}\n </button>\n );\n}\n\n// ── stroke / border preview + picker ─────────────────────────────────────────\nfunction borderSvg(b: Border): ReactNode {\n if (b.kind === 'cloudy') {\n const r = b.intensity >= 2 ? 5 : 3;\n const n = Math.ceil(80 / (r * 2));\n const step = 80 / n;\n const baseline = r + 1;\n const viewH = r * 2 + 2;\n const parts = [`M 0 ${baseline}`];\n for (let i = 0; i < n; i++) parts.push(`A ${r} ${r} 0 0 1 ${step * (i + 1)} ${baseline}`);\n return (\n <svg width=\"80\" height={viewH} viewBox={`0 0 80 ${viewH}`}>\n <path\n d={parts.join(' ')}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n }\n const dash = b.kind === 'dashed' ? b.dash.join(' ') : undefined;\n return (\n <svg width=\"80\" height=\"8\" viewBox=\"0 0 80 8\">\n <line\n x1=\"0\"\n y1=\"4\"\n x2=\"80\"\n y2=\"4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeDasharray={dash}\n />\n </svg>\n );\n}\n\nfunction BorderSelect({\n value,\n cloudy,\n onChange,\n}: {\n value: Border;\n cloudy: boolean;\n onChange: (b: Border) => void;\n}) {\n const opts = cloudy ? BORDER_OPTS : BORDER_OPTS.filter((o) => !o.key.startsWith('cloudy'));\n return (\n <DropdownShell trigger={<span className=\"text-fg-secondary\">{borderSvg(value)}</span>}>\n {(close) =>\n opts.map((o) => {\n const b = o.make();\n return (\n <OptionRow\n key={o.key}\n selected={borderKey(value) === o.key}\n onClick={() => {\n onChange(b);\n close();\n }}\n >\n <span className=\"text-fg-secondary\">{borderSvg(b)}</span>\n </OptionRow>\n );\n })\n }\n </DropdownShell>\n );\n}\n\n// ── line-ending preview + picker ─────────────────────────────────────────────\nconst LE_MARKERS: Partial<Record<LineEnding, ReactNode>> = {\n square: <path d=\"M68 -4 L76 -4 L76 4 L68 4 Z\" />,\n circle: <circle cx=\"72\" cy=\"0\" r=\"4\" />,\n diamond: <path d=\"M72 -5 L77 0 L72 5 L67 0 Z\" />,\n 'open-arrow': <path d=\"M67 -5 L77 0 L67 5\" fill=\"none\" />,\n 'closed-arrow': <path d=\"M67 -5 L77 0 L67 5 Z\" />,\n 'r-open-arrow': <path d=\"M77 -5 L67 0 L77 5\" fill=\"none\" />,\n 'r-closed-arrow': <path d=\"M77 -5 L67 0 L77 5 Z\" />,\n butt: <path d=\"M72 -5 L72 5\" fill=\"none\" />,\n slash: <path d=\"M67 -5 L77 5\" fill=\"none\" />,\n};\nconst LE_LINE_END: Partial<Record<LineEnding, number>> = {\n square: 68,\n circle: 68,\n diamond: 67,\n 'open-arrow': 76,\n 'closed-arrow': 67,\n 'r-open-arrow': 67,\n 'r-closed-arrow': 67,\n butt: 72,\n slash: 72,\n};\n\nfunction LineEndingPreview({ name, side }: { name: LineEnding; side: 'start' | 'end' }) {\n const marker = LE_MARKERS[name];\n const lineEndX = LE_LINE_END[name] ?? 77;\n const transform = side === 'start' ? 'rotate(180 40 10)' : undefined;\n return (\n <svg width=\"80\" height=\"20\" viewBox=\"0 0 80 20\" className=\"text-fg\">\n <g transform={transform}>\n <line x1=\"4\" y1=\"10\" x2={lineEndX} y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n {marker && (\n <g\n transform=\"translate(0, 10)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n {marker}\n </g>\n )}\n </g>\n </svg>\n );\n}\n\nfunction LineEndingSelect({\n side,\n value,\n onChange,\n}: {\n side: 'start' | 'end';\n value: LineEnding;\n onChange: (v: LineEnding) => void;\n}) {\n return (\n <DropdownShell trigger={<LineEndingPreview name={value} side={side} />}>\n {(close) =>\n LINE_ENDINGS.map((o) => (\n <OptionRow\n key={o.v}\n selected={value === o.v}\n onClick={() => {\n onChange(o.v);\n close();\n }}\n >\n <LineEndingPreview name={o.v} side={side} />\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font family picker ───────────────────────────────────────────────────────\nfunction FontFamilySelect({ value, onChange }: { value: string; onChange: (v: string) => void }) {\n const current = FONT_OPTIONS.find((o) => o.v === value);\n return (\n <DropdownShell trigger={<span className=\"text-fg text-sm\">{current?.label ?? value}</span>}>\n {(close) =>\n FONT_OPTIONS.map((o) => (\n <OptionRow\n key={o.v}\n selected={o.v === value}\n onClick={() => {\n onChange(o.v);\n close();\n }}\n >\n {o.label}\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font-size combo (number input + preset dropdown) ─────────────────────────\nfunction FontSizeCombo({ value, onChange }: { value: number; onChange: (n: number) => void }) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <input\n type=\"number\"\n min={1}\n value={value}\n onChange={(e) => {\n const n = parseInt(e.target.value, 10);\n if (Number.isFinite(n) && n > 0) onChange(n);\n }}\n onClick={() => setOpen(true)}\n className=\"border-border bg-surface text-fg w-full rounded border px-2 py-1.5 pr-7 text-sm\"\n />\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={() => setOpen((o) => !o)}\n className=\"absolute inset-y-0 right-1 flex items-center\"\n >\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-48 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {FONT_SIZES.map((sz) => (\n <OptionRow\n key={sz}\n selected={sz === value}\n onClick={() => {\n onChange(sz);\n setOpen(false);\n }}\n >\n {sz}\n </OptionRow>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction BlendModeSelect({\n value,\n onChange,\n}: {\n value: BlendMode;\n onChange: (mode: BlendMode) => void;\n}) {\n return (\n <select\n value={value}\n onChange={(event) => onChange(event.target.value as BlendMode)}\n className=\"border-border bg-surface text-fg w-full rounded border px-3 py-1.5 text-sm\"\n >\n {BLEND_MODES.map((mode) => (\n <option key={mode.v} value={mode.v}>\n {mode.label}\n </option>\n ))}\n </select>\n );\n}\n\n// ── align toggle ─────────────────────────────────────────────────────────────\nfunction Toggle({\n active,\n title,\n onClick,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n className={`flex h-9 w-9 items-center justify-center rounded border transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\n// ── one control per PropSpec — the entire surface an app customizes ──────────\nfunction PropControl({\n spec,\n value,\n mixed,\n onChange,\n}: {\n spec: PropSpec;\n value: unknown;\n mixed: boolean;\n onChange: (patch: AnnotationPropsPatch) => void;\n}) {\n switch (spec.key) {\n case 'color':\n case 'fontColor':\n return (\n <Field label={spec.label} mixed={mixed}>\n <SwatchGrid\n value={value as string}\n onSelect={(c) => onChange({ [spec.key]: c } as AnnotationPropsPatch)}\n />\n </Field>\n );\n case 'interiorColor':\n return (\n <Field label={spec.label} mixed={mixed}>\n <SwatchGrid\n value={value as string | null}\n allowTransparent\n onSelect={(c) => onChange({ interiorColor: c === 'transparent' ? null : c })}\n />\n </Field>\n );\n case 'opacity': {\n const v = (value as number) ?? 1;\n return (\n <Field label={spec.label} mixed={mixed}>\n <RangeSlider\n value={v}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(n) => onChange({ opacity: n })}\n />\n <span className=\"text-fg-muted text-xs\">{Math.round(v * 100)}%</span>\n </Field>\n );\n }\n case 'strokeWidth': {\n const v = (value as number) ?? spec.min;\n return (\n <Field label={spec.label} mixed={mixed}>\n <RangeSlider\n value={v}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(n) => onChange({ strokeWidth: n })}\n />\n <span className=\"text-fg-muted text-xs\">{v}px</span>\n </Field>\n );\n }\n case 'fontSize':\n return (\n <Field label={spec.label} mixed={mixed}>\n <FontSizeCombo\n value={(value as number) ?? 12}\n onChange={(n) => onChange({ fontSize: n })}\n />\n </Field>\n );\n case 'border':\n return (\n <Field label={spec.label} mixed={mixed}>\n <BorderSelect\n value={(value as Border) ?? { kind: 'solid' }}\n cloudy={spec.cloudy}\n onChange={(b) => onChange({ border: b })}\n />\n </Field>\n );\n case 'lineEndings': {\n const le = (value as LineEndings) ?? { start: 'none', end: 'none' };\n return (\n <Field label={spec.label} mixed={mixed}>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">Start</div>\n <LineEndingSelect\n side=\"start\"\n value={le.start}\n onChange={(v) => onChange({ lineEndings: { start: v } })}\n />\n </div>\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">End</div>\n <LineEndingSelect\n side=\"end\"\n value={le.end}\n onChange={(v) => onChange({ lineEndings: { end: v } })}\n />\n </div>\n </div>\n </Field>\n );\n }\n case 'fontFamily':\n return (\n <Field label={spec.label} mixed={mixed}>\n <FontFamilySelect\n value={(value as string) ?? 'helvetica'}\n onChange={(v) => onChange({ fontFamily: v })}\n />\n </Field>\n );\n case 'textAlign': {\n const alignIcon: Record<TextAlign, string> = {\n left: 'alignLeft',\n center: 'alignCenter',\n right: 'alignRight',\n };\n return (\n <Field label={spec.label} mixed={mixed}>\n <div className=\"flex gap-2\">\n {(['left', 'center', 'right'] as TextAlign[]).map((al) => (\n <Toggle\n key={al}\n title={`Align ${al}`}\n active={value === al}\n onClick={() => onChange({ textAlign: al })}\n >\n <Icon name={alignIcon[al]} size={18} />\n </Toggle>\n ))}\n </div>\n </Field>\n );\n }\n case 'blendMode':\n return (\n <Field label={spec.label} mixed={mixed}>\n <BlendModeSelect\n value={(value as BlendMode) ?? 'normal'}\n onChange={(blendMode) => onChange({ blendMode })}\n />\n </Field>\n );\n // `link` deliberately renders NOTHING here: a link is a verb on the\n // selection, edited in the anchored popover (see ui/link-editor.tsx) —\n // never a style-panel section.\n case 'link':\n return null;\n default:\n return null;\n }\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nfunction EmptyState() {\n return (\n <div className=\"text-fg-muted flex flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n <Icon name=\"palette\" size={40} className=\"text-fg-disabled\" />\n <p className=\"max-w-[180px] text-sm\">\n Pick a draw tool or select an annotation to edit its style.\n </p>\n </div>\n );\n}\n\n/**\n * The schema-driven style panel. Rendered inside the right sidebar's\n * `annotation-style` surface (see ui/panels.tsx). Owns its own scroll.\n */\nexport function AnnotationStylePanel() {\n const annotation = useAnnotation();\n const { activeToolId } = useTool();\n const sel = useSelectionProps();\n const defaults = useAnnotationDefaults(activeToolId);\n const selected = useAnnotationSelected();\n\n const hasSel = sel.specs.length > 0;\n const specs = hasSel ? sel.specs : annotation.propsForTool(activeToolId);\n const values = hasSel ? sel.values : defaults;\n const write = (patch: AnnotationPropsPatch) =>\n hasSel ? annotation.updateSelection(patch) : annotation.setDefaults(activeToolId, patch);\n\n // A selection with no editable props (e.g. a stamp, or a LOCKED annotation —\n // its style is frozen) still shows its flags: that's how you unlock it.\n if (specs.length === 0 && selected.length === 0) return <EmptyState />;\n\n const context = hasSel ? `${selected.length} selected` : `${activeToolId} defaults`;\n\n return (\n <div className=\"flex-1 overflow-y-auto p-4\">\n <p className=\"text-fg-muted mb-4 text-[11px] font-semibold uppercase tracking-wide\">\n {context}\n </p>\n {specs.map((spec) => (\n <PropControl\n key={spec.key}\n spec={spec}\n value={values[spec.key]}\n mixed={hasSel && sel.mixed.includes(spec.key)}\n onChange={write}\n />\n ))}\n {/* Redaction label (`/OverlayText` + `/Repeat`) — kind content, not a\n style prop, so it writes through the redaction plugin's setLabel. */}\n <RedactionLabelSection />\n {/* `/F` flags for whatever is selected — the live flags test surface. */}\n <AnnotationFlagsSection />\n </div>\n );\n}\n\n/**\n * Label editor shown when exactly one redaction mark is selected. The text is\n * what the destructive apply paints over the region (white-on-black by the\n * tool defaults); `repeat` tiles it. Writes ride the annotation update verb\n * via the redaction plugin, which preserves the label's `/DA` styling.\n */\nfunction RedactionLabelSection() {\n const t = useT();\n const redaction = useOptionalCapability(RedactionToken);\n const selected = useAnnotationSelected();\n const mark = selected.length === 1 && selected[0]!.subtype === 'redact' ? selected[0]! : null;\n const [draft, setDraft] = useState<string | null>(null);\n useEffect(() => setDraft(null), [mark?.ref && refKeyOfRedact(mark.ref)]);\n if (!redaction || !mark || mark.subtype !== 'redact') return null;\n\n const value = draft ?? mark.overlayText ?? '';\n const commit = () => {\n if (draft === null) return;\n void redaction.setLabel(mark.ref, { overlayText: draft.length > 0 ? draft : null });\n setDraft(null);\n };\n\n return (\n <div className=\"border-border-subtle mt-4 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('demo.redactLabelTitle')}\n </p>\n <input\n type=\"text\"\n value={value}\n placeholder={t('demo.redactLabelPlaceholder')}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commit}\n onKeyDown={(e) => e.key === 'Enter' && commit()}\n className=\"border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm\"\n />\n <label className=\"text-fg mt-2 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={mark.repeat}\n onChange={(e) => void redaction.setLabel(mark.ref, { repeat: e.target.checked })}\n />\n {t('demo.redactLabelRepeat')}\n </label>\n </div>\n );\n}\n\n/** Stable key for the effect dep — mirrors the annotation model's ref keys. */\nfunction refKeyOfRedact(ref: { kind: string } & Record<string, unknown>): string {\n return JSON.stringify(ref);\n}\n","import type { AnnotationDTO, Color } from '@embedpdf/react/annotation';\n\n/**\n * How a comment card identifies its annotation at a glance: the type's glyph,\n * tinted with THAT annotation's own colors. Ported from v2's comment-sidebar\n * config onto the v3 vocabulary — the icon names carry over verbatim (the\n * chrome icon set kept the v2 registry names and accent slots), while the\n * color model is v3's ISO-faithful one: there is exactly one `/C` (\"color\")\n * and one `/IC` (\"interiorColor\") in the spec, so `primary` is the annotation's\n * `/C` and `secondary` its interior fill where the family has one.\n */\n\nexport interface IconAccent {\n primary?: string;\n secondary?: string;\n}\n\nexport interface CommentTypeConfig {\n /** Icon name in the chrome registry. */\n icon: string;\n /** i18n key for the type's display name (tooltip). */\n labelKey: string;\n /** Fallback when the locale has no entry. */\n label: string;\n}\n\n/** `/C`-style Color → CSS. */\nexport const cssColor = (c: Color | null | undefined): string | undefined =>\n c ? `rgb(${c.r}, ${c.g}, ${c.b})` : undefined;\n\nconst TYPE_CONFIG: Record<string, CommentTypeConfig> = {\n text: { icon: 'message', labelKey: 'annotation.comment', label: 'Comment' },\n highlight: { icon: 'highlight', labelKey: 'annotation.highlight', label: 'Highlight' },\n underline: { icon: 'underline', labelKey: 'annotation.underline', label: 'Underline' },\n squiggly: { icon: 'squiggly', labelKey: 'annotation.squiggly', label: 'Squiggly' },\n strikeout: { icon: 'strikethrough', labelKey: 'annotation.strikeout', label: 'Strikethrough' },\n square: { icon: 'square', labelKey: 'annotation.square', label: 'Square' },\n circle: { icon: 'circle', labelKey: 'annotation.circle', label: 'Circle' },\n line: { icon: 'line', labelKey: 'annotation.line', label: 'Line' },\n polygon: { icon: 'polygon', labelKey: 'annotation.polygon', label: 'Polygon' },\n polyline: { icon: 'zigzag', labelKey: 'annotation.polyline', label: 'Polyline' },\n ink: { icon: 'pencilMarker', labelKey: 'annotation.ink', label: 'Ink' },\n 'free-text': { icon: 'freeText', labelKey: 'annotation.freeText', label: 'Text' },\n stamp: { icon: 'rubberStamp', labelKey: 'annotation.stamp', label: 'Stamp' },\n caret: { icon: 'insertText', labelKey: 'annotation.caret', label: 'Caret' },\n redact: { icon: 'redact', labelKey: 'annotation.redact', label: 'Redact' },\n 'file-attachment': {\n icon: 'paperclip',\n labelKey: 'annotation.fileAttachment',\n label: 'Attachment',\n },\n};\n\nconst FALLBACK: CommentTypeConfig = {\n icon: 'message',\n labelKey: 'annotation.comment',\n label: 'Comment',\n};\n\nexport const commentTypeConfig = (a: AnnotationDTO): CommentTypeConfig =>\n TYPE_CONFIG[a.subtype] ?? FALLBACK;\n\n/**\n * The glyph's tint slots, read off the annotation itself — this is what makes\n * a card recognizable as \"that yellow highlight on page 3\". Free-text prefers\n * its `fontColor` override, since that is the color a reader actually sees.\n */\nexport const commentIconAccent = (a: AnnotationDTO): IconAccent => {\n const anyA = a as { color?: Color; interiorColor?: Color | null; fontColor?: Color };\n const primary = cssColor(anyA.fontColor ?? anyA.color);\n const secondary = cssColor(anyA.interiorColor);\n return {\n ...(primary ? { primary } : {}),\n ...(secondary ? { secondary } : {}),\n };\n};\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { useCapability } from '@embedpdf/react/runtime';\nimport {\n AnnotationToken,\n refKey,\n useAnnotationSelection,\n useComments,\n useCommentThreads,\n useCommentsHydration,\n type AnnotationDTO,\n type AnnotationRef,\n type CommentThreadView,\n} from '@embedpdf/react/annotation';\nimport { StageToken } from '@embedpdf/react/stage';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { commentIconAccent, commentTypeConfig } from './comment-config';\n\n/**\n * The comments sidebar (right panel): a live view over the conversation\n * plane, in the shape v2's reviewers knew — page-grouped sections, and a\n * card that identifies its annotation at a glance by the type's glyph tinted\n * with that annotation's own colors. What v2 lacked, and this adds, is the\n * ISO 32000 §12.5.6.3 review status per thread.\n *\n * There is no per-page loading dance: the plugin hydrates the WHOLE document\n * at open (`listRawAll`), so the list is complete the moment `hydration()`\n * says so, whether or not a page was ever scrolled to.\n *\n * Selection is two-way, as in v2: clicking a card selects the annotation and\n * flies the camera to it (`stage.reveal`, the same verb search hits use);\n * selecting in the document scrolls that card into view here.\n *\n * Every action routes through the `comments` verbs — plain annotation writes\n * on the one optimistic pipeline — and every control is gated by\n * `permissionsFor`, the engine's own collab-resolver mirrors: what shows here\n * is what the engine will allow.\n */\n\nconst REVIEW_STATES = ['none', 'accepted', 'rejected', 'cancelled', 'completed'] as const;\n\nconst dateLabel = (iso: string | null): string => {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n};\n\nexport function CommentsPanel() {\n const t = useT();\n const hydration = useCommentsHydration();\n const comments = useComments();\n const threads = useCommentThreads();\n const anno = useCapability(AnnotationToken);\n const stage = useCapability(StageToken);\n const selection = useAnnotationSelection();\n const scrollRef = useRef<HTMLDivElement>(null);\n const cardRefs = useRef<Record<string, HTMLLIElement | null>>({});\n\n /** Which thread the document's selection points at — ANY member counts, so\n * selecting a reply's parent shape highlights the same card. */\n const selectedThreadKey = useMemo(() => {\n for (const id of selection) {\n const dto = anno.getSelected().find((a) => refKey(a.ref) === id || a.nm === id);\n const ref = dto?.ref ?? null;\n const thread = ref ? comments.thread(ref) : null;\n if (thread) return refKey(thread.root.ref);\n }\n return null;\n // `selection` identity changes on every selection write — the right key.\n }, [selection, anno, comments]);\n\n // Reverse sync: the selected card scrolls itself into view (v2 centered it).\n useEffect(() => {\n if (!selectedThreadKey || !scrollRef.current) return;\n const el = cardRefs.current[selectedThreadKey];\n if (!el) return;\n const container = scrollRef.current;\n const top =\n el.offsetTop - container.clientHeight / 2 + el.clientHeight / 2 - container.offsetTop;\n container.scrollTo({ top, behavior: 'smooth' });\n }, [selectedThreadKey]);\n\n /** Click a card: select the annotation AND fly the camera to it. */\n const goTo = (view: CommentThreadView) => {\n anno.select(view.root.ref);\n if (view.pageIndex < 0) return;\n // Anchor values are viewport FRACTIONS (0–1), not v2's percentages:\n // the annotation lands a third down the viewport, the find-bar feel.\n stage?.reveal(view.pageIndex, {\n ...(view.contentRect ? { rect: view.contentRect } : {}),\n anchor: { x: 'center', y: 0.35 },\n behavior: 'smooth',\n });\n };\n\n // Page-grouped, preserving the lens's display order within each page.\n const byPage = useMemo(() => {\n const groups = new Map<number, CommentThreadView[]>();\n for (const v of threads) {\n const arr = groups.get(v.pageIndex);\n if (arr) arr.push(v);\n else groups.set(v.pageIndex, [v]);\n }\n return [...groups.entries()].sort((a, b) => a[0] - b[0]);\n }, [threads]);\n\n if (hydration.status === 'loading') return <Empty icon=\"comment\" text={t('demo.commentsLoading')} />;\n if (hydration.status === 'forbidden')\n return <Empty icon=\"lock\" text={t('demo.commentsForbidden')} />;\n if (hydration.status === 'error') {\n return (\n <Empty icon=\"alertTriangle\" text={t('demo.commentsError')}>\n <button\n type=\"button\"\n onClick={() => void comments.rehydrate()}\n className=\"bg-accent text-on-accent rounded-md px-3 py-1.5 text-sm font-medium\"\n >\n {t('demo.commentsRetry')}\n </button>\n </Empty>\n );\n }\n if (threads.length === 0) return <Empty icon=\"comment\" text={t('demo.commentsEmpty')} />;\n\n return (\n <div ref={scrollRef} className=\"min-h-0 flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-5 p-3\">\n {byPage.map(([pageIndex, group]) => (\n <div key={pageIndex} className=\"flex flex-col gap-2\">\n <div className=\"bg-surface sticky top-0 z-10\">\n <div className=\"border-border-subtle border-b pb-1.5\">\n <h3 className=\"text-fg text-sm font-semibold\">\n {t('demo.commentsPage', { params: { page: group[0]!.pageLabel } })}\n </h3>\n <p className=\"text-fg-muted text-xs\">\n {t(group.length === 1 ? 'demo.commentCount' : 'demo.commentCountPlural', {\n params: { count: String(group.length) },\n })}\n </p>\n </div>\n </div>\n <ul className=\"flex flex-col gap-2\">\n {group.map((view) => {\n const key = refKey(view.root.ref);\n return (\n <ThreadCard\n key={key}\n view={view}\n selected={selectedThreadKey === key}\n onSelect={() => goTo(view)}\n cardRef={(el) => {\n cardRefs.current[key] = el;\n }}\n />\n );\n })}\n </ul>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction Empty({\n icon,\n text,\n children,\n}: {\n icon: string;\n text: string;\n children?: React.ReactNode;\n}) {\n return (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name={icon} size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{text}</p>\n {children}\n </div>\n );\n}\n\nfunction ThreadCard({\n view,\n selected,\n onSelect,\n cardRef,\n}: {\n view: CommentThreadView;\n selected: boolean;\n onSelect: () => void;\n cardRef: (el: HTMLLIElement | null) => void;\n}) {\n const t = useT();\n const comments = useComments();\n const [reply, setReply] = useState('');\n const perms = comments.permissionsFor(view.root.ref);\n const config = commentTypeConfig(view.root);\n const status = view.review.mine?.state ?? 'none';\n const latest = view.review.lastChange;\n\n const sendReply = () => {\n const text = reply.trim();\n if (!text) return;\n setReply('');\n void comments.reply(view.root.ref, text);\n };\n\n return (\n <li\n ref={cardRef}\n onClick={onSelect}\n className={`bg-surface cursor-pointer rounded-lg border shadow-sm transition-all hover:shadow-md ${\n selected ? 'border-accent ring-accent/40 ring-2' : 'border-border-subtle'\n }`}\n >\n <div className=\"flex flex-col gap-2 p-3\">\n {/* identity row: the annotation's own glyph + color is the anchor */}\n <div className=\"flex items-start gap-2.5\">\n <div\n className=\"bg-hover mt-0.5 grid h-8 w-8 shrink-0 place-items-center rounded-full\"\n title={t(config.labelKey, { fallback: config.label })}\n >\n <Icon name={config.icon} size={18} accent={commentIconAccent(view.root)} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-fg truncate text-sm font-medium\">\n {view.root.author ?? t('demo.commentsAnonymous')}\n </span>\n <span className=\"text-fg-muted ml-auto shrink-0 text-xs\">\n {dateLabel(view.root.modified ?? view.root.created)}\n </span>\n </div>\n {latest && (\n <span className=\"bg-accent-light text-accent mt-1 inline-block rounded px-1.5 py-0.5 text-[11px] font-medium\">\n {statusLabel(t, latest.state)}\n {latest.by ? ` — ${latest.by}` : ''}\n </span>\n )}\n </div>\n {perms.canDeleteThread && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void comments.removeThread(view.root.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded\"\n title={t('demo.commentsDeleteThread')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n )}\n </div>\n\n <CommentBody annotationRef={view.root.ref} text={view.root.contents ?? ''} deletable={false} />\n\n {view.replies.length > 0 && (\n <div className=\"border-border-subtle flex flex-col gap-2 border-t pt-2\">\n {view.replies.map((r) => (\n <Reply key={refKey(r.ref)} dto={r} />\n ))}\n </div>\n )}\n\n <div className=\"border-border-subtle flex flex-col gap-1.5 border-t pt-2\">\n {perms.canSetStatus && (\n <label\n className=\"text-fg-muted flex items-center gap-2 text-xs\"\n onClick={(e) => e.stopPropagation()}\n >\n {t('demo.commentsStatus')}\n <select\n value={status}\n onChange={(e) => void comments.setStatus(view.root.ref, e.target.value)}\n className=\"border-border bg-surface text-fg flex-1 rounded-md border px-1.5 py-1 text-xs outline-none\"\n >\n {REVIEW_STATES.map((s) => (\n <option key={s} value={s}>\n {statusLabel(t, s)}\n </option>\n ))}\n </select>\n </label>\n )}\n {perms.canReply && (\n <div className=\"flex items-center gap-1.5\" onClick={(e) => e.stopPropagation()}>\n <input\n type=\"text\"\n value={reply}\n placeholder={\n view.root.contents || view.replies.length\n ? t('demo.commentsReplyPlaceholder')\n : t('demo.commentsAddPlaceholder')\n }\n onChange={(e) => setReply(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && sendReply()}\n className=\"border-border bg-surface text-fg focus:border-accent w-full min-w-0 flex-1 rounded-md border px-2 py-1 text-sm outline-none\"\n />\n <button\n type=\"button\"\n onClick={sendReply}\n disabled={!reply.trim()}\n className=\"text-accent disabled:text-fg-muted grid h-7 w-7 shrink-0 place-items-center rounded-md\"\n title={t('demo.commentsReply')}\n >\n <Icon name=\"arrowForwardUp\" size={16} />\n </button>\n </div>\n )}\n </div>\n </div>\n </li>\n );\n}\n\nfunction Reply({ dto }: { dto: AnnotationDTO }) {\n const t = useT();\n return (\n <div className=\"border-border-subtle ml-1 border-l-2 pl-2\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-fg-secondary text-xs font-medium\">\n {dto.author ?? t('demo.commentsAnonymous')}\n </span>\n <span className=\"text-fg-muted text-[11px]\">\n {dateLabel(dto.modified ?? dto.created)}\n </span>\n </div>\n <CommentBody annotationRef={dto.ref} text={dto.contents ?? ''} deletable />\n </div>\n );\n}\n\n/** One comment's text with inline edit (own, unlocked) and delete (replies). */\nfunction CommentBody({\n annotationRef,\n text,\n deletable,\n}: {\n annotationRef: AnnotationRef;\n text: string;\n deletable: boolean;\n}) {\n const t = useT();\n const comments = useComments();\n const perms = comments.permissionsFor(annotationRef);\n const [draft, setDraft] = useState<string | null>(null);\n\n if (draft !== null) {\n const save = () => {\n const next = draft.trim();\n setDraft(null);\n if (next && next !== text) void comments.edit(annotationRef, next);\n };\n return (\n <textarea\n value={draft}\n autoFocus\n rows={2}\n onClick={(e) => e.stopPropagation()}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={save}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n save();\n }\n if (e.key === 'Escape') setDraft(null);\n }}\n className=\"border-accent bg-surface text-fg w-full resize-none rounded-md border px-2 py-1 text-sm outline-none\"\n />\n );\n }\n if (!text && !perms.canEditText && !deletable) return null;\n return (\n <div className=\"group/body flex items-start gap-1\">\n <p className=\"text-fg min-w-0 flex-1 whitespace-pre-wrap text-sm\">{text}</p>\n {perms.canEditText && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setDraft(text);\n }}\n className=\"text-fg-muted hover:text-fg grid h-5 w-5 shrink-0 place-items-center rounded opacity-0 group-hover/body:opacity-100\"\n title={t('demo.commentsEdit')}\n >\n <Icon name=\"pencilMarker\" size={12} />\n </button>\n )}\n {deletable && perms.canDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void comments.remove(annotationRef);\n }}\n className=\"text-fg-muted hover:text-fg grid h-5 w-5 shrink-0 place-items-center rounded opacity-0 group-hover/body:opacity-100\"\n title={t('demo.commentsDelete')}\n >\n <Icon name=\"trash\" size={12} />\n </button>\n )}\n </div>\n );\n}\n\nfunction statusLabel(t: ReturnType<typeof useT>, state: string): string {\n switch (state) {\n case 'none':\n return t('demo.commentsStatusNone');\n case 'accepted':\n return t('demo.commentsStatusAccepted');\n case 'rejected':\n return t('demo.commentsStatusRejected');\n case 'cancelled':\n return t('demo.commentsStatusCancelled');\n case 'completed':\n return t('demo.commentsStatusCompleted');\n default:\n return state; // custom vocabularies render verbatim\n }\n}\n","import { useEffect } from 'react';\nimport { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a LIVE view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n // The annotation plane loads lazily per page; pull every page in so the\n // panel shows marks on pages never scrolled to.\n useEffect(() => {\n void redaction.preparePending();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={item.id}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.select(item.ref)}\n onKeyDown={(e) => e.key === 'Enter' && anno.select(item.ref)}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || redaction.applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The search panel — the v2 snippet's search sidebar on the v3 plugin-search\n * capability. ONE shape end to end: the flat `SearchQuery` {text, regex,\n * matchCase, wholeWord} is what the engine matches, what the plugin stores\n * (document-scoped, survives the sidebar closing), and what this box renders.\n * The panel keeps only a DRAFT of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeIndex (reactive)\n * useSelector(SearchToken, c => c.hits()) → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look is ported 1:1 from viewers/snippet's search-sidebar (magnifier\n * input with clear button, option checkboxes, results-found counter with\n * prev/next, per-page grouped snippet list with the match bolded and the\n * active hit accented), retinted to this app's semantic tokens. The regex\n * toggle is new in v3 (v2 had no pattern search); matchDiacritics exists in\n * the engine but is deliberately not exposed here — v2 parity.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchState,\n validateSearchQuery,\n SearchToken,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useSelector } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (a: SearchQuery | null, b: SearchQuery) =>\n a != null &&\n a.text === b.text &&\n !!a.regex === !!b.regex &&\n !!a.matchCase === !!b.matchCase &&\n !!a.wholeWord === !!b.wholeWord;\n\n// ── option checkbox (v2's peer-checked custom box) ───────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (v: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent peer h-4 w-4 shrink-0 appearance-none rounded-[3px] border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(s: SearchSnippet | undefined) {\n if (!s) return null;\n const end = s.matchStart + s.matchLength;\n return (\n <>\n {s.text.slice(0, s.matchStart)}\n <span className=\"text-accent font-semibold\">{s.text.slice(s.matchStart, end)}</span>\n {s.text.slice(end)}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeIndex } = useSearchState();\n const hits = useSelector(SearchToken, (c) => c.hits());\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that STARTS from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // The draft IS a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((a, b) => a[0] - b[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(e) => setDraft(e.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pl-8 pr-9 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 right-0 flex items-center pr-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title=\"Previous\"\n className={buttonClass(false)}\n onClick={() => search.prev()}\n >\n <Icon name=\"chevronLeft\" size={20} />\n </button>\n <button\n type=\"button\"\n title=\"Next\"\n className={buttonClass(false)}\n onClick={() => search.next()}\n >\n <Icon name=\"chevronRight\" size={20} />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeIndex}\n onClick={() => search.goTo(index)}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","/**\n * The static chrome around the toolbars: the left/right sidebars (shell\n * surfaces) and the bottom page-controls overlay. Deliberately minimal —\n * chrome-parity scope. Panels read their open state from plugin-shell; the\n * app owns their DOM.\n *\n * There is no built-in header: branding, a locale picker and a theme switch\n * are the EMBEDDER's chrome, not the viewer's. The frame keeps a `header`\n * socket for a slotted one (see Shell).\n */\nimport { useEffect } from 'react';\nimport { useSelector, useDocumentId } from '@embedpdf/react/runtime';\nimport { Stage, StageToken, usePages } from '@embedpdf/react/stage';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { ThumbsStageToken } from '../config/stage';\nimport { Icon } from './icons';\nimport { AnnotationStylePanel } from './annotation-style';\nimport { CommentsPanel } from './comments-panel';\nimport { RedactionPanel } from './redaction-panel';\nimport { SearchPanel } from './search-panel';\n\n// ── left sidebar (thumbnails / outline tabs) ─────────────────────────────────\nexport function LeftSidebar() {\n const t = useT();\n const sidebar = useSurface('sidebar');\n if (!sidebar.isOpen) return null;\n return (\n <aside className=\"border-border-subtle bg-surface flex w-60 shrink-0 flex-col border-r\">\n <div className=\"border-border-subtle flex items-center gap-1 border-b p-2\">\n <span className=\"bg-accent-light text-accent rounded-md px-2 py-1 text-xs font-medium\">\n {t('demo.thumbnails')}\n </span>\n <span className=\"text-fg-muted rounded-md px-2 py-1 text-xs font-medium\">\n {t('demo.outline')}\n </span>\n <div className=\"flex-1\" />\n <button\n type=\"button\"\n onClick={sidebar.close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n <ThumbnailList />\n </aside>\n );\n}\n\n// The thumbnail rail: the SAME document through the thumbnail Stage lens (a\n// single-column, fixed-zoom grid — see App's `stage-thumbs` plugin). Click a\n// thumb to navigate the MAIN lens; the rail follows the main view. Read-only —\n// no page edits (rotate/move/delete), just the page bitmap and its number.\nfunction ThumbnailList() {\n const { currentPage, goToPage } = usePages(); // the MAIN lens\n const { reveal } = usePages(ThumbsStageToken); // the SIDEBAR lens\n // Follow the main view: when its current page changes, make that thumb visible —\n // minimal movement, zero when it's already on screen.\n useEffect(() => reveal(currentPage), [currentPage, reveal]);\n return (\n <Stage\n token={ThumbsStageToken}\n zoomGestures={false} // fixed-magnification rail: cmd+wheel/pinch scrolls, never zooms\n className=\"flex-1\"\n style={{ position: 'relative' }}\n pageChrome={(page) => (\n <>\n {/* BOX-SPACE chrome: the click target + selection border hug the page\n box; the number sits in the reserved bottom band. Neither rotates. */}\n <button\n type=\"button\"\n onClick={() => goToPage(page.pageIndex)}\n title={`Page ${page.pageIndex + 1}`}\n style={{\n position: 'absolute',\n top: page.frame.top,\n left: page.frame.left,\n right: page.frame.right,\n bottom: page.frame.bottom,\n cursor: 'pointer',\n boxSizing: 'border-box',\n borderRadius: 4,\n border:\n page.pageIndex === currentPage\n ? '2px solid var(--ep-accent)'\n : '1px solid var(--ep-border-subtle)',\n boxShadow:\n page.pageIndex === currentPage ? '0 0 0 2px var(--ep-accent-light)' : 'none',\n }}\n />\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: page.frame.bottom,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 11,\n color: 'var(--ep-fg-muted)',\n pointerEvents: 'none',\n }}\n >\n {page.pageIndex + 1}\n </div>\n </>\n )}\n >\n {/* page-space content: the bitmap, which rotates with the page */}\n {() => <RenderLayer />}\n </Stage>\n );\n}\n\n// ── right sidebar (search / comment / style) ─────────────────────────────────\nexport function RightSidebar() {\n const t = useT();\n // Keys the SearchPanel below: the panel seeds its query box from the active\n // document's search state on mount, so it must remount when the active\n // document changes (switching tabs with the sidebar open) to re-seed.\n const documentId = useDocumentId();\n const search = useSurface('search');\n const comment = useSurface('comment');\n const style = useSurface('annotation-style');\n const redaction = useSurface('redaction');\n const active = search.isOpen\n ? 'search'\n : comment.isOpen\n ? 'comment'\n : style.isOpen\n ? 'style'\n : redaction.isOpen\n ? 'redaction'\n : null;\n if (!active) return null;\n\n const titleKey =\n active === 'search'\n ? 'demo.searchTitle'\n : active === 'comment'\n ? 'demo.commentsTitle'\n : active === 'redaction'\n ? 'demo.redactionTitle'\n : 'demo.styleTitle';\n const close =\n active === 'search'\n ? search.close\n : active === 'comment'\n ? comment.close\n : active === 'redaction'\n ? redaction.close\n : style.close;\n\n return (\n <aside className=\"border-border-subtle bg-surface flex w-72 shrink-0 flex-col border-l\">\n <div className=\"border-border-subtle flex items-center justify-between border-b p-3\">\n <span className=\"text-fg text-sm font-semibold\">{t(titleKey)}</span>\n <button\n type=\"button\"\n onClick={close}\n className=\"text-fg-muted hover:bg-hover grid h-7 w-7 place-items-center rounded-md\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n </div>\n {active === 'style' ? (\n <AnnotationStylePanel />\n ) : active === 'search' ? (\n <SearchPanel key={documentId ?? 'none'} />\n ) : active === 'redaction' ? (\n <RedactionPanel />\n ) : (\n <CommentsPanel key={documentId ?? 'none'} />\n )}\n </aside>\n );\n}\n\n// ── bottom page-controls overlay ─────────────────────────────────────────────\nexport function PageControls() {\n const t = useT();\n // the Stage cursor is a 0-based display index; people count from 1\n const current = useSelector(StageToken, (c) => c.currentPage() + 1);\n const total = useSelector(StageToken, (c) => c.pageCount());\n if (!total) return null;\n return (\n <div className=\"pointer-events-none absolute inset-x-0 bottom-5 flex justify-center\">\n <div className=\"border-border-subtle bg-elevated/95 text-fg-secondary pointer-events-auto rounded-full border px-4 py-1.5 text-sm shadow-lg backdrop-blur\">\n {t('demo.page', { params: { current, total } })}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * CLIENT-SIDE collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n if (!surface.isOpen) return null;\n\n const count = redaction.pendingCount();\n const collateral = redaction.estimateCollateral();\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 z-50 grid place-items-center bg-black/40\">\n <div className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\">\n <h2 className=\"text-fg text-base font-semibold\">{t('demo.redactConfirmTitle')}</h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Boot-state panes for the document area — what renders INSTEAD of the Stage\n * while the selected tab's document isn't ready:\n *\n * `locked` → <PasswordPrompt/> (per-tab, v2's document-password-prompt port)\n * `error` → <DocumentError/>\n *\n * Both are per-TAB, not modal: several tabs can be locked/broken at once and\n * switching tabs stays free. The prompt drives ONE call —\n * `documents.unlock(id, { password })` — identical on the local (worker loads\n * the parked bytes) and cloud (/access grant) engines. The \"incorrect\" copy\n * keys on a real rejection: either this session's failed attempt, or\n * `passwordProvided` (a config-supplied password the engine already rejected).\n */\nimport { useState } from 'react';\nimport { useDocumentId, useDocuments } from '@embedpdf/react/runtime';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\nexport function PasswordPrompt() {\n const docId = useDocumentId();\n const { docs, unlock, close } = useDocuments();\n const t = useT();\n const [password, setPassword] = useState('');\n const [rejected, setRejected] = useState(false);\n const [busy, setBusy] = useState(false);\n\n const doc = docs.find((d) => d.id === docId);\n if (!docId || !doc) return null;\n const incorrect = rejected || doc.passwordProvided === true;\n\n const submit = async () => {\n if (busy || !password.trim()) return;\n setBusy(true);\n try {\n await unlock(docId, { password });\n // success → the tab promotes to ready and this pane unmounts\n } catch {\n setRejected(true);\n setPassword('');\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border w-full max-w-sm rounded-xl border p-6 shadow-lg\">\n <div className=\"flex flex-col items-center text-center\">\n <div className=\"bg-accent-light mb-4 rounded-full p-4\">\n <Icon name=\"lock\" size={28} className=\"text-accent\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('passwordPrompt.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n </div>\n\n <p className=\"text-fg-secondary mt-4 text-center text-sm\">\n {incorrect ? t('passwordPrompt.incorrect') : t('passwordPrompt.required')}\n </p>\n\n <div className=\"mt-5\">\n <label className=\"text-fg mb-1.5 block text-sm font-medium\" htmlFor=\"doc-password\">\n {t('passwordPrompt.label')}\n </label>\n <input\n id=\"doc-password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && void submit()}\n disabled={busy}\n placeholder={t('passwordPrompt.placeholder')}\n className=\"bg-surface border-border focus:border-accent focus:ring-accent text-fg placeholder:text-fg-muted block w-full rounded-md border px-3 py-2.5 text-sm focus:outline-none focus:ring-1 disabled:opacity-50\"\n autoFocus\n />\n </div>\n\n {incorrect && (\n <div className=\"mt-3 flex items-center gap-2 rounded-md border border-red-500/40 bg-red-500/10 p-3\">\n <Icon name=\"alertTriangle\" size={16} className=\"flex-shrink-0 text-red-500\" />\n <p className=\"text-sm text-red-500\">{t('passwordPrompt.incorrectWarning')}</p>\n </div>\n )}\n\n <div className=\"mt-6 flex gap-3\">\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n disabled={busy}\n className=\"border-border text-fg-secondary hover:bg-hover flex-1 cursor-pointer rounded-md border px-4 py-2.5 text-sm font-medium transition-colors disabled:opacity-50\"\n >\n {t('passwordPrompt.cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => void submit()}\n disabled={busy || !password.trim()}\n className=\"bg-accent text-on-accent flex-1 cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {busy ? t('passwordPrompt.opening') : t('passwordPrompt.open')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport function DocumentError() {\n const docId = useDocumentId();\n const { docs, close } = useDocuments();\n const t = useT();\n const doc = docs.find((d) => d.id === docId);\n if (!docId || !doc) return null;\n\n return (\n <div className=\"bg-app flex h-full w-full items-center justify-center p-8\">\n <div className=\"bg-surface border-border flex max-w-sm flex-col items-center rounded-xl border p-6 text-center shadow-lg\">\n <div className=\"mb-4 rounded-full bg-red-500/10 p-4\">\n <Icon name=\"alertTriangle\" size={28} className=\"text-red-500\" />\n </div>\n <h3 className=\"text-fg text-lg font-semibold\">{t('documentError.title')}</h3>\n {doc.name && <p className=\"text-fg-muted mt-1 text-sm\">{doc.name}</p>}\n <p className=\"text-fg-secondary mt-2 text-sm\">{t('documentError.unknown')}</p>\n <button\n type=\"button\"\n onClick={() => void close(docId)}\n className=\"bg-accent text-on-accent mt-5 w-full cursor-pointer rounded-md px-4 py-2.5 text-sm font-medium transition-colors hover:opacity-90\"\n >\n {t('documentError.close')}\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The viewer shell — the snippet's layout, driven entirely by the v3 commands\n * + measured-toolbar system.\n *\n * ── header socket (empty unless a child fills it) ─────────\n * ── main toolbar (measured; auto-overflows) ───────────────\n * ── mode band (DERIVED from the shell's open mode surface) ─\n * left sidebar │ Stage (pages) │ right sidebar\n * ──────────── page-controls overlay ──────────────────────\n *\n * The workspace/document split is structural: header + toolbars are\n * workspace-scoped and render at t≈0 (translated, measured) while the wasm\n * engine still boots; everything document-scoped sits inside <DocumentGate>,\n * whose fallback is the empty-workspace state (v2's loader, but UNDER a live\n * toolbar instead of replacing the whole app).\n *\n * Which mode band shows is not stored anywhere: it's a projection of\n * plugin-shell's exclusive 'mode' surface, read null-safely so the band simply\n * doesn't exist without a document.\n */\nimport { useMemo, type ReactNode } from 'react';\nimport {\n DocumentGate,\n useDocumentId,\n useDocumentStatus,\n useOptionalSelector,\n} from '@embedpdf/react/runtime';\nimport { Stage } from '@embedpdf/react/stage';\nimport { Scrollbar } from '@embedpdf/react/scrollbar';\nimport { RenderLayer } from '@embedpdf/react/render';\nimport { SelectionClipboard, SelectionHandles, SelectionLayer } from '@embedpdf/react/selection';\nimport { AnnotationLayer, useFilePickerProvider } from '@embedpdf/react/annotation';\nimport { LinkLayer } from '@embedpdf/react/link';\nimport type { AnnotationRenderer } from '@embedpdf/react/annotation';\nimport { formWidgetRenderer, useFormScriptingProvider } from '@embedpdf/react/form';\nimport { SearchLayer } from '@embedpdf/react/search';\nimport { useCommandShortcuts } from '@embedpdf/react/commands';\nimport { ShellToken } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { getModeBar } from './config/chrome';\nimport { useChromeSchema } from './config-context';\nimport { AppToolbar } from './ui/toolbar';\nimport { AnnotationStrip } from './ui/annotation-strip';\nimport { SelectionStrip } from './ui/selection-strip';\nimport { TabBar } from './ui/tab-bar';\nimport { ArmedToolCursor } from './ui/tool-cursor';\nimport { LeftSidebar, RightSidebar, PageControls } from './ui/panels';\nimport { RedactConfirmModal } from './ui/redact-confirm';\nimport { DocumentError, PasswordPrompt } from './ui/document-boot';\n\n// Annotation renderers — module scope, per the AnnotationRenderer identity\n// rule. One entry today: form widgets render as fill controls while the form\n// plugin's Behavior is engaged.\nconst ANNOTATION_RENDERERS: AnnotationRenderer[] = [formWidgetRenderer];\n\nfunction ModeBand({ edge }: { edge: 'top' | 'bottom' }) {\n const schema = useChromeSchema();\n // The mode list is DERIVED from the chrome's modeBars keys — adding a custom\n // mode is one command + one bar schema in config, not a shell change.\n const modeSurfaces = useMemo(() => Object.keys(schema.modeBars ?? {}), [schema]);\n const activeMode = useOptionalSelector(\n ShellToken,\n (s) => modeSurfaces.find((m) => s.isOpen(m)) ?? null,\n null,\n );\n if (!activeMode) return null;\n const bar = getModeBar(schema, activeMode);\n if (!bar) return null;\n return (\n <div\n className={`border-border bg-surface-alt flex shrink-0 items-center px-4 py-2 ${\n edge === 'top' ? 'border-b' : 'border-t'\n }`}\n >\n <AppToolbar bar={bar} className=\"w-full\" />\n </div>\n );\n}\n\n/** The empty-workspace state: shown while the initial documents (and the\n * engine behind them) are still loading — or if the user closes every tab. */\nfunction OpeningDocuments() {\n const t = useT();\n return (\n <div className=\"grid h-full w-full place-items-center\">\n <div className=\"text-fg-muted flex flex-col items-center gap-3\">\n <div className=\"border-border-subtle border-t-accent h-8 w-8 animate-spin rounded-full border-2\" />\n <div className=\"text-sm\">{t('demo.opening')}</div>\n </div>\n </div>\n );\n}\n\n/**\n * The document area's lifecycle switch. A `locked` tab shows its password\n * prompt, an `error` tab its error pane — per TAB (keyed by document), so\n * several can coexist and tab switching stays free. Everything else is the\n * ready-gated Stage; the gate's fallback covers `loading`.\n */\nfunction DocumentArea({ children }: { children: ReactNode }) {\n const docId = useDocumentId();\n const status = useDocumentStatus();\n if (status === 'locked') return <PasswordPrompt key={docId} />;\n if (status === 'error') return <DocumentError key={docId} />;\n return <DocumentGate fallback={<OpeningDocuments />}>{children}</DocumentGate>;\n}\n\nexport function Shell() {\n useCommandShortcuts();\n // Click-then-pick tools (stamp, file attachment) → click a page → file dialog\n // opens → the file lands where you clicked. One line: the default provider is\n // the built-in file picker honouring each tool's `accept` filter (swap it for\n // a custom picker, or pass null to disable). The plugin stays DOM-free.\n useFilePickerProvider();\n // Form scripts stay inside the isolated form pipeline; this hook fulfils the\n // resulting alert, page-navigation, and print UI requests in the React shell.\n useFormScriptingProvider();\n const schema = useChromeSchema();\n\n // The FRAME: region arrangement & visibility from the chrome value (see\n // FrameSchema). Regions render as named <slot> sockets with the built-ins\n // as fallback — light-DOM children of <embedpdf-viewer> replace them; in\n // plain light DOM a slot just displays its fallback (UA display:contents),\n // so this package's direct React consumers see no difference. A region\n // hidden by the frame hides its socket too: visibility outranks content.\n const frame = schema.frame ?? {};\n const toolbarEdge = frame.toolbar ?? 'top';\n\n // main toolbar — measured; degrades + overflows with zero config.\n // Deliberately OUTSIDE the gate: chrome renders before any document.\n // Bar id 'main' is the shell's one structural expectation — an owned\n // chrome without it simply has no main toolbar. Its mode band rides the\n // CONTENT side, whichever edge the frame picked.\n const toolbarBand = schema.bars.main && (\n <div\n part=\"toolbar\"\n className={`border-border bg-surface flex shrink-0 items-center px-4 py-2 ${\n toolbarEdge === 'top' ? 'border-b' : 'border-t'\n }`}\n >\n <AppToolbar bar={schema.bars.main} className=\"w-full\" />\n </div>\n );\n\n return (\n <div className=\"bg-app text-fg flex h-full flex-col\">\n {/* The header socket. The chrome ships NO header of its own — branding,\n locale pickers and theme switches are the embedder's chrome, not the\n viewer's — so this renders nothing until a child fills the slot. */}\n {(frame.header ?? true) && <slot name=\"header\" />}\n\n {/* the v2 document tab bar — the kernel's document registry IS the tab model */}\n {(frame.tabs ?? 'always') !== 'never' && (\n <slot name=\"tabs\">\n <TabBar visibility={frame.tabs ?? 'always'} />\n </slot>\n )}\n\n {toolbarEdge === 'top' && (\n <>\n {toolbarBand}\n <ModeBand edge=\"top\" />\n </>\n )}\n\n <div className=\"relative flex min-h-0 flex-1\">\n <DocumentArea>\n <LeftSidebar />\n <div className=\"relative min-w-0 flex-1\">\n {/* the armed tool's cursor: its toolbar icon as a real CSS cursor\n (zero-lag; the hub hides it over annotations/fields/gaps) */}\n <ArmedToolCursor />\n {/* ctrl/cmd+C and native Edit→Copy for the text selection —\n prefetches on commit so the copy event answers synchronously.\n Renders nothing; mount ONCE per document view. */}\n <SelectionClipboard />\n <Stage\n overlay={\n <>\n <AnnotationStrip />\n <SelectionStrip />\n {/* touch: draggable start/end selection handles (long-press\n selects a word; the lollipops grow it from there) */}\n <SelectionHandles />\n {/* headless scrollbars: geometry/behavior from the stage's\n scroller contract; the look is index.css (data-attrs) */}\n <Scrollbar axis=\"y\" />\n <Scrollbar axis=\"x\" />\n </>\n }\n className=\"h-full w-full\"\n style={{ background: 'var(--ep-canvas)' }}\n >\n {() => (\n <>\n {/* Base + deep-zoom tiles in one layer. Tiles engage by\n demand arithmetic when the view wants more pixels than\n the base budget supplies — the thumbnail rail's demand\n never does, so it mounts the same layer for free. */}\n <RenderLayer annotations={false} />\n <SelectionLayer />\n <SearchLayer />\n {/* Clickable links (nav plane): anchors under the default\n pointer/pan tools; stands down whenever an authoring\n tool is active (the annotation plane owns links then).\n Below the AnnotationLayer so an editing free-text box\n wins pointer hits; the annotation layer's own surface\n is pointer-events: none, so clicks fall through to the\n anchors everywhere else. */}\n <LinkLayer />\n {/* Form widgets plug into the annotation stack: engaged\n (fill mode) they render as fill controls over the baked\n appearance; under the Form tab they're plain editable\n annotations. */}\n <AnnotationLayer renderers={ANNOTATION_RENDERERS} />\n </>\n )}\n </Stage>\n <PageControls />\n </div>\n <RightSidebar />\n <RedactConfirmModal />\n </DocumentArea>\n </div>\n\n {toolbarEdge === 'bottom' && (\n <>\n <ModeBand edge=\"bottom\" />\n {toolbarBand}\n </>\n )}\n </div>\n );\n}\n","/**\n * The full viewer, as a component — and the customization CONTRACT. The\n * `ViewerCustomization` surface here is the exact shape that later powers\n * `EmbedPDF.init({...})` and every framework wrapper, because all of it is\n * plain data (see README.md).\n *\n * Two semantics, on purpose:\n * - REGISTRIES (commands / icons / strings) merge ADDITIVELY over the\n * defaults by id; a colliding id overrides.\n * - STRUCTURE (chrome) is an owned VALUE: the default, a transform of it,\n * or the host's own schema — never merged.\n *\n * The engine stays a prop — choosing local-wasm vs cloud is the host's\n * decision, and each delivery wires its own. The chrome —\n * toolbars, translations, theme — renders at t≈0; only the pages wait on\n * the engine. Customization is mount-time (exactly like v2's init config);\n * changing these props on a mounted viewer does not rebuild the workspace.\n */\n// One import line per feature: each subpath carries the\n// plugin AND its UI; delete a line and the feature leaves the bundle.\nimport { useEffect, useState, type ReactNode } from 'react';\nimport { Viewer, useKernel } from '@embedpdf/react/runtime';\nimport type { Engine, EngineFactory, InitialDocument } from '@embedpdf/react/runtime';\nimport { stagePlugin } from '@embedpdf/react/stage';\nimport { renderPlugin } from '@embedpdf/react/render';\nimport { pageEditPlugin } from '@embedpdf/react/page-edit';\nimport { feedbackPlugin, interactionPlugin, vibrationFeedback } from '@embedpdf/react/interaction';\nimport { selectionPlugin } from '@embedpdf/react/selection';\nimport { annotationPlugin } from '@embedpdf/react/annotation';\nimport { redactionPlugin } from '@embedpdf/react/redaction';\nimport { formPlugin } from '@embedpdf/react/form';\nimport { linkPlugin } from '@embedpdf/react/link';\nimport { searchPlugin } from '@embedpdf/react/search';\nimport { i18nPlugin, negotiateLocale, useT } from '@embedpdf/react/i18n';\nimport type { Locale, TranslationDictionary } from '@embedpdf/react/i18n';\nimport { commandsPlugin } from '@embedpdf/react/commands';\nimport type { CommandDef } from '@embedpdf/react/commands';\nimport { shellPlugin } from '@embedpdf/react/shell';\nimport { chromeHelpers, validateChrome } from '@embedpdf/react/toolbar';\nimport type { ChromeHelpers, ChromeSchema } from '@embedpdf/react/toolbar';\nimport { ThumbsStageToken } from './config/stage';\nimport { defaultChrome } from './config/chrome';\nimport { defaultCommands } from './config/commands';\nimport { demoToolsPlugin } from './config/demo-tools.plugin';\nimport { en } from './locales/en';\nimport { ViewerConfigProvider, type ResolvedViewerConfig } from './config-context';\nimport { createViewerHandle, type ViewerHandle } from './handle';\nimport { ICON_PATHS, type IconDef } from './ui/icons';\nimport { ThemeProvider, type ThemePreference } from './ui/theme';\nimport { Shell } from './Shell';\n\n/** Lazy built-in packs — a strings override for one of these wraps its loader. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<Locale>> = {\n es: () => import('./locales/es').then((m) => m.es),\n};\n\nconst isDict = (v: unknown): v is TranslationDictionary => typeof v === 'object' && v !== null;\n\n/**\n * Deep-merge `over` into `base` (immutably), expanding dotted keys —\n * `{ 'acme.send': 'X' }` and `{ acme: { send: 'X' } }` are the same override.\n */\nfunction mergeTranslations(\n base: TranslationDictionary,\n over: TranslationDictionary,\n): TranslationDictionary {\n const out: Record<string, string | TranslationDictionary> = { ...base };\n for (const [key, value] of Object.entries(over)) {\n const path = key.split('.');\n let node = out;\n for (let i = 0; i < path.length - 1; i++) {\n const prev = node[path[i]];\n node = (node[path[i]] = isDict(prev) ? { ...prev } : {}) as Record<\n string,\n string | TranslationDictionary\n >;\n }\n const leaf = path[path.length - 1];\n const prev = node[leaf];\n node[leaf] =\n typeof value === 'string' ? value : mergeTranslations(isDict(prev) ? prev : {}, value);\n }\n return out;\n}\n\nconst mergeLocale = (pack: Locale, over?: TranslationDictionary): Locale =>\n over ? { ...pack, translations: mergeTranslations(pack.translations, over) } : pack;\n\n/**\n * The customization surface — identical in the vanilla snippet and every\n * framework wrapper. See README.md for the ladder this implements.\n */\nexport interface ViewerCustomization {\n /** ADDITIVE over the default vocabulary; a colliding id overrides. */\n commands?: readonly CommandDef[];\n /** ADDITIVE 24×24 stroke icons by name; a colliding name overrides. */\n icons?: Readonly<Record<string, IconDef>>;\n /** Per-locale translation overrides/additions; dotted keys expand. A code\n * with no built-in pack becomes a new locale (falls back to English). */\n strings?: Readonly<Record<string, TranslationDictionary>>;\n /** 'auto' (default) negotiates from the browser languages. */\n locale?: 'auto' | (string & {});\n /** Feature gating: a disabled category vanishes from every surface. */\n disabledCategories?: readonly string[];\n /** The structure — a value you OWN: the default (pass nothing), a transform\n * of it, or your own schema. Never merged. */\n chrome?: ChromeSchema | ((base: ChromeSchema, helpers: ChromeHelpers) => ChromeSchema);\n /** Light/dark preference (string shorthand), or the full theme config with\n * `--ep-*` token overrides. Tokens are applied by the DELIVERY (the custom\n * element adopts them into its shadow root); direct consumers of this\n * package set the `--ep-*` variables in their own CSS instead. */\n theme?: ThemePreference | ThemeConfig;\n}\n\n/** Token overrides — names WITHOUT the `--ep-` prefix ('accent', 'surface'…). */\nexport type ThemeTokens = Readonly<Record<string, string>>;\n\nexport interface ThemeConfig {\n /** 'system' (default) follows the OS. */\n preference?: ThemePreference;\n /** Applied in BOTH modes (a later sheet: wins over the defaults). */\n tokens?: ThemeTokens;\n /** Dark-mode-only overrides, applied over `tokens`. */\n dark?: ThemeTokens;\n}\n\n/** Normalize the shorthand — deliveries use this to read one shape. */\nexport const themeConfigOf = (theme: ThemePreference | ThemeConfig | undefined): ThemeConfig =>\n typeof theme === 'string' ? { preference: theme } : (theme ?? {});\n\nexport interface FullViewerProps extends ViewerCustomization {\n /** Instance (borrowed) or thunk (viewer-owned) — the Viewer's own contract. */\n engine: Engine | EngineFactory;\n /** Documents to open at mount; more arrive via the tab bar's open button. */\n initialDocuments?: InitialDocument[];\n /** Shown while the workspace boots. Default: a translated pulse line. */\n fallback?: ReactNode;\n /** Where the theme's `.dark` class goes — a DELIVERY concern, not user\n * config: the custom element passes its shadow wrapper so theming never\n * touches the host page. Default: document.documentElement. */\n themeTarget?: HTMLElement | null;\n /** Called once the workspace kernel is live, with the viewer handle — the\n * DRIVE surface (`el.viewer` on the custom element, `onReady` on the\n * wrappers). Capabilities resolve from the moment this fires; document-\n * scoped calls simply await their document. */\n onViewer?: (viewer: ViewerHandle) => void;\n}\n\n/** Inside <Viewer>: mints the handle from the live kernel, reports it up. */\nfunction HandleBridge({ onViewer }: { onViewer: (viewer: ViewerHandle) => void }) {\n const kernel = useKernel();\n useEffect(() => {\n onViewer(createViewerHandle(kernel));\n // Init-only like everything else: re-fires only if the KERNEL changes\n // (a remount), never because the callback prop identity churned.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [kernel]);\n return null;\n}\n\nfunction Booting() {\n const t = useT();\n return (\n <div className=\"bg-app text-fg-muted grid h-full place-items-center\">\n <div className=\"animate-pulse text-sm\">{t('demo.starting')}</div>\n </div>\n );\n}\n\nexport function FullViewer({\n engine,\n initialDocuments,\n fallback,\n commands,\n icons,\n strings,\n locale = 'auto',\n disabledCategories,\n chrome,\n theme,\n themeTarget,\n onViewer,\n}: FullViewerProps) {\n // Customization is INIT-ONLY, exactly like v2's `EmbedPDF.init` (and like\n // the Viewer's own engine/plugins contract): the whole config resolves ONCE\n // from the mount-time props, so inline literals — the idiomatic way to pass\n // it — never churn plugin identities. Later prop changes are ignored.\n const [resolved] = useState(() => {\n // ── registries: additive, user wins by id ───────────────────────────────\n const byId = new Map(defaultCommands.map((c) => [c.id, c]));\n for (const c of commands ?? []) byId.set(c.id, c);\n const resolvedCommands = [...byId.values()];\n\n // ── structure: an owned value (default | transform | replacement) ───────\n const resolvedChrome =\n typeof chrome === 'function'\n ? chrome(defaultChrome, chromeHelpers)\n : (chrome ?? defaultChrome);\n\n // ── locale packs: overrides merge into built-ins; unknown codes become\n // new locales that fall back to English ──────────────────────────────\n const overrides = strings ?? {};\n const locales: Locale[] = [mergeLocale(en, overrides.en)];\n const loaders: Record<string, () => Promise<Locale>> = {};\n for (const [code, load] of Object.entries(BUILTIN_LOADERS)) {\n const over = overrides[code];\n loaders[code] = over ? () => load().then((pack) => mergeLocale(pack, over)) : load;\n }\n for (const [code, over] of Object.entries(overrides)) {\n if (code === 'en' || code in BUILTIN_LOADERS) continue;\n locales.push({ code, name: code, translations: mergeTranslations({}, over) });\n }\n const codes = [...new Set(['en', ...Object.keys(BUILTIN_LOADERS), ...Object.keys(overrides)])];\n const initial =\n locale === 'auto'\n ? (negotiateLocale(codes, typeof navigator !== 'undefined' ? navigator.languages : []) ??\n 'en')\n : locale;\n\n return {\n commands: resolvedCommands,\n chrome: resolvedChrome,\n icons: icons ?? {},\n i18n: { locales, loaders, initial },\n };\n });\n\n // Dev guardrail: every id the chrome references must exist; every icon a\n // command names must resolve. Warnings name the exact id (README promise).\n useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n const ids = new Set(resolved.commands.map((c) => c.id));\n for (const problem of validateChrome(resolved.chrome, ids)) {\n console.warn(`[embedpdf] chrome: ${problem}`);\n }\n for (const c of resolved.commands) {\n if (c.icon && !(c.icon in ICON_PATHS) && !(c.icon in resolved.icons)) {\n console.warn(`[embedpdf] command \"${c.id}\": unknown icon \"${c.icon}\"`);\n }\n }\n }, [resolved]);\n\n const [plugins] = useState(() => [\n stagePlugin({ layout: 'vertical' }), // main lens (tools engage via interactionPlugin below)\n // Thumbnail lens over the SAME document: a single-column grid at a fixed small\n // zoom, its own camera. Click a thumb to navigate the main lens; the sidebar\n // follows the main view (see ui/panels ThumbnailList).\n stagePlugin({\n id: 'stage-thumbs',\n token: ThumbsStageToken,\n layout: 'grid',\n columns: 1, // single column, like the v2 snippet's thumbnail rail\n sizing: 'uniform', // equalize pages so the pixel target hits every thumb\n zoom: { pageWidth: 150 }, // thumbs are 150 SCREEN px wide — for ANY document\n padding: 12,\n gap: { px: 16 }, // UI-stable spacing between thumbs\n pageFrame: { top: 0, right: 0, bottom: 20, left: 0 }, // reserved label band (screen px)\n fitAlign: { x: 'center', y: 'start' }, // few pages? thumbs hug the TOP\n scrollBehavior: 'instant',\n }),\n renderPlugin(),\n pageEditPlugin(),\n interactionPlugin(),\n // Platform haptics, default-on: the Vibration API where it exists\n // (Android), a safe silent no-op elsewhere — iOS Safari included, until\n // Apple ships a haptics API. Native shells swap in their own provider\n // (`wkFeedback`) instead.\n feedbackPlugin({ provider: vibrationFeedback }),\n selectionPlugin(),\n // The arrow tool is a `line` preset — same subtype, an arrowhead default. This is\n // the whole integration for a new tool: one `tools` entry + a command/toolbar\n // slot (see config/commands.ts + config/chrome.ts).\n annotationPlugin({\n tools: [\n {\n id: 'arrow',\n extends: 'line',\n defaults: { lineEndings: { start: 'none', end: 'open-arrow' } },\n },\n ],\n }),\n // Forms: fillable under the default pointer/pan (widgets render as fill\n // controls), editable under the Form tab's 'form-edit' + palette tools.\n formPlugin({ scripting: { enabled: true } }),\n // Links: navigable under the default pointer/pan ('link-nav'), editable\n // under the link tool — the annotation plane then owns them (select, move,\n // retarget via the style panel's Link control).\n linkPlugin(),\n // Redaction: marking is the annotation plane's composed `redact` tool; this\n // plugin adds the pending-queue view + the destructive apply.\n redactionPlugin(),\n searchPlugin(),\n demoToolsPlugin(),\n i18nPlugin({\n locale: resolved.i18n.initial,\n fallbackLocale: 'en',\n locales: resolved.i18n.locales,\n loaders: resolved.i18n.loaders,\n }),\n commandsPlugin({\n commands: resolved.commands,\n disabledCategories: disabledCategories ? [...disabledCategories] : undefined,\n }),\n shellPlugin(),\n ]);\n\n // Structural subset of `resolved`, identity-stable across renders.\n const config: ResolvedViewerConfig = resolved;\n\n return (\n <ThemeProvider preference={themeConfigOf(theme).preference} target={themeTarget}>\n <Viewer\n engine={engine}\n plugins={plugins}\n initialDocuments={initialDocuments}\n fallback={fallback ?? <Booting />}\n >\n <ViewerConfigProvider value={config}>\n {onViewer && <HandleBridge onViewer={onViewer} />}\n <Shell />\n </ViewerConfigProvider>\n </Viewer>\n </ThemeProvider>\n );\n}\n"],"mappings":"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CACR,CACF;CACA,OAAO;EACL;EACA;EACA;CACF;CACA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAIA,YAAY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kBAAkB;EAChB;EACA;EACA;EACA;EACA;CACF;CACA,aAAa;EACX;GAAE,GAAG;GAAgB,QAAQ;EAAU;EACvC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAW,QAAQ;EAAU;EAClC;GAAE,GAAG;GAAiB,QAAQ;EAAU;EACxC;GAAE,GAAG;GAAe,QAAQ;EAAU;EACtC;GAAE,GAAG;GAA4B,QAAQ;EAAU;CACrD;CACA,iBAAiB,CAAC,oCAAoC;CACtD,wBAAwB,CAAC,sCAAsC;CAC/D,aAAa,CACX,0IACA,UACF;CACA,iBAAiB;EACf;EACA;EACA;EACA;EACA;CACF;CACA,MAAM;EACJ;EACA;EACA;CACF;CACA,YAAY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,QAAQ,CAAC,8CAA8C,cAAc;CACrE,UAAU,CACR,+gBACA,oCACF;CACA,SAAS,CACP,oFACA,iFACF;CACA,WAAW,CACT,wLACF;CACA,YAAY,CAAC,iFAAiF;CAC9F,QAAQ,CACN;EACE,GAAG;EACH,QAAQ;EACR,MAAM;CACR,CACF;CACA,SAAS,CACP,6EACA,8DACF;CACA,UAAU;EACR;EACA;EACA;GAAE,GAAG;GAAwD,QAAQ;EAAU;CACjF;CACA,eAAe,CAAC,4BAA4B;EAAE,GAAG;EAAY,QAAQ;CAAU,CAAC;CAChF,MAAM;EACJ;EACA;EACA;EACA;CACF;CACA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;CACA,WAAW;EAAC;GAAE,GAAG;GAAY,QAAQ;EAAU;EAAG;EAA4B;CAAS;CAEvF,SAAS,CACP,4EACA,4EACF;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"}
|