@embedpdf/plugin-annotation 3.0.0-next.14 → 3.0.0-next.16

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 (61) hide show
  1. package/README.md +129 -0
  2. package/dist/authoring.cjs +12 -2
  3. package/dist/authoring.d.cts +2 -2
  4. package/dist/authoring.d.ts +2 -2
  5. package/dist/authoring.js +2 -3
  6. package/dist/contract/host.cjs +18 -2
  7. package/dist/contract/host.d.cts +3 -2
  8. package/dist/contract/host.d.ts +3 -2
  9. package/dist/contract/host.js +3 -2
  10. package/dist/contract-BK4LHe9v.d.cts +1127 -0
  11. package/dist/contract-BOo9iZKo.d.ts +1127 -0
  12. package/dist/contract-CPzpRG3h.cjs +692 -0
  13. package/dist/contract-CPzpRG3h.cjs.map +1 -0
  14. package/dist/contract-b2e_LZvu.js +651 -0
  15. package/dist/contract-b2e_LZvu.js.map +1 -0
  16. package/dist/contract.cjs +11 -10
  17. package/dist/contract.d.cts +2 -3
  18. package/dist/contract.d.ts +2 -3
  19. package/dist/contract.js +2 -4
  20. package/dist/host-contract-BU29qDEw.d.cts +320 -0
  21. package/dist/host-contract-CxrQPcPj.js +52 -0
  22. package/dist/host-contract-CxrQPcPj.js.map +1 -0
  23. package/dist/{contract-a4eaQWga.cjs → host-contract-DY9jFPPF.cjs} +36 -16
  24. package/dist/host-contract-DY9jFPPF.cjs.map +1 -0
  25. package/dist/host-contract-DfSvbt8c.d.ts +320 -0
  26. package/dist/index.cjs +5043 -419
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +12 -17
  29. package/dist/index.d.ts +12 -17
  30. package/dist/index.js +4995 -391
  31. package/dist/index.js.map +1 -1
  32. package/package.json +11 -14
  33. package/dist/authoring-BhtyfsMx.d.cts +0 -37
  34. package/dist/authoring-R4ezdnXd.d.ts +0 -37
  35. package/dist/capability-Bt320iJP.cjs +0 -3249
  36. package/dist/capability-Bt320iJP.cjs.map +0 -1
  37. package/dist/capability-CoL4na7g.js +0 -3226
  38. package/dist/capability-CoL4na7g.js.map +0 -1
  39. package/dist/contract-C7rcuNp_.d.cts +0 -34
  40. package/dist/contract-CM2Ovdq_.d.ts +0 -34
  41. package/dist/contract-DtXE1hjY.js +0 -32
  42. package/dist/contract-DtXE1hjY.js.map +0 -1
  43. package/dist/contract-a4eaQWga.cjs.map +0 -1
  44. package/dist/internal.cjs +0 -8
  45. package/dist/internal.d.cts +0 -14
  46. package/dist/internal.d.ts +0 -14
  47. package/dist/internal.js +0 -5
  48. package/dist/seam-6pJeKOOJ.cjs +0 -296
  49. package/dist/seam-6pJeKOOJ.cjs.map +0 -1
  50. package/dist/seam-C4L_7rDt.js +0 -225
  51. package/dist/seam-C4L_7rDt.js.map +0 -1
  52. package/dist/tools-B3i1gjRs.cjs +0 -589
  53. package/dist/tools-B3i1gjRs.cjs.map +0 -1
  54. package/dist/tools-DsfqBn_a.js +0 -566
  55. package/dist/tools-DsfqBn_a.js.map +0 -1
  56. package/dist/types-BvB1vUKb.js +0 -20
  57. package/dist/types-BvB1vUKb.js.map +0 -1
  58. package/dist/types-ChRnKozg.d.cts +0 -1246
  59. package/dist/types-Dlhdw2k_.cjs +0 -31
  60. package/dist/types-Dlhdw2k_.cjs.map +0 -1
  61. package/dist/types-Dmz3eRSG.d.ts +0 -1246
@@ -0,0 +1,1127 @@
1
+ import { BatchResult, DeepPartial, EventHook, EventOrigin, OperationOptions, PluginErrorInfo, ResourceStatus, SettingsApi, Unsubscribe } from "@embedpdf/core";
2
+ import { AnnotationTransfer } from "@embedpdf/engine-core/public";
3
+ import { Annotation, Annotation as Annotation$1, AnnotationBundle, AnnotationBundle as AnnotationBundle$1, AnnotationDraft, AnnotationDraft as AnnotationDraft$1, AnnotationImportDrop, AnnotationImportDrop as AnnotationImportDrop$1, AnnotationImportOptions, AnnotationImportOptions as AnnotationImportOptions$1, AnnotationPatch, AnnotationPatch as AnnotationPatch$1, AnnotationPosition, AnnotationPosition as AnnotationPosition$1, AnnotationRef, AnnotationRef as AnnotationRef$1, AnnotationResourceRole, AnnotationResourceRole as AnnotationResourceRole$1, AnnotationResources, AnnotationResources as AnnotationResources$1, AnnotationSubtype, AnnotationSubtype as AnnotationSubtype$1, AttachmentContent, AttachmentFileSource, AttachmentFileSource as AttachmentFileSource$1, BinarySource, Color, CommentThread, CommentThread as CommentThread$1, CommentThreadReview, PageRef, PdfActionTree, PdfLinkTarget, PdfLinkTarget as PdfLinkTarget$1, ReviewStatus, RichTextBody, RichTextParagraph, WidgetAppearance } from "@embedpdf/engine-core/runtime";
4
+ import { AnnotationFlags, AnnotationFlags as AnnotationFlags$1, AnnotationOption, AnnotationProperty, AnnotationProperty as AnnotationProperty$1, BlendMode, ClickCreate, ClickCreate as ClickCreate$1, CreationDraftAnchor, EditableKind, EditableKinds, EditableKinds as EditableKinds$1, FieldValues, FieldValues as FieldValues$1, FlagKey, HandleRole, InkStraightenOptions, KindName, LineEnding, LineEndings, MeasurementIntent, Rect, RichTextRange, RotationAnchor, SnapSettings, SnapSettings as SnapSettings$1, TextAlign, ViewEnv } from "@embedpdf/core-annotation";
5
+ import "@embedpdf/plugin-interaction/contract";
6
+ import { Point as Point$1 } from "@embedpdf/core-geometry";
7
+ //#region src/rich-text.d.ts
8
+ type TextFormat = 'bold' | 'italic' | 'underline';
9
+ /** The editor's selection inside one free-text annotation: flat offsets over
10
+ * the plain projection (paragraphs joined by `\r`). */
11
+ interface TextSelection extends RichTextRange {
12
+ id: string;
13
+ }
14
+ /** The face a run or a body names. */
15
+ interface Face {
16
+ family: string;
17
+ weight?: number;
18
+ italic?: boolean;
19
+ }
20
+ //#endregion
21
+ //#region src/tools/definitions.d.ts
22
+ /**
23
+ * How a stamp-family tool resolves the image bytes it places — pure data, so a
24
+ * tool table stays JSON-serializable (config can come from a file, a DB, or the
25
+ * server). Evaluated at click time, so the user picks the spot first, then the
26
+ * source:
27
+ * - `{ kind: 'bytes' }` — fixed bytes: a company rubber-stamp.
28
+ * - `{ kind: 'prompt' }` — ask the environment for bytes. The plugin does not
29
+ * know how (a file dialog is DOM); the file-picker port (`FilePickerProvider`),
30
+ * installed by the framework adapter, fulfils it. Resolve `null` there to cancel.
31
+ */
32
+ type StampSourceSpec = {
33
+ kind: 'bytes';
34
+ source: BinarySource;
35
+ } | PromptSourceSpec;
36
+ /**
37
+ * The ask-the-environment resolution, shared by every click-then-pick tool
38
+ * (a stamp's `'prompt'` source, the file-attachment tool). `accept` is the
39
+ * file-dialog filter the picker request carries — a UX hint only, the engine
40
+ * sniffs/validates the bytes for real. Unset = any file.
41
+ */
42
+ interface PromptSourceSpec {
43
+ kind: 'prompt';
44
+ accept?: string;
45
+ }
46
+ /**
47
+ * The tool `stamps.arm` activates — and the only tool an armed payload survives
48
+ * onto (plus the legacy `annotation-stamp` tag, honoured for embedder configs
49
+ * written before the tags were unified). Placement consults the armed payload
50
+ * before the active tool's own `source` spec, so a payload must not outlive
51
+ * its tool onto a sibling stamp preset: an `image` preset's click has to open
52
+ * its own picker, not silently place whatever the stamp panel last armed.
53
+ */
54
+ declare const ARMED_STAMP_TOOL_ID = "stamp";
55
+ /** Declarative result of committing a text selection while a tool is active. */
56
+ type SelectionAuthoring = {
57
+ kind: 'markup';
58
+ } | {
59
+ kind: 'text-edit';
60
+ operation: 'insert' | 'replace';
61
+ };
62
+ /**
63
+ * The tool's ghost: a see-through copy of what a click would place, following
64
+ * the pointer, drawn with the tool's current defaults exactly where and as
65
+ * the click will make it. `true` shows it half see-through, `{ opacity }`
66
+ * as opaque as you say (0–1; `--epdf-ghost-opacity` wins over it from CSS),
67
+ * `false` hides it. It shows only where a click creates: a tool whose click
68
+ * makes nothing (ink, a polygon, `clickCreate: false`) has none, and it hides
69
+ * over an annotation or text, where the click does something else.
70
+ * The cursor says which tool is active; the ghost says where the click lands.
71
+ */
72
+ type GhostPolicy = boolean | {
73
+ opacity: number;
74
+ };
75
+ /** A resolved ghost: how opaque it paints, or `false` for none. */
76
+ type ResolvedGhost = false | {
77
+ opacity: number;
78
+ };
79
+ /** Time/geometry policy for freehand ink authoring. */
80
+ interface InkAuthoringOptions {
81
+ /** Group strokes made within this interval into one `/InkList`; 0 commits immediately. */
82
+ groupStrokesMs?: number;
83
+ /** Optional pure straight-line recognition applied to each completed stroke. */
84
+ straighten?: InkStraightenOptions;
85
+ }
86
+ /**
87
+ * The fields no tool's defaults may set: where the annotation goes (that comes
88
+ * from the drawing), its identity and relationships, and what the engine
89
+ * stamps or keeps by itself.
90
+ */
91
+ declare const NOT_DEFAULTS: readonly ["ref", "page", "index", "hasAppearance", "appearanceState", "nm", "rect", "box", "linePoints", "vertices", "inkList", "quadPoints", "calloutLine", "captionCenter", "measure", "reply", "popup", "parent", "groupId", "author", "createdAt", "modifiedAt", "userId", "createdBy", "modifiedBy", "importedBy", "actions"];
92
+ type NotDefault = (typeof NOT_DEFAULTS)[number];
93
+ /**
94
+ * The fields each known authoring kind's defaults may set: any field a create
95
+ * from the tool takes besides where it goes, flags and `contents` included.
96
+ * A key outside it stops the app at startup, naming the tool and the field.
97
+ */
98
+ declare const TOOL_DEFAULT_FIELDS: {
99
+ readonly square: readonly string[];
100
+ readonly circle: readonly string[];
101
+ readonly line: readonly string[];
102
+ readonly polygon: readonly string[];
103
+ readonly polyline: readonly string[];
104
+ readonly ink: readonly string[];
105
+ readonly 'free-text': readonly string[];
106
+ readonly 'free-text-callout': readonly string[];
107
+ readonly highlight: readonly string[];
108
+ readonly underline: readonly string[];
109
+ readonly strikeout: readonly string[];
110
+ readonly squiggly: readonly string[];
111
+ readonly caret: readonly string[];
112
+ readonly redact: readonly string[];
113
+ readonly stamp: readonly string[];
114
+ readonly link: readonly string[];
115
+ readonly text: readonly string[];
116
+ readonly 'file-attachment': readonly string[];
117
+ readonly 'widget-text': readonly ["color", "interiorColor", "strokeWidth", "borderStyle", "fontFamily", "fontSize", "fontColor", "textAlign"];
118
+ readonly 'widget-choice': readonly ["color", "interiorColor", "strokeWidth", "borderStyle", "fontFamily", "fontSize", "fontColor", "textAlign"];
119
+ readonly 'widget-button': readonly ["color", "interiorColor", "strokeWidth", "borderStyle", "fontFamily", "fontSize", "fontColor", "textAlign"];
120
+ readonly 'widget-toggle': readonly ["color", "interiorColor", "strokeWidth", "borderStyle"];
121
+ readonly 'widget-radio': readonly ["color", "interiorColor", "strokeWidth", "borderStyle"];
122
+ readonly 'widget-box': readonly ["color", "interiorColor", "strokeWidth", "borderStyle"];
123
+ };
124
+ type ToolAuthoringKind = keyof typeof TOOL_DEFAULT_FIELDS;
125
+ /** The draft a kind's creates are: a callout is a free text; a form tool's kind is a widget's appearance. */
126
+ type ToolDraftOf<K extends ToolAuthoringKind> = K extends `widget-${string}` ? Partial<Pick<WidgetAppearance, (typeof TOOL_DEFAULT_FIELDS)[K][number] & keyof WidgetAppearance>> : Omit<Partial<Extract<AnnotationDraft, {
127
+ subtype: K extends 'free-text-callout' ? 'free-text' : K;
128
+ }>>, NotDefault | 'subtype' | 'richText'>;
129
+ /** A tool's rich text is its body: the formatting what it types starts with. */
130
+ type ToolRichText = {
131
+ richText?: {
132
+ body: Partial<RichTextBody>;
133
+ };
134
+ };
135
+ /**
136
+ * The defaults a tool of kind `K` takes: any field of what it draws, flags
137
+ * included, except where it goes (`box`, `rect`, points), which the drawing
138
+ * gives.
139
+ */
140
+ type ToolDefaultsFor<K extends ToolAuthoringKind> = ToolDraftOf<K> & (K extends 'free-text' | 'free-text-callout' ? ToolRichText : unknown);
141
+ /**
142
+ * A tool definition — the public config vocabulary. Every field except `id` is
143
+ * optional: the common cases are "configure a built-in" (`{ id, defaults }`) and
144
+ * "add a preset" (`{ id, extends, defaults }`).
145
+ */
146
+ interface AnnotationToolDef<K extends ToolAuthoringKind = ToolAuthoringKind> {
147
+ /** Stable tool id — the value passed to `activateTool` and the `defaults` key. */
148
+ id: string;
149
+ /** Inherit `subtype` / `fieldsKind` / `cursor` / `enables` / `source` /
150
+ * `selection` / `intent` / `ink` / `meta`
151
+ * from an existing tool id (a built-in or another entry). Own fields win. */
152
+ extends?: string;
153
+ /** The routing kind this tool authors — the core's client kind (the geometry
154
+ * it draws + the props key). Usually the PDF subtype, but not always:
155
+ * `free-text-callout` routes the callout gesture onto a free-text
156
+ * annotation, and `widget-text`/`widget-choice`/`widget-toggle`/`widget-radio` are client
157
+ * views of the one PDF `widget` subtype (a form tool's commit goes through
158
+ * `doc.forms`, never this plugin — see the form plugin's tool table).
159
+ * Defaults to the inherited kind, or the id when neither is given. */
160
+ subtype?: KindName;
161
+ /** The kind whose editable fields a style panel shows for this tool.
162
+ * Defaults to `subtype`. */
163
+ fieldsKind?: string;
164
+ /** Advanced: the `defaults` key this tool reads/writes. Defaults to the id, and
165
+ * that is almost always right — override it only to alias a shared defaults bag
166
+ * (the built-in insert-caret tool points its preset at the `caret` key). */
167
+ preset?: string;
168
+ /** The engine fields what the tool draws takes, besides its shape: a draft
169
+ * without its shape, merged over any inherited defaults (each value whole).
170
+ * The engine's defaults fill in what they leave out. */
171
+ defaults?: ToolDefaultsFor<K>;
172
+ /**
173
+ * `/F` annotation flags seeded on everything this tool creates, merged over
174
+ * the drawn default (`print` set — Acrobat parity) and any inherited seed.
175
+ * A note tool passes `{ noZoom: true, noRotate: true }` so its icons stay
176
+ * screen-sized and upright (the spec's rule for Text annotations).
177
+ */
178
+ flags?: Partial<AnnotationFlags>;
179
+ /** The pointer cursor while this tool is active. Defaults inherited / `crosshair`. */
180
+ cursor?: string;
181
+ /** Interaction capability tags this tool enables (which handlers wake up). */
182
+ enables?: string[];
183
+ /**
184
+ * How the click-to-place payload resolves. Stamps take the full spec
185
+ * ({@link StampSourceSpec}: fixed bytes or prompt); file attachments are
186
+ * prompt-only ({@link PromptSourceSpec} — the file always comes from the
187
+ * environment). Other kinds carry no payload.
188
+ */
189
+ source?: K extends 'stamp' ? StampSourceSpec : K extends 'file-attachment' ? PromptSourceSpec : never;
190
+ /** What a committed text selection authors. Omit for pointer/click tools. */
191
+ selection?: SelectionAuthoring;
192
+ /** Ink-only stroke grouping and straightening policy. */
193
+ ink?: K extends 'ink' ? InkAuthoringOptions : never;
194
+ /**
195
+ * Place annotations upright: counter-rotate what this tool creates against the
196
+ * page's total display rotation (document /Rotate + any stage view rotation),
197
+ * so it reads horizontally exactly as the author saw it — Adobe's behaviour
198
+ * for stamps and text on rotated pages. WYSIWYG at authoring time: the
199
+ * rotation is baked into the annotation, so a save keeps what the author saw
200
+ * (other viewers apply only /Rotate — document that when view rotation is in
201
+ * play). A drawing without a reading direction bakes no turn: a clicked
202
+ * square or circle swaps its sides instead, so it shows its `clickCreate`
203
+ * size as the author sees the page, and a clicked line points the way its
204
+ * `clickCreate` says there; a drag, and a callout's leader, follow the
205
+ * pointer. Default: on for the built-in `stamp`, `free-text`, `note`,
206
+ * `attachment`, `square`, `circle` and `line` tools, off elsewhere.
207
+ */
208
+ upright?: boolean;
209
+ /**
210
+ * What a bare click creates ({@link ClickCreate}): a default-size shape
211
+ * centred on the point, a default-length line centred on it, free text's
212
+ * type-here box hanging from it — page-clamped, in PDF pt. `false` =
213
+ * drag-only. Defaults: on for the built-in square/circle/line/free-text,
214
+ * off elsewhere.
215
+ */
216
+ clickCreate?: ClickCreate | false;
217
+ /**
218
+ * The tool's ghost ({@link GhostPolicy}). Defaults: inherited, else off;
219
+ * on for the built-in click-to-place tools (stamp, note, attachment).
220
+ */
221
+ ghost?: GhostPolicy;
222
+ /**
223
+ * What happens after this tool creates an annotation: select it, keep the
224
+ * tool, start typing in a text box. Wins over the `afterCreate` setting for
225
+ * every tool; what it leaves out comes from there.
226
+ */
227
+ afterCreate?: Partial<AfterCreateSettings>;
228
+ /** Your own data, such as a label and an icon for a toolbar that builds itself
229
+ * from the tool table. The plugin keeps it and never reads it. */
230
+ meta?: Record<string, unknown>;
231
+ }
232
+ interface BuiltinToolKindMap {
233
+ square: 'square';
234
+ circle: 'circle';
235
+ line: 'line';
236
+ distance: 'line';
237
+ perimeter: 'polyline';
238
+ area: 'polygon';
239
+ calibrate: 'line';
240
+ polygon: 'polygon';
241
+ polyline: 'polyline';
242
+ ink: 'ink';
243
+ 'ink-highlight': 'ink';
244
+ 'free-text': 'free-text';
245
+ 'free-text-callout': 'free-text-callout';
246
+ highlight: 'highlight';
247
+ underline: 'underline';
248
+ strikeout: 'strikeout';
249
+ squiggly: 'squiggly';
250
+ 'insert-text': 'caret';
251
+ 'replace-text': 'strikeout';
252
+ redact: 'redact';
253
+ stamp: 'stamp';
254
+ note: 'text';
255
+ attachment: 'file-attachment';
256
+ link: 'link';
257
+ }
258
+ type DirectToolDef = { [K in ToolAuthoringKind]: Omit<AnnotationToolDef<K>, 'subtype'> & {
259
+ subtype: K;
260
+ }; }[ToolAuthoringKind];
261
+ type BuiltinToolOverride = { [I in keyof BuiltinToolKindMap]: Omit<AnnotationToolDef<BuiltinToolKindMap[I]>, 'id' | 'extends' | 'subtype'> & {
262
+ id: I;
263
+ extends?: undefined;
264
+ subtype?: undefined;
265
+ }; }[keyof BuiltinToolKindMap];
266
+ type ExtendedBuiltinToolDef = { [I in keyof BuiltinToolKindMap]: Omit<AnnotationToolDef<BuiltinToolKindMap[I]>, 'extends' | 'subtype'> & {
267
+ extends: I;
268
+ subtype?: undefined;
269
+ }; }[keyof BuiltinToolKindMap];
270
+ /** Public tool input: known overrides, known-base presets, or an explicit subtype. */
271
+ type AnnotationToolInput = DirectToolDef | BuiltinToolOverride | ExtendedBuiltinToolDef;
272
+ /** A fully-resolved tool — what the plugin, handlers, and registration loop read. */
273
+ interface ResolvedTool {
274
+ id: string;
275
+ /** Routing token for the draw core + the created annotation's PDF subtype. */
276
+ subtype: KindName;
277
+ /** The `defaults` key (always the tool id) — keeps same-subtype tools apart. */
278
+ preset: string;
279
+ /** The kind whose properties the style panel shows (`propertiesOf(kindNamed(…))`). */
280
+ fieldsKind: string;
281
+ cursor: string;
282
+ enables: ReadonlySet<string>;
283
+ defaults?: FieldValues;
284
+ /** `/F` seed for created annotations (see {@link AnnotationToolDef.flags}). */
285
+ flags?: Partial<AnnotationFlags>;
286
+ source?: StampSourceSpec;
287
+ selection?: SelectionAuthoring;
288
+ ink?: InkAuthoringOptions;
289
+ /** Counter-rotate creations against the page's display rotation (see
290
+ * {@link AnnotationToolDef.upright}). */
291
+ upright: boolean;
292
+ /** What a bare click creates, or `false` for drag-only. */
293
+ clickCreate: ClickCreate | false;
294
+ /** The tool's ghost ({@link GhostPolicy}): how opaque it paints, or `false` for none. */
295
+ ghost: ResolvedGhost;
296
+ /** Its own `afterCreate` (see {@link AnnotationToolDef.afterCreate}), over the setting. */
297
+ afterCreate?: Partial<AfterCreateSettings>;
298
+ /** A line gesture is captured, not created ({@link CAPTURE_TOOLS}). */
299
+ capture: boolean;
300
+ meta?: Record<string, unknown>;
301
+ }
302
+ /**
303
+ * The built-in tools, as data (shapes + lines + ink
304
+ * + free text in the draw channel, text markup + caret behind text selection, and
305
+ * the click-to-place stamp). Order is display-neutral; the toolbar owns layout.
306
+ */
307
+ declare const DEFAULT_TOOLS: AnnotationToolInput[];
308
+ //#endregion
309
+ //#region src/token.d.ts
310
+ declare const AnnotationToken: import("@embedpdf/core").CapabilityToken<AnnotationCapability>;
311
+ //#endregion
312
+ //#region src/state.d.ts
313
+ declare const annotationState: import("@embedpdf/core").StateDeclaration<AnnotationCapability, {
314
+ status: import("@embedpdf/core").ResourceStatus;
315
+ selected: readonly import("@embedpdf/engine-core/runtime").Annotation[];
316
+ hovered: import("@embedpdf/engine-core/runtime").Annotation | null;
317
+ editing: import("@embedpdf/engine-core/runtime").Annotation | null;
318
+ }>;
319
+ //#endregion
320
+ //#region src/contract.d.ts
321
+ /** `'solid'` or `'dashed'` (4 pixels on, 3 off). */
322
+ type LineStyle = 'solid' | 'dashed';
323
+ /**
324
+ * How a selection looks: its outline, its handles and rotation handle, the
325
+ * lines shown while snapping and turning, the box dragged to select, a text
326
+ * box's outline while typing, and the angle while turning. Every size is in
327
+ * screen pixels, so it looks the same at every zoom. A color left `null`
328
+ * follows the part named in its doc, and in the end `accent`; every color,
329
+ * width and dash can also come from a CSS variable (`--epdf-annotation-*`),
330
+ * which wins over the setting.
331
+ */
332
+ interface ChromeSettings {
333
+ /** The color of every part below that has none of its own; `null` follows the viewer's accent. */
334
+ readonly accent: string | null;
335
+ /** The box around the selection. */
336
+ readonly outline: {
337
+ /** `null` follows `accent`. */
338
+ readonly color: string | null;
339
+ readonly style: LineStyle;
340
+ /** Line width, px. */
341
+ readonly width: number;
342
+ };
343
+ /** The resize and point handles. */
344
+ readonly handles: {
345
+ readonly shape: 'square' | 'circle';
346
+ /** What you see, px. */
347
+ readonly size: number;
348
+ /** What you can grab, px: keep it at 24 or more for touch. */
349
+ readonly hitSize: number;
350
+ readonly fill: string;
351
+ /** `null` follows `accent`. */
352
+ readonly stroke: string | null;
353
+ };
354
+ /** The round handle that turns the selection, on a short line (its stalk) above it. */
355
+ readonly rotationHandle: {
356
+ /** `false`: no rotation handle; the selection turns only from code. */
357
+ readonly enabled: boolean;
358
+ /** Its diameter, px. */
359
+ readonly size: number;
360
+ /** What you can grab, px. */
361
+ readonly hitSize: number;
362
+ /** How far it sits from the selection's edge, px. */
363
+ readonly offset: number;
364
+ /** `false` hides the line from the edge to it. */
365
+ readonly stalk: boolean;
366
+ /** `null` follows `handles.fill`. */
367
+ readonly fill: string | null;
368
+ /** `null` follows `handles.stroke`. */
369
+ readonly stroke: string | null;
370
+ };
371
+ /** The lines shown while snapping (alignment) and while turning (rotation). */
372
+ readonly guides: {
373
+ /** `false`: no rotation guides while turning. */
374
+ readonly enabled: boolean;
375
+ /** What a move snaps to. */
376
+ readonly color: string;
377
+ /** The reference cross and the angle line while turning; `null` follows `accent`. */
378
+ readonly rotationColor: string | null;
379
+ readonly style: LineStyle;
380
+ /** Line width of both kinds, px. */
381
+ readonly width: number;
382
+ };
383
+ /** The box you drag to select several annotations. */
384
+ readonly marquee: {
385
+ /** `null`: `accent` at 8%. */
386
+ readonly fill: string | null;
387
+ /** `null` follows `accent`. */
388
+ readonly stroke: string | null;
389
+ };
390
+ /** The outline of a text box while you type in it; `null` follows `accent`. */
391
+ readonly textOutline: string | null;
392
+ /** The angle shown next to the pointer while you turn a selection. */
393
+ readonly readout: {
394
+ readonly enabled: boolean;
395
+ readonly background: string;
396
+ readonly color: string;
397
+ };
398
+ }
399
+ /**
400
+ * A tool's defaults: the fields its next annotation starts with, its own over
401
+ * the engine's. Which fields there are depends on the tool's kind; the style
402
+ * fields most tools have are typed, the rest read as `unknown`.
403
+ */
404
+ interface ToolDefaults {
405
+ readonly color?: string;
406
+ readonly interiorColor?: string | null;
407
+ readonly opacity?: number;
408
+ readonly strokeWidth?: number;
409
+ readonly fontFamily?: string;
410
+ readonly fontSize?: number;
411
+ readonly fontColor?: string;
412
+ readonly textAlign?: 'left' | 'center' | 'right';
413
+ readonly icon?: string;
414
+ readonly contents?: string | null;
415
+ readonly [field: string]: unknown;
416
+ }
417
+ /** What happens after a tool creates an annotation. A tool's own `afterCreate` wins over this. */
418
+ interface AfterCreateSettings {
419
+ /** Select the new annotation. */
420
+ readonly select: boolean;
421
+ /** `'stay'` keeps the tool active; `'default'` goes back to the default tool, usually `pointer`. */
422
+ readonly tool: 'stay' | 'default';
423
+ /** For text boxes: start typing in the new box right away. */
424
+ readonly editText: boolean;
425
+ }
426
+ /**
427
+ * The annotation settings: what `annotationPlugin(config)` registers over
428
+ * {@link ANNOTATION_DEFAULTS}. `snap`, `chrome`, `afterCreate` and `editable`
429
+ * change for every open document with `updateSettings()`; `tools` is read
430
+ * when a document opens (add a tool to an open one with `tools.register()`).
431
+ */
432
+ interface AnnotationSettings {
433
+ /**
434
+ * Change the built-in tools or add your own. An entry with a built-in's id
435
+ * changes it (`{ id: 'ink', defaults: { strokeWidth: 6 } }`), a new id adds
436
+ * a tool, and `extends` starts from another tool.
437
+ */
438
+ readonly tools: readonly AnnotationToolInput[];
439
+ readonly afterCreate: AfterCreateSettings;
440
+ readonly chrome: ChromeSettings;
441
+ /** Snapping to other annotations and the page while moving, and to angles while turning. */
442
+ readonly snap: SnapSettings;
443
+ /**
444
+ * Which annotations people may change by hand: `true`, every one; `false`,
445
+ * none; or a list of the kinds they may, by subtype (`'highlight'`), a
446
+ * measurement by its intent (`'line-dimension'`). One left out can still be
447
+ * selected, read and commented on, but not moved, resized, turned,
448
+ * restyled, typed in or deleted. Only the interface: your code still
449
+ * changes it, and `canUpdate()` and `canDelete()` don't change.
450
+ */
451
+ readonly editable: EditableKinds;
452
+ }
453
+ /** What the annotation settings are when the app registers none. */
454
+ declare const ANNOTATION_DEFAULTS: AnnotationSettings;
455
+ /** What `annotationPlugin(config)` takes: any of the settings, merged over the defaults. */
456
+ type AnnotationConfig = DeepPartial<AnnotationSettings>;
457
+ /**
458
+ * The armed stamp's ghost: its image, see-through, in the box a click at the
459
+ * pointer would place it in (page space). Every other tool's ghost paints
460
+ * with the page's items (`source: 'ghost'`).
461
+ */
462
+ interface ImageGhost {
463
+ page: PageRef;
464
+ /** The box the stamp's placement would use, before its turn. */
465
+ box: Rect;
466
+ /** The tool's upright turn at this hover (degrees clockwise). */
467
+ rot: number;
468
+ /** How opaque it paints (0–1); `--epdf-ghost-opacity` wins over it. */
469
+ opacity: number;
470
+ }
471
+ /**
472
+ * One clickable link area on a page (page space): a standalone link
473
+ * annotation, or one segment of a parent's attached link. See
474
+ * {@link AnnotationHostCapability.listLinkItems}.
475
+ */
476
+ interface LinkNavItem {
477
+ /** Stable per-page key: the annot id, `#n`-suffixed for attached segments. */
478
+ id: string;
479
+ /** The clickable area in page space. */
480
+ bounds: Rect;
481
+ target: PdfLinkTarget;
482
+ /**
483
+ * True for a link child riding an editable annotation (an `/RT /Group`
484
+ * subordinate): a property of its parent while authoring, a nav behavior
485
+ * only while reading. The nav layer stands its anchors down for attached
486
+ * items whenever the active tool enables `annotation-edit`, so the parent
487
+ * stays selectable/movable; standalone document links navigate regardless.
488
+ */
489
+ attached: boolean;
490
+ /** The full payload-carrying `/A` tree, when one exists: the action
491
+ * engine's dispatch input. `target` remains its root projection. */
492
+ activate?: PdfActionTree;
493
+ /** The annotation ref, carried for ActionSource context. */
494
+ ref?: AnnotationRef;
495
+ /** Which `/AA` hover trees this link carries: the nav layer's pump flags
496
+ * (tree-less hover must cost zero dispatches). Links are behavior-inert
497
+ * to the annotation plane's hover feed while navigable, so their
498
+ * cursorEnter/cursorExit can only fire from the LinkLayer anchors. */
499
+ hoverEvents?: {
500
+ enter: boolean;
501
+ exit: boolean;
502
+ };
503
+ }
504
+ /**
505
+ * A plugin (forms, links) or an interactive renderer marks some annotations as
506
+ * interactive: while engaged, they render their own DOM, take the pointer and
507
+ * are not geometry-editable. Not engaged, they are edited like any other.
508
+ */
509
+ interface Behavior {
510
+ id: string;
511
+ /** Whether this behavior is about the annotation at all. */
512
+ matches(annotation: Annotation): boolean;
513
+ /** Whether it owns the annotation now (read live: the active tool, the app's mode). */
514
+ engaged(annotation: Annotation): boolean;
515
+ }
516
+ /**
517
+ * What a style panel shows: the {@link AnnotationProperty}s in display order,
518
+ * their current `values` by key, and which differ across the selection
519
+ * (`mixed`, shown as "mixed").
520
+ *
521
+ * For the selection, the properties are the ones every selected kind has (a
522
+ * mixed selection shows the shared ones, in the first kind's order), and the
523
+ * values the first member's; empty `properties` means nothing is selected. For
524
+ * a tool, they are its kind's, with its defaults over the engine's. The
525
+ * border's value is three keys (`borderStyle`, `dashArray`,
526
+ * `cloudyIntensity`); a text's font, size, colour and alignment read as the
527
+ * text shows (a free text's `fontColor` follows its `color` when it has none).
528
+ */
529
+ interface AnnotationProperties {
530
+ readonly properties: readonly AnnotationProperty[];
531
+ readonly values: FieldValues;
532
+ readonly mixed: readonly string[];
533
+ }
534
+ /**
535
+ * A free-text annotation projected for the framework: the box (page space,
536
+ * live gesture applied) + the plain text + an `editing` flag + a ready-to-spread
537
+ * CSS style. The framework renders one editable element from this and nothing
538
+ * more: all the mapping (fonts, colours, alignment) is done here, once. The
539
+ * element paints the text only: the box's fill and border are the vector
540
+ * scene's (`listPageItems`), the same for a plain box and a callout, so the
541
+ * live view matches the baked appearance.
542
+ */
543
+ interface TextItem {
544
+ id: string;
545
+ ref: AnnotationRef | null;
546
+ box: Rect;
547
+ contents: string;
548
+ /** The rich paragraphs the editor renders and edits (run deltas over the
549
+ * body, which `css` carries). `contents` is their plain projection. */
550
+ richText: {
551
+ paragraphs: RichTextParagraph[];
552
+ };
553
+ editing: boolean;
554
+ /** Applied rotation (deg, CW). `box` is the unrotated text box; the framework
555
+ * rotates the editable element about its centre by this. 0/undefined = none. */
556
+ rot?: number;
557
+ css: {
558
+ fontFamily: string;
559
+ /** Content units (the framework multiplies by the page scale). The line
560
+ * height is not here: the editor binding states the engine's line model
561
+ * per face on the element itself (`@embedpdf/web`, `lineModelFor`). */
562
+ fontSize: number;
563
+ color: string;
564
+ /** The body's formatting (runs override it as inline spans). */
565
+ fontWeight: number;
566
+ fontStyle: 'normal' | 'italic';
567
+ textDecoration: 'none' | 'underline';
568
+ align: 'left' | 'center' | 'right';
569
+ padding: number;
570
+ };
571
+ }
572
+ /** What `comments.deleteThread()` did: everything went, or nothing did and `failed` says why. */
573
+ interface ThreadDeleteResult {
574
+ deleted: AnnotationRef[];
575
+ failed: Array<{
576
+ ref: AnnotationRef;
577
+ error: unknown;
578
+ }>;
579
+ }
580
+ /** The public shape of a tool: a named preset over a kind. */
581
+ interface AnnotationTool {
582
+ readonly id: string;
583
+ readonly subtype: KindName;
584
+ /** The defaults key this tool reads and writes. */
585
+ readonly preset: string;
586
+ readonly cursor: string;
587
+ readonly enables: readonly string[];
588
+ readonly defaults?: FieldValues;
589
+ /** The tool's ghost, what a click would place following the pointer: how opaque it paints, or `false`. */
590
+ readonly ghost: ResolvedGhost;
591
+ /** Your own data from the tool's definition, such as a label and an icon. */
592
+ readonly meta?: Readonly<Record<string, unknown>>;
593
+ }
594
+ /** A polygon or polyline being drawn: where it is, how many points it has, and whether it can end. */
595
+ type CreationDraft = CreationDraftAnchor;
596
+ /** A turn in progress: its page, the pointer there, and the angle so far (degrees clockwise). */
597
+ type AnnotationRotationAnchor = RotationAnchor;
598
+ /** Where a menu attaches to the selection: its page and the box around it (page space). */
599
+ interface AnnotationSelectionAnchor {
600
+ readonly page: PageRef;
601
+ readonly bounds: Rect;
602
+ /** The rotation handle's middle, so a menu can stay clear of it; absent without one. */
603
+ readonly rotationHandle?: Point$1;
604
+ }
605
+ /** Where UI attaches to one annotation: its page and the box around what it shows (page space). */
606
+ interface AnnotationAnchor {
607
+ readonly page: PageRef;
608
+ readonly bounds: Rect;
609
+ /**
610
+ * For an annotation that keeps its size or stays upright on screen (a note):
611
+ * the box in a given view, where `bounds` is the box at 100%. `<Anchored>`
612
+ * calls it, so the anchor doesn't change while people zoom. Absent for
613
+ * every other annotation.
614
+ */
615
+ readonly boundsIn?: (view: ViewEnv) => Rect | null;
616
+ }
617
+ /** An annotation was added: the engine's record, whoever added it. */
618
+ interface AnnotationCreatedEvent {
619
+ readonly annotation: Annotation;
620
+ readonly origin: EventOrigin;
621
+ }
622
+ /** An annotation was changed: the engine's record after the change. */
623
+ interface AnnotationUpdatedEvent {
624
+ readonly annotation: Annotation;
625
+ readonly origin: EventOrigin;
626
+ }
627
+ /** Annotations were deleted: one, and what went with it (its popup, replies and review states). */
628
+ interface AnnotationDeletedEvent {
629
+ /** Everything that went, the annotation first. */
630
+ readonly refs: readonly AnnotationRef[];
631
+ readonly page: PageRef;
632
+ readonly origin: EventOrigin;
633
+ }
634
+ /** The drawing order on a page changed: `order` is the page's annotations, bottom to top. */
635
+ interface AnnotationReorderedEvent {
636
+ readonly page: PageRef;
637
+ readonly order: readonly AnnotationRef[];
638
+ readonly origin: EventOrigin;
639
+ }
640
+ /** Annotations were read again (a document opening, a page re-read): not a list of creates. */
641
+ interface AnnotationResyncedEvent {
642
+ readonly pages: readonly PageRef[] | 'all';
643
+ }
644
+ /**
645
+ * The engine refused a change the user made (a revoked grant, a lock set
646
+ * elsewhere). The change is already gone from the view, which shows the
647
+ * engine's record again; this says why, so a UI can tell the user.
648
+ */
649
+ interface AnnotationWriteFailedEvent {
650
+ /** The existing annotations the refused write carried; empty for a refused create. */
651
+ readonly refs: readonly AnnotationRef[];
652
+ readonly error: PluginErrorInfo;
653
+ }
654
+ /** The selection changed. */
655
+ interface AnnotationSelectionChangedEvent {
656
+ readonly refs: readonly AnnotationRef[];
657
+ readonly previousRefs: readonly AnnotationRef[];
658
+ }
659
+ /** A polygon or polyline started, got a point, or ended. */
660
+ interface AnnotationDraftChangedEvent {
661
+ readonly draft: CreationDraft | null;
662
+ }
663
+ /** Typing in a text box started (`ref`) or ended (`null`). */
664
+ interface AnnotationEditingChangedEvent {
665
+ readonly ref: AnnotationRef | null;
666
+ }
667
+ /** The pointer moved onto an annotation (`ref`), or off it (`null`). */
668
+ interface AnnotationHoverChangedEvent {
669
+ readonly ref: AnnotationRef | null;
670
+ }
671
+ /** A tool's defaults changed, from your UI or your code. */
672
+ interface ToolDefaultsChangedEvent {
673
+ readonly toolId: string;
674
+ /** The tool's defaults now, as `tools.getDefaults(toolId)` returns them. */
675
+ readonly defaults: ToolDefaults;
676
+ }
677
+ /** A thread changed through this viewer. */
678
+ interface CommentThreadChangedEvent {
679
+ readonly rootRef: AnnotationRef;
680
+ readonly change: 'reply' | 'text' | 'status' | 'marked' | 'deleted';
681
+ }
682
+ /** Which annotations `list()` returns: every field narrows. */
683
+ interface AnnotationFilter {
684
+ /** Only these pages, as refs or indexes. */
685
+ readonly pages?: readonly (PageRef | number)[];
686
+ readonly subtype?: AnnotationSubtype;
687
+ }
688
+ /** What `import()` did: the new annotations, where each bundle ref went, and what was left out. */
689
+ interface AnnotationImportResult {
690
+ /** The new annotations, in bundle order. */
691
+ readonly annotations: readonly Annotation[];
692
+ /** Each imported annotation's ref in the bundle, and its new ref here. */
693
+ readonly refMap: ReadonlyArray<{
694
+ readonly from: AnnotationRef;
695
+ readonly to: AnnotationRef;
696
+ }>;
697
+ /** What was left out, and why, in bundle order. */
698
+ readonly dropped: readonly AnnotationImportDrop[];
699
+ }
700
+ /** Which annotations `export()` takes. */
701
+ interface AnnotationExportSelection {
702
+ /** These annotations, with what they point at and their replies. */
703
+ readonly refs?: readonly AnnotationRef[];
704
+ /** Every annotation on these pages, as refs or indexes. */
705
+ readonly pages?: readonly (PageRef | number)[];
706
+ }
707
+ /** The selection: what is selected, and the verbs that change it as one. */
708
+ interface AnnotationSelectionApi {
709
+ /** Select these annotations; an annotation in a group brings its group. */
710
+ set(refs: readonly AnnotationRef[]): void;
711
+ /** Add these annotations to the selection, with their groups. */
712
+ add(refs: readonly AnnotationRef[]): void;
713
+ /** Select everything that can be selected, on one page or in the whole document. */
714
+ selectAll(page?: PageRef | number): void;
715
+ /**
716
+ * Select everything a box on a page touches of what it paints (its lines,
717
+ * or the inside of a filled shape), with the rest of each one's group, as
718
+ * dragging on empty space does. Throws `not-found` for a page that isn't
719
+ * in the document.
720
+ */
721
+ selectInRect(page: PageRef | number, rect: Rect): void;
722
+ /** Clear the selection. */
723
+ clear(): void;
724
+ /** The selected annotations, as the user sees them. */
725
+ list(): readonly Annotation[];
726
+ /**
727
+ * Change the selected annotations: each takes the fields its kind has, and
728
+ * skips the rest. A function changes each relative to itself. While words
729
+ * are selected in a text box being typed in, its font, size, colour and
730
+ * formats change those words. Resolves once the engine wrote every change,
731
+ * with what it refused in `failed`.
732
+ */
733
+ update(changes: AnnotationPatch | ((annotation: Annotation) => AnnotationPatch), options?: OperationOptions): Promise<BatchResult<AnnotationRef, AnnotationRef>>;
734
+ /** Link the selected annotations to a page or a website, or remove their links with `null`. */
735
+ updateLink(target: PdfLinkTarget | null, options?: OperationOptions): Promise<BatchResult<AnnotationRef, AnnotationRef>>;
736
+ /** What a style panel shows for the selection. The same object while nothing changes. */
737
+ getProperties(): AnnotationProperties;
738
+ /** Delete every selected annotation. */
739
+ delete(options?: OperationOptions): Promise<BatchResult<AnnotationRef, AnnotationRef>>;
740
+ /** Turn the selection a quarter turn: `90` clockwise, `-90` the other way. */
741
+ rotateBy(degrees: 90 | -90, options?: OperationOptions): Promise<void>;
742
+ /** Turn the selection upright again. */
743
+ resetRotation(options?: OperationOptions): Promise<void>;
744
+ /** Make the selected annotations one group, saved the way Acrobat saves it. */
745
+ group(options?: OperationOptions): Promise<void>;
746
+ /** Split the selected groups up again. */
747
+ ungroup(options?: OperationOptions): Promise<void>;
748
+ /** Whether the selection can be grouped: two or more on one page, each changeable. */
749
+ canGroup(): boolean;
750
+ /** Whether the selection holds a group that can be split. */
751
+ canUngroup(): boolean;
752
+ /**
753
+ * Where a menu attaches: the selection's page and the box around it, or
754
+ * `null` with nothing selected, or while a gesture moves, resizes or turns it.
755
+ */
756
+ getAnchor(): AnnotationSelectionAnchor | null;
757
+ /** While the selection is being turned: the pointer's point and the angle so far, or `null`. */
758
+ getRotationAnchor(): AnnotationRotationAnchor | null;
759
+ }
760
+ /** A polygon or polyline being drawn, a click per point. */
761
+ interface AnnotationDraftApi {
762
+ /** The shape being drawn, or `null`. */
763
+ get(): CreationDraft | null;
764
+ /** End the shape and create it, as a double-click does. Resolves `null` when there was none to make. */
765
+ finish(options?: OperationOptions): Promise<{
766
+ annotation: Annotation;
767
+ } | null>;
768
+ /** Drop the shape being drawn. */
769
+ cancel(): void;
770
+ }
771
+ /** Typing in a text box. */
772
+ interface AnnotationTextApi {
773
+ /** Start typing in a text box, as a double-click does. */
774
+ begin(ref: AnnotationRef): void;
775
+ /** Stop typing, and save what was typed. */
776
+ end(options?: OperationOptions): Promise<void>;
777
+ /** The text box being typed in, or `null`. */
778
+ getEditing(): Annotation | null;
779
+ /** Bold, italic or underline on or off: for the selected words, or the whole of each selected box. */
780
+ toggleFormat(format: TextFormat, options?: OperationOptions): Promise<void>;
781
+ }
782
+ /** The tools: what a click or a drag creates, with which defaults. */
783
+ interface AnnotationToolsApi {
784
+ /** Every tool, the built-in ones and yours. */
785
+ list(): readonly AnnotationTool[];
786
+ /** One tool, or `null`. */
787
+ get(id: string): AnnotationTool | null;
788
+ /** Add a tool while the app runs, or replace the one with the same id. Returns a function that removes it. */
789
+ register(tool: AnnotationToolInput): Unsubscribe;
790
+ /** The fields a tool's next annotation starts with: its defaults over the engine's. The same object until they change. */
791
+ getDefaults(id: string): ToolDefaults;
792
+ /**
793
+ * Change a tool's defaults for the drawings that follow: each value whole,
794
+ * as in a patch. They stay in this viewer. Fires `onDefaultsChanged`.
795
+ */
796
+ updateDefaults(id: string, changes: FieldValues): void;
797
+ /** What a style panel for the tool shows, the same shape as `selection.getProperties()`. */
798
+ getProperties(id: string): AnnotationProperties;
799
+ /** A tool's defaults changed. */
800
+ readonly onDefaultsChanged: EventHook<ToolDefaultsChangedEvent>;
801
+ }
802
+ /** A stamp's bytes, to arm for a click or to place from code. */
803
+ interface StampInput {
804
+ /** PNG, JPEG, or one-page PDF bytes (`Blob | Uint8Array | BinaryPayload`). */
805
+ source: BinarySource;
806
+ /** Placed width in PDF points (height follows the picture). Default: the picture's own width. */
807
+ targetWidth?: number;
808
+ /** The placed annotation's `/Name`: the stamp identifier (standard or custom). */
809
+ name?: string;
810
+ /** The placed annotation's `/Subj`. */
811
+ subject?: string;
812
+ /**
813
+ * The hover ghost's image. Either fixed bytes (PNG/JPEG) or, for vector
814
+ * sources, which are only right at one size on screen, a
815
+ * {@link StampPreviewProvider} the ghost asks for a render at the device
816
+ * pixel width it shows at. Raster sources default to themselves; without
817
+ * one a PDF source shows no ghost.
818
+ */
819
+ preview?: BinarySource | StampPreviewProvider;
820
+ /**
821
+ * The source's own size in PDF points. Raster sources are measured from
822
+ * their header, but PDF bytes carry no size a sniff can read: a caller that
823
+ * knows it (a stamp library does) passes it here so placement keeps the
824
+ * picture's aspect.
825
+ */
826
+ intrinsicSize?: {
827
+ width: number;
828
+ height: number;
829
+ };
830
+ }
831
+ /** Where `stamps.place()` puts a stamp, without a click. */
832
+ interface StampPlacement {
833
+ /** The page, as a ref or an index. */
834
+ page: PageRef | number;
835
+ /** Where its middle goes, in page space. The size comes from the picture. */
836
+ center: Point$1;
837
+ /** Placed width in PDF points; default the picture's own (or the stamp's `targetWidth`). */
838
+ targetWidth?: number;
839
+ /** Its turn, degrees clockwise. Default 0. */
840
+ rotation?: number;
841
+ /** Select it, as placing it with a click would. Default false: code never changes the selection. */
842
+ select?: boolean;
843
+ }
844
+ /** Stamps placed from bytes: armed for the next click, or placed from code. */
845
+ interface AnnotationStampsApi {
846
+ /**
847
+ * Arm a stamp's bytes so the next click places them, as the `stamp` tool
848
+ * does after picking a file. Rejects `invalid-input` for bytes that aren't
849
+ * PNG, JPEG or a one-page PDF.
850
+ */
851
+ arm(stamp: StampInput, options?: OperationOptions): Promise<void>;
852
+ /** Disarm the stamp. */
853
+ disarm(): void;
854
+ /** Whether a stamp is armed. */
855
+ isArmed(): boolean;
856
+ /**
857
+ * Place a stamp's bytes with its middle on `center`, sized by its picture
858
+ * and kept on the page, as a click would. Resolves `{ annotation }`.
859
+ * Rejects `permission-denied` without `annotations:create`, `not-found` for
860
+ * a page that isn't in the document, `invalid-input` for bytes that aren't
861
+ * a picture.
862
+ */
863
+ place(stamp: StampInput, placement: StampPlacement, options?: OperationOptions): Promise<{
864
+ annotation: Annotation;
865
+ }>;
866
+ }
867
+ /** Links attached to annotations (a link child), or a link annotation's own target. */
868
+ interface AnnotationLinksApi {
869
+ /** Where an annotation links to, or `null`. */
870
+ get(ref: AnnotationRef): PdfLinkTarget | null;
871
+ /** Link an annotation to a page or a website. */
872
+ set(ref: AnnotationRef, target: PdfLinkTarget, options?: OperationOptions): Promise<void>;
873
+ /** Remove an annotation's link. */
874
+ clear(ref: AnnotationRef, options?: OperationOptions): Promise<void>;
875
+ }
876
+ /**
877
+ * Comments and replies: threads over the annotations. Every verb is a plain
878
+ * annotation create, change or delete, so other people's changes, this
879
+ * viewer's and reloads all show in `listThreads()`.
880
+ */
881
+ interface CommentsApi {
882
+ /** Every thread, in reading order: by page, then from the top of the page. */
883
+ listThreads(): readonly CommentThread[];
884
+ /** The thread a comment is in (its first comment, a reply or a review state), or `null`. */
885
+ getThread(ref: AnnotationRef): CommentThread | null;
886
+ /**
887
+ * Reply to the thread's first comment, whichever comment you pass.
888
+ * Resolves `{ annotation }`. Rejects `permission-denied` without
889
+ * `annotations:create`.
890
+ */
891
+ reply(ref: AnnotationRef, text: string, options?: OperationOptions): Promise<{
892
+ annotation: Annotation;
893
+ }>;
894
+ /** Change a comment's text. Rejects `permission-denied` when `canSetText(ref)` is false. */
895
+ setText(ref: AnnotationRef, text: string, options?: OperationOptions): Promise<void>;
896
+ /** Set the user's review state on a thread, such as `'accepted'`. */
897
+ setStatus(ref: AnnotationRef, state: string, options?: OperationOptions): Promise<void>;
898
+ /** Check a thread off for the user, or clear the check mark. */
899
+ setMarked(ref: AnnotationRef, marked: boolean, options?: OperationOptions): Promise<void>;
900
+ /** Delete a comment with its replies; the first comment of a thread deletes the thread. */
901
+ delete(ref: AnnotationRef, options?: OperationOptions): Promise<void>;
902
+ /** Delete a whole thread, all of it or none. */
903
+ deleteThread(ref: AnnotationRef, options?: OperationOptions): Promise<ThreadDeleteResult>;
904
+ /** Whether the user may reply to this thread (`annotations:create`). */
905
+ canReply(ref: AnnotationRef): boolean;
906
+ /** Whether the user may change this comment's text (`annotations:update`, and not `lockedContents`). */
907
+ canSetText(ref: AnnotationRef): boolean;
908
+ /** Whether the user may set a review state on this thread (`annotations:create`). */
909
+ canSetStatus(ref: AnnotationRef): boolean;
910
+ /** Whether the user may check this thread off (`annotations:create`). */
911
+ canSetMarked(ref: AnnotationRef): boolean;
912
+ /** Whether the user may delete this comment (`annotations:delete`, and not `locked`). */
913
+ canDelete(ref: AnnotationRef): boolean;
914
+ /** Whether the user may delete every comment in this thread. */
915
+ canDeleteThread(ref: AnnotationRef): boolean;
916
+ /** A thread changed through this viewer: a reply, a text, a review state, a check mark or a delete. */
917
+ readonly onThreadChanged: EventHook<CommentThreadChangedEvent>;
918
+ }
919
+ /**
920
+ * The annotation API: the documented, stable surface for application code.
921
+ * Resolve it with the token re-exported from the package root
922
+ * (`@embedpdf/plugin-annotation`). Framework-only plumbing lives on
923
+ * {@link AnnotationHostCapability} in `@embedpdf/plugin-annotation/contract/host`.
924
+ */
925
+ interface AnnotationCapability extends SettingsApi<AnnotationSettings> {
926
+ /**
927
+ * The annotation as the user sees it: the engine's record with any change
928
+ * the user made applied, as the engine will apply it. A new annotation shows
929
+ * before the engine confirms it, under the `nm` ref it was created with.
930
+ */
931
+ get(ref: AnnotationRef): Annotation | null;
932
+ /** Every annotation in drawing order, or the ones on some pages or of one kind. */
933
+ list(filter?: AnnotationFilter): readonly Annotation[];
934
+ /**
935
+ * The topmost annotation at a point on a page, or `null`. A selected
936
+ * annotation's handles count as the annotation. A page that isn't in the
937
+ * document has none.
938
+ */
939
+ getAt(page: PageRef | number, point: Point$1): Annotation | null;
940
+ /** Whether a change the user made to it waits for the engine. */
941
+ isPending(ref: AnnotationRef): boolean;
942
+ /** `loading` until the document's annotations are in, then `ready`; `forbidden` or `error` when they can't load. */
943
+ getStatus(): ResourceStatus;
944
+ /** The annotation under the pointer, or `null`. */
945
+ getHovered(): Annotation | null;
946
+ /** Read every annotation from the engine again. */
947
+ refresh(options?: OperationOptions): Promise<void>;
948
+ /**
949
+ * Create an annotation from its kind and fields: what they leave out takes
950
+ * the `tool`'s defaults when one is named, then the engine's. Bytes travel
951
+ * beside them (a stamp's `appearance`, a file attachment's `file`). It
952
+ * shows at once; resolves `{ annotation }` with the engine's record.
953
+ * `select` selects it, as drawing it would; without it, code never changes
954
+ * the selection. A read of another annotation makes the same one again (a
955
+ * copy): its own fields are written, and where it is comes from `page`.
956
+ * Rejects `permission-denied` without `annotations:create`, `not-found` for
957
+ * a page that isn't in the document or an unknown `tool`, `invalid-input`
958
+ * for a kind the engine doesn't know or a value a write can't make (another
959
+ * app's beveled border).
960
+ */
961
+ create(page: PageRef | number, draft: AnnotationDraft | Annotation, resources?: AnnotationResources, options?: OperationOptions & {
962
+ tool?: string;
963
+ select?: boolean;
964
+ }): Promise<{
965
+ annotation: Annotation;
966
+ }>;
967
+ /**
968
+ * What a text tool makes of the selected text, one annotation per page: a
969
+ * highlight, underline, strikeout or squiggly line, an insertion caret, a
970
+ * replacement or a redaction mark. Resolves `{ annotations }` (empty
971
+ * without a text selection). The text selection is cleared afterwards
972
+ * unless `clear` is `false`. Rejects `permission-denied` without
973
+ * `annotations:create`, `not-found` for a tool that makes nothing of
974
+ * selected text.
975
+ */
976
+ createFromSelection(tool: string, options?: OperationOptions & {
977
+ clear?: boolean;
978
+ }): Promise<{
979
+ annotations: readonly Annotation[];
980
+ }>;
981
+ /**
982
+ * Change the fields the patch names, as given: the engine works out what
983
+ * follows (a free text's body from its font, a measurement's label from its
984
+ * points, a drawn kind's shape from a new `rect`). New bytes replace what
985
+ * they are for. It shows at once; resolves `{ annotation }` with the
986
+ * engine's record. Rejects `not-found` for an annotation that isn't here.
987
+ */
988
+ update(ref: AnnotationRef, patch: AnnotationPatch, resources?: AnnotationResources, options?: OperationOptions): Promise<{
989
+ annotation: Annotation;
990
+ }>;
991
+ /** Delete an annotation, with its popup and its replies. Fires `onDeleted`. */
992
+ delete(ref: AnnotationRef, options?: OperationOptions): Promise<void>;
993
+ /**
994
+ * Change the drawing order on one page: the annotations go together, in
995
+ * the order given, right after or before a neighbour annotation of the page
996
+ * (`{ after: ref }`, `{ before: ref }`), or to the bottom (`'start'`) or the
997
+ * top (`'end'`). Shows at once; fires `onReordered`. Rejects `invalid-input`
998
+ * for refs on different pages and `not-found` for a neighbour that isn't
999
+ * there. Widgets paint above every annotation and are ordered by the form.
1000
+ */
1001
+ reorder(refs: readonly AnnotationRef[], position: AnnotationPosition, options?: OperationOptions): Promise<void>;
1002
+ /**
1003
+ * Take annotations out as a bundle, with the bytes they carry (a stamp's
1004
+ * drawing, an attached file): every annotation, a selection of them (with
1005
+ * what they point at and their replies), or some pages'. Waits for pending
1006
+ * changes first. Rejects `permission-denied` without `doc.download`.
1007
+ */
1008
+ export(selection?: AnnotationExportSelection, options?: OperationOptions): Promise<AnnotationBundle>;
1009
+ /**
1010
+ * Put a bundle's annotations into this document, as one change: they show
1011
+ * once it's done. Resolves `{ annotations, refMap, dropped }`. Rejects
1012
+ * `permission-denied` without `annotations:create` (and, for the default
1013
+ * `attribution: 'restore'`, `doc.annotate.import`).
1014
+ */
1015
+ import(bundle: AnnotationBundle, options?: AnnotationImportOptions & OperationOptions): Promise<AnnotationImportResult>;
1016
+ /**
1017
+ * Download a stamp's drawing (`'appearance'`) or an attachment's file
1018
+ * (`'file'`): the bytes `create()` takes to make it again. Rejects
1019
+ * `permission-denied` without `doc.download`, `not-found` for an annotation
1020
+ * that isn't here, `invalid-input` for a role its kind doesn't have.
1021
+ */
1022
+ downloadResource(ref: AnnotationRef, role: AnnotationResourceRole, options?: OperationOptions): Promise<Uint8Array>;
1023
+ readonly links: AnnotationLinksApi;
1024
+ readonly selection: AnnotationSelectionApi;
1025
+ readonly draft: AnnotationDraftApi;
1026
+ readonly text: AnnotationTextApi;
1027
+ readonly tools: AnnotationToolsApi;
1028
+ readonly stamps: AnnotationStampsApi;
1029
+ readonly comments: CommentsApi;
1030
+ /**
1031
+ * Set the function that gives the `stamp` and `attachment` tools their
1032
+ * file, `null` to make them do nothing. Returns a function that removes it.
1033
+ */
1034
+ setFilePickerProvider(provider: FilePickerProvider | null): Unsubscribe;
1035
+ /** Whether the user may see annotations (`doc.annotate.read`). */
1036
+ canRead(): boolean;
1037
+ /** Whether the user may create annotations (`annotations:create`). */
1038
+ canCreate(): boolean;
1039
+ /** Whether the user may change this annotation: its permission and its own `locked` flag. */
1040
+ canUpdate(ref: AnnotationRef): boolean;
1041
+ /** Whether the user may delete this annotation: its permission and its own `locked` flag. */
1042
+ canDelete(ref: AnnotationRef): boolean;
1043
+ /**
1044
+ * Whether the `editable` setting lets people change this annotation by
1045
+ * hand; `false` for one the document doesn't have. Whether a change would
1046
+ * succeed is `canUpdate()` and `canDelete()`.
1047
+ */
1048
+ isEditable(ref: AnnotationRef): boolean;
1049
+ /** Stop a drag, or a polygon in progress. */
1050
+ cancel(): void;
1051
+ /** An annotation was added, once the engine saved it. */
1052
+ readonly onCreated: EventHook<AnnotationCreatedEvent>;
1053
+ /** An annotation was changed, once the engine saved it. */
1054
+ readonly onUpdated: EventHook<AnnotationUpdatedEvent>;
1055
+ /** Annotations were deleted: one, plus its popup and replies. */
1056
+ readonly onDeleted: EventHook<AnnotationDeletedEvent>;
1057
+ /** The drawing order on a page changed. */
1058
+ readonly onReordered: EventHook<AnnotationReorderedEvent>;
1059
+ /** Annotations were read again, as after loading a document. */
1060
+ readonly onResynced: EventHook<AnnotationResyncedEvent>;
1061
+ /** The engine refused a change the user made; the view already shows the engine's record again. */
1062
+ readonly onWriteFailed: EventHook<AnnotationWriteFailedEvent>;
1063
+ /** The selection changed. */
1064
+ readonly onSelectionChanged: EventHook<AnnotationSelectionChangedEvent>;
1065
+ /** A polygon or polyline is being drawn, or ended. */
1066
+ readonly onDraftChanged: EventHook<AnnotationDraftChangedEvent>;
1067
+ /** Typing in a text box started or ended. */
1068
+ readonly onEditingChanged: EventHook<AnnotationEditingChangedEvent>;
1069
+ /** The pointer moved onto an annotation, or off it. */
1070
+ readonly onHoverChanged: EventHook<AnnotationHoverChangedEvent>;
1071
+ }
1072
+ type MarkupSubtype = 'highlight' | 'underline' | 'strikeout' | 'squiggly';
1073
+ /** The armed stamp: its placement size and identity. */
1074
+ interface ArmedStampInfo {
1075
+ /** Placement size in PDF points. */
1076
+ readonly width: number;
1077
+ readonly height: number;
1078
+ readonly name?: string;
1079
+ readonly subject?: string;
1080
+ }
1081
+ /** The armed stamp's paintable preview, for the render layer's ghost `<img>`. */
1082
+ interface ArmedStampPreview {
1083
+ bytes: Uint8Array;
1084
+ mimeType?: string;
1085
+ }
1086
+ /**
1087
+ * Resolution-aware ghost preview: "give me this stamp at `devicePixelWidth`
1088
+ * pixels wide". The annotation plugin buckets the request (see
1089
+ * `previewBucket`) and caches per bucket for the arm's lifetime, so a zoom
1090
+ * gesture never renders per frame and one render serves a zoom range. A stamp
1091
+ * library renders its page lazily through its asset engine; a raster returns
1092
+ * itself (it cannot get sharper than its pixels).
1093
+ */
1094
+ type StampPreviewProvider = (devicePixelWidth: number) => Promise<ArmedStampPreview | null>;
1095
+ /**
1096
+ * What the {@link FilePickerProvider} is asked for: which tool clicked (id +
1097
+ * the kind it creates), the tool's `accept` filter, and the page-space point
1098
+ * the click landed on: enough to route per tool (asset library for stamps,
1099
+ * cloud drive for attachments) or position a picker near the click. Plain
1100
+ * data: the request crosses the plugin↔adapter boundary as a message.
1101
+ */
1102
+ interface FilePromptRequest {
1103
+ toolId: string;
1104
+ /** The kind the placement creates: the routing key for per-tool pickers. */
1105
+ subtype: KindName;
1106
+ /** The tool's file-dialog filter hint (from the tool def). UX only:
1107
+ * the engine sniffs and validates the bytes. */
1108
+ accept?: string;
1109
+ page: PageRef;
1110
+ /** The page-space point the placement is centred on. */
1111
+ point: Point$1;
1112
+ }
1113
+ /**
1114
+ * The one environment port behind every click-then-pick tool (the stamp
1115
+ * `'prompt'` source and the file-attachment tool, whose file is picked after
1116
+ * the spot): given a click, produce the file to place, `null` to cancel. The
1117
+ * plugin declares this contract but never implements it: a file dialog is a
1118
+ * DOM concern, so the framework adapter installs the implementation via
1119
+ * {@link AnnotationCapability.setFilePickerProvider}. The return shape is the
1120
+ * engine's file vocabulary: a stamp takes only `data`; an attachment embeds
1121
+ * the whole thing. A picked `File` carries its own name and type; a provider
1122
+ * returning raw bytes for an attachment must supply `name` itself.
1123
+ */
1124
+ type FilePickerProvider = (request: FilePromptRequest) => Promise<AttachmentFileSource | null>;
1125
+ //#endregion
1126
+ export { Color as $, AnnotationResources$1 as A, annotationState as At, AnnotationTool as B, ResolvedTool as Bt, AnnotationPatch$1 as C, StampPlacement as Ct, AnnotationRef$1 as D, ThreadDeleteResult as Dt, AnnotationProperty$1 as E, TextItem as Et, AnnotationSelectionChangedEvent as F, DEFAULT_TOOLS as Ft, ArmedStampInfo as G, Face as Gt, AnnotationTransfer as H, StampSourceSpec as Ht, AnnotationSettings as I, GhostPolicy as It, AttachmentFileSource$1 as J, ArmedStampPreview as K, TextFormat as Kt, AnnotationStampsApi as L, InkAuthoringOptions as Lt, AnnotationRotationAnchor as M, ARMED_STAMP_TOOL_ID as Mt, AnnotationSelectionAnchor as N, AnnotationToolDef as Nt, AnnotationReorderedEvent as O, ToolDefaults as Ot, AnnotationSelectionApi as P, AnnotationToolInput as Pt, ClickCreate$1 as Q, AnnotationSubtype$1 as R, PromptSourceSpec as Rt, AnnotationOption as S, StampInput as St, AnnotationProperties as T, TextAlign as Tt, AnnotationUpdatedEvent as U, ToolAuthoringKind as Ut, AnnotationToolsApi as V, SelectionAuthoring as Vt, AnnotationWriteFailedEvent as W, ToolDefaultsFor as Wt, BlendMode as X, Behavior as Y, ChromeSettings as Z, AnnotationHoverChangedEvent as _, MarkupSubtype as _t, AnnotationBundle$1 as a, EditableKind as at, AnnotationImportResult as b, ReviewStatus as bt, AnnotationCreatedEvent as c, FilePickerProvider as ct, AnnotationDraftApi as d, HandleRole as dt, CommentThread$1 as et, AnnotationDraftChangedEvent as f, ImageGhost as ft, AnnotationFlags$1 as g, LinkNavItem as gt, AnnotationFilter as h, LineStyle as ht, AnnotationAnchor as i, CreationDraft as it, AnnotationResyncedEvent as j, AnnotationToken as jt, AnnotationResourceRole$1 as k, ToolDefaultsChangedEvent as kt, AnnotationDeletedEvent as l, FilePromptRequest as lt, AnnotationExportSelection as m, LineEndings as mt, AfterCreateSettings as n, CommentThreadReview as nt, AnnotationCapability as o, EditableKinds$1 as ot, AnnotationEditingChangedEvent as p, LineEnding as pt, AttachmentContent as q, TextSelection as qt, Annotation$1 as r, CommentsApi as rt, AnnotationConfig as s, FieldValues$1 as st, ANNOTATION_DEFAULTS as t, CommentThreadChangedEvent as tt, AnnotationDraft$1 as u, FlagKey as ut, AnnotationImportDrop$1 as v, MeasurementIntent as vt, AnnotationPosition$1 as w, StampPreviewProvider as wt, AnnotationLinksApi as x, SnapSettings$1 as xt, AnnotationImportOptions$1 as y, PdfLinkTarget$1 as yt, AnnotationTextApi as z, ResolvedGhost as zt };
1127
+ //# sourceMappingURL=contract-BOo9iZKo.d.ts.map