@ai-matrx/office 0.8.49 → 0.8.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pdf.d.cts CHANGED
@@ -2,6 +2,67 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
3
  import { ComingSoonEntry } from '@ai-matrx/kit/coming-soon';
4
4
 
5
+ /**
6
+ * The markup session the workspace drives, as the workspace needs it. The implementation is
7
+ * `@ai-matrx/media/viewers/pdf` `createPdfMarkupEngine` (PDF.js's annotation editors over the
8
+ * windowed pages); this package does not import the PDF engine, so the contract is written here
9
+ * and the host hands media's engine through `PdfViewerState.onMarkupEngine`, where TypeScript
10
+ * checks the two agree. Change one, change the other (media `viewers/pdf/markup/markup-engine.ts`).
11
+ */
12
+ type PdfMarkupTool = "none" | "highlight" | "freetext" | "ink" | "stamp";
13
+ type PdfMarkupKind = "highlight" | "freetext" | "ink" | "stamp" | "signature";
14
+ interface PdfMarkupStyle {
15
+ /** `#rrggbb`. */
16
+ color: string;
17
+ /** 0-1. */
18
+ opacity: number;
19
+ /** Font size (text box) or stroke width (draw), PDF points. */
20
+ size: number;
21
+ }
22
+ interface PdfMarkupSnapshot {
23
+ tool: PdfMarkupTool;
24
+ pending: number;
25
+ summary: string;
26
+ canUndo: boolean;
27
+ canRedo: boolean;
28
+ selection: {
29
+ kind: PdfMarkupKind;
30
+ rect: {
31
+ x: number;
32
+ y: number;
33
+ width: number;
34
+ height: number;
35
+ };
36
+ style: PdfMarkupStyle;
37
+ comment: string;
38
+ } | null;
39
+ styles: Record<Exclude<PdfMarkupTool, "none">, PdfMarkupStyle>;
40
+ textSelected: boolean;
41
+ }
42
+ type PdfMarkupHistoryEvent = {
43
+ type: "step";
44
+ label: string;
45
+ } | {
46
+ type: "undo" | "redo";
47
+ external: boolean;
48
+ };
49
+ interface PdfMarkupEngine {
50
+ getSnapshot(): PdfMarkupSnapshot;
51
+ subscribe(listener: (snapshot: PdfMarkupSnapshot) => void): () => void;
52
+ onHistory(listener: (event: PdfMarkupHistoryEvent) => void): () => void;
53
+ setTool(tool: PdfMarkupTool): Promise<void>;
54
+ setStyle(patch: Partial<PdfMarkupStyle>): void;
55
+ setComment(text: string): void;
56
+ highlightSelection(): void;
57
+ addImage(image: Blob | string, kind: "stamp" | "signature"): Promise<void>;
58
+ deleteSelected(): void;
59
+ undo(): void;
60
+ redo(): void;
61
+ setCurrentPage(pageNumber: number): void;
62
+ save(): Promise<Uint8Array>;
63
+ destroy(): void;
64
+ }
65
+
5
66
  /**
6
67
  * The page decisions of one workspace session: which pages are turned, left out, or moved. Pure.
7
68
  *
@@ -68,6 +129,12 @@ interface PdfViewerState {
68
129
  onDocumentLoad(pageCount: number): void;
69
130
  /** A page was measured, in PDF points (crop and fit-page need it). */
70
131
  onPageSize(page: number, widthPt: number, heightPt: number): void;
132
+ /**
133
+ * Present only when the host can save markup (`saveMarkup`): the viewer turns on PDF.js's
134
+ * annotation editors and hands their session up here (`null` when the document closes).
135
+ * `@ai-matrx/media/viewers/pdf` takes it as `PdfDocumentViewer.onMarkupEngine`.
136
+ */
137
+ onMarkupEngine?(engine: PdfMarkupEngine | null): void;
71
138
  }
72
139
  type PdfRunRequest = {
73
140
  tool: "apply-pages";
@@ -162,6 +229,8 @@ interface PdfWorkspaceHost {
162
229
  renderViewer(state: PdfViewerState): ReactNode;
163
230
  /** One page thumbnail (the left panel). Absent: the panel numbers its pages only. */
164
231
  renderThumbnail?(page: number, widthPx: number): ReactNode;
232
+ /** A small badge drawn in the corner of one page's thumbnail (the app's annotation count, for example). Null or absent: none. */
233
+ renderPageBadge?(page: number): ReactNode;
165
234
  /** Run one tool on the server. Rejects with a sentence on failure. */
166
235
  run(request: PdfRunRequest): Promise<PdfRunResult>;
167
236
  /** Open another page of the app for the same file (Scan, Sign). */
@@ -195,6 +264,24 @@ interface PdfWorkspaceHost {
195
264
  online?: boolean;
196
265
  /** Show a failure to the person (the host's toast). Defaults to an inline banner. */
197
266
  notify?(message: string, tone: "error" | "info"): void;
267
+ /**
268
+ * Save the file's bytes with markup written in (PDF.js `saveDocument`) as a NEW VERSION of the
269
+ * same file. `summary` is "2 highlights, 1 text box". A markup-only change never re-extracts the
270
+ * text (PDF-PLAN rule R1). Absent: no markup tools.
271
+ */
272
+ saveMarkup?(bytes: Uint8Array, summary: string): Promise<PdfRunResult>;
273
+ /** The annotations already in the file (Acrobat's, Preview's, ours), for the markup panel's list. */
274
+ existingAnnotations?(): Promise<Array<{
275
+ page: number;
276
+ subtype: string;
277
+ contents: string;
278
+ author: string;
279
+ }>>;
280
+ /** The platform's one signature pad (`@ai-matrx/records-ui` SignaturePad). Absent: no Signature tool. */
281
+ signaturePad?: ComponentType<{
282
+ value: unknown;
283
+ onChange: (value: string | null) => void;
284
+ }>;
198
285
  }
199
286
 
200
287
  interface PdfWorkspaceProps {
@@ -214,7 +301,7 @@ declare function PdfWorkspace({ host, className }: PdfWorkspaceProps): react.JSX
214
301
  * third state, so no dead button.
215
302
  */
216
303
 
217
- type PdfToolId = "browse" | "organize" | "extract-pages" | "split" | "crop" | "redact" | "compress" | "scan" | "sign" | "extract-data" | "edit" | "forms" | "protect" | "ocr" | "convert" | "compare" | "stamp";
304
+ type PdfToolId = "browse" | "markup" | "organize" | "extract-pages" | "split" | "crop" | "redact" | "compress" | "scan" | "sign" | "extract-data" | "edit" | "forms" | "protect" | "ocr" | "convert" | "compare" | "stamp";
218
305
  interface PdfToolDef {
219
306
  id: PdfToolId;
220
307
  label: string;
@@ -236,15 +323,98 @@ declare const comingSoonIdOf: (id: PdfToolId) => string;
236
323
  /** One row per unbuilt tool, ready for `registerComingSoon` or the host's registry table. */
237
324
  declare const PDF_COMING_SOON: Record<string, ComingSoonEntry>;
238
325
 
326
+ /**
327
+ * The workspace's markup model (PDF-PLAN U10). Pure: the markup tools as data (which are built,
328
+ * which are coming and why), their keys, the palette, and the ONE session history that holds both
329
+ * page decisions and markup steps, so Undo takes back whichever came last.
330
+ *
331
+ * What is built rides PDF.js's own annotation editors (highlight, text box, draw, image; a
332
+ * signature is an image made on the platform's signature pad; a comment is the note on a piece of
333
+ * markup). What PDF.js's writer cannot make yet is a "Coming soon" row with its reason, never a
334
+ * dead button: underline and strike-out, shapes, a free-standing sticky note, links, editing the
335
+ * page's own text.
336
+ */
337
+
338
+ type PdfMarkupToolId = "highlight" | "freetext" | "ink" | "image" | "signature" | "underline" | "shapes" | "note" | "links" | "edit-text";
339
+ interface PdfMarkupToolDef {
340
+ id: PdfMarkupToolId;
341
+ label: string;
342
+ /** Single key, while the markup tool is open. */
343
+ key?: string;
344
+ status: "ready" | "soon";
345
+ /** The PDF.js editor a ready tool turns on. */
346
+ engineTool?: Exclude<PdfMarkupTool, "none">;
347
+ /** Ready only when the host brings this port. */
348
+ needs?: "signaturePad";
349
+ /** Why a coming tool is not built (shown under its name, and in its Coming-soon promise). */
350
+ reason?: string;
351
+ }
352
+ declare const PDF_MARKUP_TOOLS: readonly PdfMarkupToolDef[];
353
+ declare const pdfMarkupTool: (id: string) => PdfMarkupToolDef | undefined;
354
+ /** The palette markup offers (Acrobat's comment colors). Literal colors are data: they are written into the PDF. */
355
+ declare const MARKUP_SWATCHES: ReadonlyArray<{
356
+ value: string;
357
+ label: string;
358
+ }>;
359
+ /** Which look controls a kind of markup has (the floating toolbar and the panel show only these). */
360
+ declare const MARKUP_STYLE_FIELDS: Record<PdfMarkupKind, ReadonlyArray<keyof PdfMarkupStyle>>;
361
+ /** Sizes offered: font sizes for a text box, stroke widths for a drawing (PDF points). */
362
+ declare const MARKUP_SIZES: Record<"freetext" | "ink", readonly number[]>;
363
+ declare const MARKUP_KIND_LABEL: Record<PdfMarkupKind, string>;
364
+ declare const markupComingSoonId: (id: PdfMarkupToolId) => string;
365
+ /** One Coming-soon row per markup tool not built yet (merged into `PDF_COMING_SOON`). */
366
+ declare const PDF_MARKUP_COMING_SOON: Record<string, ComingSoonEntry>;
367
+ type StepOrigin = "page" | "markup";
368
+ interface SessionTimeline {
369
+ past: Array<{
370
+ origin: StepOrigin;
371
+ label: string;
372
+ }>;
373
+ future: Array<{
374
+ origin: StepOrigin;
375
+ label: string;
376
+ }>;
377
+ }
378
+ declare const TIMELINE_LIMIT = 100;
379
+ declare const emptyTimeline: () => SessionTimeline;
380
+ declare function recordStep(t: SessionTimeline, origin: StepOrigin, label: string): SessionTimeline;
381
+ /** The step Undo would take back, or null. */
382
+ declare const nextUndo: (t: SessionTimeline) => {
383
+ origin: StepOrigin;
384
+ label: string;
385
+ } | null;
386
+ declare const nextRedo: (t: SessionTimeline) => {
387
+ origin: StepOrigin;
388
+ label: string;
389
+ } | null;
390
+ declare function stepBack(t: SessionTimeline): SessionTimeline;
391
+ declare function stepForward(t: SessionTimeline): SessionTimeline;
392
+ /** PDF.js undid a markup step on its own (its keys, focus outside the workspace): move the newest markup step back. */
393
+ declare function markupUndoneElsewhere(t: SessionTimeline): SessionTimeline;
394
+ declare function markupRedoneElsewhere(t: SessionTimeline): SessionTimeline;
395
+ /** Saving (or discarding) one kind of change ends its steps: the file's versions are the durable undo. */
396
+ declare function dropOrigin(t: SessionTimeline, origin: StepOrigin): SessionTimeline;
397
+
239
398
  type PdfActionId = "undo" | "redo" | "find" | "print" | "save" | "zoom-in" | "zoom-out" | "zoom-fit-width" | "zoom-fit-page" | "page-next" | "page-prev" | "page-first" | "page-last" | "rotate-right" | "rotate-left" | "delete-pages" | "select-all-pages" | "toggle-pages" | "toggle-properties" | "read-mode" | "two-up" | "shortcuts" | `tool:${string}`;
240
399
  interface PdfShortcut {
241
400
  action: PdfActionId;
242
401
  label: string;
243
402
  /** Display keys: "Mod+Z" shows as Cmd+Z on a Mac and Ctrl+Z elsewhere. */
244
403
  keys: string;
245
- section: "Edit" | "View" | "Pages" | "Tools";
404
+ section: "Edit" | "View" | "Pages" | "Tools" | "Markup";
246
405
  }
247
406
  declare const PDF_SHORTCUTS: readonly PdfShortcut[];
407
+ /**
408
+ * Keys that work only while "Comment and mark up" is open (they pick a markup tool). Listed in the
409
+ * shortcut map under Markup; Delete, the arrows and Escape act on the selected markup there.
410
+ */
411
+ declare const PDF_MARKUP_SHORTCUTS: ReadonlyArray<{
412
+ tool: PdfMarkupToolId;
413
+ label: string;
414
+ keys: string;
415
+ }>;
416
+ /** The markup tool a plain key picks while markup is open, or null. */
417
+ declare function matchMarkupKey(e: KeyLike, typing: boolean): PdfMarkupToolId | null;
248
418
  interface KeyLike {
249
419
  key: string;
250
420
  ctrlKey: boolean;
@@ -288,4 +458,4 @@ declare const canRedo: (h: History<unknown>) => boolean;
288
458
  declare const undoLabel: (h: History<unknown>) => string;
289
459
  declare const redoLabel: (h: History<unknown>) => string;
290
460
 
291
- export { HISTORY_LIMIT, type History, type KeyLike, PDF_COMING_SOON, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfHostTool, type PdfHostToolContext, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, formatKeys, freshDecisions, isDirty, keptOrder, matchShortcut, pdfTool, pushStep, redo, redoLabel, reorderPages, restorePages, startHistory, turnPages, undo, undoLabel };
461
+ export { HISTORY_LIMIT, type History, type KeyLike, MARKUP_KIND_LABEL, MARKUP_SIZES, MARKUP_STYLE_FIELDS, MARKUP_SWATCHES, PDF_COMING_SOON, PDF_MARKUP_COMING_SOON, PDF_MARKUP_SHORTCUTS, PDF_MARKUP_TOOLS, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfHostTool, type PdfHostToolContext, type PdfMarkupEngine, type PdfMarkupHistoryEvent, type PdfMarkupKind, type PdfMarkupSnapshot, type PdfMarkupStyle, type PdfMarkupTool, type PdfMarkupToolDef, type PdfMarkupToolId, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type SessionTimeline, type StepOrigin, TIMELINE_LIMIT, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, dropOrigin, emptyTimeline, formatKeys, freshDecisions, isDirty, keptOrder, markupComingSoonId, markupRedoneElsewhere, markupUndoneElsewhere, matchMarkupKey, matchShortcut, nextRedo, nextUndo, pdfMarkupTool, pdfTool, pushStep, recordStep, redo, redoLabel, reorderPages, restorePages, startHistory, stepBack, stepForward, turnPages, undo, undoLabel };
package/dist/pdf.d.ts CHANGED
@@ -2,6 +2,67 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
3
  import { ComingSoonEntry } from '@ai-matrx/kit/coming-soon';
4
4
 
5
+ /**
6
+ * The markup session the workspace drives, as the workspace needs it. The implementation is
7
+ * `@ai-matrx/media/viewers/pdf` `createPdfMarkupEngine` (PDF.js's annotation editors over the
8
+ * windowed pages); this package does not import the PDF engine, so the contract is written here
9
+ * and the host hands media's engine through `PdfViewerState.onMarkupEngine`, where TypeScript
10
+ * checks the two agree. Change one, change the other (media `viewers/pdf/markup/markup-engine.ts`).
11
+ */
12
+ type PdfMarkupTool = "none" | "highlight" | "freetext" | "ink" | "stamp";
13
+ type PdfMarkupKind = "highlight" | "freetext" | "ink" | "stamp" | "signature";
14
+ interface PdfMarkupStyle {
15
+ /** `#rrggbb`. */
16
+ color: string;
17
+ /** 0-1. */
18
+ opacity: number;
19
+ /** Font size (text box) or stroke width (draw), PDF points. */
20
+ size: number;
21
+ }
22
+ interface PdfMarkupSnapshot {
23
+ tool: PdfMarkupTool;
24
+ pending: number;
25
+ summary: string;
26
+ canUndo: boolean;
27
+ canRedo: boolean;
28
+ selection: {
29
+ kind: PdfMarkupKind;
30
+ rect: {
31
+ x: number;
32
+ y: number;
33
+ width: number;
34
+ height: number;
35
+ };
36
+ style: PdfMarkupStyle;
37
+ comment: string;
38
+ } | null;
39
+ styles: Record<Exclude<PdfMarkupTool, "none">, PdfMarkupStyle>;
40
+ textSelected: boolean;
41
+ }
42
+ type PdfMarkupHistoryEvent = {
43
+ type: "step";
44
+ label: string;
45
+ } | {
46
+ type: "undo" | "redo";
47
+ external: boolean;
48
+ };
49
+ interface PdfMarkupEngine {
50
+ getSnapshot(): PdfMarkupSnapshot;
51
+ subscribe(listener: (snapshot: PdfMarkupSnapshot) => void): () => void;
52
+ onHistory(listener: (event: PdfMarkupHistoryEvent) => void): () => void;
53
+ setTool(tool: PdfMarkupTool): Promise<void>;
54
+ setStyle(patch: Partial<PdfMarkupStyle>): void;
55
+ setComment(text: string): void;
56
+ highlightSelection(): void;
57
+ addImage(image: Blob | string, kind: "stamp" | "signature"): Promise<void>;
58
+ deleteSelected(): void;
59
+ undo(): void;
60
+ redo(): void;
61
+ setCurrentPage(pageNumber: number): void;
62
+ save(): Promise<Uint8Array>;
63
+ destroy(): void;
64
+ }
65
+
5
66
  /**
6
67
  * The page decisions of one workspace session: which pages are turned, left out, or moved. Pure.
7
68
  *
@@ -68,6 +129,12 @@ interface PdfViewerState {
68
129
  onDocumentLoad(pageCount: number): void;
69
130
  /** A page was measured, in PDF points (crop and fit-page need it). */
70
131
  onPageSize(page: number, widthPt: number, heightPt: number): void;
132
+ /**
133
+ * Present only when the host can save markup (`saveMarkup`): the viewer turns on PDF.js's
134
+ * annotation editors and hands their session up here (`null` when the document closes).
135
+ * `@ai-matrx/media/viewers/pdf` takes it as `PdfDocumentViewer.onMarkupEngine`.
136
+ */
137
+ onMarkupEngine?(engine: PdfMarkupEngine | null): void;
71
138
  }
72
139
  type PdfRunRequest = {
73
140
  tool: "apply-pages";
@@ -162,6 +229,8 @@ interface PdfWorkspaceHost {
162
229
  renderViewer(state: PdfViewerState): ReactNode;
163
230
  /** One page thumbnail (the left panel). Absent: the panel numbers its pages only. */
164
231
  renderThumbnail?(page: number, widthPx: number): ReactNode;
232
+ /** A small badge drawn in the corner of one page's thumbnail (the app's annotation count, for example). Null or absent: none. */
233
+ renderPageBadge?(page: number): ReactNode;
165
234
  /** Run one tool on the server. Rejects with a sentence on failure. */
166
235
  run(request: PdfRunRequest): Promise<PdfRunResult>;
167
236
  /** Open another page of the app for the same file (Scan, Sign). */
@@ -195,6 +264,24 @@ interface PdfWorkspaceHost {
195
264
  online?: boolean;
196
265
  /** Show a failure to the person (the host's toast). Defaults to an inline banner. */
197
266
  notify?(message: string, tone: "error" | "info"): void;
267
+ /**
268
+ * Save the file's bytes with markup written in (PDF.js `saveDocument`) as a NEW VERSION of the
269
+ * same file. `summary` is "2 highlights, 1 text box". A markup-only change never re-extracts the
270
+ * text (PDF-PLAN rule R1). Absent: no markup tools.
271
+ */
272
+ saveMarkup?(bytes: Uint8Array, summary: string): Promise<PdfRunResult>;
273
+ /** The annotations already in the file (Acrobat's, Preview's, ours), for the markup panel's list. */
274
+ existingAnnotations?(): Promise<Array<{
275
+ page: number;
276
+ subtype: string;
277
+ contents: string;
278
+ author: string;
279
+ }>>;
280
+ /** The platform's one signature pad (`@ai-matrx/records-ui` SignaturePad). Absent: no Signature tool. */
281
+ signaturePad?: ComponentType<{
282
+ value: unknown;
283
+ onChange: (value: string | null) => void;
284
+ }>;
198
285
  }
199
286
 
200
287
  interface PdfWorkspaceProps {
@@ -214,7 +301,7 @@ declare function PdfWorkspace({ host, className }: PdfWorkspaceProps): react.JSX
214
301
  * third state, so no dead button.
215
302
  */
216
303
 
217
- type PdfToolId = "browse" | "organize" | "extract-pages" | "split" | "crop" | "redact" | "compress" | "scan" | "sign" | "extract-data" | "edit" | "forms" | "protect" | "ocr" | "convert" | "compare" | "stamp";
304
+ type PdfToolId = "browse" | "markup" | "organize" | "extract-pages" | "split" | "crop" | "redact" | "compress" | "scan" | "sign" | "extract-data" | "edit" | "forms" | "protect" | "ocr" | "convert" | "compare" | "stamp";
218
305
  interface PdfToolDef {
219
306
  id: PdfToolId;
220
307
  label: string;
@@ -236,15 +323,98 @@ declare const comingSoonIdOf: (id: PdfToolId) => string;
236
323
  /** One row per unbuilt tool, ready for `registerComingSoon` or the host's registry table. */
237
324
  declare const PDF_COMING_SOON: Record<string, ComingSoonEntry>;
238
325
 
326
+ /**
327
+ * The workspace's markup model (PDF-PLAN U10). Pure: the markup tools as data (which are built,
328
+ * which are coming and why), their keys, the palette, and the ONE session history that holds both
329
+ * page decisions and markup steps, so Undo takes back whichever came last.
330
+ *
331
+ * What is built rides PDF.js's own annotation editors (highlight, text box, draw, image; a
332
+ * signature is an image made on the platform's signature pad; a comment is the note on a piece of
333
+ * markup). What PDF.js's writer cannot make yet is a "Coming soon" row with its reason, never a
334
+ * dead button: underline and strike-out, shapes, a free-standing sticky note, links, editing the
335
+ * page's own text.
336
+ */
337
+
338
+ type PdfMarkupToolId = "highlight" | "freetext" | "ink" | "image" | "signature" | "underline" | "shapes" | "note" | "links" | "edit-text";
339
+ interface PdfMarkupToolDef {
340
+ id: PdfMarkupToolId;
341
+ label: string;
342
+ /** Single key, while the markup tool is open. */
343
+ key?: string;
344
+ status: "ready" | "soon";
345
+ /** The PDF.js editor a ready tool turns on. */
346
+ engineTool?: Exclude<PdfMarkupTool, "none">;
347
+ /** Ready only when the host brings this port. */
348
+ needs?: "signaturePad";
349
+ /** Why a coming tool is not built (shown under its name, and in its Coming-soon promise). */
350
+ reason?: string;
351
+ }
352
+ declare const PDF_MARKUP_TOOLS: readonly PdfMarkupToolDef[];
353
+ declare const pdfMarkupTool: (id: string) => PdfMarkupToolDef | undefined;
354
+ /** The palette markup offers (Acrobat's comment colors). Literal colors are data: they are written into the PDF. */
355
+ declare const MARKUP_SWATCHES: ReadonlyArray<{
356
+ value: string;
357
+ label: string;
358
+ }>;
359
+ /** Which look controls a kind of markup has (the floating toolbar and the panel show only these). */
360
+ declare const MARKUP_STYLE_FIELDS: Record<PdfMarkupKind, ReadonlyArray<keyof PdfMarkupStyle>>;
361
+ /** Sizes offered: font sizes for a text box, stroke widths for a drawing (PDF points). */
362
+ declare const MARKUP_SIZES: Record<"freetext" | "ink", readonly number[]>;
363
+ declare const MARKUP_KIND_LABEL: Record<PdfMarkupKind, string>;
364
+ declare const markupComingSoonId: (id: PdfMarkupToolId) => string;
365
+ /** One Coming-soon row per markup tool not built yet (merged into `PDF_COMING_SOON`). */
366
+ declare const PDF_MARKUP_COMING_SOON: Record<string, ComingSoonEntry>;
367
+ type StepOrigin = "page" | "markup";
368
+ interface SessionTimeline {
369
+ past: Array<{
370
+ origin: StepOrigin;
371
+ label: string;
372
+ }>;
373
+ future: Array<{
374
+ origin: StepOrigin;
375
+ label: string;
376
+ }>;
377
+ }
378
+ declare const TIMELINE_LIMIT = 100;
379
+ declare const emptyTimeline: () => SessionTimeline;
380
+ declare function recordStep(t: SessionTimeline, origin: StepOrigin, label: string): SessionTimeline;
381
+ /** The step Undo would take back, or null. */
382
+ declare const nextUndo: (t: SessionTimeline) => {
383
+ origin: StepOrigin;
384
+ label: string;
385
+ } | null;
386
+ declare const nextRedo: (t: SessionTimeline) => {
387
+ origin: StepOrigin;
388
+ label: string;
389
+ } | null;
390
+ declare function stepBack(t: SessionTimeline): SessionTimeline;
391
+ declare function stepForward(t: SessionTimeline): SessionTimeline;
392
+ /** PDF.js undid a markup step on its own (its keys, focus outside the workspace): move the newest markup step back. */
393
+ declare function markupUndoneElsewhere(t: SessionTimeline): SessionTimeline;
394
+ declare function markupRedoneElsewhere(t: SessionTimeline): SessionTimeline;
395
+ /** Saving (or discarding) one kind of change ends its steps: the file's versions are the durable undo. */
396
+ declare function dropOrigin(t: SessionTimeline, origin: StepOrigin): SessionTimeline;
397
+
239
398
  type PdfActionId = "undo" | "redo" | "find" | "print" | "save" | "zoom-in" | "zoom-out" | "zoom-fit-width" | "zoom-fit-page" | "page-next" | "page-prev" | "page-first" | "page-last" | "rotate-right" | "rotate-left" | "delete-pages" | "select-all-pages" | "toggle-pages" | "toggle-properties" | "read-mode" | "two-up" | "shortcuts" | `tool:${string}`;
240
399
  interface PdfShortcut {
241
400
  action: PdfActionId;
242
401
  label: string;
243
402
  /** Display keys: "Mod+Z" shows as Cmd+Z on a Mac and Ctrl+Z elsewhere. */
244
403
  keys: string;
245
- section: "Edit" | "View" | "Pages" | "Tools";
404
+ section: "Edit" | "View" | "Pages" | "Tools" | "Markup";
246
405
  }
247
406
  declare const PDF_SHORTCUTS: readonly PdfShortcut[];
407
+ /**
408
+ * Keys that work only while "Comment and mark up" is open (they pick a markup tool). Listed in the
409
+ * shortcut map under Markup; Delete, the arrows and Escape act on the selected markup there.
410
+ */
411
+ declare const PDF_MARKUP_SHORTCUTS: ReadonlyArray<{
412
+ tool: PdfMarkupToolId;
413
+ label: string;
414
+ keys: string;
415
+ }>;
416
+ /** The markup tool a plain key picks while markup is open, or null. */
417
+ declare function matchMarkupKey(e: KeyLike, typing: boolean): PdfMarkupToolId | null;
248
418
  interface KeyLike {
249
419
  key: string;
250
420
  ctrlKey: boolean;
@@ -288,4 +458,4 @@ declare const canRedo: (h: History<unknown>) => boolean;
288
458
  declare const undoLabel: (h: History<unknown>) => string;
289
459
  declare const redoLabel: (h: History<unknown>) => string;
290
460
 
291
- export { HISTORY_LIMIT, type History, type KeyLike, PDF_COMING_SOON, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfHostTool, type PdfHostToolContext, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, formatKeys, freshDecisions, isDirty, keptOrder, matchShortcut, pdfTool, pushStep, redo, redoLabel, reorderPages, restorePages, startHistory, turnPages, undo, undoLabel };
461
+ export { HISTORY_LIMIT, type History, type KeyLike, MARKUP_KIND_LABEL, MARKUP_SIZES, MARKUP_STYLE_FIELDS, MARKUP_SWATCHES, PDF_COMING_SOON, PDF_MARKUP_COMING_SOON, PDF_MARKUP_SHORTCUTS, PDF_MARKUP_TOOLS, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfHostTool, type PdfHostToolContext, type PdfMarkupEngine, type PdfMarkupHistoryEvent, type PdfMarkupKind, type PdfMarkupSnapshot, type PdfMarkupStyle, type PdfMarkupTool, type PdfMarkupToolDef, type PdfMarkupToolId, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type SessionTimeline, type StepOrigin, TIMELINE_LIMIT, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, dropOrigin, emptyTimeline, formatKeys, freshDecisions, isDirty, keptOrder, markupComingSoonId, markupRedoneElsewhere, markupUndoneElsewhere, matchMarkupKey, matchShortcut, nextRedo, nextUndo, pdfMarkupTool, pdfTool, pushStep, recordStep, redo, redoLabel, reorderPages, restorePages, startHistory, stepBack, stepForward, turnPages, undo, undoLabel };