@embedpdf/core-annotation 3.0.0-next.13 → 3.0.0-next.15
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/README.md +90 -0
- package/dist/index.cjs +8812 -5255
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1668 -962
- package/dist/index.d.ts +1668 -962
- package/dist/index.js +8719 -5234
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["NO_ANNOTATION_FLAGS","textQuadPoints","NO_ENDINGS","unionBoundsOf"],"sources":["../src/kinds.ts","../src/flags.ts","../src/plane.ts","../src/group.ts","../src/cloudy.ts","../src/endings.ts","../src/geometry.ts","../src/anchor.ts","../src/hit.ts","../src/links.ts","../src/props.ts","../src/placement.ts","../src/richtext.ts","../src/snap.ts","../src/ink.ts","../src/update.ts","../src/scene.ts","../src/view.ts"],"sourcesContent":["/**\n * The annotation KIND table — the single declarative source for \"what an\n * annotation of this subtype IS and what you can do to it\". Pure DATA (no\n * closures), keyed by subtype, so it ports to Rust as a static table and replaces\n * the scattered `subtype`/`geom.t` switches and the old binary `EDITABLE_SUBTYPES`.\n *\n * Two layers meet here:\n * • `variant` — which {@link Geom} primitive the kind renders/hit-tests as.\n * Several subtypes share one (square+circle → `rect`, the markups → `quads`).\n * • `caps` — ORTHOGONAL capability flags. \"Editable\" was one boolean that\n * conflated selectable / movable / resizable / vertex-editable; splitting it\n * is what lets text-markup be *selectable but not movable*, a note icon be\n * *movable but not resizable*, and so on — without new code paths.\n *\n * Creation lives on TOOLS (a later layer), not here: many tools can target one\n * kind (ink vs ink-highlight, line vs arrow). A kind is the editing/identity\n * surface; a tool is the authoring surface.\n */\nimport type { Geom, Subtype } from './types';\n\n/**\n * One editable property of a kind, as a UI contract: which {@link AnnotationProps}\n * key, rendered how (the union arm fixes the control + its constraints), labelled\n * what by default. A property sidebar is a `switch (spec.key)` over these — the\n * per-kind lists below are the v2 snippet's hand-rolled `TOOL_PROPERTIES` schema,\n * promoted into the library so every consumer gets it for free.\n *\n * `label` is a default (English) display name — apps with i18n map `key`s to\n * their own strings and ignore it. Array ORDER is display order.\n */\nexport type PropSpec =\n | { key: 'color'; label: string }\n | { key: 'interiorColor'; label: string }\n | { key: 'fontColor'; label: string }\n | { key: 'opacity'; label: string; min: number; max: number; step: number }\n | { key: 'strokeWidth'; label: string; min: number; max: number; step: number }\n | { key: 'fontSize'; label: string; min: number; max: number; step: number }\n /** Border style picker; `cloudy` says whether this kind honours a cloudy border. */\n | { key: 'border'; label: string; cloudy: boolean }\n | { key: 'lineEndings'; label: string }\n | { key: 'fontFamily'; label: string }\n | { key: 'textAlign'; label: string }\n /** Rich-text formatting toggles (free text): the body's formatting, or —\n * while the text editor has a range — that range's runs. */\n | { key: 'bold'; label: string }\n | { key: 'italic'; label: string }\n | { key: 'underline'; label: string }\n | { key: 'blendMode'; label: string }\n /** `/Name` icon picker for icon kinds; `options` are the legal names. */\n | { key: 'icon'; label: string; options: readonly string[] }\n /** Link-target editor (URL / page destination). Declared by the link kind\n * (its own target) and by every kind that may carry an ATTACHED link;\n * kinds that omit it (widgets, caret, redact…) simply cannot be links —\n * `applyProps` drops the key and menus never show the control. */\n | { key: 'link'; label: string };\n\n/** Orthogonal capability flags. Static data — the annotation's `/F` flags are\n * the runtime overrides (a locked annotation is never transformable, a hidden\n * one never renders, regardless of these — see flags.ts). */\nexport interface KindCaps {\n /** Can be clicked to select. */\n selectable: boolean;\n /** Can be dragged (by its body) to translate. */\n movable: boolean;\n /** Exposes the 8 box resize handles (shapes). */\n resizable: boolean;\n /** Exposes per-vertex handles (line endpoints, polygon/polyline vertices). */\n vertexEditable: boolean;\n /** Can be rotated (shapes, free text, lines/polys/ink). */\n rotatable: boolean;\n /** Can be MOVED as part of a multi-target (group) transform. */\n groupMovable: boolean;\n /** Can be uniformly SCALED as part of a multi-target (group) transform — ON\n * even for vertex kinds that have no single-shape box resize (their handles\n * ARE the vertices; in a group they scale fine). */\n groupResizable: boolean;\n /** Can be ROTATED as part of a multi-target (group) transform. */\n groupRotatable: boolean;\n /** Carries editable text content (free text, the comment popup). */\n textEditable: boolean;\n /** Can carry a comment/note + threaded replies (`/Contents` + `/Popup`). */\n commentable: boolean;\n /** Has a popup as its primary surface (the comment/Text icon). */\n hasPopup: boolean;\n /** Bound to underlying text (markup, caret) — never freely moved/resized. */\n anchored: boolean;\n /** Has an interior fill (`/IC`). */\n hasFill: boolean;\n /** Has line endings (`/LE` — line, polyline). */\n hasEndings: boolean;\n /** Can take a cloudy border effect (`/BE` — shapes). */\n hasCloudy: boolean;\n /** The whole body is visible content, so hit-testing grabs anywhere inside\n * the box (stamp images) — NOT just the stroke/fill like outline shapes. */\n opaqueBody: boolean;\n /** The `/F` ReadOnly flag is IGNORED for this kind (ISO 32000: widgets — a\n * ReadOnly form FIELD must still be movable by a form designer; the\n * form-filling layer enforces field ReadOnly itself). */\n ignoresReadOnly: boolean;\n /** Behaves as if `/F` NoZoom is always set (screen-constant size — the\n * spec's rule for Text/note icons). See anchor.ts. */\n noZoom: boolean;\n /** Behaves as if `/F` NoRotate is always set (screen-upright — the spec's\n * rule for Text/note icons). See anchor.ts. */\n noRotate: boolean;\n}\n\nexport interface AnnotationKind {\n subtype: Subtype;\n /** Future: PDF `/IT` intent (free-text vs callout, caret insert vs replace). */\n intent?: string;\n variant: Geom['t'];\n caps: KindCaps;\n /** The kind's editable properties, in DISPLAY ORDER — the contract a property\n * sidebar renders from (see {@link PropSpec}). Empty = nothing to edit. */\n props: PropSpec[];\n}\n\n/* Shared spec entries — plain data, spread into the per-kind lists below. */\nconst OPACITY: PropSpec = { key: 'opacity', label: 'Opacity', min: 0.1, max: 1, step: 0.05 };\nconst ICON_COLOR: PropSpec = { key: 'color', label: 'Color' };\n\n/* `/Name` values per icon kind — mirrors the engine's NoteIcon /\n * FileAttachmentIcon unions (the appearance generator's vocabulary). */\nconst NOTE_ICONS = [\n 'comment',\n 'key',\n 'note',\n 'help',\n 'new-paragraph',\n 'paragraph',\n 'insert',\n] as const;\nconst FILE_ATTACHMENT_ICONS = ['push-pin', 'paperclip', 'graph', 'tag'] as const;\nconst STROKE: PropSpec = { key: 'color', label: 'Stroke' };\nconst FILL: PropSpec = { key: 'interiorColor', label: 'Fill' };\nconst STROKE_WIDTH: PropSpec = {\n key: 'strokeWidth',\n label: 'Stroke width',\n min: 0.5,\n max: 30,\n step: 0.5,\n};\nconst BORDER_CLOUDY: PropSpec = { key: 'border', label: 'Border', cloudy: true };\nconst BORDER_PLAIN: PropSpec = { key: 'border', label: 'Border', cloudy: false };\nconst LINE_ENDINGS: PropSpec = { key: 'lineEndings', label: 'Line endings' };\nconst BLEND_MODE: PropSpec = { key: 'blendMode', label: 'Blend mode' };\n\n/**\n * \"This annotation links somewhere\" — one spec, shared by every kind that can\n * carry an attached link (a grouped `/Link` child; see AnnotationProps.link).\n * Deliberately absent from: widget-* (a widget's `/A` is forms-plane\n * behavior, not an attached link), caret (an anchored edit marker),\n * file-attachment (its click means \"open the attachment\"), and redact.\n */\nconst LINKABLE: PropSpec = { key: 'link', label: 'Link' };\n\n/** Shapes with a fill + a (possibly cloudy) border: square / circle / polygon. */\nconst SHAPE_PROPS: PropSpec[] = [STROKE, FILL, OPACITY, STROKE_WIDTH, BORDER_CLOUDY, LINKABLE];\n\n// Widget-plane styling: every family has a box; text-bearing families add\n// the /DA vocabulary. Same flat keys as every other kind — the writer maps\n// them onto /MK//BS//DA//Q underneath. One PDF subtype, several CLIENT\n// kinds (the free-text/callout precedent): the field FAMILY picks the kind,\n// so a radio never offers a font and the schema-driven sidebar needs no\n// widget-specific code.\nconst WIDGET_BOX_PROPS: PropSpec[] = [\n { key: 'color', label: 'Border color' },\n { key: 'interiorColor', label: 'Background' },\n { key: 'strokeWidth', label: 'Border width', min: 0, max: 12, step: 0.5 },\n { key: 'border', label: 'Border style', cloudy: false },\n];\nconst WIDGET_TEXT_PROPS: PropSpec[] = [\n ...WIDGET_BOX_PROPS,\n { key: 'fontFamily', label: 'Font' },\n { key: 'fontSize', label: 'Font size', min: 0, max: 96, step: 1 },\n { key: 'fontColor', label: 'Text color' },\n { key: 'textAlign', label: 'Alignment' },\n];\n/** Stroked vertex kinds with `/LE` endings: line / polyline. The fill colours a\n * CLOSED ending (closed arrow / circle / square / diamond). */\nconst LINE_PROPS: PropSpec[] = [\n STROKE,\n FILL,\n OPACITY,\n STROKE_WIDTH,\n BORDER_PLAIN,\n LINE_ENDINGS,\n LINKABLE,\n];\n/** Text markup: colour/opacity plus its appearance-stream blend mode. */\nconst MARK_PROPS: PropSpec[] = [{ key: 'color', label: 'Color' }, OPACITY, BLEND_MODE, LINKABLE];\n/** Carets are anchored text-edit markers, without a blend-mode control. */\nconst CARET_PROPS: PropSpec[] = [{ key: 'color', label: 'Color' }, OPACITY];\nconst INK_PROPS: PropSpec[] = [\n { key: 'color', label: 'Color' },\n OPACITY,\n STROKE_WIDTH,\n BLEND_MODE,\n LINKABLE,\n];\n/** Redaction marks: outline at rest; the fill + label are what apply paints.\n * Label size 0 = auto-fit to the region (the engine's convention). */\nconst REDACT_PROPS: PropSpec[] = [\n { key: 'color', label: 'Outline' },\n FILL,\n OPACITY,\n { key: 'fontFamily', label: 'Label font' },\n { key: 'fontSize', label: 'Label size', min: 0, max: 96, step: 1 },\n { key: 'fontColor', label: 'Label color' },\n { key: 'textAlign', label: 'Align' },\n];\n/** Free text: font first (the primary surface), then box background + border. */\nconst TEXT_PROPS: PropSpec[] = [\n { key: 'fontFamily', label: 'Font' },\n { key: 'fontSize', label: 'Font size', min: 4, max: 96, step: 1 },\n { key: 'fontColor', label: 'Text color' },\n { key: 'bold', label: 'Bold' },\n { key: 'italic', label: 'Italic' },\n { key: 'underline', label: 'Underline' },\n { key: 'textAlign', label: 'Align' },\n OPACITY,\n { key: 'interiorColor', label: 'Background' },\n { key: 'color', label: 'Border' },\n { key: 'strokeWidth', label: 'Border width', min: 0, max: 12, step: 0.5 },\n LINKABLE,\n];\n\n/** Build caps from a sparse override — everything not named is `false`. */\nconst caps = (c: Partial<KindCaps>): KindCaps => ({\n selectable: false,\n movable: false,\n resizable: false,\n vertexEditable: false,\n rotatable: false,\n groupMovable: false,\n groupResizable: false,\n groupRotatable: false,\n textEditable: false,\n commentable: false,\n hasPopup: false,\n anchored: false,\n hasFill: false,\n hasEndings: false,\n hasCloudy: false,\n opaqueBody: false,\n ignoresReadOnly: false,\n noZoom: false,\n noRotate: false,\n ...c,\n});\n\n/** Read-only fallback for unknown/unsupported subtypes (render baked, no editing). */\nconst READONLY: KindCaps = caps({});\n\n/** The built-in kinds. Shapes resize, lines/polys vertex-edit, markup is anchored\n * (selectable + recolor/delete, never move/resize). */\nexport const KINDS: Record<string, AnnotationKind> = {\n 'widget-text': {\n subtype: 'widget-text',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_TEXT_PROPS,\n },\n 'widget-choice': {\n subtype: 'widget-choice',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_TEXT_PROPS,\n },\n 'widget-button': {\n subtype: 'widget-button',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_TEXT_PROPS,\n },\n 'widget-toggle': {\n subtype: 'widget-toggle',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_BOX_PROPS,\n },\n 'widget-box': {\n subtype: 'widget-box',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n ignoresReadOnly: true,\n }),\n props: WIDGET_BOX_PROPS,\n },\n 'free-text': {\n subtype: 'free-text',\n variant: 'text',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true, // the box resizes (8 handles); text reflows\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n textEditable: true,\n commentable: true,\n hasFill: true, // `/C` box background\n }),\n props: TEXT_PROPS,\n },\n square: {\n subtype: 'square',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n }),\n props: SHAPE_PROPS,\n },\n circle: {\n subtype: 'circle',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n }),\n props: SHAPE_PROPS,\n },\n line: {\n subtype: 'line',\n variant: 'line',\n caps: caps({\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasEndings: true,\n }),\n props: LINE_PROPS,\n },\n polygon: {\n subtype: 'polygon',\n variant: 'poly',\n caps: caps({\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n }),\n props: SHAPE_PROPS,\n },\n polyline: {\n subtype: 'polyline',\n variant: 'poly',\n caps: caps({\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasEndings: true,\n }),\n props: LINE_PROPS,\n },\n // Ink: freehand strokes. Selectable + movable as a whole; no single-shape\n // resize/vertex handles (the strokes are the geometry), but rotatable and\n // group-resizable. Created by a freehand drag.\n ink: {\n subtype: 'ink',\n variant: 'ink',\n caps: caps({\n selectable: true,\n movable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n }),\n props: INK_PROPS,\n },\n // Text markup: selectable + anchored (bound to text — recolor/delete, never\n // move/resize). Created from a text selection, not a drag (see the markup tool).\n highlight: {\n subtype: 'highlight',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n underline: {\n subtype: 'underline',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n squiggly: {\n subtype: 'squiggly',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n strikeout: {\n subtype: 'strikeout',\n variant: 'quads',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: MARK_PROPS,\n },\n // Redaction mark (the non-destructive stage of the two-stage model): created\n // from a text selection (per-line quads) OR an area drag (rect-only geometry).\n // Text marks are anchored like markup; area marks move/resize — the\n // anchored+quads transform gate in hit.ts lets one caps set serve both\n // geometries.\n redact: {\n subtype: 'redact',\n variant: 'quads',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n anchored: true,\n commentable: true,\n hasFill: true,\n }),\n props: REDACT_PROPS,\n },\n caret: {\n subtype: 'caret',\n variant: 'caret',\n caps: caps({ selectable: true, anchored: true, commentable: true }),\n props: CARET_PROPS,\n },\n // Sticky note (\"comment\"): a fixed 20x20 icon whose visual is the\n // engine-baked /AP (generated from /C + /Name). Screen-constant and\n // screen-upright per the spec's Text-icon rule (noZoom/noRotate); its\n // popup thread is the primary surface once comments land.\n text: {\n subtype: 'text',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n groupMovable: true,\n commentable: true,\n hasPopup: true,\n opaqueBody: true,\n noZoom: true,\n noRotate: true,\n }),\n props: [{ key: 'icon', label: 'Icon', options: NOTE_ICONS }, ICON_COLOR, OPACITY, LINKABLE],\n },\n // File attachment: the same fixed-icon shape as the note, but its primary\n // surface is the embedded FILE (open/download), not a popup.\n 'file-attachment': {\n subtype: 'file-attachment',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n groupMovable: true,\n commentable: true,\n opaqueBody: true,\n noZoom: true,\n noRotate: true,\n }),\n props: [{ key: 'icon', label: 'Icon', options: FILE_ATTACHMENT_ICONS }, ICON_COLOR, OPACITY],\n },\n // Stamp: a rect-variant kind whose visual is ALWAYS the engine-baked /AP\n // (image or vector appearance authored at create time) — never a vector\n // re-render, so it declares no editable style props. Geometry edits\n // (move/resize/rotate) re-fit the appearance natively on the engine side.\n stamp: {\n subtype: 'stamp',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n opaqueBody: true,\n }),\n props: [LINKABLE],\n },\n // Link: an invisible hit rectangle that navigates somewhere. Paints nothing\n // of its own (scene() skips it; any /AP a PDF baked shows via the page\n // raster); `opaqueBody` gives whole-box hit-testing so the invisible rect\n // is grabbable when the link tool makes it editable. Its `link` prop is\n // its OWN target (`/A`) — the one kind where the key doesn't route to an\n // attached child. No rotate: a link has no reading orientation.\n link: {\n subtype: 'link',\n variant: 'rect',\n caps: caps({\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n opaqueBody: true,\n }),\n props: [LINKABLE],\n },\n};\n\n/** The capabilities of a subtype, or the read-only default for unknown kinds. */\nexport const capsFor = (subtype: string): KindCaps => KINDS[subtype]?.caps ?? READONLY;\n\nconst NO_PROPS: PropSpec[] = [];\n\n/** A kind's editable properties in display order — empty for unknown kinds.\n * Stable references, so selectors can compare by identity. */\nexport const propsFor = (subtype: string): PropSpec[] => KINDS[subtype]?.props ?? NO_PROPS;\n\n/** A text-markup kind (highlight/underline/squiggly/strikeout). These are drawn\n * on the text layer, which always sits beneath every other annotation. */\nexport const isMarkup = (subtype: string): boolean => KINDS[subtype]?.variant === 'quads';\n","/**\n * Annotation `/F` flags — the ONE interpretation of ISO 32000-2 Table 167.\n *\n * `Annot.flags` carries the named booleans verbatim from the engine DTO; every\n * behavioral question (can I see it? click it? move it? edit its text?) is\n * answered HERE and nowhere else, so rendering, hit-testing, chrome, and the\n * reducer can never disagree about what a flag means.\n *\n * The flag→behavior split, in one line each:\n * hidden — gone everywhere (screen, interaction, print)\n * noView — gone on screen, may still print\n * toggleNoView — reveals a noView annotation while engaged (v1: selected)\n * readOnly — visible but inert (ignored for widget kinds, per spec —\n * the form layer owns field-level ReadOnly)\n * locked — selectable but frozen: no move/resize/rotate/delete/restyle\n * lockedContents — `/Contents` text cannot change; geometry still can\n * print — include when printing (carried for the print pipeline)\n * noZoom/noRotate — screen-anchored body (see anchor.ts)\n * invisible — legacy: hide unknown subtypes with no handler\n */\nimport { NO_ANNOTATION_FLAGS, type AnnotationFlags } from '@embedpdf/engine-core/runtime';\nimport { capsFor } from './kinds';\n\nexport type { AnnotationFlags };\nexport { NO_ANNOTATION_FLAGS };\n\n/** The `/F` every freshly DRAWN annotation starts with: `print` set (Acrobat\n * parity — without it the annotation silently disappears when printed). */\nexport const DRAWN_FLAGS: AnnotationFlags = { ...NO_ANNOTATION_FLAGS, print: true };\n\n/** All ten flags, for iteration/equality — kept in the primitives' order. */\nexport const FLAG_KEYS = Object.keys(NO_ANNOTATION_FLAGS) as ReadonlyArray<keyof AnnotationFlags>;\n\nexport const flagsEqual = (a: AnnotationFlags, b: AnnotationFlags): boolean =>\n FLAG_KEYS.every((k) => a[k] === b[k]);\n\n/** Merge a partial write over the current flags. */\nexport const mergeFlags = (\n base: AnnotationFlags,\n patch: Partial<AnnotationFlags>,\n): AnnotationFlags => ({\n ...base,\n ...patch,\n});\n\n/**\n * On-screen visibility. `hidden` beats everything; `noView` hides unless\n * `toggleNoView` and the annotation is ENGAGED — the spec says hover/selection,\n * and v1 uses selection (the model tracks no hover).\n */\nexport const viewable = (f: AnnotationFlags, engaged = false): boolean =>\n !f.hidden && (!f.noView || (f.toggleNoView && engaged));\n\n/** Any pointer interaction (click-to-select, hover). ReadOnly kills it. */\nexport const interactive = (f: AnnotationFlags): boolean => !f.hidden && !f.noView && !f.readOnly;\n\n/** The subset of an Annot these predicates read — keeps them testable bare. */\nexport interface FlagBearer {\n subtype: string;\n flags: AnnotationFlags;\n /** Session authority projected at ingest (permissions.md). Absent =\n * unstamped (drafts, wildcard local engines, tests) = allowed. */\n authority?: { update: boolean; delete: boolean };\n}\n\n/** Interaction gate for a concrete annotation: widget kinds ignore `readOnly`\n * (ISO 32000 — a ReadOnly form field must still be movable by a form designer;\n * the form-filling layer enforces field ReadOnly itself). */\nexport const annotInteractive = (a: FlagBearer): boolean =>\n capsFor(a.subtype).ignoresReadOnly ? !a.flags.hidden && !a.flags.noView : interactive(a.flags);\n\n/**\n * Geometry/style mutations — `locked` freezes the OBJECT, not its contents\n * (that's `lockedContents`), AND the session must hold update authority over\n * the record. One predicate for hit-test, chrome, and props alike, so a\n * record you may not edit renders and behaves exactly like a locked one.\n */\nexport const annotTransformable = (a: FlagBearer): boolean =>\n annotInteractive(a) && !a.flags.locked && (a.authority?.update ?? true);\n\n/** Deletion — the delete half of the authority split (a narrowed grant can\n * allow update but not delete, or vice versa). Flags gate like transforms. */\nexport const annotDeletable = (a: FlagBearer): boolean =>\n annotInteractive(a) && !a.flags.locked && (a.authority?.delete ?? true);\n\n/** `/Contents` text edits — the contents counterpart of `locked`. */\nexport const annotContentsEditable = (a: FlagBearer): boolean =>\n annotInteractive(a) && !a.flags.lockedContents && (a.authority?.update ?? true);\n","/**\n * The paint/conversation plane boundary — ONE predicate, consumed by every\n * page surface (paint order, hit-testing, marquee, appearance epoch), so a\n * conversation-plane annotation can never leak onto the page through a\n * surface that forgot to filter.\n *\n * Conversation-only annotations live in the model as first-class `Annot`s\n * (selection, deletion and persistence all work on them) but they are\n * DIALOGUE, not page visuals:\n *\n * - `/RT /R` replies — threaded comment content. Their anchor (the\n * thread root) is the page visual; the reply renders in the comments\n * UI. (`/RT /Group` subordinates are the opposite: parts of ONE\n * composite visual — a caret grouped to a strikeout — and stay on the\n * paint plane.)\n * - ISO 32000 §12.5.6.3 state annotations — text annotations carrying\n * `/State`/`/StateModel`. Review-status metadata about their target,\n * never a visual of their own (foreign producers usually flag them\n * hidden, but classification never relies on flags).\n */\nimport type { Annot } from './types';\n\nconst nonEmpty = (v: string | null | undefined): v is string => typeof v === 'string' && v !== '';\n\n/** True when this annotation belongs to the conversation plane only —\n * never painted, hit, marquee-selected, or counted into a page's\n * appearance epoch. */\nexport function isConversationOnly(\n a: Pick<Annot, 'irt' | 'group' | 'subtype' | 'data'>,\n): boolean {\n // A reply: `irt` without `group` (a grouped subordinate carries both).\n if (a.irt !== undefined && a.group === undefined) return true;\n // A state annotation: a text annot with a non-empty /State or /StateModel.\n if (a.subtype === 'text' && a.data?.subtype === 'text') {\n if (nonEmpty(a.data.state) || nonEmpty(a.data.stateModel)) return true;\n }\n return false;\n}\n\n/**\n * A link CHILD attached to another annotation — a `/Link` grouped\n * (`/IRT` + `/RT /Group`) under a non-link parent. Pure substrate: it is\n * the parent's `link` PROPERTY while authoring (derived via `linkOf`) and\n * the navigation plane's anchor while reading — never painted, never hit\n * as itself. Its rect is RECONCILED from the parent's geometry, so direct\n * manipulation would be overwritten anyway.\n */\nexport function isAttachedLink(a: Pick<Annot, 'subtype' | 'group'>): boolean {\n return a.subtype === 'link' && a.group !== undefined;\n}\n\n/**\n * The ONE page-surface cull: everything that lives in the substrate but is\n * not a page visual of its own — conversation members (replies, review\n * states) and attached link children. Paint order, hit-testing, marquee\n * and the appearance epoch all filter through THIS, never the parts.\n */\nexport function isSubstrateOnly(\n a: Pick<Annot, 'irt' | 'group' | 'subtype' | 'data'>,\n): boolean {\n return isConversationOnly(a) || isAttachedLink(a);\n}\n","/**\n * Group membership — the pure, model-level view of an annotation group.\n *\n * A group is a primary annotation plus its subordinate members. Persistence is\n * the engine's `/IRT` + `/RT /Group` relationship; in the model a subordinate\n * carries `group = <primary's id>` (its `refKey`). The primary is NOT stamped —\n * it is simply the annotation whose `id` equals the group key, so membership is\n * the set of annotations pointing at it plus the primary itself.\n *\n * ATTACHED LINK CHILDREN are the exception: they ride the same `/RT /Group`\n * wire mechanism but are NOT part of the composite visual — they're substrate\n * plumbing (the parent's link property). They never count as members here, so\n * a linked square still selects as a SINGLE annotation with handles, never\n * shows Ungroup, and the ungroup verb can never strip an attached link's\n * `/IRT` (which would orphan it into an unmanaged standalone document link).\n */\nimport { capsFor } from './kinds';\nimport { annotTransformable } from './flags';\nimport { isAttachedLink } from './plane';\nimport type { Annot, Id, Model } from './types';\n\n/** A subordinate that counts toward a VISUAL group (not link plumbing). */\nconst visualMember = (a: Annot | undefined): boolean => !!a && !isAttachedLink(a);\n\n/**\n * The transform capabilities of a multi-target (group) selection: a group can\n * move/resize/rotate only if EVERY member's kind allows that group op AND no\n * member is locked. This is the SINGLE resolver every adapter consumes (v2\n * duplicated the `.every(...)` across three framework components). The iso-vs-\n * aniso resize choice is computed separately, per-gesture, since it depends on\n * the live `rot` of the members, not the static caps.\n */\nexport interface GroupCaps {\n movable: boolean;\n resizable: boolean;\n rotatable: boolean;\n}\n\nexport function groupCaps(m: Model, ids: Id[]): GroupCaps {\n const members = ids.map((id) => m.byId[id]).filter((a): a is NonNullable<typeof a> => !!a);\n if (members.length === 0) return { movable: false, resizable: false, rotatable: false };\n const ok = (pick: (c: ReturnType<typeof capsFor>) => boolean): boolean =>\n members.every((a) => annotTransformable(a) && pick(capsFor(a.subtype)));\n return {\n movable: ok((c) => c.groupMovable),\n resizable: ok((c) => c.groupResizable),\n rotatable: ok((c) => c.groupRotatable),\n };\n}\n\n/**\n * The key of the group `id` belongs to, or `null` when it is ungrouped. A\n * subordinate's key is its `group` field; a primary's key is its own id (it is\n * the target of at least one member's `group`). An annotation that is neither a\n * subordinate nor the target of any subordinate is ungrouped.\n */\nexport function groupKeyOf(m: Model, id: Id): Id | null {\n const a = m.byId[id];\n if (!a) return null;\n if (a.group) return isAttachedLink(a) ? null : a.group;\n for (const other of m.order) {\n const sub = m.byId[other];\n if (sub?.group === id && visualMember(sub)) return id;\n }\n return null;\n}\n\n/**\n * Every member of the group containing `id` (primary first), or just `[id]`\n * when it is ungrouped. The primary is the annotation whose id is the key; the\n * rest are everything whose `group` equals the key, in `order`.\n */\nexport function groupMembers(m: Model, id: Id): Id[] {\n const key = groupKeyOf(m, id);\n if (key == null) return [id];\n const members: Id[] = [];\n if (m.byId[key]) members.push(key);\n for (const other of m.order) {\n const sub = m.byId[other];\n if (other !== key && sub?.group === key && visualMember(sub)) members.push(other);\n }\n return members;\n}\n\n/** Union of every id's full group — the selection seen as whole groups. */\nexport function expandGroups(m: Model, ids: Id[]): Id[] {\n const out: Id[] = [];\n const seen = new Set<Id>();\n for (const id of ids) {\n for (const member of groupMembers(m, id)) {\n if (!seen.has(member)) {\n seen.add(member);\n out.push(member);\n }\n }\n }\n return out;\n}\n","/**\n * Cloudy-border (scalloped outline) path generation for shape annotations.\n *\n * Derived from Apache PDFBox's CloudyBorder.java (Apache-2.0):\n * https://github.com/apache/pdfbox — the arc/curl placement is theirs, and we\n * keep it because it visually matches what PDFium bakes into the `/BE` appearance\n * stream, so our live SVG preview and the saved PDF agree.\n *\n * What's v3-specific: this is a PURE function. It takes a content-space box plus\n * the border `intensity`/`strokeWidth` and returns SVG path data in ABSOLUTE\n * content coordinates (the same space `geomScene`'s rect/ellipse nodes use). There\n * is no stored `/RD`, no border-style enum, no bbox bookkeeping — the inset is\n * derived (`cloudyBorderExtent`) and the outer edge of the scallops lands exactly\n * on the box, so the box stays the annotation's outer boundary (its `/Rect`).\n *\n * The internal math runs in PDFBox's y-UP frame; `PathBuilder` flips back to\n * y-down and translates into the box's content-space origin on the way out.\n */\nimport type { Rect, Vec } from './types';\n\nconst ANGLE_180 = Math.PI;\nconst ANGLE_90 = Math.PI / 2;\nconst ANGLE_34 = (34 * Math.PI) / 180;\nconst ANGLE_30 = (30 * Math.PI) / 180;\nconst ANGLE_12 = (12 * Math.PI) / 180;\n\ninterface P {\n x: number;\n y: number;\n}\n\nconst r = (n: number): string => Number(n.toFixed(4)).toString();\n\n/**\n * Accumulates SVG path commands. Input is PDFBox's y-up frame; output is y-down\n * content space, offset into the box origin (ox, oy) so the `d` string is in the\n * same absolute coordinates as every other render node.\n */\nclass PathBuilder {\n private parts: string[] = [];\n private started = false;\n constructor(\n private ox: number,\n private oy: number,\n ) {}\n moveTo(x: number, y: number): void {\n this.parts.push(`M ${r(x + this.ox)} ${r(-y + this.oy)}`);\n this.started = true;\n }\n curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void {\n this.parts.push(\n `C ${r(x1 + this.ox)} ${r(-y1 + this.oy)}, ${r(x2 + this.ox)} ${r(-y2 + this.oy)}, ${r(x3 + this.ox)} ${r(-y3 + this.oy)}`,\n );\n }\n close(): void {\n if (this.started) this.parts.push('Z');\n }\n build(): string {\n return this.parts.join(' ');\n }\n}\n\n/* ── geometry helpers ─────────────────────────────────────────────────────── */\n\nconst distance = (a: P, b: P): number => Math.hypot(b.x - a.x, b.y - a.y);\nconst cosine = (dx: number, hyp: number): number => (hyp === 0 ? 0 : dx / hyp);\nconst sine = (dy: number, hyp: number): number => (hyp === 0 ? 0 : dy / hyp);\n\n/** Signed area (shoelace): positive = counter-clockwise. */\nfunction polygonDirection(pts: P[]): number {\n let a = 0;\n for (let i = 0; i < pts.length; i++) {\n const j = (i + 1) % pts.length;\n a += pts[i].x * pts[j].y - pts[i].y * pts[j].x;\n }\n return a;\n}\nfunction ensurePositiveWinding(pts: P[]): void {\n if (polygonDirection(pts) < 0) pts.reverse();\n}\nfunction removeZeroLengthSegments(polygon: P[]): P[] {\n if (polygon.length <= 2) return polygon;\n const tol = 0.5;\n const out: P[] = [polygon[0]];\n for (let i = 1; i < polygon.length; i++) {\n const prev = out[out.length - 1];\n const cur = polygon[i];\n if (Math.abs(cur.x - prev.x) >= tol || Math.abs(cur.y - prev.y) >= tol) out.push(cur);\n }\n return out;\n}\n\n/* ── elliptical-arc Bézier approximation ──────────────────────────────────── */\n\nfunction arcSegment(\n startAng: number,\n endAng: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n out: PathBuilder,\n addMoveTo: boolean,\n): void {\n const cosA = Math.cos(startAng);\n const sinA = Math.sin(startAng);\n const cosB = Math.cos(endAng);\n const sinB = Math.sin(endAng);\n const denom = Math.sin((endAng - startAng) / 2);\n if (denom === 0) {\n if (addMoveTo) out.moveTo(cx + rx * cosA, cy + ry * sinA);\n return;\n }\n const bcp = ((4 / 3) * (1 - Math.cos((endAng - startAng) / 2))) / denom;\n if (addMoveTo) out.moveTo(cx + rx * cosA, cy + ry * sinA);\n out.curveTo(\n cx + rx * (cosA - bcp * sinA),\n cy + ry * (sinA + bcp * cosA),\n cx + rx * (cosB + bcp * sinB),\n cy + ry * (sinB - bcp * cosB),\n cx + rx * cosB,\n cy + ry * sinB,\n );\n}\n\nfunction arcSegmentToArray(startAng: number, endAng: number, rx: number, ry: number): P[] {\n const cosA = Math.cos(startAng);\n const sinA = Math.sin(startAng);\n const cosB = Math.cos(endAng);\n const sinB = Math.sin(endAng);\n const denom = Math.sin((endAng - startAng) / 2);\n if (denom === 0) return [];\n const bcp = ((4 / 3) * (1 - Math.cos((endAng - startAng) / 2))) / denom;\n return [\n { x: rx * (cosA - bcp * sinA), y: ry * (sinA + bcp * cosA) },\n { x: rx * (cosB + bcp * sinB), y: ry * (sinB - bcp * cosB) },\n { x: rx * cosB, y: ry * sinB },\n ];\n}\n\nfunction getArc(\n startAng: number,\n endAng: number,\n rx: number,\n ry: number,\n cx: number,\n cy: number,\n out: PathBuilder,\n addMoveTo: boolean,\n): void {\n let angleTodo = endAng - startAng;\n while (angleTodo < 0) angleTodo += 2 * Math.PI;\n const sweep = angleTodo;\n let angleDone = 0;\n if (addMoveTo) out.moveTo(cx + rx * Math.cos(startAng), cy + ry * Math.sin(startAng));\n while (angleTodo > ANGLE_90) {\n arcSegment(startAng + angleDone, startAng + angleDone + ANGLE_90, cx, cy, rx, ry, out, false);\n angleDone += ANGLE_90;\n angleTodo -= ANGLE_90;\n }\n if (angleTodo > 0) arcSegment(startAng + angleDone, startAng + sweep, cx, cy, rx, ry, out, false);\n}\n\n/* ── curls ─────────────────────────────────────────────────────────────────── */\n\nfunction addCornerCurl(\n anglePrev: number,\n angleCur: number,\n radius: number,\n cx: number,\n cy: number,\n alpha: number,\n alphaPrev: number,\n out: PathBuilder,\n addMoveTo: boolean,\n): void {\n const a = anglePrev + ANGLE_180 + alphaPrev;\n const b = a - (22 * Math.PI) / 180;\n arcSegment(a, b, cx, cy, radius, radius, out, addMoveTo);\n getArc(b, angleCur - alpha, radius, radius, cx, cy, out, false);\n}\n\nfunction addFirstIntermediateCurl(\n angleCur: number,\n rad: number,\n alpha: number,\n cx: number,\n cy: number,\n out: PathBuilder,\n): void {\n const a = angleCur + ANGLE_180;\n arcSegment(a + alpha, a + alpha - ANGLE_30, cx, cy, rad, rad, out, false);\n arcSegment(a + alpha - ANGLE_30, a + ANGLE_90, cx, cy, rad, rad, out, false);\n arcSegment(a + ANGLE_90, a + ANGLE_180 - ANGLE_34, cx, cy, rad, rad, out, false);\n}\n\nfunction intermediateCurlTemplate(angleCur: number, rad: number): P[] {\n const a = angleCur + ANGLE_180;\n return [\n ...arcSegmentToArray(a + ANGLE_34, a + ANGLE_12, rad, rad),\n ...arcSegmentToArray(a + ANGLE_12, a + ANGLE_90, rad, rad),\n ...arcSegmentToArray(a + ANGLE_90, a + ANGLE_180 - ANGLE_34, rad, rad),\n ];\n}\nfunction outputCurlTemplate(template: P[], x: number, y: number, out: PathBuilder): void {\n for (let i = 0; i + 2 < template.length; i += 3) {\n out.curveTo(\n template[i].x + x,\n template[i].y + y,\n template[i + 1].x + x,\n template[i + 1].y + y,\n template[i + 2].x + x,\n template[i + 2].y + y,\n );\n }\n}\n\n/* ── cloud radius (PDFBox constants, deduced from Acrobat) ─────────────────── */\n\nconst ellipseCloudRadius = (intensity: number, lineWidth: number): number =>\n 4.75 * intensity + 0.5 * lineWidth;\nconst polygonCloudRadius = (intensity: number, lineWidth: number): number =>\n 4 * intensity + 0.5 * lineWidth;\n\n/* ── polygon core ──────────────────────────────────────────────────────────── */\n\nfunction computeParamsPolygon(\n idealRadius: number,\n k: number,\n length: number,\n): { n: number; adjustedRadius: number } {\n if (length === 0) return { n: -1, adjustedRadius: idealRadius };\n const remaining = length - 2 * k * idealRadius;\n if (remaining <= 0) return { n: 0, adjustedRadius: idealRadius };\n const n = Math.max(1, Math.ceil(remaining / (2 * k * idealRadius)));\n return { n, adjustedRadius: remaining / (n * 2 * k) };\n}\n\nfunction cloudyPolygonImpl(\n vertices: P[],\n isEllipse: boolean,\n intensity: number,\n lineWidth: number,\n out: PathBuilder,\n): void {\n const polygon = removeZeroLengthSegments(vertices);\n ensurePositiveWinding(polygon);\n const n = polygon.length;\n if (n < 2) return;\n\n if (intensity <= 0) {\n out.moveTo(polygon[0].x, polygon[0].y);\n for (let i = 1; i < n; i++)\n out.curveTo(\n polygon[i].x,\n polygon[i].y,\n polygon[i].x,\n polygon[i].y,\n polygon[i].x,\n polygon[i].y,\n );\n return;\n }\n\n let idealRadius = isEllipse\n ? ellipseCloudRadius(intensity, lineWidth)\n : polygonCloudRadius(intensity, lineWidth);\n if (idealRadius < 0.5) idealRadius = 0.5;\n const k = Math.cos(ANGLE_34);\n\n const edgeAlphas: number[] = [];\n for (let j = 0; j + 1 < n; j++) {\n const len = distance(polygon[j], polygon[j + 1]);\n edgeAlphas.push(\n len <= 0 || len >= 2 * k * idealRadius\n ? ANGLE_34\n : Math.acos(Math.min(1, len / (2 * idealRadius))),\n );\n }\n\n let anglePrev = 0;\n let started = false;\n for (let j = 0; j + 1 < n; j++) {\n const pt = polygon[j];\n const ptNext = polygon[j + 1];\n const len = distance(pt, ptNext);\n if (len === 0) continue;\n\n const params = computeParamsPolygon(idealRadius, k, len);\n if (params.n < 0) {\n if (!started) {\n out.moveTo(pt.x, pt.y);\n started = true;\n }\n continue;\n }\n\n const edgeRadius = Math.max(0.5, params.adjustedRadius);\n const intermAdvance = 2 * k * edgeRadius;\n const firstAdvance = k * idealRadius + k * edgeRadius;\n const angleCur = Math.atan2(ptNext.y - pt.y, ptNext.x - pt.x);\n if (j === 0) {\n const ptPrev = polygon[n - 2];\n anglePrev = Math.atan2(pt.y - ptPrev.y, pt.x - ptPrev.x);\n }\n const cos = cosine(ptNext.x - pt.x, len);\n const sin = sine(ptNext.y - pt.y, len);\n let x = pt.x;\n let y = pt.y;\n const alpha = edgeAlphas[j];\n const alphaPrev = edgeAlphas[j === 0 ? n - 2 : j - 1] ?? ANGLE_34;\n\n addCornerCurl(anglePrev, angleCur, idealRadius, pt.x, pt.y, alpha, alphaPrev, out, !started);\n started = true;\n\n if (params.n === 0) {\n x += len * cos;\n y += len * sin;\n } else {\n x += firstAdvance * cos;\n y += firstAdvance * sin;\n let numInterm = params.n;\n if (params.n >= 1) {\n addFirstIntermediateCurl(angleCur, edgeRadius, ANGLE_34, x, y, out);\n x += intermAdvance * cos;\n y += intermAdvance * sin;\n numInterm = params.n - 1;\n }\n const template = intermediateCurlTemplate(angleCur, edgeRadius);\n for (let i = 0; i < numInterm; i++) {\n outputCurlTemplate(template, x, y, out);\n x += intermAdvance * cos;\n y += intermAdvance * sin;\n }\n }\n anglePrev = angleCur;\n }\n}\n\n/* ── ellipse core ──────────────────────────────────────────────────────────── */\n\nfunction flattenEllipse(left: number, bottom: number, right: number, top: number): P[] {\n const cx = (left + right) / 2;\n const cy = (bottom + top) / 2;\n const rx = (right - left) / 2;\n const ry = (top - bottom) / 2;\n if (rx <= 0 || ry <= 0) return [];\n const segments = Math.max(32, Math.ceil(Math.max(rx, ry) * 2));\n const pts: P[] = [];\n for (let i = 0; i <= segments; i++) {\n const angle = (2 * Math.PI * i) / segments;\n pts.push({ x: cx + rx * Math.cos(angle), y: cy + ry * Math.sin(angle) });\n }\n return pts;\n}\n\nfunction computeParamsEllipse(pt: P, ptNext: P, rad: number, curlAdv: number): number {\n const len = distance(pt, ptNext);\n if (len === 0) return ANGLE_34;\n const arg = (curlAdv / 2 + (len - curlAdv) / 2) / rad;\n return arg < -1 || arg > 1 ? 0 : Math.acos(arg);\n}\n\nfunction cloudyEllipseImpl(\n left: number,\n bottom: number,\n right: number,\n top: number,\n intensity: number,\n lineWidth: number,\n out: PathBuilder,\n): void {\n const plainEllipse = () => {\n const rx = Math.abs(right - left) / 2;\n const ry = Math.abs(top - bottom) / 2;\n getArc(0, 2 * Math.PI, rx, ry, (left + right) / 2, (bottom + top) / 2, out, true);\n };\n\n if (intensity <= 0) return plainEllipse();\n\n const width = right - left;\n const height = top - bottom;\n let cloudRadius = ellipseCloudRadius(intensity, lineWidth);\n\n if (width < 0.5 * cloudRadius && height < 0.5 * cloudRadius) return plainEllipse();\n\n // very long & thin → treat as a rectangle so the scallops read correctly\n if ((width < 5 && height > 20) || (width > 20 && height < 5)) {\n return cloudyPolygonImpl(\n [\n { x: left, y: bottom },\n { x: right, y: bottom },\n { x: right, y: top },\n { x: left, y: top },\n { x: left, y: bottom },\n ],\n true,\n intensity,\n lineWidth,\n out,\n );\n }\n\n // shrink so the cloud tails touch the original outline\n const radiusAdj = Math.sin(ANGLE_12) * cloudRadius - 1.5;\n let adjLeft = left;\n let adjRight = right;\n let adjBottom = bottom;\n let adjTop = top;\n if (width > 2 * radiusAdj) {\n adjLeft += radiusAdj;\n adjRight -= radiusAdj;\n } else {\n const mid = (left + right) / 2;\n adjLeft = mid - 0.1;\n adjRight = mid + 0.1;\n }\n if (height > 2 * radiusAdj) {\n adjBottom += radiusAdj;\n adjTop -= radiusAdj;\n } else {\n const mid = (top + bottom) / 2;\n adjTop = mid + 0.1;\n adjBottom = mid - 0.1;\n }\n\n const flat = flattenEllipse(adjLeft, adjBottom, adjRight, adjTop);\n if (flat.length < 2) return;\n let totLen = 0;\n for (let i = 1; i < flat.length; i++) totLen += distance(flat[i - 1], flat[i]);\n\n const k = Math.cos(ANGLE_34);\n let n = Math.ceil(totLen / (2 * k * cloudRadius));\n if (n < 2) return plainEllipse();\n\n let curlAdvance = totLen / n;\n cloudRadius = curlAdvance / (2 * k);\n if (cloudRadius < 0.5) {\n cloudRadius = 0.5;\n curlAdvance = 2 * k * cloudRadius;\n } else if (cloudRadius < 3.0) {\n return plainEllipse();\n }\n\n // distribute curl centers along the flattened perimeter\n const centers: P[] = [];\n let remain = 0;\n const toler = lineWidth * 0.1;\n for (let i = 0; i + 1 < flat.length; i++) {\n const p1 = flat[i];\n const p2 = flat[i + 1];\n const segLen = distance(p1, p2);\n if (segLen === 0) continue;\n let todo = segLen + remain;\n if (todo >= curlAdvance - toler || i === flat.length - 2) {\n const cos = cosine(p2.x - p1.x, segLen);\n const sin = sine(p2.y - p1.y, segLen);\n let d = curlAdvance - remain;\n while (todo >= curlAdvance - toler) {\n centers.push({ x: p1.x + d * cos, y: p1.y + d * sin });\n todo -= curlAdvance;\n d += curlAdvance;\n }\n remain = Math.max(0, todo);\n } else {\n remain += segLen;\n }\n }\n\n const m = centers.length;\n let anglePrev = 0;\n let alphaPrev = 0;\n for (let i = 0; i < m; i++) {\n const pt = centers[i];\n const ptNext = centers[(i + 1) % m];\n if (i === 0) {\n const ptPrev = centers[m - 1];\n anglePrev = Math.atan2(pt.y - ptPrev.y, pt.x - ptPrev.x);\n alphaPrev = computeParamsEllipse(ptPrev, pt, cloudRadius, curlAdvance);\n }\n const angleCur = Math.atan2(ptNext.y - pt.y, ptNext.x - pt.x);\n const alpha = computeParamsEllipse(pt, ptNext, cloudRadius, curlAdvance);\n addCornerCurl(anglePrev, angleCur, cloudRadius, pt.x, pt.y, alpha, alphaPrev, out, i === 0);\n anglePrev = angleCur;\n alphaPrev = alpha;\n }\n}\n\n/* ── public API ────────────────────────────────────────────────────────────── */\n\n/**\n * The per-side inset (content units) from a shape's outer box to the cloud's\n * inner boundary — the scallop radius plus half the stroke. This IS the `/RD`\n * the engine stores, and it's sized so the scallop peaks reach back out to the\n * box edge: the box remains the annotation's outer boundary.\n */\nexport function cloudyBorderExtent(\n intensity: number,\n strokeWidth: number,\n ellipse: boolean,\n): number {\n const cr = ellipse\n ? ellipseCloudRadius(intensity, strokeWidth)\n : polygonCloudRadius(intensity, strokeWidth);\n return cr + strokeWidth / 2;\n}\n\n/**\n * SVG path data for a cloudy POLYGON border, in ABSOLUTE content coordinates.\n * Unlike the box kinds (whose scallops inset back INTO the outer box), a\n * polygon's curls are centred ON the vertex path and reach OUTWARD by the cloud\n * radius — the same rule PDFium's `GenerateCloudyPolygonPath` bakes into the\n * /AP, so the live preview and the saved appearance agree. The visual therefore\n * extends `cloudyBorderExtent` beyond the vertices (see `geomVisualBounds`).\n *\n * The v3 counterpart of v2's `generateCloudyPolygonPath` (same steps: y-flip,\n * close the ring, run the polygon core). Stroke it with ROUND joins — the curl\n * tails reverse direction by design, and `scene()` sets `join: 'round'` to\n * match PDFium's `1 j`; a miter join turns every seam into a spike.\n */\nexport function cloudyPolyPath(points: Vec[], intensity: number, strokeWidth: number): string {\n const out = new PathBuilder(0, 0);\n // Content space is y-down; the PDFBox core runs y-up (PathBuilder flips back).\n const ring = points.map((p) => ({ x: p.x, y: -p.y }));\n const first = ring[0];\n const last = ring[ring.length - 1];\n // The impl walks edges of a CLOSED ring (first vertex repeated at the end).\n if (first && (first.x !== last.x || first.y !== last.y)) ring.push({ ...first });\n cloudyPolygonImpl(ring, false, intensity, strokeWidth, out);\n out.close();\n return out.build();\n}\n\n/**\n * SVG path data for a cloudy square (rect) or circle (ellipse), in ABSOLUTE\n * content coordinates. The scallops are generated on the box inset by\n * `cloudyBorderExtent` and bulge back out to `box`'s edge.\n */\nexport function cloudyPath(\n box: Rect,\n ellipse: boolean,\n intensity: number,\n strokeWidth: number,\n): string {\n const inset = cloudyBorderExtent(intensity, strokeWidth, ellipse);\n const out = new PathBuilder(box.x, box.y);\n const left = inset;\n const top = inset;\n const right = box.width - inset;\n const bottom = box.height - inset;\n if (ellipse) {\n cloudyEllipseImpl(left, -bottom, right, -top, intensity, strokeWidth, out);\n } else {\n cloudyPolygonImpl(\n [\n { x: left, y: -top },\n { x: right, y: -top },\n { x: right, y: -bottom },\n { x: left, y: -bottom },\n { x: left, y: -top },\n ],\n false,\n intensity,\n strokeWidth,\n out,\n );\n }\n out.close();\n return out.build();\n}\n","/**\n * Line endings (/LE) — the arrowheads and tip shapes drawn at the ends of line\n * and polyline annotations. ONE spec per ending kind drives BOTH the rendered\n * geometry (`endingNodes`) and the bounding-box points (`endingPoints`), so the\n * visual and the engine `/Rect` can never drift. Pure content-space math (PDF\n * points, y-down) — no DOM, no SVG strings — so it ports to Rust like the rest.\n *\n * Convention: each spec is authored in a LOCAL frame with the tip at the origin\n * and the body pointing back along −X. `endingNodes`/`endingPoints` rotate it by\n * the segment angle (into the tip) and translate it to the tip point. Sizes\n * scale with the stroke width, matching the v2 renderer.\n */\nimport type { LineEnding, RenderNode, Vec } from './types';\n\ninterface EndingSpec {\n shape: 'poly' | 'ellipse';\n /** Poly: closed path (so it fills with the annotation's fill colour) vs an open\n * polyline that is stroke-only (open arrow / butt / slash). Ellipses are always\n * closed. Fill colour is the renderer's job — the spec only states closed-ness. */\n closed: boolean;\n /** Final rotation (radians) given the segment angle pointing INTO the tip. */\n rotation: (angle: number) => number;\n /** Local-frame points (tip at origin, body along −X). */\n points: (sw: number) => Vec[];\n}\n\nconst arrow = (closed: boolean): EndingSpec => ({\n shape: 'poly',\n closed,\n rotation: (a) => a,\n points: (sw) => {\n const len = sw * 9;\n const wing = Math.PI / 6; // 30°\n const x = -len * Math.cos(wing);\n const y = len * Math.sin(wing);\n return closed\n ? [\n { x: 0, y: 0 },\n { x, y },\n { x, y: -y },\n ]\n : [\n { x, y },\n { x: 0, y: 0 },\n { x, y: -y },\n ];\n },\n});\n\nconst lineCap = (factor: number, rotation: (a: number) => number): EndingSpec => ({\n shape: 'poly',\n closed: false,\n rotation,\n points: (sw) => {\n const half = (sw * factor) / 2;\n return [\n { x: -half, y: 0 },\n { x: half, y: 0 },\n ];\n },\n});\n\nconst ENDINGS: Partial<Record<LineEnding, EndingSpec>> = {\n 'open-arrow': arrow(false),\n 'closed-arrow': arrow(true),\n 'r-open-arrow': { ...arrow(false), rotation: (a) => a + Math.PI },\n 'r-closed-arrow': { ...arrow(true), rotation: (a) => a + Math.PI },\n circle: {\n shape: 'ellipse',\n closed: true,\n rotation: () => 0, // a circle reads the same at any angle\n points: (sw) => {\n const r = (sw * 5) / 2;\n return [\n { x: -r, y: -r },\n { x: r, y: r },\n ];\n },\n },\n square: {\n shape: 'poly',\n closed: true,\n rotation: (a) => a,\n points: (sw) => {\n const h = (sw * 6) / 2;\n return [\n { x: -h, y: -h },\n { x: h, y: -h },\n { x: h, y: h },\n { x: -h, y: h },\n ];\n },\n },\n diamond: {\n shape: 'poly',\n closed: true,\n rotation: (a) => a,\n points: (sw) => {\n const h = (sw * 6) / 2;\n return [\n { x: h, y: 0 },\n { x: 0, y: h },\n { x: -h, y: 0 },\n { x: 0, y: -h },\n ];\n },\n },\n butt: lineCap(6, (a) => a + Math.PI / 2),\n slash: lineCap(18, (a) => a + Math.PI / 1.5),\n};\n\nconst rotateTranslate = (p: Vec, angle: number, tip: Vec): Vec => {\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return { x: tip.x + p.x * c - p.y * s, y: tip.y + p.x * s + p.y * c };\n};\n\nconst specOf = (ending: LineEnding | undefined): EndingSpec | undefined =>\n ending && ending !== 'none' ? ENDINGS[ending] : undefined;\n\n/** Content-space points contributed by an ending — for the visual bounding box. */\nexport function endingPoints(\n tip: Vec,\n angle: number,\n ending: LineEnding | undefined,\n strokeWidth: number,\n): Vec[] {\n const spec = specOf(ending);\n if (!spec) return [];\n const rot = spec.rotation(angle);\n return spec.points(strokeWidth).map((p) => rotateTranslate(p, rot, tip));\n}\n\n/** Content-space render nodes for an ending — what the framework renderer draws. */\nexport function endingNodes(\n tip: Vec,\n angle: number,\n ending: LineEnding | undefined,\n strokeWidth: number,\n): RenderNode[] {\n const spec = specOf(ending);\n if (!spec) return [];\n const rot = spec.rotation(angle);\n const pts = spec.points(strokeWidth).map((p) => rotateTranslate(p, rot, tip));\n if (spec.shape === 'ellipse') {\n const [a, b] = pts;\n return [\n {\n kind: 'ellipse',\n rect: {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n },\n },\n ];\n }\n return [{ kind: 'poly', points: pts, closed: spec.closed }];\n}\n","/**\n * Pure content-space geometry, dispatched on the `Geom` union. This is the whole\n * per-kind surface: bounds, hit-testing (stroke + fill, with a configurable\n * margin), handles (with cursors), translate, handle-drag, and the dumb scene.\n * The PDF↔content bridge (crop-relative y-flip) is the only engine seam.\n */\nimport type { PdfPoint, PdfRect } from '@embedpdf/engine-core/runtime';\nimport {\n applyPoint,\n applyRect,\n invert,\n isQuarterTurn,\n pdfToContentMatrix,\n rotateAbout,\n textQuadPoints,\n textQuadRing,\n type Mat2D,\n type PageRotation,\n type PointIn,\n type RectIn,\n type Size,\n type TextQuad,\n} from '@embedpdf/core-geometry';\nimport { cloudyBorderExtent, cloudyPath, cloudyPolyPath } from './cloudy';\nimport { endingNodes, endingPoints } from './endings';\nimport type {\n Border,\n Cursor,\n Geom,\n Handle,\n LineEnding,\n Quad,\n Rect,\n RenderNode,\n Style,\n TextEndAnchor,\n Vec,\n} from './types';\n\nconst MIN_SIZE = 4;\n\n/* ── rect handles ─────────────────────────────────────────────────────────── */\n\nexport type RectHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';\nexport const RECT_HANDLES: RectHandle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\nconst RECT_CURSOR: Record<RectHandle, Cursor> = {\n nw: 'nwse-resize',\n se: 'nwse-resize',\n ne: 'nesw-resize',\n sw: 'nesw-resize',\n n: 'ns-resize',\n s: 'ns-resize',\n e: 'ew-resize',\n w: 'ew-resize',\n};\n/** Each handle's compass direction (deg CW from north) on the unrotated box. */\nconst HANDLE_BASE_ANGLE: Record<RectHandle, number> = {\n n: 0,\n ne: 45,\n e: 90,\n se: 135,\n s: 180,\n sw: 225,\n w: 270,\n nw: 315,\n};\n/** The resize cursor per 45° compass sector (index = sector, 0 = north). */\nconst SECTOR_CURSORS: Cursor[] = [\n 'ns-resize',\n 'nesw-resize',\n 'ew-resize',\n 'nwse-resize',\n 'ns-resize',\n 'nesw-resize',\n 'ew-resize',\n 'nwse-resize',\n];\n/** The resize cursor for a handle on a box tilted by `rot` deg: rotate the\n * handle's compass direction with the box and pick the nearest 45° sector.\n * At `rot = 0` this reproduces {@link RECT_CURSOR} exactly. */\nexport const rotatedHandleCursor = (h: RectHandle, rot: number): Cursor =>\n SECTOR_CURSORS[Math.round(normalizeDeg(HANDLE_BASE_ANGLE[h] + rot) / 45) % 8];\nconst rectEdges = (h: RectHandle) => ({\n w: h === 'nw' || h === 'w' || h === 'sw',\n e: h === 'ne' || h === 'e' || h === 'se',\n n: h === 'nw' || h === 'n' || h === 'ne',\n s: h === 'sw' || h === 's' || h === 'se',\n});\nconst rectHandlePoint = (r: Rect, h: RectHandle): Vec => {\n const e = rectEdges(h);\n return {\n x: e.w ? r.x : e.e ? r.x + r.width : r.x + r.width / 2,\n y: e.n ? r.y : e.s ? r.y + r.height : r.y + r.height / 2,\n };\n};\nfunction resizeRect(base: Rect, h: RectHandle, to: Vec): Rect {\n const e = rectEdges(h);\n let l = base.x;\n let r = base.x + base.width;\n let t = base.y;\n let b = base.y + base.height;\n if (e.w) l = to.x;\n if (e.e) r = to.x;\n if (e.n) t = to.y;\n if (e.s) b = to.y;\n return {\n x: Math.min(l, r),\n y: Math.min(t, b),\n width: Math.max(MIN_SIZE, Math.abs(r - l)),\n height: Math.max(MIN_SIZE, Math.abs(b - t)),\n };\n}\n\n/* ── small math ───────────────────────────────────────────────────────────── */\n\nexport const rectFromPoints = (a: Vec, b: Vec): Rect => ({\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n});\nexport const rectsIntersect = (a: Rect, b: Rect): boolean =>\n a.x <= b.x + b.width && a.x + a.width >= b.x && a.y <= b.y + b.height && a.y + a.height >= b.y;\nconst rectContains = (r: Rect, p: Vec): boolean =>\n p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height;\n\n/** Distance from point p to segment ab. */\nfunction segDist(p: Vec, a: Vec, b: Vec): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len2 = dx * dx + dy * dy;\n const t = len2 === 0 ? 0 : Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / len2));\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));\n}\n/** Even-odd point-in-polygon. */\nfunction pointInPoly(p: Vec, pts: Vec[]): boolean {\n let inside = false;\n for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {\n const a = pts[i];\n const b = pts[j];\n if (a.y > p.y !== b.y > p.y && p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x)\n inside = !inside;\n }\n return inside;\n}\nconst polyPoints = (geom: Extract<Geom, { t: 'poly' }>): Vec[] => geom.points;\n\nexport function unionRect(pts: Vec[]): Rect {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const p of pts) {\n x0 = Math.min(x0, p.x);\n y0 = Math.min(y0, p.y);\n x1 = Math.max(x1, p.x);\n y1 = Math.max(y1, p.y);\n }\n return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };\n}\n\nconst expandRect = (r: Rect, pad: number): Rect => ({\n x: r.x - pad,\n y: r.y - pad,\n width: r.width + 2 * pad,\n height: r.height + 2 * pad,\n});\n\nconst rectCornerPoints = (r: Rect): Vec[] => [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x + r.width, y: r.y + r.height },\n { x: r.x, y: r.y + r.height },\n];\n\n/* ── rotation ──────────────────────────────────────────────────────────────\n * Annotation rotation, layered on the generic `@embedpdf/core-geometry` affine\n * primitives (`rotateAbout`). Box kinds carry an UNROTATED `rect` + a `rot`\n * angle; vertex kinds carry already-rotated points + an ADVISORY `rot`. These\n * helpers know that split and compose the matrix builders — they never hand-roll\n * a rotation matrix. See `Geom` in types.ts.\n * ──────────────────────────────────────────────────────────────────────────── */\n\nconst DEG2RAD = Math.PI / 180;\n\n/** How far (content units) the rotate knob hangs off the top edge of the box. */\nexport const ROTATE_KNOB_OFFSET = 24;\n\n/** Fallback chrome geometry (content units) when the caller supplies none —\n * the pre-settings behavior, so bare-core callers and tests stay stable. */\nexport const DEFAULT_CHROME_GEOM = {\n handleTol: 6,\n knobTol: 6,\n knobOffset: ROTATE_KNOB_OFFSET,\n} as const;\n\n/** Normalize degrees into `[0, 360)`. */\nexport const normalizeDeg = (d: number): number => ((d % 360) + 360) % 360;\n\n/** A geom's applied rotation (deg), or 0 for the non-rotatable kinds. A\n * caret's `rot` is AUTHORING metadata (its text's baseline tilt): reported\n * here so the renderer and selection chrome follow it, while the caret's\n * caps (not movable/resizable) keep every rotate gesture away from it. */\nexport function geomRotation(g: Geom): number {\n if (\n g.t === 'rect' ||\n g.t === 'line' ||\n g.t === 'poly' ||\n g.t === 'ink' ||\n g.t === 'text' ||\n g.t === 'caret'\n )\n return g.rot ?? 0;\n return 0;\n}\n\nconst rectCenter = (r: Rect): Vec => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });\n\nconst rotateAboutM = (pivot: Vec, deg: number): Mat2D<'content', 'content'> =>\n rotateAbout(pivot as PointIn<'content'>, deg * DEG2RAD);\n\n/** Rotate one point about a pivot by `deg` (CW, content space). */\nexport const rotatePoint = (p: Vec, pivot: Vec, deg: number): Vec =>\n applyPoint(rotateAboutM(pivot, deg), p as PointIn<'content'>);\n\n/**\n * The rotation PIVOT for a single shape: a box turns about its own `rect`\n * centre; a vertex shape about the CENTROID of its points (the mean). Rotating a\n * point set about its centroid leaves the centroid fixed, so the advisory `rot`\n * stays cleanly additive across gestures and reset is exact.\n */\nexport function centroidOf(g: Geom): Vec {\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return rectCenter(g.rect);\n if (g.t === 'line') return { x: (g.a.x + g.b.x) / 2, y: (g.a.y + g.b.y) / 2 };\n const pts =\n g.t === 'poly' ? g.points : g.t === 'ink' ? g.strokes.flat() : g.quads.flatMap(textQuadPoints);\n let sx = 0;\n let sy = 0;\n for (const p of pts) {\n sx += p.x;\n sy += p.y;\n }\n const n = pts.length || 1;\n return { x: sx / n, y: sy / n };\n}\n\n/** Does the geometry carry a meaningful `rot` (an oriented local box exists)?\n * ORIENTATION is a geometry fact; whether the USER may rotate is the separate\n * `caps.rotatable` gate — a caret is oriented (it rides its text's tilt) yet\n * offers no rotate gesture. */\nexport function isRotatableGeom(g: Geom): boolean {\n return (\n g.t === 'rect' ||\n g.t === 'line' ||\n g.t === 'poly' ||\n g.t === 'ink' ||\n g.t === 'caret' ||\n (g.t === 'text' && !g.callout)\n );\n}\n\n/**\n * Rotate a geom by `deltaDeg` (clockwise) about `pivot`.\n * - BOX (`rect`/plain `text`): orbit the box centre about the pivot (a rigid\n * translation of the unrotated `rect`) and add the angle to `rot`. When the\n * pivot IS the box centre this is a pure `rot += delta`.\n * - VERTEX (`line`/`poly`/`ink`): map every point through the rotation AND bump\n * the advisory `rot` (the points stay the authoritative visual).\n * Kinds without a rotate VERB are returned unchanged: quads and callouts, and\n * also the caret — oriented (`isRotatableGeom`) but text-anchored, so its tilt\n * is authoring metadata that no gesture edits (`geomResetRotation` still\n * clears it).\n */\nexport function geomRotateAbout(g: Geom, pivot: Vec, deltaDeg: number): Geom {\n if (deltaDeg === 0) return g;\n const nextRot = normalizeDeg(geomRotation(g) + deltaDeg);\n if (g.t === 'rect') {\n const c = rotatePoint(rectCenter(g.rect), pivot, deltaDeg);\n return {\n ...g,\n rect: { ...g.rect, x: c.x - g.rect.width / 2, y: c.y - g.rect.height / 2 },\n rot: nextRot,\n };\n }\n if (g.t === 'text') {\n // The rotate GESTURE stays out of scope for callouts (no knob/orbit); the\n // box may still carry a creation-time `rot` from the upright policy.\n if (g.callout) return g;\n const c = rotatePoint(rectCenter(g.rect), pivot, deltaDeg);\n return {\n ...g,\n rect: { ...g.rect, x: c.x - g.rect.width / 2, y: c.y - g.rect.height / 2 },\n rot: nextRot,\n };\n }\n const rp = (p: Vec) => rotatePoint(p, pivot, deltaDeg);\n if (g.t === 'line') return { ...g, a: rp(g.a), b: rp(g.b), rot: nextRot };\n if (g.t === 'poly') return { ...g, points: g.points.map(rp), rot: nextRot };\n if (g.t === 'ink') return { ...g, strokes: g.strokes.map((s) => s.map(rp)), rot: nextRot };\n return g;\n}\n\n/**\n * The size of the frame an engine-baked `/AP` is authored into: the UNROTATED\n * box for box kinds (rotation is stripped to `apRot` and re-applied at the\n * blit), the point bounds for vertex kinds (their points ARE the visual).\n * Position is deliberately absent — a translation never invalidates a raster.\n */\nfunction apFrameSize(g: Geom): Size {\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret')\n return { width: g.rect.width, height: g.rect.height };\n const pts =\n g.t === 'line'\n ? [g.a, g.b]\n : g.t === 'poly'\n ? g.points\n : g.t === 'ink'\n ? g.strokes.flat()\n : g.quads.flatMap(textQuadPoints);\n const b = unionRect(pts);\n return { width: b.width, height: b.height };\n}\n\n/**\n * Did an edit change the SIZE of the geometry's `/AP` authoring frame — i.e.\n * will the engine's re-bake produce NEW raster content? One rule for every\n * gesture, so the commit sites never enumerate kinds: a move/rotate preserves\n * the frame (false), a resize/scale changes it (true). The 0.01pt tolerance\n * absorbs float noise from the gesture math.\n */\nexport function apSizeChanged(before: Geom, after: Geom): boolean {\n const a = apFrameSize(before);\n const b = apFrameSize(after);\n return Math.abs(a.width - b.width) > 0.01 || Math.abs(a.height - b.height) > 0.01;\n}\n\n/** The AABB of `rect` rotated `deg` about its own centre. */\nexport function rotatedAabb(rect: Rect, deg: number): Rect {\n if (!deg) return rect;\n const c = rectCenter(rect);\n return unionRect(rectCornerPoints(rect).map((p) => rotatePoint(p, c, deg)));\n}\n\n/* ── upright placement (counter-rotating against the DISPLAY rotation) ────────\n * An `upright` tool commits `rot = -displayRotation` so the annotation reads\n * horizontally on the rotated page. These two helpers are the ONLY placement\n * math that rule needs; both are exact for quarter-turns and pure content-space\n * (they never know about the view).\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/**\n * The counter-rotation (CW content degrees) that makes an annotation read\n * upright at `displayRotation`: on screen the two compose to 0.\n */\nexport const uprightRotation = (displayRotation: number): number => normalizeDeg(-displayRotation);\n\n/** `rect` with width↔height swapped about its own centre — the unrotated box\n * whose quarter-turn AABB is exactly `rect` again. */\nexport function transposedAboutCenter(rect: Rect): Rect {\n const c = rectCenter(rect);\n return {\n x: c.x - rect.height / 2,\n y: c.y - rect.width / 2,\n width: rect.height,\n height: rect.width,\n };\n}\n\n/**\n * The unrotated content rect for a DEFAULT-SIZE upright box \"placed at\" a\n * point: positioned so that, after the upright counter-rotation, the box shows\n * `width`×`height` with its TOP-LEFT at `anchor` in the ROTATED view — the\n * same on-screen feel as the rotation-0 `{ x: anchor.x, y: anchor.y }` box at\n * every quarter-turn (a click-created free-text box always opens down-right of\n * the cursor as the author sees it). Derived by placing the box in the display\n * frame and pulling its AABB back through the quarter-turn; the page dims\n * cancel, so no page box is needed.\n */\nexport function uprightAnchoredRect(\n anchor: Vec,\n width: number,\n height: number,\n displayRotation: number,\n): Rect {\n const r = normalizeDeg(displayRotation);\n const c: Vec =\n r === 90\n ? { x: anchor.x + height / 2, y: anchor.y - width / 2 }\n : r === 180\n ? { x: anchor.x - width / 2, y: anchor.y - height / 2 }\n : r === 270\n ? { x: anchor.x - height / 2, y: anchor.y + width / 2 }\n : { x: anchor.x + width / 2, y: anchor.y + height / 2 };\n return { x: c.x - width / 2, y: c.y - height / 2, width, height };\n}\n\nconst clampScalar = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\n/**\n * The LOGICAL (unrotated) content-space box for a stamp placed at `center`,\n * sized `desired` (points), fit onto the page and clamped fully within it —\n * the v2 rubber-stamp rule: keep the image's own size unless it would overflow\n * the page, then scale down (aspect preserved, never up) so it just fits.\n *\n * Under an upright quarter-turn the on-page FOOTPRINT is the box transposed\n * (w↔h), so BOTH the fit and the edge clamp use that footprint — a landscape\n * stamp uprighted onto a portrait page fits by its rotated silhouette, not its\n * logical box. The box centre and its footprint AABB centre coincide (rotation\n * is about the centre), so clamping one clamps the other.\n */\nexport function fitStampBox(center: Vec, desired: Size, page: Size, rotCW: number): Rect {\n const quarter = isQuarterTurn((normalizeDeg(rotCW) as PageRotation) ?? 0);\n // Footprint (AABB) dims for the desired size, before fitting.\n const fw0 = quarter ? desired.height : desired.width;\n const fh0 = quarter ? desired.width : desired.height;\n const s = Math.min(1, fw0 > 0 ? page.width / fw0 : 1, fh0 > 0 ? page.height / fh0 : 1);\n const width = desired.width * s;\n const height = desired.height * s;\n const fw = quarter ? height : width;\n const fh = quarter ? width : height;\n // Clamp the centre so the footprint stays fully on the page (the fit above\n // guarantees fw ≤ page.width and fh ≤ page.height, so the range is valid).\n const cx = clampScalar(center.x, fw / 2, page.width - fw / 2);\n const cy = clampScalar(center.y, fh / 2, page.height - fh / 2);\n return { x: cx - width / 2, y: cy - height / 2, width, height };\n}\n\n/** Reset a geom to its as-authored orientation (`rot → 0`). Box: drop `rot`.\n * Vertex: spin the points by `-rot` about their centroid so they return to the\n * orientation they were drawn at, in place. */\nexport function geomResetRotation(g: Geom): Geom {\n const rot = geomRotation(g);\n if (!rot) return g;\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return { ...g, rot: 0 };\n const c = centroidOf(g);\n const rotated = geomRotateAbout(g, c, -rot);\n // geomRotateAbout already set rot = normalize(rot - rot) = 0.\n return rotated;\n}\n\n/**\n * The oriented selection box (OBB) of a rotatable geom: four corners (in order\n * nw, ne, se, sw of the LOCAL box, transformed) + the angle. For a box this is\n * the `rect` rotated about its centre; for a vertex shape it is reconstructed\n * from the advisory `rot` — un-rotate the points to recover the as-authored\n * shape, take that tight local box, then rotate it back — giving the snug tilted\n * rectangle. Returns null for non-rotatable kinds.\n */\nexport function obbFromGeom(\n g: Geom,\n strokeWidth: number,\n border?: Border,\n): { corners: [Vec, Vec, Vec, Vec]; angle: number } | null {\n if (!isRotatableGeom(g)) return null;\n const rot = geomRotation(g);\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') {\n const c = rectCenter(g.rect);\n const corners = rectCornerPoints(g.rect).map((p) => rotatePoint(p, c, rot));\n return { corners: corners as [Vec, Vec, Vec, Vec], angle: rot };\n }\n // vertex: reconstruct the local (as-authored) box from rot about the centroid.\n const c = centroidOf(g);\n const unrotated = rot ? geomRotateAbout(g, c, -rot) : g;\n const localBox = selectionBounds(unrotated, strokeWidth, border);\n const corners = rectCornerPoints(localBox).map((p) => rotatePoint(p, c, rot));\n return { corners: corners as [Vec, Vec, Vec, Vec], angle: rot };\n}\n\n/* ── group (multi-target) scaling ─────────────────────────────────────────────\n * A multi-selection scales as one box about a fixed anchor (the opposite handle\n * corner/edge). Resize is ANISOTROPIC only when every member has `rot == 0`\n * (otherwise an off-axis scale would shear a rotated shape it can't represent —\n * so we fall back to a uniform scale). The iso/aniso choice is decided by the\n * caller (it needs the live selection); these helpers take the resolved factors.\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/** The 8 box resize handles (corner + edge, with cursors) of a plain rect — used\n * for the multi-target group box. */\nexport function rectHandlesFor(r: Rect): Handle[] {\n return RECT_HANDLES.map((h) => ({ id: h, at: rectHandlePoint(r, h), cursor: RECT_CURSOR[h] }));\n}\n\n/** The fixed point of a group resize: the OPPOSITE handle's point on the box. */\nexport function groupResizeAnchor(base: Rect, handle: string): Vec {\n return rectHandlePoint(base, OPPOSITE_HANDLE[handle as RectHandle] ?? 'nw');\n}\n\n/**\n * The live group resize box for a drag. Anisotropic = the plain axis-aligned\n * `resizeRect`; isotropic = a uniform scale of `base` about the anchor by the\n * larger of the two drag ratios (so the preview matches the committed scale and\n * never shears a rotated member).\n */\nexport function groupResizeBox(base: Rect, handle: string, to: Vec, isotropic: boolean): Rect {\n const raw = resizeRect(base, handle as RectHandle, to);\n if (!isotropic) return raw;\n const sx = base.width > 0 ? raw.width / base.width : 1;\n const sy = base.height > 0 ? raw.height / base.height : 1;\n const s = Math.max(MIN_SIZE / Math.max(base.width, base.height, 1), Math.max(sx, sy));\n const anchor = groupResizeAnchor(base, handle);\n return {\n x: anchor.x + (base.x - anchor.x) * s,\n y: anchor.y + (base.y - anchor.y) * s,\n width: base.width * s,\n height: base.height * s,\n };\n}\n\n/** The (sx, sy) factors a `base`→`cur` group resize applied about its anchor. */\nexport function groupResizeFactors(base: Rect, cur: Rect): { sx: number; sy: number } {\n return {\n sx: base.width > 0 ? cur.width / base.width : 1,\n sy: base.height > 0 ? cur.height / base.height : 1,\n };\n}\n\n/**\n * Scale a geom about `anchor` by `(sx, sy)`. For a rotated box (iso scale, so\n * `sx === sy`) the unrotated `rect` is scaled about the anchor and `rot` is\n * preserved (a uniform scale commutes with rotation). For unrotated members\n * (the anisotropic case) every point/extent scales directly.\n */\nexport function geomScaleAbout(g: Geom, anchor: Vec, sx: number, sy: number): Geom {\n const sp = (p: Vec): Vec => ({\n x: anchor.x + (p.x - anchor.x) * sx,\n y: anchor.y + (p.y - anchor.y) * sy,\n });\n if (g.t === 'rect' || g.t === 'text') {\n if (g.t === 'text' && g.callout) return g;\n const c = sp(rectCenter(g.rect));\n const w = Math.max(MIN_SIZE, g.rect.width * Math.abs(sx));\n const h = Math.max(MIN_SIZE, g.rect.height * Math.abs(sy));\n return { ...g, rect: { x: c.x - w / 2, y: c.y - h / 2, width: w, height: h } };\n }\n if (g.t === 'line') return { ...g, a: sp(g.a), b: sp(g.b) };\n if (g.t === 'poly') return { ...g, points: g.points.map(sp) };\n if (g.t === 'ink') return { ...g, strokes: g.strokes.map((s) => s.map(sp)) };\n if (g.t === 'caret') {\n const c = sp(rectCenter(g.rect));\n const w = Math.max(MIN_SIZE, g.rect.width * Math.abs(sx));\n const h = Math.max(MIN_SIZE, g.rect.height * Math.abs(sy));\n return { ...g, rect: { x: c.x - w / 2, y: c.y - h / 2, width: w, height: h } };\n }\n return g; // quads scale with their points\n}\n\n/** Where the rotate knob sits, given the OBB corners (nw, ne, se, sw) and the\n * outward offset (content units). `from` is the top-edge midpoint the connector\n * stalk anchors to; `at` is the grab dot, offset along the outward normal. */\nexport function rotateKnob(corners: [Vec, Vec, Vec, Vec], offset: number): { at: Vec; from: Vec } {\n const [nw, ne, , sw] = corners;\n const from = { x: (nw.x + ne.x) / 2, y: (nw.y + ne.y) / 2 };\n // outward normal = from the bottom edge toward the top edge (away from shape).\n const down = { x: sw.x - nw.x, y: sw.y - nw.y };\n const len = Math.hypot(down.x, down.y) || 1;\n const up = { x: -down.x / len, y: -down.y / len };\n return { at: { x: from.x + up.x * offset, y: from.y + up.y * offset }, from };\n}\n\nconst insideRect = (r: Rect, p: Vec): boolean =>\n p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height;\n\n/**\n * The chord of `box` cut by the infinite line through `p` at `angleDeg` (CW,\n * y-down) — the full-bleed rotation guide: no magic lengths, the line simply\n * spans the page. Slab-clipped (Liang–Barsky); null when the line misses the\n * box entirely (a far-off-page pivot).\n */\nexport function chordThrough(box: Rect, p: Vec, angleDeg: number): { a: Vec; b: Vec } | null {\n const d = { x: Math.cos(angleDeg * DEG2RAD), y: Math.sin(angleDeg * DEG2RAD) };\n let tMin = -Infinity;\n let tMax = Infinity;\n for (const [dc, pc, lo, hi] of [\n [d.x, p.x, box.x, box.x + box.width],\n [d.y, p.y, box.y, box.y + box.height],\n ] as const) {\n if (Math.abs(dc) < 1e-12) {\n if (pc < lo || pc > hi) return null; // parallel outside the slab\n continue;\n }\n const t1 = (lo - pc) / dc;\n const t2 = (hi - pc) / dc;\n tMin = Math.max(tMin, Math.min(t1, t2));\n tMax = Math.min(tMax, Math.max(t1, t2));\n }\n if (tMin >= tMax || !Number.isFinite(tMin) || !Number.isFinite(tMax)) return null;\n return {\n a: { x: p.x + d.x * tMin, y: p.y + d.y * tMin },\n b: { x: p.x + d.x * tMax, y: p.y + d.y * tMax },\n };\n}\n\n/**\n * `rotateKnob` with a TOTAL page-bound placement policy: annotations, gestures\n * and chrome are all page-bound, so the grab dot must land inside `pageBox` —\n * off-page it is unreachable (the pointer dispatch resolves pages by\n * containment). Policy: top edge (the default) → FLIP to the bottom edge when\n * the stalk exits the page → CLAMP the top candidate inside (degenerate: the\n * selection spans ~the whole page; the knob may then overlap the shape, and\n * hit-testing checks it first so it stays grabbable). Both render (`chrome`)\n * and hit-test (`hitTest`) place the knob through THIS function, so what you\n * see is what you can grab — by construction. No `pageBox` → the raw knob.\n */\nexport function placeRotateKnob(\n corners: [Vec, Vec, Vec, Vec],\n offset: number,\n pageBox?: Rect,\n): { at: Vec; from: Vec } {\n const top = rotateKnob(corners, offset);\n if (!pageBox || insideRect(pageBox, top.at)) return top;\n // FLIP: the same outward-normal math off the OPPOSITE (bottom) edge. On a\n // rotated OBB this exits through whichever page edge the stalk crossed.\n const [nw, , se, sw] = corners;\n const from = { x: (sw.x + se.x) / 2, y: (sw.y + se.y) / 2 };\n const down = { x: sw.x - nw.x, y: sw.y - nw.y };\n const len = Math.hypot(down.x, down.y) || 1;\n const at = {\n x: from.x + (down.x / len) * offset,\n y: from.y + (down.y / len) * offset,\n };\n if (insideRect(pageBox, at)) return { at, from };\n return {\n at: {\n x: Math.min(Math.max(top.at.x, pageBox.x), pageBox.x + pageBox.width),\n y: Math.min(Math.max(top.at.y, pageBox.y), pageBox.y + pageBox.height),\n },\n from: top.from,\n };\n}\n\n/* ── callout leader ───────────────────────────────────────────────────────────\n * A free-text callout draws a 2–3 point leader (`/CL`) from the called-out `tip`\n * to the text box, with an arrow (`/LE`) at the tip. The point where the leader\n * meets the box is DERIVED — never stored — so it tracks the box and knee.\n */\n\n/** The box-edge midpoint the leader connects to: the side `ref` (the knee, else\n * the tip) points toward, by horizontal/vertical dominance vs the box centre.\n * With `rot` (a callout box tilted by the upright policy) the decision runs in\n * the box's LOCAL frame and the midpoint lands back on the ROTATED edge — the\n * edge the user actually sees. Mirror of v2's `computeCalloutConnectionPoint`. */\nexport function calloutConnection(box: Rect, ref: Vec, rot = 0): Vec {\n if (rot) {\n const c = rectCenter(box);\n return rotatePoint(calloutConnection(box, rotatePoint(ref, c, -rot)), c, rot);\n }\n const cx = box.x + box.width / 2;\n const cy = box.y + box.height / 2;\n const dx = ref.x - cx;\n const dy = ref.y - cy;\n if (Math.abs(dx) >= Math.abs(dy)) {\n return dx >= 0 ? { x: box.x + box.width, y: cy } : { x: box.x, y: cy };\n }\n return dy >= 0 ? { x: cx, y: box.y + box.height } : { x: cx, y: box.y };\n}\n\n/** The leader polyline `[tip, knee?, conn]`, with `conn` derived from the box\n * (its ROTATED footprint when the box carries `rot`). */\nexport function calloutLinePoints(g: Extract<Geom, { t: 'text' }>): Vec[] {\n const c = g.callout;\n if (!c) return [];\n const conn = calloutConnection(g.rect, c.knee ?? c.tip, g.rot ?? 0);\n return c.knee ? [c.tip, c.knee, conn] : [c.tip, conn];\n}\n\n/** The leader's single ending segment (arrow at the tip), pointing OUT of the\n * body into the tip — so the arrowhead opens back along the leader. */\nfunction calloutEndingSeg(pts: Vec[], ending: LineEnding): EndingSeg | null {\n if (pts.length < 2) return null;\n return {\n tip: pts[0],\n angle: Math.atan2(pts[0].y - pts[1].y, pts[0].x - pts[1].x),\n ending,\n };\n}\n\n/** Shrink a rect inward by `pad` on every side, staying centred and never\n * collapsing past zero (a thick stroke on a tiny shape just yields a 0-extent\n * path rather than an inverted one). The inverse of `expandRect` for shapes. */\nconst insetRect = (r: Rect, pad: number): Rect => {\n const width = Math.max(0, r.width - 2 * pad);\n const height = Math.max(0, r.height - 2 * pad);\n return { x: r.x + (r.width - width) / 2, y: r.y + (r.height - height) / 2, width, height };\n};\n\n/**\n * The stored `rect` for a freshly-drawn shape, given the box the user dragged. A\n * cloudy border stores the OUTER box (dragged + cloud extent), so the dragged box\n * is its inner edge and the scallops bulge out to the stored box — just like a\n * solid shape, whose /Rect is the dragged box. So `g.rect` is ALWAYS the outer box;\n * the cloud-vs-solid difference lives only here, at creation.\n */\nexport function shapeRectFor(dragged: Rect, ellipse: boolean, style: Style): Rect {\n return style.border.kind === 'cloudy'\n ? expandRect(dragged, cloudyBorderExtent(style.border.intensity, style.strokeWidth, ellipse))\n : dragged;\n}\n\nexport function caretRectFromTextEnd(lineRect: Rect): Rect {\n const height = lineRect.height / 2;\n const width = height;\n const lineEndX = lineRect.x + lineRect.width;\n return {\n x: lineEndX - width / 2,\n y: lineRect.y + lineRect.height / 2,\n width,\n height,\n };\n}\n\n/**\n * Caret box for a text-edit anchor: half the glyph's ink height, centered on\n * the TRAILING baseline corner in READING direction (`advance` decides which\n * end — RTL carets land on the visual left), sitting on the baseline. The box\n * stays axis-aligned; use {@link caretGeomFromAnchor} for the tilt-carrying\n * geometry.\n */\nexport function caretRectFromAnchor(anchor: TextEndAnchor): Rect {\n const q = anchor.glyphQuad;\n const ink = Math.hypot(q.lowerStart.x - q.upperStart.x, q.lowerStart.y - q.upperStart.y);\n const size = Math.max(ink / 2, 1);\n const corner = anchor.advance > 0 ? q.lowerEnd : q.lowerStart;\n return { x: corner.x - size / 2, y: corner.y - size, width: size, height: size };\n}\n\n/** Rotations closer than ~0.05° to upright stay upright (float noise guard). */\nconst CARET_ROT_EPSILON = 0.05;\n\n/**\n * Caret GEOMETRY for a text-edit anchor: the box-family pair — an UNROTATED\n * box whose centre sits half a caret-size ascent-ward of the trailing\n * baseline corner, plus `rot` = the text's baseline tilt (deg, CW in y-down\n * content space). Rotating the box about its centre by `rot` lands it\n * hugging the rotated baseline, symbol pointing at its text. For upright\n * anchors this degenerates EXACTLY to {@link caretRectFromAnchor} with no\n * `rot` key — the dominant case is byte-identical.\n */\nexport function caretGeomFromAnchor(anchor: TextEndAnchor): Extract<Geom, { t: 'caret' }> {\n const q = anchor.glyphQuad;\n const ink = Math.hypot(q.lowerStart.x - q.upperStart.x, q.lowerStart.y - q.upperStart.y);\n const size = Math.max(ink / 2, 1);\n const corner = anchor.advance > 0 ? q.lowerEnd : q.lowerStart;\n // The caret's own orientation follows the TEXT (the symbol points at its\n // line regardless of reading direction), so the tilt comes from the\n // baseline edge, not from `advance`.\n const bx = q.lowerEnd.x - q.lowerStart.x;\n const by = q.lowerEnd.y - q.lowerStart.y;\n const rot = Math.hypot(bx, by) > 0 ? normalizeDeg((Math.atan2(by, bx) * 180) / Math.PI) : 0;\n const upright = rot < CARET_ROT_EPSILON || rot > 360 - CARET_ROT_EPSILON;\n if (upright) {\n return {\n t: 'caret',\n rect: { x: corner.x - size / 2, y: corner.y - size, width: size, height: size },\n };\n }\n // Centre = trailing corner + (size/2) toward the ascent side.\n const ux = (q.upperStart.x - q.lowerStart.x) / ink;\n const uy = (q.upperStart.y - q.lowerStart.y) / ink;\n const cx = corner.x + (ux * size) / 2;\n const cy = corner.y + (uy * size) / 2;\n return {\n t: 'caret',\n rect: { x: cx - size / 2, y: cy - size / 2, width: size, height: size },\n rot,\n };\n}\n\n/** Map a TextQuad's corners through a point function (names ride along). */\nfunction mapTextQuad(q: TextQuad, f: (p: Vec) => Vec): TextQuad {\n return {\n upperStart: f(q.upperStart),\n upperEnd: f(q.upperEnd),\n lowerStart: f(q.lowerStart),\n lowerEnd: f(q.lowerEnd),\n };\n}\n\n/* ── line endings ─────────────────────────────────────────────────────────────\n * The breathing room a stroked line/poly needs beyond its vertices, as a factor\n * of the stroke width (matches v2): the half-stroke under the centre-line plus a\n * little extra so caps/joins are never clipped by the engine `/Rect`.\n */\n/** Miter limit shared by the bounds math AND the SVG renderer (`stroke-miterlimit`),\n * so the computed box and the drawn stroke always agree on where a sharp join\n * bevels instead of spiking. 10 = the PDF default (also what the baked /AP uses). */\nexport const MITER_LIMIT = 10;\n\n/**\n * The outline points of a mitred, butt-capped polyline (open or closed) stroked\n * at `strokeWidth`: each segment's two side offsets (the straight extents + both\n * bevel corners) PLUS each interior join's OUTER miter tip — added only while the\n * join is within `MITER_LIMIT` (past that the renderer bevels it, and the segment\n * offsets already bound it). `unionRect` of these is the tight, ASYMMETRIC visual\n * box: a pointy join grows the box only on the side it actually spikes.\n *\n * Miter kinds only (line / polyline / polygon). Ink is round-capped/round-joined,\n * never spikes, and is bounded elsewhere by a plain `h` grow.\n */\nfunction strokeOutlinePoints(pts: Vec[], closed: boolean, strokeWidth: number): Vec[] {\n const h = strokeWidth / 2;\n const n = pts.length;\n if (n === 0) return [];\n if (n === 1 || h === 0) return [...pts];\n\n const segCount = closed ? n : n - 1;\n const dir: Vec[] = [];\n const nrm: Vec[] = [];\n for (let i = 0; i < segCount; i++) {\n const a = pts[i];\n const b = pts[(i + 1) % n];\n const len = Math.hypot(b.x - a.x, b.y - a.y) || 1;\n const ux = (b.x - a.x) / len;\n const uy = (b.y - a.y) / len;\n dir.push({ x: ux, y: uy });\n nrm.push({ x: -uy, y: ux }); // a unit normal (either side; sign is re-picked below)\n }\n\n const out: Vec[] = [];\n // Segment side offsets at both ends — covers the straight extents, the butt\n // caps at open ends, and the bevel corners of any beveled join.\n for (let i = 0; i < segCount; i++) {\n const a = pts[i];\n const b = pts[(i + 1) % n];\n const nx = nrm[i].x * h;\n const ny = nrm[i].y * h;\n out.push({ x: a.x + nx, y: a.y + ny }, { x: a.x - nx, y: a.y - ny });\n out.push({ x: b.x + nx, y: b.y + ny }, { x: b.x - nx, y: b.y - ny });\n }\n\n // Interior joins: the outer miter tip, gated by the miter limit.\n const joinStart = closed ? 0 : 1;\n const joinEnd = closed ? n : n - 1; // vertices [joinStart, joinEnd)\n for (let v = joinStart; v < joinEnd; v++) {\n const inIdx = closed ? (v - 1 + n) % n : v - 1;\n const outIdx = closed ? v : v; // segment starting at v\n const a = dir[inIdx]; // prev -> v\n const b = dir[outIdx]; // v -> next\n const n1 = nrm[inIdx];\n const n2 = nrm[outIdx];\n // Outer bisector direction: opposite the interior bisector `b - a`.\n const bx = a.x - b.x;\n const by = a.y - b.y;\n if (Math.hypot(bx, by) < 1e-9) continue; // straight run: no spike beyond the offsets\n let mhx = n1.x + n2.x;\n let mhy = n1.y + n2.y;\n const ml = Math.hypot(mhx, mhy);\n if (ml < 1e-9) continue; // exact hairpin: renderer bevels\n mhx /= ml;\n mhy /= ml;\n if (mhx * bx + mhy * by < 0) {\n mhx = -mhx; // point the miter unit vector to the OUTER side\n mhy = -mhy;\n }\n const cosHalf = Math.abs(mhx * n1.x + mhy * n1.y); // cos(deviation/2)\n if (cosHalf < 1e-9) continue;\n const miterLen = h / cosHalf;\n if (miterLen > MITER_LIMIT * h) continue; // too sharp: renderer bevels → offsets bound it\n const V = pts[v];\n out.push({ x: V.x + mhx * miterLen, y: V.y + mhy * miterLen });\n }\n return out;\n}\n\ntype EndingSeg = { tip: Vec; angle: number; ending: LineEnding | undefined };\n\n/** The start/end tips of a line / open poly, each with the segment angle pointing\n * OUT of the body into the tip (so an arrowhead opens back toward the line). */\nfunction endingSegs(g: Geom): EndingSeg[] {\n if (g.t === 'line' && g.ends) {\n return [\n { tip: g.a, angle: Math.atan2(g.a.y - g.b.y, g.a.x - g.b.x), ending: g.ends.start },\n { tip: g.b, angle: Math.atan2(g.b.y - g.a.y, g.b.x - g.a.x), ending: g.ends.end },\n ];\n }\n if (g.t === 'poly' && !g.closed && g.ends && g.points.length >= 2) {\n const p = g.points;\n const n = p.length;\n return [\n { tip: p[0], angle: Math.atan2(p[0].y - p[1].y, p[0].x - p[1].x), ending: g.ends.start },\n {\n tip: p[n - 1],\n angle: Math.atan2(p[n - 1].y - p[n - 2].y, p[n - 1].x - p[n - 2].x),\n ending: g.ends.end,\n },\n ];\n }\n return [];\n}\n\n/**\n * A geom's VISUAL bounds: the rect that encloses the drawn appearance, so the\n * baked /AP is never clipped and the selection outline wraps exactly what's drawn.\n *\n * A shape's `rect` IS its visual box (the PDF /Rect): solid/dashed strokes draw\n * inside it, and a cloudy border's scallops also inset back into it (the dragged\n * inner edge sits `/RD` in from it — see `shapeRectFor`). So growing the stroke or\n * the cloud thickens inward, never spilling past the handles. Lines / polylines /\n * ink have no box, so they expand by the stroke (+ endings) — the SAME math feeds\n * `geomScene`, so the visual box and what's drawn always agree.\n *\n * `border` matters for ONE case: a CLOSED poly with a cloudy border, whose curls\n * are centred on the vertex path and reach OUTWARD (there is no outer box to\n * inset into) — the bounds grow by the cloud extent, and the engine `/Rect`\n * (via `geomPdfBounds`) grows with them so the baked scallops are never clipped.\n */\nexport function geomVisualBounds(g: Geom, strokeWidth: number, border?: Border): Rect {\n if (g.t === 'poly' && g.closed && border?.kind === 'cloudy') {\n // Corner curls are arcs of the cloud radius centred at the vertices, and the\n // stroke straddles them — so ink reaches radius + strokeWidth/2 beyond the\n // vertex hull on every side: exactly `cloudyBorderExtent`.\n return expandRect(\n unionRect(g.points),\n cloudyBorderExtent(border.intensity, strokeWidth, false),\n );\n }\n if (g.t === 'text' && g.callout) {\n // The overall /Rect: the union of the text box (its ROTATED corners when the\n // box carries an upright tilt), the leader points, and the arrow-ending\n // polygon at the tip (same ending math as line/poly).\n const pts = calloutLinePoints(g);\n const seg = calloutEndingSeg(pts, g.callout.ending);\n const rot = g.rot ?? 0;\n const c = rectCenter(g.rect);\n const corners = rectCornerPoints(g.rect).map((p) => (rot ? rotatePoint(p, c, rot) : p));\n const all = [...corners, ...pts];\n if (seg) all.push(...endingPoints(seg.tip, seg.angle, seg.ending, strokeWidth));\n return expandRect(unionRect(all), strokeWidth / 2);\n }\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return g.rect;\n if (g.t === 'quads')\n return expandRect(unionRect(g.quads.flatMap(textQuadPoints)), strokeWidth / 2);\n // Ink is round-capped/round-joined: it never spikes, so a plain `h` grow of the\n // freehand hull is exact — left as-is (the freehand look must not change).\n if (g.t === 'ink') return expandRect(unionRect(g.strokes.flat()), strokeWidth / 2);\n // Line / polyline / polygon: the miter kinds. Wrap the ACTUAL stroke outline\n // (per-join, asymmetric) instead of a flat pad — for the body AND each ending,\n // so a mitred arrowhead tip is enclosed exactly (not under-covered by a flat h).\n const raw = g.t === 'line' ? [g.a, g.b] : g.points;\n const closed = g.t === 'poly' && g.closed;\n const pts = strokeOutlinePoints(raw, closed, strokeWidth);\n for (const seg of endingSegs(g)) {\n for (const node of endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth)) {\n if (node.kind === 'poly') {\n // arrowheads / diamonds / squares are stroked polys: their sharp corners\n // miter exactly like the body, so wrap the real outline (tip included).\n pts.push(...strokeOutlinePoints(node.points, node.closed, strokeWidth));\n } else if (node.kind === 'ellipse') {\n // a stroked ellipse (circle ending) grows uniformly by h — no miters.\n pts.push(...rectCornerPoints(expandRect(node.rect, strokeWidth / 2)));\n }\n }\n }\n return unionRect(pts);\n}\n\n/**\n * The rect the SELECTION wraps — and the region a SELECTED annotation can be grabbed\n * from. Centre-line geometries (line / polyline / polygon / ink) straddle their path,\n * so this is their VISUAL bounds (the join-aware stroke outline + endings) — a\n * polygon's outline wraps its stroke exactly like a polyline. Box kinds (square /\n * circle / free-text) sit tight on their `rect` (their stroke draws INSIDE the box,\n * so the 8 resize handles land on the corners). The chrome outline AND the selected\n * hit-test both call this, so what you see highlighted is exactly what you can grab —\n * they can never drift.\n */\nexport function selectionBounds(g: Geom, strokeWidth: number, border?: Border): Rect {\n if (g.t === 'line' || g.t === 'ink' || g.t === 'poly')\n return geomVisualBounds(g, strokeWidth, border);\n // A callout's tilted text box (the upright policy): the selection wraps the box\n // the user SEES — its rotated footprint. Exact for the quarter-turns upright\n // produces (the footprint stays axis-aligned), so outline and handles agree.\n if (g.t === 'text' && g.callout && (g.rot ?? 0) !== 0) return rotatedAabb(g.rect, g.rot!);\n return geomBounds(g);\n}\n\n/**\n * The four corners of the ORIENTED selection box — the SAME quad `chrome` draws.\n * For a rotatable kind this is the OBB (the tilted box, from `obbFromGeom`); at\n * `rot == 0` those are just the axis-aligned corners of `selectionBounds`, and\n * for non-rotatable kinds (markup quads, callouts) it falls back to the rect\n * corners. The grab region, the floating-menu anchor and the multi/group union\n * all consume this, so what you can grab / where the menu sits never drifts from\n * the outline you see.\n */\nexport function selectionQuad(g: Geom, strokeWidth: number, border?: Border): [Vec, Vec, Vec, Vec] {\n const obb = obbFromGeom(g, strokeWidth, border);\n if (obb) return obb.corners;\n return rectCornerPoints(selectionBounds(g, strokeWidth, border)) as [Vec, Vec, Vec, Vec];\n}\n\n/** Is the point inside the (convex) selection quad? Even-odd ring test. */\nexport const pointInQuad = (p: Vec, quad: [Vec, Vec, Vec, Vec]): boolean => pointInPoly(p, quad);\n\n/**\n * Does the (convex) selection quad intersect an axis-aligned rect? Separating\n * axis test on the only four candidate axes — the rect's x/y plus the quad's\n * two edge normals; a gap on any axis proves disjoint, otherwise they overlap\n * (touching counts). This is the marquee's predicate: it must catch a tilted\n * shape by the ORIENTED box that is actually drawn — the AABB of that quad has\n * empty corners covering most of the unrotated footprint, so testing it selects\n * shapes the marquee never touched. At `rot 0` the quad is axis-aligned and\n * this degenerates to exactly `rectsIntersect`.\n */\nexport function quadIntersectsRect(quad: [Vec, Vec, Vec, Vec], r: Rect): boolean {\n const rectPts = rectCornerPoints(r);\n const axes: Vec[] = [\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -(quad[1].y - quad[0].y), y: quad[1].x - quad[0].x },\n { x: -(quad[3].y - quad[0].y), y: quad[3].x - quad[0].x },\n ];\n for (const ax of axes) {\n if (Math.abs(ax.x) < 1e-12 && Math.abs(ax.y) < 1e-12) continue; // degenerate edge\n let qLo = Infinity;\n let qHi = -Infinity;\n for (const p of quad) {\n const d = p.x * ax.x + p.y * ax.y;\n qLo = Math.min(qLo, d);\n qHi = Math.max(qHi, d);\n }\n let rLo = Infinity;\n let rHi = -Infinity;\n for (const p of rectPts) {\n const d = p.x * ax.x + p.y * ax.y;\n rLo = Math.min(rLo, d);\n rHi = Math.max(rHi, d);\n }\n if (qHi < rLo || rHi < qLo) return false; // separated on this axis\n }\n return true;\n}\n\n/**\n * The centre of the ORIENTED selection box — the middle of the rect you see.\n * For box kinds this is the rect centre (so squares/circles are unchanged); for\n * vertex kinds it is the OBB centre, so rotation spins the shape in place rather\n * than swinging it about the off-centre vertex mean (`centroidOf`).\n */\nexport function selectionCenter(g: Geom, strokeWidth: number): Vec {\n const q = selectionQuad(g, strokeWidth);\n return {\n x: (q[0].x + q[1].x + q[2].x + q[3].x) / 4,\n y: (q[0].y + q[1].y + q[2].y + q[3].y) / 4,\n };\n}\n\n/**\n * Is the content point ON a line/poly's drawn ENDINGS — so an arrowhead is as\n * clickable as the stroke. Uses the SAME ending nodes the renderer draws: a closed\n * shape (closed arrow, circle, square, diamond) hits inside OR near its edge; an\n * open one (open arrow, butt, slash) hits near its stroke. `tol` is the stroke\n * band already widened by the hit margin.\n */\nfunction endingNodesHit(nodes: RenderNode[], p: Vec, tol: number): boolean {\n for (const node of nodes) {\n if (node.kind === 'ellipse') {\n const r = node.rect;\n const rx = r.width / 2;\n const ry = r.height / 2;\n if (rx <= 0 || ry <= 0) continue;\n const nx = (p.x - (r.x + rx)) / rx;\n const ny = (p.y - (r.y + ry)) / ry;\n if (Math.hypot(nx, ny) <= 1 + tol / Math.min(rx, ry)) return true; // filled disc + band\n } else if (node.kind === 'poly') {\n const pts = node.points;\n for (let i = 0; i < pts.length - 1; i++)\n if (segDist(p, pts[i], pts[i + 1]) <= tol) return true;\n if (node.closed) {\n if (pts.length > 2 && segDist(p, pts[pts.length - 1], pts[0]) <= tol) return true;\n if (pointInPoly(p, pts)) return true; // filled head interior\n }\n }\n }\n return false;\n}\n\nfunction endingHit(g: Geom, p: Vec, tol: number, strokeWidth: number): boolean {\n for (const seg of endingSegs(g))\n if (endingNodesHit(endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth), p, tol))\n return true;\n return false;\n}\n\n/* ── geom ops ─────────────────────────────────────────────────────────────── */\n\nexport function geomBounds(g: Geom): Rect {\n if (g.t === 'rect' || g.t === 'text' || g.t === 'caret') return g.rect;\n if (g.t === 'line') return rectFromPoints(g.a, g.b);\n if (g.t === 'poly') return unionRect(g.points);\n if (g.t === 'ink') return unionRect(g.strokes.flat());\n return unionRect(g.quads.flatMap(textQuadPoints));\n}\n\n/**\n * Is the content point ON the annotation: within `margin` of the stroke, or\n * inside the fill (when `filled`). The stroke band widens with the stroke width.\n *\n * A shape's stroke is drawn INSIDE its box, centred on `insetRect(rect, sw/2)`\n * (see `geomScene`), so the clickable band follows that inset centre-line — not\n * the box edge. The fill still reaches the box. (Cloudy scallops aren't modelled\n * here; with their typically thin stroke the inset is sub-pixel, so this matches.)\n */\nexport function geomHit(\n g: Geom,\n p: Vec,\n margin: number,\n filled: boolean,\n strokeWidth: number,\n): boolean {\n const tol = margin + strokeWidth / 2;\n // A rotated box stores its UNROTATED `rect`; inverse-rotate the pointer into\n // that local frame and run the normal axis-aligned tests. Vertex kinds carry\n // already-rotated points, so they hit-test directly (rot is advisory). A\n // callout is COMPOUND: only its box rotates (the leader is page-space), so the\n // inverse rotation applies to the box test alone — see the text branch below.\n if ((g.t === 'rect' || g.t === 'caret' || (g.t === 'text' && !g.callout)) && (g.rot ?? 0) !== 0) {\n p = rotatePoint(p, rectCenter(g.rect), -(g.rot ?? 0));\n }\n // A text box is a solid hit target anywhere inside it (+ the click margin).\n if (g.t === 'caret') return rectContains(expandRect(g.rect, margin), p);\n if (g.t === 'text') {\n // Box test in the box's LOCAL frame (a tilted callout box); leader/arrow\n // tests in the PAGE frame (their points are already where they're drawn).\n const rot = g.callout ? (g.rot ?? 0) : 0;\n const pBox = rot ? rotatePoint(p, rectCenter(g.rect), -rot) : p;\n if (rectContains(expandRect(g.rect, margin), pBox)) return true;\n if (g.callout) {\n const pts = calloutLinePoints(g);\n for (let i = 0; i < pts.length - 1; i++)\n if (segDist(p, pts[i], pts[i + 1]) <= tol) return true;\n const seg = calloutEndingSeg(pts, g.callout.ending);\n if (seg && endingNodesHit(endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth), p, tol))\n return true;\n }\n return false;\n }\n if (g.t === 'rect') {\n const r = g.rect;\n if (g.ellipse) {\n const cx = r.x + r.width / 2;\n const cy = r.y + r.height / 2;\n const orx = r.width / 2; // outer (box) radii — the fill reaches here\n const ory = r.height / 2;\n if (orx <= 0 || ory <= 0) return false;\n if (filled && Math.hypot((p.x - cx) / orx, (p.y - cy) / ory) <= 1) return true;\n // stroke band centred on the inset path (its outer edge sits on the box)\n const rx = Math.max(0.01, orx - strokeWidth / 2);\n const ry = Math.max(0.01, ory - strokeWidth / 2);\n const d = Math.hypot((p.x - cx) / rx, (p.y - cy) / ry);\n const band = tol / Math.min(rx, ry); // approximate normalized stroke band\n return Math.abs(d - 1) <= band;\n }\n if (filled && rectContains(r, p)) return true;\n // near any of the 4 edges of the inset (drawn) rectangle\n const c = insetRect(r, strokeWidth / 2);\n const edges: [Vec, Vec][] = [\n [\n { x: c.x, y: c.y },\n { x: c.x + c.width, y: c.y },\n ],\n [\n { x: c.x + c.width, y: c.y },\n { x: c.x + c.width, y: c.y + c.height },\n ],\n [\n { x: c.x + c.width, y: c.y + c.height },\n { x: c.x, y: c.y + c.height },\n ],\n [\n { x: c.x, y: c.y + c.height },\n { x: c.x, y: c.y },\n ],\n ];\n return edges.some(([a, b]) => segDist(p, a, b) <= tol);\n }\n if (g.t === 'line') return segDist(p, g.a, g.b) <= tol || endingHit(g, p, tol, strokeWidth);\n if (g.t === 'poly') {\n if (filled && g.closed && pointInPoly(p, g.points)) return true;\n const pts = g.points;\n const n = pts.length;\n for (let i = 0; i < n - 1; i++) if (segDist(p, pts[i], pts[i + 1]) <= tol) return true;\n if (g.closed && n > 2 && segDist(p, pts[n - 1], pts[0]) <= tol) return true;\n return endingHit(g, p, tol, strokeWidth);\n }\n if (g.t === 'ink') {\n // near any segment of any stroke (ink is stroke-only, never filled)\n for (const stroke of g.strokes)\n for (let i = 0; i < stroke.length - 1; i++)\n if (segDist(p, stroke[i], stroke[i + 1]) <= tol) return true;\n return false;\n }\n // quads (markup): oriented per-line cells — hit anywhere inside any quad.\n // TextQuad rings are simple (non-self-intersecting) by construction, so the\n // generic point-in-poly test is exact for rotated text too.\n return g.quads.some((q) => pointInQuad(p, textQuadRing(q)));\n}\n\nexport function geomHandles(g: Geom): Handle[] {\n if (g.t === 'rect' || g.t === 'text') {\n const rot = g.rot ?? 0;\n const c = rectCenter(g.rect);\n const handles: Handle[] = RECT_HANDLES.map((h) => ({\n id: h,\n // box handles sit on the UNROTATED rect; rotate each into place so they\n // ride the tilted box. The cursor rotates WITH the handle (the visually\n // right-edge handle of a 90°-tilted box resizes horizontally).\n at: rot ? rotatePoint(rectHandlePoint(g.rect, h), c, rot) : rectHandlePoint(g.rect, h),\n cursor: rotatedHandleCursor(h, rot),\n }));\n // A callout adds vertex handles for the leader tip and (if present) knee, so\n // the called-out point and the elbow can be dragged independently of the box.\n if (g.t === 'text' && g.callout) {\n handles.push({ id: 'callout-tip', at: g.callout.tip, cursor: 'crosshair' });\n if (g.callout.knee)\n handles.push({ id: 'callout-knee', at: g.callout.knee, cursor: 'crosshair' });\n }\n return handles;\n }\n if (g.t === 'line') {\n return [\n { id: 'v0', at: g.a, cursor: 'crosshair' },\n { id: 'v1', at: g.b, cursor: 'crosshair' },\n ];\n }\n if (g.t === 'poly') {\n return g.points.map((at, i) => ({ id: `v${i}`, at, cursor: 'crosshair' }));\n }\n return []; // markup: move only\n}\n\nexport function geomTranslate(g: Geom, d: Vec): Geom {\n const mv = (p: Vec): Vec => ({ x: p.x + d.x, y: p.y + d.y });\n if (g.t === 'text') {\n const rect = { ...g.rect, x: g.rect.x + d.x, y: g.rect.y + d.y };\n if (!g.callout) return { ...g, rect };\n return {\n ...g,\n rect,\n callout: {\n ...g.callout,\n tip: mv(g.callout.tip),\n knee: g.callout.knee ? mv(g.callout.knee) : undefined,\n },\n };\n }\n if (g.t === 'rect' || g.t === 'caret')\n return { ...g, rect: { ...g.rect, x: g.rect.x + d.x, y: g.rect.y + d.y } };\n if (g.t === 'line') return { ...g, a: mv(g.a), b: mv(g.b) };\n if (g.t === 'poly') return { ...g, points: g.points.map(mv) };\n if (g.t === 'ink') return { ...g, strokes: g.strokes.map((s) => s.map(mv)) };\n return { ...g, quads: g.quads.map((q) => mapTextQuad(q, mv)) };\n}\n\nconst OPPOSITE_HANDLE: Record<RectHandle, RectHandle> = {\n nw: 'se',\n ne: 'sw',\n se: 'nw',\n sw: 'ne',\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\n/**\n * Resize a ROTATED box by `handle`, keeping the opposite corner/edge fixed in\n * WORLD space. The pointer is mapped into the box's local (unrotated) frame, the\n * axis-aligned `resizeRect` runs there, then the new box is repositioned so the\n * anchor (the opposite handle's point) lands back where it was — and the box\n * still rotates about its OWN centre. With `rot === 0` this is exactly the plain\n * `resizeRect`.\n */\nfunction resizeRotatedRect(base: Rect, rot: number, handle: RectHandle, to: Vec): Rect {\n if (!rot) return resizeRect(base, handle, to);\n const c0 = rectCenter(base);\n const localTo = rotatePoint(to, c0, -rot);\n const next = resizeRect(base, handle, localTo);\n const anchorLocal = rectHandlePoint(base, OPPOSITE_HANDLE[handle]);\n const anchorWorld = rotatePoint(anchorLocal, c0, rot);\n const nextCenterLocal = rectCenter(next);\n // offset of the anchor from the new centre, in the local frame; rotate it to\n // world orientation and place the new centre so the anchor stays put.\n const offX = anchorLocal.x - nextCenterLocal.x;\n const offY = anchorLocal.y - nextCenterLocal.y;\n const rad = rot * DEG2RAD;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const rOffX = cos * offX - sin * offY;\n const rOffY = sin * offX + cos * offY;\n const cx = anchorWorld.x - rOffX;\n const cy = anchorWorld.y - rOffY;\n return {\n x: cx - next.width / 2,\n y: cy - next.height / 2,\n width: next.width,\n height: next.height,\n };\n}\n\nexport function geomDragHandle(g: Geom, handle: string, to: Vec): Geom {\n if (g.t === 'text') {\n if (handle === 'callout-tip' && g.callout) return { ...g, callout: { ...g.callout, tip: to } };\n if (handle === 'callout-knee' && g.callout)\n return { ...g, callout: { ...g.callout, knee: to } };\n return { ...g, rect: resizeRotatedRect(g.rect, g.rot ?? 0, handle as RectHandle, to) };\n }\n if (g.t === 'rect')\n return { ...g, rect: resizeRotatedRect(g.rect, g.rot ?? 0, handle as RectHandle, to) };\n if (g.t === 'line') return handle === 'v0' ? { ...g, a: to } : { ...g, b: to };\n if (g.t === 'poly') {\n const i = Number(handle.slice(1));\n if (!Number.isInteger(i) || i < 0 || i >= g.points.length) return g;\n const points = g.points.slice();\n points[i] = to;\n return { ...g, points };\n }\n return g;\n}\n\n/**\n * The text PLATE inset of a free-text box: twice the border width. The plate\n * — where text lays out, clips and scrolls — is the box deflated by this on\n * every side: the ink band and an equal breathing band, so the text never\n * touches the stroke. Acrobat's rule, measured 1–12 pt on plain boxes and\n * 1–7 pt on callouts (plan `2026-09-15-free-text-plate-inset.md`); the\n * engine's `FreeTextPlate` is the same formula, so the live editor sits\n * exactly where the baked text lands. Acrobat's thinnest border is 1 pt; a\n * width of 0 is ours alone and gives no inset (the plate is the box).\n */\nexport function textPlateInset(strokeWidth: number): number {\n return 2 * Math.max(0, strokeWidth);\n}\n\n/** A callout's leader (open polyline, its connection point extended under\n * the box border by half the stroke — the AP generator's `adjusted_conn` —\n * so the leader meets the border ink without an angular gap) + the arrow at\n * its tip. */\nfunction calloutLeaderNodes(\n g: Extract<Geom, { t: 'text' }>,\n callout: NonNullable<Extract<Geom, { t: 'text' }>['callout']>,\n strokeWidth: number,\n): RenderNode[] {\n const pts = [...calloutLinePoints(g)];\n if (strokeWidth > 0 && pts.length >= 2) {\n const last = pts[pts.length - 1];\n const prev = pts[pts.length - 2];\n const dx = last.x - prev.x;\n const dy = last.y - prev.y;\n const len = Math.hypot(dx, dy);\n if (len > 0) {\n pts[pts.length - 1] = {\n x: last.x + (dx / len) * (strokeWidth / 2),\n y: last.y + (dy / len) * (strokeWidth / 2),\n };\n }\n }\n const nodes: RenderNode[] = [{ kind: 'poly', points: pts, closed: false }];\n const seg = calloutEndingSeg(pts, callout.ending);\n if (seg) nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n return nodes;\n}\n\nexport function geomScene(g: Geom, strokeWidth = 0, border?: Border): RenderNode[] {\n // A text box's BOX — its fill and its border — is the scene's, plain box and\n // callout alike, so the live view paints exactly what the AP generator\n // bakes (`GenerateBorderAP`: the `/DA` colour at the `/BS` width, inset by\n // half the stroke). The framework's editable element owns only the TEXT: it\n // sits on the plate inside the border band and paints no background. A\n // callout adds its leader (open polyline) + arrow at the tip.\n if (g.t === 'text') {\n const nodes: RenderNode[] = [];\n if (g.callout) nodes.push(...calloutLeaderNodes(g, g.callout, strokeWidth));\n // The drawn path insets by half the stroke so the ink sits INSIDE\n // `g.rect` with its outer edge ON the rect — never straddling the\n // selection outline (the square/circle convention below). A tilted box\n // (the upright policy) draws as its rotated corner ring — the scene stays\n // plane-agnostic, so every framework painter gets the tilt for free (the\n // leader is page-space and never rotates).\n const r = insetRect(g.rect, strokeWidth / 2);\n const rot = g.rot ?? 0;\n const c = rectCenter(g.rect);\n nodes.push(\n rot\n ? {\n kind: 'poly',\n points: rectCornerPoints(r).map((p) => rotatePoint(p, c, rot)),\n closed: true,\n }\n : { kind: 'rect', rect: r },\n );\n return nodes;\n }\n if (g.t === 'caret') {\n const r = g.rect;\n const midX = r.x + r.width / 2;\n const bottom = r.y + r.height;\n const d = [\n `M ${r.x} ${bottom}`,\n `C ${r.x + r.width * 0.27} ${bottom} ${midX} ${r.y + r.height * 0.56} ${midX} ${r.y}`,\n `C ${midX} ${r.y + r.height * 0.56} ${r.x + r.width * 0.73} ${bottom} ${r.x + r.width} ${bottom}`,\n 'Z',\n ].join(' ');\n return [{ kind: 'path', d }];\n }\n if (g.t === 'rect') {\n // A cloudy border's scallops inset back into `g.rect` (the OUTER box): the troughs\n // land at the dragged inner edge (`g.rect` − extent) and the peaks on `g.rect`.\n // Only drawn when the box can hold them — a box smaller than 2× the inset (e.g.\n // a 0-drag, or after cranking intensity) falls through to the plain outline.\n if (border?.kind === 'cloudy') {\n const inset = cloudyBorderExtent(border.intensity, strokeWidth, g.ellipse);\n if (g.rect.width > 2 * inset && g.rect.height > 2 * inset) {\n return [{ kind: 'path', d: cloudyPath(g.rect, g.ellipse, border.intensity, strokeWidth) }];\n }\n }\n // Otherwise the stroke sits INSIDE the box: inset the drawn path by half the\n // stroke so its outer edge lands on `g.rect`, not straddling it.\n const r = insetRect(g.rect, strokeWidth / 2);\n return [g.ellipse ? { kind: 'ellipse', rect: r } : { kind: 'rect', rect: r }];\n }\n if (g.t === 'line') {\n const nodes: RenderNode[] = [{ kind: 'line', a: g.a, b: g.b }];\n for (const seg of endingSegs(g))\n nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n return nodes;\n }\n if (g.t === 'poly') {\n // A closed poly takes a cloudy border: curls centred on the vertex path,\n // reaching outward — the same geometry PDFium bakes (no /RD, unlike boxes).\n if (g.closed && border?.kind === 'cloudy' && g.points.length >= 3) {\n return [{ kind: 'path', d: cloudyPolyPath(g.points, border.intensity, strokeWidth) }];\n }\n const nodes: RenderNode[] = [{ kind: 'poly', points: g.points, closed: g.closed }];\n for (const seg of endingSegs(g))\n nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n return nodes;\n }\n if (g.t === 'ink') {\n // each pen stroke is an open polyline (stroke-only; `scene` paints it)\n return g.strokes.map((stroke) => ({ kind: 'poly', points: stroke, closed: false }));\n }\n // markup fallback: a closed ring per quad (US → UE → LE → LS). The scene\n // painter renders these per-subtype; this keeps the generic scene correct\n // regardless, rotated text included.\n return g.quads.map((q) => ({ kind: 'poly', points: textQuadRing(q), closed: true }));\n}\n\n/* ── PDF ↔ content bridge ─────────────────────────────────────────────────────\n * The ONE engine seam: PDF user space (y-up, crop bottom-left) ↔ content space\n * (y-down, crop top-left). The y-flip itself lives in `@embedpdf/core-geometry`\n * (`pdfToContentMatrix`) and is applied through its generic Mat2D primitives, so\n * this file never hand-rolls the rule. The only local work is bridging the\n * engine's edge-based `PdfRect` to geometry's corner+extent `RectIn`.\n * ──────────────────────────────────────────────────────────────────────────── */\n\nconst pdfRectToCorner = (r: PdfRect): RectIn<'pdf'> =>\n ({ x: r.left, y: r.bottom, width: r.right - r.left, height: r.top - r.bottom }) as RectIn<'pdf'>;\nconst cornerToPdfRect = (r: RectIn<'pdf'>): PdfRect => ({\n left: r.x,\n bottom: r.y,\n right: r.x + r.width,\n top: r.y + r.height,\n});\n\nexport const pdfToContentPoint = (p: PdfPoint, crop: PdfRect): Vec =>\n applyPoint(pdfToContentMatrix(crop), p as PointIn<'pdf'>);\nexport const contentToPdfPoint = (p: Vec, crop: PdfRect): PdfPoint =>\n applyPoint(invert(pdfToContentMatrix(crop)), p as PointIn<'content'>);\nexport const pdfToContentRect = (pdf: PdfRect, crop: PdfRect): Rect =>\n applyRect(pdfToContentMatrix(crop), pdfRectToCorner(pdf));\nexport const contentToPdfRect = (r: Rect, crop: PdfRect): PdfRect =>\n cornerToPdfRect(applyRect(invert(pdfToContentMatrix(crop)), r as RectIn<'content'>));\n\n/** A geom's VISUAL bounding box (geometry + stroke + line endings) as a PdfRect —\n * the engine requires an explicit `rect` that encloses the baked /AP. */\nexport const geomPdfBounds = (\n g: Geom,\n strokeWidth: number,\n crop: PdfRect,\n border?: Border,\n): PdfRect => contentToPdfRect(geomVisualBounds(g, strokeWidth, border), crop);\n","/**\n * Screen-anchored annotations — `noZoom` / `noRotate` (ISO 32000-2 §12.5.3).\n *\n * The mental model: these flags are DISPLAY-TRANSFORM EXEMPTIONS, nothing\n * more. The view composes content space onto the screen with\n * `zoom × pageRotation`; a flagged annotation asks it to skip the zoom factor\n * (`noZoom`) and/or the page-rotation factor (`noRotate`), holding the\n * `/Rect` upper-left — the geometry's bounds top-left — fixed on the page.\n *\n * The flags do NOT restrict editing. The annotation keeps its full\n * content-space identity: a size (`/Rect`, which now reads as \"screen size at\n * zoom 1\") and an authored orientation (`rot` / rotated points, which now\n * reads as \"screen tilt at every page rotation\") — and both stay editable.\n * Edit restrictions come from kind caps (a note kind declares\n * `resizable: false`) and `locked`, never from here.\n *\n * Everything derives from ONE projection, {@link anchoredGeom}: the effective\n * content-space geometry of the body at the current view — a similarity\n * (uniform scale `1/s` + rotation `-r`) about the anchor. Rendering,\n * hit-testing, chrome, marquee, and clamping all read it, so what you see,\n * what you click, and what commits can never disagree (the v2 failure: only\n * the DOM containers compensated).\n *\n * GESTURES compose in VIEW space: project first, then apply the gesture to\n * the projected geometry — for un-flagged annotations the projection is the\n * identity, so this is the ordinary pipeline. A pointer-driven commit maps\n * the final view-space geometry back to stored space through\n * {@link unanchoredGeom}, the exact closed-form inverse — chosen so that the\n * committed geometry's OWN re-projection reproduces the released preview\n * (zero release-jump, any zoom, any rotation).\n *\n * The core stays zoom-free: the view environment is passed PER CALL (the\n * `pageBox`/`chrome` pattern) and captured on pointer drafts at DOWN; it is\n * never stored on the model.\n */\nimport {\n geomBounds,\n geomRotateAbout,\n geomScaleAbout,\n geomTranslate,\n normalizeDeg,\n rotatePoint,\n} from './geometry';\nimport { capsFor } from './kinds';\nimport type { FlagBearer } from './flags';\nimport type { Geom, Vec, ViewEnv } from './types';\n\nexport type { ViewEnv };\n\n/** Which display factors this annotation is exempt from: `zoom` =\n * screen-constant size, `upright` = screen-constant orientation. */\nexport interface AnchorMode {\n zoom: boolean;\n upright: boolean;\n}\n\n/**\n * The anchor behaviors of one annotation: its `/F` flags OR'd with the kind's\n * statics — the spec's \"Text (note) annotations behave as if NoZoom and\n * NoRotate are ALWAYS set\", expressed as kind caps. Null when not anchored.\n */\nexport function anchorModeOf(a: FlagBearer): AnchorMode | null {\n const caps = capsFor(a.subtype);\n const zoom = a.flags.noZoom || caps.noZoom;\n const upright = a.flags.noRotate || caps.noRotate;\n return zoom || upright ? { zoom, upright } : null;\n}\n\n/**\n * The geometries the projection applies to: every kind with free content-space\n * geometry — boxes AND vertex kinds (line / poly / ink). Text-anchored\n * geometries (markup quads, carets) and callouts pass through: their position\n * is bound to page text, so a screen-constant body is meaningless there; the\n * flags still round-trip untouched.\n */\nconst projectable = (g: Geom): boolean =>\n g.t === 'rect' ||\n g.t === 'line' ||\n g.t === 'poly' ||\n g.t === 'ink' ||\n (g.t === 'text' && !g.callout);\n\n/** The fixed page point: the geometry's bounds top-left in content space\n * (y-down) — which IS the spec's \"upper-left corner of the annotation\n * rectangle\", since `/Rect` is emitted from these bounds. */\nexport const anchorOf = (g: Geom): Vec => {\n const b = geomBounds(g);\n return { x: b.x, y: b.y };\n};\n\nconst ORIGIN: Vec = { x: 0, y: 0 };\n\n/** The projection's factors for a mode at a view; `null` when it is the\n * identity (nothing to do). `s`/`r` are the STORED→VIEW inverse factors:\n * the forward projection applies `1/s` and `-r`.\n *\n * `s` clamps to `max(zoom, 1)` — Adobe's rule: `noZoom` holds the body at\n * its 100% size while zooming IN, but below 100% the body scales WITH the\n * page (a screen-constant body at 25% zoom would dwarf the page it\n * annotates, and its chrome would drift off-screen). */\nfunction factors(\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): { s: number; r: number } | null {\n if (!mode || !view) return null;\n const s = mode.zoom ? Math.max(view.zoom || 1, 1) : 1;\n const r = mode.upright ? normalizeDeg(view.rotation) : 0;\n return s !== 1 || r !== 0 ? { s, r } : null;\n}\n\n/**\n * THE effective content-space geometry of a screen-anchored body at `view`:\n * the stored geometry scaled by `1/max(zoom, 1)` about the anchor (`zoom`\n * exemption, Adobe-clamped) and counter-rotated by `-rotation` about it\n * (`upright`), so that after the page's own display transform the body reads\n * at its 100%-zoom size and its authored tilt, hanging from the fixed anchor.\n * Returns `g` unchanged when there is nothing to do — callers apply it\n * unconditionally.\n */\nexport function anchoredGeom(g: Geom, mode: AnchorMode | null, view: ViewEnv | undefined): Geom {\n const f = factors(mode, view);\n if (!f || !projectable(g)) return g;\n const a = anchorOf(g);\n let out: Geom = g;\n if (f.s !== 1) out = geomScaleAbout(out, a, 1 / f.s, 1 / f.s);\n if (f.r !== 0) out = geomRotateAbout(out, a, normalizeDeg(-f.r));\n return out;\n}\n\n/**\n * The exact inverse of {@link anchoredGeom} for a VIEW-space geometry a\n * gesture produced: the stored geometry whose OWN projection is `target`.\n *\n * Solving `anchoredGeom(stored) = target` where the projection anchors at\n * `stored`'s (unknown) bounds top-left `a` gives a closed form: map `target`\n * through the pure linear part (scale `s` + rotate `r` about the origin),\n * then translate so the result's bounds top-left `b` lands where the\n * projection needs it — at `a = R(-r)·b / s`, the unique fixed point. This is\n * what makes a released gesture commit EXACTLY what its preview showed.\n */\nexport function unanchoredGeom(\n target: Geom,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): Geom {\n const f = factors(mode, view);\n if (!f || !projectable(target)) return target;\n let lin: Geom = target;\n if (f.s !== 1) lin = geomScaleAbout(lin, ORIGIN, f.s, f.s);\n if (f.r !== 0) lin = geomRotateAbout(lin, ORIGIN, f.r);\n const b = anchorOf(lin);\n const a = rotatePoint(b, ORIGIN, -f.r);\n return geomTranslate(lin, { x: a.x / f.s - b.x, y: a.y / f.s - b.y });\n}\n\n/** Stroke width in the projected (view) space: a `noZoom` body's line weight\n * scales with its geometry so it stays screen-constant — through the SAME\n * factors (incl. the ≤100% clamp) the geometry projects with. */\nexport const anchoredStrokeWidth = (\n width: number,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): number => {\n const f = factors(mode, view);\n return f ? width / f.s : width;\n};\n\n/**\n * The similarity image of an axis-aligned box (a baked raster's AP `/Rect`)\n * under the anchor projection, as the blit vocabulary expects it: an\n * UNROTATED box (the projected centre + scaled size) plus the rotation to\n * re-apply about its centre. `anchor` is the OWNING GEOMETRY's anchor — the\n * raster rides its annotation's projection, it doesn't anchor itself. Null\n * when the projection is the identity.\n */\nexport function anchoredBox(\n box: { x: number; y: number; width: number; height: number },\n anchor: Vec,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): { box: { x: number; y: number; width: number; height: number }; rot: number } | null {\n const f = factors(mode, view);\n if (!f) return null;\n const c = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const scaled = {\n x: anchor.x + (c.x - anchor.x) / f.s,\n y: anchor.y + (c.y - anchor.y) / f.s,\n };\n const pc = f.r !== 0 ? rotatePoint(scaled, anchor, normalizeDeg(-f.r)) : scaled;\n const w = box.width / f.s;\n const h = box.height / f.s;\n return {\n box: { x: pc.x - w / 2, y: pc.y - h / 2, width: w, height: h },\n rot: normalizeDeg(-f.r),\n };\n}\n","import {\n geomHandles,\n geomHit,\n obbFromGeom,\n placeRotateKnob,\n pointInQuad,\n rectHandlesFor,\n selectionCenter,\n selectionQuad,\n unionRect,\n} from './geometry';\nimport { capsFor, isMarkup } from './kinds';\nimport { groupCaps } from './group';\nimport { isSubstrateOnly } from './plane';\nimport { annotInteractive, annotTransformable, viewable } from './flags';\nimport { anchoredGeom, anchoredStrokeWidth, anchorModeOf, type ViewEnv } from './anchor';\nimport {\n type Annot,\n type ChromeGeom,\n type Cursor,\n type Geom,\n type Id,\n type Model,\n type Rect,\n type Vec,\n} from './types';\n\nexport type Target =\n | { t: 'handle'; id: Id; handle: string; cursor: Cursor }\n // The rotate knob of the current selection (single shape or multi-target\n // group). `pivot` is the rotation centre the gesture turns about.\n | { t: 'rotate'; ids: Id[]; pivot: Vec }\n // A resize handle of the multi-target group box (the union box of the\n // selection). `box` is that union box; `ids` the members it scales.\n | { t: 'group-handle'; ids: Id[]; handle: string; cursor: Cursor; box: Rect }\n | { t: 'annot'; id: Id }\n | { t: 'empty' };\n\n/** Page annotation ids in PAINT order (back→front): text-layer markups first\n * (always beneath), then every other kind, each group preserving creation\n * z-order. The ONE z-order shared by rendering (`pageItems`) and hit-testing —\n * and the ONE visibility cull: what `/F` hides (hidden / un-engaged noView)\n * neither paints nor hits, so an invisible annotation can never eat a click.\n * Conversation-plane annotations (replies, review-status states) are culled\n * here too — dialogue lives in the comments UI, never on the page. */\nexport function paintOrder(m: Model, pon: number): Id[] {\n const markup: Id[] = [];\n const other: Id[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n if (!viewable(a.flags, m.selected.includes(id))) continue;\n if (isSubstrateOnly(a)) continue;\n (isMarkup(a.subtype) ? markup : other).push(id);\n }\n return [...markup, ...other];\n}\n\n/** Can this annotation be clicked to select? (`/F` interaction flags override\n * all caps — hidden/noView/readOnly are inert; LOCKED stays selectable, it\n * just won't transform.) */\nexport const isSelectable = (m: Model, id: Id): boolean => {\n const a = m.byId[id];\n return !!a && annotInteractive(a) && capsFor(a.subtype).selectable;\n};\n\n/** An anchored kind's QUAD geometry is bound to underlying text — never moved\n * or resized. This is what lets one caps set serve both redaction shapes:\n * area marks (rect geometry) keep their transforms, text marks (quads) are\n * as fixed as classic markup. Markup kinds themselves have `movable: false`\n * and never reach this gate. */\nconst textBound = (a: Annot): boolean => capsFor(a.subtype).anchored && a.geom.t === 'quads';\n\n/** Can this annotation be dragged by its body to move? (`locked` freezes it.) */\nexport const canMove = (m: Model, id: Id): boolean => {\n const a = m.byId[id];\n return !!a && annotTransformable(a) && capsFor(a.subtype).movable && !textBound(a);\n};\n\n/** Does this kind expose drag handles (box resize OR per-vertex)? Only\n * `locked` (and inert `/F` states) suppress them at runtime — a\n * screen-anchored body keeps its handles: `noZoom`/`noRotate` exempt it from\n * the display transform, they don't freeze its size or vertices. */\nconst hasHandles = (m: Model, a: Annot): boolean => {\n if (!annotTransformable(a) || textBound(a)) return false;\n const c = capsFor(a.subtype);\n return c.resizable || c.vertexEditable;\n};\n\n/** The geometry a pointer actually meets: the anchored (screen-constant)\n * projection for `noZoom`/`noRotate` annotations, the stored geom otherwise.\n * The SAME projection `pageItems` renders, so click matches paint. */\nconst hitGeomOf = (a: Annot, view: ViewEnv | undefined): Geom =>\n anchoredGeom(a.geom, anchorModeOf(a), view);\n\n/** Stroke width in EFFECTIVE content units (a noZoom body's line weight scales\n * with its geometry). */\nconst hitStrokeOf = (a: Annot, view: ViewEnv | undefined): number =>\n anchoredStrokeWidth(a.style.strokeWidth, anchorModeOf(a), view);\n\n// `opaqueBody` kinds (stamp images) are visible across their whole box, so they\n// hit like a filled shape. NOT keyed on `source: 'baked'` — every annotation\n// loaded from a PDF starts baked, and an unfilled square must still be grabbed\n// only on its outline.\nconst isFilled = (a: Annot): boolean =>\n a.style.interiorColor != null || a.geom.t === 'quads' || capsFor(a.subtype).opaqueBody;\nconst inRect = (b: Rect, p: Vec): boolean =>\n p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;\n// A SELECTED annotation is grabbable from anywhere inside its SELECTION region — the\n// SAME oriented quad the chrome outlines — so the grab area matches what you see\n// highlighted, tilt included (a rotated box is grabbable across its tilted body, not\n// just its unrotated footprint; a thin arrow's whole outline box, arrowhead and all).\nconst inBounds = (a: Annot, p: Vec, view: ViewEnv | undefined): boolean =>\n pointInQuad(p, selectionQuad(hitGeomOf(a, view), hitStrokeOf(a, view), a.style.border));\n\n/**\n * The union of the SELECTION bounds of every selected, movable annotation on a\n * page — the SAME box `chrome` outlines for a multi-selection. Null unless 2+\n * such annotations are selected here. This is the grab region for the gaps\n * BETWEEN grouped/multi-selected annotations, so dragging the whole selection\n * works from anywhere inside its visible outline (not only on a member).\n */\nfunction selectionUnionBounds(m: Model, pon: number, view: ViewEnv | undefined): Rect | null {\n const sel = m.selected.filter(\n (id) => m.byId[id]?.pon === pon && isSelectable(m, id) && canMove(m, id),\n );\n if (sel.length < 2) return null;\n const corners: Vec[] = [];\n for (const id of sel) {\n const a = m.byId[id];\n corners.push(...selectionQuad(hitGeomOf(a, view), hitStrokeOf(a, view), a.style.border));\n }\n return unionRect(corners);\n}\n\n/** The axis-aligned union of the SELECTION bounds of every selected annotation on\n * a page (no movable/lock filter) — the box group chrome + group rotate use. */\nexport function groupUnionBounds(m: Model, pon: number, view?: ViewEnv): Rect | null {\n const corners: Vec[] = [];\n for (const id of m.selected) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n corners.push(...selectionQuad(hitGeomOf(a, view), hitStrokeOf(a, view), a.style.border));\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/**\n * What's under the content point.\n * 1. a resize/vertex handle of the single selection,\n * 2. an editable annotation body — a SELECTED one anywhere in its bounds (so you\n * can drag to move it), an UNSELECTED one only on its stroke/fill (margin-aware,\n * so an unfilled circle is grabbed only on its outline),\n * 3. else empty.\n */\nexport function hitTest(\n m: Model,\n pon: number,\n p: Vec,\n geom: ChromeGeom,\n strokeMargin: number,\n pageBox?: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Target {\n if (m.selected.length === 1 && isSelectable(m, m.selected[0])) {\n const a = m.byId[m.selected[0]];\n if (a.pon === pon) {\n // The rotate knob (checked first — it floats outside the box, clear of\n // the handles), placed on the PROJECTED geometry so it sits exactly\n // where the chrome drew it — a screen-anchored body rotates too (the\n // gesture edits its authored tilt; `noRotate` only exempts it from the\n // PAGE's rotation). Locked suppresses it. `placeRotateKnob` keeps it\n // inside `pageBox`.\n if (capsFor(a.subtype).rotatable && annotTransformable(a)) {\n const hg = hitGeomOf(a, view);\n const obb = obbFromGeom(hg, hitStrokeOf(a, view), a.style.border);\n if (obb) {\n const knob = placeRotateKnob(obb.corners, geom.knobOffset, pageBox);\n if (\n Math.abs(knob.at.x - p.x) <= geom.knobTol &&\n Math.abs(knob.at.y - p.y) <= geom.knobTol\n ) {\n return {\n t: 'rotate',\n ids: [a.id],\n // VIEW-space pivot: the projected shape's centre — the point the\n // user sees the shape turn about (the commit conjugates back).\n pivot: selectionCenter(hg, hitStrokeOf(a, view)),\n };\n }\n }\n }\n if (hasHandles(m, a)) {\n // Handles live on the PROJECTED geometry — the handle gesture then\n // runs entirely in view space (see the `handle` draft).\n for (const h of geomHandles(hitGeomOf(a, view))) {\n if (\n Math.abs(h.at.x - p.x) <= geom.handleTol &&\n Math.abs(h.at.y - p.y) <= geom.handleTol\n ) {\n return { t: 'handle', id: a.id, handle: h.id, cursor: h.cursor };\n }\n }\n }\n }\n } else if (m.selected.length > 1) {\n // Multi-target group: a rotate knob hanging off the union box, gated by the\n // group caps (every member rotatable + none locked). Screen-anchored\n // members rotate WYSIWYG like everyone else (their authored tilt turns).\n const gc = groupCaps(m, m.selected);\n if (gc.rotatable) {\n const union = groupUnionBounds(m, pon, view);\n if (union) {\n const corners: [Vec, Vec, Vec, Vec] = [\n { x: union.x, y: union.y },\n { x: union.x + union.width, y: union.y },\n { x: union.x + union.width, y: union.y + union.height },\n { x: union.x, y: union.y + union.height },\n ];\n const knob = placeRotateKnob(corners, geom.knobOffset, pageBox);\n if (\n Math.abs(knob.at.x - p.x) <= geom.knobTol &&\n Math.abs(knob.at.y - p.y) <= geom.knobTol\n ) {\n const pivot = { x: union.x + union.width / 2, y: union.y + union.height / 2 };\n return { t: 'rotate', ids: m.selected.filter((id) => m.byId[id]?.pon === pon), pivot };\n }\n }\n }\n if (gc.resizable) {\n const union = groupUnionBounds(m, pon, view);\n if (union) {\n for (const h of rectHandlesFor(union)) {\n if (\n Math.abs(h.at.x - p.x) <= geom.handleTol &&\n Math.abs(h.at.y - p.y) <= geom.handleTol\n ) {\n return {\n t: 'group-handle',\n ids: m.selected.filter((id) => m.byId[id]?.pon === pon),\n handle: h.id,\n cursor: h.cursor,\n box: union,\n };\n }\n }\n }\n }\n }\n const order = paintOrder(m, pon);\n for (let i = order.length - 1; i >= 0; i--) {\n const id = order[i];\n const a = m.byId[id];\n // `inert` ids (engaged Behaviors — form widgets under a fill tool) are\n // invisible here: their own DOM owns the pointer.\n if (!a || inert?.has(id) || !isSelectable(m, id)) continue;\n // A SELECTED annotation is sticky-grabbable from anywhere in its bounds, but\n // only if it can actually move; otherwise it's grabbed on its stroke/fill like\n // an unselected one (so a selectable-but-anchored kind still re-selects cleanly).\n const hit =\n m.selected.includes(id) && canMove(m, id)\n ? inBounds(a, p, view)\n : geomHit(hitGeomOf(a, view), p, strokeMargin, isFilled(a), hitStrokeOf(a, view));\n if (hit) return { t: 'annot', id };\n }\n // Nothing under the point directly — but a multi-selection is grabbable across\n // its WHOLE union box (the gaps between members included), so a drag there moves\n // the group as a unit instead of clearing it. Resolve to the top-most selected\n // member so `editDown` keeps the selection and arms the move.\n const union = selectionUnionBounds(m, pon, view);\n if (union && inRect(union, p)) {\n for (let i = order.length - 1; i >= 0; i--) {\n if (m.selected.includes(order[i]) && canMove(m, order[i]))\n return { t: 'annot', id: order[i] };\n }\n }\n return { t: 'empty' };\n}\n\n/** The cursor to show on hover: a resize cursor over a handle, move/pointer over a body. */\nexport function cursorAt(\n m: Model,\n pon: number,\n p: Vec,\n geom: ChromeGeom,\n strokeMargin: number,\n pageBox?: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Cursor | null {\n const t = hitTest(m, pon, p, geom, strokeMargin, pageBox, inert, view);\n if (t.t === 'handle') return t.cursor;\n if (t.t === 'group-handle') return t.cursor;\n if (t.t === 'rotate') return 'grab';\n if (t.t === 'annot') return m.selected.includes(t.id) && canMove(m, t.id) ? 'move' : 'pointer';\n return null;\n}\n","/**\n * The attached-link lens — the conversation-plane pattern applied to link\n * children. The substrate keeps every `/RT /Group` link child as a\n * first-class `Annot`; these pure derivations present them as the parent's\n * `link` property. ONE source of truth (the children), so a remote\n * create/retarget/delete is an ordinary substrate upsert/remove and every\n * read converges through here — no folded copy on the parent, no join-key\n * ledger, no reconciliation rules between the two.\n *\n * Callers memoize by model identity where it matters (nav items, selection\n * props); these scans stay O(order) and allocation-light.\n */\nimport type { PdfLinkTarget } from '@embedpdf/engine-core/runtime';\n\nimport { isAttachedLink } from './plane';\nimport type { Annot, Id, Model } from './types';\n\n/** Every attached link child of `parentId`, in z-order (multi-segment\n * markup parents carry several children with one shared target). */\nexport function linkChildrenOf(m: Model, parentId: Id): Annot[] {\n const out: Annot[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (a && isAttachedLink(a) && a.group === parentId) out.push(a);\n }\n return out;\n}\n\n/** The parent's link target, derived from its first attached child — the\n * read side of the `syncLink` reconciler. Null when no child exists. */\nexport function linkOf(m: Model, parentId: Id): PdfLinkTarget | null {\n const d = linkChildrenOf(m, parentId)[0]?.data;\n return d?.subtype === 'link' ? (d.target ?? null) : null;\n}\n","/**\n * The flat property vocabulary over the model: read and apply\n * {@link AnnotationProps} keys on an `Annot`, routing each key to where it is\n * stored (`style`, `geom.ends`, or `text`) so callers never learn the storage.\n * Which keys a kind takes is declared in the KIND table (`propsFor`); keys a\n * kind doesn't declare are ignored — that's what lets ONE patch restyle a\n * mixed selection.\n */\nimport { propsFor, type PropSpec } from './kinds';\nimport { annotTransformable } from './flags';\nimport type {\n Annot,\n AnnotationProps,\n AnnotationPropsPatch,\n Geom,\n LineEndings,\n PropKey,\n Style,\n TextStyle,\n} from './types';\n\nconst NO_ENDINGS: LineEndings = { start: 'none', end: 'none' };\n\n/** Base text styling for kinds/tools with no explicit defaults. */\nexport const initialTextStyle: TextStyle = {\n fontFamily: 'helvetica',\n fontSize: 14,\n fontColor: '#000000',\n textAlign: 'left',\n};\n\n/** The `Style` slice of a resolved props bag (the create-time projection). */\nexport const styleFromProps = (p: AnnotationProps): Style => ({\n color: p.color,\n interiorColor: p.interiorColor,\n strokeWidth: p.strokeWidth,\n opacity: p.opacity,\n blendMode: p.blendMode,\n border: p.border,\n});\n\n/** The `TextStyle` slice of a resolved props bag (the create-time projection). */\nexport const textStyleFromProps = (p: AnnotationProps): TextStyle => ({\n fontFamily: p.fontFamily,\n fontSize: p.fontSize,\n fontColor: p.fontColor,\n textAlign: p.textAlign,\n ...(p.bold !== undefined ? { bold: p.bold } : {}),\n ...(p.italic !== undefined ? { italic: p.italic } : {}),\n ...(p.underline !== undefined ? { underline: p.underline } : {}),\n});\n\n/** Does this kind's prop table declare `link` (attachable link)? The link\n * KIND itself also declares it, but stores its own `/A` instead. */\nexport const kindTakesLink = (subtype: string): boolean =>\n propsFor(subtype).some((s) => s.key === 'link');\n\n/** A geom that carries `/LE` endings: a line, or an OPEN poly (polyline). */\nconst endingsGeom = (g: Geom): g is Extract<Geom, { t: 'line' } | { t: 'poly' }> =>\n g.t === 'line' || (g.t === 'poly' && !g.closed);\n\n/**\n * Read one property off an annotation — from wherever it lives — or `undefined`\n * when the annotation's kind doesn't carry it (a `fontSize` on a square, endings\n * on a polygon). The read side of `applyProps`.\n */\nexport function readProp<K extends PropKey>(a: Annot, key: K): AnnotationProps[K] | undefined {\n const out = ((): AnnotationProps[PropKey] | undefined => {\n switch (key) {\n case 'color':\n return a.style.color;\n case 'interiorColor':\n return a.style.interiorColor;\n case 'strokeWidth':\n return a.style.strokeWidth;\n case 'opacity':\n return a.style.opacity;\n case 'blendMode':\n return a.style.blendMode;\n case 'border':\n return a.style.border;\n case 'lineEndings':\n return endingsGeom(a.geom) ? (a.geom.ends ?? NO_ENDINGS) : undefined;\n case 'fontFamily':\n return a.text?.fontFamily;\n case 'fontSize':\n return a.text?.fontSize;\n case 'fontColor':\n return a.text?.fontColor;\n case 'textAlign':\n return a.text?.textAlign;\n case 'bold':\n return a.text ? (a.text.bold ?? false) : undefined;\n case 'italic':\n return a.text ? (a.text.italic ?? false) : undefined;\n case 'underline':\n return a.text ? (a.text.underline ?? false) : undefined;\n case 'icon':\n return a.icon;\n case 'link':\n return a.link;\n }\n })();\n return out as AnnotationProps[K] | undefined;\n}\n\n/**\n * Apply a property patch to one annotation, honouring its kind's declared keys.\n * Returns the changed annotation, or `null` when nothing applied (locked /\n * read-only per its `/F` flags, or no declared key in the patch) — so the\n * caller emits no spurious engine write. Flags themselves are NOT props: they\n * write through the `setFlags` message, which is deliberately not gated here\n * (unlocking must work on a locked annotation).\n */\nexport function applyProps(a: Annot, patch: AnnotationPropsPatch): Annot | null {\n if (!annotTransformable(a)) return null;\n const takes = new Set<PropKey>(propsFor(a.subtype).map((s) => s.key));\n let next = a;\n\n // `!== undefined` (not truthiness): `interiorColor: null` means CLEAR the fill.\n const style: Style = { ...a.style };\n let styleChanged = false;\n if (patch.color !== undefined && takes.has('color')) {\n style.color = patch.color;\n styleChanged = true;\n }\n if (patch.interiorColor !== undefined && takes.has('interiorColor')) {\n style.interiorColor = patch.interiorColor;\n styleChanged = true;\n }\n if (patch.strokeWidth !== undefined && takes.has('strokeWidth')) {\n style.strokeWidth = patch.strokeWidth;\n styleChanged = true;\n }\n if (patch.opacity !== undefined && takes.has('opacity')) {\n style.opacity = patch.opacity;\n styleChanged = true;\n }\n if (patch.blendMode !== undefined && takes.has('blendMode')) {\n style.blendMode = patch.blendMode;\n styleChanged = true;\n }\n if (patch.border !== undefined && takes.has('border')) {\n style.border = patch.border;\n styleChanged = true;\n }\n if (styleChanged) next = { ...next, style };\n\n if (patch.lineEndings && takes.has('lineEndings') && endingsGeom(next.geom)) {\n const ends: LineEndings = { ...(next.geom.ends ?? NO_ENDINGS), ...patch.lineEndings };\n next = { ...next, geom: { ...next.geom, ends } };\n }\n\n if (patch.icon !== undefined && takes.has('icon')) {\n next = { ...next, icon: patch.icon };\n }\n\n // Only the link KIND stores `link` (its own /A, a real wire prop). On every\n // other kind the value lives in attached child annotations: `setProps`\n // emits the `syncLink` intent instead of touching the model, and reads\n // derive through the `linkOf` lens.\n if (patch.link !== undefined && takes.has('link') && a.subtype === 'link') {\n next = { ...next, link: patch.link };\n }\n\n if (next.text) {\n const text: TextStyle = { ...next.text };\n let textChanged = false;\n if (patch.fontFamily !== undefined && takes.has('fontFamily')) {\n text.fontFamily = patch.fontFamily;\n textChanged = true;\n }\n if (patch.fontSize !== undefined && takes.has('fontSize')) {\n text.fontSize = patch.fontSize;\n textChanged = true;\n }\n if (patch.fontColor !== undefined && takes.has('fontColor')) {\n text.fontColor = patch.fontColor;\n textChanged = true;\n }\n if (patch.textAlign !== undefined && takes.has('textAlign')) {\n text.textAlign = patch.textAlign;\n textChanged = true;\n }\n for (const key of ['bold', 'italic', 'underline'] as const) {\n const value = patch[key];\n if (value !== undefined && takes.has(key) && (text[key] ?? false) !== value) {\n text[key] = value;\n textChanged = true;\n }\n }\n if (textChanged) next = { ...next, text };\n }\n\n return next === a ? null : next;\n}\n\n/**\n * The ordered property specs EVERY given kind declares — the schema for a mixed\n * selection, in the FIRST kind's display order. One kind → its own list, verbatim.\n */\nexport function sharedProps(subtypes: readonly string[]): PropSpec[] {\n const unique = [...new Set(subtypes)];\n if (!unique.length) return [];\n const first = propsFor(unique[0]);\n if (unique.length === 1) return first;\n const rest = unique.slice(1).map((s) => new Set(propsFor(s).map((p) => p.key)));\n return first.filter((p) => rest.every((keys) => keys.has(p.key)));\n}\n","/**\n * Click-create PLACEMENT — the pure, plane-agnostic layer.\n *\n * `resolveClickPlacement` answers \"where does a bare click put the thing\": a\n * box (anchored per POLICY, upright-aware, slid onto the page) or a segment\n * (default length/angle from the point, slid onto the page as a unit). It is\n * THE single source for that answer — the annotation core's click commit, the\n * hover footprint ghost, and the form plugin's field placement all consume\n * the same result, so preview ≡ commit by construction.\n *\n * It deliberately returns LOGICAL geometry: no annotation visual semantics\n * (no cloudy-border outer-box expansion, no ellipse) — a form field takes\n * `rect` straight to `doc.forms.createField`. The annotation-only conversion\n * to a committable/renderable `Geom` is {@link clickCreateGeom} below; that\n * is where `shapeRectFor` and ellipse semantics apply.\n */\nimport {\n rectFromPoints,\n shapeRectFor,\n transposedAboutCenter,\n uprightAnchoredRect,\n uprightRotation,\n} from './geometry';\nimport { styleFromProps } from './props';\nimport type { PageRotation } from '@embedpdf/core-geometry';\nimport type { AnnotationProps, ClickCreate, Geom, Rect, Subtype, Vec } from './types';\n\n/** A resolved click placement: what the click will occupy, page-clamped. */\nexport type ClickPlacement =\n | {\n kind: 'box';\n rect: Rect;\n /** Upright counter-rotation captured for the commit (deg CW; 0 = none). */\n rot: number;\n }\n | { kind: 'segment'; a: Vec; b: Vec };\n\n/** Slide a rect (as a unit) to sit inside `box`; pins at the origin edge when\n * it doesn't fit. Placements are page-bound; the pointer isn't. */\nexport const clampRectToBox = (r: Rect, box: Rect | undefined): Rect => {\n if (!box) return r;\n return {\n ...r,\n x: Math.min(Math.max(r.x, box.x), Math.max(box.x, box.x + box.width - r.width)),\n y: Math.min(Math.max(r.y, box.y), Math.max(box.y, box.y + box.height - r.height)),\n };\n};\n\n/**\n * Resolve a click-create POLICY at a content point. `anchor` defaults to\n * `center`; under `upright` a box counter-rotates against the page's display\n * rotation exactly as the drag commit would (centre-anchored boxes transpose\n * about their centre, top-left boxes anchor in the DISPLAY frame).\n */\nexport function resolveClickPlacement(\n point: Vec,\n policy: ClickCreate,\n opts: { pageBox?: Rect; upright?: boolean; displayRotation?: PageRotation } = {},\n): ClickPlacement {\n if ('length' in policy) {\n const ang = ((policy.angleDeg ?? 0) * Math.PI) / 180;\n const b = {\n x: point.x + Math.cos(ang) * policy.length,\n y: point.y + Math.sin(ang) * policy.length,\n };\n const bounds = rectFromPoints(point, b);\n const placed = clampRectToBox(bounds, opts.pageBox);\n const dx = placed.x - bounds.x;\n const dy = placed.y - bounds.y;\n return {\n kind: 'segment',\n a: { x: point.x + dx, y: point.y + dy },\n b: { x: b.x + dx, y: b.y + dy },\n };\n }\n const { width, height } = policy;\n const rot = opts.upright && opts.displayRotation ? uprightRotation(opts.displayRotation) : 0;\n let rect: Rect;\n if (policy.anchor === 'top-left') {\n rect = rot\n ? uprightAnchoredRect(point, width, height, opts.displayRotation!)\n : { x: point.x, y: point.y, width, height };\n } else {\n rect = { x: point.x - width / 2, y: point.y - height / 2, width, height };\n // A quarter-turn transposes the unrotated box so the DISPLAYED box keeps\n // the configured width×height (same rule as a dragged box).\n if (rot === 90 || rot === 270) rect = transposedAboutCenter(rect);\n }\n return { kind: 'box', rect: clampRectToBox(rect, opts.pageBox), rot };\n}\n\n/**\n * ANNOTATION-ONLY: convert a placement into the `Geom` the commit stores and\n * the ghost paints, for a routing kind. This is where annotation VISUAL\n * semantics live — ellipse for circles, the cloudy outer-box via\n * `shapeRectFor`. Forms never call this; a field box is the placement rect\n * itself. Null for kinds a click cannot author.\n */\nexport function clickCreateGeom(\n subtype: Subtype,\n placement: ClickPlacement,\n def: AnnotationProps,\n): Geom | null {\n if (placement.kind === 'segment') {\n return subtype === 'line'\n ? { t: 'line', a: placement.a, b: placement.b, ends: def.lineEndings }\n : null;\n }\n const { rect, rot } = placement;\n if (subtype === 'free-text') {\n return { t: 'text', rect, ...(rot ? { rot } : {}) };\n }\n if (subtype === 'square' || subtype === 'circle') {\n return {\n t: 'rect',\n rect: shapeRectFor(rect, subtype === 'circle', styleFromProps(def)),\n ellipse: subtype === 'circle',\n ...(rot ? { rot } : {}),\n };\n }\n return null;\n}\n","/**\n * Rich text run algebra — the pure operations an editor needs on a FreeText's\n * rich document (engine `RichTextDocumentInput`): flat offsets over the plain\n * projection, run splitting at a boundary, applying a style delta to a range,\n * and normalisation. No DOM, no engine: the editor binding (in `@embedpdf/web`)\n * maps DOM selections to these offsets and renders the result; the plugin\n * applies these functions and commits.\n *\n * Offsets are positions in the plain projection: paragraphs joined by `\\r`,\n * runs concatenated. Every character counts one, including the `\\r` a run\n * carries as a hard break and the `\\r` that separates two paragraphs.\n */\nimport type {\n RichTextDocumentInput,\n RichTextParagraph,\n RichTextRun,\n RichTextRunStyle,\n} from '@embedpdf/engine-core/runtime';\n\nexport type RichTextStyleDelta = Partial<RichTextRunStyle>;\n\n/** A range of the plain projection, `start <= end`, end exclusive. */\nexport interface RichTextRange {\n start: number;\n end: number;\n}\n\n/** Length of the plain projection. */\nexport function richTextLength(doc: { paragraphs: readonly RichTextParagraph[] }): number {\n let n = 0;\n doc.paragraphs.forEach((p, i) => {\n if (i > 0) n += 1;\n for (const r of p.runs) n += r.text.length;\n });\n return n;\n}\n\nconst DELTA_KEYS: readonly (keyof RichTextRunStyle)[] = [\n 'family',\n 'weight',\n 'italic',\n 'size',\n 'color',\n 'decoration',\n 'script',\n 'letterSpacing',\n 'horizontalScale',\n 'unknown',\n];\n\nfunction sameDecoration(\n a: readonly string[] | undefined,\n b: readonly string[] | undefined,\n): boolean {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n const sorted = (x: readonly string[]) => [...x].sort();\n const sa = sorted(a);\n const sb = sorted(b);\n return sa.every((v, i) => v === sb[i]);\n}\n\n/** Two deltas override the same properties with the same values. */\nexport function sameStyleDelta(\n a: RichTextStyleDelta | undefined,\n b: RichTextStyleDelta | undefined,\n): boolean {\n const da = a ?? {};\n const db = b ?? {};\n for (const key of DELTA_KEYS) {\n if (key === 'decoration') {\n if (!sameDecoration(da.decoration, db.decoration)) return false;\n } else if (da[key] !== db[key]) {\n return false;\n }\n }\n return true;\n}\n\n/** A delta with every `undefined` member removed; `undefined` when empty. */\nfunction cleanDelta(delta: RichTextStyleDelta | undefined): RichTextStyleDelta | undefined {\n if (!delta) return undefined;\n const out: RichTextStyleDelta = {};\n let any = false;\n for (const key of DELTA_KEYS) {\n const value = delta[key];\n if (value !== undefined) {\n (out as Record<string, unknown>)[key] = value;\n any = true;\n }\n }\n return any ? out : undefined;\n}\n\n/**\n * Merge adjacent runs whose deltas agree, drop empty runs, strip empty\n * deltas. A paragraph with no text keeps a single empty run so the editor\n * has somewhere to put the caret.\n */\nexport function normalizeRuns<T extends { paragraphs: RichTextParagraph[] }>(doc: T): T {\n const paragraphs = doc.paragraphs.map((p) => {\n const runs: RichTextRun[] = [];\n for (const run of p.runs) {\n if (run.text.length === 0) continue;\n const style = cleanDelta(run.style);\n const last = runs[runs.length - 1];\n if (last && sameStyleDelta(last.style, style)) {\n runs[runs.length - 1] = { ...last, text: last.text + run.text };\n } else {\n runs.push(style ? { text: run.text, style } : { text: run.text });\n }\n }\n if (runs.length === 0) runs.push({ text: '' });\n return { ...p, runs };\n });\n return { ...doc, paragraphs };\n}\n\n/** Where a flat offset falls: paragraph index and offset within it (the\n * separator between paragraphs belongs to the end of the earlier one). */\nexport function locateOffset(\n doc: { paragraphs: readonly RichTextParagraph[] },\n offset: number,\n): { paragraph: number; offset: number } {\n let pos = 0;\n for (let i = 0; i < doc.paragraphs.length; i++) {\n const length = doc.paragraphs[i]!.runs.reduce((n, r) => n + r.text.length, 0);\n if (offset <= pos + length || i === doc.paragraphs.length - 1) {\n return { paragraph: i, offset: Math.max(0, Math.min(length, offset - pos)) };\n }\n pos += length + 1; // the paragraph separator\n }\n return { paragraph: 0, offset: 0 };\n}\n\n/** The paragraph with a run boundary guaranteed at a local offset. */\nexport function splitRunsAt(paragraph: RichTextParagraph, offset: number): RichTextParagraph {\n const runs: RichTextRun[] = [];\n let pos = 0;\n for (const run of paragraph.runs) {\n const end = pos + run.text.length;\n if (offset > pos && offset < end) {\n const cut = offset - pos;\n runs.push({ ...run, text: run.text.slice(0, cut) });\n runs.push({ ...run, text: run.text.slice(cut) });\n } else {\n runs.push(run);\n }\n pos = end;\n }\n return { ...paragraph, runs };\n}\n\n/**\n * Apply a style delta to every character of a range: the runs it touches are\n * split at its boundaries, the covered pieces take the delta on top of what\n * they already override (`clear` names properties to stop overriding, so\n * they follow the body again), and the result is normalised. An empty range\n * is a no-op.\n */\nexport function applyStyleToRange<T extends { paragraphs: RichTextParagraph[] }>(\n doc: T,\n range: RichTextRange,\n delta: RichTextStyleDelta,\n clear: readonly (keyof RichTextRunStyle)[] = [],\n): T {\n const start = Math.max(0, Math.min(range.start, range.end));\n const end = Math.max(range.start, range.end);\n if (end <= start) return doc;\n const from = locateOffset(doc, start);\n const to = locateOffset(doc, end);\n const paragraphs = doc.paragraphs.map((paragraph, index) => {\n if (index < from.paragraph || index > to.paragraph) return paragraph;\n const localStart = index === from.paragraph ? from.offset : 0;\n const localEnd =\n index === to.paragraph ? to.offset : paragraph.runs.reduce((n, r) => n + r.text.length, 0);\n if (localEnd <= localStart) return paragraph;\n const split = splitRunsAt(splitRunsAt(paragraph, localStart), localEnd);\n let pos = 0;\n const runs = split.runs.map((run) => {\n const runStart = pos;\n pos += run.text.length;\n if (runStart < localStart || runStart >= localEnd || run.text.length === 0) return run;\n const style: RichTextStyleDelta = { ...(run.style ?? {}), ...delta };\n for (const key of clear) delete (style as Record<string, unknown>)[key];\n return { ...run, style };\n });\n return { ...split, runs };\n });\n return normalizeRuns({ ...doc, paragraphs });\n}\n\n/**\n * The delta in force at a caret: the run the offset falls in, or, at a run\n * boundary, the run before it (what typing there would inherit). Undefined\n * for an empty document.\n */\nexport function styleAt(\n doc: { paragraphs: readonly RichTextParagraph[] },\n offset: number,\n): RichTextStyleDelta | undefined {\n const at = locateOffset(doc, offset);\n const paragraph = doc.paragraphs[at.paragraph];\n if (!paragraph) return undefined;\n let pos = 0;\n let previous: RichTextRun | undefined;\n for (const run of paragraph.runs) {\n const end = pos + run.text.length;\n if (at.offset > pos && at.offset <= end) return run.style ?? {};\n if (at.offset === pos && pos === 0) return run.style ?? {};\n previous = run;\n pos = end;\n }\n return previous?.style ?? {};\n}\n\n/** Every run overlapping the range satisfies `predicate` (an empty range\n * tests the caret's style). */\nexport function rangeHasStyle(\n doc: { paragraphs: readonly RichTextParagraph[] },\n range: RichTextRange,\n predicate: (delta: RichTextStyleDelta) => boolean,\n): boolean {\n const start = Math.min(range.start, range.end);\n const end = Math.max(range.start, range.end);\n if (end <= start) return predicate(styleAt(doc, start) ?? {});\n const from = locateOffset(doc, start);\n const to = locateOffset(doc, end);\n let any = false;\n for (let index = from.paragraph; index <= to.paragraph; index++) {\n const paragraph = doc.paragraphs[index]!;\n const localStart = index === from.paragraph ? from.offset : 0;\n const localEnd =\n index === to.paragraph ? to.offset : paragraph.runs.reduce((n, r) => n + r.text.length, 0);\n let pos = 0;\n for (const run of paragraph.runs) {\n const runEnd = pos + run.text.length;\n if (runEnd > localStart && pos < localEnd && run.text.length > 0) {\n any = true;\n if (!predicate(run.style ?? {})) return false;\n }\n pos = runEnd;\n }\n }\n return any;\n}\n\n/** Plain paragraphs from text: one per line break, one unstyled run each. */\nexport function paragraphsFromPlainText(text: string): RichTextParagraph[] {\n return text.split(/\\r\\n|\\r|\\n/).map((line) => ({ runs: [{ text: line }] }));\n}\n\n/** The plain projection: paragraphs joined by `\\r`, runs concatenated. */\nexport function plainTextOf(doc: { paragraphs: readonly RichTextParagraph[] }): string {\n return doc.paragraphs.map((p) => p.runs.map((r) => r.text).join('')).join('\\r');\n}\n\n/** True when nothing in the document overrides the body: no run delta, no\n * paragraph property. Such a document commits as plain `contents`. */\nexport function isPlainRichText(doc: RichTextDocumentInput): boolean {\n if (doc.body && Object.keys(doc.body).length > 0) return false;\n return doc.paragraphs.every(\n (p) =>\n p.align === undefined &&\n p.dir === undefined &&\n p.lineHeight === undefined &&\n p.margins === undefined &&\n p.textIndent === undefined &&\n p.unknown === undefined &&\n p.runs.every((r) => cleanDelta(r.style) === undefined),\n );\n}\n","/**\n * Pure alignment snapping for the move gesture. Compares the moving selection's\n * edges + centers against every other annotation on the page (and the page\n * box); if a pair lands within the threshold, nudges the delta to align them\n * and reports a guide line to draw. One snap per axis — the closest wins.\n * Threshold is in content units (the `hitMargin` convention).\n */\nimport { anchorModeOf } from './anchor';\nimport { selectionQuad, unionRect } from './geometry';\nimport { isSelectable } from './hit';\nimport type { Guide, Id, Model, Rect, Vec } from './types';\n\nexport interface SnapResult {\n delta: Vec;\n guides: Guide[];\n}\n\ninterface Bounds {\n min: Vec;\n max: Vec;\n}\n\n/** Overshoot the shapes a little so the guide reads as a through-line. */\nconst GUIDE_PAD = 14;\n\nconst toBounds = (r: Rect): Bounds => ({\n min: { x: r.x, y: r.y },\n max: { x: r.x + r.width, y: r.y + r.height },\n});\nconst keysX = (b: Bounds) => [b.min.x, (b.min.x + b.max.x) / 2, b.max.x];\nconst keysY = (b: Bounds) => [b.min.y, (b.min.y + b.max.y) / 2, b.max.y];\nconst shift = (b: Bounds, d: Vec): Bounds => ({\n min: { x: b.min.x + d.x, y: b.min.y + d.y },\n max: { x: b.max.x + d.x, y: b.max.y + d.y },\n});\n\n/** An annotation's visual footprint corners — the ORIENTED quad, so a rotated\n * shape snaps by what's actually drawn, not its unrotated box. */\nconst annotQuad = (m: Model, id: Id): Vec[] =>\n selectionQuad(m.byId[id].geom, m.byId[id].style.strokeWidth, m.byId[id].style.border);\n\n/**\n * Snap a move delta: shift the selection's union bounds by `raw`, compare its\n * 3 keys per axis (min / center / max) against every target's, and take the\n * closest in-threshold pair per axis as an adjustment. Targets are the page box\n * (edges + center) and every non-moving annotation on the page.\n */\nexport function computeMoveSnap(\n m: Model,\n ids: Id[],\n pon: number,\n raw: Vec,\n threshold: number,\n pageBox: Rect | undefined,\n): SnapResult {\n const moving = new Set(ids);\n // Screen-anchored (`noZoom`/`noRotate`) annotations sit OUTSIDE the snapping\n // system, both ways: their content-space footprint depends on the view, so\n // an alignment made at one zoom is a lie at every other zoom. A selection\n // that contains one doesn't snap; one that's parked on the page is never a\n // reference edge. (The page-edge CLAMP is unaffected — it uses projected\n // bounds per event.)\n if (ids.some((id) => m.byId[id] && anchorModeOf(m.byId[id]))) {\n return { delta: raw, guides: [] };\n }\n const base = toBounds(unionRect(ids.flatMap((id) => annotQuad(m, id))));\n const movingBox = shift(base, raw);\n\n const targets: Bounds[] = [\n ...(pageBox ? [toBounds(pageBox)] : []),\n ...m.order\n .filter(\n (id) =>\n !moving.has(id) &&\n m.byId[id].pon === pon &&\n isSelectable(m, id) &&\n !anchorModeOf(m.byId[id]),\n )\n .map((id) => toBounds(unionRect(annotQuad(m, id)))),\n ];\n\n let bx: { adjust: number; at: number; tb: Bounds } | null = null;\n let by: { adjust: number; at: number; tb: Bounds } | null = null;\n for (const tb of targets) {\n for (const tk of keysX(tb))\n for (const mk of keysX(movingBox)) {\n const diff = tk - mk;\n if (Math.abs(diff) < threshold && (!bx || Math.abs(diff) < Math.abs(bx.adjust)))\n bx = { adjust: diff, at: tk, tb };\n }\n for (const tk of keysY(tb))\n for (const mk of keysY(movingBox)) {\n const diff = tk - mk;\n if (Math.abs(diff) < threshold && (!by || Math.abs(diff) < Math.abs(by.adjust)))\n by = { adjust: diff, at: tk, tb };\n }\n }\n\n const delta = { x: raw.x + (bx?.adjust ?? 0), y: raw.y + (by?.adjust ?? 0) };\n const snapped = shift(base, delta);\n const guides: Guide[] = [];\n if (bx)\n guides.push({\n axis: 'x',\n at: bx.at,\n lo: Math.min(snapped.min.y, bx.tb.min.y) - GUIDE_PAD,\n hi: Math.max(snapped.max.y, bx.tb.max.y) + GUIDE_PAD,\n });\n if (by)\n guides.push({\n axis: 'y',\n at: by.at,\n lo: Math.min(snapped.min.x, by.tb.min.x) - GUIDE_PAD,\n hi: Math.max(snapped.max.x, by.tb.max.x) + GUIDE_PAD,\n });\n return { delta, guides };\n}\n","import type { InkStraightenOptions, Vec } from './types';\n\n/**\n * Recognise a sufficiently straight freehand stroke and axis-snap it when it is\n * close to horizontal or vertical. Diagonal strokes remain untouched: this is\n * a highlighter aid, not a general line simplifier.\n */\nexport function straightenInkStroke(points: readonly Vec[], options: InkStraightenOptions): Vec[] {\n if (points.length < 3) return [...points];\n const first = points[0];\n const last = points[points.length - 1];\n const dx = last.x - first.x;\n const dy = last.y - first.y;\n const length = Math.hypot(dx, dy);\n if (length < 3) return [...points];\n\n const maxDeviation = points.reduce((max, point) => {\n const distance = Math.abs(dx * (first.y - point.y) - (first.x - point.x) * dy) / length;\n return Math.max(max, distance);\n }, 0);\n if (maxDeviation / length >= options.deviationThreshold) return [...points];\n\n const angle = Math.atan2(Math.abs(dy), Math.abs(dx)) * (180 / Math.PI);\n if (angle <= options.axisSnapDegrees) {\n const y = points.reduce((sum, point) => sum + point.y, 0) / points.length;\n return [\n { x: first.x, y },\n { x: last.x, y },\n ];\n }\n if (angle >= 90 - options.axisSnapDegrees) {\n const x = points.reduce((sum, point) => sum + point.x, 0) / points.length;\n return [\n { x, y: first.y },\n { x, y: last.y },\n ];\n }\n return [...points];\n}\n","/**\n * The pure annotation core: update(model, msg) → [model, effects].\n *\n * Editing is intent-driven (the shell's edit handler sends `editPointer`, the draw\n * handler `createPointer`). Geometry lives in the `Geom` union; all the per-kind\n * math is in geometry.ts. Effects (create/patch/delete) are the only impurities.\n */\nimport type {\n AnnotationFlags,\n AnnotationRef,\n InkIntent,\n RichTextDocumentInput,\n} from '@embedpdf/engine-core/runtime';\nimport { expandGroups, groupMembers } from './group';\nimport { canMove, groupUnionBounds, hitTest, isSelectable } from './hit';\nimport { isSubstrateOnly } from './plane';\nimport { linkChildrenOf } from './links';\nimport { capsFor } from './kinds';\nimport {\n annotContentsEditable,\n annotDeletable,\n annotTransformable,\n DRAWN_FLAGS,\n flagsEqual,\n mergeFlags,\n} from './flags';\nimport { anchoredGeom, anchorModeOf, unanchoredGeom, type ViewEnv } from './anchor';\nimport {\n apSizeChanged,\n caretGeomFromAnchor,\n DEFAULT_CHROME_GEOM,\n geomDragHandle,\n geomResetRotation,\n geomRotateAbout,\n geomRotation,\n geomScaleAbout,\n geomTranslate,\n groupResizeAnchor,\n groupResizeBox,\n groupResizeFactors,\n normalizeDeg,\n quadIntersectsRect,\n rectFromPoints,\n selectionCenter,\n selectionQuad,\n shapeRectFor,\n transposedAboutCenter,\n unionRect,\n uprightAnchoredRect,\n uprightRotation,\n} from './geometry';\nimport { clickCreateGeom, resolveClickPlacement } from './placement';\nimport {\n applyProps,\n initialTextStyle,\n kindTakesLink,\n styleFromProps,\n textStyleFromProps,\n} from './props';\nimport { normalizeRuns, paragraphsFromPlainText, plainTextOf } from './richtext';\nimport { computeMoveSnap } from './snap';\nimport { straightenInkStroke } from './ink';\nimport type {\n Annot,\n AnnotationProps,\n AnnotationPropsPatch,\n ClickCreate,\n Draft,\n Effect,\n Geom,\n Id,\n InkStraightenOptions,\n LineEndings,\n Model,\n Msg,\n PointerInput,\n PropKey,\n Quad,\n Rect,\n Style,\n Subtype,\n TextEndAnchor,\n TextQuad,\n Vec,\n} from './types';\n\n/** The click ↔ drag threshold (content units): a press-release whose width AND\n * height both stay under it is a CLICK. Exported so every gesture owner (the\n * draw handler, the form plugin's place handler) shares ONE definition. */\nexport const MIN_DRAG = 3;\nconst isPolySubtype = (subtype: Subtype): subtype is 'polygon' | 'polyline' =>\n subtype === 'polygon' || subtype === 'polyline';\n\nexport const initialStyle: Style = {\n color: '#e5484d',\n interiorColor: null,\n strokeWidth: 2,\n opacity: 1,\n blendMode: 'normal',\n border: { kind: 'solid' },\n};\n\nconst NO_ENDINGS: LineEndings = { start: 'none', end: 'none' };\n\nexport const initialModel: Model = {\n byId: {},\n order: [],\n selected: [],\n hovered: null,\n draft: null,\n preview: null,\n seq: 0,\n style: initialStyle,\n defaults: {},\n hitMargin: 6,\n editing: null,\n snap: {\n guides: true,\n guideThreshold: 5,\n rotation: true,\n rotationAngles: [0, 90, 180, 270],\n rotationThreshold: 4,\n },\n};\n\n/**\n * Resolve a tool's effective defaults as a FULL flat props bag: the base `style`\n * + the font/endings base, with the per-tool override layered on top. This is\n * what a defaults-editing UI reads, and what creation projects `style`/`text`\n * from (`styleFromProps` / `textStyleFromProps`).\n */\nexport function defaultsFor(m: Model, subtype: Subtype): AnnotationProps {\n const d = m.defaults[subtype];\n return {\n ...m.style,\n ...initialTextStyle,\n ...d,\n lineEndings: { ...NO_ENDINGS, ...d?.lineEndings },\n };\n}\n\n/** Flip an annotation to live (vector) rendering — we now own its appearance, so\n * the engine's baked AP is no longer authoritative. Idempotent. */\nconst toVector = (a: Annot): Annot => (a.source === 'vector' ? a : { ...a, source: 'vector' });\n/**\n * Take ownership of the appearance after a GEOMETRY edit. Vector kinds flip to\n * live rendering; `opaqueBody` kinds (stamp images) have NO vector render — they\n * stay `baked`, with the raster box following the committed geometry (the bitmap\n * shows stretched until the engine's natively re-fit appearance arrives with the\n * DTO sync). Call with the NEW geometry already applied.\n */\nconst ownGeometry = (a: Annot): Annot => {\n if (!capsFor(a.subtype).opaqueBody) return toVector(a);\n return 'rect' in a.geom ? { ...a, apBox: a.geom.rect } : a;\n};\n/**\n * Does this committed edit invalidate an engine-baked raster? Only when the\n * annotation STAYS baked (an opaque-body kind — everything else just flipped to\n * vector via {@link ownGeometry} and renders live from its geometry) AND the\n * edit changed the /AP frame's SIZE, does the engine's re-bake produce new\n * raster content. In practice: a stamp resize. Moves and rotations keep the\n * frame (the blit translates/rotates the same pixels), so they emit false and\n * a committed drag costs zero appearance re-renders. Call with the NEXT\n * (post-{@link ownGeometry}) annot and the geometry it had BEFORE the edit.\n */\nconst apInvalidated = (next: Annot, before: Geom): boolean =>\n next.source === 'baked' && apSizeChanged(before, next.geom);\n/** The patch effect for a committed geometry edit. `apChanged` is attached ONLY\n * when the edit invalidated a baked raster (a stamp resize) — so every other\n * edit keeps the bare `{ fx, id }` shape and never triggers an appearance\n * re-fetch. `next` is the post-{@link ownGeometry} annot, `before` its old geom. */\nconst patchFx = (id: Id, next: Annot, before: Geom): Effect =>\n apInvalidated(next, before)\n ? { fx: 'patch', id, scope: { kind: 'geometry' }, apChanged: true }\n : { fx: 'patch', id, scope: { kind: 'geometry' } };\nconst sub = (a: Vec, b: Vec): Vec => ({ x: a.x - b.x, y: a.y - b.y });\nconst translateRect = (r: Rect, d: Vec): Rect => ({ ...r, x: r.x + d.x, y: r.y + d.y });\n\n/**\n * Commit a VIEW-space gesture result for one annotation: apply `op` to the\n * PROJECTED geometry (the identity for un-flagged annotations — `op` then\n * simply runs on the stored geom) and map the result back to stored space\n * through `unanchoredGeom`. The exact composition `effGeom` previewed, so a\n * released gesture commits what it showed — for screen-anchored and plain\n * annotations alike, through ONE code path.\n */\nconst commitViewGesture = (a: Annot, view: ViewEnv | undefined, op: (g: Geom) => Geom): Geom => {\n const mode = anchorModeOf(a);\n return unanchoredGeom(op(anchoredGeom(a.geom, mode, view)), mode, view);\n};\n\n/* ── page-bound gestures ──────────────────────────────────────────────────────\n * Annotations are page-bound; the pointer isn't. Two rules keep them apart:\n * 1. FRAME: a gesture is anchored to the page it started on. A sample resolved\n * against another page is in a different coordinate frame (each page's\n * content space has its own origin) — subtracting across frames produced\n * the teleport-to-page-top bug, so foreign-page samples are ignored.\n * 2. CLAMP: within the home frame, geometry pins to the page box (v2 rule):\n * an overshooting pointer slides the shape along the edge; a shape larger\n * than the page pins to the page's top/left (lo wins when lo > hi).\n */\nconst clampAxis = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\nconst clampPointToBox = (p: Vec, box: Rect | undefined): Vec =>\n box\n ? {\n x: clampAxis(p.x, box.x, box.x + box.width),\n y: clampAxis(p.y, box.y, box.y + box.height),\n }\n : p;\n\n/** The pointer sample's view environment (relative zoom + display rotation),\n * when the caller supplied one — screen-anchored annotations hit-test and\n * page-clamp at their EFFECTIVE geometry with it. Absent → stored geometry\n * (headless). */\nconst viewOf = (input: PointerInput): ViewEnv | undefined =>\n input.zoom != null || input.displayRotation != null\n ? { zoom: input.zoom ?? 1, rotation: input.displayRotation ?? 0 }\n : undefined;\n\n/** The union of the ids' SELECTION bounds (the outline the user sees) — the box\n * the page-clamp keeps inside the page during a move. Screen-anchored members\n * count at their effective (view-projected) footprint. */\nfunction unionBoundsOf(m: Model, ids: Id[], view?: ViewEnv): Rect | null {\n const corners: Vec[] = [];\n for (const id of ids) {\n const a = m.byId[id];\n if (!a) continue;\n const g = anchoredGeom(a.geom, anchorModeOf(a), view);\n corners.push(...selectionQuad(g, a.style.strokeWidth, a.style.border));\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/** Clamp a move delta so the selection's union bounds stay inside the page.\n * Per-axis, so a pointer past the bottom edge still slides the selection\n * horizontally along that edge. */\nfunction clampMoveDelta(\n m: Model,\n ids: Id[],\n delta: Vec,\n page: Rect | undefined,\n view?: ViewEnv,\n): Vec {\n if (!page) return delta;\n const b = unionBoundsOf(m, ids, view);\n if (!b) return delta;\n return {\n x: clampAxis(delta.x, page.x - b.x, page.x + page.width - (b.x + b.width)),\n y: clampAxis(delta.y, page.y - b.y, page.y + page.height - (b.y + b.height)),\n };\n}\n\n/** The page an edit draft is anchored to — every edit gesture lives on ONE page. */\nfunction editDraftPon(m: Model, d: Draft): number | null {\n const id = d.g === 'handle' ? d.id : 'ids' in d && d.ids.length ? d.ids[0] : null;\n return id != null ? (m.byId[id]?.pon ?? null) : null;\n}\nconst geomEqual = (a: Geom, b: Geom): boolean => JSON.stringify(a) === JSON.stringify(b);\nconst RAD2DEG = 180 / Math.PI;\n\n/** The signed CW angle (deg) of `p` relative to `pivot`, in content space (y-down). */\nconst angleAt = (pivot: Vec, p: Vec): number => Math.atan2(p.y - pivot.y, p.x - pivot.x) * RAD2DEG;\n\n/** Shortest signed arc from `a` to `b` (deg), in (-180, 180]. */\nconst arcTo = (a: number, b: number): number => ((b - a + 540) % 360) - 180;\n\n/**\n * The live rotation of a rotate draft, snapping applied — the ONE angle rule\n * shared by the preview (`effGeom`), the commit (`editUp`) and the angle chip,\n * so they can never disagree. The selection's ABSOLUTE angle (a single member's\n * `rot` + the raw pointer delta; a group's raw delta from 0) locks onto the\n * configured angles within the threshold; `free` (shift held) bypasses.\n * `delta` is what `geomRotateAbout` applies; `angle` is what the chip shows.\n */\nexport function rotateDraftDelta(\n m: Model,\n d: Extract<Draft, { g: 'rotate' }>,\n): { delta: number; angle: number; snapped: boolean } {\n const raw = angleAt(d.pivot, d.cur) - angleAt(d.pivot, d.start);\n const one = d.ids.length === 1 ? m.byId[d.ids[0]] : null;\n // The absolute angle is read off the PROJECTED geometry (identity when\n // un-flagged): the chip and the snap targets speak about what the user SEES\n // — a noRotate shape's on-screen tilt, not its stored one.\n const base = one ? geomRotation(anchoredGeom(one.geom, anchorModeOf(one), d.view)) : 0;\n const angle = normalizeDeg(base + raw);\n if (!m.snap.rotation || d.free) return { delta: raw, angle, snapped: false };\n for (const target of m.snap.rotationAngles) {\n const adjust = arcTo(angle, normalizeDeg(target));\n if (Math.abs(adjust) <= m.snap.rotationThreshold)\n return { delta: raw + adjust, angle: normalizeDeg(target), snapped: true };\n }\n return { delta: raw, angle, snapped: false };\n}\n\n/** A group resize is isotropic (uniform) when ANY selected member is rotated —\n * an off-axis scale across a rotated rect+rot is a shear it can't represent. A\n * vertex member's advisory `rot` counts (preserves obbFromTheta + reset). */\nconst selectionHasRotation = (m: Model, ids: Id[]): boolean =>\n ids.some((id) => geomRotation(m.byId[id]?.geom ?? ({ t: 'caret' } as Geom)) !== 0);\n\nexport function update(m: Model, msg: Msg): [Model, Effect[]] {\n switch (msg.t) {\n case 'editPointer':\n return editPointer(m, msg.phase, msg.in);\n case 'marqueePointer':\n return marqueePointer(m, msg.phase, msg.in);\n case 'createPointer':\n return createPointer(\n m,\n msg.phase,\n msg.subtype,\n msg.in,\n msg.preset,\n msg.intent,\n msg.deferInkCommit,\n msg.straightenInk,\n msg.clickCreate,\n msg.flags,\n );\n case 'finishInkDraft':\n return finishInkCreate(m);\n case 'finishCreationDraft':\n return finishPolyCreate(m);\n case 'createCaret':\n return createCaret(m, msg.pon, msg.anchor, msg.flags);\n case 'createReplaceText':\n return createReplaceText(m, msg.pon, msg.quads, msg.anchor, msg.preset);\n case 'createMarkup':\n return createMarkup(m, msg.subtype, msg.pon, msg.quads, msg.preset, msg.flags);\n case 'setMarkupPreview':\n return setMarkupPreview(m, msg.subtype, msg.quadsByPage, msg.preset);\n case 'clearMarkupPreview':\n return m.preview ? [{ ...m, preview: null }, []] : [m, []];\n case 'select': {\n const ids = expandGroups(\n m,\n msg.ids.filter((id) => isSelectable(m, id)),\n );\n if (!ids.length) return [m, []];\n const selected = msg.add ? [...new Set([...m.selected, ...ids])] : ids;\n return [{ ...m, selected }, []];\n }\n case 'deselect': {\n if (!m.selected.length) return [m, []];\n // With `ids`: drop only those (an engaged Behavior retroactively un-selects\n // its annotations — engaged ⇒ not selectable ⇒ not selected). Without: all.\n if (!msg.ids) return [{ ...m, selected: [] }, []];\n const drop = new Set(msg.ids);\n const selected = m.selected.filter((id) => !drop.has(id));\n return selected.length === m.selected.length ? [m, []] : [{ ...m, selected }, []];\n }\n case 'setProps':\n return setProps(m, msg.patch);\n case 'setFlags':\n return setFlags(m, msg.patch, msg.ids);\n case 'setDefaults':\n return setDefaults(m, msg.subtype, msg.patch);\n case 'setSnap':\n return [{ ...m, snap: { ...m.snap, ...msg.patch } }, []];\n case 'rotate90':\n return rotateSelection(m, 90);\n case 'resetRotation':\n return resetRotation(m);\n case 'delete':\n return deleteSelection(m);\n case 'cancel':\n return [{ ...m, draft: null }, []];\n case 'loaded':\n return [mergeLoaded(m, msg.annots), []];\n case 'hydrated':\n return [hydrateAnnots(m, msg.annots, msg.bumpAp ?? false), []];\n case 'created':\n return [reconcile(m, msg.tempId, msg.id, msg.ref), []];\n case 'createFailed':\n return [removeAnnots(m, [msg.tempId]), []];\n case 'upsert':\n return [upsertAnnots(m, msg.annots, msg.bumpAp), []];\n case 'bumpAp':\n return [bumpAp(m, msg.ids), []];\n case 'hover':\n // Pure view-model state; the capability diffs before dispatching, so\n // this fires at enter/leave cadence only.\n return m.hovered === msg.id ? [m, []] : [{ ...m, hovered: msg.id }, []];\n case 'remove': {\n const next = removeAnnots(m, msg.ids);\n // A removed annotation can't stay hovered.\n return [next.hovered && !next.byId[next.hovered] ? { ...next, hovered: null } : next, []];\n }\n case 'beginTextEdit':\n // `lockedContents` (or an inert `/F` state) blocks entering text edit —\n // the geometry gates don't apply here: locked-only contents still edit.\n return m.byId[msg.id] && annotContentsEditable(m.byId[msg.id]!)\n ? [{ ...m, editing: msg.id, selected: [msg.id], draft: null }, []]\n : [m, []];\n case 'setText':\n return setText(m, msg.id, msg.text);\n case 'setRichText':\n return setRichText(m, msg.id, msg.doc);\n case 'endTextEdit':\n return m.editing ? [{ ...m, editing: null }, []] : [m, []];\n }\n}\n\n/** Apply the editor's plain text optimistically. Updates `contents` on the\n * DTO-backed model and flips the box to `vector` so the live text shows. Emits\n * NO effect — the plugin owns the (debounced) engine write while you type, so\n * the model never churns mid-keystroke. */\nfunction setText(m: Model, id: Id, text: string): [Model, Effect[]] {\n const a = m.byId[id];\n if (!a) return [m, []];\n // The rich projection follows plain text: body-style paragraphs, one per\n // line break, so an editor rendering `richText` shows what was typed.\n const data =\n a.data && a.data.subtype === 'free-text'\n ? {\n ...a.data,\n contents: text,\n richText: { ...a.data.richText, paragraphs: paragraphsFromPlainText(text) },\n }\n : a.data\n ? { ...a.data, contents: text }\n : a.data;\n const next = toVector({ ...a, data });\n return [{ ...m, byId: { ...m.byId, [id]: next } }, []];\n}\n\n/** Apply the editor's rich document optimistically. The DTO's body is kept\n * (a partial input body layers on it); `contents` is the projection. */\nfunction setRichText(m: Model, id: Id, doc: RichTextDocumentInput): [Model, Effect[]] {\n const a = m.byId[id];\n if (!a || !a.data || a.data.subtype !== 'free-text') return [m, []];\n const normalized = normalizeRuns(doc);\n const richText = {\n body: { ...a.data.richText.body, ...(normalized.body ?? {}) },\n paragraphs: normalized.paragraphs,\n };\n const next = toVector({\n ...a,\n data: { ...a.data, richText, contents: plainTextOf(richText) },\n });\n return [{ ...m, byId: { ...m.byId, [id]: next } }, []];\n}\n\nfunction editPointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n): [Model, Effect[]] {\n if (phase === 'down') return editDown(m, input);\n if (phase === 'move') return m.draft ? editMove(m, input) : [m, []];\n return m.draft ? editUp(m) : [m, []];\n}\n\nfunction editDown(m: Model, input: PointerInput): [Model, Effect[]] {\n // `pageBox` + `chrome` reach the hit-test so the page-bound rotate knob\n // (flipped / clamped near an edge) is grabbed exactly where the chrome drew\n // it, with the caller's (screen-constant) grab zones. The view env rides\n // along so screen-anchored annotations are grabbed where they're PAINTED.\n const hit = hitTest(\n m,\n input.pon,\n input.point,\n input.chrome ?? DEFAULT_CHROME_GEOM,\n m.hitMargin,\n input.pageBox,\n input.inert,\n viewOf(input),\n );\n if (hit.t === 'handle') {\n // The handle gesture runs in VIEW space: `base` is the PROJECTED geometry\n // the user grabbed (identity for un-flagged annotations), and the commit\n // maps the result back via `unanchoredGeom` with the SAME captured view.\n const a = m.byId[hit.id];\n const view = viewOf(input);\n const base = anchoredGeom(a.geom, anchorModeOf(a), view);\n return [\n {\n ...m,\n draft: {\n g: 'handle',\n id: hit.id,\n handle: hit.handle,\n base,\n cur: base,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.t === 'rotate') {\n const view = viewOf(input);\n return [\n {\n ...m,\n draft: {\n g: 'rotate',\n ids: hit.ids,\n pivot: hit.pivot,\n start: input.point,\n cur: input.point,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.t === 'group-handle') {\n const view = viewOf(input);\n return [\n {\n ...m,\n draft: {\n g: 'group',\n op: 'resize',\n ids: hit.ids,\n handle: hit.handle,\n anchor: groupResizeAnchor(hit.box, hit.handle),\n base: hit.box,\n cur: hit.box,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.t === 'annot') {\n // A hit on any member acts on the WHOLE group — select/toggle/drag as a unit.\n const grp = groupMembers(m, hit.id);\n const inSel = m.selected.includes(hit.id);\n const selected = input.shift\n ? inSel\n ? m.selected.filter((x) => !grp.includes(x)) // shift+click a member → drop the group\n : [...m.selected, ...grp.filter((x) => !m.selected.includes(x))]\n : inSel\n ? m.selected\n : grp;\n // Only arm a move gesture if every selected annotation can move; an anchored\n // kind (markup/caret) still selects, it just won't drag.\n const movable = selected.length > 0 && selected.every((id) => canMove(m, id));\n const draft: Draft | null = movable\n ? { g: 'move', ids: selected, start: input.point, delta: { x: 0, y: 0 }, guides: [] }\n : null;\n return [{ ...m, selected, draft }, []];\n }\n return [{ ...m, selected: [] }, []]; // empty (the handler usually pre-empts via 'deselect')\n}\n\nfunction editMove(m: Model, input: PointerInput): [Model, Effect[]] {\n const d = m.draft!;\n // Foreign coordinate frame (see the page-bound gesture rules above) — ignore.\n const home = editDraftPon(m, d);\n if (home != null && input.pon !== home) return [m, []];\n if (d.g === 'move') {\n const view = viewOf(input);\n const raw = clampMoveDelta(m, d.ids, sub(input.point, d.start), input.pageBox, view);\n if (!m.snap.guides || input.shift)\n return [{ ...m, draft: { ...d, delta: raw, guides: [] } }, []];\n // Snap guides read STORED geometry (an anchored mover aligns by its /Rect\n // box) — a deliberate simplification; the clamp above is view-exact.\n const snap = computeMoveSnap(m, d.ids, input.pon, raw, m.snap.guideThreshold, input.pageBox);\n // A snap adjusts by ≤ threshold, but never past the page edge: re-clamp, and\n // drop the guide on an axis the clamp took back (its line would be a lie).\n const delta = clampMoveDelta(m, d.ids, snap.delta, input.pageBox, view);\n const guides = snap.guides.filter((g) =>\n g.axis === 'x' ? delta.x === snap.delta.x : delta.y === snap.delta.y,\n );\n return [{ ...m, draft: { ...d, delta, guides } }, []];\n }\n const point = clampPointToBox(input.point, input.pageBox);\n if (d.g === 'handle')\n return [{ ...m, draft: { ...d, cur: geomDragHandle(d.base, d.handle, point) } }, []];\n // Rotation reads the pointer as an ANGLE about the pivot — the raw point is\n // valid (and better) outside the page; the geometry itself never translates.\n // `free` (shift) records the snap bypass for this sample.\n if (d.g === 'rotate') return [{ ...m, draft: { ...d, cur: input.point, free: input.shift } }, []];\n if (d.g === 'group') {\n const iso = selectionHasRotation(m, d.ids);\n return [{ ...m, draft: { ...d, cur: groupResizeBox(d.base, d.handle, point, iso) } }, []];\n }\n return [m, []];\n}\n\nfunction editUp(m: Model): [Model, Effect[]] {\n const d = m.draft!;\n if (d.g === 'handle') {\n // A grab that didn't actually resize leaves the appearance untouched → keep\n // it baked, no engine write.\n if (geomEqual(d.base, d.cur)) return [{ ...m, draft: null }, []];\n // A resize changes the appearance: we own it now → live (vector) render\n // (opaque-body kinds stay baked; the engine re-fits their AP natively).\n // `cur` is VIEW-space (the projected geometry the user dragged); the\n // commit maps it back to stored space — the identity when un-flagged.\n const before = m.byId[d.id];\n const stored = unanchoredGeom(d.cur, anchorModeOf(before), d.view);\n const a = ownGeometry({ ...before, geom: stored });\n return [{ ...m, byId: { ...m.byId, [d.id]: a }, draft: null }, [patchFx(d.id, a, before.geom)]];\n }\n if (d.g === 'rotate') {\n const { delta } = rotateDraftDelta(m, d);\n if (Math.abs(delta) < 0.01) return [{ ...m, draft: null }, []];\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of d.ids) {\n const a = byId[id];\n if (!a) continue;\n // rotation re-bakes the appearance → live (vector) render + patch. The\n // gesture composed in VIEW space (`effGeom`); the commit replays the\n // same composition and unprojects — a screen-anchored member's AUTHORED\n // tilt turns WYSIWYG, exactly as previewed.\n const geom = commitViewGesture(a, d.view, (g) => geomRotateAbout(g, d.pivot, delta));\n byId[id] = ownGeometry({ ...a, geom });\n fx.push(patchFx(id, byId[id], a.geom));\n }\n return [{ ...m, byId, draft: null }, fx];\n }\n if (d.g === 'group') {\n const { sx, sy } = groupResizeFactors(d.base, d.cur);\n if (Math.abs(sx - 1) < 1e-4 && Math.abs(sy - 1) < 1e-4) return [{ ...m, draft: null }, []];\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of d.ids) {\n const a = byId[id];\n if (!a) continue;\n const geom = commitViewGesture(a, d.view, (g) => geomScaleAbout(g, d.anchor, sx, sy));\n byId[id] = ownGeometry({ ...a, geom });\n fx.push(patchFx(id, byId[id], a.geom));\n }\n return [{ ...m, byId, draft: null }, fx];\n }\n if (d.g === 'move') {\n if (Math.hypot(d.delta.x, d.delta.y) < 0.01) return [{ ...m, draft: null }, []]; // a click\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of d.ids) {\n const a = byId[id];\n // A move is a rigid translation — the appearance is unchanged, so a baked\n // annotation STAYS baked and its raster box rides along. Source preserved.\n byId[id] = {\n ...a,\n geom: geomTranslate(a.geom, d.delta),\n apBox: a.apBox ? translateRect(a.apBox, d.delta) : undefined,\n };\n fx.push({ fx: 'patch', id, scope: { kind: 'geometry' } }); // a move never invalidates the raster\n }\n return [{ ...m, byId, draft: null }, fx];\n }\n return [{ ...m, draft: null }, []];\n}\n\nfunction marqueePointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n): [Model, Effect[]] {\n // The marquee lives on one page and pins to its box (same rules as editMove).\n const point = clampPointToBox(input.point, input.pageBox);\n if (phase === 'down') {\n return [{ ...m, draft: { g: 'marquee', pon: input.pon, from: point, to: point } }, []];\n }\n if (m.draft?.g !== 'marquee') return [m, []];\n if (m.draft.pon !== input.pon) return [m, []]; // foreign frame — ignore\n if (phase === 'move') {\n return [{ ...m, draft: { ...m.draft, to: point } }, []];\n }\n\n // A marquee that touches one member takes the whole group with it.\n const hits = expandGroups(\n m,\n annotsInBox(m, m.draft.pon, m.draft.from, point, input.inert, viewOf(input)),\n );\n const selected = input.shift ? toggleSelection(m.selected, hits) : hits;\n return [{ ...m, selected, draft: null }, []];\n}\n\nfunction toggleSelection(base: Id[], ids: Id[]): Id[] {\n const next = new Set(base);\n for (const id of ids) {\n if (next.has(id)) next.delete(id);\n else next.add(id);\n }\n return [...next];\n}\n\nfunction createPointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n subtype: Subtype,\n input: PointerInput,\n preset: string = subtype,\n intent?: InkIntent,\n deferInkCommit = false,\n straightenInk?: InkStraightenOptions,\n clickCreate?: ClickCreate | false,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n // An in-progress creation is anchored to its page: a move/up sample from\n // another page is a foreign frame — ignore it. (A DOWN on another page is a\n // fresh intent: the per-subtype branches below start/restart the draft there.)\n if (phase !== 'down' && m.draft && 'pon' in m.draft && m.draft.pon !== input.pon) return [m, []];\n // Shapes can't be drawn past the page edge — the pointer pins to it.\n if (input.pageBox) input = { ...input, point: clampPointToBox(input.point, input.pageBox) };\n if (subtype === 'free-text-callout') return calloutPointer(m, phase, input, preset, flags);\n if (phase === 'down') {\n if (isPolySubtype(subtype)) {\n if (input.finish) return finishPolyCreate(m);\n if (\n m.draft?.g === 'create-poly' &&\n m.draft.subtype === subtype &&\n m.draft.pon === input.pon\n ) {\n return [\n {\n ...m,\n draft: { ...m.draft, points: [...m.draft.points, input.point], cur: input.point },\n },\n [],\n ];\n }\n return [\n {\n ...m,\n selected: [],\n draft: {\n g: 'create-poly',\n subtype,\n preset,\n pon: input.pon,\n points: [input.point],\n cur: input.point,\n closed: subtype === 'polygon',\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n const draft: Draft | null =\n subtype === 'line'\n ? {\n g: 'create-line',\n subtype,\n preset,\n pon: input.pon,\n from: input.point,\n to: input.point,\n ...(clickCreate !== undefined ? { clickCreate } : {}),\n ...(flags ? { flags } : {}),\n }\n : subtype === 'ink'\n ? m.draft?.g === 'create-ink' &&\n m.draft.subtype === subtype &&\n m.draft.preset === preset &&\n m.draft.pon === input.pon\n ? { ...m.draft, strokes: [...m.draft.strokes, [input.point]] }\n : {\n g: 'create-ink',\n subtype,\n preset,\n pon: input.pon,\n strokes: [[input.point]],\n intent,\n ...(flags ? { flags } : {}),\n }\n : subtype === 'square' ||\n subtype === 'circle' ||\n subtype === 'free-text' ||\n subtype === 'redact' ||\n subtype === 'link'\n ? {\n g: 'create-rect',\n subtype,\n preset,\n pon: input.pon,\n from: input.point,\n to: input.point,\n ellipse: subtype === 'circle',\n // Captured at DOWN (the gesture's home page); a rotation of 0\n // makes upright a no-op, so the draft stays clean then.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(clickCreate !== undefined ? { clickCreate } : {}),\n ...(flags ? { flags } : {}),\n }\n : null;\n return draft ? [{ ...m, selected: [], draft }, []] : [m, []];\n }\n if (phase === 'move') {\n if (m.draft?.g === 'create-poly') {\n return [{ ...m, draft: { ...m.draft, cur: input.point } }, []];\n }\n if (m.draft?.g === 'create-rect' || m.draft?.g === 'create-line') {\n return [{ ...m, draft: { ...m.draft, to: input.point } }, []];\n }\n if (m.draft?.g === 'create-ink') {\n // append to the active (last) stroke as the pen moves\n const strokes = m.draft.strokes.slice();\n strokes[strokes.length - 1] = [...strokes[strokes.length - 1], input.point];\n return [{ ...m, draft: { ...m.draft, strokes } }, []];\n }\n return [m, []];\n }\n // up\n const d = m.draft;\n if (d?.g !== 'create-rect' && d?.g !== 'create-line' && d?.g !== 'create-ink') return [m, []];\n\n if (d.g === 'create-ink') {\n let next = m;\n if (straightenInk && d.strokes.length) {\n const strokes = d.strokes.slice();\n const last = strokes.length - 1;\n strokes[last] = straightenInkStroke(strokes[last], straightenInk);\n next = { ...m, draft: { ...d, strokes } };\n }\n return deferInkCommit ? [next, []] : finishInkCreate(next);\n }\n\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const style = styleFromProps(def);\n let geom: Geom | null = null;\n // The upright counter-rotation for a BOX commit (0 when the tool/page don't\n // ask for one). A DRAGGED box keeps the on-screen footprint the author drew:\n // for a quarter-turn the unrotated box is the drag rect TRANSPOSED about its\n // centre, so spinning it by `rot` lands exactly back on the dragged region.\n const upRot =\n d.g === 'create-rect' && d.upright && d.displayRotation\n ? uprightRotation(d.displayRotation)\n : 0;\n const uprightBox = (dragged: Rect): Rect =>\n upRot === 90 || upRot === 270 ? transposedAboutCenter(dragged) : dragged;\n // Click commits resolve through the SHARED placement layer (placement.ts) —\n // the same `resolveClickPlacement` the footprint ghost and the form plugin\n // consume, so preview ≡ commit by construction. The core only supplies the\n // kind-level fallback for free text (a click must always yield a typable\n // box) and converts the placement to a Geom via `clickCreateGeom`.\n const clickGeom = (policy: ClickCreate): Geom | null =>\n clickCreateGeom(\n d.subtype,\n resolveClickPlacement(d.from, policy, {\n pageBox: input.pageBox,\n upright: d.g === 'create-rect' ? d.upright : undefined,\n displayRotation: d.g === 'create-rect' ? d.displayRotation : undefined,\n }),\n def,\n );\n if (d.g === 'create-rect' && d.subtype === 'free-text') {\n // Free-text: a dragged box, or — on a mere click — a default box you can\n // immediately type into (created unless the tool says `clickCreate: false`;\n // an empty text box is unreachable by drag alone, hence the kind-level\n // fallback: 180×40, top-left anchored so the box hangs where you'll type).\n const dragged = rectFromPoints(d.from, d.to);\n const isClick = dragged.width < MIN_DRAG && dragged.height < MIN_DRAG;\n if (!isClick) {\n geom = { t: 'text', rect: uprightBox(dragged), ...(upRot ? { rot: upRot } : {}) };\n } else if (d.clickCreate !== false) {\n geom = clickGeom(\n d.clickCreate && 'width' in d.clickCreate\n ? d.clickCreate\n : { width: 180, height: 40, anchor: 'top-left' },\n );\n }\n } else if (d.g === 'create-rect') {\n const dragged = rectFromPoints(d.from, d.to);\n if (dragged.width >= MIN_DRAG || dragged.height >= MIN_DRAG) {\n // cloudy stores the OUTER box (dragged + extent) so the dragged box is its inner edge\n geom = {\n t: 'rect',\n rect: shapeRectFor(uprightBox(dragged), d.ellipse, style),\n ellipse: d.ellipse,\n ...(upRot ? { rot: upRot } : {}),\n };\n } else if (d.clickCreate && 'width' in d.clickCreate) {\n geom = clickGeom(d.clickCreate);\n }\n } else if (d.g === 'create-line') {\n if (Math.hypot(d.to.x - d.from.x, d.to.y - d.from.y) >= MIN_DRAG) {\n geom = { t: 'line', a: d.from, b: d.to, ends: def.lineEndings };\n } else if (d.clickCreate && 'length' in d.clickCreate) {\n geom = clickGeom(d.clickCreate);\n }\n }\n if (!geom) return [{ ...m, draft: null }, []];\n\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: d.subtype,\n geom,\n style,\n // A text kind carries its text styling from birth, so the tool's font\n // defaults actually apply to what you draw.\n ...(geom.t === 'text' ? { text: textStyleFromProps(def) } : {}),\n // A drawn link starts at the tool preset's target ('docs-link' style\n // presets), or dead (`null` — the create-then-edit flow).\n ...(d.subtype === 'link' ? { link: def.link ?? null } : {}),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n // A freshly drawn free-text box opens straight into edit (type immediately).\n editing: geom.t === 'text' ? id : m.editing,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Commit all strokes accumulated by a grouped ink gesture. */\nfunction finishInkCreate(m: Model): [Model, Effect[]] {\n const d = m.draft;\n if (d?.g !== 'create-ink') return [m, []];\n const points = d.strokes.flat();\n if (!d.strokes.some((stroke) => stroke.length >= 2) || points.length === 0)\n return [{ ...m, draft: null }, []];\n const bounds = unionRect(points);\n if (Math.max(bounds.width, bounds.height) < MIN_DRAG) return [{ ...m, draft: null }, []];\n\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: d.subtype,\n geom: { t: 'ink', strokes: d.strokes },\n style: styleFromProps(defaultsFor(m, d.preset ?? d.subtype)),\n ...(d.intent ? { intent: d.intent } : {}),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Default text-box size for a callout placed with a click (no box drag). */\nconst CALLOUT_BOX = { width: 150, height: 40 };\n\n/** The callout draft's upright counter-rotation (deg CW; 0 = none) — the SAME\n * rule the rect commit applies, shared by `calloutBox`, the ghost preview and\n * the commit so all three agree by construction. */\nexport function calloutUprightRot(d: Extract<Draft, { g: 'create-callout' }>): number {\n return d.upright && d.displayRotation ? uprightRotation(d.displayRotation) : 0;\n}\n\n/**\n * The text-box rect for an in-progress callout's `box` step — the ONE rule both\n * the live preview and the commit use, so what you see is what you get. Only a\n * drag past `MIN_DRAG` sizes the box; a press-without-drag (a click) keeps the\n * default-size box anchored at the press point, so it never collapses to a sliver\n * while you decide whether you're dragging (the \"bounce\"). Before the press\n * (hover), the default box tracks the cursor.\n *\n * Under `upright` this returns the UNROTATED logical box (the frame text is laid\n * out in): a DRAGGED box keeps the on-screen footprint the author drew (quarter\n * turns transpose it about its centre — spinning by `rot` lands exactly back on\n * the dragged region), and the default box anchors so its DISPLAYED top-left\n * hangs at the point, down-right of the cursor as the author sees it — the same\n * two rules the free-text drag/click commits use.\n */\nexport function calloutBox(d: Extract<Draft, { g: 'create-callout' }>): Rect {\n const rot = calloutUprightRot(d);\n const quarter = rot === 90 || rot === 270;\n const defaultBox = (at: Vec): Rect =>\n rot\n ? uprightAnchoredRect(at, CALLOUT_BOX.width, CALLOUT_BOX.height, d.displayRotation!)\n : { x: at.x, y: at.y, ...CALLOUT_BOX };\n if (d.boxFrom) {\n const dragged = d.boxTo ? rectFromPoints(d.boxFrom, d.boxTo) : null;\n if (dragged && (dragged.width >= MIN_DRAG || dragged.height >= MIN_DRAG))\n return quarter ? transposedAboutCenter(dragged) : dragged;\n return defaultBox(d.boxFrom);\n }\n return defaultBox(d.cur);\n}\n\n/**\n * The free-text callout's multi-step creation, a v2-style 3-click flow:\n * click 1 (down) → set the leader `tip`, advance to the `knee` step\n * hover/move → preview the leader to the cursor\n * click 2 (down) → set the `knee`, advance to the `box` step\n * drag/click (up) → lay the text box (dragged, or a default box on a click)\n * Commit creates a `free-text` annotation with a `callout` geom and opens it for\n * editing — the connection point to the box is always derived, never stored.\n */\nfunction calloutPointer(\n m: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n preset: string = 'free-text-callout',\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const d = m.draft;\n if (phase === 'down') {\n if (d?.g !== 'create-callout' || d.pon !== input.pon) {\n return [\n {\n ...m,\n selected: [],\n draft: {\n g: 'create-callout',\n subtype: 'free-text-callout',\n preset,\n pon: input.pon,\n step: 'knee',\n tip: input.point,\n cur: input.point,\n // Captured at the TIP click (the gesture's home page) — the box\n // step may span later samples that don't carry the rotation. A\n // rotation of 0 makes upright a no-op, so the draft stays clean.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n if (d.step === 'knee') {\n return [{ ...m, draft: { ...d, knee: input.point, step: 'box', cur: input.point } }, []];\n }\n // box step: begin the box drag at this point\n return [{ ...m, draft: { ...d, boxFrom: input.point, boxTo: input.point } }, []];\n }\n if (phase === 'move') {\n if (d?.g !== 'create-callout') return [m, []];\n if (d.step === 'box' && d.boxFrom) return [{ ...m, draft: { ...d, boxTo: input.point } }, []];\n return [{ ...m, draft: { ...d, cur: input.point } }, []];\n }\n // up: only the box step (with a started box) commits; the tip/knee clicks no-op.\n if (d?.g !== 'create-callout' || d.step !== 'box' || !d.boxFrom) return [m, []];\n const rect = calloutBox(d); // the SAME box the preview showed\n // The upright counter-rotation applies to the text BOX only (about its own\n // centre) — the leader tip/knee are page-space anchors and never turn.\n const rot = calloutUprightRot(d);\n const def = defaultsFor(m, d.preset ?? 'free-text-callout');\n const ending = def.lineEndings.end !== 'none' ? def.lineEndings.end : 'open-arrow';\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: 'free-text',\n geom: {\n t: 'text',\n rect,\n callout: { tip: d.tip, knee: d.knee, ending },\n ...(rot ? { rot } : {}),\n },\n style: styleFromProps(def),\n text: textStyleFromProps(def),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n editing: id,\n },\n [{ fx: 'create', id }],\n ];\n}\n\nfunction finishPolyCreate(m: Model): [Model, Effect[]] {\n const d = m.draft;\n if (d?.g !== 'create-poly') return [m, []];\n const minPoints = d.closed ? 3 : 2;\n if (d.points.length < minPoints) return [{ ...m, draft: null }, []];\n\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const geom: Geom = {\n t: 'poly',\n points: d.points,\n closed: d.closed,\n ends: d.closed ? undefined : def.lineEndings,\n };\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon: d.pon,\n subtype: d.subtype,\n geom,\n style: styleFromProps(def),\n flags: { ...DRAWN_FLAGS, ...d.flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Drop degenerate segment quads (zero-length baseline or ink extent). Area is\n * the cross product of the two edge vectors — orientation-safe. */\nconst usableQuads = (quads: TextQuad[]): TextQuad[] =>\n quads.filter((q) => {\n const ux = q.upperEnd.x - q.upperStart.x;\n const uy = q.upperEnd.y - q.upperStart.y;\n const sx = q.lowerStart.x - q.upperStart.x;\n const sy = q.lowerStart.y - q.upperStart.y;\n return Math.abs(ux * sy - uy * sx) > 0;\n });\n\n/**\n * Build a text-markup annotation from the selection's per-line rects. The new\n * annotation is `vector` (rendered live by the overlay) and selected, mirroring\n * `createPointer`. One call per page the selection spans. Clears any live preview.\n */\nfunction createMarkup(\n m: Model,\n subtype: Subtype,\n pon: Annot['pon'],\n segmentQuads: TextQuad[],\n preset: string = subtype,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const quads = usableQuads(segmentQuads);\n if (!quads.length) return [m, []];\n const id = `tmp:${m.seq + 1}`;\n const annot: Annot = {\n id,\n ref: null,\n pon,\n subtype,\n geom: { t: 'quads', quads },\n style: styleFromProps(defaultsFor(m, preset)),\n flags: { ...DRAWN_FLAGS, ...flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n preview: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/**\n * Create Adobe-compatible Replace Text as one optimistic logical annotation:\n * a top-level Caret (`/IT /Replace`) plus a StrikeOut subordinate\n * (`/IT /StrikeOutTextEdit`, `/IRT` caret, `/RT /Group`). Persistence performs\n * the two ordered writes and rolls the primary back if the subordinate fails.\n */\nfunction createReplaceText(\n m: Model,\n pon: Annot['pon'],\n segmentQuads: TextQuad[],\n anchor: TextEndAnchor,\n preset = 'replace-text',\n): [Model, Effect[]] {\n const quads = usableQuads(segmentQuads);\n if (!quads.length) return [m, []];\n const primaryId = `tmp:${m.seq + 1}`;\n const strikeoutId = `tmp:${m.seq + 2}`;\n const style = styleFromProps(defaultsFor(m, preset));\n const caret: Annot = {\n id: primaryId,\n ref: null,\n pon,\n subtype: 'caret',\n intent: 'replace',\n geom: caretGeomFromAnchor(anchor),\n style,\n flags: DRAWN_FLAGS,\n source: 'vector',\n };\n const strikeout: Annot = {\n id: strikeoutId,\n ref: null,\n pon,\n subtype: 'strikeout',\n intent: 'strikeout-text-edit',\n geom: { t: 'quads', quads },\n style,\n flags: DRAWN_FLAGS,\n source: 'vector',\n irt: primaryId,\n group: primaryId,\n };\n return [\n {\n ...m,\n seq: m.seq + 2,\n byId: { ...m.byId, [primaryId]: caret, [strikeoutId]: strikeout },\n order: [...m.order, primaryId, strikeoutId],\n selected: [primaryId, strikeoutId],\n draft: null,\n preview: null,\n },\n [{ fx: 'createGroup', primary: primaryId, members: [strikeoutId] }],\n ];\n}\n\nfunction createCaret(\n m: Model,\n pon: Annot['pon'],\n anchor: TextEndAnchor,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const caretGeom = caretGeomFromAnchor(anchor);\n if (caretGeom.rect.width <= 0 || caretGeom.rect.height <= 0) return [m, []];\n const id = `tmp:${m.seq + 1}`;\n const def = defaultsFor(m, 'caret');\n const annot: Annot = {\n id,\n ref: null,\n pon,\n subtype: 'caret',\n geom: caretGeom,\n style: styleFromProps(def),\n flags: { ...DRAWN_FLAGS, ...flags },\n source: 'vector',\n };\n return [\n {\n ...m,\n seq: m.seq + 1,\n byId: { ...m.byId, [id]: annot },\n order: [...m.order, id],\n selected: [id],\n draft: null,\n preview: null,\n },\n [{ fx: 'create', id }],\n ];\n}\n\n/** Set / replace the live markup preview from the selection's per-page quads. */\nfunction setMarkupPreview(\n m: Model,\n subtype: Subtype,\n quadsByPage: Record<number, TextQuad[]>,\n preset: string = subtype,\n): [Model, Effect[]] {\n const byPage: Record<number, TextQuad[]> = {};\n for (const k in quadsByPage) {\n const quads = usableQuads(quadsByPage[k]);\n if (quads.length) byPage[Number(k)] = quads;\n }\n return [{ ...m, preview: { subtype, preset, byPage } }, []];\n}\n\n/**\n * Apply a flat property patch to the current selection. Each member takes only\n * the keys its KIND declares (see `applyProps` — routing to `style`, `geom.ends`\n * or `text` happens there) and ignores the rest, so one patch restyles a mixed\n * selection. Changed members flip to `vector` (we own the appearance now) and\n * emit one engine patch each. The base style / tool defaults are NEVER touched:\n * editing existing annotations must not change what the next drawn one looks like.\n */\nfunction setProps(m: Model, patch: AnnotationPropsPatch): [Model, Effect[]] {\n if (!m.selected.length) return [m, []];\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n // The effect carries the user's keys VERBATIM — the shell lowers exactly\n // this intent to wire fields; the changed-prop set IS the artifact.\n const keys = (Object.keys(patch) as PropKey[]).filter((k) => patch[k] !== undefined);\n for (const id of m.selected) {\n const a = byId[id];\n if (!a) continue;\n // The `link` slot is NOT appearance and NOT model state on a non-link\n // kind: the value lives in attached child annotations (the `linkOf`\n // lens reads them back), so the intent is read off the PATCH and rides\n // the target-carrying `syncLink` — the shell's reconciler owns the child\n // operations. Locked annotations refuse it like any other prop write.\n const linkIntent =\n patch.link !== undefined &&\n a.subtype !== 'link' &&\n kindTakesLink(a.subtype) &&\n annotTransformable(a);\n const next = applyProps(a, patch);\n if (!next) {\n // Nothing applied to the model (link-only patch on a parent, or an\n // undeclared key) — the link intent still materializes.\n if (linkIntent) fx.push({ fx: 'syncLink', id, target: patch.link ?? null });\n continue;\n }\n const linkChanged = next.link !== a.link;\n const otherChanged =\n next.style !== a.style ||\n next.geom !== a.geom ||\n next.text !== a.text ||\n next.icon !== a.icon;\n // A restyle flips to vector (we own the appearance now) — EXCEPT\n // `opaqueBody` kinds (widgets), which have no vector render: they stay\n // baked and the shell re-fetches the engine's re-baked raster on resolve.\n // Flipping them would also drop them out of `appearanceEpoch`, freezing\n // their raster forever.\n byId[id] = capsFor(a.subtype).opaqueBody || !otherChanged ? next : toVector(next);\n // The link KIND's target lives on its own DTO — a plain engine patch.\n if (otherChanged || (linkChanged && a.subtype === 'link'))\n fx.push({ fx: 'patch', id, scope: { kind: 'props', keys } });\n if (linkIntent) fx.push({ fx: 'syncLink', id, target: patch.link ?? null });\n }\n return fx.length ? [{ ...m, byId }, fx] : [m, []];\n}\n\n/**\n * Merge a `/F` flags patch into the selection (or explicit ids). NOT the props\n * path, on purpose: flags aren't appearance — members keep their render\n * `source` (a baked raster stays valid; nothing re-bakes) — and the write is\n * NOT gated by `locked`, because unlocking a locked annotation is the whole\n * point (Acrobat's Locked checkbox stays live). One `flags` effect per changed\n * COMMITTED member; uncommitted drafts just merge (their create draft carries\n * the flags when it commits).\n */\n/**\n * The actions plane's session-visibility write (Hide actions, script\n * `annot.hidden`): merge per-id hidden overrides into the session overlay.\n * Pure session state — ZERO effects, no engine write, no authority. Hiding\n * clears transient engagement so no orphaned selection chrome or text editor\n * survives on an invisible annotation. Identity-preserving no-op when nothing\n * changes (plugin memo caches key on model identity).\n */\n\nfunction setFlags(m: Model, patch: Partial<AnnotationFlags>, ids?: Id[]): [Model, Effect[]] {\n const targets = ids ?? m.selected;\n if (!targets.length) return [m, []];\n const fx: Effect[] = [];\n let byId: Model['byId'] | null = null;\n for (const id of targets) {\n const a = (byId ?? m.byId)[id];\n if (!a) continue;\n const flags = mergeFlags(a.flags, patch);\n if (flagsEqual(flags, a.flags)) continue; // no spurious engine writes\n byId ??= { ...m.byId };\n byId[id] = { ...a, flags };\n if (a.ref) fx.push({ fx: 'flags', id });\n }\n return byId ? [{ ...m, byId }, fx] : [m, []];\n}\n\nfunction setDefaults(m: Model, subtype: Subtype, patch: AnnotationPropsPatch): [Model, Effect[]] {\n const prev = m.defaults[subtype] ?? {};\n const next: AnnotationPropsPatch = { ...prev, ...patch };\n // Endings merge per side, so `{ end: 'open-arrow' }` keeps a configured start.\n if (patch.lineEndings) next.lineEndings = { ...prev.lineEndings, ...patch.lineEndings };\n return [{ ...m, defaults: { ...m.defaults, [subtype]: next } }, []];\n}\n\n/**\n * Rotate the current selection by `deltaDeg` (clockwise) — the toolbar\n * \"rotate 90°\" affordance. A single shape turns about its own centre; a\n * multi-target group about the union-box centre (gated by `groupRotatable` for\n * groups, `rotatable` for a single shape). Emits one patch per rotated member.\n */\nfunction rotateSelection(m: Model, deltaDeg: number): [Model, Effect[]] {\n const ids = m.selected.filter((id) => {\n const a = m.byId[id];\n return a && annotTransformable(a) && capsFor(a.subtype).rotatable;\n });\n if (!ids.length) return [m, []];\n // pivot: a single shape's own selection-rect centre (so vertex kinds spin in\n // place, not about their off-centre vertex mean); a group's union-box centre.\n // Stored space throughout — a screen-anchored member's AUTHORED tilt turns,\n // which is exactly its on-screen tilt (the display adds nothing to it); at\n // high zoom the anchor may re-seat by a hair, which the toolbar action\n // accepts (the knob gesture, which is pointer-exact, goes through the\n // view-space commit instead).\n let pivot: Vec;\n if (ids.length === 1) {\n const a = m.byId[ids[0]];\n pivot = selectionCenter(a.geom, a.style.strokeWidth);\n } else {\n const pon = m.byId[ids[0]].pon;\n const union = groupUnionBounds({ ...m, selected: ids }, pon);\n if (!union) return [m, []];\n pivot = { x: union.x + union.width / 2, y: union.y + union.height / 2 };\n }\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of ids) {\n const a = byId[id];\n const before = a.geom;\n byId[id] = ownGeometry({ ...a, geom: geomRotateAbout(before, pivot, deltaDeg) });\n fx.push(patchFx(id, byId[id], before));\n }\n return [{ ...m, byId }, fx];\n}\n\n/** Reset rotation on the selection to the as-authored orientation. For a\n * screen-anchored annotation that IS its on-screen orientation, so reset is\n * as meaningful as for anyone else. */\nfunction resetRotation(m: Model): [Model, Effect[]] {\n const byId = { ...m.byId };\n const fx: Effect[] = [];\n for (const id of m.selected) {\n const a = byId[id];\n if (!a || !annotTransformable(a) || geomRotation(a.geom) === 0) continue;\n byId[id] = ownGeometry({ ...a, geom: geomResetRotation(a.geom) });\n fx.push(patchFx(id, byId[id], a.geom));\n }\n return fx.length ? [{ ...m, byId }, fx] : [m, []];\n}\n\nfunction deleteSelection(m: Model): [Model, Effect[]] {\n // `locked` (and inert `/F` states) protect against deletion — only the\n // transformable members go; the rest keep their selection, so a mixed\n // selection deletes what it may and leaves the frozen ones visibly selected.\n const deletable = m.selected.filter((id) => {\n const a = m.byId[id];\n return !!a && annotDeletable(a);\n });\n if (!deletable.length) return [m, []];\n // Attached link children die with their parent. They ARE model\n // annotations now, so expanding the deletable set makes the one loop\n // below handle parent and children uniformly — no side ledger.\n const withChildren = [\n ...deletable,\n ...deletable.flatMap((id) => linkChildrenOf(m, id).map((c) => c.id)),\n ];\n const fx: Effect[] = [];\n for (const id of withChildren) {\n const a = m.byId[id];\n if (a?.ref) fx.push({ fx: 'delete', ref: a.ref });\n }\n return [removeAnnots(m, withChildren), fx];\n}\n\n/* ── marquee helper; exported for tests ───────────────────────────────────── */\nexport function annotsInBox(\n m: Model,\n pon: number,\n a: Vec,\n b: Vec,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Id[] {\n const box = rectFromPoints(a, b);\n return m.order.filter((id) => {\n const annot = m.byId[id];\n if (annot?.pon !== pon || inert?.has(id) || !isSelectable(m, id)) return false;\n // Conversation-plane annotations (replies, review states) are never on\n // the page — the marquee cannot sweep up what does not paint.\n if (isSubstrateOnly(annot)) return false;\n // intersect against what is actually DRAWN: the oriented selection quad\n // (exact, via SAT) — the SAME quad the chrome outlines and the grab region\n // uses (screen-anchored bodies at their view-projected footprint). Its\n // AABB is a coarse superset whose empty corners cover most of a tilted\n // shape's unrotated footprint, so testing the AABB selected shapes the\n // marquee never touched.\n const g = anchoredGeom(annot.geom, anchorModeOf(annot), view);\n return quadIntersectsRect(selectionQuad(g, annot.style.strokeWidth, annot.style.border), box);\n });\n}\n\n/* ── store maintenance ───────────────────────────────────────────────────── */\n\nfunction mergeLoaded(m: Model, annots: Annot[]): Model {\n const byId = { ...m.byId };\n const order = [...m.order];\n for (const a of annots) {\n if (byId[a.id]) continue;\n byId[a.id] = a;\n order.push(a.id);\n }\n return { ...m, byId, order };\n}\n\n/**\n * Whole-document hydration ingest: the snapshot is the committed truth.\n * Overwrites by id via `upsertAnnots` (gesture protection included), then\n * reaps committed entries the snapshot no longer contains — deletions that\n * happened before we subscribed (initial load) or inside a desync gap.\n * Gentler than `removeAnnots`: `tmp:` drafts and gesture-locked ids\n * survive, and an in-progress draft is NOT cancelled — reaped ids can\n * never be part of it (locked ids are excluded from reaping).\n */\nfunction hydrateAnnots(m: Model, annots: Annot[], bumpApFlag: boolean): Model {\n const incoming = new Set(annots.map((a) => a.id));\n const locked = draftIds(m.draft);\n const reaped = m.order.filter((id) => {\n if (incoming.has(id) || locked.has(id)) return false;\n const a = m.byId[id];\n return a !== undefined && a.ref !== null; // committed only; tmp: drafts stay\n });\n let next = m;\n if (reaped.length > 0) {\n const gone = new Set(reaped);\n const byId = { ...m.byId };\n for (const id of reaped) delete byId[id];\n next = {\n ...m,\n byId,\n order: m.order.filter((id) => !gone.has(id)),\n selected: m.selected.filter((id) => !gone.has(id)),\n hovered: m.hovered && gone.has(m.hovered) ? null : m.hovered,\n editing: m.editing && gone.has(m.editing) ? null : m.editing,\n };\n }\n return upsertAnnots(next, annots, bumpApFlag);\n}\n\n/**\n * Add-or-replace by id. Unlike `mergeLoaded` (which skips ids it already has,\n * for the bulk page read), this OVERWRITES — it's how the data API re-syncs an\n * annotation from the authoritative engine DTO and how a remote edit lands.\n * New ids append to `order`; existing ones keep their position. An annotation\n * currently being dragged (its id is in a `move`/`handle` draft) is left as-is\n * so a remote echo can't yank geometry out from under the local gesture.\n */\nfunction upsertAnnots(m: Model, annots: Annot[], bumpAp = false): Model {\n const dragging = draftIds(m.draft);\n const byId = { ...m.byId };\n const order = [...m.order];\n for (const a of annots) {\n if (dragging.has(a.id)) continue;\n if (!byId[a.id]) order.push(a.id);\n const prev = byId[a.id];\n // `apVersion` is model-owned, not DTO-derived: carry it across the replace,\n // +1 when this upsert confirms an engine re-bake with new raster content.\n byId[a.id] = { ...a, apVersion: (prev?.apVersion ?? 0) + (bumpAp ? 1 : 0) };\n }\n return { ...m, byId, order };\n}\n\n/** Advance `apVersion` for known ids — an engine /AP re-bake that arrived\n * WITHOUT new model data (a form value write repainting its widgets). */\nfunction bumpAp(m: Model, ids: Id[]): Model {\n let byId: Model['byId'] | null = null;\n for (const id of ids) {\n const a = m.byId[id];\n if (!a) continue;\n byId ??= { ...m.byId };\n byId[id] = { ...a, apVersion: (a.apVersion ?? 0) + 1 };\n }\n return byId ? { ...m, byId } : m;\n}\n\n/** Ids locked by an in-progress local gesture (don't let an upsert clobber them). */\nfunction draftIds(draft: Draft | null): Set<Id> {\n if (!draft) return new Set();\n if (draft.g === 'move') return new Set(draft.ids);\n if (draft.g === 'handle') return new Set([draft.id]);\n if (draft.g === 'rotate' || draft.g === 'group') return new Set(draft.ids);\n return new Set();\n}\n\nfunction removeAnnots(m: Model, ids: Id[]): Model {\n const gone = new Set(ids);\n const byId = { ...m.byId };\n for (const id of ids) delete byId[id];\n return {\n ...m,\n byId,\n order: m.order.filter((id) => !gone.has(id)),\n selected: m.selected.filter((id) => !gone.has(id)),\n draft: null,\n editing: m.editing && gone.has(m.editing) ? null : m.editing,\n };\n}\n\nfunction reconcile(m: Model, tempId: Id, id: Id, ref: AnnotationRef): Model {\n const a = m.byId[tempId];\n if (!a) return m;\n const { [tempId]: _drop, ...rest } = m.byId;\n const byId: Record<Id, Annot> = { ...rest, [id]: { ...a, id, ref } };\n // Composite creations can relate another optimistic annotation to this temp\n // id. Keep the relationship coherent across the temp→durable id swap.\n for (const key of Object.keys(byId)) {\n const other = byId[key]!;\n if (other.irt === tempId || other.group === tempId) {\n byId[key] = {\n ...other,\n ...(other.irt === tempId ? { irt: id } : {}),\n ...(other.group === tempId ? { group: id } : {}),\n };\n }\n }\n return {\n ...m,\n byId,\n order: m.order.map((x) => (x === tempId ? id : x)),\n selected: m.selected.map((x) => (x === tempId ? id : x)),\n // keep the just-drawn box in edit mode across the temp→durable id swap\n editing: m.editing === tempId ? id : m.editing,\n };\n}\n","/**\n * `scene(item)` — the render contract. Turns an annotation render-item into a flat\n * list of fully-PAINTED nodes (geometry + how to paint it). A framework renderer\n * just maps each node to one element and applies `paint`; it owns no per-kind\n * appearance logic, so adding a framework (or a kind) never duplicates drawing.\n *\n * Geometry comes from `geomScene` (shared with hit-testing); paint is layered on\n * here. Text markup is the one family whose paint varies per node (highlight FILLS,\n * underline/strikeout/squiggly STROKE, widths derived from the line height), so it\n * has its own small painter — but it still emits the same generic SceneNodes.\n */\nimport { textQuadBounds, textQuadRing } from '@embedpdf/core-geometry';\nimport { geomScene } from './geometry';\nimport type {\n Geom,\n Paint,\n Rect,\n RenderItem,\n SceneNode,\n Style,\n Subtype,\n TextQuad,\n TextStyle,\n Vec,\n} from './types';\n\nconst num = (n: number): number => Number(n.toFixed(3));\n\n/** Uniform paint for a shape/line/poly node. Fill only lands on closed nodes; the\n * dash comes solely from the border style — so a live draft (ghost) previews\n * exactly how the committed annotation will look, not as a dashed hint. */\n/** CSS mix-blend-mode for live vector paint. `normal` needs no style override. */\nexport function blendFor(style: Style): Paint['blend'] {\n return style.blendMode === 'normal' ? undefined : style.blendMode;\n}\n\nfunction shapePaint(style: Style, closed: boolean): Paint {\n return {\n fill: closed ? (style.interiorColor ?? undefined) : undefined,\n stroke: style.color,\n width: style.strokeWidth,\n opacity: style.opacity,\n dash: style.border.kind === 'dashed' ? style.border.dash : undefined,\n // Cloud curls end in deliberate direction reversals (the 22° curl-back\n // tails), which a miter join blows up into spikes. PDFium bakes cloudy\n // borders with `1 j` (round join) for exactly this reason — match it, so\n // the live path and the baked /AP render the same seams.\n ...(style.border.kind === 'cloudy' ? { join: 'round' as const } : {}),\n };\n}\n\n/** A smooth squiggle (quadratic-bezier wave) along an ARBITRARY baseline,\n * generated in the (û, n̂) basis: one `Q` hump then reflected `T` segments\n * alternate across the run. Reflection is affine-invariant, so an upright\n * quad reproduces the old axis-aligned wave byte-for-byte. `n̂` points from\n * the baseline toward the ascent side; humps rise toward the text. */\nfunction squigglePath(start: Vec, u: Vec, n: Vec, w: number, amp: number): string {\n const half = Math.max(2, amp * 1.5); // half a wavelength\n const at = (t: number, off: number): Vec => ({\n x: start.x + u.x * t + n.x * off,\n y: start.y + u.y * t + n.y * off,\n });\n const p = (v: Vec) => `${num(v.x)} ${num(v.y)}`;\n const hump = at(half / 2, amp);\n let d = `M ${p(at(0, 0))} Q ${p(hump)} ${p(at(half, 0))}`;\n for (let t = half; t + half <= w + 0.5; t += half) {\n d += ` T ${p(at(t + half, 0))}`;\n }\n return d;\n}\n\n/** Per-subtype markup nodes on the quads' own edges (corner-NAMED TextQuads:\n * upper = ascent side, lower = baseline side, start → end along the frame).\n * The colour is the markup `/C` (our model keeps stroke==fill). Rotated and\n * sheared cells draw along their true baselines; upright output is identical\n * to the old axis-aligned math. */\nfunction markupScene(subtype: Subtype, quads: TextQuad[], style: Style): SceneNode[] {\n const color = style.color;\n const opacity = style.opacity;\n const nodes: SceneNode[] = [];\n for (const q of quads) {\n const down = { x: q.lowerStart.x - q.upperStart.x, y: q.lowerStart.y - q.upperStart.y };\n const h = Math.hypot(down.x, down.y); // true ink height\n const wVec = { x: q.lowerEnd.x - q.lowerStart.x, y: q.lowerEnd.y - q.lowerStart.y };\n const w = Math.hypot(wVec.x, wVec.y); // true baseline length\n if (w <= 0 || h <= 0) continue;\n const n = { x: down.x / h, y: down.y / h }; // unit, toward the baseline\n const lw = Math.min(2.5, Math.max(0.75, h * 0.06));\n if (subtype === 'underline') {\n // the baseline edge, inset lw off the descent side (the old `y + h − lw`)\n nodes.push({\n kind: 'line',\n a: { x: q.lowerStart.x - n.x * lw, y: q.lowerStart.y - n.y * lw },\n b: { x: q.lowerEnd.x - n.x * lw, y: q.lowerEnd.y - n.y * lw },\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else if (subtype === 'strikeout') {\n nodes.push({\n kind: 'line',\n a: {\n x: (q.upperStart.x + q.lowerStart.x) / 2,\n y: (q.upperStart.y + q.lowerStart.y) / 2,\n },\n b: { x: (q.upperEnd.x + q.lowerEnd.x) / 2, y: (q.upperEnd.y + q.lowerEnd.y) / 2 },\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else if (subtype === 'squiggly') {\n const amp = Math.min(2, Math.max(1, h * 0.08));\n const u = { x: wVec.x / w, y: wVec.y / w };\n const start = { x: q.lowerStart.x - n.x * amp, y: q.lowerStart.y - n.y * amp };\n nodes.push({\n kind: 'path',\n // n̂ toward ascent = −(toward baseline)\n d: squigglePath(start, u, { x: -n.x, y: -n.y }, w, amp),\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else {\n // highlight: translucent fill with `multiply` so the text reads through it\n nodes.push({\n kind: 'poly',\n points: textQuadRing(q),\n closed: true,\n paint: { fill: color, opacity, blend: blendFor(style) },\n });\n }\n }\n return nodes;\n}\n\n/** A redact mark's regions: per-quad rings (text marks) or the rect (area).\n * `bounds` feeds the (axis-aligned) label layout; `ring` is what gets drawn,\n * so rotated text marks outline and fill their true cells. */\ninterface RedactRegion {\n ring: [Vec, Vec, Vec, Vec];\n bounds: Rect;\n}\n\nconst rectRing = (r: Rect): [Vec, Vec, Vec, Vec] => [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x + r.width, y: r.y + r.height },\n { x: r.x, y: r.y + r.height },\n];\n\nfunction redactRegions(geom: Geom): RedactRegion[] {\n if (geom.t === 'quads') {\n const out: RedactRegion[] = [];\n for (const q of geom.quads) {\n const bounds = textQuadBounds(q);\n if (bounds.width > 0 && bounds.height > 0) out.push({ ring: textQuadRing(q), bounds });\n }\n return out;\n }\n if (geom.t === 'rect') return [{ ring: rectRing(geom.rect), bounds: geom.rect }];\n return [];\n}\n\n/**\n * Redaction label layout — the SAME reading of ISO 32000-2 the engine's\n * apply-time painter uses, as pure math: top-aligned, `/Q` horizontal\n * alignment, `/Repeat` tiling a full grid that FITS the region (no partial\n * glyph bleed — the scene has no clipping). Character advance is estimated\n * (0.55em Helvetica-ish); this is a live preview, the engine bakes the truth.\n */\nexport function layoutRedactLabel(\n region: Rect,\n label: { text: string; repeat: boolean },\n text: TextStyle | undefined,\n): SceneNode[] {\n if (!label.text) return [];\n const fontSize = Math.max(4, text && text.fontSize > 0 ? text.fontSize : region.height * 0.6);\n const charW = fontSize * 0.55;\n const textW = label.text.length * charW;\n const lineH = fontSize * 1.2;\n const paint: Paint = { fill: text?.fontColor ?? '#ffffff', opacity: 1 };\n const base = { fontSize, ...(text?.fontFamily ? { fontFamily: text.fontFamily } : {}), paint };\n const baseline = (rowTop: number) => rowTop + fontSize * 0.95;\n\n if (!label.repeat) {\n if (fontSize > region.height) return [];\n const x =\n text?.textAlign === 'center'\n ? region.x + Math.max(0, (region.width - textW) / 2)\n : text?.textAlign === 'right'\n ? region.x + Math.max(0, region.width - textW)\n : region.x;\n return [{ kind: 'text', at: { x, y: baseline(region.y) }, text: label.text, ...base }];\n }\n\n const cols = Math.max(1, Math.floor((region.width + charW) / (textW + charW)));\n const rows = Math.max(1, Math.floor(region.height / lineH));\n const nodes: SceneNode[] = [];\n for (let r = 0; r < rows && nodes.length < 400; r++) {\n for (let c = 0; c < cols && nodes.length < 400; c++) {\n nodes.push({\n kind: 'text',\n at: { x: region.x + c * (textW + charW), y: baseline(region.y + r * lineH) },\n text: label.text,\n ...base,\n });\n }\n }\n return nodes;\n}\n\n/**\n * Redaction marks: at REST an outline per region, nothing filled. On HOVER\n * the applied-look preview — the `/IC` fill plus the tiled `/OverlayText`\n * label — exactly what the destructive apply will paint. All pure data, so\n * every framework renders the preview from the same scene.\n */\nfunction redactScene(item: RenderItem): SceneNode[] {\n const regions = redactRegions(item.geom);\n if (!item.hovered) {\n const paint = {\n stroke: item.style.color,\n width: item.style.strokeWidth || 1.5,\n opacity: item.style.opacity,\n };\n return regions.map(\n (region) => ({ kind: 'poly', points: region.ring, closed: true, paint }) as SceneNode,\n );\n }\n const nodes: SceneNode[] = [];\n if (item.style.interiorColor) {\n const fill = { fill: item.style.interiorColor, opacity: 1 };\n for (const region of regions) {\n nodes.push({ kind: 'poly', points: region.ring, closed: true, paint: fill });\n }\n }\n if (item.label) {\n // Label tiling stays axis-aligned inside the region's bounds — the live\n // preview approximates; the engine's apply-time painter bakes the truth.\n for (const region of regions) {\n nodes.push(...layoutRedactLabel(region.bounds, item.label, item.text));\n }\n }\n return nodes;\n}\n\n/** The full painted scene for one annotation. */\nexport function scene(item: RenderItem): SceneNode[] {\n // Links paint NOTHING: an invisible hit rectangle is the norm (any visible\n // border a PDF authored shows through the page raster). Selection chrome\n // still outlines it, so an editable link is findable when selected.\n if (item.subtype === 'link') return [];\n if (item.subtype === 'redact') return redactScene(item);\n if (item.geom.t === 'quads') return markupScene(item.subtype, item.geom.quads, item.style);\n if (item.geom.t === 'caret') {\n return geomScene(item.geom).map((n) => ({\n ...n,\n paint: {\n fill: item.style.color,\n stroke: item.style.color,\n width: 0.5,\n opacity: item.style.opacity,\n },\n })) as SceneNode[];\n }\n const ink = item.geom.t === 'ink'; // freehand: round the pen-stroke ends (caps)\n return geomScene(item.geom, item.style.strokeWidth, item.style.border).map((n) => {\n const closed =\n n.kind === 'rect' ||\n n.kind === 'ellipse' ||\n n.kind === 'path' ||\n (n.kind === 'poly' && n.closed);\n const paint = { ...shapePaint(item.style, closed), blend: blendFor(item.style) };\n // Ink is freehand: round the pen-stroke ends AND joins. Every other kind keeps\n // the default butt caps + sharp (miter) joins — square corners and poly knees\n // stay crisp.\n return { ...n, paint: ink ? { ...paint, cap: 'round', join: 'round' } : paint } as SceneNode;\n });\n}\n","/**\n * Pure view selectors. `pageItems` is the per-annotation render list (live gesture\n * applied) for customRenderer wrapping; `chrome` is the selection overlay\n * (handles carry their resize cursor, group box, marquee).\n */\nimport {\n chordThrough,\n geomHandles,\n geomRotateAbout,\n geomRotation,\n geomScaleAbout,\n geomTranslate,\n geomVisualBounds,\n groupResizeFactors,\n obbFromGeom,\n placeRotateKnob,\n rectFromPoints,\n rectHandlesFor,\n normalizeDeg,\n rotatePoint,\n selectionBounds,\n selectionQuad,\n shapeRectFor,\n unionRect,\n ROTATE_KNOB_OFFSET,\n} from './geometry';\nimport { groupCaps } from './group';\nimport { isSelectable, paintOrder } from './hit';\nimport { capsFor } from './kinds';\nimport { annotTransformable, viewable } from './flags';\nimport {\n anchoredBox,\n anchoredGeom,\n anchoredStrokeWidth,\n anchorModeOf,\n anchorOf,\n type ViewEnv,\n} from './anchor';\nimport { blendFor } from './scene';\nimport { styleFromProps } from './props';\nimport { calloutBox, calloutUprightRot, defaultsFor, rotateDraftDelta } from './update';\nimport type { Annot, ChromeNode, Geom, Id, Model, Rect, RenderItem, Style, Vec } from './types';\nimport type { CreationDraftAnchor } from './types';\n\nconst DRAFT_ID = '__draft__';\nconst PREVIEW_ID = '__markup_preview__';\n\nconst polyPreviewPoints = (points: Vec[], cur: Vec): Vec[] => {\n const last = points[points.length - 1];\n return last && (cur.x !== last.x || cur.y !== last.y) ? [...points, cur] : points;\n};\n\n/**\n * The gesture-effective geometry, in VIEW space: PROJECT FIRST (screen-\n * anchored bodies to their effective footprint — the identity for everyone\n * else), then apply the live gesture. Gestures compose in view space: the\n * pointer, the drafts' pivots/boxes, and a `handle` draft's geometry all live\n * there already, so ONE code path serves flagged and unflagged annotations —\n * and the commit (`editUp`) maps the same composition back through\n * `unanchoredGeom`, so preview ≡ commit by construction. THE geometry every\n * selector below hands out, so render/chrome/bounds agree with hit.\n */\nfunction effGeom(m: Model, id: Id, view: ViewEnv | undefined): Geom {\n const a = m.byId[id];\n const g = anchoredGeom(a.geom, anchorModeOf(a), view);\n const d = m.draft;\n if (d) {\n if (d.g === 'move' && d.ids.includes(id)) return geomTranslate(g, d.delta);\n if (d.g === 'handle' && d.id === id) return d.cur; // already view space\n if (d.g === 'rotate' && d.ids.includes(id)) {\n // The SAME snapped angle rule the commit uses (see `rotateDraftDelta`).\n return geomRotateAbout(g, d.pivot, rotateDraftDelta(m, d).delta);\n }\n if (d.g === 'group' && d.ids.includes(id)) {\n const { sx, sy } = groupResizeFactors(d.base, d.cur);\n return geomScaleAbout(g, d.anchor, sx, sy);\n }\n }\n return g;\n}\n\n/** Style with the stroke width an anchored VECTOR body renders at (screen-\n * constant line weight); everyone else keeps their style verbatim. */\nfunction effStyle(a: Annot, view: ViewEnv | undefined): Style {\n const mode = anchorModeOf(a);\n if (!mode?.zoom || !view) return a.style;\n return { ...a.style, strokeWidth: anchoredStrokeWidth(a.style.strokeWidth, mode, view) };\n}\n\n/** The blit placement for a baked raster: its box (view space, live move\n * applied) + the rotation to re-apply about the box centre.\n *\n * `opaqueBody` kinds (stamp images): the raster IS the visual, so the box\n * follows EVERY live gesture — the unrotated rect of the effective geometry\n * covers move, resize, and group-scale in one rule, and the effective\n * rotation drives the blit transform (a stamp spins with the gesture).\n *\n * Everyone else blits by the AP `/Rect`: for a screen-anchored annotation\n * that box rides the SAME similarity the geometry projects through\n * (`anchoredBox`), composing its counter-rotation with any engine-stripped\n * `apRot` — so a baked noZoom/noRotate body renders screen-constant too. */\nfunction effAp(m: Model, id: Id, view: ViewEnv | undefined): { box?: Rect; rot?: number } {\n const a = m.byId[id];\n if (capsFor(a.subtype).opaqueBody) {\n const g = effGeom(m, id, view);\n return {\n box: 'rect' in g ? g.rect : a.apBox,\n rot: geomRotation(g) || undefined,\n };\n }\n if (!a.apBox) return { rot: a.apRot };\n const projected = anchoredBox(a.apBox, anchorOf(a.geom), anchorModeOf(a), view);\n let box = projected?.box ?? a.apBox;\n const rot = normalizeDeg((a.apRot ?? 0) + (projected?.rot ?? 0)) || undefined;\n const d = m.draft;\n if (d?.g === 'move' && d.ids.includes(id)) {\n box = { ...box, x: box.x + d.delta.x, y: box.y + d.delta.y };\n }\n return { box, rot };\n}\n\n/** Render source for one annotation: an in-progress resize renders LIVE (the\n * baked raster can't stretch), even though the commit hasn't flipped `source`\n * yet — so the drag is crisp and a no-op grab can revert to baked. */\nfunction effSource(m: Model, id: Id): 'baked' | 'vector' {\n const a = m.byId[id];\n // `opaqueBody` kinds have NO vector render: they stay baked through every\n // gesture — the bitmap stretches with `effApBox` and tilts via the item's\n // live `rot`, then the engine's re-fit appearance replaces it on commit.\n if (capsFor(a.subtype).opaqueBody) return a.source;\n // A text box under TEXT EDIT renders fully live (scene fill/border — and a\n // callout's leader — + DOM text): the flat baked raster can't hide just\n // its text, so any blend doubles it. Geometry gestures flip below; editing\n // joins them here.\n if (m.editing === id && a.geom.t === 'text') return 'vector';\n const d = m.draft;\n // A live resize/rotate/group transform must render LIVE — the baked raster\n // can't stretch or tilt — even before the commit flips `source`.\n if (d?.g === 'handle' && d.id === id) return 'vector';\n if ((d?.g === 'rotate' || d?.g === 'group') && d.ids.includes(id)) return 'vector';\n return a.source;\n}\n\n/** A free-text box renders as a LIVE element (editable / reflowing) while it's\n * being edited or while its source is vector (a resize, in-progress or committed);\n * otherwise it renders as the engine's baked /AP image, exactly like a shape. */\nfunction textIsLive(m: Model, id: Id): boolean {\n return m.editing === id || effSource(m, id) === 'vector';\n}\n\nexport function pageItems(m: Model, pon: number, view?: ViewEnv): RenderItem[] {\n const items: RenderItem[] = [];\n // `paintOrder` puts text-layer markups beneath every other kind (back→front),\n // so a highlight drawn after a circle still paints under it — and culls what\n // `/F` hides. The SAME order hit-testing uses, so what you click matches\n // what you see.\n for (const id of paintOrder(m, pon)) {\n const a = m.byId[id];\n // Free text stays in the render list in EVERY state, like a shape: a baked,\n // idle box renders as its engine /AP image; a live one (editing / resizing /\n // restyled) renders its box — fill + border, and a callout's leader — via\n // the vector scene, while only its TEXT is the framework's editable element\n // (see `textBoxes`). Dropping the live plain box here is what used to lose\n // its border and background the moment it was touched.\n const geom = effGeom(m, id, view);\n const style = effStyle(a, view);\n // Blit box + rotation for the baked raster (see `effAp`): opaqueBody kinds\n // follow the live effective geometry; everyone else blits by the AP /Rect,\n // projected through the anchor similarity for screen-anchored bodies and\n // composed with any engine-stripped `apRot`.\n const ap = effAp(m, id, view);\n items.push({\n id,\n ref: a.ref,\n subtype: a.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n apBox: ap.box,\n style,\n ...(a.text ? { text: a.text } : {}),\n ...(a.label ? { label: a.label } : {}),\n source: effSource(m, id),\n selected: m.selected.includes(id),\n ...(m.hovered === id ? { hovered: true } : {}),\n rot: geomRotation(geom),\n ...(ap.rot ? { apRot: ap.rot } : {}),\n blend: blendFor(a.style),\n });\n }\n const d = m.draft;\n if (\n (d?.g === 'create-rect' ||\n d?.g === 'create-line' ||\n d?.g === 'create-poly' ||\n d?.g === 'create-ink') &&\n d.pon === pon\n ) {\n // Preview with the tool's RESOLVED defaults (base + per-subtype override), so the\n // ghost is a faithful WYSIWYG of what will commit — not the bare base style. A\n // cloudy rect stores the OUTER box (see `shapeRectFor`), so the cloud grows out\n // from the cursor; a 0-drag draws nothing (skipped, like a solid 0×0).\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const style = styleFromProps(def);\n const dragged = d.g === 'create-rect' ? rectFromPoints(d.from, d.to) : null;\n const geom: Geom | null =\n d.g === 'create-rect'\n ? dragged && (dragged.width > 0 || dragged.height > 0)\n ? { t: 'rect', rect: shapeRectFor(dragged, d.ellipse, style), ellipse: d.ellipse }\n : null\n : d.g === 'create-line'\n ? { t: 'line', a: d.from, b: d.to, ends: def.lineEndings }\n : d.g === 'create-poly'\n ? {\n t: 'poly',\n points: polyPreviewPoints(d.points, d.cur),\n closed: d.closed,\n ends: d.closed ? undefined : def.lineEndings,\n }\n : { t: 'ink', strokes: d.strokes };\n if (geom)\n items.push({\n id: DRAFT_ID,\n ref: null,\n subtype: d.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n style,\n source: 'ghost',\n selected: false,\n });\n }\n // Callout creation ghost: the in-progress leader (tip → cur, then tip → knee →\n // box) and the text-box preview, painted through the SAME vector scene.\n if (d?.g === 'create-callout' && d.pon === pon) {\n const def = defaultsFor(m, d.preset ?? d.subtype);\n const style = styleFromProps(def);\n const ending = def.lineEndings.end !== 'none' ? def.lineEndings.end : 'open-arrow';\n // The box preview carries the SAME upright rot the commit will apply, so\n // the ghost box (and its leader connection) is what you actually get.\n const rot = calloutUprightRot(d);\n const geom: Geom =\n d.step === 'knee'\n ? { t: 'line', a: d.tip, b: d.cur, ends: { start: ending, end: 'none' } }\n : {\n t: 'text',\n rect: calloutBox(d),\n callout: { tip: d.tip, knee: d.knee, ending },\n ...(rot ? { rot } : {}),\n };\n items.push({\n id: DRAFT_ID,\n ref: null,\n subtype: d.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n style,\n source: 'ghost',\n selected: false,\n });\n }\n // Live text-markup preview: the in-progress selection rendered as the markup it\n // will become (same `scene()` paint as the committed annotation).\n const quads = m.preview?.byPage[pon];\n if (m.preview && quads?.length) {\n const geom: Geom = { t: 'quads', quads };\n items.push({\n id: PREVIEW_ID,\n ref: null,\n subtype: m.preview.subtype,\n geom,\n box: geomVisualBounds(geom, 0),\n style: styleFromProps(defaultsFor(m, m.preview.preset)),\n source: 'ghost',\n selected: false,\n });\n }\n return items;\n}\n\n/** One free-text box, geometry only (the live move/resize gesture applied), with\n * its edit flag. The framework renders an editable element here; the plugin\n * layers the DTO-derived text style on top. */\nexport interface TextBox {\n id: Id;\n box: Rect;\n editing: boolean;\n /** Applied rotation (deg, CW). `box` is the UNROTATED text box; the framework\n * rotates the editable element about its centre by this. 0/undefined = none. */\n rot?: number;\n}\n\n/** The free-text boxes on a page — the text counterpart of `pageItems`. */\nexport function textBoxes(m: Model, pon: number, view?: ViewEnv): TextBox[] {\n const out: TextBox[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (a.pon !== pon || a.geom.t !== 'text') continue;\n if (!viewable(a.flags, m.selected.includes(id))) continue; // `/F`-hidden\n if (!textIsLive(m, id)) continue; // baked → rendered as the /AP image instead\n const g = effGeom(m, id, view);\n if (g.t !== 'text') continue;\n out.push({ id, box: g.rect, editing: m.editing === id, rot: geomRotation(g) });\n }\n return out;\n}\n\n/** The currently selected annotations as render items (live gesture applied) —\n * cross-page, for selection-aware toolbars (style + line-ending editing). */\nexport function selectedItems(m: Model, view?: ViewEnv): RenderItem[] {\n const items: RenderItem[] = [];\n for (const id of m.selected) {\n const a = m.byId[id];\n if (!a) continue;\n const geom = effGeom(m, id, view);\n const style = effStyle(a, view);\n items.push({\n id,\n ref: a.ref,\n subtype: a.subtype,\n geom,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n style,\n source: a.source,\n selected: true,\n rot: geomRotation(geom),\n });\n }\n return items;\n}\n\nconst boxCorners = (r: Rect): [Vec, Vec, Vec, Vec] => [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x + r.width, y: r.y + r.height },\n { x: r.x, y: r.y + r.height },\n];\n\n/**\n * The union of the selection's bounds on `pon`, reading each member through\n * `geomOf` — `effGeom` for the group chrome, so the outline/handles/knob RIDE\n * a live move/scale exactly like single-selection chrome; the COMMITTED\n * geometry for a rotate gesture's rest anchor. Hit-testing keeps its own\n * committed union (hit.ts `groupUnionBounds`): hits only happen between\n * gestures, where the two are identical.\n */\nfunction unionBoundsOf(\n m: Model,\n pon: number,\n geomOf: (id: Id) => Geom,\n view?: ViewEnv,\n): Rect | null {\n const corners: Vec[] = [];\n for (const id of m.selected) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n corners.push(...selectionQuad(geomOf(id), effStyle(a, view).strokeWidth, a.style.border));\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/** The page-bound knob placement for the selection on `pon`, reading each\n * member's geometry through `geomOf` — `effGeom` for the live view, the\n * COMMITTED geometry for a rotate gesture's rest anchor (see `selectionKnob`). */\nfunction placeSelectionKnob(\n m: Model,\n pon: number,\n pageBox: Rect | undefined,\n knobOffset: number,\n geomOf: (id: Id) => Geom,\n view?: ViewEnv,\n): { at: Vec; from: Vec } | null {\n const sel = m.selected.filter((id) => isSelectable(m, id) && m.byId[id].pon === pon);\n if (sel.length === 1) {\n const a = m.byId[sel[0]];\n // No knob for a locked (frozen) annotation — the SAME gate hitTest\n // applies, so the drawn knob is always grabbable and vice versa. A\n // screen-anchored body keeps its knob: rotating edits its AUTHORED tilt\n // (`noRotate` only exempts it from the page's rotation). The obb takes\n // the PROJECTED stroke width (`effStyle`) — with the raw width, the knob\n // drifts off the outline as zoom grows.\n if (!capsFor(a.subtype).rotatable || !annotTransformable(a)) return null;\n const obb = obbFromGeom(geomOf(sel[0]), effStyle(a, view).strokeWidth, a.style.border);\n return obb ? placeRotateKnob(obb.corners, knobOffset, pageBox) : null;\n }\n if (sel.length > 1 && groupCaps(m, sel).rotatable) {\n const union = unionBoundsOf(m, pon, geomOf, view);\n if (union) return placeRotateKnob(boxCorners(union), knobOffset, pageBox);\n }\n return null;\n}\n\n/**\n * The rotate knob for the current selection on `pon` — the SAME knob `chrome`\n * draws — or null when the selection has none (non-rotatable single, or a group\n * whose caps aren't rotatable). A single shape's knob hangs off its OBB top edge;\n * a group's off the union box. With `pageBox` the knob is placed PAGE-BOUND\n * (`placeRotateKnob`: flip below / clamp inside) — off-page it would be visible\n * but unreachable, since pointer dispatch resolves pages by containment. Shared\n * by `chrome` (to draw) and `selectionAnchor` (to push the menu clear of it), so\n * the two can never disagree on where it is.\n *\n * The placement DECISION is made at rest; a gesture never re-decides — it RIDES.\n * During a live rotate the knob starts exactly where it was grabbed (the rest\n * placement on the COMMITTED geometry) and turns rigidly about the pivot by the\n * same snapped delta the shape uses; the policy re-evaluates only on release.\n * Re-deciding per frame would jump at grab and side-switch mid-spin.\n */\nexport function selectionKnob(\n m: Model,\n pon: number,\n pageBox?: Rect,\n knobOffset: number = ROTATE_KNOB_OFFSET,\n view?: ViewEnv,\n): { at: Vec; from: Vec } | null {\n const d = m.draft;\n if (d?.g === 'rotate' && m.byId[d.ids[0]]?.pon === pon) {\n const rest = placeSelectionKnob(\n m,\n pon,\n pageBox,\n knobOffset,\n (id) => anchoredGeom(m.byId[id].geom, anchorModeOf(m.byId[id]), view),\n view,\n );\n if (!rest) return null;\n const { delta } = rotateDraftDelta(m, d);\n return {\n at: rotatePoint(rest.at, d.pivot, delta),\n from: rotatePoint(rest.from, d.pivot, delta),\n };\n }\n return placeSelectionKnob(m, pon, pageBox, knobOffset, (id) => effGeom(m, id, view), view);\n}\n\nexport function chrome(\n m: Model,\n pon: number,\n pageBox?: Rect,\n knobOffset: number = ROTATE_KNOB_OFFSET,\n view?: ViewEnv,\n): ChromeNode[] {\n const nodes: ChromeNode[] = [];\n if (m.draft?.g === 'marquee' && m.draft.pon === pon) {\n nodes.push({ kind: 'marquee', rect: rectFromPoints(m.draft.from, m.draft.to) });\n }\n // Live alignment guides of a snapped move (the gesture lives on ONE page —\n // its members' page).\n if (m.draft?.g === 'move' && m.draft.guides.length && m.byId[m.draft.ids[0]]?.pon === pon) {\n for (const g of m.draft.guides)\n nodes.push({ kind: 'guide', axis: g.axis, at: g.at, lo: g.lo, hi: g.hi });\n }\n // A live rotate on THIS page's selection. While it runs, the chrome switches\n // modes (v2 behaviour): the readout chip + full-bleed guides appear, and the\n // handles/knob are suppressed below — the pointer holds capture, so grab\n // affordances are noise; \"how far am I\" feedback is everything.\n const rd = m.draft?.g === 'rotate' && m.byId[m.draft.ids[0]]?.pon === pon ? m.draft : null;\n if (rd) {\n const { angle } = rotateDraftDelta(m, rd);\n nodes.push({ kind: 'angle-chip', at: rd.cur, angle: Math.round(angle) });\n // Guides as chords of the PAGE through the pivot — the fixed 0°/90°\n // reference cross + the live indicator at the SAME snapped angle the chip\n // shows and the commit applies. Full-bleed beats a magic length constant;\n // no pageBox (headless) → a generous fixed span around the pivot.\n const span = pageBox ?? { x: rd.pivot.x - 300, y: rd.pivot.y - 300, width: 600, height: 600 };\n const lines: Array<{ a: Vec; b: Vec; role: 'axis' | 'indicator' }> = [];\n for (const [deg, role] of [\n [0, 'axis'],\n [90, 'axis'],\n [angle, 'indicator'],\n ] as const) {\n const c = chordThrough(span, rd.pivot, deg);\n if (c) lines.push({ ...c, role });\n }\n nodes.push({ kind: 'rotate-guides', center: rd.pivot, angle, lines });\n }\n const sel = m.selected.filter((id) => isSelectable(m, id) && m.byId[id].pon === pon);\n if (sel.length === 1) {\n const a = m.byId[sel[0]];\n const g = effGeom(m, sel[0], view);\n const style = effStyle(a, view);\n const caps = capsFor(a.subtype);\n const rot = geomRotation(g);\n // Oriented chrome follows the GEOMETRY, not the caps: any tilted kind with\n // an OBB — a caret riding rotated text included — outlines on its tilt.\n // The rotate KNOB stays caps-gated (`placeSelectionKnob` / `hitTest`), so\n // an oriented outline never implies a rotate affordance.\n const obb = obbFromGeom(g, style.strokeWidth, a.style.border);\n if (obb && rot !== 0) {\n nodes.push({ kind: 'obb', corners: obb.corners, angle: obb.angle });\n } else {\n nodes.push({\n kind: 'outline',\n rect: selectionBounds(g, style.strokeWidth, a.style.border),\n });\n }\n // handles for kinds that resize (box) or vertex-edit; anchored/markup show\n // a bare outline — and so do locked (frozen) annotations, the SAME gate\n // hitTest applies. Screen-anchored bodies keep their handles, placed on\n // the PROJECTED geometry (`g`), so they sit exactly where hitTest grabs\n // them. `geomHandles` already places them on the rotated box; `rot`\n // additionally tilts each handle GLYPH so it rides the box's orientation.\n // Suppressed during a live rotate (`rd`) — guides own that mode.\n if (!rd && annotTransformable(a) && (caps.resizable || caps.vertexEditable)) {\n for (const h of geomHandles(g))\n nodes.push({ kind: 'handle', at: h.at, cursor: h.cursor, ...(rot ? { rot } : {}) });\n }\n } else if (sel.length > 1 && !rd) {\n // The LIVE union (draft-effective geometry): the outline and its handles\n // ride a group move/scale exactly like single-selection chrome. During a\n // live rotate the members spin away from any axis-aligned box, so the\n // whole block is suppressed — the guides own that mode.\n const union = unionBoundsOf(m, pon, (id) => effGeom(m, id, view), view);\n if (union) {\n nodes.push({ kind: 'outline', rect: union });\n const gc = groupCaps(m, sel);\n if (gc.resizable) {\n for (const h of rectHandlesFor(union))\n nodes.push({ kind: 'handle', at: h.at, cursor: h.cursor });\n }\n }\n }\n // The rotate knob (single shape or group) — one source of truth with the menu\n // anchor, so the menu is always pushed clear of exactly this point. Hidden\n // while a rotate runs (the gesture holds capture; the guides own the mode).\n if (!rd) {\n const knob = selectionKnob(m, pon, pageBox, knobOffset, view);\n if (knob) nodes.push({ kind: 'rotate-knob', at: knob.at, from: knob.from });\n }\n return nodes;\n}\n\n/** The content-space union of the selectable selected items on `pon`, or null if\n * the page holds none. This is the SAME box the chrome outline draws, so a\n * floating menu sits exactly on the selection. */\nexport function selectionBoundsOnPage(m: Model, pon: number, view?: ViewEnv): Rect | null {\n const sel = m.selected.filter((id) => isSelectable(m, id) && m.byId[id].pon === pon);\n if (sel.length === 0) return null;\n // The rotated AABB: the axis-aligned box that encloses the ORIENTED selection\n // quad. For a tilted shape this tracks the live `rot`, so the upright floating\n // menu floats above the whole tilted shape instead of the (fixed) unrotated box.\n const corners = sel.flatMap((id) =>\n selectionQuad(\n effGeom(m, id, view),\n effStyle(m.byId[id], view).strokeWidth,\n m.byId[id].style.border,\n ),\n );\n return unionRect(corners);\n}\n\n/** The anchor for a selection-aware floating menu: the PRIMARY page (the first\n * selectable selected id) + the union box of the selection on that page (content\n * space). Null when nothing selectable is selected. A cross-page selection\n * anchors to its primary page, so there is exactly one menu. `pageBoxOf` is a\n * lookup (the anchor resolves its own page) feeding the page-bound knob\n * placement — the menu then dodges the knob where it ACTUALLY sits. */\nexport function selectionAnchor(\n m: Model,\n pageBoxOf?: (pon: number) => Rect | undefined,\n knobOffsetOf?: (pon: number) => number | undefined,\n viewOf?: (pon: number) => ViewEnv | undefined,\n): { pon: number; bounds: Rect; knob?: Vec } | null {\n // No menu while a rotate gesture runs (v2 behaviour): the chrome is in\n // guides mode and a floating menu chasing a spinning box is pure noise.\n if (m.draft?.g === 'rotate') return null;\n const id = m.selected.find((x) => isSelectable(m, x));\n if (id == null) return null;\n const pon = m.byId[id].pon;\n const view = viewOf?.(pon);\n const bounds = selectionBoundsOnPage(m, pon, view);\n if (!bounds) return null;\n // `bounds` is the plain selection box (the menu stays centred on it). The knob\n // rides ALONGSIDE it so the menu can nudge ONLY the edge it sits on, and only\n // when the handle would otherwise hide under it — never shifting the centre.\n const knob = selectionKnob(\n m,\n pon,\n pageBoxOf?.(pon),\n knobOffsetOf?.(pon) ?? ROTATE_KNOB_OFFSET,\n view,\n );\n return knob ? { pon, bounds, knob: knob.at } : { pon, bounds };\n}\n\n/** Anchor for controls that finish/cancel an active multi-click creation draft.\n * It is rect-based like selectionAnchor, using the committed vertices only so\n * the menu remains stable while the hover preview follows the pointer. */\nexport function creationDraftAnchor(m: Model): CreationDraftAnchor | null {\n const d = m.draft;\n if (d?.g !== 'create-poly') return null;\n if (!d.points.length) return null;\n const minPoints = d.closed ? 3 : 2;\n return {\n kind: 'poly',\n subtype: d.closed ? 'polygon' : 'polyline',\n pon: d.pon,\n bounds: unionRect(d.points),\n pointCount: d.points.length,\n minPoints,\n canFinish: d.points.length >= minPoints,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["boxCorners","boxCorners","quadCorners","boxCorners","TEXT_FIELDS","NO_ANNOTATION_FLAGS","ANNOTATION_FIELD_NAMES","quadBounds","ORIGIN","DRAWN_RECT_KINDS","UNBAKED_KINDS","unionBoundsOf","ANNOTATION_FIELD_NAMES","STANDARD_FACES","num"],"sources":["../src/rect.ts","../src/cloudy.ts","../src/shapes/box.ts","../src/painted.ts","../src/shapes/caret.ts","../src/endings.ts","../src/shapes/points.ts","../src/shapes/quads.ts","../src/shapes/text-box.ts","../src/shapes/index.ts","../src/kinds/define.ts","../src/kinds/fields.ts","../src/kinds/styles.ts","../src/kinds/caret.ts","../src/kinds/circle.ts","../src/kinds/file-attachment.ts","../src/kinds/texts.ts","../src/kinds/free-text.ts","../src/kinds/highlight.ts","../src/kinds/ink.ts","../src/kinds/line.ts","../src/kinds/link.ts","../src/kinds/polygon.ts","../src/kinds/polyline.ts","../src/kinds/redact.ts","../src/kinds/square.ts","../src/kinds/squiggly.ts","../src/kinds/stamp.ts","../src/kinds/strikeout.ts","../src/kinds/text-note.ts","../src/kinds/underline.ts","../src/kinds/widget.ts","../src/kinds/index.ts","../src/record/identity.ts","../src/flags.ts","../src/editable.ts","../src/plane.ts","../src/geometry.ts","../src/record/values.ts","../src/record/shape.ts","../src/record/style.ts","../src/record/text.ts","../src/record/links.ts","../src/helvetica.ts","../src/measurement-font.ts","../src/measurement.ts","../src/measurement-shape.ts","../src/record/written.ts","../src/record/index.ts","../src/group.ts","../src/anchor.ts","../src/selection.ts","../src/hit.ts","../src/appearance.ts","../src/ink.ts","../src/update/page-bound.ts","../src/placement.ts","../src/record/defaults.ts","../src/update/session.ts","../src/update/changes.ts","../src/update/draw-callout.ts","../src/update/draw-distance.ts","../src/update/draw.ts","../src/snap.ts","../src/update/edit-commit.ts","../src/update/edit.ts","../src/update/marquee.ts","../src/links.ts","../src/props.ts","../src/update/selection-edits.ts","../src/richtext.ts","../src/update/text.ts","../src/update/text-markup.ts","../src/update/index.ts","../src/frame.ts","../src/view.ts","../src/font-css.ts","../src/icons.ts","../src/scene.ts"],"sourcesContent":["/**\n * Plain page-space math: rect corners, the eight resize handles, resizing\n * (upright or turned about the middle), turning points about a pivot, and\n * point-in-polygon. No annotation kinds: the shape families and\n * `geometry.ts` share it.\n */\nimport { applyPoint, rotateAbout, type Mat2D, type PointIn } from '@embedpdf/core-geometry';\nimport type { Cursor, Point, Rect } from './types';\n\nexport const MIN_SIZE = 4;\n\n/* ── rect handles ─────────────────────────────────────────────────────────── */\n\nexport type RectHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';\nexport const RECT_HANDLES: RectHandle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\nexport const RECT_CURSOR: Record<RectHandle, Cursor> = {\n nw: 'nwse-resize',\n se: 'nwse-resize',\n ne: 'nesw-resize',\n sw: 'nesw-resize',\n n: 'ns-resize',\n s: 'ns-resize',\n e: 'ew-resize',\n w: 'ew-resize',\n};\n/** Each handle's compass direction (deg CW from north) on the unrotated box. */\nconst HANDLE_BASE_ANGLE: Record<RectHandle, number> = {\n n: 0,\n ne: 45,\n e: 90,\n se: 135,\n s: 180,\n sw: 225,\n w: 270,\n nw: 315,\n};\n/** The resize cursor per 45° compass sector (index = sector, 0 = north). */\nconst SECTOR_CURSORS: Cursor[] = [\n 'ns-resize',\n 'nesw-resize',\n 'ew-resize',\n 'nwse-resize',\n 'ns-resize',\n 'nesw-resize',\n 'ew-resize',\n 'nwse-resize',\n];\n/** The resize cursor for a handle on a box tilted by `rot` deg: rotate the\n * handle's compass direction with the box and pick the nearest 45° sector.\n * At `rot = 0` this reproduces {@link RECT_CURSOR} exactly. */\nexport const rotatedHandleCursor = (handle: RectHandle, rot: number): Cursor =>\n SECTOR_CURSORS[Math.round(normalizeDeg(HANDLE_BASE_ANGLE[handle] + rot) / 45) % 8];\n/**\n * A resize cursor as it points on screen, on a page shown turned `rotation`\n * degrees clockwise (its display rotation): handles sit in page space, but\n * the cursor follows what the user sees. Any other cursor stays as it is.\n */\nexport function cursorOnScreen(cursor: Cursor, rotation: number): Cursor {\n const sector = SECTOR_CURSORS.indexOf(cursor);\n if (sector < 0) return cursor;\n return SECTOR_CURSORS[(sector + Math.round(normalizeDeg(rotation) / 45)) % 8]!;\n}\nconst rectEdges = (handle: RectHandle) => ({\n w: handle === 'nw' || handle === 'w' || handle === 'sw',\n e: handle === 'ne' || handle === 'e' || handle === 'se',\n n: handle === 'nw' || handle === 'n' || handle === 'ne',\n s: handle === 'sw' || handle === 's' || handle === 'se',\n});\nexport const rectHandlePoint = (rect: Rect, handle: RectHandle): Point => {\n const edges = rectEdges(handle);\n return {\n x: edges.w ? rect.x : edges.e ? rect.x + rect.width : rect.x + rect.width / 2,\n y: edges.n ? rect.y : edges.s ? rect.y + rect.height : rect.y + rect.height / 2,\n };\n};\nexport function resizeRect(base: Rect, handle: RectHandle, to: Point): Rect {\n const edges = rectEdges(handle);\n let left = base.x;\n let right = base.x + base.width;\n let top = base.y;\n let bottom = base.y + base.height;\n if (edges.w) left = to.x;\n if (edges.e) right = to.x;\n if (edges.n) top = to.y;\n if (edges.s) bottom = to.y;\n return {\n x: Math.min(left, right),\n y: Math.min(top, bottom),\n width: Math.max(MIN_SIZE, Math.abs(right - left)),\n height: Math.max(MIN_SIZE, Math.abs(bottom - top)),\n };\n}\n\n/* ── small math ───────────────────────────────────────────────────────────── */\n\nexport const rectFromPoints = (from: Point, to: Point): Rect => ({\n x: Math.min(from.x, to.x),\n y: Math.min(from.y, to.y),\n width: Math.abs(to.x - from.x),\n height: Math.abs(to.y - from.y),\n});\nexport const rectsIntersect = (left: Rect, right: Rect): boolean =>\n left.x <= right.x + right.width &&\n left.x + left.width >= right.x &&\n left.y <= right.y + right.height &&\n left.y + left.height >= right.y;\nexport const rectContains = (rect: Rect, point: Point): boolean =>\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height;\n\n/** Distance from point p to segment ab. */\nexport function segDist(point: Point, from: Point, to: Point): number {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len2 = dx * dx + dy * dy;\n const fraction =\n len2 === 0\n ? 0\n : Math.max(0, Math.min(1, ((point.x - from.x) * dx + (point.y - from.y) * dy) / len2));\n return Math.hypot(point.x - (from.x + fraction * dx), point.y - (from.y + fraction * dy));\n}\n/** Distance from `point` to the rect: 0 on or inside it. */\nexport function pointRectDistance(point: Point, rect: Rect): number {\n const dx = Math.max(rect.x - point.x, 0, point.x - (rect.x + rect.width));\n const dy = Math.max(rect.y - point.y, 0, point.y - (rect.y + rect.height));\n return Math.hypot(dx, dy);\n}\n\n/** Does the segment from `from` to `to` pass through the rect (edges included)? Clipped Liang–Barsky style. */\nexport function segmentCrossesRect(from: Point, to: Point, rect: Rect): boolean {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n // Each side as `step * t <= room`: the part of the segment on the rect's side of it.\n const sides: [step: number, room: number][] = [\n [-dx, from.x - rect.x],\n [dx, rect.x + rect.width - from.x],\n [-dy, from.y - rect.y],\n [dy, rect.y + rect.height - from.y],\n ];\n let enter = 0;\n let leave = 1;\n for (const [step, room] of sides) {\n if (step === 0) {\n if (room < 0) return false;\n continue;\n }\n const t = room / step;\n if (step < 0) enter = Math.max(enter, t);\n else leave = Math.min(leave, t);\n if (enter > leave) return false;\n }\n return true;\n}\n\n/** Distance from the segment to the rect: 0 when it passes through it. */\nexport function segmentRectDistance(from: Point, to: Point, rect: Rect): number {\n if (segmentCrossesRect(from, to, rect)) return 0;\n // Two convex shapes apart are nearest at an end of one or a corner of the other.\n return Math.min(\n pointRectDistance(from, rect),\n pointRectDistance(to, rect),\n ...rectCornerPoints(rect).map((corner) => segDist(corner, from, to)),\n );\n}\n\n/**\n * Does the polygon (even-odd, as {@link pointInPoly} reads it) touch the rect:\n * overlap it, hold it, or meet its edge?\n */\nexport function polygonTouchesRect(ring: readonly Point[], rect: Rect): boolean {\n if (ring.some((vertex) => rectContains(rect, vertex))) return true;\n if (pointInPoly({ x: rect.x, y: rect.y }, ring)) return true;\n return ring.some((vertex, i) => segmentCrossesRect(vertex, ring[(i + 1) % ring.length]!, rect));\n}\n\n/** Even-odd point-in-polygon. */\nexport function pointInPoly(point: Point, points: readonly Point[]): boolean {\n let inside = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n const vertex = points[i];\n const previousVertex = points[j];\n if (\n vertex.y > point.y !== previousVertex.y > point.y &&\n point.x <\n ((previousVertex.x - vertex.x) * (point.y - vertex.y)) / (previousVertex.y - vertex.y) +\n vertex.x\n )\n inside = !inside;\n }\n return inside;\n}\n\nexport function unionRect(points: Point[]): Rect {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const point of points) {\n x0 = Math.min(x0, point.x);\n y0 = Math.min(y0, point.y);\n x1 = Math.max(x1, point.x);\n y1 = Math.max(y1, point.y);\n }\n return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };\n}\n\nexport const expandRect = (rect: Rect, pad: number): Rect => ({\n x: rect.x - pad,\n y: rect.y - pad,\n width: rect.width + 2 * pad,\n height: rect.height + 2 * pad,\n});\n\nexport const rectCornerPoints = (rect: Rect): Point[] => [\n { x: rect.x, y: rect.y },\n { x: rect.x + rect.width, y: rect.y },\n { x: rect.x + rect.width, y: rect.y + rect.height },\n { x: rect.x, y: rect.y + rect.height },\n];\n\nexport const DEG2RAD = Math.PI / 180;\n\n/** Normalize degrees into `[0, 360)`. */\nexport const normalizeDeg = (degrees: number): number => ((degrees % 360) + 360) % 360;\n\nexport const rectCenter = (rect: Rect): Point => ({\n x: rect.x + rect.width / 2,\n y: rect.y + rect.height / 2,\n});\n\n/** `rect` with width↔height swapped about its own centre — the unrotated box\n * whose quarter-turn AABB is exactly `rect` again. */\nexport function transposedAboutCenter(rect: Rect): Rect {\n const point = rectCenter(rect);\n return {\n x: point.x - rect.height / 2,\n y: point.y - rect.width / 2,\n width: rect.height,\n height: rect.width,\n };\n}\n\nconst rotateAboutM = (pivot: Point, deg: number): Mat2D<'page', 'page'> =>\n rotateAbout(pivot as PointIn<'page'>, deg * DEG2RAD);\n\n/** Rotate one point about a pivot by `deg` (CW, page space). */\nexport const rotatePoint = (point: Point, pivot: Point, deg: number): Point =>\n applyPoint(rotateAboutM(pivot, deg), point as PointIn<'page'>);\n\n/** The AABB of `rect` rotated `deg` about `pivot` (its own centre unless given). */\nexport function rotatedAabb(rect: Rect, deg: number, pivot: Point = rectCenter(rect)): Rect {\n if (!deg) return rect;\n return unionRect(rectCornerPoints(rect).map((corner) => rotatePoint(corner, pivot, deg)));\n}\n\n/** Shrink a rect inward by `pad` on every side, staying centred and never\n * collapsing past zero (a thick stroke on a tiny shape just yields a 0-extent\n * path rather than an inverted one). The inverse of `expandRect` for shapes. */\nexport const insetRect = (rect: Rect, pad: number): Rect => {\n const width = Math.max(0, rect.width - 2 * pad);\n const height = Math.max(0, rect.height - 2 * pad);\n return {\n x: rect.x + (rect.width - width) / 2,\n y: rect.y + (rect.height - height) / 2,\n width,\n height,\n };\n};\n\nexport const OPPOSITE_HANDLE: Record<RectHandle, RectHandle> = {\n nw: 'se',\n ne: 'sw',\n se: 'nw',\n sw: 'ne',\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\n/**\n * Resize a rotated box by `handle`, keeping the opposite corner/edge fixed in\n * world space. The pointer is mapped into the box's local (unrotated) frame, the\n * axis-aligned `resizeRect` runs there, then the new box is repositioned so the\n * anchor (the opposite handle's point) lands back where it was — and the box\n * still rotates about its own centre. With `rot === 0` this is exactly the plain\n * `resizeRect`.\n */\nexport function resizeRotatedRect(base: Rect, rot: number, handle: RectHandle, to: Point): Rect {\n if (!rot) return resizeRect(base, handle, to);\n const c0 = rectCenter(base);\n const localTo = rotatePoint(to, c0, -rot);\n const next = resizeRect(base, handle, localTo);\n const anchorLocal = rectHandlePoint(base, OPPOSITE_HANDLE[handle]);\n const anchorWorld = rotatePoint(anchorLocal, c0, rot);\n const nextCenterLocal = rectCenter(next);\n // offset of the anchor from the new centre, in the local frame; rotate it to\n // world orientation and place the new centre so the anchor stays put.\n const offX = anchorLocal.x - nextCenterLocal.x;\n const offY = anchorLocal.y - nextCenterLocal.y;\n const rad = rot * DEG2RAD;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const rOffX = cos * offX - sin * offY;\n const rOffY = sin * offX + cos * offY;\n const cx = anchorWorld.x - rOffX;\n const cy = anchorWorld.y - rOffY;\n return {\n x: cx - next.width / 2,\n y: cy - next.height / 2,\n width: next.width,\n height: next.height,\n };\n}\n","/**\n * Cloudy-border (scalloped outline) path generation for shape annotations.\n *\n * Derived from Apache PDFBox's CloudyBorder.java (Apache-2.0):\n * https://github.com/apache/pdfbox — the arc/curl placement is theirs, and we\n * keep it because it visually matches what PDFium bakes into the `/BE` appearance\n * stream, so our live SVG preview and the saved PDF agree.\n *\n * These are pure functions. They take a page-space box (or a polygon) plus\n * the border `intensity`/`strokeWidth`, and give the cloud's curves as SVG\n * path data in absolute content coordinates (the same space `geomScene`'s\n * rect/ellipse nodes use), or the box around what those curves paint. The\n * scallops start on the shape's box and reach out from it, as the engine\n * draws them.\n *\n * The internal math runs in PDFBox's y-up frame; a `CurveSink` flips back to\n * y-down and translates into the box's page-space origin on the way out.\n */\nimport { expandRect } from './rect';\nimport type { Rect, Point } from './types';\n\nconst ANGLE_180 = Math.PI;\nconst ANGLE_90 = Math.PI / 2;\nconst ANGLE_34 = (34 * Math.PI) / 180;\nconst ANGLE_30 = (30 * Math.PI) / 180;\nconst ANGLE_12 = (12 * Math.PI) / 180;\n\ninterface P {\n x: number;\n y: number;\n}\n\nconst formatNumber = (value: number): string => Number(value.toFixed(4)).toString();\n\n/**\n * Where the cloud's curves go: an SVG path (`PathBuilder`), their bounds\n * (`CurveBounds`), or the points along them (`CurvePolylines`).\n */\ninterface CurveSink {\n moveTo(x: number, y: number): void;\n curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void;\n}\n\n/**\n * Accumulates SVG path commands. Input is PDFBox's y-up frame; output is y-down\n * page space, offset into the box origin (ox, oy) so the `d` string is in the\n * same absolute coordinates as every other render node.\n */\nclass PathBuilder implements CurveSink {\n private parts: string[] = [];\n private started = false;\n constructor(\n private ox: number,\n private oy: number,\n ) {}\n moveTo(x: number, y: number): void {\n this.parts.push(`M ${formatNumber(x + this.ox)} ${formatNumber(-y + this.oy)}`);\n this.started = true;\n }\n curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void {\n this.parts.push(\n `C ${formatNumber(x1 + this.ox)} ${formatNumber(-y1 + this.oy)}, ${formatNumber(x2 + this.ox)} ${formatNumber(-y2 + this.oy)}, ${formatNumber(x3 + this.ox)} ${formatNumber(-y3 + this.oy)}`,\n );\n }\n close(): void {\n if (this.started) this.parts.push('Z');\n }\n build(): string {\n return this.parts.join(' ');\n }\n}\n\n/** The point at `t` on the cubic Bézier `p0..p3`. */\nfunction bezierAt(p0: P, p1: P, p2: P, p3: P, t: number): P {\n const rest = 1 - t;\n const weights = [rest * rest * rest, 3 * rest * rest * t, 3 * rest * t * t, t * t * t];\n return {\n x: weights[0]! * p0.x + weights[1]! * p1.x + weights[2]! * p2.x + weights[3]! * p3.x,\n y: weights[0]! * p0.y + weights[1]! * p1.y + weights[2]! * p2.y + weights[3]! * p3.y,\n };\n}\n\n/** Where a cubic Bézier coordinate `p0..p3` turns: the parameters in (0, 1) where its slope is zero. */\nfunction turnsOf(p0: number, p1: number, p2: number, p3: number): number[] {\n const a = -p0 + 3 * p1 - 3 * p2 + p3;\n const b = 2 * (p0 - 2 * p1 + p2);\n const c = p1 - p0;\n const roots =\n Math.abs(a) < 1e-12\n ? Math.abs(b) < 1e-12\n ? []\n : [-c / b]\n : b * b - 4 * a * c < 0\n ? []\n : [\n (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a),\n (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a),\n ];\n return roots.filter((t) => t > 0 && t < 1);\n}\n\n/**\n * The box around the curves themselves (not their control points), in the\n * same page space as `PathBuilder`'s path.\n */\nclass CurveBounds implements CurveSink {\n private left = Infinity;\n private top = Infinity;\n private right = -Infinity;\n private bottom = -Infinity;\n private current: P = { x: 0, y: 0 };\n constructor(\n private ox: number,\n private oy: number,\n ) {}\n private add(point: P): void {\n this.left = Math.min(this.left, point.x);\n this.right = Math.max(this.right, point.x);\n this.top = Math.min(this.top, point.y);\n this.bottom = Math.max(this.bottom, point.y);\n }\n private place(x: number, y: number): P {\n return { x: x + this.ox, y: -y + this.oy };\n }\n moveTo(x: number, y: number): void {\n this.current = this.place(x, y);\n this.add(this.current);\n }\n curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void {\n const p0 = this.current;\n const p1 = this.place(x1, y1);\n const p2 = this.place(x2, y2);\n const p3 = this.place(x3, y3);\n for (const t of [...turnsOf(p0.x, p1.x, p2.x, p3.x), ...turnsOf(p0.y, p1.y, p2.y, p3.y)]) {\n this.add(bezierAt(p0, p1, p2, p3, t));\n }\n this.add(p3);\n this.current = p3;\n }\n bounds(): Rect {\n return {\n x: this.left,\n y: this.top,\n width: this.right - this.left,\n height: this.bottom - this.top,\n };\n }\n}\n\n/**\n * Chord length the curves are split into, in page units: a curl of radius r\n * then strays at most 0.5² / 8r from its chords, under 0.02 for any curl a\n * cloud draws.\n */\nconst FLATTEN_STEP = 0.5;\n\n/**\n * The curves as polylines, one per subpath, in the same page space as\n * `PathBuilder`'s path: each cubic split into chords of about\n * {@link FLATTEN_STEP}. Hit-testing and the marquee read the cloud from these.\n */\nclass CurvePolylines implements CurveSink {\n readonly lines: Point[][] = [];\n private current: P = { x: 0, y: 0 };\n constructor(\n private ox: number,\n private oy: number,\n ) {}\n private place(x: number, y: number): P {\n return { x: x + this.ox, y: -y + this.oy };\n }\n moveTo(x: number, y: number): void {\n this.current = this.place(x, y);\n this.lines.push([this.current]);\n }\n curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void {\n const p0 = this.current;\n const p1 = this.place(x1, y1);\n const p2 = this.place(x2, y2);\n const p3 = this.place(x3, y3);\n // The control polygon is never shorter than the curve.\n const hull = distance(p0, p1) + distance(p1, p2) + distance(p2, p3);\n const steps = Math.max(2, Math.ceil(hull / FLATTEN_STEP));\n let line = this.lines[this.lines.length - 1];\n if (!line) this.lines.push((line = [p0]));\n for (let i = 1; i <= steps; i++) line.push(bezierAt(p0, p1, p2, p3, i / steps));\n this.current = p3;\n }\n}\n\n/* ── geometry helpers ─────────────────────────────────────────────────────── */\n\nconst distance = (left: P, right: P): number => Math.hypot(right.x - left.x, right.y - left.y);\nconst cosine = (dx: number, hyp: number): number => (hyp === 0 ? 0 : dx / hyp);\nconst sine = (dy: number, hyp: number): number => (hyp === 0 ? 0 : dy / hyp);\n\n/** Signed area (shoelace): positive = counter-clockwise. */\nfunction polygonDirection(points: P[]): number {\n let area = 0;\n for (let i = 0; i < points.length; i++) {\n const j = (i + 1) % points.length;\n area += points[i].x * points[j].y - points[i].y * points[j].x;\n }\n return area;\n}\nfunction ensurePositiveWinding(points: P[]): void {\n if (polygonDirection(points) < 0) points.reverse();\n}\nfunction removeZeroLengthSegments(polygon: P[]): P[] {\n if (polygon.length <= 2) return polygon;\n const tol = 0.5;\n const out: P[] = [polygon[0]];\n for (let i = 1; i < polygon.length; i++) {\n const previous = out[out.length - 1];\n const current = polygon[i];\n if (Math.abs(current.x - previous.x) >= tol || Math.abs(current.y - previous.y) >= tol)\n out.push(current);\n }\n return out;\n}\n\n/* ── elliptical-arc Bézier approximation ──────────────────────────────────── */\n\nfunction arcSegment(\n startAng: number,\n endAng: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n out: CurveSink,\n addMoveTo: boolean,\n): void {\n const cosA = Math.cos(startAng);\n const sinA = Math.sin(startAng);\n const cosB = Math.cos(endAng);\n const sinB = Math.sin(endAng);\n const denom = Math.sin((endAng - startAng) / 2);\n if (denom === 0) {\n if (addMoveTo) out.moveTo(cx + rx * cosA, cy + ry * sinA);\n return;\n }\n const bcp = ((4 / 3) * (1 - Math.cos((endAng - startAng) / 2))) / denom;\n if (addMoveTo) out.moveTo(cx + rx * cosA, cy + ry * sinA);\n out.curveTo(\n cx + rx * (cosA - bcp * sinA),\n cy + ry * (sinA + bcp * cosA),\n cx + rx * (cosB + bcp * sinB),\n cy + ry * (sinB - bcp * cosB),\n cx + rx * cosB,\n cy + ry * sinB,\n );\n}\n\nfunction arcSegmentToArray(startAng: number, endAng: number, rx: number, ry: number): P[] {\n const cosA = Math.cos(startAng);\n const sinA = Math.sin(startAng);\n const cosB = Math.cos(endAng);\n const sinB = Math.sin(endAng);\n const denom = Math.sin((endAng - startAng) / 2);\n if (denom === 0) return [];\n const bcp = ((4 / 3) * (1 - Math.cos((endAng - startAng) / 2))) / denom;\n return [\n { x: rx * (cosA - bcp * sinA), y: ry * (sinA + bcp * cosA) },\n { x: rx * (cosB + bcp * sinB), y: ry * (sinB - bcp * cosB) },\n { x: rx * cosB, y: ry * sinB },\n ];\n}\n\nfunction getArc(\n startAng: number,\n endAng: number,\n rx: number,\n ry: number,\n cx: number,\n cy: number,\n out: CurveSink,\n addMoveTo: boolean,\n): void {\n let angleTodo = endAng - startAng;\n while (angleTodo < 0) angleTodo += 2 * Math.PI;\n const sweep = angleTodo;\n let angleDone = 0;\n if (addMoveTo) out.moveTo(cx + rx * Math.cos(startAng), cy + ry * Math.sin(startAng));\n while (angleTodo > ANGLE_90) {\n arcSegment(startAng + angleDone, startAng + angleDone + ANGLE_90, cx, cy, rx, ry, out, false);\n angleDone += ANGLE_90;\n angleTodo -= ANGLE_90;\n }\n if (angleTodo > 0) arcSegment(startAng + angleDone, startAng + sweep, cx, cy, rx, ry, out, false);\n}\n\n/* ── curls ─────────────────────────────────────────────────────────────────── */\n\nfunction addCornerCurl(\n anglePrev: number,\n angleCur: number,\n radius: number,\n cx: number,\n cy: number,\n alpha: number,\n alphaPrev: number,\n out: CurveSink,\n addMoveTo: boolean,\n): void {\n const startAngle = anglePrev + ANGLE_180 + alphaPrev;\n const joinAngle = startAngle - (22 * Math.PI) / 180;\n arcSegment(startAngle, joinAngle, cx, cy, radius, radius, out, addMoveTo);\n getArc(joinAngle, angleCur - alpha, radius, radius, cx, cy, out, false);\n}\n\nfunction addFirstIntermediateCurl(\n angleCur: number,\n rad: number,\n alpha: number,\n cx: number,\n cy: number,\n out: CurveSink,\n): void {\n const backAngle = angleCur + ANGLE_180;\n arcSegment(backAngle + alpha, backAngle + alpha - ANGLE_30, cx, cy, rad, rad, out, false);\n arcSegment(backAngle + alpha - ANGLE_30, backAngle + ANGLE_90, cx, cy, rad, rad, out, false);\n arcSegment(backAngle + ANGLE_90, backAngle + ANGLE_180 - ANGLE_34, cx, cy, rad, rad, out, false);\n}\n\nfunction intermediateCurlTemplate(angleCur: number, rad: number): P[] {\n const backAngle = angleCur + ANGLE_180;\n return [\n ...arcSegmentToArray(backAngle + ANGLE_34, backAngle + ANGLE_12, rad, rad),\n ...arcSegmentToArray(backAngle + ANGLE_12, backAngle + ANGLE_90, rad, rad),\n ...arcSegmentToArray(backAngle + ANGLE_90, backAngle + ANGLE_180 - ANGLE_34, rad, rad),\n ];\n}\nfunction outputCurlTemplate(template: P[], x: number, y: number, out: CurveSink): void {\n for (let i = 0; i + 2 < template.length; i += 3) {\n out.curveTo(\n template[i].x + x,\n template[i].y + y,\n template[i + 1].x + x,\n template[i + 1].y + y,\n template[i + 2].x + x,\n template[i + 2].y + y,\n );\n }\n}\n\n/* ── cloud radius (PDFBox constants, deduced from Acrobat) ─────────────────── */\n\nconst ellipseCloudRadius = (intensity: number, lineWidth: number): number =>\n 4.75 * intensity + 0.5 * lineWidth;\nconst polygonCloudRadius = (intensity: number, lineWidth: number): number =>\n 4 * intensity + 0.5 * lineWidth;\n\n/* ── polygon core ──────────────────────────────────────────────────────────── */\n\nfunction computeParamsPolygon(\n idealRadius: number,\n curlFactor: number,\n length: number,\n): { n: number; adjustedRadius: number } {\n if (length === 0) return { n: -1, adjustedRadius: idealRadius };\n const remaining = length - 2 * curlFactor * idealRadius;\n if (remaining <= 0) return { n: 0, adjustedRadius: idealRadius };\n const curlCount = Math.max(1, Math.ceil(remaining / (2 * curlFactor * idealRadius)));\n return { n: curlCount, adjustedRadius: remaining / (curlCount * 2 * curlFactor) };\n}\n\nfunction cloudyPolygonImpl(\n vertices: P[],\n isEllipse: boolean,\n intensity: number,\n lineWidth: number,\n out: CurveSink,\n): void {\n const polygon = removeZeroLengthSegments(vertices);\n ensurePositiveWinding(polygon);\n const vertexCount = polygon.length;\n if (vertexCount < 2) return;\n\n if (intensity <= 0) {\n out.moveTo(polygon[0].x, polygon[0].y);\n for (let i = 1; i < vertexCount; i++)\n out.curveTo(\n polygon[i].x,\n polygon[i].y,\n polygon[i].x,\n polygon[i].y,\n polygon[i].x,\n polygon[i].y,\n );\n return;\n }\n\n let idealRadius = isEllipse\n ? ellipseCloudRadius(intensity, lineWidth)\n : polygonCloudRadius(intensity, lineWidth);\n if (idealRadius < 0.5) idealRadius = 0.5;\n const curlFactor = Math.cos(ANGLE_34);\n\n const edgeAlphas: number[] = [];\n for (let j = 0; j + 1 < vertexCount; j++) {\n const len = distance(polygon[j], polygon[j + 1]);\n edgeAlphas.push(\n len <= 0 || len >= 2 * curlFactor * idealRadius\n ? ANGLE_34\n : Math.acos(Math.min(1, len / (2 * idealRadius))),\n );\n }\n\n let anglePrev = 0;\n let started = false;\n for (let j = 0; j + 1 < vertexCount; j++) {\n const pt = polygon[j];\n const ptNext = polygon[j + 1];\n const len = distance(pt, ptNext);\n if (len === 0) continue;\n\n const params = computeParamsPolygon(idealRadius, curlFactor, len);\n if (params.n < 0) {\n if (!started) {\n out.moveTo(pt.x, pt.y);\n started = true;\n }\n continue;\n }\n\n const edgeRadius = Math.max(0.5, params.adjustedRadius);\n const intermAdvance = 2 * curlFactor * edgeRadius;\n const firstAdvance = curlFactor * idealRadius + curlFactor * edgeRadius;\n const angleCur = Math.atan2(ptNext.y - pt.y, ptNext.x - pt.x);\n if (j === 0) {\n const ptPrev = polygon[vertexCount - 2];\n anglePrev = Math.atan2(pt.y - ptPrev.y, pt.x - ptPrev.x);\n }\n const cos = cosine(ptNext.x - pt.x, len);\n const sin = sine(ptNext.y - pt.y, len);\n let x = pt.x;\n let y = pt.y;\n const alpha = edgeAlphas[j];\n const alphaPrev = edgeAlphas[j === 0 ? vertexCount - 2 : j - 1] ?? ANGLE_34;\n\n addCornerCurl(anglePrev, angleCur, idealRadius, pt.x, pt.y, alpha, alphaPrev, out, !started);\n started = true;\n\n if (params.n === 0) {\n x += len * cos;\n y += len * sin;\n } else {\n x += firstAdvance * cos;\n y += firstAdvance * sin;\n let numInterm = params.n;\n if (params.n >= 1) {\n addFirstIntermediateCurl(angleCur, edgeRadius, ANGLE_34, x, y, out);\n x += intermAdvance * cos;\n y += intermAdvance * sin;\n numInterm = params.n - 1;\n }\n const template = intermediateCurlTemplate(angleCur, edgeRadius);\n for (let i = 0; i < numInterm; i++) {\n outputCurlTemplate(template, x, y, out);\n x += intermAdvance * cos;\n y += intermAdvance * sin;\n }\n }\n anglePrev = angleCur;\n }\n}\n\n/* ── ellipse core ──────────────────────────────────────────────────────────── */\n\nfunction flattenEllipse(left: number, bottom: number, right: number, top: number): P[] {\n const cx = (left + right) / 2;\n const cy = (bottom + top) / 2;\n const rx = (right - left) / 2;\n const ry = (top - bottom) / 2;\n if (rx <= 0 || ry <= 0) return [];\n const segments = Math.max(32, Math.ceil(Math.max(rx, ry) * 2));\n const points: P[] = [];\n for (let i = 0; i <= segments; i++) {\n const angle = (2 * Math.PI * i) / segments;\n points.push({ x: cx + rx * Math.cos(angle), y: cy + ry * Math.sin(angle) });\n }\n return points;\n}\n\nfunction computeParamsEllipse(pt: P, ptNext: P, rad: number, curlAdv: number): number {\n const len = distance(pt, ptNext);\n if (len === 0) return ANGLE_34;\n const arg = (curlAdv / 2 + (len - curlAdv) / 2) / rad;\n return arg < -1 || arg > 1 ? 0 : Math.acos(arg);\n}\n\nfunction cloudyEllipseImpl(\n left: number,\n bottom: number,\n right: number,\n top: number,\n intensity: number,\n lineWidth: number,\n out: CurveSink,\n): void {\n const plainEllipse = () => {\n const rx = Math.abs(right - left) / 2;\n const ry = Math.abs(top - bottom) / 2;\n getArc(0, 2 * Math.PI, rx, ry, (left + right) / 2, (bottom + top) / 2, out, true);\n };\n\n if (intensity <= 0) return plainEllipse();\n\n const width = right - left;\n const height = top - bottom;\n let cloudRadius = ellipseCloudRadius(intensity, lineWidth);\n\n if (width < 0.5 * cloudRadius && height < 0.5 * cloudRadius) return plainEllipse();\n\n // very long & thin → treat as a rectangle so the scallops read correctly\n if ((width < 5 && height > 20) || (width > 20 && height < 5)) {\n return cloudyPolygonImpl(\n [\n { x: left, y: bottom },\n { x: right, y: bottom },\n { x: right, y: top },\n { x: left, y: top },\n { x: left, y: bottom },\n ],\n true,\n intensity,\n lineWidth,\n out,\n );\n }\n\n // shrink so the cloud tails touch the original outline\n const radiusAdj = Math.sin(ANGLE_12) * cloudRadius - 1.5;\n let adjLeft = left;\n let adjRight = right;\n let adjBottom = bottom;\n let adjTop = top;\n if (width > 2 * radiusAdj) {\n adjLeft += radiusAdj;\n adjRight -= radiusAdj;\n } else {\n const mid = (left + right) / 2;\n adjLeft = mid - 0.1;\n adjRight = mid + 0.1;\n }\n if (height > 2 * radiusAdj) {\n adjBottom += radiusAdj;\n adjTop -= radiusAdj;\n } else {\n const mid = (top + bottom) / 2;\n adjTop = mid + 0.1;\n adjBottom = mid - 0.1;\n }\n\n const flat = flattenEllipse(adjLeft, adjBottom, adjRight, adjTop);\n if (flat.length < 2) return;\n let totLen = 0;\n for (let i = 1; i < flat.length; i++) totLen += distance(flat[i - 1], flat[i]);\n\n const curlFactor = Math.cos(ANGLE_34);\n let curlCount = Math.ceil(totLen / (2 * curlFactor * cloudRadius));\n if (curlCount < 2) return plainEllipse();\n\n let curlAdvance = totLen / curlCount;\n cloudRadius = curlAdvance / (2 * curlFactor);\n if (cloudRadius < 0.5) {\n cloudRadius = 0.5;\n curlAdvance = 2 * curlFactor * cloudRadius;\n } else if (cloudRadius < 3.0) {\n return plainEllipse();\n }\n\n // distribute curl centers along the flattened perimeter\n const centers: P[] = [];\n let remain = 0;\n const toler = lineWidth * 0.1;\n for (let i = 0; i + 1 < flat.length; i++) {\n const p1 = flat[i];\n const p2 = flat[i + 1];\n const segLen = distance(p1, p2);\n if (segLen === 0) continue;\n let todo = segLen + remain;\n if (todo >= curlAdvance - toler || i === flat.length - 2) {\n const cos = cosine(p2.x - p1.x, segLen);\n const sin = sine(p2.y - p1.y, segLen);\n let offset = curlAdvance - remain;\n while (todo >= curlAdvance - toler) {\n centers.push({ x: p1.x + offset * cos, y: p1.y + offset * sin });\n todo -= curlAdvance;\n offset += curlAdvance;\n }\n remain = Math.max(0, todo);\n } else {\n remain += segLen;\n }\n }\n\n const centerCount = centers.length;\n let anglePrev = 0;\n let alphaPrev = 0;\n for (let i = 0; i < centerCount; i++) {\n const pt = centers[i];\n const ptNext = centers[(i + 1) % centerCount];\n if (i === 0) {\n const ptPrev = centers[centerCount - 1];\n anglePrev = Math.atan2(pt.y - ptPrev.y, pt.x - ptPrev.x);\n alphaPrev = computeParamsEllipse(ptPrev, pt, cloudRadius, curlAdvance);\n }\n const angleCur = Math.atan2(ptNext.y - pt.y, ptNext.x - pt.x);\n const alpha = computeParamsEllipse(pt, ptNext, cloudRadius, curlAdvance);\n addCornerCurl(anglePrev, angleCur, cloudRadius, pt.x, pt.y, alpha, alphaPrev, out, i === 0);\n anglePrev = angleCur;\n alphaPrev = alpha;\n }\n}\n\n/* ── public API ────────────────────────────────────────────────────────────── */\n\n/** The cloud of a closed polygon, its curves into `out`. */\nfunction polygonCloud(\n points: Point[],\n intensity: number,\n strokeWidth: number,\n out: CurveSink,\n): void {\n // Page space is y-down; the PDFBox core runs y-up (the sink flips back).\n const ring = points.map((point) => ({ x: point.x, y: -point.y }));\n const first = ring[0];\n const last = ring[ring.length - 1];\n // The impl walks edges of a closed ring (first vertex repeated at the end).\n if (first && (first.x !== last.x || first.y !== last.y)) ring.push({ ...first });\n cloudyPolygonImpl(ring, false, intensity, strokeWidth, out);\n}\n\n/** The cloud of a square's (rect) or circle's (ellipse) `box`, its curves into `out`. */\nfunction boxCloud(\n box: Rect,\n ellipse: boolean,\n intensity: number,\n strokeWidth: number,\n out: CurveSink,\n): void {\n const right = box.width;\n const bottom = box.height;\n if (ellipse) {\n cloudyEllipseImpl(0, -bottom, right, 0, intensity, strokeWidth, out);\n } else {\n cloudyPolygonImpl(\n [\n { x: 0, y: 0 },\n { x: right, y: 0 },\n { x: right, y: -bottom },\n { x: 0, y: -bottom },\n { x: 0, y: 0 },\n ],\n false,\n intensity,\n strokeWidth,\n out,\n );\n }\n}\n\n/**\n * SVG path data for a cloudy polygon border, in absolute content coordinates.\n * A polygon's curls are centred on the vertex path and reach outward by the\n * cloud radius, the same rule PDFium's `GenerateCloudyPolygonPath` bakes into\n * the /AP, so the live drawing and the saved appearance agree.\n *\n * Stroke it with round joins: the curl tails reverse direction by design, and\n * `scene()` sets `join: 'round'` to match PDFium's `1 j`; a miter join turns\n * every seam into a spike.\n */\nexport function cloudyPolyPath(points: Point[], intensity: number, strokeWidth: number): string {\n const out = new PathBuilder(0, 0);\n polygonCloud(points, intensity, strokeWidth, out);\n out.close();\n return out.build();\n}\n\n/**\n * SVG path data for a cloudy square (rect) or circle (ellipse), in absolute\n * content coordinates. The scallops are generated on `box` and bulge out\n * from it.\n */\nexport function cloudyPath(\n box: Rect,\n ellipse: boolean,\n intensity: number,\n strokeWidth: number,\n): string {\n const out = new PathBuilder(box.x, box.y);\n boxCloud(box, ellipse, intensity, strokeWidth, out);\n out.close();\n return out.build();\n}\n\n/**\n * The box around what a cloudy polygon border paints: its curves, and half\n * the stroke past them (round joins: the pen reaches that far every way).\n */\nexport function cloudyPolyBounds(points: Point[], intensity: number, strokeWidth: number): Rect {\n const out = new CurveBounds(0, 0);\n polygonCloud(points, intensity, strokeWidth, out);\n return expandRect(out.bounds(), strokeWidth / 2);\n}\n\n/** The points along a cloudy polygon border's curves, one closed polyline per subpath. */\nexport function cloudyPolyOutline(\n points: Point[],\n intensity: number,\n strokeWidth: number,\n): Point[][] {\n const out = new CurvePolylines(0, 0);\n polygonCloud(points, intensity, strokeWidth, out);\n return out.lines;\n}\n\n/**\n * The points along a cloudy square's or circle's border curves, as\n * `cloudyPolyOutline`: on `box` before any turn, as `cloudyPath` draws them.\n */\nexport function cloudyOutline(\n box: Rect,\n ellipse: boolean,\n intensity: number,\n strokeWidth: number,\n): Point[][] {\n const out = new CurvePolylines(box.x, box.y);\n boxCloud(box, ellipse, intensity, strokeWidth, out);\n return out.lines;\n}\n\n/** The box around what a cloudy square's or circle's border paints, as `cloudyPolyBounds`. */\nexport function cloudyBounds(\n box: Rect,\n ellipse: boolean,\n intensity: number,\n strokeWidth: number,\n): Rect {\n const out = new CurveBounds(box.x, box.y);\n boxCloud(box, ellipse, intensity, strokeWidth, out);\n return expandRect(out.bounds(), strokeWidth / 2);\n}\n","/**\n * The box family: squares, circles and stamps, and the kinds whose shape is\n * their `rect` (note and attachment icons, links, widgets, an area\n * redaction). Its shape is the engine's own fields: the box before any turn\n * (`box`, or `rect` for a kind that never turns) and the turn about the box's\n * middle (`rotation`, degrees clockwise).\n *\n * A cloudy border reaches out from the box, as the engine draws it: the box\n * is where the bumps start, and the engine's `rect` takes them in. The\n * handles sit on the box.\n *\n * Moving, turning, scaling and resizing work on any turned box\n * ({@link TurnedBox}), so the text box family shares them.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { cloudyBounds, cloudyOutline, cloudyPath } from '../cloudy';\nimport type { PaintedPiece } from '../painted';\nimport {\n RECT_HANDLES,\n expandRect,\n insetRect,\n normalizeDeg,\n rectCenter,\n rectContains,\n rectCornerPoints,\n rectHandlePoint,\n resizeRotatedRect,\n rotatePoint,\n rotatedAabb,\n rotatedHandleCursor,\n transposedAboutCenter,\n type RectHandle,\n} from '../rect';\nimport type { Handle, Placement, Point, Rect, RenderNode, Stroke } from '../types';\nimport type { ShapeFamily } from './family';\n\n/** A box and its turn, as the engine keeps them. */\nexport interface TurnedBox {\n /** The box before any turn: the engine's `box`, or its `rect` for a kind that never turns. */\n box: Rect;\n /** Degrees clockwise about the middle of `box`; 0 when upright. */\n rotation: number;\n}\n\n/** A box family record's shape: the engine's box and its turn. */\nexport interface BoxShape extends TurnedBox {\n kind: 'box';\n /** Drawn as the ellipse in `box`: a circle. */\n ellipse: boolean;\n}\n\n/** The kinds that keep their box in `box` and turn it by `rotation`; the rest keep it in `rect`. */\nconst TURNING_KINDS: ReadonlySet<string> = new Set(['square', 'circle', 'stamp']);\n\ntype TurningAnnotation = Extract<Annotation, { subtype: 'square' | 'circle' | 'stamp' }>;\n\n/** Whether a box kind draws the ellipse in its box: a circle, and a radio button (the engine draws one round). */\nconst drawsEllipse = (annotation: Annotation): boolean =>\n annotation.subtype === 'circle' ||\n (annotation.subtype === 'widget' && annotation.fieldFamily === 'radio');\n\n/** A box kind's shape, read off its annotation. */\nfunction readBox(annotation: Annotation): BoxShape {\n if (!TURNING_KINDS.has(annotation.subtype)) {\n return { kind: 'box', box: annotation.rect, rotation: 0, ellipse: drawsEllipse(annotation) };\n }\n const { box, rotation } = annotation as TurningAnnotation;\n return { kind: 'box', box, rotation: rotation ?? 0, ellipse: drawsEllipse(annotation) };\n}\n\n/**\n * A box kind's shape where a create gesture places a box. An upright tool's\n * turn (`placement.rot`, quarter turns) matters only to a drawing that reads\n * one way: a stamp's image keeps it. Every other box (a square, a circle, a\n * widget) takes the region the turned box covers, a quarter turn swapping\n * its sides, and stores no turn: it shows as the author saw it, unturned.\n */\nfunction placeBox(placement: Placement, annotation: Annotation): BoxShape | null {\n if (placement.kind !== 'box') return null;\n const keepsTurn = annotation.subtype === 'stamp';\n const quarter = placement.rot % 180 !== 0;\n return {\n kind: 'box',\n box: !keepsTurn && quarter ? transposedAboutCenter(placement.rect) : placement.rect,\n rotation: keepsTurn ? placement.rot : 0,\n ellipse: drawsEllipse(annotation),\n };\n}\n\n/**\n * The engine fields that state `shape` for a kind: its `box` and `rotation`\n * (`null` when upright, so a turn is cleared rather than kept), or its `rect`.\n */\nfunction writeBox(\n shape: BoxShape,\n subtype: string,\n): { box: Rect; rotation: number | null } | { rect: Rect } {\n return TURNING_KINDS.has(subtype)\n ? { box: shape.box, rotation: shape.rotation || null }\n : { rect: shape.box };\n}\n\n/**\n * What the shape draws, before its turn: the box (a plain stroke draws inside\n * it), or the box around what its cloud paints.\n */\nfunction boxDrawnBounds(shape: BoxShape, stroke: Stroke): Rect {\n const { cloudyIntensity, strokeWidth } = stroke;\n return cloudyIntensity && shape.box.width > 0 && shape.box.height > 0\n ? cloudyBounds(shape.box, shape.ellipse, cloudyIntensity, strokeWidth)\n : shape.box;\n}\n\n/** The upright page box around what it paints: what it draws, turned about the box's middle. */\nfunction boxRect(shape: BoxShape, stroke: Stroke): Rect {\n return rotatedAabb(boxDrawnBounds(shape, stroke), shape.rotation, rectCenter(shape.box));\n}\n\n/** The box's corners as the page shows them (nw, ne, se, sw), turned about its middle. */\nexport function boxCorners(shape: TurnedBox): [Point, Point, Point, Point] {\n const middle = rectCenter(shape.box);\n return rectCornerPoints(shape.box).map((corner) =>\n rotatePoint(corner, middle, shape.rotation),\n ) as [Point, Point, Point, Point];\n}\n\n/** Is `point` in the turned box, grown by `margin`? Tested in the box's own frame (the point turned back). */\nexport function isInTurnedBox(shape: TurnedBox, point: Point, margin: number): boolean {\n const local = shape.rotation ? rotatePoint(point, rectCenter(shape.box), -shape.rotation) : point;\n return rectContains(expandRect(shape.box, margin), local);\n}\n\n/** The shape moved by `delta`. */\nexport function boxTranslate<S extends TurnedBox>(shape: S, delta: Point): S {\n return { ...shape, box: { ...shape.box, x: shape.box.x + delta.x, y: shape.box.y + delta.y } };\n}\n\n/** The box of `size` centred on `middle`. */\nconst boxAround = (middle: Point, size: { width: number; height: number }): Rect => ({\n x: middle.x - size.width / 2,\n y: middle.y - size.height / 2,\n width: size.width,\n height: size.height,\n});\n\n/** The shape turned `degrees` clockwise about `pivot`: its middle orbits the pivot, and its turn grows. */\nexport function boxRotateAbout<S extends TurnedBox>(shape: S, pivot: Point, degrees: number): S {\n return {\n ...shape,\n box: boxAround(rotatePoint(rectCenter(shape.box), pivot, degrees), shape.box),\n rotation: normalizeDeg(shape.rotation + degrees),\n };\n}\n\n/**\n * The shape scaled about `anchor` by `(sx, sy)`: its middle moves with the\n * scale and its size scales, and its turn stays (a turned member of a\n * selection scales the same in both directions). Its size is kept at least\n * `minSize`, a resize's limit; 0 scales exactly.\n */\nexport function boxScaleAbout<S extends TurnedBox>(\n shape: S,\n anchor: Point,\n sx: number,\n sy: number,\n minSize = 0,\n): S {\n const middle = rectCenter(shape.box);\n return {\n ...shape,\n box: boxAround(\n { x: anchor.x + (middle.x - anchor.x) * sx, y: anchor.y + (middle.y - anchor.y) * sy },\n {\n width: Math.max(minSize, shape.box.width * Math.abs(sx)),\n height: Math.max(minSize, shape.box.height * Math.abs(sy)),\n },\n ),\n };\n}\n\n/** The eight resize handles, on the box as the page shows it; each cursor turns with the box. */\nexport function boxHandles(shape: TurnedBox): Handle[] {\n const middle = rectCenter(shape.box);\n return RECT_HANDLES.map((handle) => ({\n id: handle,\n at: rotatePoint(rectHandlePoint(shape.box, handle), middle, shape.rotation),\n cursor: rotatedHandleCursor(handle, shape.rotation),\n }));\n}\n\n/** The shape resized by dragging `handle` to `to`: the opposite handle stays where it is. */\nexport function boxResize<S extends TurnedBox>(shape: S, handle: string, to: Point): S {\n return { ...shape, box: resizeRotatedRect(shape.box, shape.rotation, handle as RectHandle, to) };\n}\n\n/**\n * What the shape paints, turned with the box: a plain border's ink, which\n * lies inside the box, centred half the stroke in; or a cloud's ink along its\n * curves. Filled, it paints the box too, and a cloud the ring its curves close.\n */\nfunction boxPainted(shape: BoxShape, stroke: Stroke, filled: boolean): PaintedPiece[] {\n const { strokeWidth, cloudyIntensity } = stroke;\n const { box, rotation, ellipse } = shape;\n const halfWidth = strokeWidth / 2;\n const middle = rectCenter(box);\n const turned = (points: Point[]): Point[] =>\n rotation ? points.map((point) => rotatePoint(point, middle, rotation)) : points;\n if (cloudyIntensity && box.width > 0 && box.height > 0) {\n const curves = cloudyOutline(box, ellipse, cloudyIntensity, strokeWidth).map(turned);\n const ink = curves.map(\n (points): PaintedPiece => ({ kind: 'stroke', points, closed: true, halfWidth }),\n );\n if (!filled) return ink;\n const inside: PaintedPiece = ellipse\n ? {\n kind: 'oval',\n center: middle,\n rx: box.width / 2,\n ry: box.height / 2,\n rotation,\n halfWidth: 0,\n filled: true,\n }\n : { kind: 'area', ring: boxCorners(shape) };\n return [inside, ...curves.map((ring): PaintedPiece => ({ kind: 'area', ring })), ...ink];\n }\n const inset = insetRect(box, halfWidth);\n if (ellipse) {\n if (box.width <= 0 || box.height <= 0) return [];\n // The ink's middle is the inset ellipse; its radii never quite reach 0.\n const rx = Math.max(0.01, inset.width / 2);\n const ry = Math.max(0.01, inset.height / 2);\n return [{ kind: 'oval', center: middle, rx, ry, rotation, halfWidth, filled }];\n }\n const ink: PaintedPiece = {\n kind: 'stroke',\n points: turned(rectCornerPoints(inset)),\n closed: true,\n halfWidth,\n };\n return filled ? [{ kind: 'area', ring: boxCorners(shape) }, ink] : [ink];\n}\n\n/**\n * What the shape draws, before its turn (the renderer turns it about the\n * box's middle): a cloud around the box, or the box's outline, inset half\n * the stroke so the ink lies inside the box.\n */\nfunction boxScene(shape: BoxShape, stroke: Stroke): RenderNode[] {\n const { strokeWidth, cloudyIntensity } = stroke;\n if (cloudyIntensity && shape.box.width > 0 && shape.box.height > 0) {\n return [\n {\n kind: 'path',\n d: cloudyPath(shape.box, shape.ellipse, cloudyIntensity, strokeWidth),\n },\n ];\n }\n const rect = insetRect(shape.box, strokeWidth / 2);\n return [shape.ellipse ? { kind: 'ellipse', rect } : { kind: 'rect', rect }];\n}\n\n/** The box family: a box and its turn, drawn as a rectangle, an ellipse or a cloud. */\nexport const boxFamily: ShapeFamily<BoxShape> = {\n read: readBox,\n write: writeBox,\n placed: placeBox,\n bounds: (shape) => shape.box,\n drawnBounds: boxDrawnBounds,\n rect: boxRect,\n selectionBounds: (shape) => shape.box,\n oriented: () => true,\n turnedCorners: boxCorners,\n pivot: (shape) => rectCenter(shape.box),\n translate: boxTranslate,\n rotateAbout: boxRotateAbout,\n scaleAbout: boxScaleAbout,\n upright: (shape) => ({ ...shape, rotation: 0 }),\n handles: boxHandles,\n drag: boxResize,\n painted: boxPainted,\n scene: boxScene,\n};\n","/**\n * What an annotation paints, as a few simple pieces, and the two questions\n * asked of them: is a point near the ink (a click), and does a rectangle\n * touch it (the marquee). Each shape family says what it paints\n * (`ShapeFamily.painted`); a click and a marquee read the same pieces,\n * so they can't disagree: a rectangle of no size touches exactly what a\n * click with no margin hits there.\n */\nimport {\n pointInPoly,\n polygonTouchesRect,\n rectCornerPoints,\n rotatePoint,\n segDist,\n segmentRectDistance,\n} from './rect';\nimport type { Point, Rect } from './types';\n\n/** One piece of what an annotation paints, in page space. */\nexport type PaintedPiece =\n /** Ink along a path, `halfWidth` either side of it; `closed` runs it back to the first point. */\n | {\n readonly kind: 'stroke';\n readonly points: readonly Point[];\n readonly closed: boolean;\n readonly halfWidth: number;\n }\n /** A filled polygon (even-odd). A margin doesn't grow it: ink around it does. */\n | { readonly kind: 'area'; readonly ring: readonly Point[] }\n /**\n * An ellipse turned `rotation` degrees clockwise about `center`: its ink,\n * `halfWidth` either side of it, and its inside when `filled`. The ink's\n * width is measured in radii along the smaller radius, so a long ellipse's\n * ink is a little wider at its ends.\n */\n | {\n readonly kind: 'oval';\n readonly center: Point;\n readonly rx: number;\n readonly ry: number;\n readonly rotation: number;\n readonly halfWidth: number;\n readonly filled: boolean;\n };\n\n/**\n * A solid body: anything inside the ring, and anything within a margin of\n * its edge (a rim of ink with no width). A text box, a caret and a\n * measurement's caption are hit this way.\n */\nexport const bodyPieces = (ring: readonly Point[]): PaintedPiece[] => [\n { kind: 'area', ring },\n { kind: 'stroke', points: ring, closed: true, halfWidth: 0 },\n];\n\n/** Is `point` within `margin` of what the pieces paint? */\nexport const paintedNear = (\n pieces: readonly PaintedPiece[],\n point: Point,\n margin: number,\n): boolean => pieces.some((piece) => pieceNear(piece, point, margin));\n\n/** Does the rect touch what the pieces paint: cross its ink, or lie on its fill? */\nexport const paintedTouches = (pieces: readonly PaintedPiece[], rect: Rect): boolean =>\n pieces.some((piece) => pieceTouches(piece, rect));\n\nfunction pieceNear(piece: PaintedPiece, point: Point, margin: number): boolean {\n switch (piece.kind) {\n case 'stroke':\n return someSegment(piece, (from, to) => segDist(point, from, to) <= piece.halfWidth + margin);\n case 'area':\n return pointInPoly(point, piece.ring);\n case 'oval': {\n if (piece.rx <= 0 || piece.ry <= 0) return false;\n const local = toOvalFrame(piece, point);\n const reach = Math.hypot(local.x, local.y);\n const band = inRadii(piece, piece.halfWidth + margin);\n return piece.filled ? reach <= 1 + band : Math.abs(reach - 1) <= band;\n }\n }\n}\n\nfunction pieceTouches(piece: PaintedPiece, rect: Rect): boolean {\n switch (piece.kind) {\n case 'stroke':\n return someSegment(\n piece,\n (from, to) => segmentRectDistance(from, to, rect) <= piece.halfWidth,\n );\n case 'area':\n return polygonTouchesRect(piece.ring, rect);\n case 'oval': {\n if (piece.rx <= 0 || piece.ry <= 0) return false;\n // In the oval's own frame, scaled to radii, the rect is a parallelogram\n // and the ellipse a unit circle: the rect touches the ink when it\n // reaches into the ink's ring, and the fill when it reaches its disc.\n const corners = rectCornerPoints(rect).map((corner) => toOvalFrame(piece, corner));\n const center = { x: 0, y: 0 };\n const nearest = pointInPoly(center, corners)\n ? 0\n : Math.min(...corners.map((corner, i) => segDist(center, corner, corners[(i + 1) % 4]!)));\n const farthest = Math.max(...corners.map((corner) => Math.hypot(corner.x, corner.y)));\n const band = inRadii(piece, piece.halfWidth);\n return nearest <= 1 + band && (piece.filled || farthest >= 1 - band);\n }\n }\n}\n\ntype Oval = Extract<PaintedPiece, { kind: 'oval' }>;\n\n/** `point` in the oval's own frame, scaled so the ellipse is the unit circle (1 from the middle on it). */\nfunction toOvalFrame(oval: Oval, point: Point): Point {\n const local = oval.rotation ? rotatePoint(point, oval.center, -oval.rotation) : point;\n return { x: (local.x - oval.center.x) / oval.rx, y: (local.y - oval.center.y) / oval.ry };\n}\n\n/** A distance in page units as radii, measured along the smaller radius. */\nconst inRadii = (oval: Oval, distance: number): number => distance / Math.min(oval.rx, oval.ry);\n\n/** Does `test` hold for any segment of the stroke (its closing one too)? */\nfunction someSegment(\n stroke: Extract<PaintedPiece, { kind: 'stroke' }>,\n test: (from: Point, to: Point) => boolean,\n): boolean {\n const { points } = stroke;\n for (let i = 0; i < points.length - 1; i++) if (test(points[i]!, points[i + 1]!)) return true;\n return stroke.closed && points.length > 2 && test(points[points.length - 1]!, points[0]!);\n}\n","/**\n * The caret family: an insertion mark on its text. Its shape is the engine's\n * own fields: the box before any turn (`box`) and the turn about its middle\n * (`rotation`), which is its text's baseline tilt, so the mark points at its\n * line. The caret follows its text: no gesture resizes or turns it, though\n * straightening clears its turn.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { bodyPieces } from '../painted';\nimport { normalizeDeg, rectCenter, rotatedAabb } from '../rect';\nimport type { Rect, RenderNode, TextEndAnchor } from '../types';\nimport { boxCorners, boxScaleAbout, boxTranslate, type TurnedBox } from './box';\nimport type { ShapeFamily } from './family';\n\n/** A caret record's shape: the engine's box and its turn. */\nexport interface CaretShape extends TurnedBox {\n kind: 'caret';\n}\n\n/** A caret's shape, read off its annotation. */\nfunction readCaret(annotation: Annotation): CaretShape {\n const { box, rotation } = annotation as Extract<Annotation, { subtype: 'caret' }>;\n return { kind: 'caret', box, rotation: rotation ?? 0 };\n}\n\n/** The engine fields that state `shape`: its `box` and `rotation` (`null` when upright). */\nconst writeCaret = (shape: CaretShape): { box: Rect; rotation: number | null } => ({\n box: shape.box,\n rotation: shape.rotation || null,\n});\n\n/**\n * The caret box for a text-edit anchor, upright: half the glyph's ink height,\n * centred on the trailing baseline corner in reading direction (`advance`\n * decides which end, so a right-to-left caret lands on the visual left),\n * sitting on the baseline. {@link caretFromAnchor} gives the turned caret.\n */\nexport function caretRectFromAnchor(anchor: TextEndAnchor): Rect {\n const quad = anchor.glyphQuad;\n const ink = Math.hypot(quad.lowerLeft.x - quad.upperLeft.x, quad.lowerLeft.y - quad.upperLeft.y);\n const size = Math.max(ink / 2, 1);\n const corner = anchor.advance > 0 ? quad.lowerRight : quad.lowerLeft;\n return { x: corner.x - size / 2, y: corner.y - size, width: size, height: size };\n}\n\n/** Rotations closer than ~0.05° to upright stay upright (float noise guard). */\nconst UPRIGHT_EPSILON = 0.05;\n\n/**\n * The caret for a text-edit anchor: a box whose middle sits half a caret size\n * toward the ascent from the trailing baseline corner, turned by the text's\n * baseline tilt (degrees clockwise), so the mark hugs the turned baseline and\n * points at its text. For upright text this is exactly\n * {@link caretRectFromAnchor} with no turn.\n */\nexport function caretFromAnchor(anchor: TextEndAnchor): CaretShape {\n const quad = anchor.glyphQuad;\n const ink = Math.hypot(quad.lowerLeft.x - quad.upperLeft.x, quad.lowerLeft.y - quad.upperLeft.y);\n const size = Math.max(ink / 2, 1);\n const corner = anchor.advance > 0 ? quad.lowerRight : quad.lowerLeft;\n // The caret's own orientation follows the text (the symbol points at its\n // line regardless of reading direction), so the tilt comes from the\n // baseline edge, not from `advance`.\n const bx = quad.lowerRight.x - quad.lowerLeft.x;\n const by = quad.lowerRight.y - quad.lowerLeft.y;\n const rotation = Math.hypot(bx, by) > 0 ? normalizeDeg((Math.atan2(by, bx) * 180) / Math.PI) : 0;\n if (rotation < UPRIGHT_EPSILON || rotation > 360 - UPRIGHT_EPSILON) {\n return { kind: 'caret', box: caretRectFromAnchor(anchor), rotation: 0 };\n }\n // The middle: the trailing corner + half a caret size toward the ascent.\n const ux = (quad.upperLeft.x - quad.lowerLeft.x) / ink;\n const uy = (quad.upperLeft.y - quad.lowerLeft.y) / ink;\n const cx = corner.x + (ux * size) / 2;\n const cy = corner.y + (uy * size) / 2;\n return {\n kind: 'caret',\n box: { x: cx - size / 2, y: cy - size / 2, width: size, height: size },\n rotation,\n };\n}\n\n/** The width of the caret mark's outline, whatever the annotation's stroke. */\nexport const CARET_STROKE_WIDTH = 0.5;\n\n/**\n * The caret mark in its box, before its turn (the renderer turns it about the\n * box's middle): filled, and its outline stroked from one foot over the peak\n * to the other, as the engine draws it. The base isn't stroked.\n */\nfunction caretScene(shape: CaretShape): RenderNode[] {\n const { x, y, width, height } = shape.box;\n const midX = x + width / 2;\n const bottom = y + height;\n const pathData = [\n `M ${x} ${bottom}`,\n `C ${x + width * 0.27} ${bottom} ${midX} ${y + height * 0.56} ${midX} ${y}`,\n `C ${midX} ${y + height * 0.56} ${x + width * 0.73} ${bottom} ${x + width} ${bottom}`,\n ].join(' ');\n return [{ kind: 'path', d: pathData }];\n}\n\n/**\n * What the caret draws, before its turn: its box, and the outline's half\n * width below its base. The outline runs flat at each foot (a butt end\n * reaches across it, down) and doubles back at the peak (the renderer bevels\n * it, so nothing reaches above).\n */\nfunction caretDrawnBounds(shape: CaretShape): Rect {\n const { box } = shape;\n return { ...box, height: box.height + CARET_STROKE_WIDTH / 2 };\n}\n\n/**\n * The caret family: a mark in a turned box that follows its text. It moves\n * and scales with a selection, but no gesture turns, resizes or drags it.\n */\nexport const caretFamily: ShapeFamily<CaretShape> = {\n read: readCaret,\n write: writeCaret,\n // A caret is made from a text selection, never placed.\n placed: () => null,\n bounds: (shape) => shape.box,\n drawnBounds: caretDrawnBounds,\n rect: (shape) => rotatedAabb(caretDrawnBounds(shape), shape.rotation, rectCenter(shape.box)),\n selectionBounds: (shape) => shape.box,\n oriented: () => true,\n turnedCorners: boxCorners,\n pivot: (shape) => rectCenter(shape.box),\n translate: boxTranslate,\n rotateAbout: (shape) => shape,\n scaleAbout: boxScaleAbout,\n upright: (shape) => ({ ...shape, rotation: 0 }),\n handles: () => [],\n drag: (shape) => shape,\n // A caret paints its whole box: the mark is small.\n painted: (shape) => bodyPieces(boxCorners(shape)),\n scene: caretScene,\n};\n","/**\n * Line endings (/LE) — the arrowheads and tip shapes drawn at the ends of line\n * and polyline annotations. One spec per ending kind drives both the rendered\n * geometry (`endingNodes`) and the bounding-box points (`endingPoints`), so the\n * visual and the engine `/Rect` can never drift. Pure page-space math (PDF\n * points, y-down) — no DOM, no SVG strings — so it ports to Rust like the rest.\n *\n * Convention: each spec is authored in a local frame with the tip at the origin\n * and the body pointing back along −X. `endingNodes`/`endingPoints` rotate it by\n * the segment angle (into the tip) and translate it to the tip point. Sizes\n * scale with the stroke width.\n */\nimport type { PaintedPiece } from './painted';\nimport { rectCenter } from './rect';\nimport type { LineEnding, RenderNode, Point } from './types';\n\ninterface EndingSpec {\n shape: 'poly' | 'ellipse';\n /** Poly: closed path (so it fills with the annotation's fill colour) vs an open\n * polyline that is stroke-only (open arrow / butt / slash). Ellipses are always\n * closed. Fill colour is the renderer's job — the spec only states closed-ness. */\n closed: boolean;\n /** Final rotation (radians) given the segment angle pointing into the tip. */\n rotation: (angle: number) => number;\n /** Local-frame points (tip at origin, body along −X). */\n points: (sw: number) => Point[];\n}\n\nconst arrow = (closed: boolean): EndingSpec => ({\n shape: 'poly',\n closed,\n rotation: (angle) => angle,\n points: (sw) => {\n const len = sw * 9;\n const wing = Math.PI / 6; // 30°\n const x = -len * Math.cos(wing);\n const y = len * Math.sin(wing);\n return closed\n ? [\n { x: 0, y: 0 },\n { x, y },\n { x, y: -y },\n ]\n : [\n { x, y },\n { x: 0, y: 0 },\n { x, y: -y },\n ];\n },\n});\n\nconst lineCap = (factor: number, rotation: (angle: number) => number): EndingSpec => ({\n shape: 'poly',\n closed: false,\n rotation,\n points: (sw) => {\n const half = (sw * factor) / 2;\n return [\n { x: -half, y: 0 },\n { x: half, y: 0 },\n ];\n },\n});\n\nconst ENDINGS: Partial<Record<LineEnding, EndingSpec>> = {\n 'open-arrow': arrow(false),\n 'closed-arrow': arrow(true),\n 'r-open-arrow': { ...arrow(false), rotation: (angle) => angle + Math.PI },\n 'r-closed-arrow': { ...arrow(true), rotation: (angle) => angle + Math.PI },\n circle: {\n shape: 'ellipse',\n closed: true,\n rotation: () => 0, // a circle reads the same at any angle\n points: (sw) => {\n const radius = (sw * 5) / 2;\n return [\n { x: -radius, y: -radius },\n { x: radius, y: radius },\n ];\n },\n },\n square: {\n shape: 'poly',\n closed: true,\n rotation: (angle) => angle,\n points: (sw) => {\n const halfSize = (sw * 6) / 2;\n return [\n { x: -halfSize, y: -halfSize },\n { x: halfSize, y: -halfSize },\n { x: halfSize, y: halfSize },\n { x: -halfSize, y: halfSize },\n ];\n },\n },\n diamond: {\n shape: 'poly',\n closed: true,\n rotation: (angle) => angle,\n points: (sw) => {\n const halfSize = (sw * 6) / 2;\n return [\n { x: halfSize, y: 0 },\n { x: 0, y: halfSize },\n { x: -halfSize, y: 0 },\n { x: 0, y: -halfSize },\n ];\n },\n },\n butt: lineCap(6, (angle) => angle + Math.PI / 2),\n slash: lineCap(18, (angle) => angle + Math.PI / 1.5),\n};\n\nconst rotateTranslate = (point: Point, angle: number, tip: Point): Point => {\n const cosine = Math.cos(angle);\n const sine = Math.sin(angle);\n return {\n x: tip.x + point.x * cosine - point.y * sine,\n y: tip.y + point.x * sine + point.y * cosine,\n };\n};\n\nconst specOf = (ending: LineEnding | undefined): EndingSpec | undefined =>\n ending && ending !== 'none' ? ENDINGS[ending] : undefined;\n\n/** Page-space points contributed by an ending — for the visual bounding box. */\nexport function endingPoints(\n tip: Point,\n angle: number,\n ending: LineEnding | undefined,\n strokeWidth: number,\n): Point[] {\n const spec = specOf(ending);\n if (!spec) return [];\n const rot = spec.rotation(angle);\n return spec.points(strokeWidth).map((point) => rotateTranslate(point, rot, tip));\n}\n\n/** Page-space render nodes for an ending — what the framework renderer draws. */\nexport function endingNodes(\n tip: Point,\n angle: number,\n ending: LineEnding | undefined,\n strokeWidth: number,\n): RenderNode[] {\n const spec = specOf(ending);\n if (!spec) return [];\n const rot = spec.rotation(angle);\n const points = spec.points(strokeWidth).map((point) => rotateTranslate(point, rot, tip));\n if (spec.shape === 'ellipse') {\n const [point, oppositeCorner] = points;\n return [\n {\n kind: 'ellipse',\n rect: {\n x: Math.min(point.x, oppositeCorner.x),\n y: Math.min(point.y, oppositeCorner.y),\n width: Math.abs(oppositeCorner.x - point.x),\n height: Math.abs(oppositeCorner.y - point.y),\n },\n },\n ];\n }\n return [{ kind: 'poly', points, closed: spec.closed }];\n}\n\n/**\n * What a line's drawn endings paint, from the same nodes the renderer draws,\n * so an arrowhead is as clickable as the stroke: the ink `strokeWidth` wide,\n * and the inside of a closed head (closed arrow, square, diamond) or a circle.\n * An open head (open arrow, butt, slash) paints its ink only.\n */\nexport function endingPieces(nodes: readonly RenderNode[], strokeWidth: number): PaintedPiece[] {\n const halfWidth = strokeWidth / 2;\n return nodes.flatMap((node): PaintedPiece[] => {\n if (node.kind === 'ellipse') {\n const { rect } = node;\n return [\n {\n kind: 'oval',\n center: rectCenter(rect),\n rx: rect.width / 2,\n ry: rect.height / 2,\n rotation: 0,\n halfWidth,\n filled: true,\n },\n ];\n }\n if (node.kind !== 'poly') return [];\n const ink: PaintedPiece = {\n kind: 'stroke',\n points: node.points,\n closed: node.closed,\n halfWidth,\n };\n return node.closed ? [{ kind: 'area', ring: node.points }, ink] : [ink];\n });\n}\n","/**\n * The points family: lines, polylines, polygons and ink. Its shape is the\n * engine's own fields: the points upright (`linePoints`, `vertices`,\n * `inkList`), the line endings, and the turn that draws them (`rotation`,\n * degrees clockwise about the middle of the box around the upright points,\n * as a square turns about its box). Where the points are drawn is worked out\n * from these ({@link drawnStrokesOf}) for hit-testing, drawing and handles.\n *\n * So every kind that turns works the same way: turning one changes its\n * `rotation` (and where its middle is, when it turns about another pivot),\n * and straightening one clears it. A dragged vertex lands where it was\n * dropped: the drawn points change and the upright ones follow, turned back\n * as the engine turns them.\n *\n * A polygon or polyline measurement's caption center is kept as the engine\n * keeps it, upright with the vertices: a move or a scale carries it along, a\n * turn turns it with the drawing, and a dragged vertex leaves it where it is.\n */\nimport {\n pagePointTurned,\n pagePointUnturned,\n pageTurnOfDrawn,\n pageTurnOfUpright,\n type Annotation,\n type LineEndings,\n type PagePointTurn,\n} from '@embedpdf/engine-core/runtime';\n\nimport { cloudyPolyBounds, cloudyPolyOutline, cloudyPolyPath } from '../cloudy';\nimport { endingNodes, endingPieces } from '../endings';\nimport type { PaintedPiece } from '../painted';\nimport {\n expandRect,\n normalizeDeg,\n rectCenter,\n rectCornerPoints,\n rotatePoint,\n unionRect,\n} from '../rect';\nimport type { Handle, LineEnding, Placement, Point, Rect, RenderNode, Stroke } from '../types';\nimport type { ShapeFamily } from './family';\n\n/** A line: its two ends upright, and their endings. */\nexport interface LineShape {\n kind: 'line';\n linePoints: { start: Point; end: Point };\n lineEndings?: LineEndings;\n /** Degrees clockwise about the middle of the box around the upright points; 0 when upright. */\n rotation: number;\n}\n\n/** A polygon (`closed`) or polyline: its vertices upright, and a polyline's endings. */\nexport interface PolyShape {\n kind: 'poly';\n vertices: Point[];\n closed: boolean;\n lineEndings?: LineEndings;\n /** A measurement's caption center, upright with the vertices; `null` places it automatically. */\n captionCenter?: Point | null;\n /** Degrees clockwise about the middle of the box around the upright points; 0 when upright. */\n rotation: number;\n}\n\n/** Ink: its strokes upright. */\nexport interface InkShape {\n kind: 'ink';\n inkList: Point[][];\n /** Degrees clockwise about the middle of the box around the upright points; 0 when upright. */\n rotation: number;\n}\n\n/** A points family record's shape. */\nexport type PointsShape = LineShape | PolyShape | InkShape;\n\ntype PointsAnnotation = Extract<Annotation, { subtype: 'line' | 'polyline' | 'polygon' | 'ink' }>;\n\n/** A points kind's shape, read off its annotation. */\nfunction readPoints(read: Annotation): PointsShape {\n const annotation = read as PointsAnnotation;\n const rotation = annotation.rotation ?? 0;\n switch (annotation.subtype) {\n case 'line':\n return {\n kind: 'line',\n linePoints: annotation.linePoints,\n ...(annotation.lineEndings ? { lineEndings: annotation.lineEndings } : {}),\n rotation,\n };\n case 'polyline':\n return {\n kind: 'poly',\n vertices: annotation.vertices,\n closed: false,\n ...(annotation.lineEndings ? { lineEndings: annotation.lineEndings } : {}),\n ...(annotation.captionCenter !== undefined\n ? { captionCenter: annotation.captionCenter }\n : {}),\n rotation,\n };\n case 'polygon':\n return {\n kind: 'poly',\n vertices: annotation.vertices,\n closed: true,\n ...(annotation.captionCenter !== undefined\n ? { captionCenter: annotation.captionCenter }\n : {}),\n rotation,\n };\n case 'ink':\n return { kind: 'ink', inkList: annotation.inkList, rotation };\n }\n}\n\nconst NO_ENDINGS: LineEndings = { start: 'none', end: 'none' };\n\n/** A line's or polyline's endings; none for an annotation that has none. */\nexport const lineEndingsOf = (annotation: Annotation): LineEndings =>\n ('lineEndings' in annotation && annotation.lineEndings) || NO_ENDINGS;\n\n/** A line where a create gesture places a segment, with the tool's endings; no other points kind is placed. */\nfunction placePoints(placement: Placement, annotation: Annotation): LineShape | null {\n if (placement.kind !== 'segment' || annotation.subtype !== 'line') return null;\n return {\n kind: 'line',\n linePoints: { start: placement.a, end: placement.b },\n lineEndings: lineEndingsOf(annotation),\n rotation: 0,\n };\n}\n\n/**\n * The engine fields that state `shape`'s points and turn (`null` when\n * upright, so a turn is cleared rather than kept). The endings are a field\n * of their own, written when they change.\n */\nfunction writePoints(shape: PointsShape) {\n const rotation = shape.rotation || null;\n if (shape.kind === 'line') return { linePoints: shape.linePoints, rotation };\n if (shape.kind === 'poly')\n return {\n vertices: shape.vertices,\n ...(shape.captionCenter !== undefined ? { captionCenter: shape.captionCenter } : {}),\n rotation,\n };\n return { inkList: shape.inkList, rotation };\n}\n\n/** The shape's upright points, one list per stroke: a line's two ends, a poly's vertices, each ink stroke. */\nfunction uprightStrokesOf(shape: PointsShape): Point[][] {\n if (shape.kind === 'line') return [[shape.linePoints.start, shape.linePoints.end]];\n if (shape.kind === 'poly') return [shape.vertices];\n return shape.inkList;\n}\n\n/** The shape with `strokes` as its upright points. */\nfunction withUprightStrokes<S extends PointsShape>(shape: S, strokes: Point[][]): S {\n if (shape.kind === 'line') {\n const [start, end] = strokes[0]!;\n return { ...shape, linePoints: { start: start!, end: end! } };\n }\n if (shape.kind === 'poly') return { ...shape, vertices: strokes[0]! };\n return { ...shape, inkList: strokes };\n}\n\n/** The shape with every upright point, a caption center included, moved by `map`. */\nfunction mapUpright<S extends PointsShape>(shape: S, map: (point: Point) => Point): S {\n const moved = withUprightStrokes(\n shape,\n uprightStrokesOf(shape).map((stroke) => stroke.map(map)),\n );\n return moved.kind === 'poly' && moved.captionCenter\n ? { ...moved, captionCenter: map(moved.captionCenter) }\n : moved;\n}\n\n/** The turn that draws the upright points, or `undefined` upright. */\nconst turnOf = (shape: PointsShape): PagePointTurn | undefined =>\n shape.rotation ? pageTurnOfUpright(uprightStrokesOf(shape).flat(), shape.rotation) : undefined;\n\n/** Where an upright `point` of the shape (a caption center) is drawn. */\nexport function drawnPointOf(shape: PointsShape, point: Point): Point {\n const turn = turnOf(shape);\n return turn ? pagePointTurned(point, turn) : point;\n}\n\n/** The upright point of the shape that is drawn at `point`. */\nexport function uprightPointOf(shape: PointsShape, point: Point): Point {\n const turn = turnOf(shape);\n return turn ? pagePointUnturned(point, turn) : point;\n}\n\nconst drawn = new WeakMap<PointsShape, Point[][]>();\n\n/** Where the points are drawn: the upright ones turned by `rotation`. The same lists for the same shape. */\nexport function drawnStrokesOf(shape: PointsShape): Point[][] {\n const cached = drawn.get(shape);\n if (cached) return cached;\n const turn = turnOf(shape);\n const strokes = uprightStrokesOf(shape);\n const out = turn\n ? strokes.map((stroke) => stroke.map((point) => pagePointTurned(point, turn)))\n : strokes;\n drawn.set(shape, out);\n return out;\n}\n\n/** A line's two ends where they are drawn. */\nexport function drawnLineOf(shape: LineShape): { start: Point; end: Point } {\n const [start, end] = drawnStrokesOf(shape)[0]!;\n return { start: start!, end: end! };\n}\n\n/** A poly's vertices where they are drawn. */\nexport const drawnVerticesOf = (shape: PolyShape): Point[] => drawnStrokesOf(shape)[0]!;\n\n/**\n * Where the shape turns: the middle of the box around its upright points. The\n * turn leaves it where it is, so it is also the drawing's middle; a caption or\n * an arrowhead never moves it.\n */\nconst pointsMiddleOf = (shape: PointsShape): Point =>\n rectCenter(unionRect(uprightStrokesOf(shape).flat()));\n\n/** The box around the drawn points. */\nconst pointsBounds = (shape: PointsShape): Rect => unionRect(drawnStrokesOf(shape).flat());\n\n/** The shape moved by `delta`. */\nfunction pointsTranslate<S extends PointsShape>(shape: S, delta: Point): S {\n if (!delta.x && !delta.y) return shape;\n return mapUpright(shape, (point) => ({ x: point.x + delta.x, y: point.y + delta.y }));\n}\n\n/** Moves smaller than this are float noise from a turn about the shape's own middle. */\nconst NOISE = 1e-9;\n\n/**\n * The shape turned `degrees` clockwise about `pivot`: its middle orbits the\n * pivot (the upright points move with it), and its turn grows. About its own\n * middle, only the turn changes.\n */\nfunction pointsRotateAbout<S extends PointsShape>(shape: S, pivot: Point, degrees: number): S {\n const middle = pointsMiddleOf(shape);\n const moved = rotatePoint(middle, pivot, degrees);\n const delta = { x: moved.x - middle.x, y: moved.y - middle.y };\n const shifted =\n Math.abs(delta.x) < NOISE && Math.abs(delta.y) < NOISE ? shape : pointsTranslate(shape, delta);\n return { ...shifted, rotation: normalizeDeg(shape.rotation + degrees) };\n}\n\n/**\n * The shape scaled about `anchor` by `(sx, sy)`. Upright, the points scale\n * directly. Turned (a multi-selection scales a turned member the same in both\n * directions), the upright points scale about their middle, which moves with\n * the scale, and the turn stays.\n */\nfunction pointsScaleAbout<S extends PointsShape>(\n shape: S,\n anchor: Point,\n sx: number,\n sy: number,\n): S {\n const about = shape.rotation ? pointsMiddleOf(shape) : anchor;\n const middle = shape.rotation\n ? { x: anchor.x + (about.x - anchor.x) * sx, y: anchor.y + (about.y - anchor.y) * sy }\n : anchor;\n return mapUpright(shape, (point) => ({\n x: middle.x + (point.x - about.x) * sx,\n y: middle.y + (point.y - about.y) * sy,\n }));\n}\n\n/** The shape straightened: turned back about `pivot` (its own middle by default). */\nfunction pointsUpright<S extends PointsShape>(shape: S, pivot?: Point): S {\n if (!shape.rotation) return shape;\n return pointsRotateAbout(shape, pivot ?? pointsMiddleOf(shape), -shape.rotation);\n}\n\n/** The vertex handles, where the points are drawn; ink has none. */\nfunction pointsHandles(shape: PointsShape): Handle[] {\n if (shape.kind === 'ink') return [];\n return drawnStrokesOf(shape)[0]!.map((at, i) => ({ id: `v${i}`, at, cursor: 'crosshair' }));\n}\n\n/** The shape with vertex `handle` (`v<i>`) dragged to the drawn point `to`; the upright points follow. */\nfunction pointsDrag<S extends PointsShape>(shape: S, handle: string, to: Point): S {\n if (shape.kind === 'ink') return shape;\n const index = Number(handle.slice(1));\n const points = drawnStrokesOf(shape)[0]!;\n if (!Number.isInteger(index) || index < 0 || index >= points.length) return shape;\n const moved = points.slice();\n moved[index] = to;\n if (!shape.rotation) return withUprightStrokes(shape, [moved]);\n const turn = pageTurnOfDrawn(moved, shape.rotation);\n return withUprightStrokes(shape, [moved.map((point) => pagePointUnturned(point, turn))]);\n}\n\n/* ── drawing ─────────────────────────────────────────────────────────────── */\n\n/** Miter limit shared by the bounds math and the SVG renderer (`stroke-miterlimit`),\n * so the computed box and the drawn stroke always agree on where a sharp join\n * bevels instead of spiking. 10 = the PDF default (also what the baked /AP uses). */\nexport const MITER_LIMIT = 10;\n\n/**\n * The outline points of a mitred, butt-capped polyline (open or closed) stroked\n * at `strokeWidth`: each segment's two side offsets (the straight extents + both\n * bevel corners) plus each interior join's outer miter tip — added only while the\n * join is within `MITER_LIMIT` (past that the renderer bevels it, and the segment\n * offsets already bound it). `unionRect` of these is the tight, asymmetric visual\n * box: a pointy join grows the box only on the side it actually spikes.\n *\n * Miter kinds only (line / polyline / polygon). Ink is round-capped/round-joined,\n * never spikes, and is bounded elsewhere by a plain half-width grow.\n */\nfunction strokeOutlinePoints(points: Point[], closed: boolean, strokeWidth: number): Point[] {\n const halfWidth = strokeWidth / 2;\n const pointCount = points.length;\n if (pointCount === 0) return [];\n if (pointCount === 1 || halfWidth === 0) return [...points];\n\n const segCount = closed ? pointCount : pointCount - 1;\n const dir: Point[] = [];\n const nrm: Point[] = [];\n for (let i = 0; i < segCount; i++) {\n const start = points[i]!;\n const end = points[(i + 1) % pointCount]!;\n const len = Math.hypot(end.x - start.x, end.y - start.y) || 1;\n const ux = (end.x - start.x) / len;\n const uy = (end.y - start.y) / len;\n dir.push({ x: ux, y: uy });\n nrm.push({ x: -uy, y: ux }); // a unit normal (either side; sign is re-picked below)\n }\n\n const out: Point[] = [];\n // Segment side offsets at both ends — covers the straight extents, the butt\n // caps at open ends, and the bevel corners of any beveled join.\n for (let i = 0; i < segCount; i++) {\n const start = points[i]!;\n const end = points[(i + 1) % pointCount]!;\n const nx = nrm[i]!.x * halfWidth;\n const ny = nrm[i]!.y * halfWidth;\n out.push({ x: start.x + nx, y: start.y + ny }, { x: start.x - nx, y: start.y - ny });\n out.push({ x: end.x + nx, y: end.y + ny }, { x: end.x - nx, y: end.y - ny });\n }\n\n // Interior joins: the outer miter tip, gated by the miter limit.\n const joinStart = closed ? 0 : 1;\n const joinEnd = closed ? pointCount : pointCount - 1; // vertices [joinStart, joinEnd)\n for (let vertexIndex = joinStart; vertexIndex < joinEnd; vertexIndex++) {\n const inIdx = closed ? (vertexIndex - 1 + pointCount) % pointCount : vertexIndex - 1;\n const outIdx = vertexIndex; // the segment starting at vertexIndex, open or closed\n const incoming = dir[inIdx]!; // previous -> vertexIndex\n const outgoing = dir[outIdx]!; // vertexIndex -> next\n const n1 = nrm[inIdx]!;\n const n2 = nrm[outIdx]!;\n // Outer bisector direction: opposite the interior bisector `outgoing - incoming`.\n const bx = incoming.x - outgoing.x;\n const by = incoming.y - outgoing.y;\n if (Math.hypot(bx, by) < 1e-9) continue; // straight run: no spike beyond the offsets\n let mhx = n1.x + n2.x;\n let mhy = n1.y + n2.y;\n const ml = Math.hypot(mhx, mhy);\n if (ml < 1e-9) continue; // exact hairpin: renderer bevels\n mhx /= ml;\n mhy /= ml;\n if (mhx * bx + mhy * by < 0) {\n mhx = -mhx; // point the miter unit vector to the outer side\n mhy = -mhy;\n }\n const cosHalf = Math.abs(mhx * n1.x + mhy * n1.y); // cos(deviation/2)\n if (cosHalf < 1e-9) continue;\n const miterLen = halfWidth / cosHalf;\n if (miterLen > MITER_LIMIT * halfWidth) continue; // too sharp: renderer bevels → offsets bound it\n const vertex = points[vertexIndex]!;\n out.push({ x: vertex.x + mhx * miterLen, y: vertex.y + mhy * miterLen });\n }\n return out;\n}\n\n/**\n * The outline points of `nodes` stroked at `strokeWidth`, as the renderer\n * draws them: a line or poly with butt caps and mitred joins\n * (`strokeOutlinePoints`), an ellipse or rect grown by half the stroke.\n * `unionRect` of them is the box they paint.\n */\nexport function strokedOutlineOf(nodes: readonly RenderNode[], strokeWidth: number): Point[] {\n return nodes.flatMap((node) => {\n switch (node.kind) {\n case 'line':\n return strokeOutlinePoints([node.a, node.b], false, strokeWidth);\n case 'poly':\n return strokeOutlinePoints(node.points, node.closed, strokeWidth);\n case 'ellipse':\n case 'rect':\n return rectCornerPoints(expandRect(node.rect, strokeWidth / 2));\n case 'path':\n return [];\n }\n });\n}\n\ntype EndingSeg = { tip: Point; angle: number; ending: LineEnding | undefined };\n\n/** The start/end tips of a line / open poly as drawn, each with the segment angle\n * pointing out of the body into the tip (so an arrowhead opens back toward the line). */\nfunction endingSegs(shape: PointsShape): EndingSeg[] {\n if (shape.kind === 'ink' || !shape.lineEndings) return [];\n if (shape.kind === 'poly' && shape.closed) return [];\n const points = drawnStrokesOf(shape)[0]!;\n const count = points.length;\n if (count < 2) return [];\n const first = points[0]!;\n const second = points[1]!;\n const last = points[count - 1]!;\n const beforeLast = points[count - 2]!;\n return [\n {\n tip: first,\n angle: Math.atan2(first.y - second.y, first.x - second.x),\n ending: shape.lineEndings.start,\n },\n {\n tip: last,\n angle: Math.atan2(last.y - beforeLast.y, last.x - beforeLast.x),\n ending: shape.lineEndings.end,\n },\n ];\n}\n\n/**\n * What the shape draws, as the engine's `rect` takes it in. Ink is round-capped\n * and round-joined, so its strokes grow by half the width. A line or poly wraps\n * its actual stroke outline (per join, and each ending's own outline), so a\n * mitred arrowhead tip is enclosed exactly. A closed poly's cloud reaches past\n * its vertices by the cloud's extent.\n */\nfunction pointsDrawnBounds(shape: PointsShape, stroke: Stroke): Rect {\n const { strokeWidth, cloudyIntensity } = stroke;\n const strokes = drawnStrokesOf(shape);\n if (shape.kind === 'ink') return expandRect(unionRect(strokes.flat()), strokeWidth / 2);\n const points = strokes[0]!;\n const closed = shape.kind === 'poly' && shape.closed;\n if (closed && cloudyIntensity) return cloudyPolyBounds(points, cloudyIntensity, strokeWidth);\n // Arrowheads, diamonds and squares are stroked polys whose sharp corners\n // miter like the body; a circle ending grows by half the stroke.\n const endings = endingSegs(shape).flatMap((seg) =>\n endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth),\n );\n return unionRect([\n ...strokeOutlinePoints(points, closed, strokeWidth),\n ...strokedOutlineOf(endings, strokeWidth),\n ]);\n}\n\n/**\n * The oriented box around what the shape draws: the drawn bounds of its\n * upright points, turned about its middle — the snug tilted rectangle.\n */\nfunction pointsCorners(shape: PointsShape, stroke: Stroke): [Point, Point, Point, Point] {\n const upright = { ...shape, rotation: 0 };\n const corners = rectCornerPoints(pointsDrawnBounds(upright, stroke));\n if (!shape.rotation) return corners as [Point, Point, Point, Point];\n const middle = pointsMiddleOf(shape);\n return corners.map((corner) => rotatePoint(corner, middle, shape.rotation)) as [\n Point,\n Point,\n Point,\n Point,\n ];\n}\n\n/**\n * What the shape paints: each drawn stroke's ink, a filled polygon's inside,\n * and the endings. A cloudy polygon's ink runs along its cloud's curves, and\n * filled, it paints the polygon and the ring its curves close.\n */\nfunction pointsPainted(shape: PointsShape, stroke: Stroke, filled: boolean): PaintedPiece[] {\n const { strokeWidth, cloudyIntensity } = stroke;\n const halfWidth = strokeWidth / 2;\n const strokes = drawnStrokesOf(shape);\n const closed = shape.kind === 'poly' && shape.closed;\n const outline = strokes[0];\n const pieces: PaintedPiece[] = [];\n if (outline && closed && cloudyIntensity && outline.length >= 3) {\n const curves = cloudyPolyOutline(outline, cloudyIntensity, strokeWidth);\n if (filled) {\n pieces.push({ kind: 'area', ring: outline });\n for (const ring of curves) pieces.push({ kind: 'area', ring });\n }\n for (const points of curves) pieces.push({ kind: 'stroke', points, closed: true, halfWidth });\n return pieces;\n }\n if (outline && filled && closed) pieces.push({ kind: 'area', ring: outline });\n for (const points of strokes) pieces.push({ kind: 'stroke', points, closed, halfWidth });\n for (const seg of endingSegs(shape))\n pieces.push(\n ...endingPieces(endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth), strokeWidth),\n );\n return pieces;\n}\n\n/**\n * What the shape draws, where it is drawn: a line, a poly (a closed one's\n * cloud as PDFium bakes it: curls on the vertex path, reaching out), each\n * ink stroke as an open polyline, and the endings.\n */\nfunction pointsScene(shape: PointsShape, stroke: Stroke): RenderNode[] {\n const { strokeWidth, cloudyIntensity } = stroke;\n const strokes = drawnStrokesOf(shape);\n if (shape.kind === 'ink')\n return strokes.map((stroke) => ({ kind: 'poly', points: stroke, closed: false }));\n const points = strokes[0]!;\n if (shape.kind === 'poly' && shape.closed && cloudyIntensity && points.length >= 3)\n return [{ kind: 'path', d: cloudyPolyPath(points, cloudyIntensity, strokeWidth) }];\n const nodes: RenderNode[] =\n shape.kind === 'line'\n ? [{ kind: 'line', a: points[0]!, b: points[1]! }]\n : [{ kind: 'poly', points, closed: shape.closed }];\n for (const seg of endingSegs(shape))\n nodes.push(...endingNodes(seg.tip, seg.angle, seg.ending, strokeWidth));\n return nodes;\n}\n\n/** The points family: points kept upright and the turn that draws them. */\nexport const pointsFamily: ShapeFamily<PointsShape> = {\n read: readPoints,\n write: writePoints,\n placed: placePoints,\n bounds: pointsBounds,\n drawnBounds: pointsDrawnBounds,\n rect: pointsDrawnBounds,\n selectionBounds: pointsDrawnBounds,\n oriented: () => true,\n turnedCorners: pointsCorners,\n pivot: pointsMiddleOf,\n translate: pointsTranslate,\n rotateAbout: pointsRotateAbout,\n scaleAbout: pointsScaleAbout,\n upright: pointsUpright,\n handles: pointsHandles,\n drag: pointsDrag,\n painted: pointsPainted,\n scene: pointsScene,\n};\n","/**\n * The quads family: text markup (highlight, underline, squiggly, strikeout)\n * and text redaction. Its shape is the engine's own field, `quadPoints`: one\n * quad per line of text, corners named as the text stands. The quads follow\n * their text, so no gesture resizes or turns them; a hit anywhere inside a\n * quad grabs the mark.\n */\nimport { quadCorners, quadRing, type Quad } from '@embedpdf/core-geometry';\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { expandRect, unionRect } from '../rect';\nimport type { Point, Rect, RenderNode, Stroke } from '../types';\nimport type { ShapeFamily } from './family';\n\n/** A quads family record's shape: its text's quads. */\nexport interface QuadsShape {\n kind: 'quads';\n quadPoints: Quad[];\n}\n\ntype QuadsAnnotation = Extract<\n Annotation,\n { subtype: 'highlight' | 'underline' | 'squiggly' | 'strikeout' | 'redact' }\n>;\n\n/** A text markup's or text redaction's shape, read off its annotation. */\nfunction readQuads(annotation: Annotation): QuadsShape {\n return { kind: 'quads', quadPoints: (annotation as QuadsAnnotation).quadPoints };\n}\n\n/** The box around the quads. */\nconst quadsBounds = (shape: QuadsShape): Rect => unionRect(shape.quadPoints.flatMap(quadCorners));\n\n/** What the marks draw: the quads, grown by half the stroke (an underline's or squiggle's). */\nconst quadsDrawnBounds = (shape: QuadsShape, { strokeWidth }: Stroke): Rect =>\n expandRect(quadsBounds(shape), strokeWidth / 2);\n\n/** The middle of the quads' corners: where they would turn. */\nfunction quadsCentroid(shape: QuadsShape): Point {\n const points = shape.quadPoints.flatMap(quadCorners);\n const count = points.length || 1;\n return {\n x: points.reduce((sum, point) => sum + point.x, 0) / count,\n y: points.reduce((sum, point) => sum + point.y, 0) / count,\n };\n}\n\n/** Map a quad's corners through `move` (the names ride along). */\nconst mapQuad = (quad: Quad, move: (point: Point) => Point): Quad => ({\n upperLeft: move(quad.upperLeft),\n upperRight: move(quad.upperRight),\n lowerLeft: move(quad.lowerLeft),\n lowerRight: move(quad.lowerRight),\n});\n\n/** The shape moved by `delta`. */\nfunction quadsTranslate(shape: QuadsShape, delta: Point): QuadsShape {\n const move = (point: Point): Point => ({ x: point.x + delta.x, y: point.y + delta.y });\n return { ...shape, quadPoints: shape.quadPoints.map((quad) => mapQuad(quad, move)) };\n}\n\n/**\n * A closed ring per quad (upper left round to lower left). The markup\n * painter draws each subtype from the quads itself; this keeps the generic\n * scene right regardless, turned text included.\n */\nconst quadsScene = (shape: QuadsShape): RenderNode[] =>\n shape.quadPoints.map((quad) => ({ kind: 'poly', points: quadRing(quad), closed: true }));\n\n/**\n * The quads family: marks bound to their text. They move with a selection,\n * but no gesture turns, scales or drags them, and they have no turned box.\n */\nexport const quadsFamily: ShapeFamily<QuadsShape> = {\n read: readQuads,\n write: (shape) => ({ quadPoints: shape.quadPoints }),\n // Quads are made from a text selection, never placed.\n placed: () => null,\n bounds: quadsBounds,\n drawnBounds: quadsDrawnBounds,\n rect: quadsDrawnBounds,\n selectionBounds: quadsBounds,\n oriented: () => false,\n turnedCorners: () => null,\n pivot: quadsCentroid,\n translate: quadsTranslate,\n rotateAbout: (shape) => shape,\n scaleAbout: (shape) => shape,\n upright: (shape) => shape,\n handles: () => [],\n drag: (shape) => shape,\n // Each quad is filled: a highlight's colour, or the text a mark covers.\n painted: (shape) => shape.quadPoints.map((quad) => ({ kind: 'area', ring: quadRing(quad) })),\n scene: quadsScene,\n};\n","/**\n * The text box family: free text. Its shape is the engine's own fields: the\n * text box before any turn (`box`), its turn (`rotation`), and for a callout\n * its line (`calloutLine`: the tip, the knee when it bends, and the end on\n * the box) with the ending at the tip (`lineEnding`).\n *\n * The line's end follows the box as the engine's rule has it: when the box\n * moves, turns or resizes, or the tip or knee moves, the end is where the\n * line now meets the box ({@link calloutEnd}); otherwise the stored end\n * stays. Only a plain text box turns with the rotate gesture; a callout's box\n * keeps the turn it was made with.\n *\n * A plain text box's selection frame is its box. A callout's frame is\n * everything it paints (the box, the line and the ending), so it is grabbed,\n * grouped and kept on the page as one object; its handles still act on the\n * box, the tip and the knee.\n */\nimport type { Annotation, LineEnding } from '@embedpdf/engine-core/runtime';\n\nimport { endingNodes, endingPieces, endingPoints } from '../endings';\nimport { bodyPieces, type PaintedPiece } from '../painted';\nimport {\n expandRect,\n insetRect,\n rectCenter,\n rectCornerPoints,\n rotatePoint,\n rotatedAabb,\n unionRect,\n} from '../rect';\nimport type { Handle, Placement, Point, Rect, RenderNode, Stroke } from '../types';\nimport {\n boxCorners,\n boxHandles,\n boxResize,\n boxRotateAbout,\n boxScaleAbout,\n boxTranslate,\n type TurnedBox,\n} from './box';\nimport type { ShapeFamily } from './family';\nimport { strokedOutlineOf } from './points';\n\ntype FreeTextAnnotation = Extract<Annotation, { subtype: 'free-text' }>;\n\n/** A callout's line: its tip, its knee when it bends, and where it meets the box. */\nexport type CalloutLine = NonNullable<FreeTextAnnotation['calloutLine']>;\n\n/** A free text's shape: the engine's box, turn, and a callout's line. */\nexport interface TextBoxShape extends TurnedBox {\n kind: 'text-box';\n /** A callout's line; `null` for a plain text box. */\n calloutLine: CalloutLine | null;\n /** The ending at a callout's tip. */\n lineEnding: LineEnding | null;\n}\n\n/** A plain text box where a create gesture places a box: typed into from empty, turned to read upright. */\nfunction placeTextBox(placement: Placement): TextBoxShape | null {\n if (placement.kind !== 'box') return null;\n return {\n kind: 'text-box',\n box: placement.rect,\n rotation: placement.rot,\n calloutLine: null,\n lineEnding: null,\n };\n}\n\n/** A free text's shape, read off its annotation. A line counts only on a callout. */\nfunction readTextBox(read: Annotation): TextBoxShape {\n const annotation = read as FreeTextAnnotation;\n const line = annotation.intent === 'free-text-callout' ? (annotation.calloutLine ?? null) : null;\n return {\n kind: 'text-box',\n box: annotation.box,\n rotation: annotation.rotation ?? 0,\n calloutLine: line,\n lineEnding: line ? (annotation.lineEnding ?? 'none') : null,\n };\n}\n\n/**\n * The engine fields that state `shape`: its `box` and `rotation` (`null` when\n * upright, so a turn is cleared rather than kept), and a callout's line and\n * ending.\n */\nfunction writeTextBox(shape: TextBoxShape): {\n box: Rect;\n rotation: number | null;\n calloutLine?: CalloutLine;\n lineEnding?: LineEnding;\n} {\n return {\n box: shape.box,\n rotation: shape.rotation || null,\n ...(shape.calloutLine\n ? { calloutLine: shape.calloutLine, lineEnding: shape.lineEnding ?? 'none' }\n : {}),\n };\n}\n\n/**\n * Where a callout's line meets its box: the middle of the side `toward` (the\n * knee, else the tip) lies beyond, chosen by which way it is farther from the\n * box's middle, across or up and down. A turned box decides in its own frame,\n * and the point lands on the turned side, the one the page shows. The\n * engine's rule, in page space.\n */\nexport function calloutEnd(box: Rect, toward: Point, rotation = 0): Point {\n const middle = rectCenter(box);\n const local = rotation ? rotatePoint(toward, middle, -rotation) : toward;\n const dx = local.x - middle.x;\n const dy = local.y - middle.y;\n const end =\n Math.abs(dx) >= Math.abs(dy)\n ? { x: dx >= 0 ? box.x + box.width : box.x, y: middle.y }\n : { x: middle.x, y: dy >= 0 ? box.y + box.height : box.y };\n return rotation ? rotatePoint(end, middle, rotation) : end;\n}\n\n/** The line from `tip`, through `knee` when it bends, to where it meets the box. */\nconst lineTo = (box: TurnedBox, tip: Point, knee?: Point): CalloutLine =>\n knee\n ? [tip, knee, calloutEnd(box.box, knee, box.rotation)]\n : [tip, calloutEnd(box.box, tip, box.rotation)];\n\n/** A new callout: its box and turn, a line from `tip` (through `knee`), and the ending at the tip. */\nexport function calloutShape(\n box: Rect,\n rotation: number,\n tip: Point,\n knee: Point | undefined,\n lineEnding: LineEnding,\n): TextBoxShape {\n const turned = { box, rotation };\n return { kind: 'text-box', ...turned, calloutLine: lineTo(turned, tip, knee), lineEnding };\n}\n\n/** The shape with its line's end where the line now meets the box. */\nfunction endFollows(shape: TextBoxShape): TextBoxShape {\n const line = shape.calloutLine;\n if (!line) return shape;\n return { ...shape, calloutLine: lineTo(shape, line[0], line.length === 3 ? line[1] : undefined) };\n}\n\n/** The shape moved by `delta`: the box and the whole line. */\nfunction textBoxTranslate(shape: TextBoxShape, delta: Point): TextBoxShape {\n const moved = boxTranslate(shape, delta);\n const line = shape.calloutLine;\n if (!line) return moved;\n const move = (point: Point): Point => ({ x: point.x + delta.x, y: point.y + delta.y });\n return { ...moved, calloutLine: line.map(move) as unknown as CalloutLine };\n}\n\n/** A plain text box turned `degrees` about `pivot`; a callout stays as it is. */\nfunction textBoxRotateAbout(shape: TextBoxShape, pivot: Point, degrees: number) {\n return shape.calloutLine ? shape : boxRotateAbout(shape, pivot, degrees);\n}\n\n/** A plain text box scaled about `anchor`; a callout stays as it is. */\nfunction textBoxScaleAbout(\n shape: TextBoxShape,\n anchor: Point,\n sx: number,\n sy: number,\n minSize?: number,\n) {\n return shape.calloutLine ? shape : boxScaleAbout(shape, anchor, sx, sy, minSize);\n}\n\n/** The shape upright: its turn cleared, and a callout's end back on the upright box. */\nfunction textBoxUpright(shape: TextBoxShape): TextBoxShape {\n return endFollows({ ...shape, rotation: 0 });\n}\n\n/** The box's eight resize handles, and a callout's tip and knee. */\nfunction textBoxHandles(shape: TextBoxShape): Handle[] {\n const handles = boxHandles(shape);\n const line = shape.calloutLine;\n if (line) {\n handles.push({ id: 'callout-tip', at: line[0], cursor: 'crosshair' });\n if (line.length === 3) handles.push({ id: 'callout-knee', at: line[1], cursor: 'crosshair' });\n }\n return handles;\n}\n\n/** The shape with `handle` dragged to `to`: the tip, the knee, or a side of the box. */\nfunction textBoxDrag(shape: TextBoxShape, handle: string, to: Point): TextBoxShape {\n const line = shape.calloutLine;\n if (line && handle === 'callout-tip') {\n return endFollows({\n ...shape,\n calloutLine: line.length === 3 ? [to, line[1], line[2]] : [to, line[1]],\n });\n }\n if (line && handle === 'callout-knee') {\n return line.length === 3\n ? endFollows({ ...shape, calloutLine: [line[0], to, line[2]] })\n : shape;\n }\n return endFollows(boxResize(shape, handle, to));\n}\n\n/** The angle the arrow at the tip points: out of the line, into the tip. */\nconst tipAngle = (line: CalloutLine): number =>\n Math.atan2(line[0].y - line[1].y, line[0].x - line[1].x);\n\n/**\n * What the shape draws, the engine's `rect`: a plain box; a callout's box as\n * the page shows it, its line and the arrow at its tip, grown by half the\n * stroke.\n */\nfunction textBoxDrawnBounds(shape: TextBoxShape, { strokeWidth }: Stroke): Rect {\n const line = shape.calloutLine;\n if (!line) return shape.box;\n const points = [...boxCorners(shape), ...line];\n if (shape.lineEnding) {\n points.push(...endingPoints(line[0], tipAngle(line), shape.lineEnding, strokeWidth));\n }\n return expandRect(unionRect(points), strokeWidth / 2);\n}\n\n/**\n * The upright page box around all it paints. The box, turned about its\n * middle: its border lies inside it. A callout's line, stroked from its tip\n * (a butt end) and run half the stroke into the box's border so it meets the\n * box without a gap, and the ending at its tip.\n */\nfunction textBoxRect(shape: TextBoxShape, { strokeWidth }: Stroke): Rect {\n const box = rotatedAabb(shape.box, shape.rotation);\n const line = shape.calloutLine;\n if (!line) return box;\n const end = line[line.length - 1]!;\n const before = line[line.length - 2]!;\n const length = Math.hypot(end.x - before.x, end.y - before.y) || 1;\n const reach = strokeWidth / 2 / length;\n const drawn = [\n ...line.slice(0, -1),\n { x: end.x + (end.x - before.x) * reach, y: end.y + (end.y - before.y) * reach },\n ];\n const nodes: RenderNode[] = [\n { kind: 'poly', points: drawn, closed: false },\n ...endingNodes(line[0], tipAngle(line), shape.lineEnding ?? undefined, strokeWidth),\n ];\n return unionRect([...rectCornerPoints(box), ...strokedOutlineOf(nodes, strokeWidth)]);\n}\n\n/** What a selection wraps: a plain box, or everything a callout paints. */\nfunction textBoxSelectionBounds(shape: TextBoxShape, stroke: Stroke): Rect {\n return shape.calloutLine ? textBoxRect(shape, stroke) : shape.box;\n}\n\n/**\n * What the shape paints: its box, where its text is, grabbed anywhere in it\n * and near its edge; and a callout's line, the stroke wide, and the ending at\n * its tip.\n */\nfunction textBoxPainted(shape: TextBoxShape, { strokeWidth }: Stroke): PaintedPiece[] {\n const pieces = bodyPieces(boxCorners(shape));\n const line = shape.calloutLine;\n if (!line) return pieces;\n pieces.push({ kind: 'stroke', points: line, closed: false, halfWidth: strokeWidth / 2 });\n const ending = endingNodes(line[0], tipAngle(line), shape.lineEnding ?? undefined, strokeWidth);\n return [...pieces, ...endingPieces(ending, strokeWidth)];\n}\n\n/**\n * What the shape draws, as the AP generator bakes it: a callout's line and\n * the arrow at its tip, then the box's border inset half the stroke. The line's\n * end reaches under the border by half the stroke\n * (the generator's `adjusted_conn`), so the two meet without a gap. The text\n * itself is the framework's editable element, not part of the scene.\n */\nfunction textBoxScene(shape: TextBoxShape, { strokeWidth }: Stroke): RenderNode[] {\n const nodes: RenderNode[] = [];\n const line = shape.calloutLine;\n if (line) {\n const points = [...line];\n const last = points[points.length - 1]!;\n const previous = points[points.length - 2]!;\n const length = Math.hypot(last.x - previous.x, last.y - previous.y);\n if (strokeWidth > 0 && length > 0) {\n points[points.length - 1] = {\n x: last.x + ((last.x - previous.x) / length) * (strokeWidth / 2),\n y: last.y + ((last.y - previous.y) / length) * (strokeWidth / 2),\n };\n }\n nodes.push({ kind: 'poly', points, closed: false });\n if (shape.lineEnding)\n nodes.push(...endingNodes(line[0], tipAngle(line), shape.lineEnding, strokeWidth));\n }\n const border = insetRect(shape.box, strokeWidth / 2);\n // A plain box is drawn upright: the frame it is painted in turns it\n // (`RenderItem.frame`). A callout's frame stays upright around its leader,\n // so its box is drawn turned, where the page shows it.\n if (!line || !shape.rotation) {\n nodes.push({ kind: 'rect', rect: border });\n return nodes;\n }\n const middle = rectCenter(shape.box);\n nodes.push({\n kind: 'poly',\n points: rectCornerPoints(border).map((corner) => rotatePoint(corner, middle, shape.rotation)),\n closed: true,\n });\n return nodes;\n}\n\n/**\n * The text box family: a free text's box and turn, and a callout's line.\n * Only a plain box turns; a callout's box keeps the turn it was made with,\n * and a selection outlines everything it paints, upright.\n */\nexport const textBoxFamily: ShapeFamily<TextBoxShape> = {\n read: readTextBox,\n write: writeTextBox,\n placed: placeTextBox,\n bounds: (shape) => shape.box,\n drawnBounds: textBoxDrawnBounds,\n rect: textBoxRect,\n selectionBounds: textBoxSelectionBounds,\n oriented: (shape) => !shape.calloutLine,\n turnedCorners: (shape) => (shape.calloutLine ? null : boxCorners(shape)),\n pivot: (shape) => rectCenter(shape.box),\n translate: textBoxTranslate,\n rotateAbout: textBoxRotateAbout,\n scaleAbout: textBoxScaleAbout,\n upright: textBoxUpright,\n handles: textBoxHandles,\n drag: textBoxDrag,\n // A text box is hit anywhere in its box, filled or not.\n painted: (shape, stroke) => textBoxPainted(shape, stroke),\n scene: textBoxScene,\n};\n\n/**\n * The text plate inset of a free-text box: twice the border width. The plate\n * — where text lays out, clips and scrolls — is the box deflated by this on\n * every side: the ink band and an equal breathing band, so the text never\n * touches the stroke. Acrobat's rule, measured 1–12 pt on plain boxes and\n * 1–7 pt on callouts; the engine's `FreeTextPlate` is the same formula, so\n * the live editor sits exactly where the baked text lands. Acrobat's thinnest\n * border is 1 pt; a width of 0 is ours alone and gives no inset (the plate is\n * the box).\n */\nexport function textPlateInset(strokeWidth: number): number {\n return 2 * Math.max(0, strokeWidth);\n}\n","/**\n * Every shape family, and the family of any shape. A kind names the family\n * that reads its shape off the annotation (`kinds/`); from then on the shape\n * itself says which family answers for it, by its `kind`.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport type { Shape } from '../types';\nimport { boxFamily } from './box';\nimport { caretFamily } from './caret';\nimport type { ShapeFamily } from './family';\nimport { pointsFamily } from './points';\nimport { quadsFamily } from './quads';\nimport { textBoxFamily } from './text-box';\n\nexport type { Corners, ShapeFamily } from './family';\nexport { boxFamily, caretFamily, pointsFamily, quadsFamily, textBoxFamily };\n\n/** The family that answers for each kind of shape: the points family for lines, polys and ink. */\nconst FAMILY_OF: Record<Shape['kind'], ShapeFamily> = {\n box: boxFamily,\n caret: caretFamily,\n 'text-box': textBoxFamily,\n quads: quadsFamily,\n line: pointsFamily,\n poly: pointsFamily,\n ink: pointsFamily,\n};\n\n/**\n * The family that answers for `shape`. Each family works on its own shapes\n * only; looking it up by the shape's `kind` is what hands it one.\n */\nexport const familyOf = (shape: Shape): ShapeFamily => FAMILY_OF[shape.kind];\n\n/**\n * The family of a kind whose annotation says which shape it has: `pick`\n * names the family that reads it, and the shape's own family does the rest.\n */\nexport function familyChosenBy(pick: (annotation: Annotation) => ShapeFamily): ShapeFamily {\n return {\n read: (annotation) => pick(annotation).read(annotation),\n write: (shape, subtype) => familyOf(shape).write(shape, subtype),\n placed: (placement, annotation) => pick(annotation).placed(placement, annotation),\n bounds: (shape) => familyOf(shape).bounds(shape),\n drawnBounds: (shape, stroke) => familyOf(shape).drawnBounds(shape, stroke),\n rect: (shape, stroke) => familyOf(shape).rect(shape, stroke),\n selectionBounds: (shape, stroke) => familyOf(shape).selectionBounds(shape, stroke),\n oriented: (shape) => familyOf(shape).oriented(shape),\n turnedCorners: (shape, stroke) => familyOf(shape).turnedCorners(shape, stroke),\n pivot: (shape) => familyOf(shape).pivot(shape),\n translate: (shape, delta) => familyOf(shape).translate(shape, delta),\n rotateAbout: (shape, pivot, degrees) => familyOf(shape).rotateAbout(shape, pivot, degrees),\n scaleAbout: (shape, anchor, sx, sy, minSize) =>\n familyOf(shape).scaleAbout(shape, anchor, sx, sy, minSize),\n upright: (shape, pivot) => familyOf(shape).upright(shape, pivot),\n handles: (shape) => familyOf(shape).handles(shape),\n drag: (shape, handle, to) => familyOf(shape).drag(shape, handle, to),\n painted: (shape, stroke, filled) => familyOf(shape).painted(shape, stroke, filled),\n scene: (shape, stroke) => familyOf(shape).scene(shape, stroke),\n };\n}\n","/**\n * What an annotation kind is: the shape of a kind declaration, and the\n * vocabulary it is written in (its capabilities and its sidebar fields).\n * Each kind is declared in its own file in this folder; `index.ts` lists\n * them all.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport type { ShapeFamily } from '../shapes';\nimport type { Style, TextStyle } from '../types';\n\n/** The flags an annotation carries, each a `flag` property of every kind. */\nexport type FlagKey =\n | 'invisible'\n | 'hidden'\n | 'print'\n | 'noZoom'\n | 'noRotate'\n | 'noView'\n | 'readOnly'\n | 'locked'\n | 'toggleNoView'\n | 'lockedContents';\n\n/**\n * One choice of a `choice` property, as a picker shows it: the value it\n * writes, and its name, `label` in English and `labelKey` to translate it\n * (`annotation.lineEndings.openArrow`).\n */\nexport interface AnnotationOption {\n readonly value: string;\n readonly label: string;\n readonly labelKey: string;\n}\n\n/**\n * One property a style panel edits, as a UI contract: which field, edited\n * with which control, labelled what. A panel switches on `control` (or on\n * `key`, for a richer editor of its own), reads `values[property.key]` and\n * writes `{ [property.key]: value }`, so each kind's list is its property\n * schema, kept in the library so every consumer gets it for free.\n *\n * `key` is the engine's field name, with three exceptions: the border's\n * `borderStyle` reads and writes `borderStyle`, `dashArray` and\n * `cloudyIntensity` together; `bold`, `italic` and `underline` are the rich\n * body's formatting; and `link` is an attached link, not a field of the\n * annotation.\n *\n * `label` is the English name and `labelKey` its translation key: a panel\n * shows `t(property.labelKey, { fallback: property.label })`, as a command's\n * label reads. The key names the wording, not the field, since one field is\n * called different things by different kinds: `color` is\n * `annotation.style.stroke` on a shape and `annotation.style.outline` on a\n * redaction mark. A `choice` property's options carry the same pair. Array\n * order is display order.\n */\nexport type AnnotationProperty =\n | {\n readonly key: 'color' | 'interiorColor' | 'fontColor';\n readonly control: 'color';\n readonly label: string;\n readonly labelKey: string;\n }\n | {\n readonly key: 'opacity' | 'strokeWidth' | 'fontSize';\n readonly control: 'number';\n readonly label: string;\n readonly labelKey: string;\n readonly min: number;\n readonly max: number;\n readonly step: number;\n }\n /** The border over `borderStyle`, `dashArray` and `cloudyIntensity`;\n * `cloudy` says whether this kind takes a cloudy border. */\n | {\n readonly key: 'borderStyle';\n readonly control: 'choice';\n readonly label: string;\n readonly labelKey: string;\n readonly options: readonly AnnotationOption[];\n readonly cloudy: boolean;\n }\n /** A value from a list: line endings, a font, an alignment, a blend mode, an icon. */\n | {\n readonly key: 'lineEndings' | 'fontFamily' | 'textAlign' | 'blendMode' | 'icon';\n readonly control: 'choice';\n readonly label: string;\n readonly labelKey: string;\n readonly options: readonly AnnotationOption[];\n }\n /** One of the annotation's flags, on or off. */\n | {\n readonly key: FlagKey;\n readonly control: 'flag';\n readonly label: string;\n readonly labelKey: string;\n }\n /** Free text, such as a redaction's label. */\n | {\n readonly key: 'overlayText';\n readonly control: 'text';\n readonly label: string;\n readonly labelKey: string;\n }\n /** Bold, italic or underline of a text box: the body's formatting, or,\n * while the text editor has a range, that range's runs. */\n | {\n readonly key: 'bold' | 'italic' | 'underline';\n readonly control: 'textFormat';\n readonly label: string;\n readonly labelKey: string;\n readonly format: 'bold' | 'italic' | 'underline';\n }\n /** Where it links to (a website or a page). Declared by the link kind (its\n * own target) and by every kind that may carry an attached link; kinds\n * that omit it (widgets, caret, redaction…) can't be links. */\n | {\n readonly key: 'link';\n readonly control: 'link';\n readonly label: string;\n readonly labelKey: string;\n };\n\n/** Orthogonal capability flags. Static data — the annotation's `/F` flags are\n * the runtime overrides (a locked annotation is never transformable, a hidden\n * one never renders, regardless of these — see flags.ts). */\nexport interface KindCaps {\n /** Can be clicked to select. */\n selectable: boolean;\n /** Can be dragged (by its body) to translate. */\n movable: boolean;\n /** Exposes the 8 box resize handles (shapes). */\n resizable: boolean;\n /** Exposes per-vertex handles (line endpoints, polygon/polyline vertices). */\n vertexEditable: boolean;\n /** Can be rotated (shapes, free text, lines/polys/ink). */\n rotatable: boolean;\n /** Can be moved as part of a multi-target (group) transform. */\n groupMovable: boolean;\n /** Can be uniformly scaled as part of a multi-target (group) transform — on\n * even for vertex kinds that have no single-shape box resize (their handles\n * are the vertices; in a group they scale fine). */\n groupResizable: boolean;\n /** Can be rotated as part of a multi-target (group) transform. */\n groupRotatable: boolean;\n /** Carries editable text content (free text, the comment popup). */\n textEditable: boolean;\n /** Can carry a comment/note + threaded replies (`/Contents` + `/Popup`). */\n commentable: boolean;\n /** Has a popup as its primary surface (the comment/Text icon). */\n hasPopup: boolean;\n /** Bound to underlying text (markup, caret) — never freely moved/resized. */\n anchored: boolean;\n /** Paints with the page's text, beneath every other kind (text markup, redaction marks). */\n paintsBeneath: boolean;\n /** Has an interior fill (`/IC`). */\n hasFill: boolean;\n /** Has line endings (`/LE` — line, polyline). */\n hasEndings: boolean;\n /** Can take a cloudy border effect (`/BE` — shapes). */\n hasCloudy: boolean;\n /** The whole body is visible content, so hit-testing grabs anywhere inside\n * the box (stamp images, note icons) — not just the stroke/fill like\n * outline shapes. */\n opaqueBody: boolean;\n /** Its raster is its drawing, drawn where its shape is: the kind draws none\n * of it live (a stamp's image, a form widget, a link's border). A lent\n * record can still draw live with its lender's painter (`drawsLive`). */\n rasterOnly: boolean;\n /** The `/F` ReadOnly flag is ignored for this kind (ISO 32000: widgets — a\n * ReadOnly form field must still be movable by a form designer; the\n * form-filling layer enforces field ReadOnly itself). */\n ignoresReadOnly: boolean;\n /** Behaves as if `/F` NoZoom is always set (screen-constant size — the\n * spec's rule for Text/note icons). See anchor.ts. */\n noZoom: boolean;\n /** Behaves as if `/F` NoRotate is always set (screen-upright — the spec's\n * rule for Text/note icons). See anchor.ts. */\n noRotate: boolean;\n}\n\n/** No capability at all: a kind spreads this and turns on what it can do. */\nexport const NO_CAPS: KindCaps = {\n selectable: false,\n movable: false,\n resizable: false,\n vertexEditable: false,\n rotatable: false,\n groupMovable: false,\n groupResizable: false,\n groupRotatable: false,\n textEditable: false,\n commentable: false,\n hasPopup: false,\n anchored: false,\n paintsBeneath: false,\n hasFill: false,\n hasEndings: false,\n hasCloudy: false,\n opaqueBody: false,\n rasterOnly: false,\n ignoresReadOnly: false,\n noZoom: false,\n noRotate: false,\n};\n\n/** One annotation kind: what it is, and what a user can do to it. */\nexport interface AnnotationKind {\n /** Its name: the PDF subtype, or a widget's field family (`widget-text`…). */\n readonly name: string;\n /**\n * The shape family that reads its shape off the annotation (`shapes/`).\n * The shape's family then hits, handles, moves and draws it.\n */\n readonly family: ShapeFamily;\n /**\n * How it is drawn: its colours, stroke and border, read off the annotation\n * with its kind's fill-ins (`styles.ts`).\n */\n readonly style: (annotation: Annotation) => Style;\n /**\n * How its text is set, for a kind with text: its font, size, colour and\n * alignment, read off the annotation (`texts.ts`).\n */\n readonly text?: (annotation: Annotation) => TextStyle;\n /** What a user can do to it. The annotation's `/F` flags override these at runtime (flags.ts). */\n readonly caps: KindCaps;\n /**\n * What a style panel edits, in display order, keyed by the engine's field\n * names. The flags every kind has are added by `propertiesOf`.\n */\n readonly properties: readonly AnnotationProperty[];\n}\n\n/**\n * Declares a kind. It returns the kind exactly as written: nothing is\n * registered and nothing is filled in. `index.ts` lists every kind.\n */\nexport const defineKind = <const Kind extends AnnotationKind>(kind: Kind): Kind => kind;\n","/**\n * The style-panel properties kinds share. A kind lists its own in its file, in\n * display order, from these and from ones only it has; the flags every kind\n * has are added by `propertiesOf` (props.ts). Each label has its translation\n * key beside it (`AnnotationProperty`), and so does each option.\n */\nimport type { AnnotationOption, AnnotationProperty } from './define';\n\nexport const OPACITY: AnnotationProperty = {\n key: 'opacity',\n control: 'number',\n label: 'Opacity',\n labelKey: 'annotation.style.opacity',\n min: 0.1,\n max: 1,\n step: 0.05,\n};\nexport const STROKE: AnnotationProperty = {\n key: 'color',\n control: 'color',\n label: 'Stroke',\n labelKey: 'annotation.style.stroke',\n};\nexport const FILL: AnnotationProperty = {\n key: 'interiorColor',\n control: 'color',\n label: 'Fill',\n labelKey: 'annotation.style.fill',\n};\nexport const COLOR: AnnotationProperty = {\n key: 'color',\n control: 'color',\n label: 'Color',\n labelKey: 'annotation.style.color',\n};\nexport const STROKE_WIDTH: AnnotationProperty = {\n key: 'strokeWidth',\n control: 'number',\n label: 'Stroke width',\n labelKey: 'annotation.style.strokeWidth',\n min: 0.5,\n max: 30,\n step: 0.5,\n};\n\nconst SOLID: AnnotationOption = {\n value: 'solid',\n label: 'Solid',\n labelKey: 'annotation.borderStyles.solid',\n};\nconst DASHED: AnnotationOption = {\n value: 'dashed',\n label: 'Dashed',\n labelKey: 'annotation.borderStyles.dashed',\n};\nconst CLOUDY: AnnotationOption = {\n value: 'cloudy',\n label: 'Cloudy',\n labelKey: 'annotation.borderStyles.cloudy',\n};\n\nexport const BORDER_CLOUDY: AnnotationProperty = {\n key: 'borderStyle',\n control: 'choice',\n label: 'Border',\n labelKey: 'annotation.style.border',\n options: [SOLID, DASHED, CLOUDY],\n cloudy: true,\n};\nexport const BORDER_PLAIN: AnnotationProperty = {\n key: 'borderStyle',\n control: 'choice',\n label: 'Border',\n labelKey: 'annotation.style.border',\n options: [SOLID, DASHED],\n cloudy: false,\n};\n\n/** Every line ending the engine draws. */\nexport const LINE_ENDING_NAMES = [\n 'none',\n 'square',\n 'circle',\n 'diamond',\n 'open-arrow',\n 'closed-arrow',\n 'butt',\n 'r-open-arrow',\n 'r-closed-arrow',\n 'slash',\n] as const;\n\n/** The line endings, in `LINE_ENDING_NAMES` order. */\nconst LINE_ENDING_OPTIONS: readonly AnnotationOption[] = [\n { value: 'none', label: 'None', labelKey: 'annotation.lineEndings.none' },\n { value: 'square', label: 'Square', labelKey: 'annotation.lineEndings.square' },\n { value: 'circle', label: 'Circle', labelKey: 'annotation.lineEndings.circle' },\n { value: 'diamond', label: 'Diamond', labelKey: 'annotation.lineEndings.diamond' },\n { value: 'open-arrow', label: 'Open arrow', labelKey: 'annotation.lineEndings.openArrow' },\n { value: 'closed-arrow', label: 'Closed arrow', labelKey: 'annotation.lineEndings.closedArrow' },\n { value: 'butt', label: 'Butt', labelKey: 'annotation.lineEndings.butt' },\n {\n value: 'r-open-arrow',\n label: 'Reverse open arrow',\n labelKey: 'annotation.lineEndings.reverseOpenArrow',\n },\n {\n value: 'r-closed-arrow',\n label: 'Reverse closed arrow',\n labelKey: 'annotation.lineEndings.reverseClosedArrow',\n },\n { value: 'slash', label: 'Slash', labelKey: 'annotation.lineEndings.slash' },\n];\n\nexport const LINE_ENDINGS: AnnotationProperty = {\n key: 'lineEndings',\n control: 'choice',\n label: 'Line endings',\n labelKey: 'annotation.style.lineEndings',\n options: LINE_ENDING_OPTIONS,\n};\n\n/** The blend modes an appearance stream can composite with. */\nconst BLEND_MODE_OPTIONS: readonly AnnotationOption[] = [\n { value: 'normal', label: 'Normal', labelKey: 'annotation.blendModes.normal' },\n { value: 'multiply', label: 'Multiply', labelKey: 'annotation.blendModes.multiply' },\n { value: 'screen', label: 'Screen', labelKey: 'annotation.blendModes.screen' },\n { value: 'overlay', label: 'Overlay', labelKey: 'annotation.blendModes.overlay' },\n { value: 'darken', label: 'Darken', labelKey: 'annotation.blendModes.darken' },\n { value: 'lighten', label: 'Lighten', labelKey: 'annotation.blendModes.lighten' },\n { value: 'color-dodge', label: 'Color dodge', labelKey: 'annotation.blendModes.colorDodge' },\n { value: 'color-burn', label: 'Color burn', labelKey: 'annotation.blendModes.colorBurn' },\n { value: 'hard-light', label: 'Hard light', labelKey: 'annotation.blendModes.hardLight' },\n { value: 'soft-light', label: 'Soft light', labelKey: 'annotation.blendModes.softLight' },\n { value: 'difference', label: 'Difference', labelKey: 'annotation.blendModes.difference' },\n { value: 'exclusion', label: 'Exclusion', labelKey: 'annotation.blendModes.exclusion' },\n { value: 'hue', label: 'Hue', labelKey: 'annotation.blendModes.hue' },\n { value: 'saturation', label: 'Saturation', labelKey: 'annotation.blendModes.saturation' },\n { value: 'color', label: 'Color', labelKey: 'annotation.blendModes.color' },\n { value: 'luminosity', label: 'Luminosity', labelKey: 'annotation.blendModes.luminosity' },\n];\n\nexport const BLEND_MODE: AnnotationProperty = {\n key: 'blendMode',\n control: 'choice',\n label: 'Blend mode',\n labelKey: 'annotation.style.blendMode',\n options: BLEND_MODE_OPTIONS,\n};\n\n/** The standard PDF fonts; an app adds the fonts it registered. */\nconst STANDARD_FONT_OPTIONS: readonly AnnotationOption[] = [\n { value: 'courier', label: 'Courier', labelKey: 'annotation.fonts.courier' },\n { value: 'courier-bold', label: 'Courier Bold', labelKey: 'annotation.fonts.courierBold' },\n {\n value: 'courier-bold-oblique',\n label: 'Courier Bold Oblique',\n labelKey: 'annotation.fonts.courierBoldOblique',\n },\n {\n value: 'courier-oblique',\n label: 'Courier Oblique',\n labelKey: 'annotation.fonts.courierOblique',\n },\n { value: 'helvetica', label: 'Helvetica', labelKey: 'annotation.fonts.helvetica' },\n { value: 'helvetica-bold', label: 'Helvetica Bold', labelKey: 'annotation.fonts.helveticaBold' },\n {\n value: 'helvetica-bold-oblique',\n label: 'Helvetica Bold Oblique',\n labelKey: 'annotation.fonts.helveticaBoldOblique',\n },\n {\n value: 'helvetica-oblique',\n label: 'Helvetica Oblique',\n labelKey: 'annotation.fonts.helveticaOblique',\n },\n { value: 'times-roman', label: 'Times Roman', labelKey: 'annotation.fonts.timesRoman' },\n { value: 'times-bold', label: 'Times Bold', labelKey: 'annotation.fonts.timesBold' },\n {\n value: 'times-bold-italic',\n label: 'Times Bold Italic',\n labelKey: 'annotation.fonts.timesBoldItalic',\n },\n { value: 'times-italic', label: 'Times Italic', labelKey: 'annotation.fonts.timesItalic' },\n { value: 'symbol', label: 'Symbol', labelKey: 'annotation.fonts.symbol' },\n { value: 'zapf-dingbats', label: 'Zapf Dingbats', labelKey: 'annotation.fonts.zapfDingbats' },\n];\n\n/** A font picker over the standard fonts; a kind gives it its own label where it differs. */\nexport const FONT_FAMILY: AnnotationProperty = {\n key: 'fontFamily',\n control: 'choice',\n label: 'Font',\n labelKey: 'annotation.style.font',\n options: STANDARD_FONT_OPTIONS,\n};\n\n/** A text alignment picker; a kind gives it its own label where it differs. */\nexport const TEXT_ALIGN: AnnotationProperty = {\n key: 'textAlign',\n control: 'choice',\n label: 'Align',\n labelKey: 'annotation.style.align',\n options: [\n { value: 'left', label: 'Left', labelKey: 'annotation.alignments.left' },\n { value: 'center', label: 'Center', labelKey: 'annotation.alignments.center' },\n { value: 'right', label: 'Right', labelKey: 'annotation.alignments.right' },\n ],\n};\n\n/**\n * \"This annotation links somewhere\": one property, shared by every kind that\n * can carry an attached link (a grouped `/Link` child). Deliberately absent\n * from: the widgets (a widget's `/A` is forms-plane behavior, not an attached\n * link), the caret (an anchored edit marker), the file attachment (its click\n * means \"open the attachment\") and the redaction mark.\n */\nexport const LINKABLE: AnnotationProperty = {\n key: 'link',\n control: 'link',\n label: 'Link',\n labelKey: 'annotation.style.link',\n};\n\n/** Shapes with a fill and a (possibly cloudy) border: square, circle, polygon. */\nexport const SHAPE_FIELDS: readonly AnnotationProperty[] = [\n STROKE,\n FILL,\n OPACITY,\n STROKE_WIDTH,\n BORDER_CLOUDY,\n LINKABLE,\n];\n\n/**\n * Stroked vertex kinds with `/LE` endings: line, polyline. The fill colours a\n * closed ending (closed arrow, circle, square, diamond).\n */\nexport const LINE_FIELDS: readonly AnnotationProperty[] = [\n STROKE,\n FILL,\n OPACITY,\n STROKE_WIDTH,\n BORDER_PLAIN,\n LINE_ENDINGS,\n LINKABLE,\n];\n\n/** Text markup: colour and opacity, plus its appearance stream's blend mode. */\nexport const MARKUP_FIELDS: readonly AnnotationProperty[] = [COLOR, OPACITY, BLEND_MODE, LINKABLE];\n\n/** The flags every kind has, in the order a panel lists them. */\nexport const FLAG_PROPERTIES: readonly AnnotationProperty[] = [\n { key: 'print', control: 'flag', label: 'Print', labelKey: 'annotation.flags.print' },\n { key: 'hidden', control: 'flag', label: 'Hidden', labelKey: 'annotation.flags.hidden' },\n { key: 'noView', control: 'flag', label: 'No view', labelKey: 'annotation.flags.noView' },\n {\n key: 'toggleNoView',\n control: 'flag',\n label: 'Toggle no view',\n labelKey: 'annotation.flags.toggleNoView',\n },\n { key: 'readOnly', control: 'flag', label: 'Read only', labelKey: 'annotation.flags.readOnly' },\n { key: 'locked', control: 'flag', label: 'Locked', labelKey: 'annotation.flags.locked' },\n {\n key: 'lockedContents',\n control: 'flag',\n label: 'Locked contents',\n labelKey: 'annotation.flags.lockedContents',\n },\n { key: 'noZoom', control: 'flag', label: 'No zoom', labelKey: 'annotation.flags.noZoom' },\n { key: 'noRotate', control: 'flag', label: 'No rotate', labelKey: 'annotation.flags.noRotate' },\n { key: 'invisible', control: 'flag', label: 'Invisible', labelKey: 'annotation.flags.invisible' },\n];\n","/**\n * How each kind is drawn: the style view a kind names (`style` in its file),\n * which reads its colours, stroke and border off the annotation by the\n * engine's field names and fills in what the kind doesn't keep (a highlight\n * strokes nothing, a caret draws 1 pt, a redaction's outline 1.5 pt).\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport type { Paint, Style } from '../types';\n\n/** A style's border when it has no dash of its own and no cloud. */\nconst PLAIN_BORDER = { borderStyle: 'solid', dashArray: null, cloudyIntensity: null } as const;\n\ntype Stroked = Extract<\n Annotation,\n { subtype: 'square' | 'circle' | 'line' | 'polygon' | 'polyline' | 'ink' | 'free-text' }\n>;\n\n/**\n * A kind drawn with a stroke, as the engine keeps it: its stroke, its fill\n * (ink has none) and its border, a dash or a cloud (square, circle, line,\n * polygon, polyline, ink, free text).\n */\nexport function strokedStyle(annotation: Annotation): Style {\n const stroked = annotation as Stroked;\n return {\n color: stroked.color,\n interiorColor: ('interiorColor' in stroked && stroked.interiorColor) || null,\n strokeWidth: stroked.strokeWidth,\n opacity: stroked.opacity,\n blendMode: stroked.blendMode,\n borderStyle: stroked.borderStyle ?? 'solid',\n dashArray: stroked.dashArray ?? null,\n cloudyIntensity: ('cloudyIntensity' in stroked && stroked.cloudyIntensity) || null,\n };\n}\n\ntype Coloured = Extract<\n Annotation,\n {\n subtype:\n | 'highlight'\n | 'underline'\n | 'squiggly'\n | 'strikeout'\n | 'caret'\n | 'redact'\n | 'text'\n | 'file-attachment';\n }\n>;\n\n/** A kind drawn in its one colour, with the stroke width its drawing uses and no border of its own. */\nconst colouredStyle =\n (strokeWidth: number) =>\n (annotation: Annotation): Style => {\n const coloured = annotation as Coloured;\n return {\n color: coloured.color,\n interiorColor: ('interiorColor' in coloured && coloured.interiorColor) || null,\n strokeWidth,\n opacity: coloured.opacity,\n blendMode: coloured.blendMode,\n ...PLAIN_BORDER,\n };\n };\n\n/** Text markup: its colour and opacity; its marks' widths follow the line height, so it strokes nothing itself. */\nexport const markupStyle = colouredStyle(0);\n\n/** A caret: its mark in its colour, drawn 1 pt. */\nexport const caretStyle = colouredStyle(1);\n\n/** A redaction mark: its outline (1.5 pt, a viewer's choice: the file keeps no width) and the fill applying paints. */\nexport const redactStyle = colouredStyle(1.5);\n\n/** A note or attachment icon: its colour is the icon's. */\nexport const iconStyle = colouredStyle(1);\n\n/** A stamp: its drawing is its appearance, so its opacity is the only style it has. */\nexport function stampStyle(annotation: Annotation): Style {\n const stamp = annotation as Extract<Annotation, { subtype: 'stamp' }>;\n return {\n color: '#444444',\n interiorColor: null,\n strokeWidth: 1,\n opacity: stamp.opacity,\n blendMode: stamp.blendMode,\n ...PLAIN_BORDER,\n };\n}\n\n/** A form widget: its border and background as the form draws them; a widget has no dash of its own. */\nexport function widgetStyle(annotation: Annotation): Style {\n const widget = annotation as Extract<Annotation, { subtype: 'widget' }>;\n return {\n color: widget.color ?? '#1a1a1a',\n interiorColor: widget.interiorColor ?? null,\n strokeWidth: widget.strokeWidth,\n opacity: 1,\n blendMode: widget.blendMode,\n ...PLAIN_BORDER,\n // Only a widget draws an underline border; a box drawn for it (a tool's\n // ghost) shows it solid.\n borderStyle: widget.borderStyle === 'underline' ? 'solid' : widget.borderStyle,\n };\n}\n\n/** A kind the viewer only shows (a link, a popup, an unknown type): an outline it never draws itself. */\nexport function plainStyle(annotation: Annotation): Style {\n return {\n color: '#444444',\n interiorColor: null,\n strokeWidth: 1,\n opacity: 1,\n blendMode: annotation.blendMode,\n ...PLAIN_BORDER,\n };\n}\n\n/** The CSS mix-blend-mode a style's live drawing composites with; `undefined` for normal. */\nexport function blendFor(style: Style): Paint['blend'] {\n return style.blendMode === 'normal' ? undefined : style.blendMode;\n}\n\n/** The dash a border draws with, or `undefined` for a solid or cloudy one. */\nexport function dashOf(style: Style): number[] | undefined {\n if (style.cloudyIntensity || style.borderStyle !== 'dashed') return undefined;\n return style.dashArray?.length ? style.dashArray : [3, 3];\n}\n","import { caretFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { COLOR, OPACITY } from './fields';\nimport { caretStyle } from './styles';\n\n/** An insertion mark on text (`/Caret`), bound to it like markup; it has no blend mode. */\nexport const caret = defineKind({\n name: 'caret',\n family: caretFamily,\n style: caretStyle,\n caps: { ...NO_CAPS, selectable: true, anchored: true, commentable: true },\n properties: [COLOR, OPACITY],\n});\n","import { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { SHAPE_FIELDS } from './fields';\nimport { strokedStyle } from './styles';\n\n/** An ellipse in its box, stroked and optionally filled, with a plain or cloudy border (`/Circle`). */\nexport const circle = defineKind({\n name: 'circle',\n family: boxFamily,\n style: strokedStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n },\n properties: SHAPE_FIELDS,\n});\n","import { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS, type AnnotationOption } from './define';\nimport { COLOR, OPACITY } from './fields';\nimport { iconStyle } from './styles';\n\n/** The `/Name` icons an attachment can show: the engine's `FileAttachmentIcon` names. */\nconst FILE_ATTACHMENT_ICONS: readonly AnnotationOption[] = [\n { value: 'push-pin', label: 'Push pin', labelKey: 'annotation.attachmentIcons.pushPin' },\n { value: 'paperclip', label: 'Paperclip', labelKey: 'annotation.attachmentIcons.paperclip' },\n { value: 'graph', label: 'Graph', labelKey: 'annotation.attachmentIcons.graph' },\n { value: 'tag', label: 'Tag', labelKey: 'annotation.attachmentIcons.tag' },\n];\n\n/**\n * An embedded file shown as an icon (`/FileAttachment`): the note's fixed\n * icon, but what it is for is the file (open, download), not a popup.\n */\nexport const fileAttachment = defineKind({\n name: 'file-attachment',\n family: boxFamily,\n style: iconStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n groupMovable: true,\n commentable: true,\n opaqueBody: true,\n noZoom: true,\n noRotate: true,\n },\n properties: [\n {\n key: 'icon',\n control: 'choice',\n label: 'Icon',\n labelKey: 'annotation.style.icon',\n options: FILE_ATTACHMENT_ICONS,\n },\n COLOR,\n OPACITY,\n ],\n});\n","/**\n * How each kind with text sets it: the text view a kind names (`text` in its\n * file), which reads its font, size, colour and alignment off the annotation\n * by the engine's field names and fills in what the kind doesn't keep.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport type { TextStyle } from '../types';\n\n/**\n * A free text's text is its rich body: the font, size, colour and alignment\n * the engine keeps beside it, and the body's weight, italic and decoration\n * as bold, italic and underline (absent = off). The editor has no justify: a\n * justified box shows left-aligned, and keeps its justify until another\n * alignment is picked.\n */\nexport function bodyText(annotation: Annotation): TextStyle {\n const freeText = annotation as Extract<Annotation, { subtype: 'free-text' }>;\n const body = freeText.richText?.body;\n return {\n fontFamily: freeText.fontFamily,\n fontSize: freeText.fontSize,\n fontColor: freeText.fontColor,\n textAlign: freeText.textAlign === 'justify' ? 'left' : freeText.textAlign,\n ...(body && body.weight >= 600 ? { bold: true } : {}),\n ...(body?.italic ? { italic: true } : {}),\n ...(body?.decoration.includes('underline') ? { underline: true } : {}),\n };\n}\n\n/**\n * A form field's text (`/DA`): its font (Helvetica when it names none), its\n * size (0 fits the box), its colour (black when it has none) and alignment.\n */\nexport function fieldText(annotation: Annotation): TextStyle {\n const widget = annotation as Extract<Annotation, { subtype: 'widget' }>;\n return {\n fontFamily: widget.fontFamily ?? 'helvetica',\n fontSize: widget.fontSize ?? 0,\n fontColor: widget.fontColor ? widget.fontColor : '#000000',\n textAlign: widget.textAlign,\n };\n}\n\n/** A redaction's label (`/DA`), set like free text; a size of 0 fits the region (the engine's convention). */\nexport function labelText(annotation: Annotation): TextStyle {\n const redact = annotation as Extract<Annotation, { subtype: 'redact' }>;\n return {\n fontFamily: redact.fontFamily,\n fontSize: redact.fontSize,\n fontColor: redact.fontColor,\n textAlign: redact.textAlign,\n };\n}\n","import { textBoxFamily } from '../shapes';\nimport { defineKind, NO_CAPS, type AnnotationProperty, type KindCaps } from './define';\nimport { FONT_FAMILY, LINKABLE, OPACITY, TEXT_ALIGN } from './fields';\nimport { strokedStyle } from './styles';\nimport { bodyText } from './texts';\n\nconst TEXT_BOX_CAPS: KindCaps = {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n textEditable: true,\n commentable: true,\n hasFill: true, // `/C`, the box's background\n};\n\n// The font first (the text is what it is for), then the box's background and border.\nconst TEXT_BOX_FIELDS: readonly AnnotationProperty[] = [\n FONT_FAMILY,\n {\n key: 'fontSize',\n control: 'number',\n label: 'Font size',\n labelKey: 'annotation.style.fontSize',\n min: 4,\n max: 96,\n step: 1,\n },\n {\n key: 'fontColor',\n control: 'color',\n label: 'Text color',\n labelKey: 'annotation.style.textColor',\n },\n {\n key: 'bold',\n control: 'textFormat',\n label: 'Bold',\n labelKey: 'annotation.style.bold',\n format: 'bold',\n },\n {\n key: 'italic',\n control: 'textFormat',\n label: 'Italic',\n labelKey: 'annotation.style.italic',\n format: 'italic',\n },\n {\n key: 'underline',\n control: 'textFormat',\n label: 'Underline',\n labelKey: 'annotation.style.underline',\n format: 'underline',\n },\n TEXT_ALIGN,\n OPACITY,\n {\n key: 'interiorColor',\n control: 'color',\n label: 'Background',\n labelKey: 'annotation.style.background',\n },\n { key: 'color', control: 'color', label: 'Border', labelKey: 'annotation.style.border' },\n {\n key: 'strokeWidth',\n control: 'number',\n label: 'Border width',\n labelKey: 'annotation.style.borderWidth',\n min: 0,\n max: 12,\n step: 0.5,\n },\n LINKABLE,\n];\n\n/**\n * A text box (`/FreeText`). Its box resizes and turns, its text reflows, and\n * its text is edited in place.\n */\nexport const freeText = defineKind({\n name: 'free-text',\n family: textBoxFamily,\n style: strokedStyle,\n text: bodyText,\n caps: TEXT_BOX_CAPS,\n properties: TEXT_BOX_FIELDS,\n});\n\n/**\n * A text box with a line pointing out (`/FreeText` with the `FreeTextCallout`\n * intent). It keeps the turn it was made with, the one that stands it upright\n * on a turned page, so nothing turns it, and a group resize can't scale it.\n * Its box resizes; its tip and knee move.\n */\nexport const freeTextCallout = defineKind({\n name: 'free-text-callout',\n family: textBoxFamily,\n style: strokedStyle,\n text: bodyText,\n caps: { ...TEXT_BOX_CAPS, rotatable: false, groupResizable: false, groupRotatable: false },\n properties: TEXT_BOX_FIELDS,\n});\n","import { quadsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { MARKUP_FIELDS } from './fields';\nimport { markupStyle } from './styles';\n\n/**\n * A highlight over text (`/Highlight`). Bound to the text it marks: it can be selected,\n * recoloured and deleted, never moved or resized. Made from a text\n * selection, not a drag.\n */\nexport const highlight = defineKind({\n name: 'highlight',\n family: quadsFamily,\n style: markupStyle,\n caps: { ...NO_CAPS, paintsBeneath: true, selectable: true, anchored: true, commentable: true },\n properties: MARKUP_FIELDS,\n});\n","import { pointsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { BLEND_MODE, COLOR, LINKABLE, OPACITY, STROKE_WIDTH } from './fields';\nimport { strokedStyle } from './styles';\n\n/**\n * Freehand strokes (`/Ink`). It moves and turns as a whole, and scales in a\n * group, but has no handles of its own: the strokes are its geometry.\n */\nexport const ink = defineKind({\n name: 'ink',\n family: pointsFamily,\n style: strokedStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n },\n properties: [COLOR, OPACITY, STROKE_WIDTH, BLEND_MODE, LINKABLE],\n});\n","import { pointsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { LINE_FIELDS } from './fields';\nimport { strokedStyle } from './styles';\n\n/** A straight line between two points, with endings; a distance measurement is one (`/Line`). */\nexport const line = defineKind({\n name: 'line',\n family: pointsFamily,\n style: strokedStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasEndings: true,\n },\n properties: LINE_FIELDS,\n});\n","import { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { LINKABLE } from './fields';\nimport { plainStyle } from './styles';\n\n/**\n * A link (`/Link`): an invisible rectangle that goes somewhere when clicked.\n * It draws nothing of its own (an appearance a PDF baked shows in the page's\n * raster); its whole box is grabbable, so the link tool can edit it. Its\n * `link` field is its own target (`/A`): the one kind where that field isn't\n * an attached child. It doesn't turn: a link has no reading direction.\n */\nexport const link = defineKind({\n name: 'link',\n family: boxFamily,\n style: plainStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n opaqueBody: true,\n rasterOnly: true,\n },\n properties: [LINKABLE],\n});\n","import { pointsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { SHAPE_FIELDS } from './fields';\nimport { strokedStyle } from './styles';\n\n/** A closed shape through its vertices, filled or not; an area measurement is one (`/Polygon`). */\nexport const polygon = defineKind({\n name: 'polygon',\n family: pointsFamily,\n style: strokedStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n },\n properties: SHAPE_FIELDS,\n});\n","import { pointsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { LINE_FIELDS } from './fields';\nimport { strokedStyle } from './styles';\n\n/** An open line through its vertices, with endings; a perimeter measurement is one (`/PolyLine`). */\nexport const polyline = defineKind({\n name: 'polyline',\n family: pointsFamily,\n style: strokedStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n vertexEditable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasEndings: true,\n },\n properties: LINE_FIELDS,\n});\n","import type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { boxFamily, familyChosenBy, quadsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { FILL, FONT_FAMILY, OPACITY, TEXT_ALIGN } from './fields';\nimport { redactStyle } from './styles';\nimport { labelText } from './texts';\n\n/** A mark over text has its quads; an area mark has none, and its shape is its rect, a box. */\nconst markShape = familyChosenBy((annotation: Annotation) =>\n annotation.subtype === 'redact' && annotation.quadPoints.length > 0 ? quadsFamily : boxFamily,\n);\n\n/**\n * A redaction mark (`/Redact`): the stage before content is removed. Made from\n * a text selection (one quad per line) or an area drag (a rect). A mark over\n * text is bound to it like markup; an area mark moves and resizes: one set of\n * caps serves both, as hit.ts gates transforms on anchored quads.\n *\n * At rest it shows an outline; its fill and label are what applying paints.\n * A label size of 0 fits the region (the engine's convention).\n */\nexport const redact = defineKind({\n name: 'redact',\n family: markShape,\n style: redactStyle,\n text: labelText,\n caps: {\n ...NO_CAPS,\n paintsBeneath: true,\n selectable: true,\n movable: true,\n resizable: true,\n anchored: true,\n commentable: true,\n hasFill: true,\n },\n properties: [\n { key: 'color', control: 'color', label: 'Outline', labelKey: 'annotation.style.outline' },\n FILL,\n OPACITY,\n { key: 'overlayText', control: 'text', label: 'Label', labelKey: 'annotation.style.label' },\n { ...FONT_FAMILY, label: 'Label font', labelKey: 'annotation.style.labelFont' },\n {\n key: 'fontSize',\n control: 'number',\n label: 'Label size',\n labelKey: 'annotation.style.labelSize',\n min: 0,\n max: 96,\n step: 1,\n },\n {\n key: 'fontColor',\n control: 'color',\n label: 'Label color',\n labelKey: 'annotation.style.labelColor',\n },\n TEXT_ALIGN,\n ],\n});\n","import { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { SHAPE_FIELDS } from './fields';\nimport { strokedStyle } from './styles';\n\n/** A rectangle, stroked and optionally filled, with a plain or cloudy border (`/Square`). */\nexport const square = defineKind({\n name: 'square',\n family: boxFamily,\n style: strokedStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n hasFill: true,\n hasCloudy: true,\n },\n properties: SHAPE_FIELDS,\n});\n","import { quadsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { MARKUP_FIELDS } from './fields';\nimport { markupStyle } from './styles';\n\n/**\n * A wavy line under text (`/Squiggly`). Bound to the text it marks: it can be selected,\n * recoloured and deleted, never moved or resized. Made from a text\n * selection, not a drag.\n */\nexport const squiggly = defineKind({\n name: 'squiggly',\n family: quadsFamily,\n style: markupStyle,\n caps: { ...NO_CAPS, paintsBeneath: true, selectable: true, anchored: true, commentable: true },\n properties: MARKUP_FIELDS,\n});\n","import { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { LINKABLE, OPACITY } from './fields';\nimport { stampStyle } from './styles';\n\n/**\n * A stamp (`/Stamp`): an image or drawing whose look is always the engine's\n * appearance, made when it was created, never drawn live. Its one style field\n * is opacity, which the engine paints over the whole drawing; a move, resize,\n * turn or new opacity is re-baked by the engine.\n */\nexport const stamp = defineKind({\n name: 'stamp',\n family: boxFamily,\n style: stampStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n resizable: true,\n rotatable: true,\n groupMovable: true,\n groupResizable: true,\n groupRotatable: true,\n commentable: true,\n opaqueBody: true,\n rasterOnly: true,\n },\n properties: [OPACITY, LINKABLE],\n});\n","import { quadsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { MARKUP_FIELDS } from './fields';\nimport { markupStyle } from './styles';\n\n/**\n * A line through text (`/StrikeOut`). Bound to the text it marks: it can be selected,\n * recoloured and deleted, never moved or resized. Made from a text\n * selection, not a drag.\n */\nexport const strikeout = defineKind({\n name: 'strikeout',\n family: quadsFamily,\n style: markupStyle,\n caps: { ...NO_CAPS, paintsBeneath: true, selectable: true, anchored: true, commentable: true },\n properties: MARKUP_FIELDS,\n});\n","import { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS, type AnnotationOption } from './define';\nimport { COLOR, LINKABLE, OPACITY } from './fields';\nimport { iconStyle } from './styles';\n\n/** The `/Name` icons a note can show: the engine's `NoteIcon` names. */\nconst NOTE_ICONS: readonly AnnotationOption[] = [\n { value: 'comment', label: 'Comment', labelKey: 'annotation.noteIcons.comment' },\n { value: 'key', label: 'Key', labelKey: 'annotation.noteIcons.key' },\n { value: 'note', label: 'Note', labelKey: 'annotation.noteIcons.note' },\n { value: 'help', label: 'Help', labelKey: 'annotation.noteIcons.help' },\n {\n value: 'new-paragraph',\n label: 'New paragraph',\n labelKey: 'annotation.noteIcons.newParagraph',\n },\n { value: 'paragraph', label: 'Paragraph', labelKey: 'annotation.noteIcons.paragraph' },\n { value: 'insert', label: 'Insert', labelKey: 'annotation.noteIcons.insert' },\n];\n\n/**\n * A sticky note (`/Text`): a fixed icon whose drawing is the engine's\n * appearance (from `/C` and `/Name`). It keeps its size and stays upright on\n * screen, the spec's rule for note icons; its popup thread is what it is for.\n */\nexport const textNote = defineKind({\n name: 'text',\n family: boxFamily,\n style: iconStyle,\n caps: {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n groupMovable: true,\n commentable: true,\n hasPopup: true,\n opaqueBody: true,\n noZoom: true,\n noRotate: true,\n },\n properties: [\n {\n key: 'icon',\n control: 'choice',\n label: 'Icon',\n labelKey: 'annotation.style.icon',\n options: NOTE_ICONS,\n },\n COLOR,\n OPACITY,\n LINKABLE,\n ],\n});\n","import { quadsFamily } from '../shapes';\nimport { defineKind, NO_CAPS } from './define';\nimport { MARKUP_FIELDS } from './fields';\nimport { markupStyle } from './styles';\n\n/**\n * A line under text (`/Underline`). Bound to the text it marks: it can be selected,\n * recoloured and deleted, never moved or resized. Made from a text\n * selection, not a drag.\n */\nexport const underline = defineKind({\n name: 'underline',\n family: quadsFamily,\n style: markupStyle,\n caps: { ...NO_CAPS, paintsBeneath: true, selectable: true, anchored: true, commentable: true },\n properties: MARKUP_FIELDS,\n});\n","/**\n * Form widgets (`/Widget`): one PDF subtype, six kinds. The widget's field\n * family picks its kind, so a checkbox never offers a font and a sidebar needs\n * no widget-specific code. Every widget has a box; the text-bearing ones add\n * the `/DA` text fields. The writer maps these flat fields onto `/MK`, `/BS`,\n * `/DA` and `/Q`.\n *\n * A widget ignores the `ReadOnly` flag here: a form designer must still move a\n * read-only field; the form-filling layer enforces it itself.\n */\nimport { boxFamily } from '../shapes';\nimport { defineKind, NO_CAPS, type AnnotationProperty, type KindCaps } from './define';\nimport { BORDER_PLAIN, FONT_FAMILY, TEXT_ALIGN } from './fields';\nimport { widgetStyle } from './styles';\nimport { fieldText } from './texts';\n\nconst WIDGET_CAPS: KindCaps = {\n ...NO_CAPS,\n selectable: true,\n movable: true,\n resizable: true,\n groupMovable: true,\n hasFill: true,\n opaqueBody: true,\n rasterOnly: true,\n ignoresReadOnly: true,\n};\n\nconst BOX_FIELDS: readonly AnnotationProperty[] = [\n {\n key: 'color',\n control: 'color',\n label: 'Border color',\n labelKey: 'annotation.style.borderColor',\n },\n {\n key: 'interiorColor',\n control: 'color',\n label: 'Background',\n labelKey: 'annotation.style.background',\n },\n {\n key: 'strokeWidth',\n control: 'number',\n label: 'Border width',\n labelKey: 'annotation.style.borderWidth',\n min: 0,\n max: 12,\n step: 0.5,\n },\n { ...BORDER_PLAIN, label: 'Border style', labelKey: 'annotation.style.borderStyle' },\n];\n\nconst TEXT_FIELDS: readonly AnnotationProperty[] = [\n ...BOX_FIELDS,\n FONT_FAMILY,\n {\n key: 'fontSize',\n control: 'number',\n label: 'Font size',\n labelKey: 'annotation.style.fontSize',\n min: 0,\n max: 96,\n step: 1,\n },\n {\n key: 'fontColor',\n control: 'color',\n label: 'Text color',\n labelKey: 'annotation.style.textColor',\n },\n { ...TEXT_ALIGN, label: 'Alignment', labelKey: 'annotation.style.alignment' },\n];\n\n/** A text field. */\nexport const widgetText = defineKind({\n name: 'widget-text',\n family: boxFamily,\n style: widgetStyle,\n text: fieldText,\n caps: WIDGET_CAPS,\n properties: TEXT_FIELDS,\n});\n\n/** A combo box or a list box. */\nexport const widgetChoice = defineKind({\n name: 'widget-choice',\n family: boxFamily,\n style: widgetStyle,\n text: fieldText,\n caps: WIDGET_CAPS,\n properties: TEXT_FIELDS,\n});\n\n/** A push button: its caption is text. */\nexport const widgetButton = defineKind({\n name: 'widget-button',\n family: boxFamily,\n style: widgetStyle,\n text: fieldText,\n caps: WIDGET_CAPS,\n properties: TEXT_FIELDS,\n});\n\n/** A checkbox: no text. */\nexport const widgetToggle = defineKind({\n name: 'widget-toggle',\n family: boxFamily,\n style: widgetStyle,\n caps: WIDGET_CAPS,\n properties: BOX_FIELDS,\n});\n\n/** A radio button: no text, and round (its box draws the ellipse in it, as the engine draws one). */\nexport const widgetRadio = defineKind({\n name: 'widget-radio',\n family: boxFamily,\n style: widgetStyle,\n caps: WIDGET_CAPS,\n properties: BOX_FIELDS,\n});\n\n/** Any other widget (a signature field, one in no field): a box. */\nexport const widgetBox = defineKind({\n name: 'widget-box',\n family: boxFamily,\n style: widgetStyle,\n caps: WIDGET_CAPS,\n properties: BOX_FIELDS,\n});\n\n/** The widget kind for a field family. */\nconst KIND_BY_FAMILY: Readonly<Record<string, string>> = {\n text: widgetText.name,\n combobox: widgetChoice.name,\n listbox: widgetChoice.name,\n pushbutton: widgetButton.name,\n checkbox: widgetToggle.name,\n radio: widgetRadio.name,\n};\n\n/** The name of the widget kind for a widget's field family. */\nexport const widgetKindOf = (family: string): string => KIND_BY_FAMILY[family] ?? widgetBox.name;\n\n/**\n * The field family a widget kind stands for, the other way round: what a form\n * tool's defaults read as, so they read as the tool's own kind (a choice tool\n * as a combo box, the bare box as a signature field).\n */\nconst FAMILY_BY_KIND: Readonly<Record<string, string>> = {\n [widgetText.name]: 'text',\n [widgetChoice.name]: 'combobox',\n [widgetButton.name]: 'pushbutton',\n [widgetToggle.name]: 'checkbox',\n [widgetRadio.name]: 'radio',\n [widgetBox.name]: 'signature',\n};\n\n/** The field family a widget kind stands for; `undefined` for a kind that is no widget's. */\nexport const fieldFamilyOfKind = (kind: string): string | undefined => FAMILY_BY_KIND[kind];\n","/**\n * Every annotation kind. Each is declared in its own file in this folder: its\n * shape family, how it is drawn, what a user can do to it, and what a sidebar\n * edits. To add a kind, declare it in a file and list it below.\n *\n * A kind is how an annotation is edited; a tool is how one is made (tools/,\n * in the plugin). Many tools can make one kind: ink and the ink highlighter,\n * a line and an arrow.\n */\nimport { boxFamily } from '../shapes';\nimport { caret } from './caret';\nimport { circle } from './circle';\nimport { NO_CAPS, type AnnotationKind } from './define';\nimport { fileAttachment } from './file-attachment';\nimport { freeText, freeTextCallout } from './free-text';\nimport { highlight } from './highlight';\nimport { ink } from './ink';\nimport { line } from './line';\nimport { link } from './link';\nimport { polygon } from './polygon';\nimport { polyline } from './polyline';\nimport { redact } from './redact';\nimport { square } from './square';\nimport { squiggly } from './squiggly';\nimport { stamp } from './stamp';\nimport { strikeout } from './strikeout';\nimport { textNote } from './text-note';\nimport { underline } from './underline';\nimport {\n widgetBox,\n widgetButton,\n widgetChoice,\n widgetRadio,\n widgetText,\n widgetToggle,\n} from './widget';\nimport { plainStyle } from './styles';\n\nexport {\n defineKind,\n NO_CAPS,\n type AnnotationKind,\n type AnnotationOption,\n type AnnotationProperty,\n type FlagKey,\n type KindCaps,\n} from './define';\nexport { fieldFamilyOfKind, widgetKindOf } from './widget';\n\n/** The kinds, by name. */\nexport const KINDS: Readonly<Record<string, AnnotationKind>> = {\n [square.name]: square,\n [circle.name]: circle,\n [line.name]: line,\n [polygon.name]: polygon,\n [polyline.name]: polyline,\n [ink.name]: ink,\n [freeText.name]: freeText,\n [freeTextCallout.name]: freeTextCallout,\n [highlight.name]: highlight,\n [underline.name]: underline,\n [squiggly.name]: squiggly,\n [strikeout.name]: strikeout,\n [caret.name]: caret,\n [redact.name]: redact,\n [textNote.name]: textNote,\n [fileAttachment.name]: fileAttachment,\n [stamp.name]: stamp,\n [link.name]: link,\n [widgetText.name]: widgetText,\n [widgetChoice.name]: widgetChoice,\n [widgetButton.name]: widgetButton,\n [widgetToggle.name]: widgetToggle,\n [widgetRadio.name]: widgetRadio,\n [widgetBox.name]: widgetBox,\n};\n\n/**\n * A kind the viewer shows but doesn't edit (an annotation type it doesn't\n * model): drawn from the engine's raster, with nothing to do to it. Without\n * an appearance in the file it draws nothing: it has no fields the viewer\n * could draw it from.\n */\nconst shownOnly = new Map<string, AnnotationKind>();\n\n/** The kind named `name`; a name no kind has reads as one that is only shown. */\nexport function kindNamed(name: string): AnnotationKind {\n const kind = KINDS[name];\n if (kind) return kind;\n let shown = shownOnly.get(name);\n if (!shown) {\n shown = {\n name,\n family: boxFamily,\n style: plainStyle,\n caps: { ...NO_CAPS, rasterOnly: true },\n properties: [],\n };\n shownOnly.set(name, shown);\n }\n return shown;\n}\n","/**\n * Who a record is, read off its annotation: its engine ref, its kind, and the\n * annotations it answers. The record keeps none of these beside the\n * annotation, so every reader asks here.\n */\nimport type { Annotation, AnnotationRef } from '@embedpdf/engine-core/runtime';\nimport { annotationKey } from '@embedpdf/core';\n\nimport { kindNamed, widgetKindOf, type AnnotationKind } from '../kinds';\nimport type { Id, ModelAnnotation } from '../types';\n\n/**\n * An annotation's kind (`kinds/`): the one its subtype names; for a widget,\n * the one its field family picks (`widget-text`…); for a free text with the\n * callout intent, the callout.\n */\nexport function kindOf(annotation: Annotation): AnnotationKind {\n switch (annotation.subtype) {\n case 'widget':\n return kindNamed(widgetKindOf(annotation.fieldFamily));\n case 'free-text':\n return kindNamed(\n annotation.intent === 'free-text-callout' ? 'free-text-callout' : 'free-text',\n );\n default:\n return kindNamed(annotation.subtype);\n }\n}\n\n/**\n * A record's engine ref, a new one's included (it names the object number\n * its create takes); `null` for a record the view doesn't hold.\n */\nexport const refOf = (record: ModelAnnotation | undefined): AnnotationRef | null =>\n record?.annotation.ref ?? null;\n\n/**\n * The key of the annotation an annotation answers (`/IRT`): a comment reply's\n * parent, or a group member's primary.\n */\nexport const irtOf = (annotation: Annotation): Id | undefined =>\n annotation.reply ? annotationKey(annotation.reply.to) : undefined;\n\n/**\n * The key of the group an annotation belongs to: its primary's, for a\n * `/RT /Group` member only (a visual group acts as a unit; a comment reply\n * answers its parent but is not part of it).\n */\nexport const groupOf = (annotation: Annotation): Id | undefined =>\n annotation.reply?.type === 'group' ? annotationKey(annotation.reply.to) : undefined;\n","/**\n * Annotation `/F` flags — the one interpretation of ISO 32000-2 Table 167.\n *\n * A record's annotation carries the named booleans as the engine reads them; every\n * behavioral question (can I see it? click it? move it? edit its text?) is\n * answered here and nowhere else, so rendering, hit-testing, chrome, and the\n * reducer can never disagree about what a flag means.\n *\n * The flag→behavior split, in one line each:\n * hidden — gone everywhere (screen, interaction, print)\n * noView — gone on screen, may still print\n * toggleNoView — reveals a noView annotation while engaged (v1: selected)\n * readOnly — visible but inert (ignored for widget kinds, per spec —\n * the form layer owns field-level ReadOnly)\n * locked — selectable but frozen: no move/resize/rotate/delete/restyle\n * lockedContents — `/Contents` text cannot change; geometry still can\n * print — include when printing (carried for the print pipeline)\n * noZoom/noRotate — screen-anchored body (see anchor.ts)\n * invisible — legacy: hide unknown subtypes with no handler\n */\nimport {\n NO_ANNOTATION_FLAGS,\n type Annotation,\n type AnnotationFlags,\n} from '@embedpdf/engine-core/runtime';\nimport { kindOf } from './record/identity';\n\nexport type { AnnotationFlags };\nexport { NO_ANNOTATION_FLAGS };\n\n/** The `/F` every freshly drawn annotation starts with: `print` set (Acrobat\n * parity — without it the annotation silently disappears when printed). */\nexport const DRAWN_FLAGS: AnnotationFlags = { ...NO_ANNOTATION_FLAGS, print: true };\n\n/** All ten flags, for iteration/equality — kept in the primitives' order. */\nexport const FLAG_KEYS = Object.keys(NO_ANNOTATION_FLAGS) as ReadonlyArray<keyof AnnotationFlags>;\n\nexport const flagsEqual = (left: AnnotationFlags, right: AnnotationFlags): boolean =>\n FLAG_KEYS.every((flag) => left[flag] === right[flag]);\n\n/** Merge a partial write over the current flags. */\nexport const mergeFlags = (\n base: AnnotationFlags,\n patch: Partial<AnnotationFlags>,\n): AnnotationFlags => ({\n ...base,\n ...patch,\n});\n\n/**\n * On-screen visibility. `hidden` beats everything; `noView` hides unless\n * `toggleNoView` and the annotation is engaged — the spec says hover/selection,\n * and v1 uses selection (the model tracks no hover).\n */\nexport const viewable = (flags: AnnotationFlags, engaged = false): boolean =>\n !flags.hidden && (!flags.noView || (flags.toggleNoView && engaged));\n\n/** Any pointer interaction (click-to-select, hover). ReadOnly kills it. */\nexport const interactive = (flags: AnnotationFlags): boolean =>\n !flags.hidden && !flags.noView && !flags.readOnly;\n\n/** The part of a ModelAnnotation these predicates read. */\nexport interface FlagBearer {\n /** The record's annotation: its kind and `/F` flags are read off it. */\n annotation: Annotation;\n /** Session authority projected at ingest (permissions.md). Absent =\n * unstamped (drafts, wildcard local engines, tests) = allowed. */\n authority?: { update: boolean; delete: boolean };\n}\n\n/** Interaction gate for a concrete annotation: widget kinds ignore `readOnly`\n * (ISO 32000 — a ReadOnly form field must still be movable by a form designer;\n * the form-filling layer enforces field ReadOnly itself). */\nexport const annotInteractive = (record: FlagBearer): boolean =>\n kindOf(record.annotation).caps.ignoresReadOnly\n ? !record.annotation.hidden && !record.annotation.noView\n : interactive(record.annotation);\n\n/**\n * Geometry/style mutations — `locked` freezes the object, not its contents\n * (that's `lockedContents`), and the session must hold update authority over\n * the record. One predicate for hit-test, chrome, and props alike, so a\n * record you may not edit renders and behaves exactly like a locked one.\n */\nexport const annotTransformable = (record: FlagBearer): boolean =>\n annotInteractive(record) && !record.annotation.locked && (record.authority?.update ?? true);\n\n/** Deletion — the delete half of the authority split (a narrowed grant can\n * allow update but not delete, or vice versa). Flags gate like transforms. */\nexport const annotDeletable = (record: FlagBearer): boolean =>\n annotInteractive(record) && !record.annotation.locked && (record.authority?.delete ?? true);\n\n/** `/Contents` text edits — the contents counterpart of `locked`. */\nexport const annotContentsEditable = (record: FlagBearer): boolean =>\n annotInteractive(record) &&\n !record.annotation.lockedContents &&\n (record.authority?.update ?? true);\n\n/** An annotation's text: `lockedContents` guards it, not `locked`. */\nconst TEXT_FIELDS: ReadonlySet<string> = new Set(['contents', 'richText']);\n\n/**\n * May this session change the record's engine `field` now? The one table\n * every write of engine fields asks (`withValues`):\n *\n * a flag always, given update authority: unlocking a locked\n * annotation, or showing a hidden one, must work\n * contents, richText unless `lockedContents`: its text\n * anything else unless `locked`: the annotation itself\n */\nexport function mayWrite(record: FlagBearer, field: string): boolean {\n if ((FLAG_KEYS as readonly string[]).includes(field)) return record.authority?.update ?? true;\n return TEXT_FIELDS.has(field) ? annotContentsEditable(record) : annotTransformable(record);\n}\n","/**\n * What people may change by hand: the session's `editable` rule, plain data\n * the plugin sets from its settings. It joins the `/F` flags and the record's\n * authority (flags.ts) in every gesture gate and every edit of the selection,\n * and nowhere else: a change stated in code never asks it, and neither do the\n * `can*` twins, which stay facts. An annotation the rule freezes can still be\n * selected, hovered, read and commented on; it has no handles, no knob, no\n * drag, no text editing, and the selection's edits and delete skip it.\n */\nimport {\n isDimension,\n type Annotation,\n type AnnotationSubtype,\n} from '@embedpdf/engine-core/runtime';\n\nimport { annotContentsEditable, annotDeletable, annotTransformable } from './flags';\nimport type { ModelAnnotation, Session } from './types';\n\n/** The intents a measurement goes by in {@link EditableKinds}. */\nexport type MeasurementIntent = 'line-dimension' | 'polyline-dimension' | 'polygon-dimension';\n\n/** What {@link EditableKinds} names an annotation by: {@link editableKindOf}. */\nexport type EditableKind = AnnotationSubtype | MeasurementIntent;\n\n/**\n * Which annotations people may change by hand: `true`, every one; `false`,\n * none; a list, the annotations of the kinds it names, each by its subtype,\n * or a measurement by its intent (so measurements and the shapes they're\n * drawn as are told apart).\n */\nexport type EditableKinds = boolean | readonly EditableKind[];\n\n/** The name {@link EditableKinds} knows an annotation by: a measurement's intent, else its subtype. */\nexport function editableKindOf(annotation: Annotation): EditableKind {\n const { intent } = annotation as { readonly intent?: string | null };\n return isDimension(annotation) ? (intent as MeasurementIntent) : annotation.subtype;\n}\n\n/** Whether the session's rule lets people change this annotation by hand. */\nexport function isEditableByHand(\n model: Pick<Session, 'editable'>,\n annotation: Annotation,\n): boolean {\n const { editable } = model;\n return typeof editable === 'boolean' ? editable : editable.includes(editableKindOf(annotation));\n}\n\n/** Whether people may move, resize, turn, reshape or restyle the record by hand now. */\nexport const isTransformableByHand = (\n model: Pick<Session, 'editable'>,\n record: ModelAnnotation,\n): boolean => annotTransformable(record) && isEditableByHand(model, record.annotation);\n\n/** Whether people may delete the record by hand now. */\nexport const isDeletableByHand = (\n model: Pick<Session, 'editable'>,\n record: ModelAnnotation,\n): boolean => annotDeletable(record) && isEditableByHand(model, record.annotation);\n\n/** Whether people may edit the record's text in place now. */\nexport const isContentsEditableByHand = (\n model: Pick<Session, 'editable'>,\n record: ModelAnnotation,\n): boolean => annotContentsEditable(record) && isEditableByHand(model, record.annotation);\n","/**\n * The paint/conversation plane boundary — one predicate, consumed by every\n * page surface (paint order, hit-testing, marquee, appearance epoch), so a\n * conversation-plane annotation can never leak onto the page through a\n * surface that forgot to filter.\n *\n * Conversation-only annotations live in the model as first-class `ModelAnnotation`s\n * (selection, deletion and persistence all work on them) but they are\n * dialogue, not page visuals:\n *\n * - `/RT /R` replies — threaded comment content. Their anchor (the\n * thread root) is the page visual; the reply renders in the comments\n * UI. (`/RT /Group` subordinates are the opposite: parts of one\n * composite visual — a caret grouped to a strikeout — and stay on the\n * paint plane.)\n * - ISO 32000 §12.5.6.3 state annotations — text annotations carrying\n * `/State`/`/StateModel`. Review-status metadata about their target,\n * never a visual of their own (foreign producers usually flag them\n * hidden, but classification never relies on flags).\n * - ISO 32000 §12.5.6.14 popups — the window a markup annotation's\n * comment shows in. The comments UI is that window, as Acrobat draws its\n * own and ignores a popup's appearance: a popup is never painted, open or\n * not, wherever its rect sits (producers put it in the page's margin, or\n * past it).\n */\nimport type { ModelAnnotation } from './types';\n\nconst nonEmpty = (value: string | null | undefined): value is string =>\n typeof value === 'string' && value !== '';\n\n/** True when this annotation belongs to the conversation plane only —\n * never painted, hit, marquee-selected, or counted into a page's\n * appearance epoch. */\nexport function isConversationOnly(record: Pick<ModelAnnotation, 'annotation'>): boolean {\n const annotation = record.annotation;\n // A reply: `/IRT` that isn't a `/RT /Group` membership.\n if (annotation.reply && annotation.reply.type !== 'group') return true;\n // A state annotation: a text annot with a non-empty /State or /StateModel.\n if (annotation.subtype === 'text') {\n if (nonEmpty(annotation.state) || nonEmpty(annotation.stateModel)) return true;\n }\n // A comment's window: the comments UI draws it.\n return annotation.subtype === 'popup';\n}\n\n/**\n * A link child attached to another annotation — a `/Link` grouped\n * (`/IRT` + `/RT /Group`) under a non-link parent. Pure substrate: it is\n * the parent's `link` property while authoring (derived via `linkOf`) and\n * the navigation plane's anchor while reading — never painted, never hit\n * as itself. Its rect is reconciled from the parent's geometry, so direct\n * manipulation would be overwritten anyway.\n */\nexport function isAttachedLink(record: Pick<ModelAnnotation, 'annotation'>): boolean {\n return record.annotation.subtype === 'link' && record.annotation.reply?.type === 'group';\n}\n\n/**\n * The one page-surface cull: everything that lives in the substrate but is\n * not a page visual of its own — conversation members (replies, review\n * states) and attached link children. Paint order, hit-testing, marquee\n * and the appearance epoch all filter through this, never the parts.\n */\nexport function isSubstrateOnly(record: Pick<ModelAnnotation, 'annotation'>): boolean {\n return isConversationOnly(record) || isAttachedLink(record);\n}\n","/**\n * Pure page-space geometry for any shape. What one shape does — its bounds,\n * hit test, handles, moves and drawing — its family answers (`shapes/`,\n * found by `familyOf`); these functions ask it. What spans families lives\n * here: the selection outline, the rotate knob, a multi-selection's resize,\n * and upright placement. The engine speaks page space too: the same\n * numbers, nothing to convert.\n */\nimport { isQuarterTurn, type PageRotation, type Size } from '@embedpdf/core-geometry';\nimport { paintedNear, type PaintedPiece } from './painted';\nimport {\n DEG2RAD,\n MIN_SIZE,\n OPPOSITE_HANDLE,\n RECT_CURSOR,\n RECT_HANDLES,\n type RectHandle,\n normalizeDeg,\n pointInPoly,\n rectCenter,\n rectCornerPoints,\n rectHandlePoint,\n resizeRect,\n} from './rect';\nimport { familyOf } from './shapes';\nimport type { Shape, Handle, Rect, RenderNode, Point, Stroke } from './types';\n\n/* ── rotation ──────────────────────────────────────────────────────────────\n * Annotation rotation, layered on the generic `@embedpdf/core-geometry` affine\n * primitives (`rotateAbout`). Box kinds carry an unrotated `rect` + a `rot`\n * angle; vertex kinds carry already-rotated points + an advisory `rot`. These\n * helpers know that split and compose the matrix builders — they never hand-roll\n * a rotation matrix. See `Shape` in types.ts.\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/** How far (content units) the rotate knob hangs off the top edge of the box. */\nexport const ROTATE_KNOB_OFFSET = 24;\n\n/** Fallback chrome geometry (content units) when the caller supplies none —\n * the pre-settings behavior, so bare-core callers and tests stay stable. */\nexport const DEFAULT_CHROME_GEOMETRY = {\n handleTol: 6,\n knobTol: 6,\n knobOffset: ROTATE_KNOB_OFFSET,\n} as const;\n\n/** A geom's applied rotation (deg), or 0 for text markup. A caret's turn is\n * its text's baseline tilt: reported here so the renderer and selection\n * chrome follow it, while the caret's caps (not movable/resizable) keep\n * every rotate gesture away from it. */\nexport function geomRotation(geometry: Shape): number {\n return geometry.kind === 'quads' ? 0 : geometry.rotation;\n}\n\n/**\n * Where a turn of a single shape pivots, as the engine turns it: a box about\n * its own `rect` centre; a line, polygon, polyline or ink about the middle of\n * the box around its points upright. A turn then changes only the angle, never\n * where the upright points are, and a caption or an arrowhead never moves the\n * pivot.\n */\nexport const turnPivotOf = (geometry: Shape): Point => familyOf(geometry).pivot(geometry);\n\n/** Does the geometry carry a meaningful `rot` (an oriented local box exists)?\n * Orientation is a geometry fact; whether the user may rotate is the separate\n * `caps.rotatable` gate — a caret is oriented (it rides its text's tilt) yet\n * offers no rotate gesture. */\nexport const isRotatableGeom = (geometry: Shape): boolean => familyOf(geometry).oriented(geometry);\n\n/**\n * Rotate a geom by `deltaDeg` (clockwise) about `pivot`: a box's middle\n * orbits the pivot and its turn grows, and so does a points shape's. A shape\n * without a rotate verb comes back unchanged: quads, a callout, and the\n * caret (oriented, but it follows its text; `geomResetRotation` still clears\n * its turn).\n */\nexport function geomRotateAbout(geometry: Shape, pivot: Point, deltaDeg: number): Shape {\n return deltaDeg === 0 ? geometry : familyOf(geometry).rotateAbout(geometry, pivot, deltaDeg);\n}\n\n/* ── upright placement (counter-rotating against the display rotation) ────────\n * An `upright` tool commits `rot = -displayRotation` so the annotation reads\n * horizontally on the rotated page. These two helpers are the only placement\n * math that rule needs; both are exact for quarter-turns and pure page-space\n * (they never know about the view).\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/**\n * The counter-rotation (CW content degrees) that makes an annotation read\n * upright at `displayRotation`: on screen the two compose to 0.\n */\nexport const uprightRotation = (displayRotation: number): number => normalizeDeg(-displayRotation);\n\n/**\n * The unrotated content rect for a default-size upright box \"placed at\" a\n * point: positioned so that, after the upright counter-rotation, the box shows\n * `width`×`height` with its top-left at `anchor` in the rotated view — the\n * same on-screen feel as the rotation-0 `{ x: anchor.x, y: anchor.y }` box at\n * every quarter-turn (a click-created free-text box always opens down-right of\n * the cursor as the author sees it). Derived by placing the box in the display\n * frame and pulling its AABB back through the quarter-turn; the page dims\n * cancel, so no page box is needed.\n */\nexport function uprightAnchoredRect(\n anchor: Point,\n width: number,\n height: number,\n displayRotation: number,\n): Rect {\n const rotation = normalizeDeg(displayRotation);\n const point: Point =\n rotation === 90\n ? { x: anchor.x + height / 2, y: anchor.y - width / 2 }\n : rotation === 180\n ? { x: anchor.x - width / 2, y: anchor.y - height / 2 }\n : rotation === 270\n ? { x: anchor.x - height / 2, y: anchor.y + width / 2 }\n : { x: anchor.x + width / 2, y: anchor.y + height / 2 };\n return { x: point.x - width / 2, y: point.y - height / 2, width, height };\n}\n\nconst clampScalar = (value: number, lo: number, hi: number): number =>\n Math.max(lo, Math.min(hi, value));\n\n/**\n * The logical (unrotated) page-space box for a stamp placed at `center`,\n * sized `desired` (points), fit onto the page and clamped fully within it —\n * the rubber-stamp rule: keep the image's own size unless it would overflow\n * the page, then scale down (aspect preserved, never up) so it just fits.\n *\n * Under an upright quarter-turn the on-page footprint is the box transposed\n * (w↔h), so both the fit and the edge clamp use that footprint — a landscape\n * stamp uprighted onto a portrait page fits by its rotated silhouette, not its\n * logical box. The box centre and its footprint AABB centre coincide (rotation\n * is about the centre), so clamping one clamps the other.\n */\nexport function fitStampBox(center: Point, desired: Size, page: Size, rotCW: number): Rect {\n const quarter = isQuarterTurn((normalizeDeg(rotCW) as PageRotation) ?? 0);\n // Footprint (AABB) dims for the desired size, before fitting.\n const fw0 = quarter ? desired.height : desired.width;\n const fh0 = quarter ? desired.width : desired.height;\n const fitScale = Math.min(1, fw0 > 0 ? page.width / fw0 : 1, fh0 > 0 ? page.height / fh0 : 1);\n const width = desired.width * fitScale;\n const height = desired.height * fitScale;\n const fw = quarter ? height : width;\n const fh = quarter ? width : height;\n // Clamp the centre so the footprint stays fully on the page (the fit above\n // guarantees fw ≤ page.width and fh ≤ page.height, so the range is valid).\n const cx = clampScalar(center.x, fw / 2, page.width - fw / 2);\n const cy = clampScalar(center.y, fh / 2, page.height - fh / 2);\n return { x: cx - width / 2, y: cy - height / 2, width, height };\n}\n\n/** Reset a geom to its as-authored orientation (turn → 0). Box: drop the turn.\n * Points: turn back about `pivot` (the middle of the upright points by\n * default, which only clears the turn). */\nexport function geomResetRotation(geometry: Shape, pivot?: Point): Shape {\n return geomRotation(geometry) ? familyOf(geometry).upright(geometry, pivot) : geometry;\n}\n\n/**\n * The oriented selection box (OBB) of a rotatable geom: four corners (in order\n * nw, ne, se, sw of the local box, transformed) + the angle. For a box this is\n * the box rotated about its centre; for a points shape it is the drawn bounds\n * of its upright points, turned about their middle — the snug tilted\n * rectangle. Returns null for non-rotatable kinds.\n */\nexport function obbFromGeom(\n geometry: Shape,\n stroke: Stroke,\n): { corners: [Point, Point, Point, Point]; angle: number } | null {\n const corners = familyOf(geometry).turnedCorners(geometry, stroke);\n return corners ? { corners, angle: geomRotation(geometry) } : null;\n}\n\n/* ── group (multi-target) scaling ─────────────────────────────────────────────\n * A multi-selection scales as one box about a fixed anchor (the opposite handle\n * corner/edge). Resize is anisotropic only when every member has `rot == 0`\n * (otherwise an off-axis scale would shear a rotated shape it can't represent —\n * so we fall back to a uniform scale). The iso/aniso choice is decided by the\n * caller (it needs the live selection); these helpers take the resolved factors.\n * ──────────────────────────────────────────────────────────────────────────── */\n\n/** The 8 box resize handles (corner + edge, with cursors) of a plain rect — used\n * for the multi-target group box. */\nexport function rectHandlesFor(rect: Rect): Handle[] {\n return RECT_HANDLES.map((handle) => ({\n id: handle,\n at: rectHandlePoint(rect, handle),\n cursor: RECT_CURSOR[handle],\n }));\n}\n\n/** The fixed point of a group resize: the opposite handle's point on the box. */\nexport function groupResizeAnchor(base: Rect, handle: string): Point {\n return rectHandlePoint(base, OPPOSITE_HANDLE[handle as RectHandle] ?? 'nw');\n}\n\n/**\n * The live group resize box for a drag. Anisotropic = the plain axis-aligned\n * `resizeRect`; isotropic = a uniform scale of `base` about the anchor by the\n * larger of the two drag ratios (so the preview matches the committed scale and\n * never shears a rotated member).\n */\nexport function groupResizeBox(base: Rect, handle: string, to: Point, isotropic: boolean): Rect {\n const raw = resizeRect(base, handle as RectHandle, to);\n if (!isotropic) return raw;\n const sx = base.width > 0 ? raw.width / base.width : 1;\n const sy = base.height > 0 ? raw.height / base.height : 1;\n const scale = Math.max(MIN_SIZE / Math.max(base.width, base.height, 1), Math.max(sx, sy));\n const anchor = groupResizeAnchor(base, handle);\n return {\n x: anchor.x + (base.x - anchor.x) * scale,\n y: anchor.y + (base.y - anchor.y) * scale,\n width: base.width * scale,\n height: base.height * scale,\n };\n}\n\n/** The (sx, sy) factors a `base`→`cur` group resize applied about its anchor. */\nexport function groupResizeFactors(base: Rect, current: Rect): { sx: number; sy: number } {\n return {\n sx: base.width > 0 ? current.width / base.width : 1,\n sy: base.height > 0 ? current.height / base.height : 1,\n };\n}\n\n/**\n * Scale a geom about `anchor` by `(sx, sy)`, exactly. For a rotated box (iso\n * scale, so `sx === sy`) the unrotated box is scaled about the anchor and its\n * turn is preserved (a uniform scale commutes with rotation). For unrotated\n * members (the anisotropic case) every point/extent scales directly. A resize\n * passes `minSize`, the smallest a box may end up.\n */\nexport function geomScaleAbout(\n geometry: Shape,\n anchor: Point,\n sx: number,\n sy: number,\n minSize?: number,\n): Shape {\n return familyOf(geometry).scaleAbout(geometry, anchor, sx, sy, minSize);\n}\n\n/** Where the rotate knob sits, given the OBB corners (nw, ne, se, sw) and the\n * outward offset (content units). `from` is the top-edge midpoint the connector\n * stalk anchors to; `at` is the grab dot, offset along the outward normal. */\nexport function rotateKnob(\n corners: [Point, Point, Point, Point],\n offset: number,\n): { at: Point; from: Point } {\n const [nw, ne, , sw] = corners;\n const from = { x: (nw.x + ne.x) / 2, y: (nw.y + ne.y) / 2 };\n // outward normal = from the bottom edge toward the top edge (away from shape).\n const down = { x: sw.x - nw.x, y: sw.y - nw.y };\n const len = Math.hypot(down.x, down.y) || 1;\n const up = { x: -down.x / len, y: -down.y / len };\n return { at: { x: from.x + up.x * offset, y: from.y + up.y * offset }, from };\n}\n\nconst insideRect = (rect: Rect, point: Point): boolean =>\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height;\n\n/**\n * The chord of `box` cut by the infinite line through `point` at `angleDeg` (CW,\n * y-down) — the full-bleed rotation guide: no magic lengths, the line simply\n * spans the page. Slab-clipped (Liang–Barsky); null when the line misses the\n * box entirely (a far-off-page pivot).\n */\nexport function chordThrough(\n box: Rect,\n point: Point,\n angleDeg: number,\n): { a: Point; b: Point } | null {\n const direction = { x: Math.cos(angleDeg * DEG2RAD), y: Math.sin(angleDeg * DEG2RAD) };\n let tMin = -Infinity;\n let tMax = Infinity;\n for (const [dc, pc, lo, hi] of [\n [direction.x, point.x, box.x, box.x + box.width],\n [direction.y, point.y, box.y, box.y + box.height],\n ] as const) {\n if (Math.abs(dc) < 1e-12) {\n if (pc < lo || pc > hi) return null; // parallel outside the slab\n continue;\n }\n const t1 = (lo - pc) / dc;\n const t2 = (hi - pc) / dc;\n tMin = Math.max(tMin, Math.min(t1, t2));\n tMax = Math.min(tMax, Math.max(t1, t2));\n }\n if (tMin >= tMax || !Number.isFinite(tMin) || !Number.isFinite(tMax)) return null;\n return {\n a: { x: point.x + direction.x * tMin, y: point.y + direction.y * tMin },\n b: { x: point.x + direction.x * tMax, y: point.y + direction.y * tMax },\n };\n}\n\n/**\n * `rotateKnob` with a total page-bound placement policy: annotations, gestures\n * and chrome are all page-bound, so the grab dot must land inside `pageBox` —\n * off-page it is unreachable (the pointer dispatch resolves pages by\n * containment). Policy: top edge (the default) → flip to the bottom edge when\n * the stalk exits the page → clamp the top candidate inside (degenerate: the\n * selection spans ~the whole page; the knob may then overlap the shape, and\n * hit-testing checks it first so it stays grabbable). Both render (`chrome`)\n * and hit-test (`hitTest`) place the knob through this function, so what you\n * see is what you can grab — by construction. No `pageBox` → the raw knob.\n */\nexport function placeRotateKnob(\n corners: [Point, Point, Point, Point],\n offset: number,\n pageBox?: Rect,\n): { at: Point; from: Point } {\n const top = rotateKnob(corners, offset);\n if (!pageBox || insideRect(pageBox, top.at)) return top;\n // Flip: the same outward-normal math off the opposite (bottom) edge. On a\n // rotated OBB this exits through whichever page edge the stalk crossed.\n const [nw, , se, sw] = corners;\n const from = { x: (sw.x + se.x) / 2, y: (sw.y + se.y) / 2 };\n const down = { x: sw.x - nw.x, y: sw.y - nw.y };\n const len = Math.hypot(down.x, down.y) || 1;\n const at = {\n x: from.x + (down.x / len) * offset,\n y: from.y + (down.y / len) * offset,\n };\n if (insideRect(pageBox, at)) return { at, from };\n return {\n at: {\n x: Math.min(Math.max(top.at.x, pageBox.x), pageBox.x + pageBox.width),\n y: Math.min(Math.max(top.at.y, pageBox.y), pageBox.y + pageBox.height),\n },\n from: top.from,\n };\n}\n\n/**\n * A geom's visual bounds: the rect that encloses the drawn appearance, so the\n * baked /AP is never clipped.\n *\n * A box's strokes draw inside it; a cloudy border's bumps reach out from it,\n * so its bounds grow by the cloud's reach (`boxDrawnBounds`), before its\n * turn. Lines / polylines / ink have no box, so they expand by the stroke\n * (+ endings) — the same math feeds `geomScene`, so the visual box and what's\n * drawn always agree.\n *\n * The stroke's cloud matters too: a box's, and a closed poly's, whose curls\n * are centred on the vertex path and reach outward — the bounds grow by the\n * cloud extent, and the engine's `rect` grows with them so the baked scallops\n * are never clipped.\n */\nexport const geomVisualBounds = (geometry: Shape, stroke: Stroke): Rect =>\n familyOf(geometry).drawnBounds(geometry, stroke);\n\n/**\n * The rect the selection wraps — and the region a selected annotation can be grabbed\n * from. Centre-line geometries (line / polyline / polygon / ink) straddle their path,\n * so this is their visual bounds (the join-aware stroke outline + endings) — a\n * polygon's outline wraps its stroke exactly like a polyline. Box kinds (square /\n * circle / free-text) sit tight on their box (a stroke draws inside it, and a\n * cloud's bumps reach past it), so the 8 resize handles land on its corners. The chrome outline and the selected\n * hit-test both call this, so what you see highlighted is exactly what you can grab —\n * they can never drift.\n */\nexport const selectionBounds = (geometry: Shape, stroke: Stroke): Rect =>\n familyOf(geometry).selectionBounds(geometry, stroke);\n\n/**\n * The four corners of the oriented selection box — the same quad `chrome` draws.\n * For a rotatable kind this is the OBB (the tilted box, from `obbFromGeom`); at\n * `rot == 0` those are just the axis-aligned corners of `selectionBounds`, and\n * for non-rotatable kinds (markup quads, callouts) it falls back to the rect\n * corners. The grab region, the floating-menu anchor and the multi/group union\n * all consume this, so what you can grab / where the menu sits never drifts from\n * the outline you see.\n */\nexport function selectionQuad(geometry: Shape, stroke: Stroke): [Point, Point, Point, Point] {\n const obb = obbFromGeom(geometry, stroke);\n if (obb) return obb.corners;\n return rectCornerPoints(selectionBounds(geometry, stroke)) as [Point, Point, Point, Point];\n}\n\n/** Is the point inside the (convex) selection quad? Even-odd ring test. */\nexport const pointInQuad = (point: Point, quad: [Point, Point, Point, Point]): boolean =>\n pointInPoly(point, quad);\n\n/* ── geom ops ─────────────────────────────────────────────────────────────── */\n\n/** The box around the shape's own box or points, the stroke left out. */\nexport const geomBounds = (geometry: Shape): Rect => familyOf(geometry).bounds(geometry);\n\n/**\n * Is the page point on what the shape paints ({@link geomPainted}): within\n * `margin` of its ink, which widens with the stroke width, or inside it when\n * `filled`. A cloudy border is hit on its curves.\n */\nexport function geomHit(\n geometry: Shape,\n point: Point,\n margin: number,\n filled: boolean,\n stroke: Stroke,\n): boolean {\n return paintedNear(geomPainted(geometry, stroke, filled), point, margin);\n}\n\n/** The pieces each shape object painted last, and the stroke and fill they were asked for. */\nconst paintedCache = new WeakMap<\n Shape,\n { stroke: Required<Stroke>; filled: boolean; pieces: readonly PaintedPiece[] }\n>();\n\n/**\n * What the shape paints (`painted.ts`): its ink for `stroke`, and its inside\n * when `filled`. Kept per shape object for the stroke and fill last asked\n * about, since a hover asks again on every pointer move.\n */\nexport function geomPainted(\n geometry: Shape,\n stroke: Stroke,\n filled: boolean,\n): readonly PaintedPiece[] {\n const asked = {\n strokeWidth: stroke.strokeWidth,\n cloudyIntensity: stroke.cloudyIntensity ?? null,\n };\n const cached = paintedCache.get(geometry);\n if (\n cached?.filled === filled &&\n cached.stroke.strokeWidth === asked.strokeWidth &&\n cached.stroke.cloudyIntensity === asked.cloudyIntensity\n )\n return cached.pieces;\n const pieces = familyOf(geometry).painted(geometry, asked, filled);\n paintedCache.set(geometry, { stroke: asked, filled, pieces });\n return pieces;\n}\n\n/** The shape's handles: resize corners and sides, a callout's tip and knee, or vertices. */\nexport const geomHandles = (geometry: Shape): Handle[] => familyOf(geometry).handles(geometry);\n\nexport const geomTranslate = (geometry: Shape, delta: Point): Shape =>\n familyOf(geometry).translate(geometry, delta);\n\nexport const geomDragHandle = (geometry: Shape, handle: string, to: Point): Shape =>\n familyOf(geometry).drag(geometry, handle, to);\n\n/**\n * What the shape draws for the live view. A text box's box — its fill and\n * its border — is the scene's, plain box and callout alike, so the live view\n * paints exactly what the AP generator bakes; the framework's editable\n * element owns only the text.\n */\nexport const geomScene = (geometry: Shape, stroke: Stroke): RenderNode[] =>\n familyOf(geometry).scene(geometry, stroke);\n","/**\n * Writing engine fields to a record: the one door every edit that states\n * engine fields goes through — a sidebar restyle, a flag, a link target, a\n * text format, a measurement's leader.\n */\nimport {\n ANNOTATION_FIELD_NAMES,\n annotationPatchBetween,\n mergeAnnotationPatch,\n resolveRectCommand,\n type AnnotationPatch,\n} from '@embedpdf/engine-core/runtime';\n\nimport { mayWrite } from '../flags';\nimport type { FieldValues, ModelAnnotation } from '../types';\n\n/**\n * The record with engine `values` written, as far as it takes them:\n *\n * 1. Only the fields its kind has and this session may change now\n * (`mayWrite`). The rest are ignored, so one set of values restyles a\n * mixed selection.\n * 2. A `rect` is a command, resolved as the engine resolves it\n * (`resolveRectCommand`): it becomes the shape that puts the drawing\n * there, and one the engine would refuse throws.\n * 3. Merged into its annotation as given. The engine's follow rules (a\n * measurement's label, a callout's end) run once, where the change is\n * applied (`applyChange`).\n *\n * A value set to what it was is no change: the same record comes back.\n */\nexport function withValues(record: ModelAnnotation, values: FieldValues): ModelAnnotation {\n const declared = ANNOTATION_FIELD_NAMES[record.annotation.subtype];\n const taken: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(values)) {\n if (value === undefined || field === 'subtype' || !declared.includes(field)) continue;\n if (mayWrite(record, field)) taken[field] = value;\n }\n if (!Object.keys(taken).length) return record;\n const stated = resolveRectCommand(record.annotation, {\n ...taken,\n subtype: record.annotation.subtype,\n } as AnnotationPatch);\n const annotation = mergeAnnotationPatch(record.annotation, stated);\n return Object.keys(annotationPatchBetween(record.annotation, annotation)).length\n ? { ...record, annotation }\n : record;\n}\n","/**\n * An annotation's shape: its kind's family reads it off the annotation, and\n * a changed shape goes back as the engine fields that state it.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { familyOf } from '../shapes';\nimport type { ModelAnnotation, Shape } from '../types';\nimport { kindOf } from './identity';\nimport { withValues } from './values';\n\nconst shapes = new WeakMap<Annotation, Shape>();\n\n/**\n * The annotation's shape (`shapes/`), read by its kind's family. The same\n * shape for the same annotation, so what is worked out from a shape once\n * (where its points are drawn) is kept.\n */\nexport function shapeOf(annotation: Annotation): Shape {\n let shape = shapes.get(annotation);\n if (!shape) {\n shape = kindOf(annotation).family.read(annotation);\n shapes.set(annotation, shape);\n }\n return shape;\n}\n\n/**\n * The record with its shape changed: the engine fields that state `shape`,\n * written through `withValues`. The same record when the shape is the one\n * it has, or when the record may not change now.\n */\nexport const withShape = (record: ModelAnnotation, shape: Shape): ModelAnnotation =>\n withValues(record, familyOf(shape).write(shape, record.annotation.subtype));\n","/**\n * An annotation's style: how it is drawn, worked out by its kind from the\n * annotation's own fields (`kinds/styles.ts`).\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport type { Style } from '../types';\nimport { kindOf } from './identity';\n\nconst styles = new WeakMap<Annotation, Style>();\n\n/**\n * How the annotation is drawn: its colours, stroke and border, by the\n * engine's names, with its kind's fill-ins. A view: nothing is written back\n * through it. The same style for the same annotation.\n */\nexport function styleOf(annotation: Annotation): Style {\n let style = styles.get(annotation);\n if (!style) {\n style = kindOf(annotation).style(annotation);\n styles.set(annotation, style);\n }\n return style;\n}\n","/**\n * An annotation's text: how it is set, worked out by its kind from the\n * annotation's own fields (`kinds/texts.ts`), for the kinds that have text.\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport type { TextStyle } from '../types';\nimport { kindOf } from './identity';\n\nconst texts = new WeakMap<Annotation, TextStyle | undefined>();\n\n/**\n * How the annotation's text is set: its font, size, colour and alignment by\n * the engine's names, and a free text's bold, italic and underline. A view:\n * nothing is written back through it. `undefined` for a kind without text.\n * The same value for the same annotation.\n */\nexport function textOf(annotation: Annotation): TextStyle | undefined {\n if (texts.has(annotation)) return texts.get(annotation);\n const text = kindOf(annotation).text?.(annotation);\n texts.set(annotation, text);\n return text;\n}\n","/**\n * Links: the rects a parent's attached link children take, and the link\n * targets a write can state.\n */\nimport { quadBounds } from '@embedpdf/core-geometry';\nimport type { PdfLinkTarget, PdfLinkTargetWritable } from '@embedpdf/engine-core/runtime';\n\nimport { selectionQuad } from '../geometry';\nimport { rotatedAabb, unionRect } from '../rect';\nimport type { Shape, Rect, Style } from '../types';\n\n/**\n * The desired hit rects (page space) of a parent's attached link\n * children — derived fresh from the parent's committed geometry, never\n * tracked: markup gets one child per quad (per-line hit areas), a text box\n * one child over its box, every other kind one child over its visual bounds.\n * The reconciler and the navigation lens both read this, so the clickable\n * area and the written `/Rect`s can never disagree.\n *\n * A link's `/Rect` is axis-aligned by spec (no rotation exists for links),\n * so a rotated parent gets the AABB of its rotated footprint — the\n * `selectionQuad` corners (rotation + stroke included), the same envelope\n * the selection chrome outlines. A text box's link covers only its turned\n * box: a callout's frame also takes in its line, and a link that size\n * would make the empty space around the line clickable. Exact rotated hit\n * regions need `/QuadPoints` (tier 2).\n */\nexport function linkChildRects(shape: Shape, style: Style): Rect[] {\n if (shape.kind === 'quads') return shape.quadPoints.map(quadBounds);\n if (shape.kind === 'text-box') return [rotatedAabb(shape.box, shape.rotation)];\n return [unionRect(selectionQuad(shape, style))];\n}\n\n/** The writable projection of a `link` value: `goto`/`uri` pass through,\n * read-only arms (`javascript`, `named`, `goto-remote`, `launch`,\n * `unsupported`) yield `null` — they can be carried, never (re)written. */\nexport function writableTarget(\n target: PdfLinkTarget | null | undefined,\n): PdfLinkTargetWritable | null {\n return target && (target.kind === 'goto' || target.kind === 'uri') ? target : null;\n}\n","/**\n * Helvetica as the engine sets it. A label or caption that names no other\n * font is drawn in Helvetica, so measuring with these numbers lays text out\n * where the engine will, independent of the fonts a browser has.\n */\n\n// Standard Helvetica advances in 1/1000 em, ASCII 32–126.\nconst ADVANCES = [\n 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556,\n 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667,\n 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667,\n 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500,\n 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584,\n];\n\n// Superscripts and typographic primes, which the built-in unit formats use.\nconst EXTRA_ADVANCES: Record<string, number> = {\n '²': 333,\n '³': 333,\n '′': 191,\n '″': 355,\n '−': 584,\n ' ': 278,\n};\n\n/** From a line's top to its baseline, in em. */\nexport const HELVETICA_ASCENT = 0.962;\n\n/** From one line's top to the next, in em. */\nexport const HELVETICA_LINE_HEIGHT = 1.169;\n\n/**\n * How far `text` advances, in em. A character without a width here counts as\n * wide as a digit.\n */\nexport function helveticaAdvance(text: string): number {\n let advance = 0;\n for (const character of text) {\n const code = character.codePointAt(0)!;\n advance += ADVANCES[code - 32] ?? EXTRA_ADVANCES[character] ?? 556;\n }\n return advance / 1000;\n}\n","import { helveticaAdvance } from './helvetica';\n\nexport const DISTANCE_CAPTION_SIZE = 9;\n\n/**\n * A distance caption's width. Distance authoring uses the same base font as\n * the native caption fallback, Helvetica, also for headless callers.\n */\nexport function distanceCaptionWidth(text: string): number {\n return helveticaAdvance(text.trimEnd()) * DISTANCE_CAPTION_SIZE;\n}\n","import { isReadout, measurementReadout } from '@embedpdf/engine-core/runtime';\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\nimport { endingNodes, endingPieces, endingPoints } from './endings';\nimport { DISTANCE_CAPTION_SIZE as CAPTION_SIZE, distanceCaptionWidth } from './measurement-font';\nimport { geomRotation, selectionQuad } from './geometry';\nimport { dashOf } from './kinds/styles';\nimport { bodyPieces, type PaintedPiece } from './painted';\nimport { rotatePoint, unionRect } from './rect';\nimport { drawnLineOf, strokedOutlineOf } from './shapes/points';\nimport type {\n FieldValues,\n Shape,\n Handle,\n Paint,\n QuadRing,\n Rect,\n RenderNode,\n SceneNode,\n Style,\n Point,\n} from './types';\nimport type { ShapeMeasurementAppearance } from './measurement-shape';\n\nexport type MeasurementAppearance = DistanceAppearance | ShapeMeasurementAppearance;\n\ntype LineAnnotation = Extract<Annotation, { subtype: 'line' }>;\n\n/**\n * A distance's measurement: the engine's own fields for its scale, its\n * caption (on or off, its position, and its offset in the line's own axes),\n * its leader and its label (`contents`, which the engine works out).\n */\nexport type DistanceAppearance = { intent: 'line-dimension' } & Pick<\n LineAnnotation,\n 'measure' | 'captionEnabled' | 'captionPosition' | 'captionOffset' | 'leader' | 'contents'\n>;\n\n/**\n * The annotation's measurement, when it is one: a line measuring a\n * distance, a polyline a perimeter, a polygon an area, as its intent says.\n * Its measurement fields, read off it for drawing and hit-testing.\n */\nexport function measurementOf(annotation: Annotation): MeasurementAppearance | undefined {\n if (annotation.subtype === 'line' && annotation.intent === 'line-dimension') {\n return {\n intent: annotation.intent,\n measure: annotation.measure,\n captionEnabled: annotation.captionEnabled,\n captionPosition: annotation.captionPosition,\n captionOffset: annotation.captionOffset,\n leader: annotation.leader,\n contents: annotation.contents,\n };\n }\n if (\n (annotation.subtype === 'polyline' || annotation.subtype === 'polygon') &&\n (annotation.intent === 'polyline-dimension' || annotation.intent === 'polygon-dimension')\n ) {\n return {\n intent: annotation.intent,\n measure: annotation.measure,\n captionEnabled: annotation.captionEnabled,\n contents: annotation.contents,\n };\n }\n return undefined;\n}\n\n/** The subject a measurement is named by, as Acrobat names it. */\nconst SUBJECT = {\n 'line-dimension': 'Distance',\n 'polyline-dimension': 'Perimeter',\n 'polygon-dimension': 'Area',\n} as const;\n\n/**\n * What a new measurement states beside its points: its intent, its scale\n * (one the engine can write), its caption and leader as it has them, and its\n * subject. Its label is the engine's: it works it out from the points and\n * the scale.\n */\nexport function measurementDraftFields(appearance: MeasurementAppearance): FieldValues {\n const caption =\n appearance.intent === 'line-dimension'\n ? {\n captionEnabled: appearance.captionEnabled,\n captionPosition: appearance.captionPosition,\n captionOffset: appearance.captionOffset,\n leader: appearance.leader,\n }\n : { captionEnabled: appearance.captionEnabled };\n return {\n intent: appearance.intent,\n measure: appearance.measure?.subtype === 'rectilinear' ? appearance.measure : null,\n ...Object.fromEntries(Object.entries(caption).filter(([, value]) => value !== undefined)),\n subject: SUBJECT[appearance.intent],\n };\n}\n\ntype CaptionOffset = DistanceAppearance['captionOffset'];\n\nexport interface DistanceSegment {\n from: Point;\n to: Point;\n}\n\nexport interface DistanceCaptionLayout {\n text: string;\n center: Point;\n along: Point;\n normal: Point;\n width: number;\n height: number;\n bounds: QuadRing;\n}\n\n/** One layout drives the preview, selection, handles, and hit testing. */\nexport interface DistanceLayout {\n along: Point;\n normal: Point;\n length: number;\n measuredStart: Point;\n measuredEnd: Point;\n dimensionStart: Point;\n dimensionEnd: Point;\n dimensionSegments: DistanceSegment[];\n leaderSegments: DistanceSegment[];\n captionConnector: DistanceSegment[];\n caption: DistanceCaptionLayout | null;\n arrowPlacement: 'inside' | 'outside';\n endings: RenderNode[];\n selectionPoints: Point[];\n visualBounds: Rect;\n}\n\nconst CAPTION_PADDING = 2;\nconst OUTSIDE_CAPTION_PADDING = 7;\nconst ARROW_RESERVE = 24;\nconst OUTSIDE_STUB_LENGTH = 20;\n\nfunction offsetPoint(point: Point, direction: Point, distance: number): Point {\n return {\n x: point.x + direction.x * distance,\n y: point.y + direction.y * distance,\n };\n}\n\nfunction projectDelta(from: Point, to: Point, direction: Point): number {\n return (to.x - from.x) * direction.x + (to.y - from.y) * direction.y;\n}\n\nfunction lineAxes(start: Point, end: Point) {\n const length = Math.hypot(end.x - start.x, end.y - start.y);\n const along =\n length > 0 ? { x: (end.x - start.x) / length, y: (end.y - start.y) / length } : { x: 1, y: 0 };\n\n // PDF's +90° normal, expressed in content coordinates (y down).\n const normal = { x: along.y, y: -along.x };\n\n return { along, normal, length };\n}\n\nexport function distanceLabel(geometry: Shape, appearance: DistanceAppearance): string {\n if (geometry.kind !== 'line') {\n return appearance.contents ?? '';\n }\n\n const readout = measurementReadout({\n subtype: 'line',\n intent: appearance.intent,\n measure: appearance.measure,\n linePoints: geometry.linePoints,\n });\n\n return isReadout(readout) ? readout.label : (appearance.contents ?? '');\n}\n\nfunction captionQuad(\n center: Point,\n along: Point,\n normal: Point,\n width: number,\n height: number,\n): QuadRing {\n const corner = (x: number, y: number) => offsetPoint(offsetPoint(center, along, x), normal, y);\n\n return [\n corner(-width / 2, -height / 2),\n corner(width / 2, -height / 2),\n corner(width / 2, height / 2),\n corner(-width / 2, height / 2),\n ];\n}\n\n/** A displaced caption connects to the midpoint, stopping clear of its text. */\nfunction captionConnector(\n midpoint: Point,\n caption: DistanceCaptionLayout,\n along: Point,\n normal: Point,\n offset: CaptionOffset,\n): DistanceSegment[] {\n if (!offset || (offset.along === 0 && offset.perpendicular === 0)) {\n return [];\n }\n\n const perpendicular = projectDelta(midpoint, caption.center, normal);\n const horizontal = projectDelta(midpoint, caption.center, along);\n const halfWidth = caption.width / 2 + CAPTION_PADDING;\n const halfHeight = caption.height / 2 + CAPTION_PADDING;\n\n if (Math.abs(perpendicular) <= halfHeight) {\n return [];\n }\n\n if (Math.abs(horizontal) <= halfWidth) {\n const to = offsetPoint(midpoint, normal, perpendicular - Math.sign(perpendicular) * halfHeight);\n return [{ from: midpoint, to }];\n }\n\n const knee = offsetPoint(midpoint, normal, perpendicular);\n const to = offsetPoint(caption.center, along, -Math.sign(horizontal) * halfWidth);\n\n return [\n { from: midpoint, to: knee },\n { from: knee, to },\n ];\n}\n\nfunction dimensionSegments(\n start: Point,\n end: Point,\n along: Point,\n normal: Point,\n length: number,\n caption: DistanceCaptionLayout | null,\n position: DistanceAppearance['captionPosition'],\n outside: boolean,\n strokeWidth: number,\n): DistanceSegment[] {\n if (outside) {\n const stubLength = OUTSIDE_STUB_LENGTH * strokeWidth;\n return [\n { from: offsetPoint(start, along, -stubLength), to: start },\n { from: end, to: offsetPoint(end, along, stubLength) },\n ];\n }\n\n if (!caption || position === 'top') {\n return [{ from: start, to: end }];\n }\n\n const perpendicular = projectDelta(start, caption.center, normal);\n if (Math.abs(perpendicular) >= caption.height / 2 + CAPTION_PADDING) {\n return [{ from: start, to: end }];\n }\n\n const at = projectDelta(start, caption.center, along);\n const halfGap = caption.width / 2 + CAPTION_PADDING;\n const gapStart = Math.max(0, Math.min(length, at - halfGap));\n const gapEnd = Math.max(0, Math.min(length, at + halfGap));\n const segments: DistanceSegment[] = [];\n\n if (gapStart > 0) {\n segments.push({ from: start, to: offsetPoint(start, along, gapStart) });\n }\n if (gapEnd < length) {\n segments.push({ from: offsetPoint(start, along, gapEnd), to: end });\n }\n\n return segments;\n}\n\nexport function distanceLayout(\n geometry: Shape,\n appearance: DistanceAppearance,\n strokeWidth: number,\n): DistanceLayout | null {\n if (geometry.kind !== 'line') {\n return null;\n }\n\n const { start: a, end: b } = drawnLineOf(geometry);\n const { along, normal, length } = lineAxes(a, b);\n const leaderLength = appearance.leader?.length ?? 0;\n const dimensionStart = offsetPoint(a, normal, leaderLength);\n const dimensionEnd = offsetPoint(b, normal, leaderLength);\n const midpoint = offsetPoint(dimensionStart, along, length / 2);\n const text = distanceLabel(geometry, appearance);\n const width = distanceCaptionWidth(text);\n const hasCaption = !!appearance.captionEnabled && text.length > 0;\n // A documented fit policy, constrained by the Acrobat 1.75 m / 2.01 m cases.\n const outside = hasCaption && width + 2 * CAPTION_PADDING + ARROW_RESERVE * strokeWidth > length;\n\n let caption: DistanceCaptionLayout | null = null;\n if (hasCaption) {\n const reversed = along.x < 0 || (along.x === 0 && along.y > 0);\n const textAlong = reversed ? { x: -along.x, y: -along.y } : along;\n const textNormal = { x: textAlong.y, y: -textAlong.x };\n const offset = appearance.captionOffset;\n let center = offsetPoint(midpoint, along, offset?.along ?? 0);\n center = offsetPoint(center, normal, offset?.perpendicular ?? 0);\n\n if (appearance.captionPosition === 'top' || outside) {\n const side = outside && leaderLength < 0 ? -1 : 1;\n const padding = outside ? OUTSIDE_CAPTION_PADDING : CAPTION_PADDING;\n // The anchor follows the directed line when it rotates. Only the glyph\n // orientation flips for readability; that must not move the caption.\n center = offsetPoint(center, normal, side * (CAPTION_SIZE / 2 + padding));\n }\n\n caption = {\n text,\n center,\n along: textAlong,\n normal: textNormal,\n width,\n height: CAPTION_SIZE,\n bounds: captionQuad(center, textAlong, textNormal, width, CAPTION_SIZE),\n };\n }\n\n const leaderSegments: DistanceSegment[] = [];\n if (leaderLength !== 0) {\n const side = Math.sign(leaderLength);\n const leaderOffset = side * (appearance.leader?.offset ?? 0);\n const leaderEnd = leaderLength + side * (appearance.leader?.extension ?? 0);\n\n for (const endpoint of [a, b]) {\n leaderSegments.push({\n from: offsetPoint(endpoint, normal, leaderOffset),\n to: offsetPoint(endpoint, normal, leaderEnd),\n });\n }\n }\n\n const segments = dimensionSegments(\n dimensionStart,\n dimensionEnd,\n along,\n normal,\n length,\n caption,\n appearance.captionPosition,\n outside,\n strokeWidth,\n );\n const connector = caption\n ? captionConnector(midpoint, caption, along, normal, appearance.captionOffset)\n : [];\n\n const angle = Math.atan2(along.y, along.x);\n const startAngle = outside ? angle : angle + Math.PI;\n const endAngle = outside ? angle + Math.PI : angle;\n const endings = [\n ...endingNodes(dimensionStart, startAngle, geometry.lineEndings?.start, strokeWidth),\n ...endingNodes(dimensionEnd, endAngle, geometry.lineEndings?.end, strokeWidth),\n ];\n const boundsPoints = [\n a,\n b,\n ...segments.flatMap((segment) => [segment.from, segment.to]),\n ...leaderSegments.flatMap((segment) => [segment.from, segment.to]),\n ...connector.flatMap((segment) => [segment.from, segment.to]),\n ...endingPoints(dimensionStart, startAngle, geometry.lineEndings?.start, strokeWidth),\n ...endingPoints(dimensionEnd, endAngle, geometry.lineEndings?.end, strokeWidth),\n ...(caption?.bounds ?? []),\n ];\n\n return {\n along,\n normal,\n length,\n measuredStart: a,\n measuredEnd: b,\n dimensionStart,\n dimensionEnd,\n dimensionSegments: segments,\n leaderSegments,\n captionConnector: connector,\n caption,\n arrowPlacement: outside ? 'outside' : 'inside',\n endings,\n selectionPoints: boundsPoints,\n visualBounds: expandDistanceBounds(unionRect(boundsPoints), strokeWidth / 2 + 1),\n };\n}\n\nexport function expandDistanceBounds(bounds: Rect, padding: number): Rect {\n return {\n x: bounds.x - padding,\n y: bounds.y - padding,\n width: bounds.width + 2 * padding,\n height: bounds.height + 2 * padding,\n };\n}\n\nexport function distanceSelectionQuad(\n geometry: Shape,\n appearance: DistanceAppearance,\n strokeWidth: number,\n): QuadRing {\n const layout = distanceLayout(geometry, appearance, strokeWidth);\n if (!layout || geometry.kind !== 'line') {\n return selectionQuad(geometry, { strokeWidth: strokeWidth });\n }\n\n // The line's own frame is its turn. Include every measurement component\n // before constructing that frame, then rotate its corners back. Reboxing the\n // page-aligned bounds would grow and shift the selection as the annotation\n // turns.\n const angle = geomRotation(geometry);\n const origin = drawnLineOf(geometry).start;\n const points = layout.selectionPoints.map((point) => rotatePoint(point, origin, -angle));\n const bounds = expandDistanceBounds(unionRect(points), strokeWidth / 2 + 1);\n const corner = (x: number, y: number) => rotatePoint({ x, y }, origin, angle);\n\n return [\n corner(bounds.x, bounds.y),\n corner(bounds.x + bounds.width, bounds.y),\n corner(bounds.x + bounds.width, bounds.y + bounds.height),\n corner(bounds.x, bounds.y + bounds.height),\n ];\n}\n\nexport function distanceHandles(layout: DistanceLayout): Handle[] {\n return [\n { id: 'v0', at: layout.measuredStart, cursor: 'crosshair' },\n { id: 'v1', at: layout.measuredEnd, cursor: 'crosshair' },\n { id: 'leader-start', at: layout.dimensionStart, cursor: 'move' },\n { id: 'leader-end', at: layout.dimensionEnd, cursor: 'move' },\n ];\n}\n\nexport function distanceCaptionHit(\n layout: { caption: DistanceCaptionLayout | null },\n point: Point,\n margin = 0,\n): boolean {\n const caption = layout.caption;\n if (!caption) {\n return false;\n }\n\n const along = projectDelta(caption.center, point, caption.along);\n const perpendicular = projectDelta(caption.center, point, caption.normal);\n\n return (\n Math.abs(along) <= caption.width / 2 + margin &&\n Math.abs(perpendicular) <= caption.height / 2 + margin\n );\n}\n\n/** What a measurement's caption paints: its box, grabbed anywhere in it and near its edge. */\nexport const captionPainted = (caption: DistanceCaptionLayout | null): PaintedPiece[] =>\n caption ? bodyPieces(caption.bounds) : [];\n\n/**\n * What a distance measurement paints: its caption, the ink of its dimension\n * line, leaders and caption connector, and its endings.\n */\nexport function distancePainted(layout: DistanceLayout, strokeWidth: number): PaintedPiece[] {\n const halfWidth = strokeWidth / 2;\n const segments = [\n ...layout.dimensionSegments,\n ...layout.leaderSegments,\n ...layout.captionConnector,\n ];\n return [\n ...captionPainted(layout.caption),\n ...segments.map(\n ({ from, to }): PaintedPiece => ({\n kind: 'stroke',\n points: [from, to],\n closed: false,\n halfWidth,\n }),\n ),\n ...endingPieces(layout.endings, strokeWidth),\n ];\n}\n\nexport function distanceCaptionAt(\n geometry: Shape,\n appearance: DistanceAppearance,\n width: number,\n): Point | null {\n return distanceLayout(geometry, appearance, width)?.caption?.center ?? null;\n}\n\nexport function distanceLeaderLength(geometry: Shape, point: Point): number {\n if (geometry.kind !== 'line') {\n return 0;\n }\n\n const { start, end } = drawnLineOf(geometry);\n const { normal } = lineAxes(start, end);\n return projectDelta(start, point, normal);\n}\n\nexport function moveDistanceCaption(\n geometry: Shape,\n appearance: DistanceAppearance,\n delta: Point,\n): DistanceAppearance {\n if (geometry.kind !== 'line') {\n return appearance;\n }\n\n const { start, end } = drawnLineOf(geometry);\n const { along, normal } = lineAxes(start, end);\n const previous = appearance.captionOffset;\n\n return {\n ...appearance,\n captionOffset: {\n along: (previous?.along ?? 0) + delta.x * along.x + delta.y * along.y,\n perpendicular: (previous?.perpendicular ?? 0) + delta.x * normal.x + delta.y * normal.y,\n },\n };\n}\n\n/**\n * The upright box around all a distance paints: its dimension line, leader\n * and connector lines and its endings stroked at `strokeWidth` (what\n * `distanceScene` draws), and its caption's box.\n */\nexport function distanceDrawnBounds(layout: DistanceLayout, strokeWidth: number): Rect {\n const lines = [\n ...layout.dimensionSegments,\n ...layout.leaderSegments,\n ...layout.captionConnector,\n ].map((segment): RenderNode => ({ kind: 'line', a: segment.from, b: segment.to }));\n return unionRect([\n ...strokedOutlineOf([...lines, ...layout.endings], strokeWidth),\n ...(layout.caption?.bounds ?? []),\n ]);\n}\n\nexport function distanceScene(\n geometry: Shape,\n appearance: DistanceAppearance,\n style: Style,\n): SceneNode[] {\n const layout = distanceLayout(geometry, appearance, style.strokeWidth);\n if (!layout) {\n return [];\n }\n\n const paint: Paint = {\n stroke: style.color,\n width: style.strokeWidth,\n opacity: style.opacity,\n dash: dashOf(style),\n };\n const segments = [\n ...layout.dimensionSegments,\n ...layout.leaderSegments,\n ...layout.captionConnector,\n ];\n const nodes: SceneNode[] = segments.map((segment) => ({\n kind: 'line',\n a: segment.from,\n b: segment.to,\n paint,\n }));\n\n for (const ending of layout.endings) {\n const filled = ending.kind === 'ellipse' || (ending.kind === 'poly' && ending.closed);\n nodes.push({\n ...ending,\n paint: {\n ...paint,\n fill: filled ? (style.interiorColor ?? undefined) : undefined,\n },\n } as SceneNode);\n }\n\n nodes.push(...measurementCaptionScene(layout.caption, style));\n\n return nodes;\n}\n\nexport function measurementCaptionScene(\n caption: DistanceCaptionLayout | null,\n style: Style,\n): SceneNode[] {\n if (caption) {\n const baseline = offsetPoint(caption.center, caption.normal, -CAPTION_SIZE * 0.33);\n const at = offsetPoint(baseline, caption.along, -caption.width / 2);\n\n return [\n {\n kind: 'text',\n at,\n text: caption.text,\n fontSize: CAPTION_SIZE,\n fontFamily: 'Helvetica, Arial, sans-serif',\n rotation: (Math.atan2(caption.along.y, caption.along.x) * 180) / Math.PI,\n paint: { fill: '#000000', opacity: style.opacity },\n },\n ];\n }\n return [];\n}\n","import { isReadout, measurementReadout } from '@embedpdf/engine-core/runtime';\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\nimport { geomRotation, selectionQuad } from './geometry';\nimport { pointInPoly, rotatePoint, unionRect } from './rect';\nimport { drawnPointOf, drawnVerticesOf, uprightPointOf } from './shapes/points';\nimport { DISTANCE_CAPTION_SIZE, distanceCaptionWidth } from './measurement-font';\nimport { distanceLayout, distanceSelectionQuad, moveDistanceCaption } from './measurement';\nimport type { DistanceCaptionLayout, MeasurementAppearance } from './measurement';\nimport type { Shape, QuadRing, Rect, Style, Point } from './types';\n\ntype ShapeAnnotation = Extract<Annotation, { subtype: 'polygon' | 'polyline' }>;\n\n/**\n * A perimeter's or area's measurement: the engine's own fields for its scale,\n * whether its caption shows, and its label (`contents`, which the engine\n * works out). Where the caption sits is the shape's `captionCenter`.\n */\nexport type ShapeMeasurementAppearance = {\n intent: 'polyline-dimension' | 'polygon-dimension';\n} & Pick<ShapeAnnotation, 'measure' | 'captionEnabled' | 'contents'>;\n\nexport interface ShapeMeasurementLayout {\n caption: DistanceCaptionLayout | null;\n visualBounds: Rect;\n selectionPoints: Point[];\n}\n\nconst ORIGIN = { x: 0, y: 0 };\n\nexport function shapeMeasurementReadout(geometry: Shape, appearance: ShapeMeasurementAppearance) {\n return measurementReadout({\n subtype: appearance.intent === 'polygon-dimension' ? 'polygon' : 'polyline',\n intent: appearance.intent,\n measure: appearance.measure,\n vertices: geometry.kind === 'poly' ? geometry.vertices : [],\n });\n}\n\nexport function shapeMeasurementLabel(\n geometry: Shape,\n appearance: ShapeMeasurementAppearance,\n): string {\n const readout = shapeMeasurementReadout(geometry, appearance);\n if (isReadout(readout)) return readout.label;\n return readout.unavailable === 'invalid-geometry' ? '—' : (appearance.contents ?? '');\n}\n\n/** Match the native shape-caption anchor, including an interior fallback for concave areas. */\nexport function automaticShapeCaptionCenter(points: readonly Point[], closed: boolean): Point {\n if (!points.length) return ORIGIN;\n if (!closed) {\n const lengths = points\n .slice(1)\n .map((point, i) => Math.hypot(point.x - points[i].x, point.y - points[i].y));\n let remaining = lengths.reduce((sum, length) => sum + length, 0) / 2;\n for (let i = 0; i < lengths.length; i++) {\n const length = lengths[i];\n if (length > 0 && remaining <= length) {\n const fraction = remaining / length;\n return {\n x: points[i].x + fraction * (points[i + 1].x - points[i].x),\n y:\n points[i].y +\n fraction * (points[i + 1].y - points[i].y) -\n DISTANCE_CAPTION_SIZE / 2 -\n 2,\n };\n }\n remaining -= length;\n }\n return points[0];\n }\n\n const origin = points[0];\n let area = 0;\n let momentX = 0;\n let momentY = 0;\n for (let i = 0; i < points.length; i++) {\n const start = { x: points[i].x - origin.x, y: points[i].y - origin.y };\n const next = points[(i + 1) % points.length];\n const end = { x: next.x - origin.x, y: next.y - origin.y };\n const cross = start.x * end.y - end.x * start.y;\n area += cross;\n momentX += (start.x + end.x) * cross;\n momentY += (start.y + end.y) * cross;\n }\n if (Math.abs(area) > 1e-8) {\n const center = { x: origin.x + momentX / (3 * area), y: origin.y + momentY / (3 * area) };\n if (pointInPoly(center, points)) return center;\n }\n\n const bounds = unionRect([...points]);\n const fallback = { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 };\n const intersections: number[] = [];\n for (let i = 0; i < points.length; i++) {\n const start = points[i];\n const end = points[(i + 1) % points.length];\n if (start.y > fallback.y !== end.y > fallback.y) {\n intersections.push(\n start.x + ((fallback.y - start.y) * (end.x - start.x)) / (end.y - start.y),\n );\n }\n }\n intersections.sort((left, right) => left - right);\n let widest = -1;\n for (let i = 1; i < intersections.length; i += 2) {\n const width = intersections[i] - intersections[i - 1];\n if (width > widest) {\n widest = width;\n fallback.x = (intersections[i] + intersections[i - 1]) / 2;\n }\n }\n return fallback;\n}\n\nexport function shapeMeasurementLayout(\n geometry: Shape,\n appearance: ShapeMeasurementAppearance,\n style: Style,\n): ShapeMeasurementLayout | null {\n if (geometry.kind !== 'poly' || !geometry.vertices.length) return null;\n const angle = geomRotation(geometry);\n const localPoints = drawnVerticesOf(geometry).map((point) => rotatePoint(point, ORIGIN, -angle));\n const center = geometry.captionCenter\n ? drawnPointOf(geometry, geometry.captionCenter)\n : rotatePoint(automaticShapeCaptionCenter(localPoints, geometry.closed), ORIGIN, angle);\n const text = shapeMeasurementLabel(geometry, appearance);\n const width = distanceCaptionWidth(text);\n const height = DISTANCE_CAPTION_SIZE;\n const along = rotatePoint({ x: 1, y: 0 }, ORIGIN, angle);\n const normal = { x: along.y, y: -along.x };\n const corner = (x: number, y: number): Point => ({\n x: center.x + x * along.x + y * normal.x,\n y: center.y + x * along.y + y * normal.y,\n });\n const caption: DistanceCaptionLayout | null =\n appearance.captionEnabled && text\n ? {\n text,\n center,\n along,\n normal,\n width,\n height,\n bounds: [\n corner(-width / 2, -height / 2),\n corner(width / 2, -height / 2),\n corner(width / 2, height / 2),\n corner(-width / 2, height / 2),\n ],\n }\n : null;\n const selectionPoints = [...selectionQuad(geometry, style), ...(caption?.bounds ?? [])];\n return { caption, selectionPoints, visualBounds: unionRect(selectionPoints) };\n}\n\nexport function measurementLayout(\n geometry: Shape,\n appearance: MeasurementAppearance,\n style: Style,\n) {\n return appearance.intent === 'line-dimension'\n ? distanceLayout(geometry, appearance, style.strokeWidth)\n : shapeMeasurementLayout(geometry, appearance, style);\n}\n\nexport function measurementSelectionQuad(\n geometry: Shape,\n appearance: MeasurementAppearance,\n style: Style,\n): QuadRing {\n if (appearance.intent === 'line-dimension') {\n return distanceSelectionQuad(geometry, appearance, style.strokeWidth);\n }\n const layout = shapeMeasurementLayout(geometry, appearance, style);\n if (!layout) return selectionQuad(geometry, style);\n const angle = geomRotation(geometry);\n const bounds = unionRect(\n layout.selectionPoints.map((point) => rotatePoint(point, ORIGIN, -angle)),\n );\n return [\n { x: bounds.x, y: bounds.y },\n { x: bounds.x + bounds.width, y: bounds.y },\n { x: bounds.x + bounds.width, y: bounds.y + bounds.height },\n { x: bounds.x, y: bounds.y + bounds.height },\n ].map((point) => rotatePoint(point, ORIGIN, angle)) as QuadRing;\n}\n\n/**\n * The caption dragged by `delta`: a distance's caption offset changes (its\n * measurement), a perimeter's or area's caption center (its shape, kept\n * upright with the vertices).\n */\nexport function moveMeasurementCaption(\n geometry: Shape,\n appearance: MeasurementAppearance,\n delta: Point,\n style: Style,\n): { geometry: Shape; measure: MeasurementAppearance } {\n if (appearance.intent === 'line-dimension')\n return { geometry, measure: moveDistanceCaption(geometry, appearance, delta) };\n const center = shapeMeasurementLayout(geometry, appearance, style)?.caption?.center;\n if (!center || geometry.kind !== 'poly') return { geometry, measure: appearance };\n const moved = { x: center.x + delta.x, y: center.y + delta.y };\n return {\n geometry: { ...geometry, captionCenter: uprightPointOf(geometry, moved) },\n measure: appearance,\n };\n}\n","/**\n * An annotation as the engine writes it: what the viewer shows while a\n * create or an edit is on its way, field for field what the engine's answer\n * will bring.\n *\n * The engine's own functions state the fields the change writes\n * (`annotationOfDraft`, `applyAnnotationPatch`). Two fields the engine works\n * out as it writes, and they follow its own verdict on the change\n * (`appearanceChangeOf`): a drawn kind's `rect` (`DRAWN_RECT_KINDS`), the\n * upright box around what its appearance paints, and `hasAppearance`,\n * whether the file holds that appearance:\n *\n * | The change | `rect` | `hasAppearance` |\n * | :---------------------------------- | :----------------------------- | :----------------------- |\n * | Nothing visible | as it is | as it is |\n * | A pure move | moved the same distance | as it is |\n * | Anything else visible, and a create | the box around the new drawing | baked |\n *\n * The engine measures that box on the appearance it bakes; the viewer\n * measures it on the drawing it draws live (`drawnBoundsOf`). The two\n * drawings are the same drawing (or the annotation would jump when it\n * switches between them), so the two boxes are the same box:\n * `packages/engine/main/test/annotation-rect.test.ts` holds them to it.\n *\n * A kind whose shape is its rect (a link, a note, a form field) states its\n * rect itself. A link or form widget gets no appearance of the engine's\n * (`UNBAKED_KINDS`): whether the file holds one stays as it was, and a new\n * one has none.\n */\nimport {\n annotationOfDraft,\n appearanceChangeOf,\n applyAnnotationPatch,\n DRAWN_RECT_KINDS,\n resolveAnnotationPatch,\n UNBAKED_KINDS,\n type AnnotationDraft,\n type Annotation,\n type AnnotationPatch,\n type AnnotationRef,\n} from '@embedpdf/engine-core/runtime';\n\nimport { distanceDrawnBounds, distanceLayout, measurementOf } from '../measurement';\nimport { shapeMeasurementLayout } from '../measurement-shape';\nimport { rectCornerPoints, unionRect } from '../rect';\nimport { familyOf } from '../shapes';\nimport type { Rect } from '../types';\nimport { shapeOf } from './shape';\nimport { styleOf } from './style';\n\n/** Does the engine work out this annotation's `rect` from its drawing? */\nconst rectFollowsDrawing = (annotation: Annotation): boolean =>\n DRAWN_RECT_KINDS.has(annotation.subtype);\n\n/**\n * The upright page box around all the annotation paints: its shape as its\n * family paints it (stroke, endings, cloud, turn), and a measurement's\n * dimension line, leader lines and caption.\n */\nfunction drawnBoundsOf(annotation: Annotation): Rect {\n const shape = shapeOf(annotation);\n const style = styleOf(annotation);\n const bounds = familyOf(shape).rect(shape, style);\n const measure = measurementOf(annotation);\n if (!measure) return bounds;\n if (measure.intent === 'line-dimension') {\n const layout = distanceLayout(shape, measure, style.strokeWidth);\n return layout ? distanceDrawnBounds(layout, style.strokeWidth) : bounds;\n }\n const caption = shapeMeasurementLayout(shape, measure, style)?.caption;\n return caption ? unionRect([...rectCornerPoints(bounds), ...caption.bounds]) : bounds;\n}\n\n/**\n * The annotation `draft` creates, as the engine reads it back: the draft's\n * fields as the engine states them, and a drawn kind's `rect` the box around\n * its drawing. `at` names the ref it will have.\n */\nexport function annotationOfNew(\n draft: AnnotationDraft,\n at: { readonly ref: AnnotationRef },\n): Annotation {\n const annotation = annotationOfDraft(draft, at);\n return rectFollowsDrawing(annotation)\n ? { ...annotation, rect: drawnBoundsOf(annotation) }\n : annotation;\n}\n\n/**\n * `annotation` after `patch`, as the engine reads it back: the patch applied\n * by the engine's own rules, and the fields the engine works out as its\n * verdict on the change says (the table at the top of this file). Throws, as\n * the engine does, for a patch its rules refuse without its schemas\n * (`resolveAnnotationPatch`); values only the schemas refuse are applied, and\n * the engine refuses them when the patch reaches it.\n */\nexport function annotationAfter(annotation: Annotation, patch: AnnotationPatch): Annotation {\n const after = applyAnnotationPatch(annotation, patch);\n const change = appearanceChangeOf(annotation, resolveAnnotationPatch(annotation, patch));\n switch (change.impact) {\n case 'inert':\n return after;\n case 'translation': {\n if (!rectFollowsDrawing(after)) return after;\n const { rect } = annotation;\n return { ...after, rect: { ...rect, x: rect.x + change.by.x, y: rect.y + change.by.y } };\n }\n case 'regenerate':\n return {\n ...after,\n ...(UNBAKED_KINDS.has(after.subtype) ? {} : { hasAppearance: true }),\n ...(rectFollowsDrawing(after) ? { rect: drawnBoundsOf(after) } : {}),\n };\n }\n}\n","/**\n * A record: one annotation as the core works on it (`ModelAnnotation`). The\n * engine's annotation is its only data; this folder reads it and writes\n * engine fields back:\n *\n * identity.ts who it is: its ref, its kind, the annotations it answers\n * shape.ts its shape, read by its kind's family, and a changed shape back\n * style.ts how it is drawn: its kind's style view\n * text.ts how its text is set: its kind's text view\n * values.ts engine fields written to it: the one door every edit uses\n * links.ts the rects its attached links take, and writable link targets\n * written.ts how it reads as the engine writes a create or an edit\n * defaults.ts a tool's defaults, read as an annotation (or a widget appearance)\n */\nimport { annotationKey } from '@embedpdf/core';\nimport { appearanceTurnOf, type Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { geomRotation } from '../geometry';\nimport type { ModelAnnotation } from '../types';\nimport { shapeOf } from './shape';\n\nexport { groupOf, irtOf, kindOf, refOf } from './identity';\nexport { shapeOf, withShape } from './shape';\nexport { styleOf } from './style';\nexport { textOf } from './text';\nexport { withValues } from './values';\nexport { linkChildRects, writableTarget } from './links';\nexport { annotationAfter, annotationOfNew } from './written';\n\n/**\n * The record an engine annotation reads as: keyed by its ref, drawn from the\n * engine's appearance raster (`source: 'baked'`, placed by `apBox`). Whether\n * this session draws it live instead is the appearance rule's\n * (appearance.ts).\n */\nexport function fromDTO(dto: Annotation): ModelAnnotation {\n // Rotation-stripped appearances (`appearanceTurnOf`, the engine's own rule):\n // a box kind drawn turned whose drawing stays inside the turned box has a\n // flat raster placed by its `box`, the stripped rotation re-applied as a\n // view transform (`apRot`). Every other raster — vertex kinds, a callout\n // (only its text box tilts), a turned drawing that reaches past its box —\n // is placed by `/Rect`, untransformed.\n const strippedRect = 'box' in dto && appearanceTurnOf(dto) !== null ? dto.box : undefined;\n return {\n id: annotationKey(dto.ref),\n source: 'baked',\n annotation: dto,\n apBox: strippedRect ?? dto.rect,\n ...(strippedRect ? { apRot: geomRotation(shapeOf(dto)) } : {}),\n };\n}\n","/**\n * Group membership — the pure, model-level view of an annotation group.\n *\n * A group is a primary annotation plus its subordinate members. Persistence is\n * the engine's `/IRT` + `/RT /Group` relationship: a subordinate's annotation\n * answers the primary's ref, so its `groupOf` is the primary's key. The\n * primary is not stamped — it is simply the annotation whose `id` equals the\n * group key, so membership is the set of annotations pointing at it plus the\n * primary itself.\n *\n * Attached link children are the exception: they ride the same `/RT /Group`\n * wire mechanism but are not part of the composite visual — they're substrate\n * plumbing (the parent's link property). They never count as members here, so\n * a linked square still selects as a single annotation with handles, never\n * shows Ungroup, and the ungroup verb can never strip an attached link's\n * `/IRT` (which would orphan it into an unmanaged standalone document link).\n */\nimport { isTransformableByHand } from './editable';\nimport { isAttachedLink } from './plane';\nimport type { KindCaps } from './kinds';\nimport { groupOf, kindOf } from './record';\nimport type { ModelAnnotation, Id, Model } from './types';\n\n/** A subordinate that counts toward a visual group (not link plumbing). */\nconst visualMember = (record: ModelAnnotation | undefined): boolean =>\n !!record && !isAttachedLink(record);\n\n/**\n * The transform capabilities of a multi-target (group) selection: a group can\n * move/resize/rotate only if every member's kind allows that group op and no\n * member is locked or frozen by the session's `editable` rule. This is the single resolver every adapter consumes, so no\n * framework component re-derives the rule. The iso-vs-\n * aniso resize choice is computed separately, per-gesture, since it depends on\n * the live `rot` of the members, not the static caps.\n */\nexport interface GroupCaps {\n movable: boolean;\n resizable: boolean;\n rotatable: boolean;\n}\n\nexport function groupCaps(model: Model, ids: Id[]): GroupCaps {\n const members = ids\n .map((id) => model.byId[id])\n .filter((record): record is NonNullable<typeof record> => !!record);\n if (members.length === 0) return { movable: false, resizable: false, rotatable: false };\n const ok = (pick: (caps: KindCaps) => boolean): boolean =>\n members.every(\n (record) => isTransformableByHand(model, record) && pick(kindOf(record.annotation).caps),\n );\n return {\n movable: ok((caps) => caps.groupMovable),\n resizable: ok((caps) => caps.groupResizable),\n rotatable: ok((caps) => caps.groupRotatable),\n };\n}\n\n/**\n * The key of the group `id` belongs to, or `null` when it is ungrouped. A\n * subordinate's key is its `groupOf`; a primary's key is its own id (it is the\n * target of at least one member's `groupOf`). An annotation that is neither a\n * subordinate nor the target of any subordinate is ungrouped.\n */\nexport function groupKeyOf(model: Model, id: Id): Id | null {\n const record = model.byId[id];\n if (!record) return null;\n const group = groupOf(record.annotation);\n if (group) return isAttachedLink(record) ? null : group;\n for (const other of model.order) {\n const sub = model.byId[other];\n if (sub && groupOf(sub.annotation) === id && visualMember(sub)) return id;\n }\n return null;\n}\n\n/**\n * Every member of the group containing `id` (primary first), or just `[id]`\n * when it is ungrouped. The primary is the annotation whose id is the key; the\n * rest are everything whose `groupOf` equals the key, in `order`.\n */\nexport function groupMembers(model: Model, id: Id): Id[] {\n const key = groupKeyOf(model, id);\n if (key == null) return [id];\n const members: Id[] = [];\n if (model.byId[key]) members.push(key);\n for (const other of model.order) {\n const sub = model.byId[other];\n if (other !== key && sub && groupOf(sub.annotation) === key && visualMember(sub))\n members.push(other);\n }\n return members;\n}\n\n/** Union of every id's full group — the selection seen as whole groups. */\nexport function expandGroups(model: Model, ids: Id[]): Id[] {\n const out: Id[] = [];\n const seen = new Set<Id>();\n for (const id of ids) {\n for (const member of groupMembers(model, id)) {\n if (!seen.has(member)) {\n seen.add(member);\n out.push(member);\n }\n }\n }\n return out;\n}\n","/**\n * Screen-anchored annotations — `noZoom` / `noRotate` (ISO 32000-2 §12.5.3).\n *\n * The mental model: these flags are display-transform exemptions, nothing\n * more. The view composes page space onto the screen with\n * `zoom × pageRotation`; a flagged annotation asks it to skip the zoom factor\n * (`noZoom`) and/or the page-rotation factor (`noRotate`), holding the\n * `/Rect` upper-left — the geometry's bounds top-left — fixed on the page.\n *\n * The flags do not restrict editing. The annotation keeps its full\n * page-space identity: a size (`/Rect`, which now reads as \"screen size at\n * zoom 1\") and an authored orientation (`rot` / rotated points, which now\n * reads as \"screen tilt at every page rotation\") — and both stay editable.\n * Edit restrictions come from kind caps (a note kind declares\n * `resizable: false`) and `locked`, never from here.\n *\n * Everything derives from one projection, {@link anchoredGeom}: the effective\n * page-space geometry of the body at the current view — a similarity\n * (uniform scale `1/s` + rotation `-r`) about the anchor. Rendering,\n * hit-testing, chrome, marquee, and clamping all read it, so what you see,\n * what you click, and what commits can never disagree. Compensating only in\n * the DOM containers would let hit-testing and commits drift from the render.\n *\n * Gestures compose in view space: project first, then apply the gesture to\n * the projected geometry — for un-flagged annotations the projection is the\n * identity, so this is the ordinary pipeline. A pointer-driven commit maps\n * the final view-space geometry back to stored space through\n * {@link unanchoredGeom}, the exact closed-form inverse — chosen so that the\n * committed geometry's own re-projection reproduces the released preview\n * (zero release-jump, any zoom, any rotation).\n *\n * The core stays zoom-free: the view environment is passed per call (the\n * `pageBox`/`chrome` pattern) and captured on pointer drafts at down; it is\n * never stored on the model.\n */\nimport { geomBounds, geomRotateAbout, geomScaleAbout, geomTranslate } from './geometry';\nimport { normalizeDeg, rotatePoint } from './rect';\nimport type { FlagBearer } from './flags';\nimport { kindOf } from './record/identity';\nimport type { Shape, Point, ViewEnv } from './types';\n\nexport type { ViewEnv };\n\n/** Which display factors this annotation is exempt from: `zoom` =\n * screen-constant size, `upright` = screen-constant orientation. */\nexport interface AnchorMode {\n zoom: boolean;\n upright: boolean;\n}\n\n/**\n * The anchor behaviors of one annotation: its `/F` flags or'd with the kind's\n * statics — the spec's \"Text (note) annotations behave as if NoZoom and\n * NoRotate are always set\", expressed as kind caps. Null when not anchored.\n */\nexport function anchorModeOf(record: FlagBearer): AnchorMode | null {\n const caps = kindOf(record.annotation).caps;\n const zoom = !!record.annotation.noZoom || caps.noZoom;\n const upright = !!record.annotation.noRotate || caps.noRotate;\n return zoom || upright ? { zoom, upright } : null;\n}\n\n/**\n * The geometries the projection applies to: every kind with free page-space\n * geometry — boxes and vertex kinds (line / poly / ink). Text-anchored\n * geometries (markup quads, carets) and callouts pass through: their position\n * is bound to page text, so a screen-constant body is meaningless there; the\n * flags still round-trip untouched.\n */\nconst projectable = (geometry: Shape): boolean =>\n geometry.kind === 'box' ||\n geometry.kind === 'line' ||\n geometry.kind === 'poly' ||\n geometry.kind === 'ink' ||\n (geometry.kind === 'text-box' && !geometry.calloutLine);\n\n/** The fixed page point: the geometry's bounds top-left in page space\n * (y-down) — which is the spec's \"upper-left corner of the annotation\n * rectangle\", since `/Rect` is emitted from these bounds. */\nexport const anchorOf = (geometry: Shape): Point => {\n const rect = geomBounds(geometry);\n return { x: rect.x, y: rect.y };\n};\n\nconst ORIGIN: Point = { x: 0, y: 0 };\n\n/** The projection's factors for a mode at a view; `null` when it is the\n * identity (nothing to do). `s`/`r` are the stored→view inverse factors:\n * the forward projection applies `1/s` and `-r`.\n *\n * `s` clamps to `max(zoom, 1)` — Adobe's rule: `noZoom` holds the body at\n * its 100% size while zooming in, but below 100% the body scales with the\n * page (a screen-constant body at 25% zoom would dwarf the page it\n * annotates, and its chrome would drift off-screen). */\nfunction factors(\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): { s: number; r: number } | null {\n if (!mode || !view) return null;\n const scale = mode.zoom ? Math.max(view.zoom || 1, 1) : 1;\n const rotation = mode.upright ? normalizeDeg(view.rotation) : 0;\n return scale !== 1 || rotation !== 0 ? { s: scale, r: rotation } : null;\n}\n\n/**\n * How large a screen-anchored body is drawn on the page relative to its own\n * size: `1 / max(zoom, 1)` for `noZoom` (it keeps its 100% size on screen as\n * people zoom in), 1 for everything else.\n */\nexport function anchoredScale(mode: AnchorMode | null, view: ViewEnv | undefined): number {\n const projection = factors(mode, view);\n return projection ? 1 / projection.s : 1;\n}\n\n/**\n * The effective page-space geometry of a screen-anchored body at `view`:\n * the stored geometry scaled by `1/max(zoom, 1)` about the anchor (`zoom`\n * exemption, Adobe-clamped) and counter-rotated by `-rotation` about it\n * (`upright`), so that after the page's own display transform the body reads\n * at its 100%-zoom size and its authored tilt, hanging from the fixed anchor.\n * Returns `geometry` unchanged when there is nothing to do — callers apply it\n * unconditionally.\n */\nexport function anchoredGeom(\n geometry: Shape,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): Shape {\n const projection = factors(mode, view);\n if (!projection || !projectable(geometry)) return geometry;\n const point = anchorOf(geometry);\n let out: Shape = geometry;\n if (projection.s !== 1) out = geomScaleAbout(out, point, 1 / projection.s, 1 / projection.s);\n if (projection.r !== 0) out = geomRotateAbout(out, point, normalizeDeg(-projection.r));\n return out;\n}\n\n/**\n * The exact inverse of {@link anchoredGeom} for a view-space geometry a\n * gesture produced: the stored geometry whose own projection is `target`.\n *\n * Solving `anchoredGeom(stored) = target` where the projection anchors at\n * `stored`'s (unknown) bounds top-left `a` gives a closed form: map `target`\n * through the pure linear part (scale `s` + rotate `r` about the origin),\n * then translate so the result's bounds top-left `b` lands where the\n * projection needs it — at `a = R(-r)·b / s`, the unique fixed point. This is\n * what makes a released gesture commit exactly what its preview showed.\n */\nexport function unanchoredGeom(\n target: Shape,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): Shape {\n const projection = factors(mode, view);\n if (!projection || !projectable(target)) return target;\n let lin: Shape = target;\n if (projection.s !== 1) lin = geomScaleAbout(lin, ORIGIN, projection.s, projection.s);\n if (projection.r !== 0) lin = geomRotateAbout(lin, ORIGIN, projection.r);\n const point = anchorOf(lin);\n const unrotatedAnchor = rotatePoint(point, ORIGIN, -projection.r);\n return geomTranslate(lin, {\n x: unrotatedAnchor.x / projection.s - point.x,\n y: unrotatedAnchor.y / projection.s - point.y,\n });\n}\n\n/** Stroke width in the projected (view) space: a `noZoom` body's line weight\n * scales with its geometry so it stays screen-constant — through the same\n * factors (incl. the ≤100% clamp) the geometry projects with. */\nexport const anchoredStrokeWidth = (\n width: number,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): number => {\n const projection = factors(mode, view);\n return projection ? width / projection.s : width;\n};\n\n/**\n * The similarity image of an axis-aligned box (a baked raster's AP `/Rect`)\n * under the anchor projection, as the blit vocabulary expects it: an\n * unrotated box (the projected centre + scaled size) plus the rotation to\n * re-apply about its centre. `anchor` is the owning geometry's anchor — the\n * raster rides its annotation's projection, it doesn't anchor itself. Null\n * when the projection is the identity.\n */\nexport function anchoredBox(\n box: { x: number; y: number; width: number; height: number },\n anchor: Point,\n mode: AnchorMode | null,\n view: ViewEnv | undefined,\n): { box: { x: number; y: number; width: number; height: number }; rot: number } | null {\n const projection = factors(mode, view);\n if (!projection) return null;\n const center = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const scaled = {\n x: anchor.x + (center.x - anchor.x) / projection.s,\n y: anchor.y + (center.y - anchor.y) / projection.s,\n };\n const pc = projection.r !== 0 ? rotatePoint(scaled, anchor, normalizeDeg(-projection.r)) : scaled;\n const width = box.width / projection.s;\n const height = box.height / projection.s;\n return {\n box: { x: pc.x - width / 2, y: pc.y - height / 2, width, height },\n rot: normalizeDeg(-projection.r),\n };\n}\n","/** The complete annotation frame shared by selection and transform gestures. */\nimport { anchoredGeom, anchoredStrokeWidth, anchorModeOf } from './anchor';\nimport { geomRotation, isRotatableGeom, selectionQuad, turnPivotOf } from './geometry';\nimport { measurementOf, type MeasurementAppearance } from './measurement';\nimport { measurementSelectionQuad } from './measurement-shape';\nimport { shapeOf, styleOf } from './record';\nimport type { ModelAnnotation, Shape, QuadRing, Point, Style, ViewEnv } from './types';\n\nexport interface SelectionFrame {\n corners: QuadRing;\n center: Point;\n angle: number;\n}\n\n/**\n * The frame of `record` as it is drawn, or with `live` fields laid over its\n * own (a gesture's geometry, a screen-anchored stroke).\n */\nexport function annotationSelectionFrame(\n record: ModelAnnotation,\n view?: ViewEnv,\n live?: { geometry?: Shape; style?: Style; measure?: MeasurementAppearance },\n): SelectionFrame {\n const style = live?.style ?? styleOf(record.annotation);\n const measure = live?.measure ?? measurementOf(record.annotation);\n const mode = anchorModeOf(record);\n const geometry = anchoredGeom(live?.geometry ?? shapeOf(record.annotation), mode, view);\n const strokeWidth = anchoredStrokeWidth(style.strokeWidth, mode, view);\n const corners = measure\n ? measurementSelectionQuad(geometry, measure, { ...style, strokeWidth })\n : selectionQuad(geometry, { ...style, strokeWidth: strokeWidth });\n\n // PDF /Rect is a page-aligned rendering envelope. Its conservative padding\n // must not change the editor's frame or rotation center after an engine echo.\n return {\n corners,\n center: {\n x: (corners[0].x + corners[1].x + corners[2].x + corners[3].x) / 4,\n y: (corners[0].y + corners[1].y + corners[2].y + corners[3].y) / 4,\n },\n angle: isRotatableGeom(geometry) ? geomRotation(geometry) : 0,\n };\n}\n\n/** Where a turn of `record` pivots (`turnPivotOf`), in its frame's space. */\nexport function annotationTurnPivot(record: ModelAnnotation, view?: ViewEnv): Point {\n return turnPivotOf(anchoredGeom(shapeOf(record.annotation), anchorModeOf(record), view));\n}\n","import type { PageRef } from '@embedpdf/engine-core/runtime';\nimport { annotationSelectionFrame, annotationTurnPivot } from './selection';\nimport {\n captionPainted,\n distanceCaptionHit,\n distanceHandles,\n distanceLayout,\n distancePainted,\n measurementOf,\n} from './measurement';\nimport { measurementLayout } from './measurement-shape';\nimport { geomHandles, geomPainted, placeRotateKnob, pointInQuad, rectHandlesFor } from './geometry';\nimport { cursorOnScreen, unionRect } from './rect';\nimport { groupCaps } from './group';\nimport { isSubstrateOnly } from './plane';\nimport { isTransformableByHand } from './editable';\nimport { annotInteractive, viewable } from './flags';\nimport { anchoredGeom, anchoredStrokeWidth, anchorModeOf, type ViewEnv } from './anchor';\nimport { paintedNear, type PaintedPiece } from './painted';\nimport {\n type ModelAnnotation,\n type ChromeGeometry,\n type Cursor,\n type Shape,\n type Id,\n type Model,\n type Rect,\n type Point,\n} from './types';\nimport { kindOf, shapeOf, styleOf } from './record';\nimport { isInTurnedBox } from './shapes/box';\n\nexport type Target =\n | { kind: 'handle'; id: Id; handle: string; cursor: Cursor }\n // The rotate knob of the current selection (single shape or multi-target\n // group). `pivot` is the rotation centre the gesture turns about.\n | { kind: 'rotate'; ids: Id[]; pivot: Point }\n // A resize handle of the multi-target group box (the union box of the\n // selection). `box` is that union box; `ids` the members it scales.\n | { kind: 'group-handle'; ids: Id[]; handle: string; cursor: Cursor; box: Rect }\n | { kind: 'annot'; id: Id }\n | { kind: 'empty' };\n\n/** Page annotation ids in paint order (back→front): text-layer markups first\n * (always beneath), then every other kind, each group preserving creation\n * z-order. The one z-order shared by rendering (`pageItems`) and hit-testing —\n * and the one visibility cull: what `/F` hides (hidden / un-engaged noView)\n * neither paints nor hits, so an invisible annotation can never eat a click.\n * Conversation-plane annotations (replies, review-status states) are culled\n * here too — dialogue lives in the comments UI, never on the page. */\nexport function paintOrder(model: Model, page: PageRef): Id[] {\n const pageObjectNumber = page.objectNumber;\n const markup: Id[] = [];\n const other: Id[] = [];\n for (const id of model.order) {\n const record = model.byId[id];\n if (!record || record.annotation.page.objectNumber !== pageObjectNumber) continue;\n if (!viewable(record.annotation, model.selected.includes(id))) continue;\n if (isSubstrateOnly(record)) continue;\n (kindOf(record.annotation).caps.paintsBeneath ? markup : other).push(id);\n }\n return [...markup, ...other];\n}\n\n/** Can this annotation be clicked to select? (`/F` interaction flags override\n * all caps — hidden/noView/readOnly are inert; locked stays selectable, it\n * just won't transform.) */\nexport const isSelectable = (model: Model, id: Id): boolean => {\n const record = model.byId[id];\n return !!record && annotInteractive(record) && kindOf(record.annotation).caps.selectable;\n};\n\n/** An anchored kind's quad geometry is bound to underlying text — never moved\n * or resized. This is what lets one caps set serve both redaction shapes:\n * area marks (rect geometry) keep their transforms, text marks (quads) are\n * as fixed as classic markup. Markup kinds themselves have `movable: false`\n * and never reach this gate. */\nconst textBound = (record: ModelAnnotation): boolean =>\n kindOf(record.annotation).caps.anchored && shapeOf(record.annotation).kind === 'quads';\n\n/** Can this annotation be dragged by its body to move? (`locked` and the\n * session's `editable` rule freeze it.) */\nexport const canMove = (model: Model, id: Id): boolean => {\n const record = model.byId[id];\n return (\n !!record &&\n isTransformableByHand(model, record) &&\n kindOf(record.annotation).caps.movable &&\n !textBound(record)\n );\n};\n\n/** Does this kind expose drag handles (box resize or per-vertex)? Only\n * `locked`, inert `/F` states and the `editable` rule suppress them at runtime — a\n * screen-anchored body keeps its handles: `noZoom`/`noRotate` exempt it from\n * the display transform, they don't freeze its size or vertices. */\nconst hasHandles = (model: Model, record: ModelAnnotation): boolean => {\n if (!isTransformableByHand(model, record) || textBound(record)) return false;\n const caps = kindOf(record.annotation).caps;\n return caps.resizable || caps.vertexEditable;\n};\n\n/** The geometry a pointer actually meets: the anchored (screen-constant)\n * projection for `noZoom`/`noRotate` annotations, the stored geom otherwise.\n * The same projection `pageItems` renders, so click matches paint. */\nconst hitGeomOf = (record: ModelAnnotation, view: ViewEnv | undefined): Shape =>\n anchoredGeom(shapeOf(record.annotation), anchorModeOf(record), view);\n\n/**\n * What an annotation paints where the pointer meets it (`painted.ts`): its\n * shape's pieces, projected as a screen-anchored body shows at `view`, and a\n * measurement's caption, dimension line and leaders. A click and the marquee\n * both read this.\n */\nexport function paintedOf(record: ModelAnnotation, view?: ViewEnv): readonly PaintedPiece[] {\n const style = styleOf(record.annotation);\n const measure = measurementOf(record.annotation);\n const geometry = hitGeomOf(record, view);\n const stroke = { ...style, strokeWidth: hitStrokeOf(record, view) };\n if (measure?.intent === 'line-dimension') {\n const distance = distanceLayout(geometry, measure, stroke.strokeWidth);\n if (distance) return distancePainted(distance, stroke.strokeWidth);\n }\n const caption = measure ? measurementLayout(geometry, measure, stroke)?.caption : null;\n const shape = geomPainted(geometry, stroke, isFilled(record));\n return caption ? [...captionPainted(caption), ...shape] : shape;\n}\n\n/**\n * Is `point` on a text box's own box, where its text is? Not on a callout's\n * line, and not in the empty rest of its frame. `margin` reaches the resize\n * handles on its border. The box is tested where the page shows it, as a\n * click tests it.\n */\nexport function isOnTextBox(\n record: ModelAnnotation,\n point: Point,\n margin: number,\n view?: ViewEnv,\n): boolean {\n const geometry = hitGeomOf(record, view);\n return geometry.kind === 'text-box' && isInTurnedBox(geometry, point, margin);\n}\n\n/** Stroke width in effective content units (a noZoom body's line weight scales\n * with its geometry). */\nconst hitStrokeOf = (record: ModelAnnotation, view: ViewEnv | undefined): number =>\n anchoredStrokeWidth(styleOf(record.annotation).strokeWidth, anchorModeOf(record), view);\n\n// `opaqueBody` kinds (stamp images, note icons) are visible across their whole box, so they\n// hit like a filled shape. Not keyed on `source: 'baked'` — every annotation\n// loaded from a PDF starts baked, and an unfilled square must still be grabbed\n// only on its outline.\nconst isFilled = (record: ModelAnnotation): boolean => {\n const geometry = shapeOf(record.annotation);\n const style = styleOf(record.annotation);\n return (\n style.interiorColor != null ||\n geometry.kind === 'quads' ||\n kindOf(record.annotation).caps.opaqueBody\n );\n};\nconst inRect = (rect: Rect, point: Point): boolean =>\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height;\n// Is the point inside the annotation's selection frame: the oriented quad the chrome\n// outlines, tilt included (a rotated box across its tilted body; a thin arrow's or a\n// callout's whole outline box, empty corners and all)?\nconst inFrame = (record: ModelAnnotation, point: Point, view: ViewEnv | undefined): boolean =>\n pointInQuad(point, annotationSelectionFrame(record, view).corners);\n\n/**\n * The union of the selection bounds of every selected, movable annotation on a\n * page — the same box `chrome` outlines for a multi-selection. Null unless 2+\n * such annotations are selected here. This is the grab region for the gaps\n * between grouped/multi-selected annotations, so dragging the whole selection\n * works from anywhere inside its visible outline (not only on a member).\n */\nfunction selectionUnionBounds(model: Model, page: PageRef, view: ViewEnv | undefined): Rect | null {\n const pageObjectNumber = page.objectNumber;\n const selection = model.selected.filter(\n (id) =>\n model.byId[id]?.annotation.page.objectNumber === pageObjectNumber &&\n isSelectable(model, id) &&\n canMove(model, id),\n );\n if (selection.length < 2) return null;\n const corners: Point[] = [];\n for (const id of selection) {\n const record = model.byId[id];\n corners.push(...annotationSelectionFrame(record, view).corners);\n }\n return unionRect(corners);\n}\n\n/** The axis-aligned union of the selection bounds of every selected annotation on\n * a page (no movable/lock filter) — the box group chrome + group rotate use. */\nexport function groupUnionBounds(model: Model, page: PageRef, view?: ViewEnv): Rect | null {\n const pageObjectNumber = page.objectNumber;\n const corners: Point[] = [];\n for (const id of model.selected) {\n const record = model.byId[id];\n if (!record || record.annotation.page.objectNumber !== pageObjectNumber) continue;\n corners.push(...annotationSelectionFrame(record, view).corners);\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/**\n * What's under the page point.\n * 1. a resize/vertex handle of the single selection,\n * 2. an editable annotation body — a selected one anywhere in its bounds (so you\n * can drag to move it), an unselected one only on its stroke/fill (margin-aware,\n * so an unfilled circle is grabbed only on its outline),\n * 3. else empty.\n */\nexport function hitTest(\n model: Model,\n page: PageRef,\n point: Point,\n chromeGeometry: ChromeGeometry,\n strokeMargin: number,\n pageBox?: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Target {\n const pageObjectNumber = page.objectNumber;\n if (model.selected.length === 1 && isSelectable(model, model.selected[0])) {\n const record = model.byId[model.selected[0]];\n if (record.annotation.page.objectNumber === pageObjectNumber) {\n // The rotate knob (checked first — it floats outside the box, clear of\n // the handles), placed on the projected selection frame so it sits exactly\n // where the chrome drew it — a screen-anchored body rotates too (the\n // gesture edits its authored tilt; `noRotate` only exempts it from the\n // page's rotation). Locked, or frozen by the `editable` rule, suppresses\n // it. `placeRotateKnob` keeps it inside `pageBox`.\n if (kindOf(record.annotation).caps.rotatable && isTransformableByHand(model, record)) {\n const frame = annotationSelectionFrame(record, view);\n const knob = placeRotateKnob(frame.corners, chromeGeometry.knobOffset, pageBox);\n if (\n chromeGeometry.rotationHandle !== false &&\n Math.abs(knob.at.x - point.x) <= chromeGeometry.knobTol &&\n Math.abs(knob.at.y - point.y) <= chromeGeometry.knobTol\n ) {\n return {\n kind: 'rotate',\n ids: [record.id],\n pivot: annotationTurnPivot(record, view),\n };\n }\n }\n if (hasHandles(model, record)) {\n const style = styleOf(record.annotation);\n const measure = measurementOf(record.annotation);\n const geometry = hitGeomOf(record, view);\n const distance =\n measure?.intent === 'line-dimension' &&\n distanceLayout(geometry, measure, hitStrokeOf(record, view));\n const handles = distance ? distanceHandles(distance) : geomHandles(geometry);\n if (distance) {\n // Nearby endpoint and leader hit areas overlap at small offsets.\n // The closest visible handle wins, regardless of declaration order.\n const distanceToPointer = (handle: (typeof handles)[number]) =>\n Math.hypot(handle.at.x - point.x, handle.at.y - point.y);\n handles.sort((left, right) => distanceToPointer(left) - distanceToPointer(right));\n }\n\n // The text is the drag target. It owns no visible handle, and wins\n // before the annotation's sticky body bounds.\n const layout =\n measure &&\n measurementLayout(geometry, measure, {\n ...style,\n strokeWidth: hitStrokeOf(record, view),\n });\n if (\n layout &&\n distanceCaptionHit(layout, point, Math.min(2, chromeGeometry.handleTol / 3))\n ) {\n return { kind: 'handle', id: record.id, handle: 'caption', cursor: 'move' };\n }\n // Handles live on the projected geometry — the handle gesture then\n // runs entirely in view space (see the `handle` draft).\n for (const handle of handles) {\n if (\n Math.abs(handle.at.x - point.x) <= chromeGeometry.handleTol &&\n Math.abs(handle.at.y - point.y) <= chromeGeometry.handleTol\n ) {\n return {\n kind: 'handle',\n id: record.id,\n handle: handle.id,\n cursor: cursorOnScreen(handle.cursor, view?.rotation ?? 0),\n };\n }\n }\n }\n }\n } else if (model.selected.length > 1) {\n // Multi-target group: a rotate knob hanging off the union box, gated by the\n // group caps (every member rotatable + none locked). Screen-anchored\n // members rotate WYSIWYG like everyone else (their authored tilt turns).\n const gc = groupCaps(model, model.selected);\n if (gc.rotatable) {\n const union = groupUnionBounds(model, page, view);\n if (union) {\n const corners: [Point, Point, Point, Point] = [\n { x: union.x, y: union.y },\n { x: union.x + union.width, y: union.y },\n { x: union.x + union.width, y: union.y + union.height },\n { x: union.x, y: union.y + union.height },\n ];\n const knob = placeRotateKnob(corners, chromeGeometry.knobOffset, pageBox);\n if (\n chromeGeometry.rotationHandle !== false &&\n Math.abs(knob.at.x - point.x) <= chromeGeometry.knobTol &&\n Math.abs(knob.at.y - point.y) <= chromeGeometry.knobTol\n ) {\n const pivot = { x: union.x + union.width / 2, y: union.y + union.height / 2 };\n return {\n kind: 'rotate',\n ids: model.selected.filter(\n (id) => model.byId[id]?.annotation.page.objectNumber === pageObjectNumber,\n ),\n pivot,\n };\n }\n }\n }\n if (gc.resizable) {\n const union = groupUnionBounds(model, page, view);\n if (union) {\n for (const handle of rectHandlesFor(union)) {\n if (\n Math.abs(handle.at.x - point.x) <= chromeGeometry.handleTol &&\n Math.abs(handle.at.y - point.y) <= chromeGeometry.handleTol\n ) {\n return {\n kind: 'group-handle',\n ids: model.selected.filter(\n (id) => model.byId[id]?.annotation.page.objectNumber === pageObjectNumber,\n ),\n handle: handle.id,\n cursor: cursorOnScreen(handle.cursor, view?.rotation ?? 0),\n box: union,\n };\n }\n }\n }\n }\n }\n const order = paintOrder(model, page);\n for (let i = order.length - 1; i >= 0; i--) {\n const id = order[i];\n const record = model.byId[id];\n // `inert` ids (engaged Behaviors — form widgets under a fill tool) are\n // invisible here: their own DOM owns the pointer.\n if (!record || inert?.has(id) || !isSelectable(model, id)) continue;\n // A selected annotation that can move is grabbed anywhere in its frame as\n // well as on what it paints, so selecting never shrinks where it is grabbed;\n // any other is grabbed only on its stroke or fill (so a selectable but\n // text-bound kind still re-selects cleanly).\n if (model.selected.includes(id) && canMove(model, id) && inFrame(record, point, view)) {\n return { kind: 'annot', id };\n }\n if (paintedNear(paintedOf(record, view), point, strokeMargin)) {\n return { kind: 'annot', id };\n }\n }\n // Nothing under the point directly — but a multi-selection is grabbable across\n // its whole union box (the gaps between members included), so a drag there moves\n // the group as a unit instead of clearing it. Resolve to the top-most selected\n // member so `editDown` keeps the selection and arms the move.\n const union = selectionUnionBounds(model, page, view);\n if (union && inRect(union, point)) {\n for (let i = order.length - 1; i >= 0; i--) {\n if (model.selected.includes(order[i]) && canMove(model, order[i]))\n return { kind: 'annot', id: order[i] };\n }\n }\n return { kind: 'empty' };\n}\n\n/** The cursor to show on hover: a resize cursor over a handle, move/pointer over a body. */\nexport function cursorAt(\n model: Model,\n page: PageRef,\n point: Point,\n geometry: ChromeGeometry,\n strokeMargin: number,\n pageBox?: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Cursor | null {\n const target = hitTest(model, page, point, geometry, strokeMargin, pageBox, inert, view);\n if (target.kind === 'handle') return target.cursor;\n if (target.kind === 'group-handle') return target.cursor;\n if (target.kind === 'rotate') return 'grab';\n if (target.kind === 'annot')\n return model.selected.includes(target.id) && canMove(model, target.id) ? 'move' : 'pointer';\n return null;\n}\n","/**\n * How an annotation is drawn: from the engine's raster of its appearance\n * (`baked`), or live from its fields (`vector`). Everything that chooses\n * between the two is in this file.\n *\n * After a change, whether a gesture, a sidebar edit or code made it:\n *\n * | The change | How the record is drawn next |\n * | :---------------------------------------------------------- | :------------------------------------------------------------- |\n * | Nothing visible (a lock, the author, a square's comment) | Unchanged |\n * | A pure move | Unchanged; a baked raster moves the same distance |\n * | Anything else visible (restyle, resize, turn, text, points) | Live |\n * | A stamp, link or form widget, no live drawing (not lent) | Always the raster, drawn where its shape is |\n *\n * The change is the engine's own verdict (`appearanceChangeOf`): where the\n * engine keeps the appearance it has, so does the view, so an imported\n * appearance moved by a drag looks exactly as it did.\n *\n * During a gesture the same rule holds for the change in progress: a move\n * carries the raster along; a resize, turn, group transform, caption or\n * leader drag draws live, and so does a text box being typed into.\n *\n * A new record draws live: it has no raster until the engine bakes one. A\n * new stamp shows its image.\n *\n * A record with no appearance in the file (`hasAppearance` false) draws\n * live: every viewer draws that one from its fields, so the engine's raster\n * would be its drawing too, made in memory. A note or file attachment draws\n * its icon.\n *\n * A lent form widget has a live drawing: its lender's (`painter`). It follows\n * the rule like a square, while its raster stays drawn where its shape is.\n * Its lender says when its look is new; the plugin draws it live then.\n *\n * The plugin holds the rest (its `vector` preference): a record this session\n * drew live stays live for the session, and another session's edit hands it\n * back to the engine's raster (`plugin-annotation`, `sync/confirmed.ts`).\n */\nimport { containedRect } from '@embedpdf/core-geometry';\nimport {\n appearanceChangeOf,\n resolveAnnotationPatch,\n type Annotation,\n type AnnotationPatch,\n} from '@embedpdf/engine-core/runtime';\n\nimport { anchoredBox, anchorModeOf, anchorOf } from './anchor';\nimport { geomRotation } from './geometry';\nimport { normalizeDeg } from './rect';\nimport { annotationAfter, kindOf, shapeOf } from './record';\nimport type { Id, Model, ModelAnnotation, Shape, Rect, ViewEnv } from './types';\n\n/** The part of a record that says how it is drawn. */\nexport type DrawState = Pick<ModelAnnotation, 'source' | 'apBox'>;\n\n/**\n * Has the record a live drawing? Its kind's own, or its lender's (a lent form\n * widget, drawn by the form's painter). Stamps, links and form widgets have\n * none of their own: their raster is their drawing.\n */\nexport const drawsLive = (record: Pick<ModelAnnotation, 'annotation' | 'painter'>): boolean =>\n record.painter !== undefined || !kindOf(record.annotation).caps.rasterOnly;\n\n/** How a record this session creates is drawn at first. */\nexport const sourceOfNew = (annotation: Annotation): ModelAnnotation['source'] =>\n drawsLive({ annotation }) ? 'vector' : 'baked';\n\n/**\n * How a record the engine reports is drawn: live when this session drew it\n * live (`vector`, the plugin's preference) or when the file holds no\n * appearance for it; otherwise from the engine's raster.\n */\nexport const sourceOfConfirmed = (\n annotation: Annotation,\n vector: boolean,\n): ModelAnnotation['source'] =>\n drawsLive({ annotation }) && (vector || !annotation.hasAppearance) ? 'vector' : 'baked';\n\n/**\n * What changes in how `record` is drawn once `patch` is written: the rule at\n * the top of this file. Only the fields that change. The engine judges the\n * patch as it will write it: a `rect` command is the shape it moves to by\n * then.\n */\nexport function drawnAfter(record: ModelAnnotation, patch: AnnotationPatch): Partial<DrawState> {\n if (!drawsLive(record)) return {};\n const change = appearanceChangeOf(\n record.annotation,\n resolveAnnotationPatch(record.annotation, patch),\n );\n switch (change.impact) {\n case 'inert':\n return {};\n case 'translation': {\n const box = record.apBox;\n return box ? { apBox: { ...box, x: box.x + change.by.x, y: box.y + change.by.y } } : {};\n }\n case 'regenerate':\n return record.source === 'vector' ? {} : { source: 'vector' };\n }\n}\n\n/** `record` after `patch`: its annotation as the engine will read it back (`annotationAfter`), drawn as the rule says. */\nexport function applyChange(record: ModelAnnotation, patch: AnnotationPatch): ModelAnnotation {\n return {\n ...record,\n annotation: annotationAfter(record.annotation, patch),\n ...drawnAfter(record, patch),\n };\n}\n\n/**\n * How a record is drawn right now, its gesture in progress included: the\n * baked raster can't stretch, tilt or hide its text, so those gestures draw\n * live before their commit decides. A no-op grab leaves the record as it was.\n */\nexport function sourceDuring(model: Model, id: Id): ModelAnnotation['source'] {\n const record = model.byId[id];\n // No live drawing: the raster follows the gesture (`rasterPlacement`), and\n // the engine's refitted appearance replaces it after the commit.\n if (!drawsLive(record)) return record.source;\n // A text box being typed into: the raster can't hide just its text, so a\n // blend would show it twice.\n if (model.editing === id && shapeOf(record.annotation).kind === 'text-box') return 'vector';\n const draft = model.draft;\n if (\n (draft?.kind === 'handle' || draft?.kind === 'caption' || draft?.kind === 'leader') &&\n draft.id === id\n )\n return 'vector';\n if ((draft?.kind === 'rotate' || draft?.kind === 'group') && draft.ids.includes(id))\n return 'vector';\n return record.source;\n}\n\n/**\n * Where the raster of a kind without a live drawing goes in `box`, its shape\n * now: filling it, or, for a stamp that fits its drawing `contain`, at the\n * raster's own proportions, centred, as the engine fits the drawing into a\n * resized box. A resize never stretches it.\n */\nfunction rasterInShape(record: ModelAnnotation, box: Rect): Rect {\n const { annotation, apBox } = record;\n return annotation.subtype === 'stamp' && annotation.fit === 'contain' && apBox\n ? containedRect(apBox, box)\n : box;\n}\n\n/**\n * Where a record's raster is drawn right now, in view space: its box and the\n * turn to put back about its middle.\n *\n * - A stamp, link or form widget: where its shape is (`shapeNow`, the gesture\n * in progress included), turned with it, lent or not: its raster is the\n * drawing of its shape. A stamp's keeps its proportions in a resized box\n * (`rasterInShape`).\n * - Every other kind: at the raster's box (`apBox`), carried along by a move\n * in progress. A screen-anchored annotation's box rides the same\n * similarity its shape projects through (`anchoredBox`), composed with any\n * turn the engine took out of the raster (`apRot`).\n */\nexport function rasterPlacement(\n model: Model,\n id: Id,\n view: ViewEnv | undefined,\n shapeNow: Shape,\n): { box?: Rect; rot?: number } {\n const record = model.byId[id];\n if (kindOf(record.annotation).caps.rasterOnly) {\n return {\n box: shapeNow.kind === 'box' ? rasterInShape(record, shapeNow.box) : record.apBox,\n rot: geomRotation(shapeNow) || undefined,\n };\n }\n if (!record.apBox) return { rot: record.apRot };\n const projected = anchoredBox(\n record.apBox,\n anchorOf(shapeOf(record.annotation)),\n anchorModeOf(record),\n view,\n );\n let box = projected?.box ?? record.apBox;\n const rot = normalizeDeg((record.apRot ?? 0) + (projected?.rot ?? 0)) || undefined;\n const draft = model.draft;\n if (draft?.kind === 'move' && draft.ids.includes(id)) {\n box = { ...box, x: box.x + draft.delta.x, y: box.y + draft.delta.y };\n }\n return { box, rot };\n}\n","import type { InkStraightenOptions, Point } from './types';\n\n/**\n * Recognise a sufficiently straight freehand stroke and axis-snap it when it is\n * close to horizontal or vertical. Diagonal strokes remain untouched: this is\n * a highlighter aid, not a general line simplifier.\n */\nexport function straightenInkStroke(\n points: readonly Point[],\n options: InkStraightenOptions,\n): Point[] {\n if (points.length < 3) return [...points];\n const first = points[0];\n const last = points[points.length - 1];\n const dx = last.x - first.x;\n const dy = last.y - first.y;\n const length = Math.hypot(dx, dy);\n if (length < 3) return [...points];\n\n const maxDeviation = points.reduce((max, point) => {\n const distance = Math.abs(dx * (first.y - point.y) - (first.x - point.x) * dy) / length;\n return Math.max(max, distance);\n }, 0);\n if (maxDeviation / length >= options.deviationThreshold) return [...points];\n\n const angle = Math.atan2(Math.abs(dy), Math.abs(dx)) * (180 / Math.PI);\n if (angle <= options.axisSnapDegrees) {\n const y = points.reduce((sum, point) => sum + point.y, 0) / points.length;\n return [\n { x: first.x, y },\n { x: last.x, y },\n ];\n }\n if (angle >= 90 - options.axisSnapDegrees) {\n const x = points.reduce((sum, point) => sum + point.x, 0) / points.length;\n return [\n { x, y: first.y },\n { x, y: last.y },\n ];\n }\n return [...points];\n}\n","/**\n * Page-bound gestures. Annotations are page-bound; the pointer isn't. Two\n * rules keep them apart:\n * 1. Frame: a gesture is anchored to the page it started on. A sample resolved\n * against another page is in a different coordinate frame (each page's\n * page space has its own origin) — subtracting across frames would\n * teleport the shape to the page top, so foreign-page samples are ignored.\n * 2. Clamp: within the home frame, geometry pins to the page box:\n * an overshooting pointer slides the shape along the edge; a shape larger\n * than the page pins to the page's top/left (lo wins when lo > hi).\n * 3. Frame: a gesture that reshapes an annotation (a handle, a measurement's\n * leader or caption) stops where its frame would reach further past the\n * page's edge than it did when the gesture began ({@link fractionOnPage}).\n */\nimport type { PageRef } from '@embedpdf/engine-core/runtime';\n\nimport { type ViewEnv } from '../anchor';\nimport { unionRect } from '../rect';\nimport { annotationSelectionFrame } from '../selection';\nimport type { Draft, Id, Model, Point, PointerInput, Rect } from '../types';\n\nconst clampAxis = (value: number, lo: number, hi: number): number =>\n Math.max(lo, Math.min(hi, value));\n\nexport const clampPointToBox = (point: Point, box: Rect | undefined): Point =>\n box\n ? {\n x: clampAxis(point.x, box.x, box.x + box.width),\n y: clampAxis(point.y, box.y, box.y + box.height),\n }\n : point;\n\n/** The pointer sample's view environment (relative zoom + display rotation),\n * when the caller supplied one — screen-anchored annotations hit-test and\n * page-clamp at their effective geometry with it. Absent → stored geometry\n * (headless). */\nexport const viewOf = (input: PointerInput): ViewEnv | undefined =>\n input.zoom != null || input.displayRotation != null\n ? { zoom: input.zoom ?? 1, rotation: input.displayRotation ?? 0 }\n : undefined;\n\n/** How far any of `corners` reaches past the page's edge: 0 when all are on it. */\nfunction overhangOf(corners: readonly Point[], page: Rect): number {\n let overhang = 0;\n for (const point of corners)\n overhang = Math.max(\n overhang,\n page.x - point.x,\n point.x - (page.x + page.width),\n page.y - point.y,\n point.y - (page.y + page.height),\n );\n return overhang;\n}\n\n/**\n * How much of a gesture the page allows: 1 when all of it, otherwise the\n * fraction of the way at which the annotation's frame (`cornersAt(fraction)`)\n * would first reach further past the page's edge than it did at the start.\n * An annotation on its page stays on it; one already past the edge is never\n * pushed further out. A frame's overhang grows steadily along a straight\n * gesture, so halving the way finds where it starts to.\n */\nexport function fractionOnPage(\n page: Rect | undefined,\n cornersAt: (fraction: number) => readonly Point[],\n): number {\n if (!page) return 1;\n const allowed = overhangOf(cornersAt(0), page) + 1e-9;\n const fits = (fraction: number) => overhangOf(cornersAt(fraction), page) <= allowed;\n if (fits(1)) return 1;\n let inside = 0;\n let outside = 1;\n for (let i = 0; i < 30; i++) {\n const middle = (inside + outside) / 2;\n if (fits(middle)) inside = middle;\n else outside = middle;\n }\n return inside;\n}\n\n/**\n * How much of a two-way gesture `wanted` the page allows\n * ({@link fractionOnPage}), across then up and down, so that a pointer past\n * the edge slides the annotation along it instead of stopping it.\n */\nexport function deltaOnPage(\n page: Rect | undefined,\n wanted: Point,\n cornersFor: (delta: Point) => readonly Point[],\n): Point {\n const x =\n wanted.x * fractionOnPage(page, (fraction) => cornersFor({ x: wanted.x * fraction, y: 0 }));\n const y =\n wanted.y * fractionOnPage(page, (fraction) => cornersFor({ x, y: wanted.y * fraction }));\n return { x, y };\n}\n\n/** The union of the ids' selection frames: what a move keeps inside the page.\n * A frame takes in everything an annotation paints (a callout's arrow too),\n * and a screen-anchored member counts at its view-projected footprint. */\nexport function unionBoundsOf(model: Model, ids: Id[], view?: ViewEnv): Rect | null {\n const corners: Point[] = [];\n for (const id of ids) {\n const record = model.byId[id];\n if (!record) continue;\n corners.push(...annotationSelectionFrame(record, view).corners);\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/** Clamp a move delta so the move-clamp bounds stay inside the page.\n * Per-axis, so a pointer past the bottom edge still slides the selection\n * horizontally along that edge. */\nexport function clampMoveDelta(\n model: Model,\n ids: Id[],\n delta: Point,\n page: Rect | undefined,\n view?: ViewEnv,\n): Point {\n if (!page) return delta;\n const rect = unionBoundsOf(model, ids, view);\n if (!rect) return delta;\n return {\n x: clampAxis(delta.x, page.x - rect.x, page.x + page.width - (rect.x + rect.width)),\n y: clampAxis(delta.y, page.y - rect.y, page.y + page.height - (rect.y + rect.height)),\n };\n}\n\n/** The page an edit draft is anchored to — every edit gesture lives on one page. */\nexport function editDraftPage(model: Model, draft: Draft): PageRef | null {\n const id = 'id' in draft ? draft.id : 'ids' in draft && draft.ids.length ? draft.ids[0] : null;\n return id != null ? (model.byId[id]?.annotation.page ?? null) : null;\n}\n","/**\n * Where a create gesture puts what it makes — the pure, plane-agnostic layer.\n *\n * A create tool answers one question: if the gesture ended now, what would\n * exist? `gesturePlacement` answers the \"where\": past the drag threshold, the\n * dragged box or segment; under it, the tool's click default\n * (`resolveClickPlacement`). `placedShape` answers the \"what\": the kind's\n * shape family lays its shape there. The commit, the drawing in progress and\n * the tool's ghost all make these two calls, so a ghost shows what a click\n * makes by construction. A form field takes the placed box as its bounds.\n */\nimport type { PageRotation } from '@embedpdf/core-geometry';\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { uprightAnchoredRect, uprightRotation } from './geometry';\nimport { kindOf } from './record';\nimport { rectFromPoints, rotatePoint, transposedAboutCenter } from './rect';\nimport type { ClickCreate, Placement, Point, Rect, Shape } from './types';\nimport { clampPointToBox } from './update/page-bound';\n\n/** The click ↔ drag threshold (content units): a press-release that stays\n * under it is a click. Every gesture owner (the draw handler, the form\n * plugin's place handler) shares this one definition. */\nexport const MIN_DRAG = 3;\n\n/** What a create gesture lays: a box (shapes, text boxes, form fields) or a segment (lines). */\nexport type GestureForm = 'box' | 'segment';\n\n/** The page a placement is made on, and how the person sees it. */\nexport interface PlacementFrame {\n /** The page's content box: a placement slides inside it. */\n pageBox?: Rect;\n /** Lay it out as the person sees the page: the tool's `upright`. */\n upright?: boolean;\n /** How far the page shows turned (document /Rotate + view rotation, degrees clockwise). */\n displayRotation?: PageRotation;\n}\n\n/** Slide a rect (as a unit) to sit inside `box`; pins at the origin edge when\n * it doesn't fit. Placements are page-bound; the pointer isn't. */\nexport const clampRectToBox = (rect: Rect, box: Rect | undefined): Rect => {\n if (!box) return rect;\n return {\n ...rect,\n x: Math.min(Math.max(rect.x, box.x), Math.max(box.x, box.x + box.width - rect.width)),\n y: Math.min(Math.max(rect.y, box.y), Math.max(box.y, box.y + box.height - rect.height)),\n };\n};\n\n/** Whether a gesture from `from` to `to` is a drag: a segment once it is\n * `MIN_DRAG` long, a box once either side is. */\nexport function isDrag(form: GestureForm, from: Point, to: Point): boolean {\n if (form === 'segment') return Math.hypot(to.x - from.x, to.y - from.y) >= MIN_DRAG;\n return Math.abs(to.x - from.x) >= MIN_DRAG || Math.abs(to.y - from.y) >= MIN_DRAG;\n}\n\n/** The turn an upright tool gives a box on a page shown turned: that turn undone. */\nconst uprightTurn = ({ upright, displayRotation }: PlacementFrame): number =>\n upright && displayRotation ? uprightRotation(displayRotation) : 0;\n\n/**\n * Where a create gesture from `from` to `to` puts what it makes: the dragged\n * box or segment once it is a drag, else the tool's click default at `from`\n * (`null` when a click makes nothing). A drag stays on the page: its points\n * pin to the edge. An upright drag keeps the region the author dragged: under\n * a quarter turn the box before its turn is the dragged one with its sides\n * swapped about its middle, so the turn lands it back on that region.\n */\nexport function gesturePlacement(\n form: GestureForm,\n from: Point,\n to: Point,\n clickCreate: ClickCreate | false | undefined,\n frame: PlacementFrame = {},\n): Placement | null {\n if (!isDrag(form, from, to)) {\n return clickCreate ? resolveClickPlacement(from, clickCreate, frame) : null;\n }\n const a = frame.pageBox ? clampPointToBox(from, frame.pageBox) : from;\n const b = frame.pageBox ? clampPointToBox(to, frame.pageBox) : to;\n if (form === 'segment') return { kind: 'segment', a, b };\n const rot = uprightTurn(frame);\n const dragged = rectFromPoints(a, b);\n return { kind: 'box', rect: rot % 180 ? transposedAboutCenter(dragged) : dragged, rot };\n}\n\n/**\n * Where a bare click at `point` puts what the tool makes (see\n * {@link ClickCreate}), slid inside the page. Under `upright` it is laid out\n * as the person sees the page: a line's direction and a box's top-left corner\n * are the screen's, and a box turns to read upright, showing `width` ×\n * `height` as configured.\n */\nexport function resolveClickPlacement(\n point: Point,\n policy: ClickCreate,\n frame: PlacementFrame = {},\n): Placement {\n // How far the person sees the page turned, for an upright tool.\n const seen = frame.upright ? (frame.displayRotation ?? 0) : 0;\n if ('length' in policy) {\n const turn = ((policy.rotation ?? 0) * Math.PI) / 180;\n // The line as the person sees it, turned back into page space.\n const span = rotatePoint(\n { x: Math.cos(turn) * policy.length, y: Math.sin(turn) * policy.length },\n { x: 0, y: 0 },\n -seen,\n );\n // How much of the line lies before the click: none from its start, all to its end.\n const before = policy.anchor === 'start' ? 0 : policy.anchor === 'end' ? 1 : 0.5;\n const a = { x: point.x - span.x * before, y: point.y - span.y * before };\n const b = { x: a.x + span.x, y: a.y + span.y };\n const bounds = rectFromPoints(a, b);\n const placed = clampRectToBox(bounds, frame.pageBox);\n const dx = placed.x - bounds.x;\n const dy = placed.y - bounds.y;\n return { kind: 'segment', a: { x: a.x + dx, y: a.y + dy }, b: { x: b.x + dx, y: b.y + dy } };\n }\n const { width, height } = policy;\n const rot = uprightTurn(frame);\n const rect =\n policy.anchor === 'top-left'\n ? uprightAnchoredRect(point, width, height, seen)\n : { x: point.x - width / 2, y: point.y - height / 2, width, height };\n // What the page shows is the box turned by `rot` (a quarter turn swaps its\n // sides): slide that inside the page, and the box with it.\n const shown = rot % 180 ? transposedAboutCenter(rect) : rect;\n const placed = clampRectToBox(shown, frame.pageBox);\n return {\n kind: 'box',\n rect: { ...rect, x: rect.x + placed.x - shown.x, y: rect.y + placed.y - shown.y },\n rot,\n };\n}\n\n/**\n * What a create from a tool makes at `placement`: its kind's shape there, as\n * the kind's shape family lays it (`ShapeFamily.placed`), or `null` when the\n * kind can't be made that way (a line from a box). `annotation` is what the\n * tool creates before it has a shape (`toolAnnotation`): its kind, and what\n * the shape takes from it (a line's endings, a circle's roundness).\n */\nexport function placedShape(annotation: Annotation, placement: Placement): Shape | null {\n return kindOf(annotation).family.placed(placement, annotation);\n}\n","/**\n * A tool's defaults, read as an annotation: the tool's engine fields laid\n * over the engine's own defaults for its kind. A form tool's defaults also\n * read as the engine's widget appearance.\n */\nimport {\n annotationDefaultsOf,\n type Annotation,\n type AnnotationSubtype,\n type WidgetAppearance,\n} from '@embedpdf/engine-core/runtime';\n\nimport { fieldFamilyOfKind } from '../kinds';\nimport type { FieldValues } from '../types';\n\n/** The engine subtype a client kind creates: a callout is a free text, a form tool's kind a widget. */\nexport const engineSubtypeOf = (kind: string): AnnotationSubtype =>\n kind === 'free-text-callout'\n ? 'free-text'\n : kind.startsWith('widget')\n ? 'widget'\n : (kind as AnnotationSubtype);\n\n/**\n * A tool's `defaults` over the engine's defaults for `kind`: what a create\n * from the tool starts from. A form tool's reads as a widget of its field\n * family, so it reads as the tool's own kind (a radio tool's is round).\n */\nexport function readOfDefaults(kind: string, defaults: FieldValues): Annotation {\n const subtype = engineSubtypeOf(kind);\n const fieldFamily = subtype === 'widget' ? fieldFamilyOfKind(kind) : undefined;\n return {\n subtype,\n ...annotationDefaultsOf(subtype),\n ...(fieldFamily ? { fieldFamily } : {}),\n ...defaults,\n } as unknown as Annotation;\n}\n\nconst WIDGET_APPEARANCE_FIELDS = [\n 'color',\n 'interiorColor',\n 'strokeWidth',\n 'borderStyle',\n 'fontFamily',\n 'fontSize',\n 'fontColor',\n 'textAlign',\n] as const;\n\n/**\n * A form tool's defaults as the engine's widget appearance for `doc.forms`\n * authoring: the widget's style fields among them, as they are. Absent fields\n * stay absent (the engine writes nothing for them).\n */\nexport function widgetAppearanceOf(defaults: FieldValues): WidgetAppearance {\n return Object.fromEntries(\n WIDGET_APPEARANCE_FIELDS.filter((name) => defaults[name] !== undefined).map((name) => [\n name,\n defaults[name],\n ]),\n ) as WidgetAppearance;\n}\n","/**\n * The session: its initial value, the tool defaults new annotations take, and\n * dropping its references to records that leave the view (`forget`).\n */\nimport type { Annotation } from '@embedpdf/engine-core/runtime';\n\nimport { readOfDefaults } from '../record/defaults';\nimport { lineEndingsOf } from '../shapes/points';\nimport type { Draft, Effect, FieldValues, Id, Model, Session } from '../types';\n\nexport const initialSession: Session = {\n selected: [],\n hovered: null,\n draft: null,\n preview: null,\n objectNumbers: [],\n defaults: {},\n hitMargin: 6,\n editing: null,\n snap: {\n alignment: true,\n alignmentThreshold: 6,\n rotation: true,\n rotationAngles: [0, 90, 180, 270],\n rotationThreshold: 4,\n },\n editable: true,\n};\n\nconst NO_DEFAULTS: FieldValues = {};\n\n/** A tool's defaults, by its preset: the engine fields its creates state. */\nexport const defaultsFor = (model: Model, preset: string): FieldValues =>\n model.defaults[preset] ?? NO_DEFAULTS;\n\n/**\n * What a create from a tool starts from, before it has a shape: the tool's\n * defaults (by its preset) over the engine's for its `kind`, read as an\n * annotation. A ghost is drawn with its style (`styleOf`).\n */\nexport const toolAnnotation = (model: Model, kind: string, preset: string = kind): Annotation =>\n readOfDefaults(kind, defaultsFor(model, preset));\n\n// A tool's line endings are read off what it creates, as a line's are (shapes/points.ts).\nexport { lineEndingsOf };\n\n/** Merge fields into a tool's defaults; each value is whole, as in a patch. */\nexport function setDefaults(model: Model, preset: string, patch: FieldValues): [Model, Effect[]] {\n const next = { ...defaultsFor(model, preset), ...patch };\n return [{ ...model, defaults: { ...model.defaults, [preset]: next } }, []];\n}\n\n/** Ids a gesture in progress works on. */\nfunction draftIds(draft: Draft | null): Set<Id> {\n if (!draft) return new Set();\n if (draft.kind === 'move') return new Set(draft.ids);\n if (draft.kind === 'handle' || draft.kind === 'caption' || draft.kind === 'leader') {\n return new Set([draft.id]);\n }\n if (draft.kind === 'rotate' || draft.kind === 'group') return new Set(draft.ids);\n return new Set();\n}\n\n/** Drop every session reference to records that left the view; a gesture on one of them ends. */\nexport function forget(model: Model, ids: readonly Id[]): Model {\n const gone = new Set(ids);\n const selected = model.selected.filter((id) => !gone.has(id));\n const hovered = model.hovered !== null && gone.has(model.hovered) ? null : model.hovered;\n const editing = model.editing !== null && gone.has(model.editing) ? null : model.editing;\n const draftGone = [...draftIds(model.draft)].some((id) => gone.has(id));\n if (\n selected.length === model.selected.length &&\n hovered === model.hovered &&\n editing === model.editing &&\n !draftGone\n ) {\n return model;\n }\n return { ...model, selected, hovered, editing, draft: draftGone ? null : model.draft };\n}\n","/**\n * What every transition that changes records shares — the records it returns\n * become the message's change set: a new record and the draft it is written\n * from, a view-space gesture's commit, and removing records.\n */\nimport { annotationKey } from '@embedpdf/core';\nimport {\n ANNOTATION_FIELD_NAMES,\n type AnnotationDraft,\n type Annotation,\n type AnnotationFlags,\n type AnnotationRef,\n type PageRef,\n} from '@embedpdf/engine-core/runtime';\n\nimport { anchoredGeom, anchorModeOf, unanchoredGeom, type ViewEnv } from '../anchor';\nimport { sourceOfNew } from '../appearance';\nimport { DRAWN_FLAGS } from '../flags';\nimport { annotationOfNew, shapeOf } from '../record';\nimport { engineSubtypeOf } from '../record/defaults';\nimport { familyOf } from '../shapes';\nimport type { FieldValues, Shape, Id, Model, ModelAnnotation, Point, KindName } from '../types';\nimport { forget } from './session';\n\nexport const isPolySubtype = (subtype: KindName): subtype is 'polygon' | 'polyline' =>\n subtype === 'polygon' || subtype === 'polyline';\n\nexport const sub = (from: Point, to: Point): Point => ({ x: from.x - to.x, y: from.y - to.y });\n\n/**\n * Commit a view-space gesture result for one annotation: apply `op` to the\n * projected geometry (the identity for un-flagged annotations — `op` then\n * simply runs on the stored geom) and map the result back to stored space\n * through `unanchoredGeom`. The exact composition `effGeom` previewed, so a\n * released gesture commits what it showed — for screen-anchored and plain\n * annotations alike, through one code path.\n */\nexport const commitViewGesture = (\n record: ModelAnnotation,\n view: ViewEnv | undefined,\n op: (geometry: Shape) => Shape,\n): Shape => {\n const mode = anchorModeOf(record);\n return unanchoredGeom(op(anchoredGeom(shapeOf(record.annotation), mode, view)), mode, view);\n};\n\nexport const geomEqual = (left: Shape, right: Shape): boolean =>\n JSON.stringify(left) === JSON.stringify(right);\n\n/**\n * The ref of the `offset`-th record a message creates: the object number the\n * session holds in that place (`Session.objectNumbers`), on `page`. Throws\n * when the session holds too few: the plugin hands it what a message needs\n * before it runs (`newRecordsAtMost`).\n */\nconst newRecordRef = (\n model: Model,\n page: PageRef,\n offset: number,\n): Extract<AnnotationRef, { kind: 'objectNumber' }> => {\n const objectNumber = model.objectNumbers[offset - 1];\n if (objectNumber === undefined) {\n throw new Error('annotation-core: the session holds no object number for a new record');\n }\n return { kind: 'objectNumber', page, objectNumber };\n};\n\n/** The session's object numbers once a message created `count` records. */\nexport const numbersLeft = (model: Model, count: number): readonly number[] =>\n model.objectNumbers.slice(count);\n\n/**\n * The draft a drawing creates, complete before its record is made: the\n * tool's `defaults` (the fields its kind has), the fields that state its\n * `shape`, what the drawing adds (`fields`: an intent, a measurement, first\n * text), and the flags a drawn annotation starts with (`print`, and the\n * tool's own). The view's record and the engine's create both come from\n * it.\n */\nexport function draftOf(\n kind: string,\n defaults: FieldValues,\n shape: Shape,\n fields: FieldValues = {},\n flags: Partial<AnnotationFlags> = {},\n): AnnotationDraft {\n const subtype = engineSubtypeOf(kind);\n const declared = ANNOTATION_FIELD_NAMES[subtype];\n const own = Object.fromEntries(\n Object.entries(defaults).filter(([name]) => declared.includes(name)),\n );\n return {\n ...own,\n ...familyOf(shape).write(shape, subtype),\n ...fields,\n ...DRAWN_FLAGS,\n ...flags,\n subtype,\n } as unknown as AnnotationDraft;\n}\n\n/** A record a message creates, and the draft it is written from. */\nexport interface NewRecord {\n readonly record: ModelAnnotation;\n readonly draft: AnnotationDraft;\n}\n\n/**\n * The `offset`-th record a message creates, from its `draft`: keyed by the\n * object number it takes (`newRecordRef`), holding the annotation the engine\n * will read back (`annotationOfNew`), and drawn as a new record is\n * (`sourceOfNew`). `reply` ties it to\n * the annotation it belongs to, which can be one the same message creates.\n */\nexport function newRecord(\n model: Model,\n page: PageRef,\n draft: AnnotationDraft,\n options: { offset?: number; reply?: NonNullable<Annotation['reply']> } = {},\n): NewRecord {\n const offset = options.offset ?? 1;\n const ref = newRecordRef(model, page, offset);\n // The annotation it answers is the engine's to look up as it writes: read\n // without it, then stated.\n const read = annotationOfNew(draft, { ref });\n const annotation: Annotation = options.reply ? { ...read, reply: options.reply } : read;\n return {\n record: {\n id: annotationKey(ref),\n unconfirmed: true,\n source: sourceOfNew(annotation),\n annotation,\n },\n draft: options.reply ? ({ ...draft, reply: options.reply } as AnnotationDraft) : draft,\n };\n}\n\n/** The model without these records, and without any session reference to them. */\nexport function withoutRecords(model: Model, ids: readonly Id[]): Model {\n const gone = new Set(ids);\n const byId = { ...model.byId };\n for (const id of ids) delete byId[id];\n return forget({ ...model, byId, order: model.order.filter((id) => !gone.has(id)) }, ids);\n}\n","/** Drawing a free-text callout: the tip, the elbow, then the text box it points from. */\nimport type { AnnotationFlags } from '@embedpdf/engine-core/runtime';\n\nimport { uprightRotation } from '../geometry';\nimport { gesturePlacement } from '../placement';\nimport { calloutShape } from '../shapes/text-box';\nimport type { ClickCreate, Draft, Effect, Model, Placement, PointerInput, Rect } from '../types';\nimport { draftOf, newRecord, numbersLeft } from './changes';\nimport { defaultsFor, toolAnnotation } from './session';\n\n/** A callout's text box on a click (no box drag): hanging down-right of the press, as a free text's does. */\nconst CALLOUT_BOX: ClickCreate = { width: 150, height: 40, anchor: 'top-left' };\n\n/** The callout draft's upright counter-rotation (deg CW; 0 = none) — the same\n * rule the rect commit applies, shared by `calloutBox`, the ghost preview and\n * the commit so all three agree by construction. */\nexport function calloutUprightRot(draft: Extract<Draft, { kind: 'create-callout' }>): number {\n return draft.upright && draft.displayRotation ? uprightRotation(draft.displayRotation) : 0;\n}\n\n/**\n * The text-box rect for an in-progress callout's `box` step — the one rule both\n * the live preview and the commit use, so what you see is what you get: the\n * box step's gesture placed as any box tool's is (`gesturePlacement`). A drag\n * past `MIN_DRAG` sizes the box; a press-without-drag (a click) keeps the\n * default-size box at the press point, so it never collapses to a sliver\n * while you decide whether you're dragging (the \"bounce\"). Before the press\n * (hover), the default box tracks the cursor. Under `upright` it is the box\n * before its turn, laid out as the author sees the page.\n */\nexport function calloutBox(draft: Extract<Draft, { kind: 'create-callout' }>): Rect {\n const from = draft.boxFrom ?? draft.current;\n // A box gesture with a box policy always places a box.\n const placement = gesturePlacement('box', from, draft.boxTo ?? from, CALLOUT_BOX, {\n pageBox: draft.pageBox,\n upright: draft.upright,\n displayRotation: draft.displayRotation,\n }) as Extract<Placement, { kind: 'box' }>;\n return placement.rect;\n}\n\n/**\n * The free-text callout's multi-step creation, a 3-click flow:\n * click 1 (down) → set the leader `tip`, advance to the `knee` step\n * hover/move → preview the leader to the cursor\n * click 2 (down) → set the `knee`, advance to the `box` step\n * drag/click (up) → lay the text box (dragged, or a default box on a click)\n * Commit creates a `free-text` callout and opens it for editing; the line's\n * end is where it meets the box (`calloutShape`).\n */\nexport function calloutPointer(\n model: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n preset: string = 'free-text-callout',\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const draft = model.draft;\n if (phase === 'down') {\n if (draft?.kind !== 'create-callout' || draft.page.objectNumber !== input.page.objectNumber) {\n return [\n {\n ...model,\n selected: [],\n draft: {\n kind: 'create-callout',\n subtype: 'free-text-callout',\n preset,\n page: input.page,\n step: 'knee',\n tip: input.point,\n current: input.point,\n // Captured at the tip click (the gesture's home page) — the box\n // step may span later samples that don't carry the rotation. A\n // rotation of 0 makes upright a no-op, so the draft stays clean.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(input.pageBox ? { pageBox: input.pageBox } : {}),\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n if (draft.step === 'knee') {\n return [\n { ...model, draft: { ...draft, knee: input.point, step: 'box', current: input.point } },\n [],\n ];\n }\n // box step: begin the box drag at this point\n return [{ ...model, draft: { ...draft, boxFrom: input.point, boxTo: input.point } }, []];\n }\n if (phase === 'move') {\n if (draft?.kind !== 'create-callout') return [model, []];\n if (draft.step === 'box' && draft.boxFrom)\n return [{ ...model, draft: { ...draft, boxTo: input.point } }, []];\n return [{ ...model, draft: { ...draft, current: input.point } }, []];\n }\n // up: only the box step (with a started box) commits; the tip/knee clicks no-op.\n if (draft?.kind !== 'create-callout' || draft.step !== 'box' || !draft.boxFrom)\n return [model, []];\n const rect = calloutBox(draft); // the same box the preview showed\n // The upright counter-rotation applies to the text box only (about its own\n // centre) — the leader tip/knee are page-space anchors and never turn.\n const rot = calloutUprightRot(draft);\n const tool = toolAnnotation(model, 'free-text-callout', draft.preset);\n // The tool's arrow at the tip; a callout without one gets an open arrow.\n const toolEnding = tool.subtype === 'free-text' ? tool.lineEnding : null;\n const ending = toolEnding && toolEnding !== 'none' ? toolEnding : 'open-arrow';\n const created = newRecord(\n model,\n draft.page,\n draftOf(\n 'free-text-callout',\n defaultsFor(model, draft.preset ?? 'free-text-callout'),\n calloutShape(rect, rot, draft.tip, draft.knee, ending),\n { intent: 'free-text-callout', contents: '' },\n draft.flags,\n ),\n );\n const id = created.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n editing: id,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n","/** Drawing a distance measurement: the measured line, then the offset of its dimension line. */\nimport type { AnnotationFlags } from '@embedpdf/engine-core/runtime';\n\nimport {\n distanceLeaderLength,\n measurementDraftFields,\n type DistanceAppearance,\n} from '../measurement';\nimport { styleOf } from '../record';\nimport type { Shape, Effect, Model, PointerInput } from '../types';\nimport { draftOf, newRecord, numbersLeft } from './changes';\nimport { measurementSelectionQuad } from '../measurement-shape';\nimport { MIN_DRAG } from '../placement';\nimport { fractionOnPage } from './page-bound';\nimport { defaultsFor, lineEndingsOf, toolAnnotation } from './session';\n\n/**\n * Distance creation has two stages. Releasing the endpoint drag only advances\n * to offset placement; the following click is the sole persistence boundary.\n */\nexport function distancePointer(\n model: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n preset: string,\n measure?: DistanceAppearance,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const draft = model.draft;\n\n if (draft?.kind !== 'create-distance') {\n if (phase !== 'down' || !measure) {\n return [model, []];\n }\n\n return [\n {\n ...model,\n selected: [],\n draft: {\n kind: 'create-distance',\n step: 'endpoints',\n subtype: 'line',\n preset,\n page: input.page,\n from: input.point,\n to: input.point,\n measure: {\n ...measure,\n leader: { ...measure.leader, length: 0 },\n },\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n\n // Even the final placement click belongs to the draft's original page.\n if (input.page.objectNumber !== draft.page.objectNumber) {\n return [model, []];\n }\n\n if (draft.step === 'endpoints') {\n if (phase === 'down') {\n return [model, []];\n }\n\n const nextDraft = { ...draft, to: input.point };\n if (phase === 'move') {\n return [{ ...model, draft: nextDraft }, []];\n }\n\n const length = Math.hypot(nextDraft.to.x - nextDraft.from.x, nextDraft.to.y - nextDraft.from.y);\n if (length < MIN_DRAG) {\n return [{ ...model, draft: null }, []];\n }\n\n return [{ ...model, draft: { ...nextDraft, step: 'offset' } }, []];\n }\n\n if (phase === 'up') {\n return [model, []];\n }\n\n const tool = toolAnnotation(model, draft.subtype, draft.preset);\n const geometry: Shape = {\n kind: 'line',\n linePoints: { start: draft.from, end: draft.to },\n lineEndings: lineEndingsOf(tool),\n rotation: 0,\n };\n const style = styleOf(tool);\n const withLeader = (length: number): DistanceAppearance => ({\n ...draft.measure,\n leader: { ...draft.measure.leader, length },\n });\n // The dimension line goes out from the measured line toward the pointer,\n // as far as the whole measurement stays on the page.\n const wanted = distanceLeaderLength(geometry, input.point);\n const fraction = fractionOnPage(input.pageBox, (part) =>\n measurementSelectionQuad(geometry, withLeader(wanted * part), style),\n );\n const appearance = withLeader(wanted * fraction);\n\n if (phase === 'move') {\n return [{ ...model, draft: { ...draft, measure: appearance } }, []];\n }\n\n const created = newRecord(\n model,\n draft.page,\n draftOf(\n 'line',\n defaultsFor(model, draft.preset),\n geometry,\n {\n ...measurementDraftFields(appearance),\n // The arrowheads fill with the stroke colour when the tool gives no fill.\n interiorColor: style.interiorColor ?? style.color,\n },\n draft.flags,\n ),\n );\n const id = created.record.id;\n\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n","/**\n * Drawing new annotations with the pointer: shapes, lines, ink and polygons.\n * A finished drawing becomes a new record (keyed by the `nm` ref it is\n * written under) and a `create` effect.\n * Callouts and distance measurements have their own gestures (draw-callout.ts,\n * draw-distance.ts).\n */\nimport type { AnnotationFlags, InkIntent } from '@embedpdf/engine-core/runtime';\n\nimport { straightenInkStroke } from '../ink';\nimport { measurementDraftFields, type MeasurementAppearance } from '../measurement';\nimport { shapeMeasurementReadout } from '../measurement-shape';\nimport { gesturePlacement, MIN_DRAG, placedShape } from '../placement';\nimport { writableTarget } from '../record';\nimport { unionRect } from '../rect';\nimport type {\n ClickCreate,\n Shape,\n Draft,\n Effect,\n FieldValues,\n InkStraightenOptions,\n Model,\n Placement,\n PointerInput,\n Rect,\n KindName,\n} from '../types';\nimport { draftOf, isPolySubtype, newRecord, numbersLeft } from './changes';\nimport { calloutPointer } from './draw-callout';\nimport { distancePointer } from './draw-distance';\nimport { clampPointToBox } from './page-bound';\nimport { defaultsFor, lineEndingsOf, toolAnnotation } from './session';\n\n/** A box or a line being drawn: the gestures a click or a drag completes. */\ntype ShapeDraft = Extract<Draft, { kind: 'create-rect' | 'create-line' }>;\n\n/**\n * Where a box or a line being drawn puts what it makes if released now: the\n * dragged box or segment, or the tool's click default (`gesturePlacement`).\n * The commit below and the drawing in progress (view.ts) both read it, and\n * the tool's ghost makes the same call at the pointer.\n */\nexport function draftPlacement(draft: ShapeDraft, pageBox?: Rect): Placement | null {\n return gesturePlacement(\n draft.kind === 'create-line' ? 'segment' : 'box',\n draft.from,\n draft.to,\n draft.clickCreate,\n { pageBox, upright: draft.upright, displayRotation: draft.displayRotation },\n );\n}\n\nexport function createPointer(\n model: Model,\n phase: 'down' | 'move' | 'up',\n subtype: KindName,\n input: PointerInput,\n preset: string = subtype,\n intent?: InkIntent,\n deferInkCommit = false,\n straightenInk?: InkStraightenOptions,\n clickCreate?: ClickCreate | false,\n flags?: Partial<AnnotationFlags>,\n measure?: MeasurementAppearance,\n capture?: string,\n): [Model, Effect[]] {\n // An in-progress creation is anchored to its page: a move/up sample from\n // another page is a foreign frame — ignore it. (A down on another page is a\n // fresh intent: the per-subtype branches below start/restart the draft there.)\n if (\n phase !== 'down' &&\n model.draft &&\n 'page' in model.draft &&\n model.draft.page.objectNumber !== input.page.objectNumber\n )\n return [model, []];\n // Shapes can't be drawn past the page edge — the pointer pins to it.\n if (input.pageBox) input = { ...input, point: clampPointToBox(input.point, input.pageBox) };\n if (\n model.draft?.kind === 'create-distance' ||\n (measure?.intent === 'line-dimension' && !capture)\n ) {\n return distancePointer(\n model,\n phase,\n input,\n preset,\n measure?.intent === 'line-dimension' ? measure : undefined,\n flags,\n );\n }\n if (subtype === 'free-text-callout') return calloutPointer(model, phase, input, preset, flags);\n if (phase === 'down') {\n if (isPolySubtype(subtype)) {\n if (input.finish) return finishPolyCreate(model);\n if (\n model.draft?.kind === 'create-poly' &&\n model.draft.subtype === subtype &&\n model.draft.preset === preset &&\n model.draft.page.objectNumber === input.page.objectNumber\n ) {\n return [\n {\n ...model,\n draft: {\n ...model.draft,\n points: [...model.draft.points, input.point],\n current: input.point,\n },\n },\n [],\n ];\n }\n return [\n {\n ...model,\n selected: [],\n draft: {\n kind: 'create-poly',\n subtype,\n preset,\n page: input.page,\n points: [input.point],\n current: input.point,\n closed: subtype === 'polygon',\n ...(measure && measure.intent !== 'line-dimension' ? { measure } : {}),\n ...(flags ? { flags } : {}),\n },\n },\n [],\n ];\n }\n const draft: Draft | null =\n subtype === 'line'\n ? {\n kind: 'create-line',\n measure,\n capture,\n subtype,\n preset,\n page: input.page,\n from: input.point,\n to: input.point,\n // Captured at down, as for a box: an upright click lays the line as seen.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(clickCreate !== undefined ? { clickCreate } : {}),\n ...(flags ? { flags } : {}),\n }\n : subtype === 'ink'\n ? model.draft?.kind === 'create-ink' &&\n model.draft.subtype === subtype &&\n model.draft.preset === preset &&\n model.draft.page.objectNumber === input.page.objectNumber\n ? { ...model.draft, strokes: [...model.draft.strokes, [input.point]] }\n : {\n kind: 'create-ink',\n subtype,\n preset,\n page: input.page,\n strokes: [[input.point]],\n intent,\n ...(flags ? { flags } : {}),\n }\n : subtype === 'square' ||\n subtype === 'circle' ||\n subtype === 'free-text' ||\n subtype === 'redact' ||\n subtype === 'link'\n ? {\n kind: 'create-rect',\n subtype,\n preset,\n page: input.page,\n from: input.point,\n to: input.point,\n // Captured at down (the gesture's home page); a rotation of 0\n // makes upright a no-op, so the draft stays clean then.\n ...(input.upright && input.displayRotation\n ? { displayRotation: input.displayRotation, upright: true }\n : {}),\n ...(clickCreate !== undefined ? { clickCreate } : {}),\n ...(flags ? { flags } : {}),\n }\n : null;\n return draft ? [{ ...model, selected: [], draft }, []] : [model, []];\n }\n if (phase === 'move') {\n if (model.draft?.kind === 'create-poly') {\n return [{ ...model, draft: { ...model.draft, current: input.point } }, []];\n }\n if (model.draft?.kind === 'create-rect' || model.draft?.kind === 'create-line') {\n return [{ ...model, draft: { ...model.draft, to: input.point } }, []];\n }\n if (model.draft?.kind === 'create-ink') {\n // append to the active (last) stroke as the pen moves\n const strokes = model.draft.strokes.slice();\n strokes[strokes.length - 1] = [...strokes[strokes.length - 1], input.point];\n return [{ ...model, draft: { ...model.draft, strokes } }, []];\n }\n return [model, []];\n }\n // up\n const activeDraft = model.draft;\n if (\n activeDraft?.kind !== 'create-rect' &&\n activeDraft?.kind !== 'create-line' &&\n activeDraft?.kind !== 'create-ink'\n )\n return [model, []];\n\n if (activeDraft.kind === 'create-ink') {\n let next = model;\n if (straightenInk && activeDraft.strokes.length) {\n const strokes = activeDraft.strokes.slice();\n const last = strokes.length - 1;\n strokes[last] = straightenInkStroke(strokes[last], straightenInk);\n next = { ...model, draft: { ...activeDraft, strokes } };\n }\n return deferInkCommit ? [next, []] : finishInkCreate(next);\n }\n\n // What the gesture makes: the dragged shape, or the tool's click default,\n // laid by the kind's shape family. The tool's ghost showed exactly this.\n const tool = toolAnnotation(model, activeDraft.subtype, activeDraft.preset);\n const placement = draftPlacement(activeDraft, input.pageBox);\n const geometry: Shape | null = placement && placedShape(tool, placement);\n if (!geometry) return [{ ...model, draft: null }, []];\n if (activeDraft.kind === 'create-line' && activeDraft.capture)\n return [\n { ...model, draft: null },\n [{ type: 'captured', tool: activeDraft.capture, page: activeDraft.page, geometry }],\n ];\n\n const fields: FieldValues = {\n // A measurement states its intent, scale, caption and leader.\n ...(activeDraft.kind === 'create-line' && activeDraft.measure\n ? measurementDraftFields(activeDraft.measure)\n : {}),\n // A free text starts empty, as a plain box.\n ...(geometry.kind === 'text-box' ? { intent: 'free-text', contents: '' } : {}),\n // A drawn link starts at the tool preset's target ('docs-link' style\n // presets), or dead (`null` — the create-then-edit flow).\n ...(activeDraft.subtype === 'link'\n ? { target: writableTarget(tool.subtype === 'link' ? tool.target : null) }\n : {}),\n };\n const created = newRecord(\n model,\n activeDraft.page,\n draftOf(\n activeDraft.subtype,\n defaultsFor(model, activeDraft.preset ?? activeDraft.subtype),\n geometry,\n fields,\n activeDraft.flags,\n ),\n );\n const id = created.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n // A freshly drawn free-text box opens straight into edit (type immediately).\n editing: geometry.kind === 'text-box' ? id : model.editing,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n\n/** Commit all strokes accumulated by a grouped ink gesture. */\nexport function finishInkCreate(model: Model): [Model, Effect[]] {\n const draft = model.draft;\n if (draft?.kind !== 'create-ink') return [model, []];\n const points = draft.strokes.flat();\n if (!draft.strokes.some((stroke) => stroke.length >= 2) || points.length === 0)\n return [{ ...model, draft: null }, []];\n const bounds = unionRect(points);\n if (Math.max(bounds.width, bounds.height) < MIN_DRAG) return [{ ...model, draft: null }, []];\n\n const created = newRecord(\n model,\n draft.page,\n draftOf(\n draft.subtype,\n defaultsFor(model, draft.preset ?? draft.subtype),\n { kind: 'ink', inkList: draft.strokes, rotation: 0 },\n // The ink highlighter says so: `/IT` is set at create, never changed.\n draft.intent === 'ink-highlight' ? { intent: draft.intent } : {},\n draft.flags,\n ),\n );\n const id = created.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n\nexport function finishPolyCreate(model: Model): [Model, Effect[]] {\n const draft = model.draft;\n if (draft?.kind !== 'create-poly') return [model, []];\n const minPoints = draft.closed ? 3 : 2;\n if (draft.points.length < minPoints) return [{ ...model, draft: null }, []];\n\n const tool = toolAnnotation(model, draft.subtype, draft.preset);\n const geometry: Shape = {\n kind: 'poly',\n vertices: draft.points,\n closed: draft.closed,\n lineEndings: draft.closed ? undefined : lineEndingsOf(tool),\n rotation: 0,\n };\n if (draft.measure && 'unavailable' in shapeMeasurementReadout(geometry, draft.measure))\n return [model, []];\n\n const created = newRecord(\n model,\n draft.page,\n draftOf(\n draft.subtype,\n defaultsFor(model, draft.preset ?? draft.subtype),\n geometry,\n draft.measure ? measurementDraftFields(draft.measure) : {},\n draft.flags,\n ),\n );\n const id = created.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n","/**\n * Pure alignment snapping for the move gesture. Compares the moving selection's\n * edges + centers against every other annotation on the page (and the page\n * box); if a pair lands within the threshold, nudges the delta to align them\n * and reports a guide line to draw. One snap per axis — the closest wins.\n * Threshold is in content units: the caller converts the screen-pixel setting.\n */\nimport type { PageRef } from '@embedpdf/engine-core/runtime';\nimport { anchorModeOf } from './anchor';\nimport { selectionQuad } from './geometry';\nimport { unionRect } from './rect';\nimport { isSelectable } from './hit';\nimport type { Guide, Id, Model, Rect, Point } from './types';\nimport { shapeOf, styleOf } from './record';\n\nexport interface SnapResult {\n delta: Point;\n guides: Guide[];\n}\n\ninterface Bounds {\n min: Point;\n max: Point;\n}\n\n/** Overshoot the shapes a little so the guide reads as a through-line. */\nconst GUIDE_PAD = 14;\n\nconst toBounds = (rect: Rect): Bounds => ({\n min: { x: rect.x, y: rect.y },\n max: { x: rect.x + rect.width, y: rect.y + rect.height },\n});\nconst keysX = (bounds: Bounds) => [bounds.min.x, (bounds.min.x + bounds.max.x) / 2, bounds.max.x];\nconst keysY = (bounds: Bounds) => [bounds.min.y, (bounds.min.y + bounds.max.y) / 2, bounds.max.y];\nconst shift = (bounds: Bounds, point: Point): Bounds => ({\n min: { x: bounds.min.x + point.x, y: bounds.min.y + point.y },\n max: { x: bounds.max.x + point.x, y: bounds.max.y + point.y },\n});\n\n/** An annotation's visual footprint corners — the oriented quad, so a rotated\n * shape snaps by what's actually drawn, not its unrotated box. */\nconst annotQuad = (model: Model, id: Id): Point[] => {\n const geometry = shapeOf(model.byId[id].annotation);\n const style = styleOf(model.byId[id].annotation);\n return selectionQuad(geometry, style);\n};\n\n/**\n * Snap a move delta: shift the selection's union bounds by `raw`, compare its\n * 3 keys per axis (min / center / max) against every target's, and take the\n * closest in-threshold pair per axis as an adjustment. Targets are the page box\n * (edges + center) and every non-moving annotation on the page.\n */\nexport function computeMoveSnap(\n model: Model,\n ids: Id[],\n page: PageRef,\n raw: Point,\n threshold: number,\n pageBox: Rect | undefined,\n): SnapResult {\n const pageObjectNumber = page.objectNumber;\n const moving = new Set(ids);\n // Screen-anchored (`noZoom`/`noRotate`) annotations sit outside the snapping\n // system, both ways: their page-space footprint depends on the view, so\n // an alignment made at one zoom is a lie at every other zoom. A selection\n // that contains one doesn't snap; one that's parked on the page is never a\n // reference edge. (The page-edge clamp is unaffected — it uses projected\n // bounds per event.)\n if (ids.some((id) => model.byId[id] && anchorModeOf(model.byId[id]))) {\n return { delta: raw, guides: [] };\n }\n const base = toBounds(unionRect(ids.flatMap((id) => annotQuad(model, id))));\n const movingBox = shift(base, raw);\n\n const targets: Bounds[] = [\n ...(pageBox ? [toBounds(pageBox)] : []),\n ...model.order\n .filter(\n (id) =>\n !moving.has(id) &&\n model.byId[id].annotation.page.objectNumber === pageObjectNumber &&\n isSelectable(model, id) &&\n !anchorModeOf(model.byId[id]),\n )\n .map((id) => toBounds(unionRect(annotQuad(model, id)))),\n ];\n\n let bx: { adjust: number; at: number; tb: Bounds } | null = null;\n let by: { adjust: number; at: number; tb: Bounds } | null = null;\n for (const tb of targets) {\n for (const tk of keysX(tb))\n for (const mk of keysX(movingBox)) {\n const diff = tk - mk;\n if (Math.abs(diff) < threshold && (!bx || Math.abs(diff) < Math.abs(bx.adjust)))\n bx = { adjust: diff, at: tk, tb };\n }\n for (const tk of keysY(tb))\n for (const mk of keysY(movingBox)) {\n const diff = tk - mk;\n if (Math.abs(diff) < threshold && (!by || Math.abs(diff) < Math.abs(by.adjust)))\n by = { adjust: diff, at: tk, tb };\n }\n }\n\n const delta = { x: raw.x + (bx?.adjust ?? 0), y: raw.y + (by?.adjust ?? 0) };\n const snapped = shift(base, delta);\n const guides: Guide[] = [];\n if (bx)\n guides.push({\n axis: 'x',\n at: bx.at,\n lo: Math.min(snapped.min.y, bx.tb.min.y) - GUIDE_PAD,\n hi: Math.max(snapped.max.y, bx.tb.max.y) + GUIDE_PAD,\n });\n if (by)\n guides.push({\n axis: 'y',\n at: by.at,\n lo: Math.min(snapped.min.x, by.tb.min.x) - GUIDE_PAD,\n hi: Math.max(snapped.max.x, by.tb.max.x) + GUIDE_PAD,\n });\n return { delta, guides };\n}\n","/**\n * The release of an edit gesture: the previewed result becomes the records'\n * new geometry, and one patch effect per changed record asks for the write.\n * A grab that changed nothing writes nothing.\n */\nimport { anchorModeOf, unanchoredGeom } from '../anchor';\nimport { geomRotateAbout, geomScaleAbout, geomTranslate, groupResizeFactors } from '../geometry';\nimport { measurementOf } from '../measurement';\nimport { moveMeasurementCaption, shapeMeasurementReadout } from '../measurement-shape';\nimport { MIN_SIZE } from '../rect';\nimport { shapeOf, styleOf, withShape, withValues } from '../record';\nimport type { Effect, Model } from '../types';\nimport { commitViewGesture, geomEqual } from './changes';\nimport { rotateDraftDelta } from './edit';\n\nexport function editUp(model: Model): [Model, Effect[]] {\n const draft = model.draft!;\n if (draft.kind === 'leader') {\n const record = model.byId[draft.id];\n const measure = record && measurementOf(record.annotation);\n if (measure?.intent !== 'line-dimension' || draft.delta === 0) {\n return [{ ...model, draft: null }, []];\n }\n\n const updated = withValues(record!, {\n leader: { ...measure.leader, length: (measure.leader?.length ?? 0) + draft.delta },\n });\n\n return [{ ...model, draft: null, byId: { ...model.byId, [updated.id]: updated } }, []];\n }\n if (draft.kind === 'caption') {\n const record = model.byId[draft.id];\n const measure = record && measurementOf(record.annotation);\n if (!measure || (!draft.delta.x && !draft.delta.y)) return [{ ...model, draft: null }, []];\n const style = styleOf(record!.annotation);\n const caption = moveMeasurementCaption(\n shapeOf(record!.annotation),\n measure,\n draft.delta,\n style,\n );\n // A distance's caption offset is a field of its own; a perimeter's or\n // area's caption center is its shape's.\n const moved =\n caption.measure.intent === 'line-dimension'\n ? withValues(record!, { captionOffset: caption.measure.captionOffset })\n : withShape(record!, caption.geometry);\n return [{ ...model, draft: null, byId: { ...model.byId, [moved.id]: moved } }, []];\n }\n if (draft.kind === 'handle') {\n // A grab that didn't actually resize writes nothing.\n if (geomEqual(draft.base, draft.current)) return [{ ...model, draft: null }, []];\n // `cur` is view-space (the projected geometry the user dragged); the\n // commit maps it back to stored space — the identity when un-flagged.\n const before = model.byId[draft.id];\n const stored = unanchoredGeom(draft.current, anchorModeOf(before), draft.view);\n const measure = measurementOf(before.annotation);\n if (measure?.intent === 'polygon-dimension') {\n const readout = shapeMeasurementReadout(stored, measure);\n if ('unavailable' in readout && readout.unavailable === 'invalid-geometry') {\n return [{ ...model, draft: null }, []];\n }\n }\n const record = withShape(before, stored);\n return [{ ...model, byId: { ...model.byId, [draft.id]: record }, draft: null }, []];\n }\n if (draft.kind === 'rotate') {\n const { delta } = rotateDraftDelta(model, draft);\n if (Math.abs(delta) < 0.01) return [{ ...model, draft: null }, []];\n const byId = { ...model.byId };\n for (const id of draft.ids) {\n const record = byId[id];\n if (!record) continue;\n // The gesture composed in view space (`effGeom`); the commit replays the\n // same composition and unprojects — a screen-anchored member's authored\n // tilt turns WYSIWYG, exactly as previewed. A measurement's caption\n // center turns with its shape.\n const rotated = commitViewGesture(record, draft.view, (geometry) =>\n geomRotateAbout(geometry, draft.pivot, delta),\n );\n byId[id] = withShape(record, rotated);\n }\n return [{ ...model, byId, draft: null }, []];\n }\n if (draft.kind === 'group') {\n const { sx, sy } = groupResizeFactors(draft.base, draft.current);\n if (Math.abs(sx - 1) < 1e-4 && Math.abs(sy - 1) < 1e-4) return [{ ...model, draft: null }, []];\n const byId = { ...model.byId };\n for (const id of draft.ids) {\n const record = byId[id];\n if (!record) continue;\n const scaled = commitViewGesture(record, draft.view, (geometry) =>\n geomScaleAbout(geometry, draft.anchor, sx, sy, MIN_SIZE),\n );\n byId[id] = withShape(record, scaled);\n }\n return [{ ...model, byId, draft: null }, []];\n }\n if (draft.kind === 'move') {\n if (Math.hypot(draft.delta.x, draft.delta.y) < 0.01) return [{ ...model, draft: null }, []]; // a click\n const byId = { ...model.byId };\n for (const id of draft.ids) {\n const record = byId[id];\n const geometry = shapeOf(record.annotation);\n byId[id] = withShape(record, geomTranslate(geometry, draft.delta));\n }\n return [{ ...model, byId, draft: null }, []];\n }\n return [{ ...model, draft: null }, []];\n}\n","/**\n * Editing existing annotations with the pointer: the press that picks what to\n * do (select, move, resize, rotate, drag a caption or a leader) and the moves\n * that preview it. The release commits it (edit-commit.ts).\n */\nimport { anchoredGeom, anchorModeOf } from '../anchor';\nimport {\n DEFAULT_CHROME_GEOMETRY,\n geomDragHandle,\n geomHandles,\n geomRotation,\n groupResizeAnchor,\n groupResizeBox,\n} from '../geometry';\nimport { groupMembers } from '../group';\nimport { canMove, hitTest } from '../hit';\nimport { distanceLeaderLength, measurementOf } from '../measurement';\nimport { moveMeasurementCaption } from '../measurement-shape';\nimport { shapeOf, styleOf } from '../record';\nimport { normalizeDeg } from '../rect';\nimport { annotationSelectionFrame } from '../selection';\nimport { computeMoveSnap } from '../snap';\nimport type { Draft, Effect, Id, Model, Point, PointerInput } from '../types';\nimport { sub } from './changes';\nimport { editUp } from './edit-commit';\nimport {\n clampMoveDelta,\n clampPointToBox,\n deltaOnPage,\n editDraftPage,\n fractionOnPage,\n viewOf,\n} from './page-bound';\n\nconst RAD2DEG = 180 / Math.PI;\n\n/** The signed CW angle (deg) of `point` relative to `pivot`, in page space (y-down). */\nconst angleAt = (pivot: Point, point: Point): number =>\n Math.atan2(point.y - pivot.y, point.x - pivot.x) * RAD2DEG;\n\n/** Shortest signed arc from `from` to `to` (deg), in (-180, 180]. */\nconst arcTo = (from: number, to: number): number => ((to - from + 540) % 360) - 180;\n\n/**\n * The live rotation of a rotate draft, snapping applied — the one angle rule\n * shared by the preview (`effGeom`), the commit (`editUp`) and the angle chip,\n * so they can never disagree. The selection's absolute angle (a single member's\n * `rot` + the raw pointer delta; a group's raw delta from 0) locks onto the\n * configured angles within the threshold; `free` (shift held) bypasses.\n * `delta` is what `geomRotateAbout` applies; `angle` is what the chip shows.\n */\nexport function rotateDraftDelta(\n model: Model,\n draft: Extract<Draft, { kind: 'rotate' }>,\n): { delta: number; angle: number; snapped: boolean } {\n const raw = angleAt(draft.pivot, draft.current) - angleAt(draft.pivot, draft.start);\n const one = draft.ids.length === 1 ? model.byId[draft.ids[0]] : null;\n // The absolute angle is read off the projected geometry (identity when\n // un-flagged): the chip and the snap targets speak about what the user sees\n // — a noRotate shape's on-screen tilt, not its stored one.\n const base = one\n ? geomRotation(anchoredGeom(shapeOf(one.annotation), anchorModeOf(one), draft.view))\n : 0;\n const angle = normalizeDeg(base + raw);\n if (!model.snap.rotation || draft.free) return { delta: raw, angle, snapped: false };\n for (const target of model.snap.rotationAngles) {\n const adjust = arcTo(angle, normalizeDeg(target));\n if (Math.abs(adjust) <= model.snap.rotationThreshold)\n return { delta: raw + adjust, angle: normalizeDeg(target), snapped: true };\n }\n return { delta: raw, angle, snapped: false };\n}\n\n/** A group resize is isotropic (uniform) when any selected member is rotated —\n * an off-axis scale across a rotated rect+rot is a shear it can't represent. A\n * vertex member's advisory `rot` counts (preserves obbFromTheta + reset). */\nconst selectionHasRotation = (model: Model, ids: Id[]): boolean =>\n ids.some((id) => {\n const record = model.byId[id];\n return !!record && geomRotation(shapeOf(record.annotation)) !== 0;\n });\n\nexport function editPointer(\n model: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n): [Model, Effect[]] {\n if (phase === 'down') return editDown(model, input);\n if (phase === 'move') return model.draft ? editMove(model, input) : [model, []];\n return model.draft ? editUp(model) : [model, []];\n}\n\nexport function editDown(model: Model, input: PointerInput): [Model, Effect[]] {\n // `pageBox` + `chrome` reach the hit-test so the page-bound rotate knob\n // (flipped / clamped near an edge) is grabbed exactly where the chrome drew\n // it, with the caller's (screen-constant) grab zones. The view env rides\n // along so screen-anchored annotations are grabbed where they're painted.\n const hit = hitTest(\n model,\n input.page,\n input.point,\n input.chrome ?? DEFAULT_CHROME_GEOMETRY,\n model.hitMargin / (input.scale || 1),\n input.pageBox,\n input.inert,\n viewOf(input),\n );\n if (hit.kind === 'handle' && hit.handle === 'caption') {\n return [\n {\n ...model,\n draft: { kind: 'caption', id: hit.id, start: input.point, delta: { x: 0, y: 0 } },\n },\n [],\n ];\n }\n if (hit.kind === 'handle' && (hit.handle === 'leader-start' || hit.handle === 'leader-end')) {\n return [\n {\n ...model,\n draft: { kind: 'leader', id: hit.id, start: input.point, delta: 0 },\n },\n [],\n ];\n }\n if (hit.kind === 'handle') {\n // The handle gesture runs in view space: `base` is the projected geometry\n // the user grabbed (identity for un-flagged annotations), and the commit\n // maps the result back via `unanchoredGeom` with the same captured view.\n const record = model.byId[hit.id];\n const view = viewOf(input);\n const base = anchoredGeom(shapeOf(record.annotation), anchorModeOf(record), view);\n return [\n {\n ...model,\n draft: {\n kind: 'handle',\n id: hit.id,\n handle: hit.handle,\n base,\n current: base,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.kind === 'rotate') {\n const view = viewOf(input);\n return [\n {\n ...model,\n draft: {\n kind: 'rotate',\n ids: hit.ids,\n pivot: hit.pivot,\n start: input.point,\n current: input.point,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.kind === 'group-handle') {\n const view = viewOf(input);\n return [\n {\n ...model,\n draft: {\n kind: 'group',\n op: 'resize',\n ids: hit.ids,\n handle: hit.handle,\n anchor: groupResizeAnchor(hit.box, hit.handle),\n base: hit.box,\n current: hit.box,\n ...(view ? { view } : {}),\n },\n },\n [],\n ];\n }\n if (hit.kind === 'annot') {\n // A hit on any member acts on the whole group — select/toggle/drag as a unit.\n const grp = groupMembers(model, hit.id);\n const inSel = model.selected.includes(hit.id);\n const selected = input.shift\n ? inSel\n ? model.selected.filter((selectedId) => !grp.includes(selectedId)) // shift+click a member → drop the group\n : [...model.selected, ...grp.filter((memberId) => !model.selected.includes(memberId))]\n : inSel\n ? model.selected\n : grp;\n // Only arm a move gesture if every selected annotation can move; an anchored\n // kind (markup/caret) still selects, it just won't drag.\n const movable = selected.length > 0 && selected.every((id) => canMove(model, id));\n const draft: Draft | null = movable\n ? { kind: 'move', ids: selected, start: input.point, delta: { x: 0, y: 0 }, guides: [] }\n : null;\n return [{ ...model, selected, draft }, []];\n }\n return [{ ...model, selected: [] }, []]; // empty (the handler usually pre-empts via 'deselect')\n}\n\nexport function editMove(model: Model, input: PointerInput): [Model, Effect[]] {\n const draft = model.draft!;\n // Foreign coordinate frame (see the page-bound gesture rules above) — ignore.\n const home = editDraftPage(model, draft);\n if (home != null && input.page.objectNumber !== home.objectNumber) return [model, []];\n if (draft.kind === 'move') {\n const view = viewOf(input);\n const raw = clampMoveDelta(\n model,\n draft.ids,\n sub(input.point, draft.start),\n input.pageBox,\n view,\n );\n if (!model.snap.alignment || input.shift)\n return [{ ...model, draft: { ...draft, delta: raw, guides: [] } }, []];\n // Snap guides read stored geometry (an anchored mover aligns by its /Rect\n // box) — a deliberate simplification; the clamp above is view-exact.\n const snap = computeMoveSnap(\n model,\n draft.ids,\n input.page,\n raw,\n // Screen pixels to page units at this sample's view.\n model.snap.alignmentThreshold / (input.scale || 1),\n input.pageBox,\n );\n // A snap adjusts by ≤ threshold, but never past the page edge: re-clamp, and\n // drop the guide on an axis the clamp took back (its line would be a lie).\n const delta = clampMoveDelta(model, draft.ids, snap.delta, input.pageBox, view);\n const guides = snap.guides.filter((guide) =>\n guide.axis === 'x' ? delta.x === snap.delta.x : delta.y === snap.delta.y,\n );\n return [{ ...model, draft: { ...draft, delta, guides } }, []];\n }\n const point = clampPointToBox(input.point, input.pageBox);\n // A reshaping gesture stops where the annotation would reach past the page\n // (see `fractionOnPage`): the pointer's clamp alone lets a dimension line,\n // a caption or an arrowhead built out from it leave the page.\n if (draft.kind === 'leader') {\n const record = model.byId[draft.id];\n const geometry = shapeOf(record.annotation);\n const measure = measurementOf(record.annotation);\n const wanted =\n distanceLeaderLength(geometry, point) - distanceLeaderLength(geometry, draft.start);\n if (measure?.intent !== 'line-dimension')\n return [{ ...model, draft: { ...draft, delta: wanted } }, []];\n const length = measure.leader?.length ?? 0;\n const fraction = fractionOnPage(input.pageBox, (part) => {\n const leader = { ...measure.leader, length: length + wanted * part };\n return annotationSelectionFrame(record, undefined, { measure: { ...measure, leader } })\n .corners;\n });\n return [{ ...model, draft: { ...draft, delta: wanted * fraction } }, []];\n }\n if (draft.kind === 'caption') {\n const record = model.byId[draft.id];\n const geometry = shapeOf(record.annotation);\n const measure = measurementOf(record.annotation);\n const style = styleOf(record.annotation);\n const wanted = sub(point, draft.start);\n const delta = !measure\n ? wanted\n : deltaOnPage(input.pageBox, wanted, (moved) => {\n const caption = moveMeasurementCaption(geometry, measure, moved, style);\n return annotationSelectionFrame(record, undefined, caption).corners;\n });\n return [{ ...model, draft: { ...draft, delta } }, []];\n }\n if (draft.kind === 'handle') {\n // From where the handle is to the pointer; the base is what the view shows.\n const record = model.byId[draft.id];\n const from = geomHandles(draft.base).find((handle) => handle.id === draft.handle)?.at ?? point;\n const draggedBy = (delta: Point) =>\n geomDragHandle(draft.base, draft.handle, { x: from.x + delta.x, y: from.y + delta.y });\n const delta = deltaOnPage(input.pageBox, sub(point, from), (moved) => {\n const geometry = draggedBy(moved);\n return annotationSelectionFrame(record, undefined, { geometry }).corners;\n });\n return [{ ...model, draft: { ...draft, current: draggedBy(delta) } }, []];\n }\n // Rotation reads the pointer as an angle about the pivot — the raw point is\n // valid (and better) outside the page; the geometry itself never translates.\n // `free` (shift) records the snap bypass for this sample.\n if (draft.kind === 'rotate')\n return [{ ...model, draft: { ...draft, current: input.point, free: input.shift } }, []];\n if (draft.kind === 'group') {\n const iso = selectionHasRotation(model, draft.ids);\n return [\n {\n ...model,\n draft: { ...draft, current: groupResizeBox(draft.base, draft.handle, point, iso) },\n },\n [],\n ];\n }\n return [model, []];\n}\n","/**\n * Rubber-band selection: drag a box on empty page space to select what it\n * touches of what each annotation paints (`painted.ts`), the ink, or the\n * inside of a filled shape, as a click would hit it.\n */\nimport type { PageRef } from '@embedpdf/engine-core/runtime';\n\nimport { type ViewEnv } from '../anchor';\nimport { rectFromPoints } from '../rect';\nimport { expandGroups } from '../group';\nimport { isSelectable, paintedOf } from '../hit';\nimport { paintedTouches } from '../painted';\nimport { isSubstrateOnly } from '../plane';\nimport type { Effect, Id, Model, PointerInput, Rect } from '../types';\nimport { clampPointToBox, viewOf } from './page-bound';\n\nexport function marqueePointer(\n model: Model,\n phase: 'down' | 'move' | 'up',\n input: PointerInput,\n): [Model, Effect[]] {\n // The marquee lives on one page and pins to its box (same rules as editMove).\n const point = clampPointToBox(input.point, input.pageBox);\n if (phase === 'down') {\n return [{ ...model, draft: { kind: 'marquee', page: input.page, from: point, to: point } }, []];\n }\n if (model.draft?.kind !== 'marquee') return [model, []];\n if (model.draft.page.objectNumber !== input.page.objectNumber) return [model, []]; // foreign frame — ignore\n if (phase === 'move') {\n return [{ ...model, draft: { ...model.draft, to: point } }, []];\n }\n\n const hits = selectionInBox(\n model,\n model.draft.page,\n rectFromPoints(model.draft.from, point),\n input.inert,\n viewOf(input),\n );\n const selected = input.shift ? toggleSelection(model.selected, hits) : hits;\n return [{ ...model, selected, draft: null }, []];\n}\n\nfunction toggleSelection(base: Id[], ids: Id[]): Id[] {\n const next = new Set(base);\n for (const id of ids) {\n if (next.has(id)) next.delete(id);\n else next.add(id);\n }\n return [...next];\n}\n\n/**\n * What a box on `page` selects: every annotation it touches\n * ({@link annotsInBox}), and the rest of the group of each. The marquee and\n * the capability's `selectInRect` both select this.\n */\nexport function selectionInBox(\n model: Model,\n page: PageRef,\n box: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Id[] {\n return expandGroups(model, annotsInBox(model, page, box, inert, view));\n}\n\n/**\n * The selectable annotations on `page` whose paint the box touches: their\n * ink, or their inside where a click would hit it. Screen-anchored bodies\n * count as they show at `view`. An unfilled shape's empty middle, or the\n * empty corners of a diagonal line's bounds, is not touching it.\n */\nexport function annotsInBox(\n model: Model,\n page: PageRef,\n box: Rect,\n inert?: ReadonlySet<Id>,\n view?: ViewEnv,\n): Id[] {\n const pageObjectNumber = page.objectNumber;\n return model.order.filter((id) => {\n const record = model.byId[id];\n if (\n record?.annotation.page.objectNumber !== pageObjectNumber ||\n inert?.has(id) ||\n !isSelectable(model, id)\n )\n return false;\n // Conversation-plane annotations (replies, review states) are never on\n // the page — the marquee cannot sweep up what does not paint.\n if (isSubstrateOnly(record)) return false;\n return paintedTouches(paintedOf(record, view), box);\n });\n}\n","/**\n * The attached-link lens — the conversation-plane pattern applied to link\n * children. The substrate keeps every `/RT /Group` link child as a\n * first-class `ModelAnnotation`; these pure derivations present them as the parent's\n * `link` property. One source of truth (the children), so a remote\n * create/retarget/delete is an ordinary substrate upsert/remove and every\n * read converges through here — no folded copy on the parent, no join-key\n * ledger, no reconciliation rules between the two.\n *\n * Callers memoize by model identity where it matters (nav items, selection\n * props); these scans stay O(order) and allocation-light.\n */\nimport type { PdfLinkTarget } from '@embedpdf/engine-core/runtime';\n\nimport { isAttachedLink } from './plane';\nimport { groupOf } from './record';\nimport type { ModelAnnotation, Id, Model } from './types';\n\n/** Every attached link child of `parentId`, in z-order (multi-segment\n * markup parents carry several children with one shared target). */\nexport function linkChildrenOf(model: Model, parentId: Id): ModelAnnotation[] {\n const out: ModelAnnotation[] = [];\n for (const id of model.order) {\n const record = model.byId[id];\n if (record && isAttachedLink(record) && groupOf(record.annotation) === parentId)\n out.push(record);\n }\n return out;\n}\n\n/** The parent's link target, derived from its first attached child — the\n * read side of the `syncLink` reconciler. Null when no child exists. */\nexport function linkOf(model: Model, parentId: Id): PdfLinkTarget | null {\n const child = linkChildrenOf(model, parentId)[0]?.annotation;\n return child?.subtype === 'link' ? (child.target ?? null) : null;\n}\n","/**\n * The kind table's style-panel properties over a selection: which properties\n * a mixed selection shares, and which kinds may carry a link.\n */\nimport type { AnnotationKind, AnnotationProperty } from './kinds';\nimport { FLAG_PROPERTIES } from './kinds/fields';\nimport type { TextStyle } from './types';\n\n/** Base text styling for kinds/tools with no explicit defaults. */\nexport const initialTextStyle: TextStyle = {\n fontFamily: 'helvetica',\n fontSize: 14,\n fontColor: '#000000',\n textAlign: 'left',\n};\n\n/** Does this kind's property table declare `link` (attachable link)? The link\n * kind itself also declares it, but stores its own `/A` instead. */\nexport const kindTakesLink = (kind: AnnotationKind): boolean =>\n kind.properties.some((property) => property.key === 'link');\n\nconst withFlags = new WeakMap<AnnotationKind, readonly AnnotationProperty[]>();\n\n/**\n * Everything a style panel edits for one kind: its own properties, then the\n * flags every kind has. The same array for a kind on every call.\n */\nexport function propertiesOf(kind: AnnotationKind): readonly AnnotationProperty[] {\n let properties = withFlags.get(kind);\n if (!properties) {\n properties = [...kind.properties, ...FLAG_PROPERTIES];\n withFlags.set(kind, properties);\n }\n return properties;\n}\n\n/**\n * The ordered properties every given kind has: the schema for a mixed\n * selection, in the first kind's display order. One kind: its own list\n * (`propertiesOf`), the same array every time.\n */\nexport function sharedProperties(kinds: readonly AnnotationKind[]): readonly AnnotationProperty[] {\n const unique = [...new Set(kinds)];\n if (!unique.length) return [];\n const first = propertiesOf(unique[0]!);\n if (unique.length === 1) return first;\n const rest = unique\n .slice(1)\n .map((kind) => new Set(propertiesOf(kind).map((property) => property.key)));\n return first.filter((property) => rest.every((keys) => keys.has(property.key)));\n}\n","/**\n * Edits the toolbar applies to the whole selection: fields, text formats,\n * links, flags, quarter turns, reset rotation, delete. Each changed record's\n * change is its own engine write (`update` derives it from the change set).\n * They are changes by hand: a record the session's `editable` rule freezes\n * is skipped (editable.ts).\n */\nimport type { AnnotationFlags, PdfLinkTarget, RichTextBody } from '@embedpdf/engine-core/runtime';\n\nimport { isDeletableByHand, isEditableByHand, isTransformableByHand } from '../editable';\nimport { geomResetRotation, geomRotateAbout, geomRotation } from '../geometry';\nimport { groupUnionBounds } from '../hit';\nimport { linkChildrenOf } from '../links';\nimport { kindTakesLink } from '../props';\nimport { kindOf, shapeOf, withShape, withValues, writableTarget } from '../record';\nimport { annotationTurnPivot } from '../selection';\nimport type { Effect, FieldValues, Id, Model, ModelAnnotation, Point } from '../types';\nimport { withoutRecords } from './changes';\n\ntype TextFormat = 'bold' | 'italic' | 'underline';\n\n/**\n * The model with `change` applied to each record of `ids` that people may\n * change by hand (a record listed twice sees its first change). The same\n * model when no record changes.\n */\nfunction changeRecords(\n model: Model,\n ids: readonly Id[],\n change: (record: ModelAnnotation) => ModelAnnotation,\n): Model {\n let byId: Model['byId'] | null = null;\n for (const id of ids) {\n const record = (byId ?? model.byId)[id];\n if (!record || !isEditableByHand(model, record.annotation)) continue;\n const next = change(record);\n if (next === record) continue;\n byId ??= { ...model.byId };\n byId[id] = next;\n }\n return byId ? { ...model, byId } : model;\n}\n\n/**\n * Write engine fields to records, a patch per id, each through `withValues`:\n * a record takes the fields its kind has and may change now, so one message\n * restyles a mixed selection, and a `rect` the engine would refuse throws.\n * The tool defaults are never touched: editing existing annotations doesn't\n * change the next one drawn.\n */\nexport function setFields(\n model: Model,\n patches: Readonly<Record<Id, FieldValues>>,\n): [Model, Effect[]] {\n const next = changeRecords(model, Object.keys(patches), (record) =>\n withValues(record, patches[record.id]!),\n );\n return [next, []];\n}\n\n/** Does a free text's body carry `format`, as the sidebar shows it? */\nfunction bodyHas(body: RichTextBody, format: TextFormat): boolean {\n if (format === 'bold') return body.weight >= 600;\n if (format === 'italic') return body.italic;\n return body.decoration.includes('underline');\n}\n\n/** The body with `format` on or off, the rest of it as it was. */\nfunction bodyWith(body: RichTextBody, format: TextFormat, on: boolean): RichTextBody {\n if (format === 'bold') return { ...body, weight: on ? 700 : 400 };\n if (format === 'italic') return { ...body, italic: on };\n const lines = body.decoration.filter((line) => line !== 'underline');\n return { ...body, decoration: on ? [...lines, 'underline'] : lines };\n}\n\n/**\n * Bold, italic or underline on or off for the selection's free texts. A\n * format is the rich text's body, so every run that doesn't set its own\n * follows; the editor's range formats runs instead.\n */\nexport function setTextFormat(model: Model, format: TextFormat, on: boolean): [Model, Effect[]] {\n const next = changeRecords(model, model.selected, (record) => {\n const annotation = record.annotation;\n if (annotation.subtype !== 'free-text') return record;\n const { body, paragraphs } = annotation.richText;\n if (bodyHas(body, format) === on) return record;\n return withValues(record, { richText: { body: bodyWith(body, format, on), paragraphs } });\n });\n return [next, []];\n}\n\n/**\n * Link the selection to `target`, or unlink it (`null`). A link annotation's\n * target is a field of it. Every other linkable kind's link lives in\n * attached child annotations, so it rides a `syncLink` effect and the\n * plugin's reconciler writes the children. Locked annotations refuse it.\n */\nexport function setLink(model: Model, target: PdfLinkTarget | null): [Model, Effect[]] {\n const fx: Effect[] = [];\n const links: Id[] = [];\n for (const id of model.selected) {\n const record = model.byId[id];\n if (\n !record ||\n !isTransformableByHand(model, record) ||\n !kindTakesLink(kindOf(record.annotation))\n )\n continue;\n if (record.annotation.subtype === 'link') links.push(id);\n else fx.push({ type: 'syncLink', id, target });\n }\n // A read-only target (a script, a named action) is carried, never written.\n if (target && !writableTarget(target)) return [model, fx];\n return [changeRecords(model, links, (record) => withValues(record, { target })), fx];\n}\n\n/**\n * Merge `/F` flags into the selection (or explicit ids), through\n * `withValues`: a flag is writable with update authority alone, so a locked\n * annotation unlocks and a hidden one shows. A flag changes no drawing: a\n * baked raster stays baked.\n */\nexport function setFlags(\n model: Model,\n patch: Partial<AnnotationFlags>,\n ids?: Id[],\n): [Model, Effect[]] {\n return [changeRecords(model, ids ?? model.selected, (record) => withValues(record, patch)), []];\n}\n\n/**\n * Rotate the current selection by `deltaDeg` (clockwise) — the toolbar\n * \"rotate 90°\" affordance. A single shape turns about its own centre; a\n * multi-target group about the union-box centre (gated by `groupRotatable` for\n * groups, `rotatable` for a single shape). Emits one patch per rotated member.\n */\nexport function rotateSelection(model: Model, deltaDeg: number): [Model, Effect[]] {\n const ids = model.selected.filter((id) => {\n const record = model.byId[id];\n return (\n record && isTransformableByHand(model, record) && kindOf(record.annotation).caps.rotatable\n );\n });\n if (!ids.length) return [model, []];\n // pivot: where the engine turns a single shape (`turnPivotOf`: a box's\n // centre, the middle of a point kind's upright points), so a turn changes only\n // its angle; a group's union-box centre.\n // Stored space throughout — a screen-anchored member's authored tilt turns,\n // which is exactly its on-screen tilt (the display adds nothing to it); at\n // high zoom the anchor may re-seat by a hair, which the toolbar action\n // accepts (the knob gesture, which is pointer-exact, goes through the\n // view-space commit instead).\n let pivot: Point;\n if (ids.length === 1) {\n const record = model.byId[ids[0]];\n pivot = annotationTurnPivot(record);\n } else {\n const page = model.byId[ids[0]].annotation.page;\n const union = groupUnionBounds({ ...model, selected: ids }, page);\n if (!union) return [model, []];\n pivot = { x: union.x + union.width / 2, y: union.y + union.height / 2 };\n }\n const byId = { ...model.byId };\n for (const id of ids) {\n const record = byId[id];\n const geometry = shapeOf(record.annotation);\n byId[id] = withShape(record, geomRotateAbout(geometry, pivot, deltaDeg));\n }\n return [{ ...model, byId }, []];\n}\n\n/** Reset rotation on the selection to the as-authored orientation. For a\n * screen-anchored annotation that is its on-screen orientation, so reset is\n * as meaningful as for anyone else. A kind that doesn't turn keeps its turn:\n * a caret's follows its text, a callout's stands it upright. */\nexport function resetRotation(model: Model): [Model, Effect[]] {\n const byId = { ...model.byId };\n let turned = false;\n for (const id of model.selected) {\n const record = byId[id];\n if (\n !record ||\n !isTransformableByHand(model, record) ||\n !kindOf(record.annotation).caps.rotatable\n )\n continue;\n const geometry = shapeOf(record.annotation);\n if (geomRotation(geometry) === 0) continue;\n const pivot = annotationTurnPivot(record);\n byId[id] = withShape(record, geomResetRotation(geometry, pivot));\n turned = true;\n }\n return turned ? [{ ...model, byId }, []] : [model, []];\n}\n\nexport function deleteSelection(model: Model): [Model, Effect[]] {\n // `locked` (and inert `/F` states) and the `editable` rule protect against\n // deletion — only the deletable members go; the rest keep their selection,\n // so a mixed selection deletes what it may and leaves the frozen ones\n // visibly selected.\n const deletable = model.selected.filter((id) => {\n const record = model.byId[id];\n return !!record && isDeletableByHand(model, record);\n });\n if (!deletable.length) return [model, []];\n // Attached link children die with their parent. They are model\n // annotations now, so expanding the deletable set makes the one loop\n // below handle parent and children uniformly — no side ledger.\n const withChildren = [\n ...deletable,\n ...deletable.flatMap((id) => linkChildrenOf(model, id).map((record) => record.id)),\n ];\n const fx: Effect[] = withChildren\n .filter((id) => model.byId[id])\n .map((id): Effect => ({ type: 'delete', id }));\n return [{ ...withoutRecords(model, withChildren), draft: null }, fx];\n}\n","/**\n * Rich text run algebra — the pure operations an editor needs on a FreeText's\n * rich document (engine `RichTextDocumentInput`): flat offsets over the plain\n * projection, run splitting at a boundary, applying a style delta to a range,\n * and normalisation. No DOM, no engine: the editor binding (in `@embedpdf/web`)\n * maps DOM selections to these offsets and renders the result; the plugin\n * applies these functions and commits.\n *\n * Offsets are positions in the plain projection: paragraphs joined by `\\r`,\n * runs concatenated. Every character counts one, including the `\\r` a run\n * carries as a hard break and the `\\r` that separates two paragraphs.\n */\nimport {\n faceForFreeTextFont,\n type Annotation,\n type FaceRequest,\n type FontHandle,\n type RichTextBody,\n type RichTextDocument,\n type RichTextDocumentInput,\n type RichTextParagraph,\n type RichTextRun,\n type RichTextRunStyle,\n} from '@embedpdf/engine-core/runtime';\n\nimport { textOf } from './record/text';\nimport type { TextStyle } from './types';\n\nexport type RichTextStyleDelta = Partial<RichTextRunStyle>;\n\n/** A range of the plain projection, `start <= end`, end exclusive. */\nexport interface RichTextRange {\n start: number;\n end: number;\n}\n\n/** Length of the plain projection. */\nexport function richTextLength(doc: { paragraphs: readonly RichTextParagraph[] }): number {\n let length = 0;\n doc.paragraphs.forEach((paragraph, i) => {\n if (i > 0) length += 1;\n for (const run of paragraph.runs) length += run.text.length;\n });\n return length;\n}\n\nconst DELTA_KEYS: readonly (keyof RichTextRunStyle)[] = [\n 'family',\n 'weight',\n 'italic',\n 'size',\n 'color',\n 'decoration',\n 'script',\n 'letterSpacing',\n 'horizontalScale',\n 'unknown',\n];\n\nfunction sameDecoration(\n left: readonly string[] | undefined,\n right: readonly string[] | undefined,\n): boolean {\n if (left === right) return true;\n if (!left || !right || left.length !== right.length) return false;\n const sorted = (values: readonly string[]) => [...values].sort();\n const sa = sorted(left);\n const sb = sorted(right);\n return sa.every((value, i) => value === sb[i]);\n}\n\n/** Two deltas override the same properties with the same values. */\nexport function sameStyleDelta(\n left: RichTextStyleDelta | undefined,\n right: RichTextStyleDelta | undefined,\n): boolean {\n const da = left ?? {};\n const db = right ?? {};\n for (const key of DELTA_KEYS) {\n if (key === 'decoration') {\n if (!sameDecoration(da.decoration, db.decoration)) return false;\n } else if (da[key] !== db[key]) {\n return false;\n }\n }\n return true;\n}\n\n/** A delta with every `undefined` member removed; `undefined` when empty. */\nfunction cleanDelta(delta: RichTextStyleDelta | undefined): RichTextStyleDelta | undefined {\n if (!delta) return undefined;\n const out: RichTextStyleDelta = {};\n let any = false;\n for (const key of DELTA_KEYS) {\n const value = delta[key];\n if (value !== undefined) {\n (out as Record<string, unknown>)[key] = value;\n any = true;\n }\n }\n return any ? out : undefined;\n}\n\n/**\n * Merge adjacent runs whose deltas agree, drop empty runs, strip empty\n * deltas. A paragraph with no text keeps a single empty run so the editor\n * has somewhere to put the caret.\n */\nexport function normalizeRuns<T extends { paragraphs: RichTextParagraph[] }>(doc: T): T {\n const paragraphs = doc.paragraphs.map((paragraph) => {\n const runs: RichTextRun[] = [];\n for (const run of paragraph.runs) {\n if (run.text.length === 0) continue;\n const style = cleanDelta(run.style);\n const last = runs[runs.length - 1];\n if (last && sameStyleDelta(last.style, style)) {\n runs[runs.length - 1] = { ...last, text: last.text + run.text };\n } else {\n runs.push(style ? { text: run.text, style } : { text: run.text });\n }\n }\n if (runs.length === 0) runs.push({ text: '' });\n return { ...paragraph, runs };\n });\n return { ...doc, paragraphs };\n}\n\n/** Where a flat offset falls: paragraph index and offset within it (the\n * separator between paragraphs belongs to the end of the earlier one). */\nexport function locateOffset(\n doc: { paragraphs: readonly RichTextParagraph[] },\n offset: number,\n): { paragraph: number; offset: number } {\n let pos = 0;\n for (let i = 0; i < doc.paragraphs.length; i++) {\n const length = doc.paragraphs[i]!.runs.reduce((sum, run) => sum + run.text.length, 0);\n if (offset <= pos + length || i === doc.paragraphs.length - 1) {\n return { paragraph: i, offset: Math.max(0, Math.min(length, offset - pos)) };\n }\n pos += length + 1; // the paragraph separator\n }\n return { paragraph: 0, offset: 0 };\n}\n\n/** The paragraph with a run boundary guaranteed at a local offset. */\nexport function splitRunsAt(paragraph: RichTextParagraph, offset: number): RichTextParagraph {\n const runs: RichTextRun[] = [];\n let pos = 0;\n for (const run of paragraph.runs) {\n const end = pos + run.text.length;\n if (offset > pos && offset < end) {\n const cut = offset - pos;\n runs.push({ ...run, text: run.text.slice(0, cut) });\n runs.push({ ...run, text: run.text.slice(cut) });\n } else {\n runs.push(run);\n }\n pos = end;\n }\n return { ...paragraph, runs };\n}\n\n/**\n * Apply a style delta to every character of a range: the runs it touches are\n * split at its boundaries, the covered pieces take the delta on top of what\n * they already override (`clear` names properties to stop overriding, so\n * they follow the body again), and the result is normalised. An empty range\n * is a no-op.\n */\nexport function applyStyleToRange<T extends { paragraphs: RichTextParagraph[] }>(\n doc: T,\n range: RichTextRange,\n delta: RichTextStyleDelta,\n clear: readonly (keyof RichTextRunStyle)[] = [],\n): T {\n const start = Math.max(0, Math.min(range.start, range.end));\n const end = Math.max(range.start, range.end);\n if (end <= start) return doc;\n const from = locateOffset(doc, start);\n const to = locateOffset(doc, end);\n const paragraphs = doc.paragraphs.map((paragraph, index) => {\n if (index < from.paragraph || index > to.paragraph) return paragraph;\n const localStart = index === from.paragraph ? from.offset : 0;\n const localEnd =\n index === to.paragraph\n ? to.offset\n : paragraph.runs.reduce((sum, run) => sum + run.text.length, 0);\n if (localEnd <= localStart) return paragraph;\n const split = splitRunsAt(splitRunsAt(paragraph, localStart), localEnd);\n let pos = 0;\n const runs = split.runs.map((run) => {\n const runStart = pos;\n pos += run.text.length;\n if (runStart < localStart || runStart >= localEnd || run.text.length === 0) return run;\n const style: RichTextStyleDelta = { ...(run.style ?? {}), ...delta };\n for (const key of clear) delete (style as Record<string, unknown>)[key];\n return { ...run, style };\n });\n return { ...split, runs };\n });\n return normalizeRuns({ ...doc, paragraphs });\n}\n\n/**\n * The delta in force at a caret: the run the offset falls in, or, at a run\n * boundary, the run before it (what typing there would inherit). Undefined\n * for an empty document.\n */\nexport function styleAt(\n doc: { paragraphs: readonly RichTextParagraph[] },\n offset: number,\n): RichTextStyleDelta | undefined {\n const at = locateOffset(doc, offset);\n const paragraph = doc.paragraphs[at.paragraph];\n if (!paragraph) return undefined;\n let pos = 0;\n let previous: RichTextRun | undefined;\n for (const run of paragraph.runs) {\n const end = pos + run.text.length;\n if (at.offset > pos && at.offset <= end) return run.style ?? {};\n if (at.offset === pos && pos === 0) return run.style ?? {};\n previous = run;\n pos = end;\n }\n return previous?.style ?? {};\n}\n\n/** Every run overlapping the range satisfies `predicate` (an empty range\n * tests the caret's style). */\nexport function rangeHasStyle(\n doc: { paragraphs: readonly RichTextParagraph[] },\n range: RichTextRange,\n predicate: (delta: RichTextStyleDelta) => boolean,\n): boolean {\n const start = Math.min(range.start, range.end);\n const end = Math.max(range.start, range.end);\n if (end <= start) return predicate(styleAt(doc, start) ?? {});\n const from = locateOffset(doc, start);\n const to = locateOffset(doc, end);\n let any = false;\n for (let index = from.paragraph; index <= to.paragraph; index++) {\n const paragraph = doc.paragraphs[index]!;\n const localStart = index === from.paragraph ? from.offset : 0;\n const localEnd =\n index === to.paragraph\n ? to.offset\n : paragraph.runs.reduce((sum, run) => sum + run.text.length, 0);\n let pos = 0;\n for (const run of paragraph.runs) {\n const runEnd = pos + run.text.length;\n if (runEnd > localStart && pos < localEnd && run.text.length > 0) {\n any = true;\n if (!predicate(run.style ?? {})) return false;\n }\n pos = runEnd;\n }\n }\n return any;\n}\n\n/** Plain paragraphs from text: one per line break, one unstyled run each. */\nexport function paragraphsFromPlainText(text: string): RichTextParagraph[] {\n return text.split(/\\r\\n|\\r|\\n/).map((line) => ({ runs: [{ text: line }] }));\n}\n\n/** The plain projection: paragraphs joined by `\\r`, runs concatenated. */\nexport function plainTextOf(doc: { paragraphs: readonly RichTextParagraph[] }): string {\n return doc.paragraphs\n .map((paragraph) => paragraph.runs.map((run) => run.text).join(''))\n .join('\\r');\n}\n\n/** True when nothing in the document overrides the body: no run delta, no\n * paragraph property. Such a document commits as plain `contents`. */\nexport function isPlainRichText(doc: RichTextDocumentInput): boolean {\n if (doc.body && Object.keys(doc.body).length > 0) return false;\n return doc.paragraphs.every(\n (paragraph) =>\n paragraph.align === undefined &&\n paragraph.dir === undefined &&\n paragraph.lineHeight === undefined &&\n paragraph.margins === undefined &&\n paragraph.textIndent === undefined &&\n paragraph.unknown === undefined &&\n paragraph.runs.every((run) => cleanDelta(run.style) === undefined),\n );\n}\n\n/* ── a free text's document ──────────────────────────────────────────────── */\n\n/** The registered fonts an engine knows (the local engine's `fonts.list()`;\n * none on the cloud engine). */\nexport type FontLookup = () => readonly FontHandle[];\n\n/** The face a DTO font names: a standard font's family, weight and italic, a\n * registered key's identity, else the string itself as a family. */\nexport const faceForFont = (font: string, fonts?: FontLookup): FaceRequest =>\n faceForFreeTextFont(font, fonts && ((key) => fonts().find((handle) => handle.key === key)));\n\nconst hex = (css: string): string => css.trim().toUpperCase();\n\n/** The rich body the `/DA` text style describes (a draft's body before its\n * DTO exists; also the fallback for a DTO without `richText`). */\nexport function bodyFromTextStyle(style: TextStyle, fonts?: FontLookup): RichTextBody {\n const face = faceForFont(style.fontFamily, fonts);\n return {\n family: face.family,\n weight: style.bold ? 700 : (face.weight ?? 400),\n italic: style.italic ?? face.italic ?? false,\n size: style.fontSize,\n color: hex(style.fontColor),\n decoration: style.underline ? ['underline'] : [],\n script: 'normal',\n letterSpacing: 0,\n horizontalScale: 1,\n align: style.textAlign,\n dir: 'ltr',\n };\n}\n\n/** The annotation's rich document: a free text's own, else one made from\n * its plain text and how its text is set. */\nexport function richDocOf(annotation: Annotation, fonts?: FontLookup): RichTextDocument {\n if (annotation.subtype === 'free-text' && annotation.richText) return annotation.richText;\n const style: TextStyle = textOf(annotation) ?? {\n fontFamily: 'helvetica',\n fontSize: 12,\n fontColor: '#000000',\n textAlign: 'left',\n };\n return {\n body: bodyFromTextStyle(style, fonts),\n paragraphs: paragraphsFromPlainText(annotation.contents ?? ''),\n };\n}\n","/**\n * Free-text typing: the editor's plain or rich result becomes the record's\n * text at once, and a `text` effect asks for the (debounced) engine write.\n */\nimport type { RichTextDocumentInput } from '@embedpdf/engine-core/runtime';\n\nimport { normalizeRuns, paragraphsFromPlainText, plainTextOf } from '../richtext';\nimport type { Effect, Id, Model } from '../types';\n\n/** Apply the editor's plain text. Updates `contents` on the record's\n * annotation and flips the box to `vector` so the live text shows. The `text`\n * effect asks for the write; the plugin waits for a pause in typing before it runs. */\nexport function setText(model: Model, id: Id, text: string): [Model, Effect[]] {\n const record = model.byId[id];\n if (!record) return [model, []];\n // The rich projection follows plain text: body-style paragraphs, one per\n // line break, so an editor rendering `richText` shows what was typed; and\n // `contents` is their plain projection, as the engine reads it back.\n const paragraphs = paragraphsFromPlainText(text);\n const annotation =\n record.annotation.subtype === 'free-text'\n ? {\n ...record.annotation,\n contents: plainTextOf({ paragraphs }),\n richText: { ...record.annotation.richText, paragraphs },\n }\n : { ...record.annotation, contents: text };\n return [\n { ...model, byId: { ...model.byId, [id]: { ...record, annotation } } },\n [{ type: 'text', id }],\n ];\n}\n\n/** Apply the editor's rich document, like `setText`. The annotation's body is\n * kept (a partial input body layers on it); `contents` is the projection. */\nexport function setRichText(model: Model, id: Id, doc: RichTextDocumentInput): [Model, Effect[]] {\n const record = model.byId[id];\n if (!record || record.annotation.subtype !== 'free-text') return [model, []];\n const normalized = normalizeRuns(doc);\n const richText = {\n body: { ...record.annotation.richText.body, ...(normalized.body ?? {}) },\n paragraphs: normalized.paragraphs,\n };\n const next = {\n ...record,\n annotation: { ...record.annotation, richText, contents: plainTextOf(richText) },\n };\n return [{ ...model, byId: { ...model.byId, [id]: next } }, [{ type: 'text', id }]];\n}\n","/**\n * Annotations over selected text: highlight, underline, squiggly and strikeout\n * from the text's quads, carets at a text position, and replace-text (a caret\n * grouped with a strikeout). Also the live preview while the text is selected.\n */\nimport type { AnnotationFlags, PageRef } from '@embedpdf/engine-core/runtime';\n\nimport { geomBounds } from '../geometry';\nimport { styleOf } from '../record';\nimport { caretFromAnchor } from '../shapes/caret';\nimport type { QuadsShape } from '../shapes/quads';\nimport type { Effect, Model, KindName, TextEndAnchor, Quad } from '../types';\nimport { draftOf, newRecord, numbersLeft } from './changes';\nimport { defaultsFor, toolAnnotation } from './session';\n\n/** Drop degenerate segment quads (zero-length baseline or ink extent). Area is\n * the cross product of the two edge vectors — orientation-safe. */\nconst usableQuads = (quads: Quad[]): Quad[] =>\n quads.filter((quad) => {\n const ux = quad.upperRight.x - quad.upperLeft.x;\n const uy = quad.upperRight.y - quad.upperLeft.y;\n const sx = quad.lowerLeft.x - quad.upperLeft.x;\n const sy = quad.lowerLeft.y - quad.upperLeft.y;\n return Math.abs(ux * sy - uy * sx) > 0;\n });\n\n/**\n * Build a text-markup annotation from the selection's per-line rects. The new\n * annotation is `vector` (rendered live by the overlay) and selected, mirroring\n * `createPointer`. One call per page the selection spans. Clears any live preview.\n */\nexport function createMarkup(\n model: Model,\n subtype: KindName,\n page: PageRef,\n segmentQuads: Quad[],\n preset: string = subtype,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const quads = usableQuads(segmentQuads);\n if (!quads.length) return [model, []];\n const shape: QuadsShape = { kind: 'quads', quadPoints: quads };\n // A text redaction states the box around its quads: the engine asks for it.\n const fields = subtype === 'redact' ? { rect: geomBounds(shape) } : {};\n const created = newRecord(\n model,\n page,\n draftOf(subtype, defaultsFor(model, preset), shape, fields, flags),\n );\n const id = created.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n preview: null,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n\n/**\n * Create Adobe-compatible Replace Text as one logical annotation: a top-level\n * Caret (`/IT /Replace`) plus a StrikeOut subordinate (`/IT /StrikeOutTextEdit`,\n * `/IRT` caret, `/RT /Group`). Two creates, the caret first: the strikeout\n * names the caret by the object number it takes, so one change writes both.\n */\nexport function createReplaceText(\n model: Model,\n page: PageRef,\n segmentQuads: Quad[],\n anchor: TextEndAnchor,\n preset = 'replace-text',\n): [Model, Effect[]] {\n const quads = usableQuads(segmentQuads);\n if (!quads.length) return [model, []];\n // The caret takes the strikeout tool's colour, so the pair reads as one mark.\n const strikeStyle = styleOf(toolAnnotation(model, 'strikeout', preset));\n const caret = newRecord(\n model,\n page,\n draftOf('caret', {}, caretFromAnchor(anchor), {\n color: strikeStyle.color,\n opacity: strikeStyle.opacity,\n intent: 'replace',\n }),\n );\n const primaryId = caret.record.id;\n const strikeout = newRecord(\n model,\n page,\n draftOf(\n 'strikeout',\n defaultsFor(model, preset),\n { kind: 'quads', quadPoints: quads },\n { intent: 'strikeout-text-edit' },\n ),\n { offset: 2, reply: { to: caret.record.annotation.ref, type: 'group' } },\n );\n const strikeoutId = strikeout.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 2),\n byId: { ...model.byId, [primaryId]: caret.record, [strikeoutId]: strikeout.record },\n order: [...model.order, primaryId, strikeoutId],\n selected: [primaryId, strikeoutId],\n draft: null,\n preview: null,\n },\n [\n { type: 'create', id: primaryId, draft: caret.draft },\n { type: 'create', id: strikeoutId, draft: strikeout.draft },\n ],\n ];\n}\n\nexport function createCaret(\n model: Model,\n page: PageRef,\n anchor: TextEndAnchor,\n flags?: Partial<AnnotationFlags>,\n): [Model, Effect[]] {\n const caretGeom = caretFromAnchor(anchor);\n if (caretGeom.box.width <= 0 || caretGeom.box.height <= 0) return [model, []];\n const created = newRecord(\n model,\n page,\n draftOf('caret', defaultsFor(model, 'caret'), caretGeom, {}, flags),\n );\n const id = created.record.id;\n return [\n {\n ...model,\n objectNumbers: numbersLeft(model, 1),\n byId: { ...model.byId, [id]: created.record },\n order: [...model.order, id],\n selected: [id],\n draft: null,\n preview: null,\n },\n [{ type: 'create', id, draft: created.draft }],\n ];\n}\n\n/** Set / replace the live markup preview from the selection's per-page quads. */\nexport function setMarkupPreview(\n model: Model,\n subtype: KindName,\n quadsByPage: Record<number, Quad[]>,\n preset: string = subtype,\n): [Model, Effect[]] {\n const byPage: Record<number, Quad[]> = {};\n for (const key in quadsByPage) {\n const quads = usableQuads(quadsByPage[key]);\n if (quads.length) byPage[Number(key)] = quads;\n }\n return [{ ...model, preview: { subtype, preset, byPage } }, []];\n}\n","/**\n * The pure annotation core: `update(model, message)` returns the next session,\n * the records the message changed, and the engine work to do.\n *\n * The core never stores a record. A transition computes a next model from the\n * one it was given; `update` keeps the session and reports the records that\n * differ as a change set, which the plugin shows until the engine confirms it.\n *\n * Where each message is handled:\n *\n * edit.ts, edit-commit.ts pointer editing of existing annotations\n * marquee.ts rubber-band selection\n * draw*.ts pointer drawing of new annotations\n * text-markup.ts markup, carets and replace-text over selected text\n * selection-edits.ts toolbar edits of the whole selection\n * text.ts free-text typing\n * session.ts the session itself: defaults, forget\n */\nimport { isContentsEditableByHand } from '../editable';\nimport { expandGroups } from '../group';\nimport { isSelectable } from '../hit';\nimport { annotationPatchBetween, type AnnotationPatch } from '@embedpdf/engine-core/runtime';\n\nimport { applyChange } from '../appearance';\n\nimport type {\n ChangeSet,\n Effect,\n Id,\n Message,\n Model,\n ModelAnnotation,\n Session,\n UpdateResult,\n} from '../types';\nimport { createPointer, finishInkCreate, finishPolyCreate } from './draw';\nimport { editPointer } from './edit';\nimport { marqueePointer } from './marquee';\nimport {\n deleteSelection,\n resetRotation,\n rotateSelection,\n setFields,\n setFlags,\n setLink,\n setTextFormat,\n} from './selection-edits';\nimport { forget, initialSession, setDefaults } from './session';\nimport { setRichText, setText } from './text';\nimport { createCaret, createMarkup, createReplaceText, setMarkupPreview } from './text-markup';\n\n/** The model before any record or gesture: an empty view over the initial session. */\nexport const initialModel: Model = { ...initialSession, byId: {}, order: [] };\n\n/**\n * Run one message. The session is returned whole; the records are returned\n * as the difference the message made, so the caller decides where they live.\n */\nexport function update(model: Model, message: Message): UpdateResult {\n const [next, effects] = transition(model, message);\n const change = changeBetween(model, next);\n return { session: sessionOf(next), change, effects: [...effects, ...writesOf(change, effects)] };\n}\n\n/**\n * The most records `message` can create: how many object numbers the session\n * must hold before it runs (`Session.objectNumbers`). A pointer press or\n * release of a creating tool can finish a drawing; a move never does.\n */\nexport function newRecordsAtMost(message: Message): number {\n switch (message.type) {\n case 'createReplaceText':\n return 2;\n case 'createPointer':\n return message.phase === 'move' ? 0 : 1;\n case 'finishInkDraft':\n case 'finishCreationDraft':\n case 'createCaret':\n case 'createMarkup':\n return 1;\n default:\n return 0;\n }\n}\n\n/**\n * A `patch` effect for each changed record the change set has a patch for:\n * the change is the write. Typed text is the exception; its `text` effect\n * writes it once typing pauses.\n */\nfunction writesOf(change: ChangeSet, effects: readonly Effect[]): Effect[] {\n const typed = new Set(effects.flatMap((effect) => (effect.type === 'text' ? [effect.id] : [])));\n return change.put.flatMap((record): Effect[] => {\n const patch = change.patches[record.id];\n return patch && !typed.has(record.id) ? [{ type: 'patch', id: record.id, patch }] : [];\n });\n}\n\n/** Every session field, checked by the compiler to be exactly the fields of `Session`. */\nconst SESSION_FIELDS = {\n selected: true,\n hovered: true,\n draft: true,\n preview: true,\n objectNumbers: true,\n defaults: true,\n hitMargin: true,\n editing: true,\n snap: true,\n editable: true,\n} satisfies Record<keyof Session, true>;\n\nconst SESSION_KEYS = Object.keys(SESSION_FIELDS) as (keyof Session)[];\n\nconst sessionOf = (model: Model): Session => ({\n selected: model.selected,\n hovered: model.hovered,\n draft: model.draft,\n preview: model.preview,\n objectNumbers: model.objectNumbers,\n defaults: model.defaults,\n hitMargin: model.hitMargin,\n editing: model.editing,\n snap: model.snap,\n editable: model.editable,\n});\n\n/** True when every session field is the same value: a message that changed nothing. */\nexport const sameSession = (left: Session, right: Session): boolean =>\n SESSION_KEYS.every((key) => Object.is(left[key], right[key]));\n\n/** The change set of a message that changed no record. */\nexport const EMPTY_CHANGE: ChangeSet = { put: [], drop: [], patches: {} };\n\n/**\n * The records a transition changed, each with the patch its change means (the\n * annotation fields it changed), its annotation brought up to date as the\n * engine will apply that patch, and drawn as the appearance rule says\n * (`applyChange`): a transition changes annotations, never how they are\n * drawn. A new record already carries the annotation its create writes. Cheap when\n * nothing changed: `byId` keeps its identity.\n */\nfunction changeBetween(before: Model, after: Model): ChangeSet {\n if (before.byId === after.byId) return EMPTY_CHANGE;\n const put: ModelAnnotation[] = [];\n const patches: Record<Id, AnnotationPatch> = {};\n for (const id of after.order) {\n const record = after.byId[id];\n const previous = before.byId[id];\n if (!record || record === previous) continue;\n if (!previous) {\n put.push(record);\n continue;\n }\n const fields = annotationPatchBetween(previous.annotation, record.annotation);\n if (!Object.keys(fields).length) continue;\n const patch = { ...fields, subtype: previous.annotation.subtype } as AnnotationPatch;\n patches[id] = patch;\n put.push(applyChange(previous, patch));\n }\n const drop = before.order.filter((id) => before.byId[id] && !after.byId[id]);\n return put.length || drop.length ? { put, drop, patches } : EMPTY_CHANGE;\n}\n\nfunction transition(model: Model, message: Message): [Model, Effect[]] {\n switch (message.type) {\n case 'editPointer':\n return editPointer(model, message.phase, message.in);\n case 'marqueePointer':\n return marqueePointer(model, message.phase, message.in);\n case 'createPointer':\n return createPointer(\n model,\n message.phase,\n message.subtype,\n message.in,\n message.preset,\n message.intent,\n message.deferInkCommit,\n message.straightenInk,\n message.clickCreate,\n message.flags,\n message.measure,\n message.capture,\n );\n case 'finishInkDraft':\n return finishInkCreate(model);\n case 'finishCreationDraft':\n return finishPolyCreate(model);\n case 'createCaret':\n return createCaret(model, message.page, message.anchor, message.flags);\n case 'createReplaceText':\n return createReplaceText(model, message.page, message.quads, message.anchor, message.preset);\n case 'createMarkup':\n return createMarkup(\n model,\n message.subtype,\n message.page,\n message.quads,\n message.preset,\n message.flags,\n );\n case 'setMarkupPreview':\n return setMarkupPreview(model, message.subtype, message.quadsByPage, message.preset);\n case 'clearMarkupPreview':\n return model.preview ? [{ ...model, preview: null }, []] : [model, []];\n case 'select': {\n const ids = expandGroups(\n model,\n message.ids.filter((id) => isSelectable(model, id)),\n );\n if (!ids.length) return [model, []];\n const selected = message.add ? [...new Set([...model.selected, ...ids])] : ids;\n return [{ ...model, selected }, []];\n }\n case 'deselect': {\n if (!model.selected.length) return [model, []];\n // With `ids`: drop only those (an engaged Behavior retroactively un-selects\n // its annotations — engaged ⇒ not selectable ⇒ not selected). Without: all.\n if (!message.ids) return [{ ...model, selected: [] }, []];\n const drop = new Set(message.ids);\n const selected = model.selected.filter((id) => !drop.has(id));\n return selected.length === model.selected.length ? [model, []] : [{ ...model, selected }, []];\n }\n case 'setFields':\n return setFields(model, message.patches);\n case 'setTextFormat':\n return setTextFormat(model, message.format, message.on);\n case 'setLink':\n return setLink(model, message.target);\n case 'setFlags':\n return setFlags(model, message.patch, message.ids);\n case 'setDefaults':\n return setDefaults(model, message.preset, message.patch);\n case 'setSnap':\n return [{ ...model, snap: { ...model.snap, ...message.patch } }, []];\n case 'rotateSelection':\n return rotateSelection(model, message.degrees);\n case 'resetRotation':\n return resetRotation(model);\n case 'delete':\n return deleteSelection(model);\n case 'cancel':\n return [{ ...model, draft: null }, []];\n case 'forget':\n return [forget(model, message.ids), []];\n case 'hover':\n // Pure view-model state; the capability diffs before dispatching, so\n // this fires at enter/leave cadence only.\n return model.hovered === message.id ? [model, []] : [{ ...model, hovered: message.id }, []];\n case 'beginTextEdit':\n // `lockedContents` (or an inert `/F` state) blocks entering text edit, and\n // so does the `editable` rule; the geometry gates don't apply here:\n // locked-only contents still edit.\n return model.byId[message.id] && isContentsEditableByHand(model, model.byId[message.id]!)\n ? [{ ...model, editing: message.id, selected: [message.id], draft: null }, []]\n : [model, []];\n case 'setText':\n return setText(model, message.id, message.text);\n case 'setRichText':\n return setRichText(model, message.id, message.doc);\n case 'endTextEdit':\n return model.editing ? [{ ...model, editing: null }, []] : [model, []];\n }\n}\n\nexport { initialSession, defaultsFor, lineEndingsOf, toolAnnotation } from './session';\nexport { rotateDraftDelta } from './edit';\nexport { draftPlacement } from './draw';\nexport { annotsInBox, selectionInBox } from './marquee';\nexport { calloutBox, calloutUprightRot } from './draw-callout';\n","/**\n * Where a render item draws. Its frame is the box a painter draws into,\n * placed and turned on the page like the annotation; everything the item\n * draws sits upright inside it: its scene, a custom look, or the engine's\n * raster at its own box and turn. Every item carries both, so a framework\n * layer paints from data and decides no placement of its own.\n */\nimport { normalizeDeg, rectCenter, rotatePoint } from './rect';\nimport type { Rect, RenderItem, Shape } from './types';\n\n/** A box and its turn, degrees clockwise about the box's middle. */\ntype TurnedBox = { box: Rect; rotation: number };\n\n/**\n * The frame's turn: the annotation's own turn for every shape that is a turned\n * box (a box, a caret, a text box without a callout). A callout and the vertex\n * kinds carry their turn in their points, so their frame stays upright.\n */\nfunction frameRotationOf(geometry: Shape, rot: number | undefined): number {\n const turnedBox =\n geometry.kind === 'box' ||\n geometry.kind === 'caret' ||\n (geometry.kind === 'text-box' && !geometry.calloutLine);\n return turnedBox ? normalizeDeg(rot ?? 0) : 0;\n}\n\n/**\n * Where a raster sits inside a frame: its box relative to the frame's\n * top-left before the frame's turn, and its own turn about its middle. Drawn\n * inside the frame, it lands exactly where the raster lands on its own\n * (`raster` turned by `rotation`).\n */\nexport function rasterInFrame(frame: TurnedBox, raster: Rect, rotation: number): TurnedBox {\n const middle = rotatePoint(rectCenter(raster), rectCenter(frame.box), -frame.rotation);\n return {\n box: {\n x: middle.x - raster.width / 2 - frame.box.x,\n y: middle.y - raster.height / 2 - frame.box.y,\n width: raster.width,\n height: raster.height,\n },\n rotation: normalizeDeg(rotation - frame.rotation),\n };\n}\n\n/**\n * The item with where it draws: its frame, and the engine's raster inside it.\n * `scale` is how large the page draws the item relative to its own size: below\n * 1 only for a body that keeps its size on screen (`anchoredScale`).\n */\nexport function placed(item: Omit<RenderItem, 'frame' | 'raster'>, scale = 1): RenderItem {\n const frame = { box: item.box, rotation: frameRotationOf(item.geometry, item.rot), scale };\n return {\n ...item,\n frame,\n raster: item.apBox ? rasterInFrame(frame, item.apBox, item.apRot ?? 0) : null,\n };\n}\n","import type { Annotation, PageRef } from '@embedpdf/engine-core/runtime';\nimport { rasterPlacement, sourceDuring } from './appearance';\nimport { annotationSelectionFrame } from './selection';\n/**\n * Pure view selectors. `pageItems` is the per-annotation render list (live gesture\n * applied) for customRenderer wrapping; `chrome` is the selection overlay\n * (handles carry their resize cursor, group box, marquee).\n */\nimport {\n distanceHandles,\n distanceLayout,\n measurementOf,\n type MeasurementAppearance,\n} from './measurement';\nimport {\n measurementLayout,\n moveMeasurementCaption,\n shapeMeasurementReadout,\n} from './measurement-shape';\nimport {\n chordThrough,\n geomHandles,\n geomRotateAbout,\n geomRotation,\n geomScaleAbout,\n geomTranslate,\n geomVisualBounds,\n groupResizeFactors,\n placeRotateKnob,\n rectHandlesFor,\n ROTATE_KNOB_OFFSET,\n} from './geometry';\nimport { MIN_SIZE, cursorOnScreen, rectFromPoints, rotatePoint, unionRect } from './rect';\nimport { placed } from './frame';\nimport { calloutShape } from './shapes/text-box';\nimport { groupCaps } from './group';\nimport { isSelectable, paintOrder } from './hit';\nimport { isTransformableByHand } from './editable';\nimport { viewable } from './flags';\nimport {\n anchoredGeom,\n anchoredScale,\n anchoredStrokeWidth,\n anchorModeOf,\n type ViewEnv,\n} from './anchor';\nimport { blendFor } from './kinds/styles';\nimport { isDrag, placedShape } from './placement';\nimport {\n calloutBox,\n calloutUprightRot,\n draftPlacement,\n lineEndingsOf,\n rotateDraftDelta,\n toolAnnotation,\n} from './update';\nimport type {\n ChromeNode,\n HandleRole,\n Shape,\n Id,\n Model,\n Rect,\n RenderItem,\n Style,\n Point,\n} from './types';\nimport type { CreationDraftAnchor, RotationAnchor } from './types';\nimport { kindOf, refOf, shapeOf, styleOf, textOf } from './record';\n\nconst DRAFT_ID = '__draft__';\nconst PREVIEW_ID = '__markup_preview__';\n\nconst polyPreviewPoints = (points: Point[], current: Point): Point[] => {\n const last = points[points.length - 1];\n return last && (current.x !== last.x || current.y !== last.y) ? [...points, current] : points;\n};\n\n/** A redaction's overlay text: the label its hover preview draws. */\nconst redactionLabelOf = (annotation: Annotation): Pick<RenderItem, 'label'> =>\n annotation.subtype === 'redact' && annotation.overlayText\n ? { label: { text: annotation.overlayText, repeat: annotation.repeat } }\n : {};\n\n/** A note's or file attachment's icon: what its live drawing draws. */\nexport const iconOf = (annotation: Annotation): Pick<RenderItem, 'icon'> =>\n (annotation.subtype === 'text' || annotation.subtype === 'file-attachment') && annotation.icon\n ? { icon: annotation.icon }\n : {};\n\nfunction effMeasure(model: Model, id: Id) {\n const record = model.byId[id];\n const draft = model.draft;\n const measure = measurementOf(record.annotation);\n\n if (!measure || !draft) {\n return measure;\n }\n\n if (draft.kind === 'caption' && draft.id === id) {\n const geometry = shapeOf(record.annotation);\n const style = styleOf(record.annotation);\n return moveMeasurementCaption(geometry, measure, draft.delta, style).measure;\n }\n\n if (draft.kind === 'leader' && draft.id === id && measure.intent === 'line-dimension') {\n return {\n ...measure,\n leader: {\n ...measure.leader,\n length: (measure.leader?.length ?? 0) + draft.delta,\n },\n };\n }\n\n return measure;\n}\n\n/**\n * The gesture-effective geometry, in view space: Project first (screen-\n * anchored bodies to their effective footprint — the identity for everyone\n * else), then apply the live gesture. Gestures compose in view space: the\n * pointer, the drafts' pivots/boxes, and a `handle` draft's geometry all live\n * there already, so one code path serves flagged and unflagged annotations —\n * and the commit (`editUp`) maps the same composition back through\n * `unanchoredGeom`, so preview ≡ commit by construction. The geometry every\n * selector below hands out, so render/chrome/bounds agree with hit.\n */\nfunction effGeom(model: Model, id: Id, view: ViewEnv | undefined): Shape {\n const record = model.byId[id];\n const geometry = anchoredGeom(shapeOf(record.annotation), anchorModeOf(record), view);\n const draft = model.draft;\n if (draft) {\n if (draft.kind === 'move' && draft.ids.includes(id))\n return geomTranslate(geometry, draft.delta);\n if (draft.kind === 'handle' && draft.id === id) return draft.current; // already view space\n if (draft.kind === 'caption' && draft.id === id) {\n // A perimeter's or area's caption center is its shape's.\n const style = styleOf(record.annotation);\n const measure = measurementOf(record.annotation);\n return measure\n ? moveMeasurementCaption(geometry, measure, draft.delta, style).geometry\n : geometry;\n }\n if (draft.kind === 'rotate' && draft.ids.includes(id)) {\n // The same snapped angle rule the commit uses (see `rotateDraftDelta`).\n return geomRotateAbout(geometry, draft.pivot, rotateDraftDelta(model, draft).delta);\n }\n if (draft.kind === 'group' && draft.ids.includes(id)) {\n const { sx, sy } = groupResizeFactors(draft.base, draft.current);\n return geomScaleAbout(geometry, draft.anchor, sx, sy, MIN_SIZE);\n }\n }\n return geometry;\n}\n\n/** Style with the stroke width an anchored vector body renders at (screen-\n * constant line weight); everyone else keeps their style verbatim. */\nfunction effStyle(annotation: Annotation, view: ViewEnv | undefined): Style {\n const mode = anchorModeOf({ annotation });\n const style = styleOf(annotation);\n if (!mode?.zoom || !view) return style;\n return { ...style, strokeWidth: anchoredStrokeWidth(style.strokeWidth, mode, view) };\n}\n\n/**\n * How an annotation not made yet paints, drawn as it will be once made: a\n * drawing in progress (`draft`) or the tool's ghost (`ghost`, what a click\n * would place). `annotation` is what the tool creates, its defaults and\n * flags; `shape` is where it goes, as the made one will store it, so a\n * screen-anchored icon shows at its size on screen, as a made one does.\n */\nexport function unmadeItem(\n id: Id,\n annotation: Annotation,\n shape: Shape,\n source: 'draft' | 'ghost',\n view?: ViewEnv,\n measure?: MeasurementAppearance,\n): RenderItem {\n const geometry = anchoredGeom(shape, anchorModeOf({ annotation }), view);\n const style = effStyle(annotation, view);\n const distance = measure && measurementLayout(geometry, measure, style);\n const text = textOf(annotation);\n return placed(\n {\n id,\n ref: null,\n subtype: kindOf(annotation).name,\n geometry,\n box: distance?.visualBounds ?? geomVisualBounds(geometry, style),\n style,\n ...(text ? { text } : {}),\n ...iconOf(annotation),\n ...redactionLabelOf(annotation),\n ...(measure ? { measure } : {}),\n source,\n selected: false,\n rot: geomRotation(geometry),\n blend: blendFor(style),\n },\n anchoredScale(anchorModeOf({ annotation }), view),\n );\n}\n\n/** `paint(box)`, made the first time it's asked for and kept. */\nfunction once<Result>(paint: (box: Rect) => Result, box: Rect): () => Result {\n let made: { readonly result: Result } | null = null;\n return () => (made ??= { result: paint(box) }).result;\n}\n\n/** A free-text box renders as a live element (editable / reflowing) while it's\n * being edited or while its source is vector (a resize, in-progress or committed);\n * otherwise it renders as the engine's baked /AP image, exactly like a shape. */\nfunction textIsLive(model: Model, id: Id): boolean {\n return model.editing === id || sourceDuring(model, id) === 'vector';\n}\n\nexport function pageItems(model: Model, page: PageRef, view?: ViewEnv): RenderItem[] {\n const pageObjectNumber = page.objectNumber;\n const items: RenderItem[] = [];\n // `paintOrder` puts text-layer markups beneath every other kind (back→front),\n // so a highlight drawn after a circle still paints under it — and culls what\n // `/F` hides. The same order hit-testing uses, so what you click matches\n // what you see.\n for (const id of paintOrder(model, page)) {\n const record = model.byId[id];\n const text = textOf(record.annotation);\n // Free text stays in the render list in every state, like a shape: a baked,\n // idle box renders as its engine /AP image; a live one (editing / resizing /\n // restyled) renders its box — fill + border, and a callout's leader — via\n // the vector scene, while only its text is the framework's editable element\n // (see `textBoxes`). Dropping the live plain box here would lose its border\n // and background the moment it is touched.\n const geometry = effGeom(model, id, view);\n const style = effStyle(record.annotation, view);\n // Where the baked raster is drawn (appearance.ts): a stamp's where its\n // shape is, everyone else's at its raster box, carried along by a move.\n const ap = rasterPlacement(model, id, view, geometry);\n const measure = effMeasure(model, id);\n const distance = measure && measurementLayout(geometry, measure, style);\n const box = distance?.visualBounds ?? geomVisualBounds(geometry, style);\n items.push(\n placed(\n {\n id,\n ref: refOf(record),\n annotation: record.annotation,\n subtype: kindOf(record.annotation).name,\n geometry,\n box,\n apBox: ap.box,\n style,\n ...(text ? { text } : {}),\n ...iconOf(record.annotation),\n ...redactionLabelOf(record.annotation),\n measure,\n source: sourceDuring(model, id),\n pictureVersion: record.pictureVersion ?? 0,\n // A lent record's lender draws it where it is now, a gesture included.\n ...(record.painter ? { lentScene: once(record.painter, box) } : {}),\n selected: model.selected.includes(id),\n ...(model.hovered === id ? { hovered: true } : {}),\n rot: geomRotation(geometry),\n ...(ap.rot ? { apRot: ap.rot } : {}),\n blend: blendFor(style),\n },\n anchoredScale(anchorModeOf(record), view),\n ),\n );\n }\n const draft = model.draft;\n // A box or a line being drawn shows what releasing it makes, once it is a\n // drag. Until then the release is a click: the tool's ghost shows that.\n if (\n (draft?.kind === 'create-rect' || draft?.kind === 'create-line') &&\n draft.page.objectNumber === pageObjectNumber &&\n isDrag(draft.kind === 'create-line' ? 'segment' : 'box', draft.from, draft.to)\n ) {\n const placement = draftPlacement(draft);\n const tool = { ...toolAnnotation(model, draft.subtype, draft.preset), ...draft.flags };\n const shape = placement && placedShape(tool, placement);\n if (shape) {\n const measure = draft.kind === 'create-line' ? draft.measure : undefined;\n items.push(unmadeItem(DRAFT_ID, tool, shape, 'draft', view, measure));\n }\n }\n if (\n (draft?.kind === 'create-distance' ||\n draft?.kind === 'create-poly' ||\n draft?.kind === 'create-ink') &&\n draft.page.objectNumber === pageObjectNumber\n ) {\n // Preview with the tool's resolved defaults (base + per-subtype override), so the\n // drawing is a faithful WYSIWYG of what will commit — not the bare base style.\n const tool = toolAnnotation(model, draft.subtype, draft.preset);\n const style = { ...styleOf(tool) };\n if (draft.kind === 'create-distance' && style.interiorColor == null) {\n style.interiorColor = style.color;\n }\n const geometry: Shape =\n draft.kind === 'create-distance'\n ? {\n kind: 'line',\n linePoints: { start: draft.from, end: draft.to },\n lineEndings: lineEndingsOf(tool),\n rotation: 0,\n }\n : draft.kind === 'create-poly'\n ? {\n kind: 'poly',\n vertices: polyPreviewPoints(draft.points, draft.current),\n closed: draft.closed,\n lineEndings: draft.closed ? undefined : lineEndingsOf(tool),\n rotation: 0,\n }\n : { kind: 'ink', inkList: draft.strokes, rotation: 0 };\n const measure =\n draft.kind === 'create-distance' || draft.kind === 'create-poly' ? draft.measure : undefined;\n const distance = measure && measurementLayout(geometry, measure, style);\n items.push(\n placed({\n id: DRAFT_ID,\n ref: null,\n measure,\n subtype: draft.subtype,\n geometry,\n box: distance?.visualBounds ?? geomVisualBounds(geometry, style),\n style,\n source: 'draft',\n selected: false,\n }),\n );\n }\n // Callout creation drawing: the in-progress leader (tip → cur, then tip → knee →\n // box) and the text-box preview, painted through the same vector scene.\n if (draft?.kind === 'create-callout' && draft.page.objectNumber === pageObjectNumber) {\n const tool = toolAnnotation(model, draft.subtype, draft.preset);\n const style = styleOf(tool);\n const toolEnding = tool.subtype === 'free-text' ? tool.lineEnding : null;\n const ending = toolEnding && toolEnding !== 'none' ? toolEnding : 'open-arrow';\n // The box preview carries the same upright rot the commit will apply, so\n // the ghost box (and its leader connection) is what you actually get.\n const rot = calloutUprightRot(draft);\n const geometry: Shape =\n draft.step === 'knee'\n ? {\n kind: 'line',\n linePoints: { start: draft.tip, end: draft.current },\n lineEndings: { start: ending, end: 'none' },\n rotation: 0,\n }\n : calloutShape(calloutBox(draft), rot, draft.tip, draft.knee, ending);\n items.push(\n placed({\n id: DRAFT_ID,\n ref: null,\n subtype: draft.subtype,\n geometry,\n box: geomVisualBounds(geometry, style),\n style,\n source: 'draft',\n selected: false,\n }),\n );\n }\n // Live text-markup preview: the in-progress selection rendered as the markup it\n // will become (same `scene()` paint as the committed annotation).\n const quads = model.preview?.byPage[pageObjectNumber];\n if (model.preview && quads?.length) {\n const geometry: Shape = { kind: 'quads', quadPoints: quads };\n items.push(\n placed({\n id: PREVIEW_ID,\n ref: null,\n subtype: model.preview.subtype,\n geometry,\n box: geomVisualBounds(geometry, { strokeWidth: 0 }),\n style: styleOf(toolAnnotation(model, model.preview.subtype, model.preview.preset)),\n source: 'draft',\n selected: false,\n }),\n );\n }\n return items;\n}\n\n/** One free-text box, geometry only (the live move/resize gesture applied), with\n * its edit flag. The framework renders an editable element here; the plugin\n * layers the DTO-derived text style on top. */\nexport interface TextBox {\n id: Id;\n box: Rect;\n editing: boolean;\n /** Applied rotation (deg, CW). `box` is the unrotated text box; the framework\n * rotates the editable element about its centre by this. 0/undefined = none. */\n rot?: number;\n}\n\n/** The free-text boxes on a page — the text counterpart of `pageItems`. */\nexport function textBoxes(model: Model, page: PageRef, view?: ViewEnv): TextBox[] {\n const pageObjectNumber = page.objectNumber;\n const out: TextBox[] = [];\n for (const id of model.order) {\n const record = model.byId[id];\n if (\n record.annotation.page.objectNumber !== pageObjectNumber ||\n shapeOf(record.annotation).kind !== 'text-box'\n )\n continue;\n if (!viewable(record.annotation, model.selected.includes(id))) continue; // `/F`-hidden\n if (!textIsLive(model, id)) continue; // baked → rendered as the /AP image instead\n const geometry = effGeom(model, id, view);\n if (geometry.kind !== 'text-box') continue;\n out.push({\n id,\n box: geometry.box,\n editing: model.editing === id,\n rot: geomRotation(geometry),\n });\n }\n return out;\n}\n\n/** The currently selected annotations as render items (live gesture applied) —\n * cross-page, for selection-aware toolbars (style + line-ending editing). */\nexport function selectedItems(model: Model, view?: ViewEnv): RenderItem[] {\n const items: RenderItem[] = [];\n for (const id of model.selected) {\n const record = model.byId[id];\n if (!record) continue;\n const geometry = effGeom(model, id, view);\n const style = effStyle(record.annotation, view);\n items.push(\n placed(\n {\n id,\n ref: refOf(record),\n annotation: record.annotation,\n subtype: kindOf(record.annotation).name,\n geometry,\n box: geomVisualBounds(geometry, style),\n style,\n source: record.source,\n selected: true,\n rot: geomRotation(geometry),\n },\n anchoredScale(anchorModeOf(record), view),\n ),\n );\n }\n return items;\n}\n\nconst boxCorners = (rect: Rect): [Point, Point, Point, Point] => [\n { x: rect.x, y: rect.y },\n { x: rect.x + rect.width, y: rect.y },\n { x: rect.x + rect.width, y: rect.y + rect.height },\n { x: rect.x, y: rect.y + rect.height },\n];\n\n/** Project the complete annotation after applying the current gesture. */\nfunction effectiveSelectionFrame(model: Model, id: Id, geometry: Shape, view?: ViewEnv) {\n const record = model.byId[id];\n return annotationSelectionFrame(record, undefined, {\n geometry,\n style: effStyle(record.annotation, view),\n measure: effMeasure(model, id),\n });\n}\n\n/** Union of the effective frames; group chrome and rotation use this box. */\nfunction unionBoundsOf(\n model: Model,\n page: PageRef,\n geomOf: (id: Id) => Shape,\n view?: ViewEnv,\n): Rect | null {\n const pageObjectNumber = page.objectNumber;\n const corners: Point[] = [];\n for (const id of model.selected) {\n const record = model.byId[id];\n if (!record || record.annotation.page.objectNumber !== pageObjectNumber) continue;\n corners.push(...effectiveSelectionFrame(model, id, geomOf(id), view).corners);\n }\n return corners.length ? unionRect(corners) : null;\n}\n\n/** The page-bound knob placement for the selection on `page`, reading each\n * member's geometry through `geomOf` — `effGeom` for the live view, the\n * committed geometry for a rotate gesture's rest anchor (see `selectionKnob`). */\nfunction placeSelectionKnob(\n model: Model,\n page: PageRef,\n pageBox: Rect | undefined,\n knobOffset: number,\n geomOf: (id: Id) => Shape,\n view?: ViewEnv,\n): { at: Point; from: Point } | null {\n const pageObjectNumber = page.objectNumber;\n const selection = model.selected.filter(\n (id) =>\n isSelectable(model, id) && model.byId[id].annotation.page.objectNumber === pageObjectNumber,\n );\n if (selection.length === 1) {\n const record = model.byId[selection[0]];\n // No knob for a locked or frozen annotation — the same gate hitTest\n // applies, so the drawn knob is always grabbable and vice versa. A\n // screen-anchored body keeps its knob: rotating edits its authored tilt\n // (`noRotate` only exempts it from the page's rotation). The obb takes\n // the projected stroke width (`effStyle`) — with the raw width, the knob\n // drifts off the outline as zoom grows.\n if (!kindOf(record.annotation).caps.rotatable || !isTransformableByHand(model, record))\n return null;\n const frame = effectiveSelectionFrame(model, record.id, geomOf(record.id), view);\n return placeRotateKnob(frame.corners, knobOffset, pageBox);\n }\n if (selection.length > 1 && groupCaps(model, selection).rotatable) {\n const union = unionBoundsOf(model, page, geomOf, view);\n if (union) return placeRotateKnob(boxCorners(union), knobOffset, pageBox);\n }\n return null;\n}\n\n/**\n * The rotate knob for the current selection on `page` — the same knob `chrome`\n * draws — or null when the selection has none (non-rotatable single, or a group\n * whose caps aren't rotatable). A single shape's knob hangs off its OBB top edge;\n * a group's off the union box. With `pageBox` the knob is placed page-bound\n * (`placeRotateKnob`: flip below / clamp inside) — off-page it would be visible\n * but unreachable, since pointer dispatch resolves pages by containment. Shared\n * by `chrome` (to draw) and `selectionAnchor` (to push the menu clear of it), so\n * the two can never disagree on where it is.\n *\n * The placement decision is made at rest; a gesture never re-decides — it rides.\n * During a live rotate the knob starts exactly where it was grabbed (the rest\n * placement on the committed geometry) and turns rigidly about the pivot by the\n * same snapped delta the shape uses; the policy re-evaluates only on release.\n * Re-deciding per frame would jump at grab and side-switch mid-spin.\n */\nexport function selectionKnob(\n model: Model,\n page: PageRef,\n pageBox?: Rect,\n knobOffset: number = ROTATE_KNOB_OFFSET,\n view?: ViewEnv,\n): { at: Point; from: Point } | null {\n const draft = model.draft;\n if (\n draft?.kind === 'rotate' &&\n model.byId[draft.ids[0]]?.annotation.page.objectNumber === page.objectNumber\n ) {\n const rest = placeSelectionKnob(\n model,\n page,\n pageBox,\n knobOffset,\n (id) => anchoredGeom(shapeOf(model.byId[id].annotation), anchorModeOf(model.byId[id]), view),\n view,\n );\n if (!rest) return null;\n const { delta } = rotateDraftDelta(model, draft);\n return {\n at: rotatePoint(rest.at, draft.pivot, delta),\n from: rotatePoint(rest.from, draft.pivot, delta),\n };\n }\n return placeSelectionKnob(\n model,\n page,\n pageBox,\n knobOffset,\n (id) => effGeom(model, id, view),\n view,\n );\n}\n\nexport function chrome(\n model: Model,\n page: PageRef,\n pageBox?: Rect,\n knobOffset: number = ROTATE_KNOB_OFFSET,\n view?: ViewEnv,\n): ChromeNode[] {\n const pageObjectNumber = page.objectNumber;\n const nodes: ChromeNode[] = [];\n if (model.draft?.kind === 'marquee' && model.draft.page.objectNumber === pageObjectNumber) {\n nodes.push({ kind: 'marquee', rect: rectFromPoints(model.draft.from, model.draft.to) });\n }\n // A link being drawn: it has no drawing of its own, so the box it will\n // cover shows as the rubber band.\n if (\n model.draft?.kind === 'create-rect' &&\n model.draft.subtype === 'link' &&\n model.draft.page.objectNumber === pageObjectNumber\n ) {\n nodes.push({ kind: 'marquee', rect: rectFromPoints(model.draft.from, model.draft.to) });\n }\n // Live alignment guides of a snapped move (the gesture lives on one page —\n // its members' page).\n if (\n model.draft?.kind === 'move' &&\n model.draft.guides.length &&\n model.byId[model.draft.ids[0]]?.annotation.page.objectNumber === pageObjectNumber\n ) {\n for (const guide of model.draft.guides)\n nodes.push({ kind: 'guide', axis: guide.axis, at: guide.at, lo: guide.lo, hi: guide.hi });\n }\n // A live rotate on this page's selection. While it runs, the chrome switches\n // modes: full-bleed guides appear (the angle is the rotation badge's, a\n // screen overlay: `rotationAnchor`), and the handles/knob are suppressed\n // below — the pointer holds capture, so grab affordances are noise; \"how\n // far am I\" feedback is everything.\n const rd =\n model.draft?.kind === 'rotate' &&\n model.byId[model.draft.ids[0]]?.annotation.page.objectNumber === pageObjectNumber\n ? model.draft\n : null;\n if (rd) {\n const { angle } = rotateDraftDelta(model, rd);\n // Guides as chords of the page through the pivot — the fixed 0°/90°\n // reference cross + the live indicator at the same snapped angle the badge\n // shows and the commit applies. Full-bleed beats a magic length constant;\n // no pageBox (headless) → a generous fixed span around the pivot.\n const span = pageBox ?? { x: rd.pivot.x - 300, y: rd.pivot.y - 300, width: 600, height: 600 };\n const lines: Array<{ a: Point; b: Point; role: 'axis' | 'indicator' }> = [];\n for (const [deg, role] of [\n [0, 'axis'],\n [90, 'axis'],\n [angle, 'indicator'],\n ] as const) {\n const chord = chordThrough(span, rd.pivot, deg);\n if (chord) lines.push({ ...chord, role });\n }\n nodes.push({ kind: 'rotate-guides', center: rd.pivot, angle, lines });\n }\n const selection = model.selected.filter(\n (id) =>\n isSelectable(model, id) && model.byId[id].annotation.page.objectNumber === pageObjectNumber,\n );\n if (selection.length === 1) {\n const record = model.byId[selection[0]];\n const geometry = effGeom(model, selection[0], view);\n const style = effStyle(record.annotation, view);\n const caps = kindOf(record.annotation).caps;\n const rot = geomRotation(geometry);\n const measure = effMeasure(model, record.id);\n const distance =\n measure?.intent === 'line-dimension' && distanceLayout(geometry, measure, style.strokeWidth);\n const frame = effectiveSelectionFrame(model, record.id, geometry, view);\n if (frame.angle !== 0) {\n nodes.push({ kind: 'obb', corners: frame.corners, angle: frame.angle });\n } else {\n nodes.push({ kind: 'outline', rect: unionRect(frame.corners) });\n }\n // handles for kinds that resize (box) or vertex-edit; anchored/markup show\n // a bare outline — and so do locked or frozen annotations, the same gate\n // hitTest applies. Screen-anchored bodies keep their handles, placed on\n // the projected geometry (`geometry`), so they sit exactly where hitTest grabs\n // them. `geomHandles` already places them on the rotated box; `rot`\n // additionally tilts each handle glyph so it rides the box's orientation.\n // Suppressed during a live rotate (`rd`) — guides own that mode.\n if (!rd && isTransformableByHand(model, record) && (caps.resizable || caps.vertexEditable)) {\n const handles = distance ? distanceHandles(distance) : geomHandles(geometry);\n const dragged =\n model.draft?.kind === 'handle' && model.draft.id === record.id ? model.draft.handle : null;\n for (const handle of handles) {\n nodes.push({\n kind: 'handle',\n at: handle.at,\n cursor: cursorOnScreen(handle.cursor, view?.rotation ?? 0),\n ...(rot ? { rot } : {}),\n role: handleRole(handle.id),\n active: handle.id === dragged,\n });\n }\n }\n } else if (selection.length > 1 && !rd) {\n // The live union (draft-effective geometry): the outline and its handles\n // ride a group move/scale exactly like single-selection chrome. During a\n // live rotate the members spin away from any axis-aligned box, so the\n // whole block is suppressed — the guides own that mode.\n const union = unionBoundsOf(model, page, (id) => effGeom(model, id, view), view);\n if (union) {\n nodes.push({ kind: 'outline', rect: union });\n const gc = groupCaps(model, selection);\n if (gc.resizable) {\n const dragged =\n model.draft?.kind === 'group' && model.draft.op === 'resize' ? model.draft.handle : null;\n for (const handle of rectHandlesFor(union))\n nodes.push({\n kind: 'handle',\n at: handle.at,\n cursor: cursorOnScreen(handle.cursor, view?.rotation ?? 0),\n role: handleRole(handle.id),\n active: handle.id === dragged,\n });\n }\n }\n }\n // The rotate knob (single shape or group) — one source of truth with the menu\n // anchor, so the menu is always pushed clear of exactly this point. Hidden\n // while a rotate runs (the gesture holds capture; the guides own the mode).\n if (!rd) {\n const knob = selectionKnob(model, page, pageBox, knobOffset, view);\n if (knob) nodes.push({ kind: 'rotate-knob', at: knob.at, from: knob.from });\n }\n return nodes;\n}\n\n/** The page-space union of the selectable selected items on `page`, or null if\n * the page holds none. This is the same box the chrome outline draws, so a\n * floating menu sits exactly on the selection. */\nexport function selectionBoundsOnPage(model: Model, page: PageRef, view?: ViewEnv): Rect | null {\n const pageObjectNumber = page.objectNumber;\n const selection = model.selected.filter(\n (id) =>\n isSelectable(model, id) && model.byId[id].annotation.page.objectNumber === pageObjectNumber,\n );\n if (selection.length === 0) return null;\n // The rotated AABB: the axis-aligned box that encloses the oriented selection\n // quad. For a tilted shape this tracks the live `rot`, so the upright floating\n // menu floats above the whole tilted shape instead of the (fixed) unrotated box.\n const corners = selection.flatMap(\n (id) => effectiveSelectionFrame(model, id, effGeom(model, id, view), view).corners,\n );\n return unionRect(corners);\n}\n\n/** The anchor for a selection-aware floating menu: the primary page (the first\n * selectable selected id) + the union box of the selection on that page (content\n * space). Null when nothing selectable is selected. A cross-page selection\n * anchors to its primary page, so there is exactly one menu. `pageBoxOf` is a\n * lookup (the anchor resolves its own page) feeding the page-bound knob\n * placement — the menu then dodges the knob where it actually sits. */\nexport function selectionAnchor(\n model: Model,\n pageBoxOf?: (page: PageRef) => Rect | undefined,\n knobOffsetOf?: (page: PageRef) => number | undefined,\n viewOf?: (page: PageRef) => ViewEnv | undefined,\n): { page: PageRef; bounds: Rect; knob?: Point } | null {\n // No menu while a gesture moves, resizes or turns the selection, or a box\n // selects: a floating menu chasing the pointer is noise, and it would cover\n // what the user is placing.\n if (model.draft && !model.draft.kind.startsWith('create-')) return null;\n const id = model.selected.find((selectedId) => isSelectable(model, selectedId));\n if (id == null) return null;\n const page = model.byId[id].annotation.page;\n const view = viewOf?.(page);\n const bounds = selectionBoundsOnPage(model, page, view);\n if (!bounds) return null;\n // `bounds` is the plain selection box (the menu stays centred on it). The knob\n // rides alongside it so the menu can nudge only the edge it sits on, and only\n // when the handle would otherwise hide under it — never shifting the centre.\n const knob = selectionKnob(\n model,\n page,\n pageBoxOf?.(page),\n knobOffsetOf?.(page) ?? ROTATE_KNOB_OFFSET,\n view,\n );\n return knob ? { page, bounds, knob: knob.at } : { page, bounds };\n}\n\n/** Anchor for controls that finish/cancel an active multi-click creation draft.\n * It is rect-based like selectionAnchor, using the committed vertices only so\n * the menu remains stable while the hover preview follows the pointer. */\n/**\n * The rotation in progress, for the badge that follows the pointer: `null`\n * when nothing is being turned. The badge is a screen overlay, so it stays\n * upright however the page is shown.\n */\nexport function rotationAnchor(model: Model): RotationAnchor | null {\n const draft = model.draft;\n if (draft?.kind !== 'rotate') return null;\n const page = model.byId[draft.ids[0]]?.annotation.page;\n if (!page) return null;\n return {\n page,\n at: draft.current,\n angle: Math.round(rotateDraftDelta(model, draft).angle),\n };\n}\n\nexport function creationDraftAnchor(model: Model): CreationDraftAnchor | null {\n const draft = model.draft;\n if (draft?.kind !== 'create-poly') return null;\n if (!draft.points.length) return null;\n const minPoints = draft.closed ? 3 : 2;\n return {\n kind: 'poly',\n subtype: draft.closed ? 'polygon' : 'polyline',\n page: draft.page,\n bounds: unionRect(draft.points),\n pointCount: draft.points.length,\n minPoints,\n canFinish:\n draft.points.length >= minPoints &&\n (!draft.measure ||\n !(\n 'unavailable' in\n shapeMeasurementReadout(\n { kind: 'poly', vertices: draft.points, closed: draft.closed, rotation: 0 },\n draft.measure,\n )\n )),\n };\n}\n\n/** A box's corner handle (`nw`), a side's (`n`), or one point of a line, polygon or dimension. */\nfunction handleRole(id: string): HandleRole {\n if (id === 'nw' || id === 'ne' || id === 'se' || id === 'sw') return 'corner';\n if (id === 'n' || id === 'e' || id === 's' || id === 'w') return 'side';\n return 'point';\n}\n\n/**\n * Where UI attaches to one annotation: its page and the box around what it\n * shows, a gesture in progress included, so an overlay follows a drag. `null`\n * for a record the model doesn't have.\n */\nexport function annotationAnchor(\n model: Model,\n id: Id,\n view?: ViewEnv,\n): { page: PageRef; bounds: Rect } | null {\n const record = model.byId[id];\n if (!record) return null;\n const frame = effectiveSelectionFrame(model, id, effGeom(model, id, view), view);\n return { page: record.annotation.page, bounds: unionRect(frame.corners) };\n}\n","/**\n * The CSS font family the browser draws an annotation's font with, wherever\n * it draws one itself: the live text editor, a drawn text box, a redaction's\n * label. A standard font gets a web stack with its metrics; any other font is\n * a registered key, drawn in the face mounted for it.\n */\nimport { isStandardFontName, STANDARD_FACES } from '@embedpdf/engine-core/runtime';\n\ntype StandardFamily = (typeof STANDARD_FACES)[keyof typeof STANDARD_FACES]['family'];\n\n/** Web stacks with the standard families' metrics. */\nexport const STANDARD_FONT_STACKS: Readonly<Record<StandardFamily, string>> = {\n Helvetica: 'Helvetica, Arial, sans-serif',\n Times: '\"Times New Roman\", Times, serif',\n Courier: '\"Courier New\", Courier, monospace',\n Symbol: 'serif',\n ZapfDingbats: 'serif',\n};\n\n/**\n * The family `mountWebFont` (`@embedpdf/web`) mounts a registered font's key\n * under: namespaced, so a page's own family of the same name never stands in\n * for it.\n */\nexport const mountedFontFamily = (key: string): string => `\"epdf-${key}\"`;\n\n/** The CSS family list for a DTO font: a standard kebab name or a registered key. */\nexport function cssFontFamilyForFont(font: string): string {\n if (isStandardFontName(font)) return STANDARD_FONT_STACKS[STANDARD_FACES[font].family];\n return `${mountedFontFamily(font)}, sans-serif`;\n}\n","/**\n * The note and file-attachment icons, drawn live. They are the drawings the\n * engine bakes for these kinds (the fork's `GenerateTextSymbolAP` and\n * `GenerateFileAttachmentSymbolAP`), so a new or restyled icon shows at once,\n * before the engine answers, and looks the same after.\n *\n * Each icon is designed in a 20 × 20 square, y up as PDF draws, and stretched\n * onto the annotation's box, each axis on its own. The annotation's colour\n * fills the body; the outline is black, or white on a dark colour.\n */\nimport { blendFor } from './kinds/styles';\nimport type { Paint, Point, Rect, RenderItem, SceneNode, Style } from './types';\n\n/** The side of the square every icon is designed in. */\nconst DESIGN = 20;\n\n/** The icons' outline width, in design units. */\nconst OUTLINE = 1;\n\n/** A point in the design square, y up. */\ntype DesignPoint = (x: number, y: number) => Point;\n\nconst num = (value: number): number => Number(value.toFixed(3));\n\n/** Builds an SVG path from design-square coordinates. */\nclass DesignPath {\n private readonly parts: string[] = [];\n\n constructor(private readonly toPage: DesignPoint) {}\n\n private point(x: number, y: number): string {\n const point = this.toPage(x, y);\n return `${num(point.x)} ${num(point.y)}`;\n }\n\n move(x: number, y: number): this {\n this.parts.push(`M ${this.point(x, y)}`);\n return this;\n }\n\n line(x: number, y: number): this {\n this.parts.push(`L ${this.point(x, y)}`);\n return this;\n }\n\n curve(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): this {\n this.parts.push(`C ${this.point(x1, y1)} ${this.point(x2, y2)} ${this.point(x3, y3)}`);\n return this;\n }\n\n close(): this {\n this.parts.push('Z');\n return this;\n }\n\n /** A closed rectangle from one corner to the other, as PDF's `re` draws it. */\n rect(x1: number, y1: number, x2: number, y2: number): this {\n return this.move(x1, y1).line(x2, y1).line(x2, y2).line(x1, y2).close();\n }\n\n /** A closed ellipse in the box between two corners: four curves from its top middle. */\n ellipse(x1: number, y1: number, x2: number, y2: number): this {\n const middleX = (x1 + x2) / 2;\n const middleY = (y1 + y2) / 2;\n const dx = (KAPPA * Math.abs(x2 - x1)) / 2;\n const dy = (KAPPA * Math.abs(y2 - y1)) / 2;\n const [left, right] = [Math.min(x1, x2), Math.max(x1, x2)];\n const [bottom, top] = [Math.min(y1, y2), Math.max(y1, y2)];\n return this.move(middleX, top)\n .curve(middleX + dx, top, right, middleY + dy, right, middleY)\n .curve(right, middleY - dy, middleX + dx, bottom, middleX, bottom)\n .curve(middleX - dx, bottom, left, middleY - dy, left, middleY)\n .curve(left, middleY + dy, middleX - dx, top, middleX, top)\n .close();\n }\n\n get d(): string {\n return this.parts.join(' ');\n }\n}\n\n/** How far a quarter ellipse's control points sit from its ends, as a share of the radius. */\nconst KAPPA = 0.5523;\n\n/** Black on a light colour, white on a dark one: the outline that reads on the fill. */\nexport function contrastOf(color: string | null): string {\n const hex = color?.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);\n const [red, green, blue] = hex ? hex.slice(1).map((part) => parseInt(part, 16) / 255) : [0, 0, 0];\n const luminance = 0.299 * red! + 0.587 * green! + 0.114 * blue!;\n return luminance < 0.45 ? '#ffffff' : '#000000';\n}\n\n/** The paints an icon uses, for its style and scale. */\nfunction iconPaints(style: Style, pen: number) {\n const contrast = contrastOf(style.color);\n const base = { opacity: style.opacity, blend: blendFor(style) };\n return {\n contrast,\n /** Filled with the colour and outlined, as PDF's `B` (or `B*`, even-odd) paints. */\n body: (evenOdd = false): Paint => ({\n ...base,\n fill: style.color ?? undefined,\n stroke: contrast,\n width: OUTLINE * pen,\n ...(evenOdd ? { fillRule: 'evenodd' as const } : {}),\n }),\n /** Outlined only. */\n outline: (width = OUTLINE, round = false): Paint => ({\n ...base,\n stroke: contrast,\n width: width * pen,\n ...(round ? { lineCap: 'round' as const, join: 'round' as const } : {}),\n }),\n /** Filled with the outline colour. */\n mark: (): Paint => ({ ...base, fill: contrast }),\n /** A round-ended stroke in the annotation's colour. */\n wire: (width: number): Paint => ({\n ...base,\n stroke: style.color ?? undefined,\n width: width * pen,\n lineCap: 'round',\n join: 'round',\n }),\n };\n}\n\n/**\n * The design square stretched onto `box` (page space, y down), and the width\n * a design unit of pen becomes. A stretched icon's pen stretches too; one\n * width, the mean of the two scales, stands in for it.\n */\nfunction designOnto(box: Rect): { toPage: DesignPoint; pen: number } {\n const scaleX = box.width / DESIGN;\n const scaleY = box.height / DESIGN;\n return {\n toPage: (x, y) => ({ x: box.x + x * scaleX, y: box.y + (DESIGN - y) * scaleY }),\n pen: Math.sqrt(scaleX * scaleY),\n };\n}\n\n/**\n * A point of a glyph drawn in the square inset by half the outline, so the\n * outline stays inside the box.\n */\nconst inset =\n (toPage: DesignPoint, design: number): DesignPoint =>\n (x, y) =>\n toPage(\n OUTLINE / 2 + (x / design) * (DESIGN - OUTLINE),\n OUTLINE / 2 + (y / design) * (DESIGN - OUTLINE),\n );\n\n/** A note's icon (`/Name`; `note` when it has none), filling `box`. */\nexport function noteIconScene(icon: RenderItem['icon'], box: Rect, style: Style): SceneNode[] {\n const { toPage, pen } = designOnto(box);\n const paints = iconPaints(style, pen);\n const path = () => new DesignPath(toPage);\n const glyph = () => new DesignPath(inset(toPage, DESIGN));\n const node = (d: DesignPath, paint: Paint): SceneNode => ({ kind: 'path', d: d.d, paint });\n\n switch (icon) {\n case 'comment': {\n // A speech balloon with its tip at the bottom left, and three lines of text.\n const balloon = path()\n .move(0.5, 4.5)\n .line(0.5, 19.5)\n .line(19.5, 19.5)\n .line(19.5, 4.5)\n .line(8.5, 4.5)\n .line(6.5, 0.5)\n .line(4.5, 4.5)\n .line(0.5, 4.5);\n for (const y of [15.75, 12, 8.25]) balloon.move(2.5, y).line(17.5, y);\n return [node(balloon, paints.body(true))];\n }\n case 'help': {\n // A disc with a question mark in the outline colour.\n const question = glyph()\n .move(7.2, 12.8)\n .curve(7.2, 15.2, 8.6, 16.2, 10.2, 16.2)\n .curve(11.9, 16.2, 13, 15.1, 13, 13.6)\n .curve(13, 11.6, 10.2, 11.3, 10.2, 9)\n .line(10.2, 7.8);\n return [\n node(glyph().ellipse(1, 1, 19, 19), paints.body()),\n node(question, paints.outline(1.8, true)),\n node(glyph().ellipse(9, 4, 11.4, 6.4), paints.mark()),\n ];\n }\n case 'key': {\n // Its ring (even-odd punches the hole), shaft and two teeth.\n const key = glyph()\n .ellipse(1.5, 8.5, 10.5, 17.5)\n .ellipse(4.2, 11.2, 7.8, 14.8)\n .rect(10.5, 11.8, 18.5, 14.2)\n .rect(13.5, 8.8, 15, 11.8)\n .rect(16.5, 9.8, 18.5, 11.8);\n return [node(key, paints.body(true))];\n }\n case 'new-paragraph': {\n // A triangle pointing up over a line: a new paragraph starts here.\n const mark = glyph().move(3, 8).line(17, 8).line(10, 18).close().rect(3, 2, 17, 5);\n return [node(mark, paints.body(true))];\n }\n case 'paragraph': {\n // The pilcrow as one outline: two stems and the bowl on the left.\n const pilcrow = glyph()\n .move(15.5, 18)\n .line(15.5, 2)\n .line(13.7, 2)\n .line(13.7, 16.2)\n .line(11.8, 16.2)\n .line(11.8, 2)\n .line(10, 2)\n .line(10, 9.6)\n .curve(6.6, 9.6, 4, 11.4, 4, 13.8)\n .curve(4, 16.2, 6.6, 18, 10, 18)\n .close();\n return [node(pilcrow, paints.body())];\n }\n case 'insert': {\n // A caret.\n const caret = glyph()\n .move(2.5, 3)\n .line(10, 17)\n .line(17.5, 3)\n .line(14.3, 3)\n .line(10, 11.2)\n .line(5.7, 3)\n .close();\n return [node(caret, paints.body())];\n }\n default: {\n // Note: a page with its top right corner folded over, and three lines.\n const page = glyph()\n .move(3.5, 1)\n .line(3.5, 19)\n .line(12.5, 19)\n .line(16.5, 15)\n .line(16.5, 1)\n .close();\n const fold = glyph().move(12.5, 19).line(12.5, 15).line(16.5, 15);\n for (const y of [12, 8.5, 5]) fold.move(6, y).line(14, y);\n return [node(page, paints.body()), node(fold, paints.outline())];\n }\n }\n}\n\n/** A file attachment's icon (`/Name`; `push-pin` when it has none), filling `box`. */\nexport function fileAttachmentIconScene(\n icon: RenderItem['icon'],\n box: Rect,\n style: Style,\n): SceneNode[] {\n const { toPage, pen } = designOnto(box);\n const paints = iconPaints(style, pen);\n // The glyphs are laid out in shares of the inset square.\n const glyph = () => new DesignPath(inset(toPage, 1));\n const node = (d: DesignPath, paint: Paint): SceneNode => ({ kind: 'path', d: d.d, paint });\n\n switch (icon) {\n case 'paperclip': {\n // A wire, not a region: a wide outline pass, then the wire in the colour over it.\n const wire = glyph()\n .move(0.32, 0.28)\n .line(0.32, 0.72)\n .curve(0.32, 0.85, 0.68, 0.85, 0.68, 0.72)\n .line(0.68, 0.2)\n .curve(0.68, 0.1, 0.5, 0.1, 0.5, 0.2)\n .line(0.5, 0.65)\n .curve(0.5, 0.72, 0.41, 0.72, 0.41, 0.65)\n .line(0.41, 0.3);\n return [node(wire, paints.outline(2.6, true)), node(wire, paints.wire(1.4))];\n }\n case 'graph': {\n // A frame ring (even-odd) with three bars standing on its bottom edge.\n const graph = glyph()\n .rect(0.1, 0.1, 0.9, 0.9)\n .rect(0.16, 0.16, 0.84, 0.84)\n .rect(0.22, 0.16, 0.36, 0.4)\n .rect(0.43, 0.16, 0.57, 0.56)\n .rect(0.64, 0.16, 0.78, 0.76);\n return [node(graph, paints.body(true))];\n }\n case 'tag': {\n // A label pointing left; even-odd punches its eyelet.\n const tag = glyph()\n .move(0.1, 0.5)\n .line(0.34, 0.8)\n .line(0.9, 0.8)\n .line(0.9, 0.2)\n .line(0.34, 0.2)\n .close()\n .ellipse(0.305, 0.445, 0.415, 0.555);\n return [node(tag, paints.body(true))];\n }\n default: {\n // Push pin: round head, collar and a tapering needle, merged by the nonzero rule.\n const pin = glyph()\n .ellipse(0.33, 0.53, 0.67, 0.87)\n .rect(0.37, 0.46, 0.63, 0.525)\n .move(0.47, 0.455)\n .line(0.53, 0.455)\n .line(0.5, 0.1)\n .close();\n return [node(pin, paints.body())];\n }\n }\n}\n","/**\n * `scene(item)` — the render contract. Turns an annotation render-item into a flat\n * list of fully-painted nodes (geometry + how to paint it). A framework renderer\n * just maps each node to one element and applies `paint`; it owns no per-kind\n * appearance logic, so adding a framework (or a kind) never duplicates drawing.\n *\n * Geometry comes from `geomScene` (shared with hit-testing); paint is layered on\n * here. Text markup is the one family whose paint varies per node (highlight fills,\n * underline/strikeout/squiggly stroke, widths derived from the line height), so it\n * has its own small painter — but it still emits the same generic SceneNodes.\n */\nimport { cssFontFamilyForFont } from './font-css';\nimport { distanceScene, measurementCaptionScene } from './measurement';\nimport { shapeMeasurementLayout } from './measurement-shape';\nimport { quadBounds, quadRing } from '@embedpdf/core-geometry';\nimport { geomScene } from './geometry';\nimport { HELVETICA_ASCENT, HELVETICA_LINE_HEIGHT, helveticaAdvance } from './helvetica';\nimport { drawsLive } from './appearance';\nimport { fileAttachmentIconScene, noteIconScene } from './icons';\nimport { blendFor, dashOf } from './kinds/styles';\nimport { CARET_STROKE_WIDTH } from './shapes/caret';\nimport type {\n Shape,\n Paint,\n Rect,\n RenderItem,\n SceneNode,\n Style,\n KindName,\n Quad,\n TextStyle,\n Point,\n} from './types';\n\nconst num = (value: number): number => Number(value.toFixed(3));\n\n/** Uniform paint for a shape/line/poly node. Fill only lands on closed nodes; the\n * dash comes solely from the border style — so a live draft (ghost) previews\n * exactly how the committed annotation will look, not as a dashed hint. */\nfunction shapePaint(style: Style, closed: boolean): Paint {\n return {\n fill: closed ? (style.interiorColor ?? undefined) : undefined,\n stroke: style.color,\n width: style.strokeWidth,\n opacity: style.opacity,\n dash: dashOf(style),\n // Cloud curls end in deliberate direction reversals (the 22° curl-back\n // tails), which a miter join blows up into spikes. PDFium bakes cloudy\n // borders with `1 j` (round join) for exactly this reason — match it, so\n // the live path and the baked /AP render the same seams.\n ...(style.cloudyIntensity ? { join: 'round' as const } : {}),\n };\n}\n\n/** A smooth squiggle (quadratic-bezier wave) along an arbitrary baseline,\n * generated in the (û, n̂) basis: one `Q` hump then reflected `T` segments\n * alternate across the run. Reflection is affine-invariant, so an upright\n * quad reproduces the old axis-aligned wave byte-for-byte. `n̂` points from\n * the baseline toward the ascent side; humps rise toward the text. */\nfunction squigglePath(\n start: Point,\n direction: Point,\n normal: Point,\n length: number,\n amp: number,\n): string {\n const half = Math.max(2, amp * 1.5); // half a wavelength\n const at = (distance: number, off: number): Point => ({\n x: start.x + direction.x * distance + normal.x * off,\n y: start.y + direction.y * distance + normal.y * off,\n });\n const formatPoint = (point: Point) => `${num(point.x)} ${num(point.y)}`;\n const hump = at(half / 2, amp);\n let pathData = `M ${formatPoint(at(0, 0))} Q ${formatPoint(hump)} ${formatPoint(at(half, 0))}`;\n for (let position = half; position + half <= length + 0.5; position += half) {\n pathData += ` T ${formatPoint(at(position + half, 0))}`;\n }\n return pathData;\n}\n\n/** Per-subtype markup nodes on the quads' own edges (upper = ascent side,\n * lower = baseline side, left → right along the frame).\n * The colour is the markup `/C` (our model keeps stroke==fill). Rotated and\n * sheared cells draw along their true baselines; upright output is identical\n * to the old axis-aligned math. */\nfunction markupScene(subtype: KindName, quads: Quad[], style: Style): SceneNode[] {\n const color = style.color;\n const opacity = style.opacity;\n const nodes: SceneNode[] = [];\n for (const quad of quads) {\n const down = {\n x: quad.lowerLeft.x - quad.upperLeft.x,\n y: quad.lowerLeft.y - quad.upperLeft.y,\n };\n const inkHeight = Math.hypot(down.x, down.y); // true ink height\n const wVec = {\n x: quad.lowerRight.x - quad.lowerLeft.x,\n y: quad.lowerRight.y - quad.lowerLeft.y,\n };\n const baselineLength = Math.hypot(wVec.x, wVec.y); // true baseline length\n if (baselineLength <= 0 || inkHeight <= 0) continue;\n const normal = { x: down.x / inkHeight, y: down.y / inkHeight }; // unit, toward the baseline\n const lw = Math.min(2.5, Math.max(0.75, inkHeight * 0.06));\n if (subtype === 'underline') {\n // the baseline edge, inset lw off the descent side (the old `y + h − lw`)\n nodes.push({\n kind: 'line',\n a: { x: quad.lowerLeft.x - normal.x * lw, y: quad.lowerLeft.y - normal.y * lw },\n b: { x: quad.lowerRight.x - normal.x * lw, y: quad.lowerRight.y - normal.y * lw },\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else if (subtype === 'strikeout') {\n nodes.push({\n kind: 'line',\n a: {\n x: (quad.upperLeft.x + quad.lowerLeft.x) / 2,\n y: (quad.upperLeft.y + quad.lowerLeft.y) / 2,\n },\n b: {\n x: (quad.upperRight.x + quad.lowerRight.x) / 2,\n y: (quad.upperRight.y + quad.lowerRight.y) / 2,\n },\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else if (subtype === 'squiggly') {\n const amp = Math.min(2, Math.max(1, inkHeight * 0.08));\n const direction = { x: wVec.x / baselineLength, y: wVec.y / baselineLength };\n const start = {\n x: quad.lowerLeft.x - normal.x * amp,\n y: quad.lowerLeft.y - normal.y * amp,\n };\n nodes.push({\n kind: 'path',\n // n̂ toward ascent = −(toward baseline)\n d: squigglePath(start, direction, { x: -normal.x, y: -normal.y }, baselineLength, amp),\n paint: { stroke: color, width: lw, opacity, blend: blendFor(style) },\n });\n } else {\n // highlight: translucent fill with `multiply` so the text reads through it\n nodes.push({\n kind: 'poly',\n points: quadRing(quad),\n closed: true,\n paint: { fill: color, opacity, blend: blendFor(style) },\n });\n }\n }\n return nodes;\n}\n\n/** A redact mark's regions: per-quad rings (text marks) or the rect (area).\n * `bounds` feeds the (axis-aligned) label layout; `ring` is what gets drawn,\n * so rotated text marks outline and fill their true cells. */\ninterface RedactRegion {\n ring: [Point, Point, Point, Point];\n bounds: Rect;\n}\n\nconst rectRing = (rect: Rect): [Point, Point, Point, Point] => [\n { x: rect.x, y: rect.y },\n { x: rect.x + rect.width, y: rect.y },\n { x: rect.x + rect.width, y: rect.y + rect.height },\n { x: rect.x, y: rect.y + rect.height },\n];\n\nfunction redactRegions(geometry: Shape): RedactRegion[] {\n if (geometry.kind === 'quads') {\n const out: RedactRegion[] = [];\n for (const quad of geometry.quadPoints) {\n const bounds = quadBounds(quad);\n if (bounds.width > 0 && bounds.height > 0) out.push({ ring: quadRing(quad), bounds });\n }\n return out;\n }\n if (geometry.kind === 'box') return [{ ring: rectRing(geometry.box), bounds: geometry.box }];\n return [];\n}\n\n/**\n * The size a label draws at when its `fontSize` is 0 (fit) and `/Repeat` is\n * on: fitting would only shrink the label as it repeats, so the engine tiles\n * at this size instead.\n */\nconst REPEAT_FIT_FONT_SIZE = 12;\n\n/** The sizes the engine tries when it fits a label to its region, smallest first. */\nconst FIT_FONT_SIZES = [\n 4, 6, 8, 9, 10, 12, 14, 18, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90, 100, 110, 120, 130,\n 144,\n];\n\n/** The largest size at which one line of text `advance` em wide fits the region. */\nfunction fitFontSize(region: Rect, advance: number): number {\n let fitted = FIT_FONT_SIZES[0]!;\n for (const size of FIT_FONT_SIZES) {\n if (size * HELVETICA_LINE_HEIGHT > region.height || size * advance > region.width) break;\n fitted = size;\n }\n return fitted;\n}\n\n/**\n * Redaction label layout — the same reading of ISO 32000-2 the engine's\n * apply-time painter uses, as pure math: top-aligned, `/Q` horizontal\n * alignment, `/Repeat` tiling a full grid that fits the region (no partial\n * glyph bleed — the scene has no clipping). A `fontSize` of 0 fits one label\n * to the region on one line, and tiles a repeated one at 12pt, like the\n * engine. Text is measured in Helvetica, the engine's default label font, so\n * a label in another font is estimated; this is a live preview, the engine\n * bakes the truth.\n */\nexport function layoutRedactLabel(\n region: Rect,\n label: { text: string; repeat: boolean },\n text: TextStyle | undefined,\n): SceneNode[] {\n if (!label.text) return [];\n const advance = helveticaAdvance(label.text);\n const fit = label.repeat ? REPEAT_FIT_FONT_SIZE : fitFontSize(region, advance);\n const fontSize = Math.max(4, text && text.fontSize > 0 ? text.fontSize : fit);\n const textW = advance * fontSize;\n // Repeated labels are joined with a space.\n const gap = helveticaAdvance(' ') * fontSize;\n const lineH = fontSize * HELVETICA_LINE_HEIGHT;\n const paint: Paint = { fill: text?.fontColor ?? '#ffffff', opacity: 1 };\n const base = {\n fontSize,\n ...(text?.fontFamily ? { fontFamily: cssFontFamilyForFont(text.fontFamily) } : {}),\n paint,\n };\n const baseline = (rowTop: number) => rowTop + fontSize * HELVETICA_ASCENT;\n /** Where a line `width` wide starts, by the label's alignment. */\n const lineStart = (width: number) =>\n text?.textAlign === 'center'\n ? region.x + Math.max(0, (region.width - width) / 2)\n : text?.textAlign === 'right'\n ? region.x + Math.max(0, region.width - width)\n : region.x;\n\n if (!label.repeat) {\n if (fontSize > region.height) return [];\n return [\n {\n kind: 'text',\n at: { x: lineStart(textW), y: baseline(region.y) },\n text: label.text,\n ...base,\n },\n ];\n }\n\n const cols = Math.max(1, Math.floor((region.width + gap) / (textW + gap)));\n const rows = Math.max(1, Math.floor(region.height / lineH));\n const left = lineStart(cols * textW + (cols - 1) * gap);\n const nodes: SceneNode[] = [];\n for (let row = 0; row < rows && nodes.length < 400; row++) {\n for (let column = 0; column < cols && nodes.length < 400; column++) {\n nodes.push({\n kind: 'text',\n at: { x: left + column * (textW + gap), y: baseline(region.y + row * lineH) },\n text: label.text,\n ...base,\n });\n }\n }\n return nodes;\n}\n\n/**\n * Redaction marks: at REST an outline per region, nothing filled. On hover\n * the applied-look preview — the `/IC` fill plus the tiled `/OverlayText`\n * label — exactly what the destructive apply will paint. All pure data, so\n * every framework renders the preview from the same scene.\n */\nfunction redactScene(item: RenderItem): SceneNode[] {\n const regions = redactRegions(item.geometry);\n if (!item.hovered) {\n const paint = {\n stroke: item.style.color,\n width: item.style.strokeWidth || 1.5,\n opacity: item.style.opacity,\n };\n return regions.map(\n (region) => ({ kind: 'poly', points: region.ring, closed: true, paint }) as SceneNode,\n );\n }\n const nodes: SceneNode[] = [];\n if (item.style.interiorColor) {\n const fill = { fill: item.style.interiorColor, opacity: 1 };\n for (const region of regions) {\n nodes.push({ kind: 'poly', points: region.ring, closed: true, paint: fill });\n }\n }\n if (item.label) {\n // Label tiling stays axis-aligned inside the region's bounds — the live\n // preview approximates; the engine's apply-time painter bakes the truth.\n for (const region of regions) {\n nodes.push(...layoutRedactLabel(region.bounds, item.label, item.text));\n }\n }\n return nodes;\n}\n\n/**\n * Whether the item can be drawn live now (`scene(item)`): anything not\n * drawn from the engine's picture, a kind with a live drawing, and a lent\n * record its lender draws. A stamp or a link can't: its picture is its\n * drawing.\n */\nexport const hasLiveDrawing = (item: RenderItem): boolean =>\n item.source !== 'baked' ||\n item.lentScene !== undefined ||\n (item.annotation !== undefined && drawsLive({ annotation: item.annotation }));\n\n/** The full painted scene for one annotation. */\nexport function scene(item: RenderItem): SceneNode[] {\n // A lent record: its lender draws it.\n if (item.lentScene) return [...item.lentScene()];\n // A link draws nothing live: its look, a border when the file gives it one,\n // is the engine's raster (`rasterOnly`), and one being drawn shows as the\n // rubber band. Selection chrome outlines it, so an editable link is\n // findable when selected.\n if (item.subtype === 'link') return [];\n // A note's or file attachment's icon fills its box.\n if (item.geometry.kind === 'box' && item.subtype === 'text')\n return noteIconScene(item.icon, item.geometry.box, item.style);\n if (item.geometry.kind === 'box' && item.subtype === 'file-attachment')\n return fileAttachmentIconScene(item.icon, item.geometry.box, item.style);\n if (item.measure?.intent === 'line-dimension')\n return distanceScene(item.geometry, item.measure, item.style);\n if (item.subtype === 'redact') return redactScene(item);\n if (item.geometry.kind === 'quads')\n return markupScene(item.subtype, item.geometry.quadPoints, item.style);\n if (item.geometry.kind === 'caret') {\n return geomScene(item.geometry, item.style).map((node) => ({\n ...node,\n paint: {\n fill: item.style.color,\n stroke: item.style.color,\n width: CARET_STROKE_WIDTH,\n opacity: item.style.opacity,\n },\n })) as SceneNode[];\n }\n const ink = item.geometry.kind === 'ink'; // freehand: round the pen-stroke ends (caps)\n const nodes = geomScene(item.geometry, item.style).map((node) => {\n const closed =\n node.kind === 'rect' ||\n node.kind === 'ellipse' ||\n node.kind === 'path' ||\n (node.kind === 'poly' && node.closed);\n const paint = { ...shapePaint(item.style, closed), blend: blendFor(item.style) };\n // Ink is freehand: round the pen-stroke ends and joins. Every other kind keeps\n // the default butt caps + sharp (miter) joins — square corners and poly knees\n // stay crisp.\n return {\n ...node,\n paint: ink ? { ...paint, lineCap: 'round', join: 'round' } : paint,\n } as SceneNode;\n });\n if (item.measure) {\n const layout = shapeMeasurementLayout(item.geometry, item.measure, item.style);\n nodes.push(...measurementCaptionScene(layout?.caption ?? null, item.style));\n }\n return nodes;\n}\n"],"mappings":"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"}
|