@embedpdf/plugin-annotation 3.0.0-next.10 → 3.0.0-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/authoring-BhtyfsMx.d.cts +37 -0
  2. package/dist/authoring-R4ezdnXd.d.ts +37 -0
  3. package/dist/authoring.cjs +16 -0
  4. package/dist/authoring.d.cts +2 -0
  5. package/dist/authoring.d.ts +2 -0
  6. package/dist/authoring.js +3 -0
  7. package/dist/{capability-Cl9x8oLS.cjs → capability-Csb9WMm-.cjs} +256 -348
  8. package/dist/capability-Csb9WMm-.cjs.map +1 -0
  9. package/dist/{capability-BRf0HrOi.js → capability-DBsr2D-L.js} +191 -259
  10. package/dist/capability-DBsr2D-L.js.map +1 -0
  11. package/dist/contract/host.cjs +3 -0
  12. package/dist/contract/host.d.cts +2 -0
  13. package/dist/contract/host.d.ts +2 -0
  14. package/dist/contract/host.js +2 -0
  15. package/dist/contract.cjs +8 -0
  16. package/dist/contract.cjs.map +1 -0
  17. package/dist/contract.d.cts +10 -0
  18. package/dist/contract.d.ts +10 -0
  19. package/dist/contract.js +8 -0
  20. package/dist/contract.js.map +1 -0
  21. package/dist/index.cjs +22 -23
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +4 -46
  24. package/dist/index.d.ts +4 -46
  25. package/dist/index.js +12 -13
  26. package/dist/index.js.map +1 -1
  27. package/dist/internal.cjs +4 -2
  28. package/dist/internal.d.cts +2 -1
  29. package/dist/internal.d.ts +2 -1
  30. package/dist/internal.js +3 -1
  31. package/dist/seam-6pJeKOOJ.cjs +296 -0
  32. package/dist/seam-6pJeKOOJ.cjs.map +1 -0
  33. package/dist/seam-C4L_7rDt.js +225 -0
  34. package/dist/seam-C4L_7rDt.js.map +1 -0
  35. package/dist/types-CwytT-TI.js +13 -0
  36. package/dist/types-CwytT-TI.js.map +1 -0
  37. package/dist/types-DimcLIic.cjs +17 -0
  38. package/dist/types-DimcLIic.cjs.map +1 -0
  39. package/dist/{types-Due7UgzE.d.cts → types-eLTpocXz.d.cts} +37 -9
  40. package/dist/{types-DITX_3CG.d.ts → types-otwv-Cdl.d.ts} +36 -8
  41. package/package.json +21 -7
  42. package/dist/capability-BRf0HrOi.js.map +0 -1
  43. package/dist/capability-Cl9x8oLS.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-DBsr2D-L.js","names":["contentToPdfRect","pdfToContentRect","pdfToContentPoint","pdfToContentPoint","pdfToContentRect","contentToPdfRect","contentToPdfRect","pdfToContentRect","pdfToContentRect","PublicActionsToken","corePageItems","coreChrome","coreSelectionAnchor","coreCreationDraftAnchor","SelectionPublicToken"],"sources":["../src/repository/props.ts","../src/repository/projection.ts","../src/repository/kinds/shape.ts","../src/repository/kinds/stroke.ts","../src/repository/kinds/freeText.ts","../src/repository/kinds/quads.ts","../src/repository/kinds/misc.ts","../src/repository/links.ts","../src/repository/index.ts","../src/hover-feed.ts","../src/text-item.ts","../src/tools.ts","../src/placement.ts","../src/capability.ts"],"sourcesContent":["/**\n * GENERIC per-key prop lowerings — the 1:1 mappings from the flat props\n * vocabulary to wire fields that hold for every kind that declares the key.\n * Kind modules override ONLY their exceptions (a coupling lives in its\n * owner's file: cloudy `/RD` in shape.ts, visual-bounds `/Rect` in stroke.ts,\n * the link target in link.ts).\n */\nimport { initialTextStyle, type Annot, type PropKey } from '@embedpdf/core-annotation';\n\nimport type { Wire } from './projection';\nimport { cssToColor } from './seam';\n\n/** /BS slice of the style — a cloudy border keeps a solid underlying stroke\n * (the scallops are the /BE effect, layered on by the shape kinds). */\nexport const borderSlice = (style: Annot['style']): Wire => ({\n borderStyle: style.border.kind === 'dashed' ? ('dashed' as const) : ('solid' as const),\n ...(style.border.kind === 'dashed' ? { dashArray: style.border.dash } : {}),\n});\n\n/** The `/DA`-styled text slice falls back to the draw-time seed exactly like\n * the old projections did (a fresh draft may not carry `text` yet). */\nconst textOf = (a: Annot) => a.text ?? initialTextStyle;\n\nexport const GENERIC_PROPS: Partial<Record<PropKey, (a: Annot) => Wire>> = {\n color: (a) => ({ color: cssToColor(a.style.color) }),\n opacity: (a) => ({ opacity: a.style.opacity }),\n blendMode: (a) => ({ blendMode: a.style.blendMode }),\n interiorColor: (a) => ({\n interiorColor: a.style.interiorColor ? cssToColor(a.style.interiorColor) : null,\n }),\n strokeWidth: (a) => ({ strokeWidth: a.style.strokeWidth }),\n border: (a) => borderSlice(a.style),\n fontFamily: (a) => ({ fontFamily: textOf(a).fontFamily }),\n fontSize: (a) => ({ fontSize: textOf(a).fontSize }),\n fontColor: (a) => ({ fontColor: cssToColor(textOf(a).fontColor) }),\n textAlign: (a) => ({ textAlign: textOf(a).textAlign }),\n icon: (a) => (a.icon !== undefined ? { icon: a.icon } : {}),\n // A non-link kind's `link` prop is NOT wire data on the parent: it\n // materializes as attached child annotations through the syncLink\n // reconciler. The link KIND overrides this with its own `/A` target.\n link: () => ({}),\n};\n","import type { AnnotationDTO, PdfRect } from '@embedpdf/engine-core/runtime';\nimport { geomRotation, type Annot, type PropKey } from '@embedpdf/core-annotation';\n\nimport { boxGeomFields } from './seam';\n\n/** An untyped partial wire statement — merged fragments are cast to the\n * concrete `AnnotationDraft`/`AnnotationPatch` at the derivation boundary. */\nexport type Wire = Record<string, unknown>;\n\n/** The kind-specific slice a DTO ingest contributes on top of the generic\n * base (id/ref/flags/relationships) that `fromDTO` builds for every kind. */\nexport type IngestSlice = { geom: Annot['geom'] } & Partial<\n Pick<Annot, 'text' | 'icon' | 'label' | 'link' | 'intent'>\n>;\n\n/**\n * ONE declaration per kind family; every wire statement shape derives from it\n * (see `repository/index.ts`):\n *\n * full patch = geometry(a) ∪ props(a, every key the kind declares)\n * create draft = full patch ∪ draftExtras(a)\n * scoped patch = geometry(a) | props(a, the touched keys)\n *\n * This is the wire-side sibling of the core's PropSpec table: a new kind\n * declares one projection and gets ingest, drafts, full patches, and scoped\n * patches for free. The algebra is sound because of the engine's tri-state\n * law — omission preserves, so a statement never has to restate what it\n * didn't change.\n */\nexport interface KindProjection {\n /** DTO → the kind's model slice (geom + text/icon/label/link/intent). */\n ingest(dto: AnnotationDTO, crop: PdfRect): IngestSlice;\n /**\n * The committed-geometry wire group: the primary geometry plus every field\n * the engine writers couple to it (the box transform trio, a callout's\n * leader group, advisory rotation). `null` = the kind has no editable\n * geometry (text markup) — geometry statements fall back to the full patch.\n */\n geometry(a: Annot, crop: PdfRect): Wire | null;\n /** Kind-specific prop lowerings — ONLY the exceptions; `props.ts` GENERIC\n * covers every 1:1 key. A kind's couplings live here, in its owner's file. */\n prop?: Partial<Record<PropKey, (a: Annot, crop: PdfRect) => Wire>>;\n /** Create-only statement extras (intent, quadPoints, contents seeds…). */\n draftExtras?(a: Annot, crop: PdfRect): Wire | null;\n /** Kinds whose creates do NOT go through the repository (stamps carry a\n * binary source and use their own create path; widgets are form-plane). */\n createable?: false;\n}\n\n/** Box-kind geometry emission: the model's unrotated `rect` + applied tilt →\n * `/Rect`(+`unrotatedRect`+`rotation`), total (nulls state the clears). */\nexport const boxEmit = (a: Annot, crop: PdfRect): Wire => {\n const g = a.geom as Extract<Annot['geom'], { t: 'rect' } | { t: 'text' }>;\n return boxGeomFields(g.rect, geomRotation(a.geom), crop);\n};\n","/**\n * Square + circle. Owns the cloudy-border physics: the `/BE` intensity, the\n * derived `/RD` inset (`cloudyBorderExtent(intensity, strokeWidth)` — client\n * policy, the engine never derives it), and the tri-state clears that remove\n * both when the border returns to plain. The `/Rect` we emit is the OUTER box\n * and `/RD` insets the drawn geometry so the scallops bulge back out to it —\n * derived, never stored on the model.\n */\nimport type { AnnotationDTO, PdfRect } from '@embedpdf/engine-core/runtime';\nimport { cloudyBorderExtent, type Annot } from '@embedpdf/core-annotation';\n\nimport { boxEmit, type KindProjection, type Wire } from '../projection';\nimport { borderSlice } from '../props';\nimport { boxGeomFromDTO } from '../seam';\n\ntype ShapeDTO = Extract<AnnotationDTO, { subtype: 'square' | 'circle' }>;\n\n/** Cloudy `/BE` + `/RD` for a rect shape — TOTAL: the non-cloudy state is\n * stated as `null` (tri-state remove), never omitted, so toggling cloudy OFF\n * removes the stale inset (the Adobe phantom-padding bug). */\nexport function cloudyExtras(a: Annot): Wire {\n if (a.geom.t !== 'rect') return {};\n if (a.style.border.kind === 'cloudy') {\n const inset = cloudyBorderExtent(a.style.border.intensity, a.style.strokeWidth, a.geom.ellipse);\n return {\n cloudyIntensity: a.style.border.intensity,\n rectDifferences: { left: inset, top: inset, right: inset, bottom: inset },\n };\n }\n return { cloudyIntensity: null, rectDifferences: null };\n}\n\nconst ingest = (dto: AnnotationDTO, crop: PdfRect, ellipse: boolean) => {\n const d = dto as ShapeDTO;\n return { geom: boxGeomFromDTO(d, d.rotation, d.unrotatedRect, crop, ellipse) };\n};\n\nconst projection = (ellipse: boolean): KindProjection => ({\n ingest: (dto, crop) => ingest(dto, crop, ellipse),\n geometry: (a, crop) => boxEmit(a, crop),\n prop: {\n // The inset derives from intensity × stroke width, so a width change on a\n // cloudy shape re-states the /RD it owns.\n strokeWidth: (a) => ({ strokeWidth: a.style.strokeWidth, ...cloudyExtras(a) }),\n border: (a) => ({ ...borderSlice(a.style), ...cloudyExtras(a) }),\n },\n});\n\nexport const square: KindProjection = projection(false);\nexport const circle: KindProjection = projection(true);\n","/**\n * The stroke family — line, polygon, polyline, ink. Shared physics: their\n * `/Rect` is the VISUAL bounds (stroke radius included — and, for a cloudy\n * polygon, the outward curl extent), so it derives from the point geometry\n * PLUS the stroke width, border, and line endings; and their\n * `/EMBD_Metadata/Rotation` is an advisory scalar (the points are already\n * rotated; inert for AP).\n */\nimport type { AnnotationDTO, PdfRect } from '@embedpdf/engine-core/runtime';\nimport {\n geomPdfBounds,\n geomRotation,\n pdfToContentPoint,\n type Annot,\n} from '@embedpdf/core-annotation';\n\nimport type { KindProjection, Wire } from '../projection';\nimport { borderSlice } from '../props';\nimport { contentToPdfPoint, rotFromDTO, toPdfRotation } from '../seam';\n\n/** Advisory rotation, TOTAL: rotation 0 states `null` (tri-state clear) —\n * omission would preserve a stale advisory angle. */\nconst advisoryRotation = (g: Annot['geom']): { rotation: number | null } => {\n const rot = geomRotation(g);\n return { rotation: rot ? toPdfRotation(rot) : null };\n};\n\n/** `/BE` intensity for a closed poly (polygon): the curls are generated from\n * /Vertices + /BE alone — per ISO 32000 no /RD applies — and the /Rect\n * (geomPdfBounds WITH the border) already includes the outward cloud extent. */\nconst polyCloudy = (a: Annot): Wire =>\n a.geom.t === 'poly' && a.geom.closed\n ? { cloudyIntensity: a.style.border.kind === 'cloudy' ? a.style.border.intensity : null }\n : {};\n\n/** The visual-bounds `/Rect` (stroke + border included) of a stroke geom. */\nconst visualRect = (a: Annot, crop: PdfRect): Wire => {\n const g = a.geom;\n if (g.t === 'line' || g.t === 'ink') return { rect: geomPdfBounds(g, a.style.strokeWidth, crop) };\n if (g.t === 'poly') return { rect: geomPdfBounds(g, a.style.strokeWidth, crop, a.style.border) };\n return {};\n};\n\n/**\n * A lowering whose key is an INPUT of the derived /Rect: the visual bounds\n * ride along with every emission, so a sparse patch can never change an input\n * without re-emitting the derivation. (The bug this kills: patch `lineEndings`\n * alone → the engine re-bakes the /AP inside the stale /Rect → the new\n * arrowhead is clipped in every viewer except the live vector one.)\n */\nconst withRect =\n (lower: (a: Annot, crop: PdfRect) => Wire) =>\n (a: Annot, crop: PdfRect): Wire => ({ ...lower(a, crop), ...visualRect(a, crop) });\n\n/** Stroke-family prop exceptions: width, border, AND line endings feed the\n * derived /Rect — an ending's arrowhead reaches well past the endpoint, and\n * ISO 32000 requires /Rect to enclose it. Where a key can't change the\n * bounds (a line's border restyle), the re-emitted rect is an idempotent\n * no-op — uniformity beats per-case reasoning here. */\nconst strokeProps: KindProjection['prop'] = {\n strokeWidth: withRect((a) => ({ strokeWidth: a.style.strokeWidth })),\n border: withRect((a) => ({ ...borderSlice(a.style), ...polyCloudy(a) })),\n lineEndings: withRect((a) =>\n (a.geom.t === 'line' || a.geom.t === 'poly') && a.geom.ends\n ? { lineEndings: a.geom.ends }\n : {},\n ),\n};\n\nexport const line: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'line' }>;\n return {\n geom: {\n t: 'line',\n a: pdfToContentPoint(d.linePoints.start, crop),\n b: pdfToContentPoint(d.linePoints.end, crop),\n ends: d.lineEndings,\n ...rotFromDTO(d.rotation),\n },\n };\n },\n geometry: (a, crop) => {\n const g = a.geom;\n if (g.t !== 'line') return null;\n return {\n linePoints: { start: contentToPdfPoint(g.a, crop), end: contentToPdfPoint(g.b, crop) },\n ...visualRect(a, crop),\n ...advisoryRotation(g),\n };\n },\n prop: strokeProps,\n};\n\nconst polyProjection = (closed: boolean): KindProjection => ({\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'polygon' | 'polyline' }>;\n return {\n geom: {\n t: 'poly',\n points: d.vertices.map((p) => pdfToContentPoint(p, crop)),\n closed,\n ...('lineEndings' in d ? { ends: d.lineEndings } : {}),\n ...rotFromDTO(d.rotation),\n },\n };\n },\n geometry: (a, crop) => {\n const g = a.geom;\n if (g.t !== 'poly') return null;\n return {\n vertices: g.points.map((p) => contentToPdfPoint(p, crop)),\n ...visualRect(a, crop),\n ...advisoryRotation(g),\n };\n },\n prop: strokeProps,\n});\n\nexport const polygon: KindProjection = polyProjection(true);\nexport const polyline: KindProjection = polyProjection(false);\n\nexport const ink: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'ink' }>;\n return {\n geom: {\n t: 'ink',\n strokes: d.inkList.map((stroke) => stroke.map((p) => pdfToContentPoint(p, crop))),\n ...rotFromDTO(d.rotation),\n },\n ...(d.intent ? { intent: d.intent } : {}),\n };\n },\n geometry: (a, crop) => {\n const g = a.geom;\n if (g.t !== 'ink') return null;\n return {\n inkList: g.strokes.map((stroke) => stroke.map((p) => contentToPdfPoint(p, crop))),\n ...visualRect(a, crop),\n ...advisoryRotation(g),\n };\n },\n prop: strokeProps,\n // `/IT` is set at create and never patched (the engine preserves it).\n draftExtras: (a) => (a.intent === 'ink-highlight' ? { intent: a.intent } : {}),\n};\n","/**\n * Free text (plain box + callout). Owns the callout leader group — the one\n * geometry where `/RD` means \"text box inset\" rather than a border effect —\n * and the `/DA` text-slice ingest. Font/size/colour lowerings are the GENERIC\n * 1:1 keys (safe as singles since the engine's `/DA` read-modify-write).\n */\nimport type {\n AnnotationDTO,\n CalloutLine,\n LineEnding,\n PdfRect,\n PdfRectDifferences,\n} from '@embedpdf/engine-core/runtime';\nimport {\n calloutLinePoints,\n geomPdfBounds,\n geomRotation,\n rotatedAabb,\n type Annot,\n type TextStyle,\n} from '@embedpdf/core-annotation';\n\nimport { boxEmit, type KindProjection } from '../projection';\nimport {\n colorToCss,\n contentToPdfPoint,\n contentToPdfRect,\n fromPdfRotation,\n insetPdfRectByRD,\n pdfToContentPoint,\n pdfToContentRect,\n toPdfRotation,\n} from '../seam';\n\ntype FreeTextDTO = Extract<AnnotationDTO, { subtype: 'free-text' }>;\n\n/** Free-text `/DA` fields → content {@link TextStyle}. An absent `fontColor`\n * falls back to the `/DA` colour — the same rule the CPVT renderer applies. */\nfunction textFromDTO(dto: FreeTextDTO): TextStyle {\n return {\n fontFamily: dto.fontFamily,\n fontSize: dto.fontSize,\n fontColor: colorToCss(dto.fontColor ?? dto.color),\n textAlign: dto.textAlign,\n };\n}\n\n/**\n * The engine geometry for a callout: the overall `/Rect` (text box ∪ leader ∪\n * arrow), the `/RD` inset that recovers the text box from it, the `/CL` leader\n * (`[tip, knee, conn]` with the connection point derived), and the `/LE`\n * ending. All in PDF user space (y-up), with every `/RD` inset clamped\n * non-negative.\n *\n * A tilted box (the upright policy) additionally emits `rotation` +\n * `unrotatedRect` (the logical text box) — the engine bakes the box + text\n * under an INLINE rotation about the box centre while the leader stays\n * page-space, so (unlike plain boxes) the /AP form `/Matrix` stays identity\n * and the raster stays placed by `/Rect`. `/RD` then insets to the ROTATED\n * box's AABB — the best axis-aligned text box a foreign viewer regenerating\n * the AP can draw (spec-conformant degradation). The transform pair is TOTAL\n * (nulls state the clears) like every box emission.\n */\nexport function calloutFields(\n a: Annot,\n crop: PdfRect,\n): {\n rect: PdfRect;\n rectDifferences: PdfRectDifferences;\n calloutLine: CalloutLine;\n lineEnding: LineEnding;\n rotation: number | null;\n unrotatedRect: PdfRect | null;\n} | null {\n const g = a.geom;\n if (g.t !== 'text' || !g.callout) return null;\n const rot = geomRotation(g);\n const overall = geomPdfBounds(g, a.style.strokeWidth, crop);\n const tb = contentToPdfRect(rot ? rotatedAabb(g.rect, rot) : g.rect, crop);\n const nn = (n: number) => Math.max(0, n);\n const pts = calloutLinePoints(g).map((p) => contentToPdfPoint(p, crop));\n const calloutLine = (\n pts.length === 3 ? [pts[0], pts[1], pts[2]] : [pts[0], pts[1]]\n ) as CalloutLine;\n return {\n rect: overall,\n rectDifferences: {\n left: nn(tb.left - overall.left),\n bottom: nn(tb.bottom - overall.bottom),\n right: nn(overall.right - tb.right),\n top: nn(overall.top - tb.top),\n },\n calloutLine,\n lineEnding: g.callout.ending,\n ...(rot\n ? { rotation: toPdfRotation(rot), unrotatedRect: contentToPdfRect(g.rect, crop) }\n : { rotation: null, unrotatedRect: null }),\n };\n}\n\nexport const freeText: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as FreeTextDTO;\n // A callout (`/IT free-text-callout` + a `/CL` leader): the stored `rect`\n // is the TEXT BOX (the overall `/Rect` inset by `/RD`); the leader's tip\n // is `cl[0]` and the elbow `cl[1]` (a 3-point `/CL`). The connection point\n // — `cl` last — is NOT stored; it's re-derived from the box. A tilted box\n // (the upright policy) reads back from `unrotatedRect` + `rotation`\n // instead — `/RD` only recovers its axis-aligned AABB; foreign PDFs\n // (no EMBD metadata) keep the `/RD` path bit-identically.\n if (d.intent === 'free-text-callout' && d.calloutLine && d.calloutLine.length >= 2) {\n const cl = d.calloutLine;\n const rot = d.rotation ? fromPdfRotation(d.rotation) : 0;\n const box =\n rot && d.unrotatedRect\n ? pdfToContentRect(d.unrotatedRect, crop)\n : pdfToContentRect(insetPdfRectByRD(d.rect, d.rectDifferences), crop);\n return {\n geom: {\n t: 'text',\n rect: box,\n callout: {\n tip: pdfToContentPoint(cl[0], crop),\n knee: cl.length === 3 ? pdfToContentPoint(cl[1], crop) : undefined,\n ending: d.lineEnding ?? 'none',\n },\n ...(rot && d.unrotatedRect ? { rot } : {}),\n },\n text: textFromDTO(d),\n };\n }\n // Plain text box: a box kind — read back the unrotated box + advisory tilt.\n const rot = d.rotation ? fromPdfRotation(d.rotation) : 0;\n const box = rot && d.unrotatedRect ? d.unrotatedRect : d.rect;\n return {\n geom: { t: 'text', rect: pdfToContentRect(box, crop), ...(rot ? { rot } : {}) },\n text: textFromDTO(d),\n };\n },\n geometry: (a, crop) => {\n if (a.geom.t !== 'text') return null;\n const cf = calloutFields(a, crop);\n if (cf) return { ...cf };\n return boxEmit(a, crop);\n },\n // `/IT` + the initial `/Contents` are create-only statements; while typing,\n // the debounced text-edit write owns `contents`.\n draftExtras: (a, crop) => ({\n intent: calloutFields(a, crop) ? 'free-text-callout' : 'free-text',\n contents: a.data?.contents ?? '',\n }),\n};\n","/**\n * The quad-bound kinds: text markup (highlight/underline/squiggly/strikeout),\n * caret, and redact. Their `/QuadPoints` are text-anchored — set at create and\n * never patched — so markup and text-redact have NO editable geometry (the\n * full projection is their geometry fallback), while an AREA redact and a\n * caret are box-like and move by `/Rect`.\n */\nimport type { AnnotationDTO, PdfRect } from '@embedpdf/engine-core/runtime';\nimport { normalizeQuad } from '@embedpdf/core-geometry';\nimport { type Annot, type TextQuad } from '@embedpdf/core-annotation';\n\nimport type { KindProjection } from '../projection';\nimport {\n boxGeomFields,\n colorToCss,\n contentToPdfPoint,\n contentToPdfRect,\n fromPdfRotation,\n pdfToContentPoint,\n pdfToContentRect,\n} from '../seam';\n\ntype PdfPt = { x: number; y: number };\ntype QuadDTO = { p1: PdfPt; p2: PdfPt; p3: PdfPt; p4: PdfPt };\n\n/**\n * Imported `/QuadPoints` → semantic TextQuads. `normalizeQuad` is a\n * NORMALIZER, not a cast: the de-facto zigzag order passes through, ring-order\n * producers are repaired, and garbage gets a deterministic labeling — so\n * drawing code can never put an underline on the wrong edge of a well-formed\n * quad, rotated ones included.\n */\nconst quadsFromDTO = (quadPoints: QuadDTO[], crop: PdfRect): TextQuad[] =>\n quadPoints.map((q) =>\n normalizeQuad({\n p1: pdfToContentPoint(q.p1, crop),\n p2: pdfToContentPoint(q.p2, crop),\n p3: pdfToContentPoint(q.p3, crop),\n p4: pdfToContentPoint(q.p4, crop),\n }),\n );\n\n/** Content quads → engine `/QuadPoints` (PDF user space, zigzag slot order:\n * p1..p4 = upper-start, upper-end, lower-start, lower-end — under the y-flip\n * exactly PDFium's documented TL, TR, BL, BR); null off quads geom. */\nexport function quadPointsFor(a: Annot, crop: PdfRect): QuadDTO[] | null {\n if (a.geom.t !== 'quads') return null;\n return a.geom.quads.map((q) => ({\n p1: contentToPdfPoint(q.upperStart, crop),\n p2: contentToPdfPoint(q.upperEnd, crop),\n p3: contentToPdfPoint(q.lowerStart, crop),\n p4: contentToPdfPoint(q.lowerEnd, crop),\n }));\n}\n\n/** PDF-space bounding box of a set of `/QuadPoints` quads — the `/Rect` a\n * quad-bearing draft must carry alongside its quads. */\nexport const pdfBoundsOfQuads = (quads: QuadDTO[]): PdfRect => {\n let left = Infinity;\n let bottom = Infinity;\n let right = -Infinity;\n let top = -Infinity;\n for (const q of quads) {\n for (const p of [q.p1, q.p2, q.p3, q.p4]) {\n if (p.x < left) left = p.x;\n if (p.x > right) right = p.x;\n if (p.y < bottom) bottom = p.y;\n if (p.y > top) top = p.y;\n }\n }\n return { left, bottom, right, top };\n};\n\nconst markupProjection = (subtype: 'highlight' | 'underline' | 'squiggly' | 'strikeout') => {\n const p: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: typeof subtype }>;\n return {\n geom: { t: 'quads', quads: quadsFromDTO(d.quadPoints, crop) },\n ...(subtype === 'strikeout' && 'intent' in d && d.intent ? { intent: d.intent } : {}),\n };\n },\n // /QuadPoints geometry isn't edited after create.\n geometry: () => null,\n draftExtras: (a, crop) => {\n const quads = quadPointsFor(a, crop);\n if (!quads) return null;\n return {\n quadPoints: quads,\n ...(subtype === 'strikeout' && a.intent === 'strikeout-text-edit'\n ? { intent: a.intent }\n : {}),\n };\n },\n };\n return p;\n};\n\nexport const highlight = markupProjection('highlight');\nexport const underline = markupProjection('underline');\nexport const squiggly = markupProjection('squiggly');\nexport const strikeout = markupProjection('strikeout');\n\nexport const caret: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'caret' }>;\n // Box-family rotation pair: when present, the model's `rect` is the\n // logical (unrotated) box and `rot` the tilt — the free-text/shape rule.\n const rot = d.rotation ? fromPdfRotation(d.rotation) : 0;\n const box = rot && d.unrotatedRect ? d.unrotatedRect : d.rect;\n return {\n geom: { t: 'caret', rect: pdfToContentRect(box, crop), ...(rot ? { rot } : {}) },\n ...(d.intent ? { intent: d.intent } : {}),\n };\n },\n geometry: (a, crop) =>\n a.geom.t === 'caret' ? boxGeomFields(a.geom.rect, a.geom.rot ?? 0, crop) : null,\n // The fixed drawn-symbol inset + the replace-text intent + seeded contents\n // are create-only statements.\n draftExtras: (a) => ({\n rectDifferences: { left: 0.5, top: 0.5, right: 0.5, bottom: 0.5 },\n ...(a.intent === 'replace' ? { intent: a.intent } : {}),\n ...(a.data?.contents != null ? { contents: a.data.contents } : {}),\n }),\n};\n\nexport const redact: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'redact' }>;\n // Text redaction carries per-line quads; an AREA redaction is rect-only\n // (`/Rect` IS the removal region per ISO 32000-2), so its geometry is a\n // box and it moves/resizes like a shape.\n const geom: Annot['geom'] =\n d.quadPoints.length > 0\n ? { t: 'quads', quads: quadsFromDTO(d.quadPoints, crop) }\n : { t: 'rect', rect: pdfToContentRect(d.rect, crop), ellipse: false };\n return {\n geom,\n // The label is `/DA`-styled exactly like free text; `fontSize` 0 means\n // auto-fit and round-trips verbatim (the engine's convention).\n text: {\n fontFamily: d.fontFamily,\n fontSize: d.fontSize,\n fontColor: colorToCss(d.fontColor),\n textAlign: d.textAlign,\n },\n ...(d.overlayText ? { label: { text: d.overlayText, repeat: d.repeat } } : {}),\n };\n },\n // Only an AREA mark's box moves/resizes; text-mark quads are create-only.\n geometry: (a, crop) =>\n a.geom.t === 'rect' ? { rect: contentToPdfRect(a.geom.rect, crop) } : null,\n draftExtras: (a, crop) => {\n const quads = quadPointsFor(a, crop);\n // Text redaction: quads + their PDF bounding box as `/Rect` (the engine\n // requires an explicit rect). Area redaction: the geometry group has it.\n return quads ? { quadPoints: quads, rect: pdfBoundsOfQuads(quads) } : {};\n },\n};\n","/**\n * The remaining small families: icon kinds (text note / file attachment),\n * stamps, links, widgets, and the unsupported fallback. Icon kinds and links\n * are `/Rect`-movable with tiny prop surfaces; stamps and widgets emit\n * patches here but are NOT createable through the repository (stamps carry a\n * binary source through their own create path; widgets are form-plane).\n */\nimport type { AnnotationDTO, PdfRect } from '@embedpdf/engine-core/runtime';\nimport type { Annot, TextStyle } from '@embedpdf/core-annotation';\n\nimport { boxEmit, type KindProjection } from '../projection';\nimport {\n boxGeomFromDTO,\n colorToCss,\n contentToPdfRect,\n pdfToContentRect,\n writableTarget,\n} from '../seam';\n\nconst rectGeometry = (a: Annot, crop: PdfRect) =>\n 'rect' in a.geom ? { rect: contentToPdfRect(a.geom.rect, crop) } : null;\n\nconst iconProjection = (subtype: 'text' | 'file-attachment'): KindProjection => ({\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: typeof subtype }>;\n return {\n geom: { t: 'rect', rect: pdfToContentRect(d.rect, crop), ellipse: false },\n // The /Name icon is a content projection like `style` — icon kinds only.\n icon: d.icon,\n };\n },\n geometry: rectGeometry,\n // Creates go through the click-to-place path (placement.ts), which also\n // carries the attached file for file-attachment — never this repository.\n createable: false,\n});\n\nexport const textNote = iconProjection('text');\nexport const fileAttachment = iconProjection('file-attachment');\n\nexport const stamp: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'stamp' }>;\n return { geom: boxGeomFromDTO(d, d.rotation, d.unrotatedRect, crop, false) };\n },\n // Geometry only — the visual is the engine-baked /AP, re-fit natively when\n // /Rect changes. Content replacement carries bytes and goes through\n // `capability.update` with an inline `source`, never through this path.\n geometry: (a, crop) => boxEmit(a, crop),\n createable: false,\n};\n\nexport const link: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'link' }>;\n return {\n geom: { t: 'rect', rect: pdfToContentRect(d.rect, crop), ellipse: false },\n // The link kind's own target — attached links (grouped children of\n // another kind) fold onto their PARENT's `link` slot instead, in\n // `foldAttachedLinks`.\n link: d.target,\n };\n },\n // A geometry-only move deliberately omits `target`: a foreign read-only /A\n // (javascript/named/…) survives every drag untouched.\n geometry: rectGeometry,\n prop: {\n // Three-state target: a writable value replaces `/A`; an explicit model\n // `null` CLEARS it (the engine removes /A + /Dest); a read-only arm is\n // left untouched — the foreign action survives.\n link: (a) => {\n const target = writableTarget(a.link);\n return target ? { target } : a.link == null ? { target: null } : {};\n },\n },\n // The create-then-edit flow states its (possibly null) target explicitly.\n draftExtras: (a) => ({ target: writableTarget(a.link) }),\n};\n\n/** One PDF `widget` subtype → per-family CLIENT kinds (radios have no font). */\nconst WIDGET_KIND_BY_FAMILY: Record<string, string> = {\n text: 'widget-text',\n combobox: 'widget-choice',\n listbox: 'widget-choice',\n pushbutton: 'widget-button',\n checkbox: 'widget-toggle',\n radio: 'widget-toggle',\n};\nexport const widgetKindOf = (family: string): string =>\n WIDGET_KIND_BY_FAMILY[family] ?? 'widget-box';\nconst WIDGET_TEXT_KINDS = new Set(['widget-text', 'widget-choice', 'widget-button']);\n\nfunction widgetTextFromDTO(dto: Extract<AnnotationDTO, { subtype: 'widget' }>): TextStyle {\n return {\n fontFamily: dto.fontFamily ?? 'helvetica',\n fontSize: dto.fontSize ?? 0, // 0 = auto-size\n fontColor: dto.fontColor ? colorToCss(dto.fontColor) : '#000000',\n textAlign: dto.textAlign,\n };\n}\n\nexport const widget: KindProjection = {\n ingest: (dto, crop) => {\n const d = dto as Extract<AnnotationDTO, { subtype: 'widget' }>;\n return {\n geom: boxGeomFromDTO(d, undefined, undefined, crop, false),\n ...(WIDGET_TEXT_KINDS.has(widgetKindOf(d.fieldFamily)) ? { text: widgetTextFromDTO(d) } : {}),\n };\n },\n geometry: rectGeometry,\n createable: false,\n};\n\nexport const unsupported: KindProjection = {\n ingest: (dto, crop) => ({\n geom: { t: 'rect', rect: pdfToContentRect(dto.rect, crop), ellipse: false },\n }),\n geometry: () => null,\n createable: false,\n};\n","/**\n * Attached-link folding + desired-state derivation — RELATIONSHIP logic, not\n * projection: a `/Link` child grouped under a linkable parent becomes the\n * parent's `link` prop, and the reconciler derives the children it should\n * have from the parent's committed geometry.\n */\nimport { textQuadBounds } from '@embedpdf/core-geometry';\nimport {\n propsFor,\n selectionQuad,\n unionRect,\n type Annot,\n type Quad,\n type Rect,\n} from '@embedpdf/core-annotation';\n\nimport { refKey } from './seam';\n\n/** Does this kind's table declare the `link` prop (may it carry an attached\n * link)? Widgets/caret/redact/file-attachment deliberately don't. */\nconst takesLink = (subtype: string): boolean => propsFor(subtype).some((s) => s.key === 'link');\n\n/** Bounds of one quad (content space). */\nconst quadBounds = (q: Quad): Rect => unionRect(q);\n\n/**\n * The DESIRED hit rects (content 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, the v2\n * segment behaviour), 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. Exact rotated hit regions need\n * `/QuadPoints` (tier 2).\n */\nexport function linkChildRects(a: Annot): Rect[] {\n if (a.geom.t === 'quads') return a.geom.quads.map(textQuadBounds);\n return [unionRect(selectionQuad(a.geom, a.style.strokeWidth, a.style.border))];\n}\n","/**\n * The boundary between the engine's PDF-space annotation DTOs and the core's\n * content-space `Annot` — organized KIND-MAJOR like the rest of the stack\n * (engine-core `kinds/`, the services writer registry, the core PropSpec\n * table): each family declares ONE {@link KindProjection} and every wire\n * statement shape derives from it here:\n *\n * full patch = geometry(a) ∪ props(a, every key the kind declares)\n * create draft = full patch ∪ draftExtras(a) (+ `/F` verbatim)\n * scoped patch = geometry(a) | props(a, the touched keys)\n *\n * The derivation is sound because of the engine's tri-state law (\"a patch\n * touches what it states, preserves what it omits\"): a statement never has to\n * restate what it didn't change, and the emitted key set IS the editable set\n * (`propsFor` — the same table that routes `setProps`), so anything outside\n * it can never change in the model. Any key a kind cannot lower degrades to\n * the FULL patch — verbose, never a dropped write.\n */\nimport type {\n AnnotationDraft,\n AnnotationDTO,\n AnnotationPatch,\n PdfRect,\n} from '@embedpdf/engine-core/runtime';\nimport { propsFor, type Annot, type PatchScope, type PropKey } from '@embedpdf/core-annotation';\n\nimport { boxEmit, type KindProjection, type Wire } from './projection';\nimport { GENERIC_PROPS } from './props';\nimport { circle, square } from './kinds/shape';\nimport { ink, line, polygon, polyline } from './kinds/stroke';\nimport { freeText } from './kinds/freeText';\nimport { caret, highlight, redact, squiggly, strikeout, underline } from './kinds/quads';\nimport {\n fileAttachment,\n link,\n stamp,\n textNote,\n unsupported,\n widget,\n widgetKindOf,\n} from './kinds/misc';\nimport { pdfToContentRect, refKey, styleFromDTO } from './seam';\nimport { geomRotation } from '@embedpdf/core-annotation';\n\nexport {\n boxGeomFields,\n colorToCss,\n cssToColor,\n refKey,\n styleFromDTO,\n widgetAppearanceFromProps,\n writableTarget,\n} from './seam';\nexport { linkChildRects } from './links';\nexport { boxEmit } from './projection';\nexport type { KindProjection } from './projection';\n\n/** Every wire subtype declares exactly one projection — a missing kind is a\n * COMPILE error, not a silent fall-through. */\nconst KINDS = {\n square,\n circle,\n line,\n polygon,\n polyline,\n ink,\n 'free-text': freeText,\n highlight,\n underline,\n squiggly,\n strikeout,\n caret,\n redact,\n text: textNote,\n 'file-attachment': fileAttachment,\n stamp,\n link,\n widget,\n unsupported,\n} satisfies Record<AnnotationDTO['subtype'], KindProjection>;\n\n/** Model subtypes are wire subtypes except the widget CLIENT kinds\n * (`widget-text`…), which all project through the widget family. */\nconst projectionOf = (subtype: string): KindProjection =>\n subtype.startsWith('widget')\n ? KINDS.widget\n : ((KINDS as Record<string, KindProjection>)[subtype] ?? KINDS.unsupported);\n\nconst wireSubtypeOf = (a: Annot): string => (a.subtype.startsWith('widget') ? 'widget' : a.subtype);\n\n/* ── DTO → content model ──────────────────────────────────────────────────── */\n\n/**\n * Engine DTO → content-space Annot. `source` decides how it renders: `'baked'`\n * shows the engine's appearance raster (a page load, or a remote edit — trust\n * the authored AP); `'vector'` renders live from geom/style (we authored or\n * changed it). `apBox` is the raster's content-space box, used while baked.\n */\nexport function fromDTO(\n dto: AnnotationDTO,\n crop: PdfRect,\n source: 'baked' | 'vector' = 'baked',\n): Annot {\n const slice = projectionOf(dto.subtype).ingest(dto, crop);\n // Rotation-stripped appearances (mirrors the engine's EXACT condition — see\n // AnnotationAppearanceReader): only when the DTO carries BOTH `rotation` and\n // `unrotatedRect` (box-family kinds) is the raster flat and placed by the\n // unrotated box, with the stripped rotation re-applied as a view transform\n // (`apRot`). Vertex kinds pre-rotate their geometry and never carry\n // `unrotatedRect` — their rasters stay placed by `/Rect`, untransformed.\n // A CALLOUT is excluded even when it carries both fields: only its text BOX\n // tilts, via an INLINE matrix mid-stream (the leader is page-space), so its\n // /AP form `/Matrix` is identity and the raster stays placed by `/Rect`.\n const isCallout = dto.subtype === 'free-text' && dto.intent === 'free-text-callout';\n const strippedRect =\n !isCallout && 'unrotatedRect' in dto && 'rotation' in dto && dto.rotation\n ? dto.unrotatedRect\n : undefined;\n return {\n id: refKey(dto.ref),\n ref: dto.ref,\n pon: dto.pageObjectNumber,\n subtype: dto.subtype === 'widget' ? widgetKindOf(dto.fieldFamily) : dto.subtype,\n // `/F` verbatim — every behavioral question (visible? selectable? frozen?)\n // is answered by the core's flag predicates, never derived here.\n flags: dto.flags,\n source,\n // Carry the canonical DTO; geom/style below are derived projections of it.\n data: dto,\n // Relationship to a parent annotation. `irt` mirrors `/IRT`; `group` is the\n // primary's key for `/RT /Group` subordinates only (a visual group acts as\n // a unit). `/RT /R` (comment replies) keep `irt` but are NOT a visual group.\n ...(dto.inReplyTo ? { irt: refKey(dto.inReplyTo) } : {}),\n ...(dto.replyType === 'group' && dto.inReplyTo ? { group: refKey(dto.inReplyTo) } : {}),\n style: styleFromDTO(dto),\n ...slice,\n apBox: pdfToContentRect(strippedRect ?? dto.rect, crop),\n ...(strippedRect ? { apRot: geomRotation(slice.geom) } : {}),\n };\n}\n\n/* ── content model → wire statements (the derivation) ─────────────────────── */\n\n/** Lower `keys` through the kind's overrides + the generic table. `null` =\n * some key has no lowering — the caller degrades to the full projection. */\nfunction emitProps(a: Annot, crop: PdfRect, keys: readonly PropKey[]): Wire | null {\n const kind = projectionOf(a.subtype);\n const out: Wire = {};\n for (const key of keys) {\n const lower = kind.prop?.[key] ?? GENERIC_PROPS[key];\n if (!lower) return null;\n Object.assign(out, lower(a, crop));\n }\n return out;\n}\n\nconst editableKeys = (subtype: string): PropKey[] => propsFor(subtype).map((s) => s.key);\n\n/** Content Annot → the FULL engine patch: the kind's geometry group plus every\n * prop it declares editable. The reference statement — scoped emission and\n * drafts both build on it. */\nexport function toPatch(a: Annot, crop: PdfRect): AnnotationPatch | null {\n const kind = projectionOf(a.subtype);\n const geo = kind.geometry(a, crop);\n const props = emitProps(a, crop, editableKeys(a.subtype)) ?? {};\n if (!geo && Object.keys(props).length === 0) return null;\n return { subtype: wireSubtypeOf(a), ...geo, ...props } as AnnotationPatch;\n}\n\n/**\n * Content Annot + a {@link PatchScope} → the SPARSE patch for exactly that\n * intent (the shell's `patch` effect emitter): the reducer says WHAT changed —\n * geometry, or the props keys verbatim — and this lowers only that. Kinds\n * without editable geometry (text markup) and unlowerable keys degrade to the\n * full patch: verbose, never a dropped write.\n */\nexport function toScopedPatch(a: Annot, scope: PatchScope, crop: PdfRect): AnnotationPatch | null {\n const kind = projectionOf(a.subtype);\n if (scope.kind === 'geometry') {\n const geo = kind.geometry(a, crop);\n return geo ? ({ subtype: wireSubtypeOf(a), ...geo } as AnnotationPatch) : toPatch(a, crop);\n }\n const props = emitProps(a, crop, scope.keys);\n if (props === null) return toPatch(a, crop);\n if (Object.keys(props).length === 0) return null;\n return { subtype: wireSubtypeOf(a), ...props } as AnnotationPatch;\n}\n\n/** Content Annot → engine create draft: the full statement plus the kind's\n * create-only extras, with the model's `/F` emitted verbatim, once, for every\n * kind (a fresh draw carries DRAWN_FLAGS plus any tool seed). `null` for the\n * kinds whose creates travel their own path (stamps, widgets, icon place). */\nexport function toCreateDraft(a: Annot, crop: PdfRect): AnnotationDraft | null {\n const kind = projectionOf(a.subtype);\n if (kind.createable === false) return null;\n const base = toPatch(a, crop);\n if (!base) return null;\n const extras = kind.draftExtras?.(a, crop);\n if (kind.draftExtras && extras === null) return null;\n // Seed /NM on every create: a durable identity that survives save/reload\n // and gives replies and status annotations a stable join key from birth\n // (the engine never auto-stamps on read — creation is the one moment).\n return { ...base, ...extras, nm: crypto.randomUUID(), flags: a.flags } as AnnotationDraft;\n}\n","import { createHoverPump } from '@embedpdf/plugin-actions/contract';\nimport type { ActionsCapability, HoverTarget } from '@embedpdf/plugin-actions/contract';\nimport type { Annot } from '@embedpdf/core-annotation';\n\nexport interface AnnotationHoverFeed {\n /** Report the pointer-driven hover target (the hoverAt diff's new id). */\n hover(id: string | null): void;\n}\n\n/**\n * The annotation plane's E/X trigger feed — a thin adapter from the ONE\n * pointer-driven hover seam (the `hoverAt` diff) onto the shared hover pump.\n *\n * Anti-cascade is structural and lives in the CALLER's seam placement:\n * reducer-side hover clears (session-hide, remove, reload) never pass\n * through `hoverAt`, so an effect-induced hover loss can never masquerade as\n * a cursor exit. This module only decides WHO is hoverable here:\n *\n * - Drafts (no engine ref) can't carry /AA — skipped.\n * - Widgets and links belong to their own event planes (fill controls /\n * LinkLayer anchors own their pixels). When they ARE hit-testable on this\n * plane, an authoring tool owns them — firing hover actions while editing\n * would be wrong — so they are skipped unconditionally.\n * - Tree-less annotations are FREE: no target, no dispatch, and per-event\n * flags keep a lone /E or /X from dispatching its inert twin.\n */\nexport function createAnnotationHoverFeed(\n actions: ActionsCapability,\n annotOf: (id: string) => Annot | null,\n): AnnotationHoverFeed {\n const pump = createHoverPump(actions.dispatch);\n\n const targetOf = (id: string | null): HoverTarget | null => {\n if (!id) return null;\n const annot = annotOf(id);\n if (!annot?.ref) return null;\n if (annot.subtype.startsWith('widget') || annot.subtype === 'link') return null;\n const enter = Boolean(annot.data?.actions?.cursorEnter?.root);\n const exit = Boolean(annot.data?.actions?.cursorExit?.root);\n if (!enter && !exit) return null;\n return { ref: annot.ref, pon: annot.pon, events: { enter, exit } };\n };\n\n return {\n hover: (id) => pump.hover(targetOf(id)),\n };\n}\n","/**\n * The free-text presentation projection: the core's geometry-only `textBoxes`\n * joined with the DTO-derived font + CSS into render-ready {@link TextItem}s. This\n * is the text analogue of the core's `scene()` \"paint\" for shapes — it lives in\n * the plugin (not the portable core) because the font→CSS stack mapping and the\n * engine `Color`→CSS seam are web concerns, shared across every web framework.\n */\nimport { initialTextStyle, textBoxes, type Model, type ViewEnv } from '@embedpdf/core-annotation';\nimport type { TextItem } from './types';\n\n/** Map a free-text `/DA` font to a CSS font-family. A standard PDF font → a web\n * stack with the same metrics; anything else is a registered font key → mount it\n * as a `@font-face` of that family (see the framework `mountWebFont` helper). */\nconst STANDARD_FONT_CSS: Record<string, string> = {\n helvetica: 'Helvetica, Arial, sans-serif',\n 'helvetica-bold': 'Helvetica, Arial, sans-serif',\n courier: '\"Courier New\", Courier, monospace',\n 'times-roman': '\"Times New Roman\", Times, serif',\n symbol: 'serif',\n 'zapf-dingbats': 'serif',\n};\nconst cssFontFor = (font: string): string => STANDARD_FONT_CSS[font] ?? `\"${font}\", sans-serif`;\n\n/** Project the model's free-text boxes into render-ready {@link TextItem}s — the\n * core geometry (`textBoxes`) joined with the DTO-derived CSS. Pure; memoized by\n * model identity at the call site so selectors get a stable reference. */\nexport function buildTextItems(m: Model, pon: number, view?: ViewEnv): TextItem[] {\n return textBoxes(m, pon, view).map((tb) => {\n const a = m.byId[tb.id];\n // `text`/`style` are the OPTIMISTIC content projections (a props edit lands\n // here before the engine round-trips), so the editor restyles instantly.\n const t = a?.text ?? initialTextStyle;\n // The text plate inset MIRRORS the engine's AP generator, so the DOM text\n // sits exactly where the baked text will land (WYSIWYG across the\n // baked↔live swap): callout body = border + 2 (`kCalloutTextPadding`),\n // plain free-text body = border width (two half-width deflates).\n const sw = a?.style.strokeWidth ?? 0;\n const isCallout = a?.geom.t === 'text' && !!a.geom.callout;\n return {\n id: tb.id,\n ref: a?.ref ?? null,\n box: tb.box,\n contents: a?.data?.contents ?? '',\n editing: tb.editing,\n ...(tb.rot ? { rot: tb.rot } : {}),\n css: {\n fontFamily: cssFontFor(t.fontFamily),\n fontSize: t.fontSize,\n lineHeight: t.fontSize, // CPVT lays out free-text at line-height ≈ font size\n color: t.fontColor,\n align: t.textAlign,\n padding: isCallout ? sw + 2 : sw,\n background: a?.style.interiorColor ?? null,\n },\n };\n });\n}\n","/**\n * The annotation TOOL registry — the one place that says which tools exist and\n * what each one authors. A tool is a named authoring PRESET, not a new kind: it\n * binds an `id` to a PDF `subtype`, a bag of per-tool `defaults`, a cursor, and\n * the interaction TAGS it turns on. Two tools can share a subtype but differ in\n * defaults (an \"arrow\" is a `line` with an arrowhead default), which is exactly\n * why defaults are keyed by the tool id (the `preset`), never by the subtype.\n *\n * The built-in {@link DEFAULT_TOOLS} reproduce v2's tool set; an embedder tweaks\n * or extends them with `annotationPlugin({ tools: [...] })`. Same-id entries MERGE\n * over the built-in (configure it); a new id ADDS a tool; `extends` inherits an\n * existing tool's subtype/cursor/tags so a preset is one line.\n */\nimport type {\n AnnotationFlags,\n AnnotationPropsPatch,\n ClickCreate,\n InkStraightenOptions,\n PropKey,\n Subtype,\n} from '@embedpdf/core-annotation';\nimport type { BinarySource, InkIntent } from '@embedpdf/engine-core/runtime';\n\n/**\n * How a stamp-family tool resolves the image bytes it places — pure DATA, so a\n * tool table stays JSON-serializable (config can come from a file, a DB, or the\n * server). Evaluated at CLICK time, so the user picks the spot first, then the\n * source:\n * - `{ kind: 'bytes' }` — fixed bytes: a company rubber-stamp.\n * - `{ kind: 'prompt' }` — ask the environment for bytes. The plugin does NOT\n * know how (a file dialog is DOM); the file-picker port (`FilePickerProvider`),\n * installed by the framework adapter, fulfils it. Resolve `null` there to cancel.\n */\nexport type StampSourceSpec = { kind: 'bytes'; source: BinarySource } | PromptSourceSpec;\n\n/**\n * The ask-the-environment resolution, shared by every click-then-pick tool\n * (a stamp's `'prompt'` source, the file-attachment tool). `accept` is the\n * file-dialog filter the picker request carries — a UX hint only, the engine\n * sniffs/validates the bytes for real. Unset = any file.\n */\nexport interface PromptSourceSpec {\n kind: 'prompt';\n accept?: string;\n}\n\n/** Declarative result of committing a text selection while a tool is active. */\nexport type SelectionAuthoring =\n | { kind: 'markup' }\n | { kind: 'text-edit'; operation: 'insert' | 'replace' };\n\n/**\n * The armed tool's IN-PAGE preview:\n * - `footprint` — the EXACT box a click would place, in the page (content\n * space, page-clamped, WYSIWYG). Meaningful only when the box is\n * determinable: an armed stamp payload, or a `clickCreate` size.\n * - `false` — no preview.\n * WHICH tool is armed is the CURSOR's job, not a ghost's: give the tool an\n * image cursor built from your toolbar icon (the hub's `setToolCursor` + the\n * web package's `svgCursor`), and the hub's claim/gap arbitration keeps it\n * honest over annotations, form fields, and page gaps.\n */\nexport type GhostPolicy = false | { mode: 'footprint' };\n\n/** Time/geometry policy for freehand ink authoring. */\nexport interface InkAuthoringOptions {\n /** Group strokes made within this interval into one `/InkList`; 0 commits immediately. */\n groupStrokesMs?: number;\n /** Optional pure straight-line recognition applied to each completed stroke. */\n straighten?: InkStraightenOptions;\n}\n\n/**\n * The creation properties each known authoring kind actually consumes. This is\n * deliberately separate from the flat internal patch vocabulary: it gives tool\n * configuration precise compile-time and runtime validation while mixed-selection\n * edits can keep using `AnnotationPropsPatch`.\n */\nexport const TOOL_DEFAULT_KEYS = {\n square: ['color', 'interiorColor', 'opacity', 'strokeWidth', 'border'],\n circle: ['color', 'interiorColor', 'opacity', 'strokeWidth', 'border'],\n line: ['color', 'interiorColor', 'opacity', 'strokeWidth', 'border', 'lineEndings'],\n polygon: ['color', 'interiorColor', 'opacity', 'strokeWidth', 'border'],\n polyline: ['color', 'interiorColor', 'opacity', 'strokeWidth', 'border', 'lineEndings'],\n ink: ['color', 'opacity', 'strokeWidth', 'blendMode'],\n 'free-text': [\n 'fontFamily',\n 'fontSize',\n 'fontColor',\n 'textAlign',\n 'opacity',\n 'interiorColor',\n 'color',\n 'strokeWidth',\n 'border',\n ],\n 'free-text-callout': [\n 'fontFamily',\n 'fontSize',\n 'fontColor',\n 'textAlign',\n 'opacity',\n 'interiorColor',\n 'color',\n 'strokeWidth',\n 'border',\n 'lineEndings',\n ],\n highlight: ['color', 'opacity', 'blendMode'],\n underline: ['color', 'opacity', 'blendMode'],\n strikeout: ['color', 'opacity', 'blendMode'],\n squiggly: ['color', 'opacity', 'blendMode'],\n caret: ['color', 'opacity'],\n redact: ['color', 'interiorColor', 'opacity', 'fontFamily', 'fontSize', 'fontColor', 'textAlign'],\n stamp: [],\n // A link preset may carry a FIXED target ('docs-link' style one-click links).\n link: ['link'],\n text: ['icon', 'color', 'opacity'],\n 'file-attachment': ['icon', 'color', 'opacity'],\n // Widget CLIENT kinds (the form plugin's palette tools): the same key sets\n // the kind table declares — box styling for every family, /DA text styling\n // for the text-bearing ones. The engine maps them onto /MK //BS //DA //Q.\n 'widget-text': [\n 'color',\n 'interiorColor',\n 'strokeWidth',\n 'border',\n 'fontFamily',\n 'fontSize',\n 'fontColor',\n 'textAlign',\n ],\n 'widget-choice': [\n 'color',\n 'interiorColor',\n 'strokeWidth',\n 'border',\n 'fontFamily',\n 'fontSize',\n 'fontColor',\n 'textAlign',\n ],\n 'widget-toggle': ['color', 'interiorColor', 'strokeWidth', 'border'],\n} as const satisfies Record<string, readonly PropKey[]>;\n\nexport type ToolAuthoringKind = keyof typeof TOOL_DEFAULT_KEYS;\ntype ToolDefaultKey<K extends ToolAuthoringKind> = (typeof TOOL_DEFAULT_KEYS)[K][number];\nexport type ToolDefaultsFor<K extends ToolAuthoringKind> = [ToolDefaultKey<K>] extends [never]\n ? never\n : Pick<AnnotationPropsPatch, ToolDefaultKey<K>>;\n\n/**\n * A tool definition — the public config vocabulary. Every field except `id` is\n * optional: the common cases are \"configure a built-in\" (`{ id, defaults }`) and\n * \"add a preset\" (`{ id, extends, defaults }`).\n */\nexport interface AnnotationToolDef<K extends ToolAuthoringKind = ToolAuthoringKind> {\n /** Stable tool id — the value passed to `activateTool` and the `defaults` key. */\n id: string;\n /** Inherit `subtype` / `propsKind` / `cursor` / `enables` / `source` /\n * `selection` / `intent` / `ink` / `meta`\n * from an existing tool id (a built-in or another entry). Own fields win. */\n extends?: string;\n /** The ROUTING KIND this tool authors — the core's client kind (the geometry\n * it draws + the props key). Usually the PDF subtype, but not always:\n * `free-text-callout` routes the callout gesture onto a free-text\n * annotation, and `widget-text`/`widget-choice`/`widget-toggle` are client\n * views of the ONE PDF `widget` subtype (a form tool's commit goes through\n * `doc.forms`, never this plugin — see the form plugin's tool table).\n * Defaults to the inherited kind, or the id when neither is given. */\n subtype?: Subtype;\n /** The kind whose editable-property specs a style panel shows for this tool.\n * Defaults to `subtype` (a callout authors `free-text` props, for example). */\n propsKind?: string;\n /** ADVANCED: the `defaults` key this tool reads/writes. Defaults to the id, and\n * that is almost always right — override it only to alias a shared defaults bag\n * (the built-in insert-caret tool points its preset at the `caret` key). */\n preset?: string;\n /** Seed defaults for newly drawn annotations — the flat AnnotationProps patch,\n * merged over any inherited defaults (line endings merge per side). */\n defaults?: ToolDefaultsFor<K>;\n /**\n * `/F` annotation flags seeded on everything this tool creates, merged over\n * the drawn default (`print` set — Acrobat parity) and any inherited seed.\n * A note tool passes `{ noZoom: true, noRotate: true }` so its icons stay\n * screen-sized and upright (the spec's rule for Text annotations).\n */\n flags?: Partial<AnnotationFlags>;\n /** The pointer cursor while this tool is active. Defaults inherited / `crosshair`. */\n cursor?: string;\n /** Interaction capability tags this tool enables (which handlers wake up). */\n enables?: string[];\n /**\n * How the click-to-place payload resolves. Stamps take the full spec\n * ({@link StampSourceSpec}: fixed bytes or prompt); file attachments are\n * prompt-only ({@link PromptSourceSpec} — the file always comes from the\n * environment). Other kinds carry no payload.\n */\n source?: K extends 'stamp'\n ? StampSourceSpec\n : K extends 'file-attachment'\n ? PromptSourceSpec\n : never;\n /** What a committed text selection authors. Omit for pointer/click tools. */\n selection?: SelectionAuthoring;\n /** PDF `/IT` authored by an intent-bearing ink preset. */\n intent?: K extends 'ink' ? InkIntent : never;\n /** Ink-only stroke grouping and straightening policy. */\n ink?: K extends 'ink' ? InkAuthoringOptions : never;\n /**\n * Place annotations UPRIGHT: counter-rotate what this tool creates against the\n * page's TOTAL display rotation (document /Rotate + any stage view rotation),\n * so it reads horizontally exactly as the author saw it — Adobe's behaviour\n * for stamps and text on rotated pages. WYSIWYG at authoring time: the\n * rotation is baked into the annotation, so a save keeps what the author saw\n * (other viewers apply only /Rotate — document that when view rotation is in\n * play). Box kinds only (stamp / free-text, where reading orientation is\n * meaningful); ignored by vertex kinds and callouts. Default: on for the\n * built-in `stamp` and `free-text` tools, off elsewhere.\n */\n upright?: boolean;\n /**\n * What a bare CLICK creates (v2's `clickBehavior`): a default-size shape\n * centred on the point / a default-length line from it / free-text's\n * type-here box — page-clamped, in PDF pt. `false` = drag-only. Defaults:\n * on for the built-in square/circle/line/free-text, off elsewhere.\n */\n clickCreate?: ClickCreate | false;\n /**\n * The armed-tool in-page preview ({@link GhostPolicy}). Defaults: inherited,\n * else off (the built-in stamp declares `footprint`).\n */\n ghost?: GhostPolicy;\n /** Opaque presentation hints (label/icon…) for a toolbar or cursor that builds\n * itself from the tool table. Never read by the plugin or the interaction hub. */\n meta?: Record<string, unknown>;\n}\n\nexport interface BuiltinToolKindMap {\n square: 'square';\n circle: 'circle';\n line: 'line';\n polygon: 'polygon';\n polyline: 'polyline';\n ink: 'ink';\n 'ink-highlight': 'ink';\n 'free-text': 'free-text';\n 'free-text-callout': 'free-text-callout';\n highlight: 'highlight';\n underline: 'underline';\n strikeout: 'strikeout';\n squiggly: 'squiggly';\n 'insert-text': 'caret';\n 'replace-text': 'strikeout';\n redact: 'redact';\n stamp: 'stamp';\n note: 'text';\n attachment: 'file-attachment';\n link: 'link';\n}\n\ntype DirectToolDef = {\n [K in ToolAuthoringKind]: Omit<AnnotationToolDef<K>, 'subtype'> & { subtype: K };\n}[ToolAuthoringKind];\ntype BuiltinToolOverride = {\n [I in keyof BuiltinToolKindMap]: Omit<\n AnnotationToolDef<BuiltinToolKindMap[I]>,\n 'id' | 'extends' | 'subtype'\n > & {\n id: I;\n extends?: never;\n subtype?: never;\n };\n}[keyof BuiltinToolKindMap];\ntype ExtendedBuiltinToolDef = {\n [I in keyof BuiltinToolKindMap]: Omit<\n AnnotationToolDef<BuiltinToolKindMap[I]>,\n 'extends' | 'subtype'\n > & {\n extends: I;\n subtype?: never;\n };\n}[keyof BuiltinToolKindMap];\n\n/** Public tool input: known overrides, known-base presets, or an explicit subtype. */\nexport type AnnotationToolInput = DirectToolDef | BuiltinToolOverride | ExtendedBuiltinToolDef;\n\n/** A fully-resolved tool — what the plugin, handlers, and registration loop read. */\nexport interface ResolvedTool {\n id: string;\n /** Routing token for the draw core + the created annotation's PDF subtype. */\n subtype: Subtype;\n /** The `defaults` key (always the tool id) — keeps same-subtype tools apart. */\n preset: string;\n /** The `propsFor` key for the style panel. */\n propsKind: string;\n cursor: string;\n enables: ReadonlySet<string>;\n defaults?: AnnotationPropsPatch;\n /** `/F` seed for created annotations (see {@link AnnotationToolDef.flags}). */\n flags?: Partial<AnnotationFlags>;\n source?: StampSourceSpec;\n selection?: SelectionAuthoring;\n intent?: InkIntent;\n ink?: InkAuthoringOptions;\n /** Counter-rotate creations against the page's display rotation (see\n * {@link AnnotationToolDef.upright}). */\n upright: boolean;\n /** What a bare click creates, or `false` for drag-only. */\n clickCreate: ClickCreate | false;\n /** The armed-tool in-page preview ({@link GhostPolicy}). */\n ghost: GhostPolicy;\n meta?: Record<string, unknown>;\n}\n\n// ── field groups shared by the built-ins (keeps the table readable) ──────────\nconst DRAW_TAGS = ['annotation-draw', 'annotation-edit'];\nconst MARKUP_TAGS = ['text-select', 'annotation-edit'];\n\n/**\n * Whether arming this ANNOTATION tool is touch consent (`Tool.touchDirect`):\n * drag-CREATE tools — shape/ink draw and text-markup select — take\n * single-finger touch wholesale (finger draws/marks, two fingers navigate:\n * the drawing-app convention). Click-to-PLACE tools (stamp, note) do not: a\n * tap places without any claim, and drags keep scrolling. Derived from the\n * gesture tags, so custom registered tools inherit the right behavior. Only\n * annotation-owned tools run through this — the built-in `pointer` tool also\n * enables `text-select`, but it is registered by the hub, not here.\n */\nexport const isTouchDirect = (enables: ReadonlySet<string>): boolean =>\n enables.has('annotation-draw') || enables.has('text-select');\n\n/**\n * The built-in tools — a data mirror of v2's registrations (shapes + lines + ink\n * + free text in the draw channel, text markup + caret behind text selection, and\n * the click-to-place stamp). Order is display-neutral; the toolbar owns layout.\n */\nexport const DEFAULT_TOOLS: AnnotationToolInput[] = [\n // shapes / lines / ink / free text — the `annotation-draw` gesture.\n // Draw tools carry v2's click-create defaults (a bare click places a\n // default-size annotation); armed-tool identity rides the cursor, so none\n // of them needs a ghost.\n {\n id: 'square',\n subtype: 'square',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { strokeWidth: 6 },\n clickCreate: { width: 80, height: 60 },\n },\n {\n id: 'circle',\n subtype: 'circle',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { strokeWidth: 6 },\n clickCreate: { width: 80, height: 60 },\n },\n {\n id: 'line',\n subtype: 'line',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { strokeWidth: 6 },\n clickCreate: { length: 80 },\n },\n {\n id: 'polygon',\n subtype: 'polygon',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { strokeWidth: 6 },\n },\n {\n id: 'polyline',\n subtype: 'polyline',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { strokeWidth: 6 },\n },\n {\n id: 'ink',\n subtype: 'ink',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { color: '#ef4444', strokeWidth: 6, blendMode: 'normal' },\n ink: { groupStrokesMs: 800 },\n },\n {\n id: 'ink-highlight',\n extends: 'ink',\n intent: 'ink-highlight',\n defaults: { color: '#ffcd45', strokeWidth: 14, blendMode: 'multiply' },\n ink: {\n straighten: { deviationThreshold: 0.15, axisSnapDegrees: 15 },\n },\n },\n {\n id: 'free-text',\n subtype: 'free-text',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { fontColor: '#ef4444' },\n upright: true,\n // Top-left anchored: the box hangs where you'll type (the kind's reading\n // feel); shapes default to `center`. Anchoring is explicit policy data.\n clickCreate: { width: 180, height: 40, anchor: 'top-left' },\n },\n {\n // Routes on the `free-text-callout` subtype token but authors a `free-text`\n // annotation (leader + box). Its leader defaults to an open arrowhead.\n // `upright` applies to the text BOX only: on a rotated page it commits\n // counter-rotated (readable), while the leader tip/knee stay page-space\n // anchors — see the core's `calloutPointer`.\n id: 'free-text-callout',\n subtype: 'free-text-callout',\n propsKind: 'free-text',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n defaults: { strokeWidth: 6, lineEndings: { end: 'open-arrow' } },\n upright: true,\n },\n // text markup — the `text-select` gesture (inert without a selection plugin).\n // Base cursor is the plain arrow: the I-beam appears only where the action is\n // possible, via the selection handler's over-text claim (which an app can\n // reskin with the tool's icon — see the hub's ToolCursorSkin).\n {\n id: 'highlight',\n subtype: 'highlight',\n cursor: 'default',\n enables: MARKUP_TAGS,\n defaults: { color: '#ffe16a', blendMode: 'multiply' },\n selection: { kind: 'markup' },\n },\n // Redaction marking — the COMPOSED tool: over text it rides the selection\n // gesture (per-line quad marks, like a highlight); anywhere else it drag-\n // draws an area mark. One tool, both modes; the destructive apply lives in\n // plugin-redaction.\n {\n id: 'redact',\n subtype: 'redact',\n cursor: 'crosshair',\n enables: ['text-select', 'annotation-draw', 'annotation-edit'],\n defaults: {\n color: '#e44234',\n interiorColor: '#000000',\n fontColor: '#ffffff',\n opacity: 1,\n },\n selection: { kind: 'markup' },\n },\n {\n id: 'underline',\n subtype: 'underline',\n cursor: 'default',\n enables: MARKUP_TAGS,\n defaults: { color: '#ef4444' },\n selection: { kind: 'markup' },\n },\n {\n id: 'strikeout',\n subtype: 'strikeout',\n cursor: 'default',\n enables: MARKUP_TAGS,\n defaults: { color: '#ef4444' },\n selection: { kind: 'markup' },\n },\n {\n id: 'squiggly',\n subtype: 'squiggly',\n cursor: 'default',\n enables: MARKUP_TAGS,\n defaults: { color: '#ef4444' },\n selection: { kind: 'markup' },\n },\n {\n // The insert-caret tool authors a `caret` from a text selection. Its defaults\n // live under the `caret` preset — the key `createCaret` resolves.\n id: 'insert-text',\n subtype: 'caret',\n propsKind: 'caret',\n preset: 'caret',\n cursor: 'default',\n enables: MARKUP_TAGS,\n defaults: { color: '#ef4444' },\n selection: { kind: 'text-edit', operation: 'insert' },\n },\n {\n id: 'replace-text',\n subtype: 'strikeout',\n propsKind: 'strikeout',\n cursor: 'default',\n enables: MARKUP_TAGS,\n defaults: { color: '#ef4444' },\n selection: { kind: 'text-edit', operation: 'replace' },\n },\n // stamp — click-to-place; 'prompt' asks the environment through the ONE\n // file-picker port (the React adapter wires a file dialog by default; an\n // embedder can pass fixed bytes instead). `accept` narrows the dialog to\n // what the engine's stamp sniffer takes anyway.\n {\n id: 'stamp',\n subtype: 'stamp',\n cursor: 'copy',\n enables: ['annotation-place', 'annotation-edit'],\n source: { kind: 'prompt', accept: 'image/png,image/jpeg,application/pdf' },\n upright: true,\n ghost: { mode: 'footprint' },\n },\n // link — drag an invisible hit rectangle; the target is set afterwards\n // through the selection editor (create-then-edit), unless a preset carries\n // a fixed one (`{ id: 'docs-link', extends: 'link', defaults: { link: … } }`).\n // While this tool is active the navigation plane stands down (no `link-nav`),\n // so existing links become plain editable rects.\n {\n id: 'link',\n subtype: 'link',\n cursor: 'crosshair',\n enables: DRAW_TAGS,\n },\n // sticky note (\"comment\") — click-to-place, no payload: each click drops a\n // fixed 20×20 icon (engine-baked /AP from /C + /Name), screen-sized and\n // upright per the spec's Text-icon rule (the noZoom/noRotate seed).\n {\n id: 'note',\n subtype: 'text',\n cursor: 'crosshair',\n enables: ['annotation-place', 'annotation-edit'],\n defaults: { icon: 'comment', color: '#facc15' },\n flags: { noZoom: true, noRotate: true },\n upright: true,\n ghost: { mode: 'footprint' },\n },\n // file attachment — click-to-place with the spot-first-file-second rule:\n // the click opens the installed file-picker port (a file dialog by\n // default; `accept` unset = any file — attaching any format is the point);\n // the picked file embeds at the clicked point.\n {\n id: 'attachment',\n subtype: 'file-attachment',\n cursor: 'copy',\n enables: ['annotation-place', 'annotation-edit'],\n source: { kind: 'prompt' },\n defaults: { icon: 'paperclip', color: '#facc15' },\n flags: { noZoom: true, noRotate: true },\n upright: true,\n ghost: { mode: 'footprint' },\n },\n];\n\n/** Merge two default patches, `b` over `a`, with line endings merged per side. */\nfunction mergeDefaults(\n a?: AnnotationPropsPatch,\n b?: AnnotationPropsPatch,\n): AnnotationPropsPatch | undefined {\n if (!a) return b;\n if (!b) return a;\n const merged: AnnotationPropsPatch = { ...a, ...b };\n if (a.lineEndings || b.lineEndings) merged.lineEndings = { ...a.lineEndings, ...b.lineEndings };\n return merged;\n}\n\n/** Overlay a same-id override onto a base definition (configure a built-in). */\nfunction mergeDef(base: AnnotationToolDef, over: AnnotationToolDef): AnnotationToolDef {\n return {\n ...base,\n ...over,\n enables: over.enables ?? base.enables,\n meta: base.meta || over.meta ? { ...base.meta, ...over.meta } : undefined,\n defaults: mergeDefaults(base.defaults, over.defaults),\n flags: base.flags || over.flags ? { ...base.flags, ...over.flags } : undefined,\n ink: base.ink || over.ink ? { ...base.ink, ...over.ink } : undefined,\n };\n}\n\nfunction validateDefaults(tool: ResolvedTool): void {\n if (!tool.defaults) return;\n const allowed = TOOL_DEFAULT_KEYS[tool.subtype as ToolAuthoringKind];\n // Unknown/custom routing kinds remain extensible; known built-ins are strict.\n if (!allowed) return;\n const keys = new Set<string>(allowed);\n for (const key of Object.keys(tool.defaults)) {\n if (!keys.has(key)) {\n throw new Error(\n `[annotation] tool '${tool.id}' does not support default '${key}' for '${tool.subtype}'`,\n );\n }\n }\n}\n\n/**\n * Resolve {@link DEFAULT_TOOLS} + embedder overrides into the ready-to-use table.\n * A same-id override merges over the built-in; a new id adds a tool; `extends`\n * inherits from an already-defined tool. Keyed by id, so lookups are O(1).\n */\nexport function buildToolRegistry(\n overrides: AnnotationToolInput[] = [],\n): Map<string, ResolvedTool> {\n const defs = new Map<string, AnnotationToolDef>();\n for (const d of DEFAULT_TOOLS) defs.set(d.id, d);\n for (const o of overrides) {\n const prev = defs.get(o.id);\n defs.set(o.id, prev ? mergeDef(prev, o) : o);\n }\n\n const out = new Map<string, ResolvedTool>();\n const resolving = new Set<string>();\n const resolve = (id: string): ResolvedTool => {\n const cached = out.get(id);\n if (cached) return cached;\n const def = defs.get(id);\n if (!def) throw new Error(`[annotation] tool '${id}' extends an unknown tool`);\n // Inherit from the base first (guarding self / cyclic extends), then own fields win.\n let base: ResolvedTool | undefined;\n if (def.extends && def.extends !== id && !resolving.has(def.extends)) {\n resolving.add(id);\n base = resolve(def.extends);\n resolving.delete(id);\n }\n const subtype = (def.subtype ?? base?.subtype ?? def.id) as Subtype;\n const resolved: ResolvedTool = {\n id: def.id,\n subtype,\n preset: def.preset ?? def.id,\n propsKind: def.propsKind ?? base?.propsKind ?? subtype,\n cursor: def.cursor ?? base?.cursor ?? 'crosshair',\n enables: new Set(def.enables ?? (base ? [...base.enables] : [])),\n defaults: mergeDefaults(base?.defaults, def.defaults),\n flags: base?.flags || def.flags ? { ...base?.flags, ...def.flags } : undefined,\n source: def.source ?? base?.source,\n selection: def.selection ?? base?.selection,\n intent: def.intent ?? base?.intent,\n ink: base?.ink || def.ink ? { ...base?.ink, ...def.ink } : undefined,\n upright: def.upright ?? base?.upright ?? false,\n clickCreate: def.clickCreate ?? base?.clickCreate ?? false,\n ghost: def.ghost ?? base?.ghost ?? false,\n meta: base?.meta || def.meta ? { ...base?.meta, ...def.meta } : undefined,\n };\n validateDefaults(resolved);\n out.set(id, resolved);\n return resolved;\n };\n for (const id of defs.keys()) resolve(id);\n return out;\n}\n","import type {\n AnnotationDraft,\n AnnotationFlags,\n AttachmentFileSource,\n FileAttachmentIcon,\n NoteIcon,\n PdfRect,\n} from '@embedpdf/engine-core/runtime';\nimport type { AnnotationProps, Subtype } from '@embedpdf/core-annotation';\n\nimport { cssToColor } from './repository';\n\n/**\n * Per-kind CODE for the click-to-place ICON kinds (note / file attachment)\n * — the `props.ts`/`repository.ts` pattern: all tool CONFIG stays in the\n * tool table; this module only interprets it. The stamp keeps its own\n * sizing/sniffing path in the capability; everything funnels through the\n * one `placeAt` entry there.\n */\n\n/**\n * Icon kinds place at the generator's fixed box: the engine forces the\n * `/Rect` to 20×20 from its bottom-left corner (the spec's note-icon rule),\n * so the footprint ghost and the placement use exactly this size.\n */\nexport const ICON_PLACE_SIZE = { width: 20, height: 20 } as const;\n\nexport type IconPlaceKind = 'text' | 'file-attachment';\n\nexport const isIconPlaceKind = (subtype: Subtype): subtype is IconPlaceKind =>\n subtype === 'text' || subtype === 'file-attachment';\n\n/**\n * Build the engine create draft for a placed icon annotation. `geom` is the\n * repository's `boxGeomFields` emit (the `/Rect` + upright rotation pair);\n * `defaults` is the tool's resolved flat props bag (`defaultsFor`) — the\n * colour seam is crossed here via the repository's `cssToColor`, and the\n * icon falls back to the kind's own default when the bag carries none.\n */\nexport function iconPlacementDraft(\n subtype: IconPlaceKind,\n geom: { rect: PdfRect; rotation?: number | null; unrotatedRect?: PdfRect | null },\n defaults: AnnotationProps,\n flags: Partial<AnnotationFlags> | undefined,\n file: AttachmentFileSource | null,\n): AnnotationDraft {\n const shared = {\n ...geom,\n color: cssToColor(defaults.color),\n opacity: defaults.opacity,\n // A fresh placement carries print (Acrobat parity) plus the tool's seed\n // (the note/attachment tools pass noZoom + noRotate).\n flags: { print: true, ...flags },\n };\n if (subtype === 'text') {\n return { subtype: 'text', icon: (defaults.icon as NoteIcon) ?? 'comment', ...shared };\n }\n if (!file) {\n throw new Error('[annotation] a file-attachment placement requires a file payload');\n }\n return {\n subtype: 'file-attachment',\n icon: (defaults.icon as FileAttachmentIcon) ?? 'paperclip',\n file,\n ...shared,\n };\n}\n","import {\n CONTINUOUS_RENDER_POLICY,\n snapAppearanceScale,\n type DocumentEvent,\n type PluginContext,\n} from '@embedpdf/core';\nimport type { PageRotation } from '@embedpdf/core-geometry';\nimport {\n buildCommentThreads,\n encodeStableIdKey,\n resolveBinarySource,\n sniffBinaryMetadata,\n type CommentThread,\n type AnnotationDraft,\n type AnnotationDTO,\n type AnnotationPatch,\n type AnnotationRef,\n type AttachmentFileSource,\n type BinarySource,\n type PdfLinkTarget,\n type PdfRect,\n} from '@embedpdf/engine-core/runtime';\nimport { ActionsToken as PublicActionsToken } from '@embedpdf/plugin-actions/contract';\nimport { scriptColorToRgb } from '@embedpdf/core-acrojs';\nimport type { ScriptAnnotEffect, ScriptColorArray } from '@embedpdf/core-acrojs';\nimport type { AnnotCommitResult } from '@embedpdf/plugin-actions/contract/host';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract';\nimport { SelectionToken as SelectionPublicToken } from '@embedpdf/plugin-selection/contract';\nimport {\n canMove,\n chrome as coreChrome,\n clickCreateGeom,\n contentToPdfRect,\n creationDraftAnchor as coreCreationDraftAnchor,\n cursorAt,\n defaultsFor,\n expandGroups,\n FLAG_KEYS,\n fitStampBox,\n geomVisualBounds,\n groupKeyOf,\n hitTest,\n pageItems as corePageItems,\n pdfToContentRect,\n propsFor,\n readProp,\n resolveClickPlacement,\n selectionAnchor as coreSelectionAnchor,\n sharedProps,\n styleFromProps,\n update,\n annotContentsEditable,\n annotDeletable,\n annotTransformable,\n isSubstrateOnly,\n linkChildrenOf,\n linkOf,\n uprightRotation,\n viewable,\n type Annot,\n type AnnotationProps,\n type ChromeGeom,\n type ChromeNode,\n type CreationDraftAnchor,\n type Effect,\n type Geom,\n type Id,\n type Model,\n type Msg,\n type PropKey,\n type Rect,\n type RenderItem,\n type Subtype,\n type Vec,\n type ViewEnv,\n} from '@embedpdf/core-annotation';\nimport {\n boxGeomFields,\n fromDTO,\n linkChildRects,\n refKey,\n toCreateDraft,\n toPatch,\n toScopedPatch,\n writableTarget,\n} from './repository';\nimport { createAnnotationHoverFeed } from './hover-feed';\nimport { buildTextItems } from './text-item';\nimport { buildToolRegistry, isTouchDirect } from './tools';\nimport type { AnnotationToolInput, ResolvedTool } from './tools';\nimport type {\n AnnotationAction,\n AnnotationConfig,\n AnnotationHostCapability,\n AnnotationHydration,\n AnnotationState,\n ArmedStampPreview,\n CommentPermissions,\n CommentsApi,\n ThreadDeleteResult,\n Behavior,\n ChromeSettings,\n SelectionFlags,\n SelectionProps,\n FilePickerProvider,\n FilePromptRequest,\n LinkNavItem,\n StampToolInput,\n TextItem,\n} from './types';\nimport { ICON_PLACE_SIZE, iconPlacementDraft, isIconPlaceKind } from './placement';\n\n/** Fold `zoom`/`rotation` host args into the core's ViewEnv (or none).\n * `zoom` is the page's RELATIVE zoom (`transform.zoom`) — never the\n * px-per-point `scale` (that one only converts CSS-px chrome settings). */\nconst viewEnv = (zoom?: number, rotation?: number): ViewEnv | undefined =>\n zoom != null || rotation != null\n ? { zoom: zoom ?? 1, rotation: (rotation ?? 0) as ViewEnv['rotation'] }\n : undefined;\n\nconst TEXT_COMMIT_DEBOUNCE_MS = 250;\n\n/**\n * The annotation shell. The pure `update` runs HERE (so it can emit effects);\n * the resulting model is dispatched to the store, and each effect is performed\n * against the engine repository — optimistic create → reconcile to the durable\n * ref, patch/delete fire-and-forget.\n */\nexport function createAnnotationCapability(\n ctx: PluginContext<AnnotationState, AnnotationAction>,\n config: AnnotationConfig = {},\n): AnnotationHostCapability {\n const behaviors: Behavior[] = [];\n /** Per-annotation debounce timer for the engine `contents` write while typing. */\n const textTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n // The resolved tool table (built-ins + config overrides). A tool is a named\n // authoring preset: it maps its id → a routing subtype, a `defaults` key\n // (`preset`), a `propsFor` kind, and — for stamps — a source spec. `configTools`\n // is kept so `registerTool` can re-resolve `extends` against the same base pool.\n const configTools = config.tools ?? [];\n const registry = buildToolRegistry(configTools);\n /** The installed file-picker port (a DOM file dialog, wired by the framework\n * adapter), or null — every click-then-pick tool resolves through this ONE\n * slot. See {@link FilePickerProvider}. */\n let filePickerProvider: FilePickerProvider | null = null;\n\n const model = (): Model => ctx.getState().model;\n\n // The E/X trigger feed (actions plugin present): driven ONLY from the\n // pointer-driven hoverAt diff below — see hover-feed.ts for the law.\n const actionsForHover = ctx.tryGet(PublicActionsToken);\n const hoverFeed = actionsForHover\n ? createAnnotationHoverFeed(actionsForHover, (id) => model().byId[id] ?? null)\n : null;\n const chromeSettings = (): ChromeSettings => ctx.getState().chrome;\n\n /**\n * Ids on a page whose Behavior is currently ENGAGED (form widgets under a\n * fill tool): they render their own DOM, so hit-test/marquee must not see\n * them. Resolved per event — engagement follows the active tool live.\n */\n const inertIdsAt = (pon: number): ReadonlySet<Id> | undefined => {\n if (!behaviors.length) return undefined;\n const m = model();\n let out: Set<Id> | undefined;\n for (const id of m.order) {\n const a = m.byId[id];\n if (!a || a.pon !== pon) continue;\n if (behaviors.some((b) => b.matches({ subtype: a.subtype, ref: a.ref }) && b.engaged())) {\n (out ??= new Set()).add(id);\n }\n }\n return out;\n };\n\n /** The CSS-px chrome settings converted to CONTENT units by the page's view\n * scale (px per content unit) — screen-constant grab zones + stalk at every\n * zoom. No scale → the values are read as content units (headless callers).\n * `boost` widens the GRAB tolerances only (never the drawn chrome or the\n * knob's position) — the touch path passes {@link TOUCH_GRAB_BOOST} so\n * handles present finger-sized targets. */\n const chromeGeomAt = (scale?: number, boost = 1): ChromeGeom => {\n const cs = chromeSettings();\n const s = scale || 1;\n return {\n handleTol: (cs.handles.hitSize / 2 / s) * boost,\n knobTol: (cs.knob.hitSize / 2 / s) * boost,\n knobOffset: cs.knob.offset / s,\n };\n };\n /** Finger-sized grab zones: 2× the mouse tolerances lands a ~24px handle hit\n * box in Apple's ~44pt-target territory without moving any visuals. */\n const TOUCH_GRAB_BOOST = 2;\n const grabBoost = (touch?: boolean): number => (touch ? TOUCH_GRAB_BOOST : 1);\n\n // Memoize the derived per-page arrays by input identity, so a selector returns\n // a STABLE reference between dispatches (useSyncExternalStore needs this — the\n // model object only changes when `update` produces a new one; chrome also keys\n // on the settings object + the page scale it was projected with).\n const itemsCache = new Map<\n number,\n {\n model: Model;\n ghost: AnnotationState['toolGhost'];\n zoom: number | undefined;\n rotation: number | undefined;\n v: RenderItem[];\n }\n >();\n const chromeCache = new Map<\n number,\n {\n model: Model;\n cs: ChromeSettings;\n scale: number | undefined;\n rotation: number | undefined;\n zoom: number | undefined;\n v: ChromeNode[];\n }\n >();\n const memoItems = (pon: number, view?: ViewEnv): RenderItem[] => {\n const m = model();\n const g = ctx.getState().toolGhost;\n const c = itemsCache.get(pon);\n if (\n c &&\n c.model === m &&\n c.ghost === g &&\n c.zoom === view?.zoom &&\n c.rotation === view?.rotation\n )\n return c.v;\n const v = corePageItems(m, pon, view);\n // The armed tool's VECTOR footprint ghost rides the same items pipeline as\n // every draft preview (image ghosts blit through the framework instead).\n if (g && g.pon === pon && g.kind === 'vector') {\n const tool = registry.get(g.toolId);\n const style = styleFromProps(defaultsFor(m, tool?.preset ?? g.toolId));\n v.push({\n id: 'tool-ghost',\n ref: null,\n subtype: tool?.subtype ?? 'square',\n geom: g.geom,\n box: g.box,\n style,\n source: 'ghost',\n selected: false,\n });\n }\n itemsCache.set(pon, { model: m, ghost: g, zoom: view?.zoom, rotation: view?.rotation, v });\n return v;\n };\n const memoChrome = (\n pon: number,\n scale?: number,\n rotation?: number,\n zoom?: number,\n ): ChromeNode[] => {\n const m = model();\n const cs = chromeSettings();\n const c = chromeCache.get(pon);\n if (\n c &&\n c.model === m &&\n c.cs === cs &&\n c.scale === scale &&\n c.rotation === rotation &&\n c.zoom === zoom\n )\n return c.v;\n let v = coreChrome(\n m,\n pon,\n pageBoxOf(pon),\n chromeGeomAt(scale).knobOffset,\n viewEnv(zoom, rotation),\n );\n // `guides.enabled` is presentation config, filtered HERE so the emitted\n // chrome stays authoritative for every painter (default and headless alike).\n if (!cs.guides.enabled) v = v.filter((n) => n.kind !== 'rotate-guides');\n chromeCache.set(pon, { model: m, cs, scale, rotation, zoom, v });\n return v;\n };\n // Anchor for the selection menu — memoized by input identity so the selector\n // returns a stable reference between unrelated dispatches.\n let anchorCache: {\n model: Model;\n cs: ChromeSettings;\n scale: number | undefined;\n rotation: number | undefined;\n zoom: number | undefined;\n v: { pon: number; bounds: Rect; knob?: Vec } | null;\n } | null = null;\n const memoAnchor = (\n scale?: number,\n rotation?: number,\n zoom?: number,\n ): { pon: number; bounds: Rect; knob?: Vec } | null => {\n const m = model();\n const cs = chromeSettings();\n if (\n anchorCache &&\n anchorCache.model === m &&\n anchorCache.cs === cs &&\n anchorCache.scale === scale &&\n anchorCache.rotation === rotation &&\n anchorCache.zoom === zoom\n )\n return anchorCache.v;\n const v = coreSelectionAnchor(\n m,\n pageBoxOf,\n () => chromeGeomAt(scale).knobOffset,\n () => viewEnv(zoom, rotation),\n );\n anchorCache = { model: m, cs, scale, rotation, zoom, v };\n return v;\n };\n let draftAnchorCache: { model: Model; v: CreationDraftAnchor | null } | null = null;\n const memoDraftAnchor = (): CreationDraftAnchor | null => {\n const m = model();\n if (draftAnchorCache && draftAnchorCache.model === m) return draftAnchorCache.v;\n const v = coreCreationDraftAnchor(m);\n draftAnchorCache = { model: m, v };\n return v;\n };\n // The selection's property schema + values — memoized by model identity so a\n // subscribed sidebar re-renders only when the model actually changed.\n let selPropsCache: { model: Model; v: SelectionProps } | null = null;\n const memoSelectionProps = (): SelectionProps => {\n const m = model();\n if (selPropsCache && selPropsCache.model === m) return selPropsCache.v;\n const members = m.selected.map((id) => m.byId[id]).filter((a): a is Annot => !!a);\n const specs = sharedProps(members.map((a) => a.subtype));\n const values: Partial<AnnotationProps> = {};\n const mixed: PropKey[] = [];\n // `link` is the one derived value: parents store nothing — the committed\n // children are the truth, read through the lens (the link KIND still\n // reads its own /A off the annot).\n const valueOf = (a: Annot, key: PropKey): unknown =>\n key === 'link' && a.subtype !== 'link' ? linkOf(m, a.id) : readProp(a, key);\n for (const spec of specs) {\n const first = valueOf(members[0], spec.key);\n (values as Record<PropKey, unknown>)[spec.key] = first;\n const firstJson = JSON.stringify(first);\n if (members.some((a) => JSON.stringify(valueOf(a, spec.key)) !== firstJson))\n mixed.push(spec.key);\n }\n const v: SelectionProps = { specs, values, mixed };\n selPropsCache = { model: m, v };\n return v;\n };\n // The navigation plane's feed: clickable link areas per page — standalone\n // links + attached-link segments (rects derived by the reconciler's own\n // rule). Memoized by model identity for selector use.\n const linkItemsCache = new Map<number, { model: Model; v: LinkNavItem[] }>();\n const memoLinkItems = (pon: number): LinkNavItem[] => {\n const m = model();\n const c = linkItemsCache.get(pon);\n if (c && c.model === m) return c.v;\n const v: LinkNavItem[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (!a || a.pon !== pon || a.subtype !== 'link') continue;\n if (!viewable(a.flags, false)) continue; // hidden links don't navigate\n // Standalone links carry their own model `link` (/A); attached children\n // carry the target on their DTO. Rects are the CHILD's own committed\n // geometry — anchors render only in view contexts, where nothing is\n // mid-gesture, so no live parent-derivation is needed.\n const target =\n a.link ?? (a.data?.subtype === 'link' ? (a.data.target ?? null) : null);\n if (target == null || a.geom.t !== 'rect') continue;\n const activate = a.data?.actions?.activate;\n const ref = a.ref ?? a.data?.ref ?? undefined;\n const hoverEnter = Boolean(a.data?.actions?.cursorEnter?.root);\n const hoverExit = Boolean(a.data?.actions?.cursorExit?.root);\n v.push({\n id,\n rect: a.geom.rect,\n target,\n attached: a.group !== undefined,\n ...(activate ? { activate } : {}),\n ...(ref ? { ref } : {}),\n ...(hoverEnter || hoverExit\n ? { hoverEvents: { enter: hoverEnter, exit: hoverExit } }\n : {}),\n });\n }\n linkItemsCache.set(pon, { model: m, v });\n return v;\n };\n\n const textsCache = new Map<\n number,\n { model: Model; zoom: number | undefined; rotation: number | undefined; v: TextItem[] }\n >();\n const memoTexts = (pon: number, view?: ViewEnv): TextItem[] => {\n const m = model();\n const c = textsCache.get(pon);\n if (c && c.model === m && c.zoom === view?.zoom && c.rotation === view?.rotation) return c.v;\n const v = buildTextItems(m, pon, view);\n textsCache.set(pon, { model: m, zoom: view?.zoom, rotation: view?.rotation, v });\n return v;\n };\n // The selection's `/F` state — per-flag value, `null` where members disagree.\n let selFlagsCache: { model: Model; v: SelectionFlags | null } | null = null;\n const memoSelectionFlags = (): SelectionFlags | null => {\n const m = model();\n if (selFlagsCache && selFlagsCache.model === m) return selFlagsCache.v;\n const members = m.selected.map((id) => m.byId[id]).filter((a): a is Annot => !!a);\n let v: SelectionFlags | null = null;\n if (members.length) {\n v = {} as SelectionFlags;\n for (const key of FLAG_KEYS) {\n const first = members[0].flags[key];\n v[key] = members.every((a) => a.flags[key] === first) ? first : null;\n }\n }\n selFlagsCache = { model: m, v };\n return v;\n };\n const cropOf = (pon: number) =>\n ctx.document()?.pages.find((p) => p.pageObjectNumber === pon)?.boxes.crop ?? null;\n /** The page's box in content space (origin at the crop top-left) — the box\n * pointer gestures clamp to, so annotations stay page-bound. */\n const pageBoxOf = (pon: number): Rect | undefined => {\n const crop = cropOf(pon);\n return crop\n ? { x: 0, y: 0, width: crop.right - crop.left, height: crop.top - crop.bottom }\n : undefined;\n };\n\n /**\n * The armed stamp-tool payload: the bytes the next click places, plus the\n * PDF-point placement size (derived from the sniffed intrinsic aspect).\n * Transient tool state — deliberately NOT in the model: it is never\n * rendered, never synced, and dies with the tool.\n */\n // The DESIRED placement size (PDF points, pre page-clamp): the image's own\n // intrinsic size unless the caller overrides it. Clamping to the page happens\n // at placement, since it depends on which page (and rotation) receives it.\n // `preview` is the browser-paintable render for the hover ghost — transient\n // tool state like the bytes themselves, so it lives here, not in the store.\n let armedStamp: {\n source: BinarySource;\n width: number;\n height: number;\n preview: ArmedStampPreview | null;\n } | null = null;\n\n /**\n * The desired stamp size (PDF points) from sniffed bytes: the image's\n * INTRINSIC pixel dimensions taken 1:1 as points (the v2 rule — keep the\n * artwork's own size, then clamp to the page at placement). A `targetWidth`\n * override scales to that width, aspect preserved. Vector (PDF) stamps carry\n * no sniffable dimensions — a caller-supplied `intrinsic` override (a stamp\n * library knows its page size) keeps the true aspect; without one they fall\n * back to a square target.\n */\n const desiredStampSize = (\n meta: NonNullable<ReturnType<typeof sniffBinaryMetadata>>,\n targetWidth?: number,\n intrinsicOverride?: { width: number; height: number },\n ): { width: number; height: number } => {\n const intrinsic =\n intrinsicOverride && intrinsicOverride.width > 0 && intrinsicOverride.height > 0\n ? intrinsicOverride\n : 'width' in meta && meta.width > 0\n ? { width: meta.width, height: meta.height }\n : { width: targetWidth ?? 150, height: targetWidth ?? 150 };\n if (targetWidth === undefined) return intrinsic;\n return { width: targetWidth, height: targetWidth * (intrinsic.height / intrinsic.width) };\n };\n\n const armStamp = async (input: StampToolInput): Promise<void> => {\n // Resolve + sniff up front: a bad payload fails HERE (at the button),\n // not at the click. The original `source` is kept for the create call —\n // normalization inside the engine handles it again from scratch.\n const resolved = await resolveBinarySource(input.source);\n const meta = sniffBinaryMetadata(resolved.bytes);\n if (!meta) {\n throw new Error('[annotation] stamp source must be PNG, JPEG, or single-page PDF bytes');\n }\n // Ghost preview: an explicit `preview` wins (the only way for PDF sources —\n // browsers can't paint those); raster sources default to their own bytes.\n let preview: ArmedStampPreview | null = null;\n if (input.preview) {\n const p = await resolveBinarySource(input.preview);\n preview = { bytes: new Uint8Array(p.bytes), mimeType: p.mimeType };\n } else if (meta.mimeType !== 'application/pdf') {\n preview = { bytes: new Uint8Array(resolved.bytes), mimeType: meta.mimeType };\n }\n armedStamp = {\n source: input.source,\n ...desiredStampSize(meta, input.targetWidth, input.intrinsicSize),\n preview,\n };\n ctx.dispatch({ type: 'STAMP_ARM_CHANGED' });\n ctx.tryGet(InteractionToken)?.activateTool('stamp');\n };\n\n const disarmStamp = (): void => {\n if (!armedStamp) return;\n armedStamp = null;\n ctx.dispatch({ type: 'STAMP_ARM_CHANGED' });\n };\n\n /** Move the hover FOOTPRINT ghost to a content point. The box/geometry is\n * computed by the SAME rules the click's placement uses ({@link createStampAt}\n * fit + clamp for an armed stamp; the click-create anchor + page clamp for a\n * draw tool), so the ghost is the placement, not an approximation of it. */\n const ghostHoverAt = (\n toolId: string,\n pon: number,\n point: Vec,\n displayRotation?: number,\n ): void => {\n const tool = registry.get(toolId);\n const crop = cropOf(pon);\n if (!tool || tool.ghost === false || !crop) {\n clearGhost();\n return;\n }\n const page = { width: crop.right - crop.left, height: crop.top - crop.bottom };\n // The armed stamp: the fitted image box (the framework blits the preview).\n if (armedStamp) {\n const rot = uprightRotFor(displayRotation);\n const box = fitStampBox(\n point,\n { width: armedStamp.width, height: armedStamp.height },\n page,\n rot,\n );\n ctx.dispatch({ type: 'SET_TOOL_GHOST', ghost: { pon, box, rot, kind: 'image' } });\n return;\n }\n // Icon kinds: the fixed 20×20 footprint under the cursor — the SAME box\n // the click's placement uses (fit + clamp), painted as a vector ghost.\n if (isIconPlaceKind(tool.subtype)) {\n const rot = uprightRotFor(displayRotation);\n const box = fitStampBox(point, ICON_PLACE_SIZE, page, rot);\n dispatchVectorGhost(pon, toolId, { t: 'rect', rect: box, ellipse: false });\n return;\n }\n // A click-create tool: the SHARED placement layer resolves where the click\n // would land (same call the core's commit makes — preview ≡ commit by\n // construction), and the annotation-only conversion paints it as a vector\n // ghost through pageItems. No kind knowledge lives in this shell.\n if (!tool.clickCreate) {\n clearGhost();\n return;\n }\n const placement = resolveClickPlacement(point, tool.clickCreate, {\n pageBox: { x: 0, y: 0, width: page.width, height: page.height },\n upright: tool.upright,\n displayRotation: displayRotation as PageRotation | undefined,\n });\n const geom = clickCreateGeom(tool.subtype, placement, defaultsFor(model(), tool.preset));\n if (!geom) {\n clearGhost();\n return;\n }\n dispatchVectorGhost(pon, toolId, geom);\n };\n\n /** Paint a vector ghost item for a tool's would-be geometry — shared by the\n * hover footprint and the externally-driven placement preview. */\n const dispatchVectorGhost = (pon: number, toolId: string, geom: Geom): void => {\n const tool = registry.get(toolId);\n const style = styleFromProps(defaultsFor(model(), tool?.preset ?? toolId));\n ctx.dispatch({\n type: 'SET_TOOL_GHOST',\n ghost: {\n pon,\n box: geomVisualBounds(geom, style.strokeWidth, style.border),\n rot: 0,\n kind: 'vector',\n toolId,\n geom,\n },\n });\n };\n\n /**\n * Drive the placement preview during an EXTERNALLY-owned creation gesture\n * (the form plugin's drag-to-place): paint the box the commit would use,\n * styled from the TOOL's defaults, through the same ghost pipeline as every\n * footprint. The box is clamped to the page (a drag may overshoot).\n */\n const setPlacementPreview = (toolId: string, pon: number, box: Rect): void => {\n const crop = cropOf(pon);\n if (!crop) return;\n const page = { width: crop.right - crop.left, height: crop.top - crop.bottom };\n const x = Math.max(0, Math.min(box.x, page.width));\n const y = Math.max(0, Math.min(box.y, page.height));\n const rect: Rect = {\n x,\n y,\n width: Math.max(0, Math.min(box.x + box.width, page.width) - x),\n height: Math.max(0, Math.min(box.y + box.height, page.height) - y),\n };\n dispatchVectorGhost(pon, toolId, { t: 'rect', rect, ellipse: false });\n };\n\n const clearGhost = (): void => {\n if (ctx.getState().toolGhost) ctx.dispatch({ type: 'SET_TOOL_GHOST', ghost: null });\n };\n\n /** Place a stamp of `desired` PDF-point size centred on a content point — the\n * one engine-write both the armed and click-to-place paths funnel through.\n * The size is fit to the page and clamped fully onto it (v2 rubber-stamp\n * rule: never larger than the page, aspect preserved), and never spills off\n * the edge. `rotCW` (the tool's upright counter-rotation, CW content degrees)\n * emits the repository's box rotation fields — the engine bakes the tilted\n * /AP exactly as an interactively rotated stamp round-trips, and the fit uses\n * the ROTATED footprint. Returns false when the page/document isn't ready. */\n const createStampAt = (\n pon: number,\n point: Vec,\n source: BinarySource,\n desired: { width: number; height: number },\n rotCW = 0,\n ): boolean => {\n const doc = ctx.doc;\n const crop = cropOf(pon);\n if (!doc || !crop) return false;\n const page = { width: crop.right - crop.left, height: crop.top - crop.bottom };\n const box: Rect = fitStampBox(point, desired, page, rotCW);\n doc\n .page(pon)\n .annotations.create({\n subtype: 'stamp',\n ...boxGeomFields(box, rotCW, crop),\n source,\n fit: 'contain',\n })\n .then(\n // A stamp has no vector render — the engine-baked /AP IS the visual.\n // Every placement selects its result (the anchor for menus/editing).\n (res) => {\n syncDTO(res.created, 'baked');\n apply({ t: 'select', ids: [refKey(res.created.ref)] });\n },\n (err) => console.error('[annotation] stamp placement failed:', err),\n );\n return true;\n };\n\n /** The active tool's upright counter-rotation for a click at `displayRotation`\n * (0 when the tool doesn't ask for upright, or the display isn't rotated). */\n const uprightRotFor = (displayRotation?: number): number => {\n if (!displayRotation) return 0;\n const ix = ctx.tryGet(InteractionToken);\n const tool = ix ? registry.get(ix.activeToolId()) : undefined;\n return tool?.upright ? uprightRotation(displayRotation) : 0;\n };\n\n const placeArmedStamp = (pon: number, point: Vec, displayRotation?: number): boolean => {\n const armed = armedStamp;\n if (!armed) return false;\n return createStampAt(\n pon,\n point,\n armed.source,\n { width: armed.width, height: armed.height },\n uprightRotFor(displayRotation),\n );\n };\n\n /** Sniff a stamp source (rejecting non-image bytes) and place it at its\n * intrinsic size (fit to the page in {@link createStampAt}); `targetWidth`\n * overrides the width, aspect preserved. */\n const placeStampSource = async (\n pon: number,\n point: Vec,\n source: BinarySource,\n rotCW: number,\n targetWidth?: number,\n ): Promise<void> => {\n const resolved = await resolveBinarySource(source);\n const meta = sniffBinaryMetadata(resolved.bytes);\n if (!meta) {\n console.error('[annotation] stamp source must be PNG, JPEG, or single-page PDF bytes');\n return;\n }\n createStampAt(pon, point, source, desiredStampSize(meta, targetWidth), rotCW);\n };\n\n /**\n * Click-to-place: resolve the ACTIVE tool's source spec. Fixed `bytes` place\n * immediately; a `'prompt'` source asks the installed provider, then places on\n * resolve — dropping the placement if it was cancelled, or if the tool or\n * document changed while the picker was open (the intent expired).\n */\n const requestStampAt = (pon: number, point: Vec, displayRotation?: number): boolean => {\n const ix = ctx.tryGet(InteractionToken);\n const tool = ix ? registry.get(ix.activeToolId()) : undefined;\n const spec = tool?.source;\n if (!spec) return false;\n // Resolved AT the click (like the placement point): the upright intent\n // belongs to the moment the author picked the spot, even when a 'prompt'\n // source resolves the bytes later.\n const rotCW = tool.upright && displayRotation ? uprightRotation(displayRotation) : 0;\n if (spec.kind === 'bytes') {\n void placeStampSource(pon, point, spec.source, rotCW);\n return true;\n }\n // kind === 'prompt' — needs the environment: the ONE file-picker port.\n return promptFileAt(\n tool,\n pon,\n point,\n (picked) => void placeStampSource(pon, point, picked.data, rotCW),\n );\n };\n\n /**\n * Run the installed file-picker port for a click-then-pick tool, with the\n * shared expiry rule: the placement is dropped if the picker cancels, or if\n * the document or the active tool changed while it was open (the intent\n * expired with the click). No provider installed → decline the click (let a\n * lower-priority handler act) rather than swallow it.\n */\n const promptFileAt = (\n tool: ResolvedTool,\n pon: number,\n point: Vec,\n place: (picked: AttachmentFileSource) => void,\n ): boolean => {\n const provider = filePickerProvider;\n if (!provider) return false;\n const spec = tool.source;\n const req: FilePromptRequest = {\n toolId: tool.id,\n subtype: tool.subtype,\n accept: spec?.kind === 'prompt' ? spec.accept : undefined,\n pon,\n point,\n };\n const docAtClick = ctx.doc;\n provider(req).then(\n (picked) => {\n if (!picked) return; // cancelled\n if (ctx.doc !== docAtClick) return; // document changed underneath\n if (ctx.tryGet(InteractionToken)?.activeToolId() !== tool.id) return; // tool changed\n place(picked);\n },\n (err) => console.error('[annotation] file-picker provider failed:', err),\n );\n return true;\n };\n\n /** Place a fixed-size ICON annotation (note / file attachment) centred on a\n * content point — the icon-kind sibling of {@link createStampAt}. The\n * engine bakes the 20×20 /AP from /C + /Name; a successful create selects\n * the new annotation (the anchor for its menu / future comment popup). */\n const createIconAt = (\n tool: ResolvedTool,\n pon: number,\n point: Vec,\n rotCW: number,\n file: AttachmentFileSource | null,\n ): boolean => {\n const doc = ctx.doc;\n const crop = cropOf(pon);\n if (!doc || !crop || !isIconPlaceKind(tool.subtype)) return false;\n const page = { width: crop.right - crop.left, height: crop.top - crop.bottom };\n const box: Rect = fitStampBox(point, ICON_PLACE_SIZE, page, rotCW);\n const draft = iconPlacementDraft(\n tool.subtype,\n boxGeomFields(box, rotCW, crop),\n defaultsFor(model(), tool.preset),\n tool.flags,\n file,\n );\n doc\n .page(pon)\n .annotations.create(draft)\n .then(\n (res) => {\n syncDTO(res.created, 'baked');\n apply({ t: 'select', ids: [refKey(res.created.ref)] });\n },\n (err) => console.error('[annotation] icon placement failed:', err),\n );\n return true;\n };\n\n /**\n * The ONE click-to-place entry the place handler forwards every down to —\n * armed payload first, then the active tool's kind decides:\n * - stamp → the source spec (fixed bytes, or the file-picker port)\n * - note (text) → place immediately (no payload)\n * - attachment → spot first, file second: the file-picker port opens\n * inside the click gesture, and placement lands when it\n * resolves (dropped on cancel, or if the tool/document\n * changed while the picker was open).\n * Returns whether the click was consumed.\n */\n const placeAt = (pon: number, point: Vec, displayRotation?: number): boolean => {\n if (placeArmedStamp(pon, point, displayRotation)) return true;\n const ix = ctx.tryGet(InteractionToken);\n const tool = ix ? registry.get(ix.activeToolId()) : undefined;\n if (!tool) return false;\n if (tool.subtype === 'stamp') return requestStampAt(pon, point, displayRotation);\n if (!isIconPlaceKind(tool.subtype)) return false;\n const rotCW = tool.upright && displayRotation ? uprightRotation(displayRotation) : 0;\n if (tool.subtype === 'text') return createIconAt(tool, pon, point, rotCW, null);\n return promptFileAt(tool, pon, point, (picked) =>\n createIconAt(tool, pon, point, rotCW, picked),\n );\n };\n\n /** The page a ref lives on: from the loaded model first (covers obj/nm refs\n * that don't carry a pon), else the ref itself (index refs do). */\n const ponForRef = (ref: AnnotationRef): number | null =>\n model().byId[refKey(ref)]?.pon ?? (ref.kind === 'index' ? ref.pageObjectNumber : null);\n\n /**\n * Re-sync one annotation into the model from the authoritative engine DTO,\n * with the render `source` the caller decides: `'vector'` when WE authored or\n * changed the appearance (create / restyle / resize), `'baked'` when the AP is\n * still authoritative (a move, which preserves it, or a remote edit).\n * `bumpAp` marks the upsert as confirming an engine /AP re-bake with new\n * content, so the annotation's `apVersion` — and with it the page's\n * appearance epoch — advances and the shell fetches the fresh raster.\n */\n const syncDTO = (\n dto: Parameters<typeof fromDTO>[0],\n source: 'baked' | 'vector',\n bumpAp = false,\n ): void => {\n const crop = cropOf(dto.pageObjectNumber);\n if (crop) apply({ t: 'upsert', annots: [ingestDTO(dto, crop, source)], bumpAp });\n };\n\n /** The one engine-update path, shared by `update` and `updateSelection`. A\n * programmatic patch changes the appearance → render live (vector). */\n const updateOne = async (ref: AnnotationRef, patch: AnnotationPatch): Promise<void> => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[annotation] no document bound');\n const pon = ponForRef(ref);\n if (pon == null) throw new Error('[annotation] cannot resolve page for ref');\n const res = await doc.page(pon).annotations.update(ref, patch);\n syncDTO(res.updated, 'vector');\n };\n\n function apply(msg: Msg): void {\n const [next, effects] = update(model(), msg);\n ctx.dispatch({ type: 'SET_MODEL', model: next });\n for (const fx of effects) perform(fx, next);\n }\n\n // ── whole-document hydration ──────────────────────────────────────────\n // The plugin ALWAYS hydrates every page via `listRawAll()` — one bulk\n // request on cloud, one raw worker job locally. A comments sidebar needs\n // every page, and per-page lazy loading could never truthfully claim\n // completeness. Coherence protocol: the snapshot arrives cursor-stamped\n // (`auditHead`); remote annotation events arriving DURING the hydration\n // window queue here and replay by cursor after ingest — events with\n // `serverId <= auditHead` are already inside the snapshot and drop,\n // newer ones apply on top. This makes the delete-during-hydrate\n // resurrection structurally impossible. `stream.desynced` re-runs the\n // same ingest with `bumpAp` (rasters may have changed invisibly inside\n // the gap).\n let hydrationStarted = false;\n let hydrationWindow = false;\n let hydrationRunning: Promise<void> | null = null;\n let hydrateAgain = false;\n const pendingRemote: DocumentEvent[] = [];\n\n const setHydration = (hydration: AnnotationHydration): void =>\n ctx.dispatch({ type: 'SET_HYDRATION', hydration });\n\n const ingestSnapshot = (\n snap: Awaited<ReturnType<NonNullable<typeof ctx.doc>['annotations']['listRawAll']>>,\n bumpAp: boolean,\n ): void => {\n const annots: Annot[] = [];\n for (const page of snap.pages) {\n const crop = cropOf(page.pageState.pageObjectNumber);\n if (!crop) continue;\n // Children (replies, states, attached links) enter the substrate as\n // first-class annots; the planes derive (paint cull + lenses).\n annots.push(...page.annotations.map((d) => ingestDTO(d, crop)));\n }\n apply({ t: 'hydrated', annots, bumpAp });\n };\n\n const canRead = (): boolean => ctx.doc?.security.allows('doc.annotate.read') ?? true;\n\n const runHydration = (bumpAp: boolean): Promise<void> => {\n const doc = ctx.doc;\n if (!doc) return Promise.resolve();\n // No read grant → no doomed listRawAll: the state says so, the comments\n // panel hides, and a later rehydrate (e.g. post-/access) re-checks.\n if (!canRead()) {\n setHydration({ status: 'forbidden' });\n return Promise.resolve();\n }\n hydrationWindow = true;\n setHydration({ status: 'loading' });\n const run = doc.annotations\n .listRawAll()\n .then((snap) => {\n ingestSnapshot(snap, bumpAp);\n const head = snap.auditHead;\n const queued = pendingRemote.splice(0);\n hydrationWindow = false;\n for (const event of queued) {\n const serverId = 'origin' in event ? event.origin.serverId : null;\n // ≤ auditHead ⇒ already inside the snapshot; drop. Absent head =\n // a local engine, which has no remote events anyway.\n if (head !== undefined && serverId !== null && serverId <= head) continue;\n applyRemoteAnnotationEvent(event);\n }\n setHydration({ status: 'complete' });\n })\n .catch((error: unknown) => {\n // Degrade to live-only: queued and future events apply directly so\n // the view stays as correct as it can be until a rehydrate lands.\n hydrationWindow = false;\n for (const event of pendingRemote.splice(0)) applyRemoteAnnotationEvent(event);\n setHydration({ status: 'error', error });\n })\n .finally(() => {\n hydrationRunning = null;\n if (hydrateAgain) {\n hydrateAgain = false;\n hydrationRunning = runHydration(true);\n }\n });\n hydrationRunning = run;\n return run;\n };\n\n const rehydrate = (): Promise<void> => {\n if (hydrationRunning) {\n // A desync during an in-flight hydration: that snapshot may already\n // be stale — run once more after it settles.\n hydrateAgain = true;\n return hydrationRunning;\n }\n hydrationRunning = runHydration(true);\n return hydrationRunning;\n };\n\n /**\n * Fold one REMOTE annotation event into the model (transplanted from the\n * effects layer so hydration can queue + replay through the same code\n * path). `bump` re-fetches rasters, `keep` doesn't — driven by the\n * ENGINE'S appearance echo riding the event, so a remote MOVE costs\n * peers zero re-renders while a remote restyle refreshes exactly once.\n */\n const upsertRemote = (\n dtos: ReadonlyArray<Parameters<typeof fromDTO>[0]>,\n bumpAp: boolean,\n ): void => {\n const bump: Annot[] = [];\n const keep: Annot[] = [];\n for (const dto of dtos) {\n const crop = cropOf(dto.pageObjectNumber);\n if (!crop) continue;\n // Another session authored this — trust the engine's baked AP.\n const a = ingestDTO(dto, crop, 'baked');\n // Substrate-only annotations (replies, review states, attached link\n // children) never paint, so their arrival must not trigger a raster\n // fetch or epoch churn. A remote link child is just an upsert — the\n // `linkOf` lens re-derives the parent's value on the next read.\n (bumpAp && !isSubstrateOnly(a) ? bump : keep).push(a);\n }\n if (bump.length) apply({ t: 'upsert', annots: bump, bumpAp: true });\n if (keep.length) apply({ t: 'upsert', annots: keep });\n };\n\n const applyRemoteAnnotationEvent = (event: DocumentEvent): void => {\n switch (event.type) {\n case 'annotation.created':\n // A create ships with a freshly baked /AP — fetch it.\n upsertRemote([event.created], true);\n break;\n case 'annotation.updated':\n // The engine's verdict rides the event: preserved moves keep the\n // cached raster, regenerated appearances re-fetch exactly once.\n upsertRemote([event.updated], event.appearance.changed);\n break;\n case 'annotation.moved':\n // A z-order move never touches /AP.\n upsertRemote(event.moved, false);\n break;\n case 'annotation.deleted':\n if (event.deleted) {\n const key = encodeStableIdKey(event.deleted);\n // Attached link children are model annotations, so a remote child\n // delete is this same plain remove — the `linkOf` lens re-derives.\n if (model().byId[key]) apply({ t: 'remove', ids: [key] });\n }\n break;\n default:\n break;\n }\n };\n\n // ── the comments lens (the conversation plane's surface) ──────────────\n // A derived, memoized threads index over the substrate. Because every\n // path — optimistic writes, engine confirms, remote events, hydration —\n // lands in the model, the sidebar updates with zero extra wiring. The\n // memo keys on the model's annotation content (byId/order — hover and\n // drafts don't invalidate) PLUS the layout (display order is computed\n // fresh against the live pages) and the session identity.\n\n const currentUserId = (): string | undefined => ctx.doc?.security.identity?.user_id;\n\n interface ThreadsIndex {\n threads: CommentThread[];\n byMember: Map<Id, CommentThread>;\n }\n let threadsMemo:\n | (ThreadsIndex & {\n byId: Model['byId'];\n order: Model['order'];\n layout: string;\n userId: string | undefined;\n })\n | null = null;\n\n /** Value-stable layout key: display order is all the sort consumes, so\n * the memo must survive hosts that rebuild the pages array per read. */\n const layoutSignature = (): string =>\n (ctx.document()?.pages ?? []).map((p) => p.pageObjectNumber).join(',');\n\n const computeThreadsIndex = (): ThreadsIndex => {\n const m = model();\n // Committed truth only: optimistic tmp drafts have no DTO yet and join\n // the index when their create confirms.\n const dtos: AnnotationDTO[] = [];\n for (const id of m.order) {\n const data = m.byId[id]?.data;\n if (data) dtos.push(data);\n }\n const threads = buildCommentThreads(dtos, { currentUserId: currentUserId() });\n\n // Display order: page position first (live layout), then top of page\n // (PDF user space is y-up — larger `top` sits higher), then creation.\n const pages = ctx.document()?.pages ?? [];\n const displayIndex = new Map(pages.map((p, i) => [p.pageObjectNumber, i]));\n threads.sort((a, b) => {\n const pa = displayIndex.get(a.pageObjectNumber) ?? Number.MAX_SAFE_INTEGER;\n const pb = displayIndex.get(b.pageObjectNumber) ?? Number.MAX_SAFE_INTEGER;\n if (pa !== pb) return pa - pb;\n if (a.root.rect.top !== b.root.rect.top) return b.root.rect.top - a.root.rect.top;\n const ca = a.root.created ?? '';\n const cb = b.root.created ?? '';\n return ca < cb ? -1 : ca > cb ? 1 : 0;\n });\n\n const byMember = new Map<Id, CommentThread>();\n for (const t of threads) {\n byMember.set(refKey(t.root.ref), t);\n for (const r of t.replies) byMember.set(refKey(r.ref), t);\n for (const g of t.groupedParts) byMember.set(refKey(g.ref), t);\n for (const s of t.review.statusRefs) byMember.set(refKey(s), t);\n }\n return { threads, byMember };\n };\n\n const threadsIndex = (): ThreadsIndex => {\n const m = model();\n const layout = layoutSignature();\n const userId = currentUserId();\n if (\n threadsMemo &&\n threadsMemo.byId === m.byId &&\n threadsMemo.order === m.order &&\n threadsMemo.layout === layout &&\n threadsMemo.userId === userId\n ) {\n return threadsMemo;\n }\n threadsMemo = { ...computeThreadsIndex(), byId: m.byId, order: m.order, layout, userId };\n return threadsMemo;\n };\n\n const threadOf = (ref: AnnotationRef): CommentThread => {\n const t = threadsIndex().byMember.get(refKey(ref));\n if (!t) throw new Error('[annotation] no comment thread contains this ref');\n return t;\n };\n\n /** Engine create + model sync for conversation-plane annotations (they\n * never paint, so the render source is immaterial — 'baked' avoids any\n * vector-scene work). */\n const createConversationAnnot = async (\n pon: number,\n draft: AnnotationDraft,\n ): Promise<AnnotationDTO> => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[annotation] no document bound');\n const res = await doc.page(pon).annotations.create(draft);\n syncDTO(res.created, 'baked');\n return res.created;\n };\n\n const deleteOne = async (ref: AnnotationRef): Promise<void> => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[annotation] no document bound');\n await doc.page(ref.pageObjectNumber).annotations.delete(ref);\n apply({ t: 'remove', ids: [refKey(ref)] });\n };\n\n // Screen-anchored like a sticky note; `print` for Acrobat parity.\n const REPLY_FLAGS = { print: true, noZoom: true, noRotate: true };\n // Status annotations are metadata: hidden everywhere (our paint plane\n // culls them regardless; `hidden` keeps foreign viewers from drawing an\n // icon). Phase 0 golden fixtures may refine this convention.\n const STATUS_FLAGS = { hidden: true, noZoom: true, noRotate: true };\n\n /** Coarse authority mirror (doc.annotate.modify) — B3 replaces this with\n * the collab-scope mirrors; the FLAG split is already the real rule. */\n // ── authorization: the engine's own collab resolver, mirrored ──\n // `allowsAnnotationMutation` asks about the TARGET's stamped owner,\n // built from the record's EMBD metadata. An unstamped record yields\n // `{}`, which any narrowed grant denies — matching the engine, so a\n // control gated here never disagrees with the write's outcome.\n const mutationTarget = (ref: AnnotationRef): { userId?: string; groupId?: string } => {\n const d = model().byId[refKey(ref)]?.data;\n return {\n ...(d?.userId !== undefined ? { userId: d.userId } : {}),\n ...(d?.groupId !== undefined ? { groupId: d.groupId } : {}),\n };\n };\n const allowsCreate = (): boolean => ctx.doc?.security.allowsAnnotationCreate() ?? false;\n\n /**\n * Ingest an engine DTO with this session's per-record AUTHORITY projected\n * onto it (permissions.md) — asked of the SAME mirrors the server enforces\n * with, against the record's stamped owner. Fused into\n * `annotTransformable`/`annotDeletable`, so hit-test, chrome, props and\n * delete all agree with the engine by construction. No security context\n * (bare local engines, tests) → unstamped → allowed; the engine enforces.\n */\n const ingestDTO = (\n dto: Parameters<typeof fromDTO>[0],\n crop: PdfRect,\n source?: Parameters<typeof fromDTO>[2],\n ): Annot => {\n const a = fromDTO(dto, crop, source);\n const sec = ctx.doc?.security;\n if (!sec) return a;\n const target = {\n ...(dto.userId !== undefined ? { userId: dto.userId } : {}),\n ...(dto.groupId !== undefined ? { groupId: dto.groupId } : {}),\n };\n return {\n ...a,\n authority: {\n update: sec.allowsAnnotationMutation('update', target),\n delete: sec.allowsAnnotationMutation('delete', target),\n },\n };\n };\n const allowsMutation = (action: 'update' | 'delete', ref: AnnotationRef): boolean =>\n ctx.doc?.security.allowsAnnotationMutation(action, mutationTarget(ref)) ?? false;\n const deletableOne = (ref: AnnotationRef): boolean => {\n const m = model();\n const a = m.byId[refKey(ref)];\n return !!a && annotDeletable(a);\n };\n const threadMemberRefs = (t: CommentThread): AnnotationRef[] => [\n ...t.replies.map((r) => r.ref),\n ...t.groupedParts.map((g) => g.ref),\n ...t.review.statusRefs,\n t.root.ref, // root LAST — children first keeps foreign readers coherent\n ];\n\n const comments: CommentsApi = {\n threads: () => threadsIndex().threads,\n thread: (ref) => threadsIndex().byMember.get(refKey(ref)) ?? null,\n hydration: () => ctx.getState().hydration,\n rehydrate,\n\n reply: async (ref, text) => {\n const t = threadOf(ref);\n const created = await createConversationAnnot(t.pageObjectNumber, {\n subtype: 'text',\n rect: t.root.rect,\n icon: 'comment',\n contents: text,\n inReplyTo: t.root.ref,\n flags: { ...REPLY_FLAGS },\n } as AnnotationDraft);\n return created.ref;\n },\n\n edit: async (ref, text) => {\n const subtype = model().byId[refKey(ref)]?.data?.subtype;\n if (!subtype) throw new Error('[annotation] cannot edit an uncommitted annotation');\n await updateOne(ref, { subtype, contents: text } as AnnotationPatch);\n },\n\n setStatus: async (ref, state) => {\n const t = threadOf(ref);\n const userId = currentUserId();\n // ISO chain: reply to the caller's previous state annotation when one\n // exists, else to the root. Readers everywhere (ours included) accept\n // both shapes.\n const previous = userId ? t.review.byReviewer[userId] : undefined;\n await createConversationAnnot(t.pageObjectNumber, {\n subtype: 'text',\n rect: t.root.rect,\n inReplyTo: previous?.ref ?? t.root.ref,\n state,\n stateModel: 'review',\n flags: { ...STATUS_FLAGS },\n } as AnnotationDraft);\n },\n\n setMarked: async (ref, marked) => {\n const t = threadOf(ref);\n await createConversationAnnot(t.pageObjectNumber, {\n subtype: 'text',\n rect: t.root.rect,\n inReplyTo: t.root.ref,\n state: marked ? 'marked' : 'unmarked',\n stateModel: 'marked',\n flags: { ...STATUS_FLAGS },\n } as AnnotationDraft);\n },\n\n remove: deleteOne,\n\n removeThread: async (ref): Promise<ThreadDeleteResult> => {\n const t = threadOf(ref);\n const members = threadMemberRefs(t);\n // Preflight: all-or-nothing. A blocked member means NOTHING deletes —\n // a half-deleted thread orphans replies in every other viewer.\n const blocked = members.filter((r) => !deletableOne(r));\n if (blocked.length > 0) {\n return {\n deleted: [],\n failed: blocked.map((r) => ({ ref: r, error: new Error('delete not permitted') })),\n };\n }\n const deleted: AnnotationRef[] = [];\n const failed: ThreadDeleteResult['failed'] = [];\n for (const member of members) {\n // A child failure (a race: someone else acted first) stops the\n // cascade before the root, so nothing orphans.\n if (failed.length > 0) break;\n try {\n await deleteOne(member);\n deleted.push(member);\n } catch (error) {\n failed.push({ ref: member, error });\n }\n }\n return { deleted, failed };\n },\n\n permissionsFor: (ref): CommentPermissions => {\n const flags = model().byId[refKey(ref)]?.flags;\n const t = threadsIndex().byMember.get(refKey(ref)) ?? null;\n return {\n // Replying and setting status CREATE new annotations — gated on\n // the caller's own identity, not the target's owner.\n canReply: allowsCreate(),\n canSetStatus: allowsCreate(),\n canEditText: (() => {\n const m = model();\n const a = m.byId[refKey(ref)];\n return !!a && annotContentsEditable(a);\n })(),\n canDelete: deletableOne(ref),\n canDeleteThread: t !== null && threadMemberRefs(t).every(deletableOne),\n };\n },\n };\n\n /**\n * Per-parent serialization of attached-link reconciles: rapid edits chain\n * instead of interleaving (two overlapping runs could double-create\n * children). Each run reads the CURRENT model at execution time, so a\n * chained run converges on the latest desired state.\n */\n const linkSyncChains = new Map<Id, Promise<void>>();\n /**\n * Queue a reconcile. `intent` is either an explicit target (a set/clear —\n * captured by THIS run's closure, so chained sets stay latest-wins) or\n * `'keep'` (a geometry follow: re-rect the children toward whatever target\n * the substrate holds AT RUN TIME — so a remote retarget is never undone\n * by a local move). Returns the chain, so `links.set()` can await commit.\n */\n const scheduleLinkSync = (id: Id, intent: { target: PdfLinkTarget | null } | 'keep'): Promise<void> => {\n const prev = linkSyncChains.get(id) ?? Promise.resolve();\n const next = prev.then(() =>\n reconcileLinkChildren(id, intent === 'keep' ? linkOf(model(), id) : intent.target),\n );\n linkSyncChains.set(id, next);\n void next.finally(() => {\n if (linkSyncChains.get(id) === next) linkSyncChains.delete(id);\n });\n return next;\n };\n\n /**\n * THE one place attached link children are created, retargeted, re-rected,\n * or deleted. Declarative: desired state = `desired` target + the parent's\n * committed geometry (`linkChildRects`); CURRENT state is read straight\n * from the substrate (`linkChildrenOf`) — no join-key ledger. Results land\n * as ordinary substrate upserts/removes, so the `linkOf` lens converges\n * immediately locally and via events everywhere else. Idempotent — foreign\n * inconsistencies heal on the next local edit.\n */\n const reconcileLinkChildren = async (id: Id, desired: PdfLinkTarget | null): Promise<void> => {\n const doc = ctx.doc;\n const a = model().byId[id];\n if (!doc || !a || !a.ref || a.subtype === 'link') return;\n const crop = cropOf(a.pon);\n if (!crop) return;\n const page = doc.page(a.pon);\n // Read-only target arms can't be (re)written: children keep their /A and\n // only their rects follow the parent.\n const target = writableTarget(desired);\n const rects = desired == null ? [] : linkChildRects(a).map((r) => contentToPdfRect(r, crop));\n const current = linkChildrenOf(model(), id);\n try {\n const paired = Math.min(current.length, rects.length);\n for (let i = 0; i < paired; i++) {\n const ref = current[i].ref;\n if (!ref) continue;\n const res = await page.annotations.update(ref, {\n subtype: 'link',\n rect: rects[i],\n ...(target ? { target } : {}),\n });\n apply({ t: 'upsert', annots: [ingestDTO(res.updated, crop, 'baked')] });\n }\n for (let i = current.length; i < rects.length; i++) {\n const res = await page.annotations.create({\n subtype: 'link',\n rect: rects[i],\n target,\n inReplyTo: a.ref,\n replyType: 'group',\n });\n apply({ t: 'upsert', annots: [ingestDTO(res.created, crop, 'baked')] });\n }\n for (let i = rects.length; i < current.length; i++) {\n const child = current[i];\n if (child.ref) await page.annotations.delete(child.ref);\n apply({ t: 'remove', ids: [child.id] });\n }\n } catch (err) {\n console.error('[annotation] attached-link sync failed:', err);\n }\n };\n\n /** A relationship-only engine patch (sets/clears `/IRT` + `/RT`) — geometry and\n * style are left untouched, so grouping never re-bakes an appearance. */\n const relationshipPatch = (\n subtype: AnnotationDTO['subtype'],\n rel: { inReplyTo: AnnotationRef | null; replyType?: 'group' },\n ): AnnotationPatch => ({ subtype, ...rel }) as AnnotationPatch;\n\n /** Write a relationship change to one committed annotation and re-sync it from\n * the authoritative DTO (preserving its render source — relationships don't\n * change the appearance). */\n const writeRelationship = async (\n a: Annot,\n rel: { inReplyTo: AnnotationRef | null; replyType?: 'group' },\n ): Promise<void> => {\n const doc = ctx.doc;\n if (!doc || !a.ref || !a.data) return;\n const res = await doc\n .page(a.pon)\n .annotations.update(a.ref, relationshipPatch(a.data.subtype, rel));\n syncDTO(res.updated, a.source);\n };\n\n /** Committed, data-backed annotations in the current selection. */\n const selectedCommitted = (): Annot[] => {\n const m = model();\n return m.selected.map((id) => m.byId[id]).filter((a): a is Annot => !!a && !!a.ref && !!a.data);\n };\n\n function perform(fx: Effect, m: Model): void {\n const doc = ctx.doc;\n if (!doc) return;\n if (fx.fx === 'createGroup') {\n const ids = [fx.primary, ...fx.members];\n const annots = ids.map((id) => m.byId[id]);\n const primary = annots[0];\n if (!primary || annots.some((a) => !a || a.pon !== primary.pon)) {\n apply({ t: 'remove', ids });\n return;\n }\n const crop = cropOf(primary.pon);\n const drafts = crop\n ? annots.map((a) => (a ? toCreateDraft(a, crop) : null))\n : annots.map(() => null);\n if (drafts.some((d) => !d)) {\n apply({ t: 'remove', ids });\n return;\n }\n\n void (async () => {\n const committed: Array<{ tempId: string; ref: AnnotationRef }> = [];\n try {\n const page = doc.page(primary.pon);\n const primaryResult = await page.annotations.create(drafts[0]!);\n committed.push({ tempId: fx.primary, ref: primaryResult.created.ref });\n apply({\n t: 'created',\n tempId: fx.primary,\n id: refKey(primaryResult.created.ref),\n ref: primaryResult.created.ref,\n });\n syncDTO(primaryResult.created, 'vector');\n\n for (let i = 0; i < fx.members.length; i++) {\n const tempId = fx.members[i]!;\n const draft = {\n ...drafts[i + 1]!,\n inReplyTo: primaryResult.created.ref,\n replyType: 'group' as const,\n } as AnnotationDraft;\n const result = await page.annotations.create(draft);\n committed.push({ tempId, ref: result.created.ref });\n apply({\n t: 'created',\n tempId,\n id: refKey(result.created.ref),\n ref: result.created.ref,\n });\n syncDTO(result.created, 'vector');\n }\n } catch (error) {\n // A PDF write cannot be transactional, so compensate in reverse: remove\n // every committed part. Keep any part whose rollback itself fails in the\n // model; the UI must reflect the authoritative PDF, never hide an orphan.\n const removeIds = ids.filter((id) => !committed.some((c) => c.tempId === id));\n for (const part of [...committed].reverse()) {\n try {\n await doc.page(primary.pon).annotations.delete(part.ref);\n removeIds.push(refKey(part.ref));\n } catch {\n // `syncDTO` already made this committed annotation visible.\n }\n }\n if (removeIds.length) apply({ t: 'remove', ids: removeIds });\n console.error('[annotation] grouped annotation creation failed:', error);\n }\n })();\n } else if (fx.fx === 'create') {\n const a = m.byId[fx.id];\n const crop = a && cropOf(a.pon);\n const draft = a && crop ? toCreateDraft(a, crop) : null;\n if (!a || !draft) return;\n doc\n .page(a.pon)\n .annotations.create(draft)\n .then(\n (res) => {\n // Reconcile temp→durable id (keeps selection/order), then attach the\n // authoritative DTO so the committed annotation is fully data-backed.\n apply({\n t: 'created',\n tempId: fx.id,\n id: refKey(res.created.ref),\n ref: res.created.ref,\n });\n // We just drew it — render live, not the engine's freshly-baked AP.\n syncDTO(res.created, 'vector');\n },\n () => apply({ t: 'createFailed', tempId: fx.id }),\n );\n } else if (fx.fx === 'flags') {\n // A `/F`-only write: the model already holds the MERGED flags, so emit\n // the full set (create/update both land on exactly these bits). The\n // re-sync PRESERVES the render source — flags never change an\n // appearance, so a baked raster stays authoritative and nothing\n // re-fetches.\n const a = m.byId[fx.id];\n if (!a || !a.ref || !a.data) return;\n doc\n .page(a.pon)\n .annotations.update(a.ref, {\n subtype: a.data.subtype,\n flags: a.flags,\n } as AnnotationPatch)\n .then(\n (res) => syncDTO(res.updated, a.source),\n (err) => console.error('[annotation] flags write failed:', err),\n );\n } else if (fx.fx === 'patch') {\n const a = m.byId[fx.id];\n const crop = a && cropOf(a.pon);\n const patch = a && a.ref && crop ? toScopedPatch(a, fx.scope, crop) : null;\n if (!a || !a.ref || !patch) return;\n // Re-sync from the authoritative DTO, PRESERVING the source the gesture\n // chose: a move kept it baked (raster rides along), a resize flipped it to\n // vector. So the round-trip can't silently re-bake an edited annotation.\n //\n // `apVersion` is driven by the ENGINE'S echo (`res.appearance.changed`),\n // not by guessing from the patch we sent: the engine value-diffs the\n // patch, verifies rigid translations, and reports whether the document's\n // appearance definition actually changed. Preserved moves (including\n // widget/stamp drags — their /AP survives now) cost zero re-fetches;\n // regenerated appearances re-fetch exactly once, when the engine is\n // done — never one-behind. The core's `fx.apChanged` prediction stays\n // advisory (a future pre-commit \"this will replace an imported\n // appearance\" affordance); the echo is the authority.\n doc\n .page(a.pon)\n .annotations.update(a.ref, patch)\n .then(\n (res) => {\n syncDTO(res.updated, a.source, res.appearance.changed);\n // Attached link children follow their parent's COMMITTED geometry\n // — scheduled after the parent's own write resolves, from ONE\n // place, so no gesture ever has to know the children exist.\n if (linkChildrenOf(model(), fx.id).length)\n void scheduleLinkSync(fx.id, 'keep');\n },\n // A refused write (a race, a stale /access) must not leave the\n // optimistic patch as a lie. The effect runs AFTER the reducer\n // applied it, so the pre-image is the annot's own canonical DTO —\n // the last COMMITTED truth — re-ingested with fresh authority.\n () => {\n if (a.data && crop) apply({ t: 'upsert', annots: [ingestDTO(a.data, crop, a.source)] });\n },\n );\n } else if (fx.fx === 'syncLink') {\n void scheduleLinkSync(fx.id, { target: fx.target });\n } else {\n const deletedId = refKey(fx.ref);\n doc\n .page(fx.ref.pageObjectNumber)\n .annotations.delete(fx.ref)\n .then(\n () => {},\n () => {},\n );\n }\n }\n\n const reloadPageNow = async (pon: number): Promise<void> => {\n const doc = ctx.doc;\n const crop = cropOf(pon);\n if (!doc || !crop) return;\n try {\n const snap = await doc.page(pon).annotations.list();\n // Replace, not merge: drop this page's current annots first so\n // cross-plane deletions (deleteField) actually disappear.\n const m = model();\n const stale = m.order.filter((id) => m.byId[id]?.pon === pon);\n if (stale.length) apply({ t: 'remove', ids: stale });\n apply({ t: 'loaded', annots: snap.annotations.map((d) => ingestDTO(d, crop)) });\n } catch {\n // A failed reload leaves the previous view; the next event or a\n // rehydrate reconciles.\n }\n };\n\n /** Script patch → the engine's per-kind patch vocabulary. Colors cross the\n * Acrobat-array → engine {r,g,b}/255 boundary here; everything else maps\n * one-to-one (the VM's validity matrix already scoped keys per kind). */\n const engineScriptPatch = (\n subtype: string,\n patch: ScriptAnnotEffect['patch'],\n ): Record<string, unknown> | Error => {\n const out: Record<string, unknown> = { subtype };\n const toEngineColor = (color: ScriptColorArray) => {\n const rgb = scriptColorToRgb(color);\n return rgb\n ? {\n r: Math.round(rgb.r * 255),\n g: Math.round(rgb.g * 255),\n b: Math.round(rgb.b * 255),\n }\n : null;\n };\n if (patch.strokeColor) {\n const color = toEngineColor(patch.strokeColor);\n if (!color) return new Error('transparent stroke colours are not supported');\n out.color = color;\n }\n if (patch.fillColor) out.interiorColor = toEngineColor(patch.fillColor);\n if (patch.opacity !== undefined) out.opacity = patch.opacity;\n if (patch.width !== undefined) out.strokeWidth = patch.width;\n if (patch.borderStyle) out.borderStyle = patch.borderStyle === 'D' ? 'dashed' : 'solid';\n if (patch.dash) out.dashArray = patch.dash;\n if (patch.rect) {\n out.rect = {\n left: patch.rect[0],\n bottom: patch.rect[1],\n right: patch.rect[2],\n top: patch.rect[3],\n };\n }\n if (patch.contents !== undefined) out.contents = patch.contents;\n if (patch.flags) out.flags = patch.flags;\n return out;\n };\n\n return {\n // ── data API: create / update / delete (engine-routed, ref-addressed) ──\n create: async (pon, draft: AnnotationDraft): Promise<AnnotationRef> => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[annotation] no document bound');\n // Default `/F` to `print` (Acrobat parity — without it the annotation\n // disappears when printed). An EXPLICIT `flags` is respected verbatim.\n const withFlags = (\n draft.flags ? draft : { ...draft, flags: { print: true } }\n ) as AnnotationDraft;\n const res = await doc.page(pon).annotations.create(withFlags);\n // Stamps have no vector render — their engine-baked /AP is the visual.\n syncDTO(res.created, res.created.subtype === 'stamp' ? 'baked' : 'vector');\n return res.created.ref;\n },\n armStamp,\n disarmStamp,\n placeArmedStamp,\n requestStampAt,\n placeAt,\n hasArmedStamp: () => armedStamp != null,\n ghostHoverAt,\n clearGhost,\n setPlacementPreview,\n clearPlacementPreview: clearGhost,\n toolGhost: (pon) => {\n const g = ctx.getState().toolGhost;\n return g && g.pon === pon ? g : null;\n },\n armedStampPreview: () => armedStamp?.preview ?? null,\n stampArmEpoch: () => ctx.getState().stampArmEpoch,\n setFilePickerProvider: (provider) => {\n filePickerProvider = provider;\n },\n downloadAttachment: async (ref) => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[annotation] no document bound');\n const pon = ponForRef(ref);\n if (pon == null) throw new Error('[annotation] cannot resolve page for ref');\n const annotations = doc.page(pon).annotations;\n if (!annotations.downloadFile) {\n throw new Error('[annotation] this engine does not support attachment download');\n }\n return annotations.downloadFile(ref);\n },\n // ── tool registry ──\n tools: () => [...registry.values()],\n tool: (id) => registry.get(id) ?? null,\n toolSubtype: (id) => registry.get(id)?.subtype ?? (id as Subtype),\n registerTool: (def: AnnotationToolInput) => {\n // Re-resolve against the same base pool so `extends` can reach built-ins /\n // config tools, then register just this one with the hub + seed its defaults.\n const resolved = buildToolRegistry([...configTools, def]).get(def.id);\n if (!resolved) throw new Error(`[annotation] could not resolve tool '${def.id}'`);\n registry.set(resolved.id, resolved);\n const un = ctx\n .tryGet(InteractionToken)\n ?.registerTool({\n id: resolved.id,\n cursor: resolved.cursor,\n enables: resolved.enables,\n touchDirect: isTouchDirect(resolved.enables),\n });\n if (resolved.defaults)\n apply({ t: 'setDefaults', subtype: resolved.preset, patch: resolved.defaults });\n return () => {\n registry.delete(resolved.id);\n un?.();\n };\n },\n update: (ref: AnnotationRef, patch: AnnotationPatch) => updateOne(ref, patch),\n // Restyle the selection: ONE flat props patch through the pure core (the\n // same `update → patch effect → toPatch` path every gesture takes). Each\n // member takes the keys its kind declares and ignores the rest; the model\n // updates optimistically, the engine writes fire per member and re-sync.\n updateSelection: (patch) => apply({ t: 'setProps', patch }),\n // Flag writes take their own message (NOT the props path): they must never\n // flip a member to vector or re-bake its /AP, and they must work on a\n // LOCKED annotation — unlocking is the point.\n updateSelectionFlags: (patch) => apply({ t: 'setFlags', patch }),\n getSelectionFlags: () => memoSelectionFlags(),\n delete: async (ref: AnnotationRef): Promise<void> => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[annotation] no document bound');\n const pon = ponForRef(ref);\n if (pon == null) throw new Error('[annotation] cannot resolve page for ref');\n await doc.page(pon).annotations.delete(ref);\n apply({ t: 'remove', ids: [refKey(ref)] });\n },\n\n // ── authorization: per-record mirrors of the engine's collab\n // resolver. `canCreate` asks about the caller's own identity;\n // `canEdit`/`canDelete` about the target's stamped owner. Pure\n // authority — aspect-specific flag gates (`locked` for geometry\n // and delete, `lockedContents` for text) live with the surfaces\n // that touch that aspect (comments.permissionsFor, interaction).\n canRead: () => canRead(),\n canCreate: () => allowsCreate(),\n // The twins answer \"would the verb succeed?\" — authority AND flags, via\n // the SAME fused predicates the gestures and chrome consume, so a false\n // twin and a bare-outline render can never disagree (permissions.md).\n canEdit: (ref) => {\n const a = model().byId[refKey(ref)];\n return !!a && annotTransformable(a);\n },\n canDelete: (ref) => {\n const m = model();\n const a = m.byId[refKey(ref)];\n return !!a && annotDeletable(a);\n },\n\n comments,\n\n links: {\n of: (ref) => {\n const a = model().byId[refKey(ref)];\n if (!a) return null;\n return a.subtype === 'link' ? (a.link ?? null) : linkOf(model(), a.id);\n },\n // The verbs go straight to the reconciler chain (latest-wins per\n // parent) and resolve when the children are COMMITTED — `of` reads\n // the new value the moment the promise settles.\n set: (ref, target) => scheduleLinkSync(refKey(ref), { target }),\n clear: (ref) => scheduleLinkSync(refKey(ref), { target: null }),\n },\n\n getSelection: (): AnnotationRef[] => {\n const m = model();\n return m.selected.map((id) => m.byId[id]?.ref).filter((r): r is AnnotationRef => r != null);\n },\n\n // ── DTO-returning reads (canonical engine vocabulary) ──\n get: (ref: AnnotationRef): AnnotationDTO | null => model().byId[refKey(ref)]?.data ?? null,\n list: (pon: number): AnnotationDTO[] => {\n const m = model();\n return m.order\n .map((id) => m.byId[id])\n .filter((a) => a?.pon === pon)\n .map((a) => a?.data)\n .filter((d): d is AnnotationDTO => d != null);\n },\n getSelected: (): AnnotationDTO[] => {\n const m = model();\n return m.selected.map((id) => m.byId[id]?.data).filter((d): d is AnnotationDTO => d != null);\n },\n\n // ── property introspection (the schema a sidebar renders from) ──\n getSelectionProps: () => memoSelectionProps(),\n // A tool's editable-prop schema comes from its kind: a callout edits free-text\n // props, an arrow edits line props. The registry holds that mapping.\n propsForTool: (toolId) => propsFor(registry.get(toolId)?.propsKind ?? toolId),\n\n // selectors\n pageItems: (pon, view) => memoItems(pon, view),\n chrome: (pon, scale, rotation, zoom) => memoChrome(pon, scale, rotation, zoom),\n selectionAnchor: (scale, rotation, zoom) => memoAnchor(scale, rotation, zoom),\n creationDraftAnchor: () => memoDraftAnchor(),\n selection: () => model().selected,\n hitKind: (pon, point, scale, rotation, zoom, touch) =>\n hitTest(\n model(),\n pon,\n point,\n chromeGeomAt(scale, grabBoost(touch)),\n model().hitMargin,\n pageBoxOf(pon),\n inertIdsAt(pon),\n viewEnv(zoom, rotation),\n ).t,\n claimsTouchAt: (pon, point, scale, rotation, zoom) => {\n const m = model();\n const t = hitTest(\n m,\n pon,\n point,\n chromeGeomAt(scale, TOUCH_GRAB_BOOST),\n m.hitMargin,\n pageBoxOf(pon),\n inertIdsAt(pon),\n viewEnv(zoom, rotation),\n );\n // Selection chrome only exists FOR the selection — always a claim (the\n // hit-tester already suppresses handles on kinds/states that can't\n // resize or rotate).\n if (t.t === 'handle' || t.t === 'rotate' || t.t === 'group-handle') return true;\n // A body claims only when a drag would actually ARM A MOVE — mirror the\n // core's edit-down exactly (update.ts editPointer: a hit on a selected\n // member moves the WHOLE selection only if every member canMove). A\n // selected highlight/caret (selectable, not movable) and a locked\n // annotation must keep scrolling, never eat the drag into a dead zone.\n if (t.t === 'annot') {\n return m.selected.includes(t.id) && m.selected.every((id) => canMove(m, id));\n }\n return false;\n },\n cursorAt: (pon, point, scale, rotation, zoom) =>\n cursorAt(\n model(),\n pon,\n point,\n chromeGeomAt(scale),\n model().hitMargin,\n pageBoxOf(pon),\n inertIdsAt(pon),\n viewEnv(zoom, rotation),\n ),\n hoverAt: (at) => {\n const m = model();\n let id: string | null = null;\n if (at) {\n const h = hitTest(\n m,\n at.pon,\n at.point,\n chromeGeomAt(at.scale),\n m.hitMargin,\n pageBoxOf(at.pon),\n inertIdsAt(at.pon),\n viewEnv(at.zoom, at.rotation),\n );\n if (h.t === 'annot') id = h.id;\n }\n // Diff HERE so the reducer sees enter/leave transitions only. The E/X\n // feed hangs off THIS seam alone: reducer-side hover clears\n // (session-hide, remove, reload) bypass it, so effect-induced hover\n // loss never fires a cursor exit (the anti-cascade law).\n if (m.hovered !== id) {\n hoverFeed?.hover(id);\n apply({ t: 'hover', id });\n }\n },\n behaviorFor: (a) => behaviors.find((b) => b.matches(a) && b.engaged()) ?? null,\n linkItemsOn: (pon) => memoLinkItems(pon),\n\n appearanceEpoch: (pon) => {\n // What a baked raster DEPENDS on, and nothing else: which annotations are\n // baked on this page, and each one's /AP content version (`apVersion` —\n // bumped when a size-changing patch RESOLVES, or a remote edit folds in).\n // Position and rotation are deliberately absent: the blit translates\n // (`apBox`) and rotates (`apRot`) the same pixels, so a move or a spin\n // costs zero re-renders — and because the version bumps when the engine\n // CONFIRMS the re-bake, the fetch can never read a stale /AP (\"one\n // behind\"). Render scale is the shell effect's own dependency.\n const m = model();\n const parts: string[] = [];\n for (const id of m.order) {\n const a = m.byId[id];\n if (!a || a.pon !== pon || a.source !== 'baked' || !a.ref) continue;\n // Conversation-plane annotations never paint — a remote reply or\n // status change must not churn the page's raster cache key.\n if (isSubstrateOnly(a)) continue;\n parts.push(`${id}@${a.apVersion ?? 0}`);\n }\n return parts.sort().join('|');\n },\n bakeScale: (renderScale) =>\n // The render policy is a document FACT off the kernel registry (like\n // `pages`), interpreted by the pure engine-core helper — one lifecycle,\n // one interpretation, no plugin dependency. Identity under continuous.\n snapAppearanceScale(ctx.document()?.renderPolicy ?? CONTINUOUS_RENDER_POLICY, renderScale),\n appearances: (pon, scale, signal) => {\n const doc = ctx.doc;\n if (!doc) return Promise.resolve([]);\n const task = doc.page(pon).annotations.renderAppearanceImages({ scale });\n if (signal) {\n if (signal.aborted) task.abort(signal.reason);\n else signal.addEventListener('abort', () => task.abort(signal.reason), { once: true });\n }\n return task.then(\n (r) => r.appearances,\n () => [],\n );\n },\n toContentBox: (pon, rect) => {\n const crop = cropOf(pon);\n return crop ? pdfToContentRect(rect, crop) : null;\n },\n\n // intents\n editPointer: (phase, pon, point, shift, scale, rotation, zoom, touch) =>\n apply({\n t: 'editPointer',\n phase,\n in: {\n pon,\n point,\n shift,\n pageBox: pageBoxOf(pon),\n // Touch grabs with the same widened zones the claim used, so the\n // gesture picks up exactly what claimsTouchAt said it would.\n chrome: chromeGeomAt(scale, grabBoost(touch)),\n inert: inertIdsAt(pon),\n // the view env (screen-anchored bodies hit/clamp at their footprint)\n ...(zoom != null ? { zoom } : {}),\n ...(rotation != null ? { displayRotation: rotation } : {}),\n },\n }),\n marqueePointer: (phase, pon, point, shift, scale, rotation, zoom) =>\n apply({\n t: 'marqueePointer',\n phase,\n in: {\n pon,\n point,\n shift,\n pageBox: pageBoxOf(pon),\n inert: inertIdsAt(pon),\n ...(zoom != null ? { zoom } : {}),\n ...(rotation != null ? { displayRotation: rotation } : {}),\n },\n }),\n createPointer: (tool, phase, pon, point, finish = false, displayRotation) => {\n // No create authority → creation gestures are inert: no ghost, no\n // draft, no doomed 403. The engine enforces; this keeps pixels honest.\n if (!allowsCreate()) return;\n // Resolve the authoring TOOL to its routing subtype + defaults key. Two\n // tools can share a subtype (line / arrow); `preset` keeps their defaults\n // apart. Unknown id → treat it as a bare subtype (headless/programmatic).\n // The tool's `upright` policy + the sample's display rotation ride the\n // input bag; the core captures them on the draft at DOWN.\n const t = registry.get(tool);\n apply({\n t: 'createPointer',\n phase,\n subtype: t?.subtype ?? (tool as Subtype),\n preset: t?.preset ?? tool,\n intent: t?.intent,\n clickCreate: t?.clickCreate,\n flags: t?.flags,\n deferInkCommit: (t?.ink?.groupStrokesMs ?? 0) > 0,\n straightenInk: t?.ink?.straighten,\n in: {\n pon,\n point,\n shift: false,\n finish,\n pageBox: pageBoxOf(pon),\n displayRotation,\n upright: t?.upright,\n },\n });\n },\n finishCreationDraft: () => apply({ t: 'finishCreationDraft' }),\n finishInkDraft: () => apply({ t: 'finishInkDraft' }),\n cancelCreationDraft: () => apply({ t: 'cancel' }),\n markupFromSelection: (subtype, preset) => {\n // One-shot form of the markup tools' commit: selection quads → one\n // markup per page → clear. Selection is an OPTIONAL peer — resolve\n // lazily so annotation keeps working without it installed.\n if (!allowsCreate()) return false;\n const selection = ctx.tryGet(SelectionPublicToken);\n if (!selection || !selection.hasSelection()) return false;\n const snapshot = selection.snapshot();\n let created = false;\n for (const page of snapshot.pages) {\n if (!page.segments.length) continue;\n apply({\n t: 'createMarkup',\n subtype,\n pon: page.pon,\n quads: page.segments.map((s) => s.quad),\n preset,\n flags: preset ? registry.get(preset)?.flags : undefined,\n });\n created = true;\n }\n if (created) selection.clear();\n return created;\n },\n createMarkup: (subtype, pon, quads, preset) => {\n // Optimistic create — the same self-refusal `createPointer` has.\n if (!allowsCreate()) return;\n // A markup tool's `/F` seed rides along (the preset IS the tool id).\n apply({\n t: 'createMarkup',\n subtype,\n pon,\n quads,\n preset,\n flags: preset ? registry.get(preset)?.flags : undefined,\n });\n },\n createCaret: (pon, anchor) => {\n if (!allowsCreate()) return;\n apply({ t: 'createCaret', pon, anchor });\n },\n createReplaceText: (pon, quads, anchor, preset) => {\n if (!allowsCreate()) return;\n apply({ t: 'createReplaceText', pon, quads, anchor, preset });\n },\n previewMarkup: (subtype, quadsByPage, preset) =>\n apply({ t: 'setMarkupPreview', subtype, quadsByPage, preset }),\n clearMarkupPreview: () => apply({ t: 'clearMarkupPreview' }),\n setDefaults: (subtype, patch) => apply({ t: 'setDefaults', subtype, patch }),\n // Resolve through the tool's `preset` key so arrow reads arrow's defaults, not\n // line's (and the insert-caret tool reads the shared `caret` bag). Falls back\n // to the given id for a bare subtype.\n currentDefaults: (toolId) => defaultsFor(model(), registry.get(toolId)?.preset ?? toolId),\n // Live-adjustable snapping (a UI toggle); seeded by the registration config.\n setSnap: (patch) => apply({ t: 'setSnap', patch }),\n snapSettings: () => model().snap,\n // Live-adjustable selection chrome (theming); seeded by the registration config.\n setChrome: (patch) => ctx.dispatch({ type: 'SET_CHROME', patch }),\n chromeSettings: () => chromeSettings(),\n deleteSelection: () => apply({ t: 'delete' }),\n deselect: () => apply({ t: 'deselect' }),\n select: (ref, options) => {\n apply({ t: 'select', ids: [refKey(ref)], add: options?.add });\n },\n pruneEngagedSelection: () => {\n // Engaged ⇒ hit-test-inert ⇒ must not STAY selected either (a widget\n // selected in design mode keeps no chrome once the fill tool engages).\n const m = model();\n const drop = m.selected.filter((id) => {\n const a = m.byId[id];\n return (\n a && behaviors.some((b) => b.matches({ subtype: a.subtype, ref: a.ref }) && b.engaged())\n );\n });\n if (drop.length) apply({ t: 'deselect', ids: drop });\n },\n cancel: () => apply({ t: 'cancel' }),\n // Rotate the selection a quarter-turn clockwise / reset it to as-authored.\n // Both commit one geometry patch per rotatable member (the same path the\n // rotate-knob gesture uses), so they round-trip through the engine identically.\n rotateSelection90: () => apply({ t: 'rotate90' }),\n resetSelectionRotation: () => apply({ t: 'resetRotation' }),\n\n // ── grouping (engine `/IRT` + `/RT /Group`; page-local) ──\n /** Group the current selection into one unit: the bottom-most member becomes\n * the primary, every other member becomes a `/RT /Group` subordinate of it.\n * No-op unless 2+ committed annotations on a single page are selected. */\n group: async (): Promise<void> => {\n const m = model();\n const members = selectedCommitted();\n if (members.length < 2) return;\n const pon = members[0].pon;\n if (members.some((a) => a.pon !== pon)) return; // groups are page-local\n const ordered = [...members].sort((a, b) => m.order.indexOf(a.id) - m.order.indexOf(b.id));\n const [primary, ...rest] = ordered;\n if (!primary.ref) return;\n await Promise.all(\n rest.map((a) => writeRelationship(a, { inReplyTo: primary.ref, replyType: 'group' })),\n );\n },\n /** Ungroup: clear `/IRT` (+ `/RT`) on every subordinate in the group(s) the\n * selection touches, so each member becomes top-level again. */\n ungroup: async (): Promise<void> => {\n const m = model();\n const subs = expandGroups(m, m.selected)\n .map((id) => m.byId[id])\n .filter((a): a is Annot => !!a && !!a.ref && !!a.data && !!a.group);\n await Promise.all(subs.map((a) => writeRelationship(a, { inReplyTo: null })));\n },\n canGroup: (): boolean => {\n const m = model();\n const members = selectedCommitted();\n if (members.length < 2) return false;\n if (members.some((a) => a.pon !== members[0].pon)) return false;\n // Grouping WRITES a relationship onto every member — each must\n // pass the per-record update check.\n if (!members.every((a) => a.ref != null && allowsMutation('update', a.ref))) return false;\n // Already exactly one complete group → nothing to do.\n const keys = new Set(m.selected.map((id) => groupKeyOf(m, id)));\n if (keys.size === 1 && !keys.has(null)) return false;\n return true;\n },\n canUngroup: (): boolean => {\n const m = model();\n // Ungrouping clears the relationship on every member of every\n // selected group — same per-record write gate as `ungroup` hits.\n const subs = expandGroups(m, m.selected)\n .map((id) => m.byId[id])\n .filter((a): a is Annot => !!a && !!a.group);\n return subs.length > 0 && subs.every((a) => a.ref != null && allowsMutation('update', a.ref));\n },\n\n // Whole-document hydration supersedes per-page loading: the model is\n // seeded by `listRawAll()` at document open (see `ensureHydrated`), so\n // a page mount has nothing to fetch. Kept as API for layers/plugins\n // that call it on mount; appearance fetching stays per-page/viewport.\n ensurePage: () => {},\n\n reloadPage: (pon) => reloadPageNow(pon),\n\n hydration: () => ctx.getState().hydration,\n ensureHydrated: () => {\n if (hydrationStarted) return;\n hydrationStarted = true;\n void runHydration(false);\n },\n rehydrate,\n deliverRemoteAnnotationEvent: (event) => {\n if (hydrationWindow) {\n pendingRemote.push(event);\n return;\n }\n applyRemoteAnnotationEvent(event);\n },\n\n // ── free-text (the editable-element layer) ──\n textItems: (pon, view) => memoTexts(pon, view),\n currentEditing: () => model().editing,\n beginTextEdit: (ref) => apply({ t: 'beginTextEdit', id: refKey(ref) }),\n beginTextEditAt: (pon, point, scale, rotation, zoom) => {\n const m = model();\n const h = hitTest(\n m,\n pon,\n point,\n chromeGeomAt(scale),\n m.hitMargin,\n pageBoxOf(pon),\n undefined,\n viewEnv(zoom, rotation),\n );\n // A double-click on the box body OR one of its resize handles both target the\n // same annotation; either should open it for editing.\n const id = h.t === 'annot' || h.t === 'handle' ? h.id : null;\n if (id != null && m.byId[id]?.geom.t === 'text') {\n apply({ t: 'beginTextEdit', id });\n return true;\n }\n // Nothing editable here — report it so the caller can fall through to a\n // normal press instead of swallowing the gesture on a non-text annotation.\n return false;\n },\n setContents: (ref, text) => {\n apply({ t: 'setText', id: refKey(ref), text }); // optimistic, no engine churn\n const key = refKey(ref);\n clearTimeout(textTimers.get(key));\n textTimers.set(\n key,\n setTimeout(() => {\n textTimers.delete(key);\n const pon = ponForRef(ref);\n if (pon != null) {\n ctx.doc\n ?.page(pon)\n .annotations.update(ref, { subtype: 'free-text', contents: text })\n .then(\n () => {},\n () => {},\n );\n }\n }, TEXT_COMMIT_DEBOUNCE_MS),\n );\n },\n endTextEdit: () => {\n // flush any pending debounced write immediately, then leave edit mode\n for (const t of textTimers.values()) clearTimeout(t);\n const id = model().editing;\n const a = id ? model().byId[id] : null;\n if (a?.ref) {\n const pon = ponForRef(a.ref);\n const text = a.data?.contents ?? '';\n if (pon != null)\n ctx.doc\n ?.page(pon)\n .annotations.update(a.ref, { subtype: 'free-text', contents: text })\n .then(\n () => {},\n () => {},\n );\n }\n textTimers.clear();\n apply({ t: 'endTextEdit' });\n },\n\n // Full ISO (D7): every script/Hide effect is a DOCUMENT mutation — the\n // owner commits it (engine write, authority-enforced there) and\n // reconciles its own model, so the PDF and the pixels can never diverge.\n commitScriptEffects: async (entries) => {\n const doc = ctx.doc;\n if (!doc) {\n return {\n results: entries.map((entry) => ({\n annotObjectNumber: entry.annotObjectNumber,\n status: 'failed' as const,\n error: 'no document',\n })),\n };\n }\n const results: AnnotCommitResult['results'] = [];\n const touchedPons = new Set<number>();\n let failed = false;\n for (const entry of entries) {\n if (failed) {\n results.push({ annotObjectNumber: entry.annotObjectNumber, status: 'skipped' });\n continue;\n }\n const loaded = model().byId[`obj:${entry.annotObjectNumber}`];\n const pon = loaded?.pon ?? entry.pageObjectNumber;\n let ref = loaded?.ref ?? null;\n let subtype: string | undefined = loaded?.subtype;\n if ((!ref || !subtype) && pon !== undefined) {\n // Engine fallback for pages the model hasn't loaded.\n try {\n const { annotations } = await doc.page(pon).annotations.list();\n const dto = annotations.find(\n (candidate) =>\n candidate.ref.kind === 'objectNumber' &&\n candidate.ref.annotObjectNumber === entry.annotObjectNumber,\n );\n if (dto) {\n ref = dto.ref;\n subtype = dto.subtype;\n }\n } catch {\n /* resolved as a failure below */\n }\n }\n if (pon === undefined || !ref || !subtype) {\n results.push({\n annotObjectNumber: entry.annotObjectNumber,\n status: 'failed',\n error: 'annotation not resolved (page not loaded)',\n });\n continue;\n }\n const patch = engineScriptPatch(subtype, entry.patch);\n if (patch instanceof Error) {\n results.push({\n annotObjectNumber: entry.annotObjectNumber,\n status: 'failed',\n error: patch.message,\n });\n continue;\n }\n try {\n await doc.page(pon).annotations.update(ref, patch as never);\n touchedPons.add(pon);\n results.push({ annotObjectNumber: entry.annotObjectNumber, status: 'applied' });\n } catch (error) {\n // Stop-on-failure: PermissionDenied and friends fail THIS entry and\n // skip the rest — the declared cross-plane law, per-plane too.\n failed = true;\n results.push({\n annotObjectNumber: entry.annotObjectNumber,\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n // Reconcile OUR model (the engine emitted local events both listeners\n // deliberately ignore — the owner folds its own writes).\n for (const touched of touchedPons) await reloadPageNow(touched);\n return { results };\n },\n registerBehavior: (b) => {\n behaviors.push(b);\n return () => {\n const i = behaviors.indexOf(b);\n if (i >= 0) behaviors.splice(i, 1);\n };\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_types = require("../types-DimcLIic.cjs");
3
+ exports.AnnotationToken = require_types.AnnotationToken;
@@ -0,0 +1,2 @@
1
+ import { i as AnnotationHostCapability, s as AnnotationToken } from "../types-eLTpocXz.cjs";
2
+ export { type AnnotationHostCapability, AnnotationToken };
@@ -0,0 +1,2 @@
1
+ import { i as AnnotationHostCapability, s as AnnotationToken } from "../types-otwv-Cdl.js";
2
+ export { type AnnotationHostCapability, AnnotationToken };
@@ -0,0 +1,2 @@
1
+ import { t as AnnotationToken } from "../types-CwytT-TI.js";
2
+ export { AnnotationToken };
@@ -0,0 +1,8 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/contract.ts
3
+ /** The public lens over the host capability's one runtime token. */
4
+ const AnnotationToken = require("./types-DimcLIic.cjs").AnnotationToken;
5
+ //#endregion
6
+ exports.AnnotationToken = AnnotationToken;
7
+
8
+ //# sourceMappingURL=contract.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.cjs","names":["AnnotationHostToken"],"sources":["../src/contract.ts"],"sourcesContent":["/**\n * Public annotation protocol without the repository, reducer, tools, or plugin\n * wiring. Cross-package capability consumers import this entry.\n */\nimport type { CapabilityToken } from '@embedpdf/core';\n\nimport { AnnotationToken as AnnotationHostToken } from './types';\nimport type { AnnotationCapability } from './types';\n\nexport type {\n AnnotationCapability,\n AnnotationConfig,\n AnnotationState,\n AnnotationAction,\n AnnotationHydration,\n Behavior,\n CommentPermissions,\n CommentsApi,\n ThreadDeleteResult,\n ChromeSettings,\n ChromeSettingsPatch,\n LinkNavItem,\n SelectionFlags,\n SelectionProps,\n StampToolInput,\n FilePickerProvider,\n FilePromptRequest,\n TextItem,\n ToolGhost,\n} from './types';\nexport type {\n AnnotationDTO,\n AnnotationRef,\n AnnotationSubtype,\n Color,\n CommentThread,\n CommentThreadReview,\n ReviewStatus,\n} from '@embedpdf/engine-core/runtime';\nexport type {\n AnnotationFlags,\n AnnotationProps,\n AnnotationPropsPatch,\n BlendMode,\n Border,\n ClickCreate,\n LineEnding,\n LineEndings,\n PropKey,\n PropSpec,\n SnapSettings,\n TextAlign,\n} from '@embedpdf/core-annotation';\n\n/** The public lens over the host capability's one runtime token. */\nexport const AnnotationToken =\n AnnotationHostToken as unknown as CapabilityToken<AnnotationCapability>;\n"],"mappings":";;;AAuDA,MAAa,gDACXA,CAAAA,CAAAA"}