@inkbar/core 0.2.0 → 0.4.0

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/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { $ as NoteAnnotation, A as summarise, At as multiplyMatrix, B as AnnotationInput, Bt as unionRects, C as createAnnotationStore, Ct as Matrix, D as importEmbeddedPage, Dt as applyMatrix, E as SUPPORTED_SUBTYPES, Et as Rect, F as ANNOTATION_FORMAT, Ft as rectFromPoints, G as ForeignAnnotation, H as AnnotationSchema, I as ANNOTATION_VERSION, It as rectFromQuad, J as InkAnnotation, K as FreeTextAnnotation, L as Annotation, Lt as rectsIntersect, M as cssVariableDefaults, Mt as quadFromRect, N as normalizeColor, Nt as quadsFromFlat, O as importedId, Ot as approxEqual, P as staticDefaults, Pt as rectContainsPoint, Q as LineSchema, R as AnnotationDocument, Rt as translateQuad, S as StoreOptions, St as PdfAssets, T as EmbeddedSummary, Tt as Quad, U as AnnotationType, V as AnnotationOfType, W as ConfidenceBucket, X as LineAnnotation, Y as InkSchema, Z as LineEndingSchema, _ as History, _t as derived, a as OpenOptions, at as RectSchema, b as AnnotationStore, bt as PageInfo, c as TextItem, ct as ShapeAnnotation, d as InkErrorCode, dt as SuggestionSchema, et as NoteSchema, f as isInkError, ft as TextMarkupAnnotation, g as importAnnotations, gt as Writable, h as exportAnnotations, ht as Readable, i as InkStatus, it as QuadSchema, j as AnnotationDefaults, jt as pointsFromFlat, k as pdfColorToHex, kt as invertMatrix, l as DocumentSource, lt as ShapeSchema, m as ImportResult, mt as confidenceBucket, n as DocumentStatus, nt as PolyAnnotation, o as openDocument, ot as RedactAnnotation, p as ImportOptions, pt as TextMarkupSchema, q as FreeTextSchema, r as InkDocument, rt as PolySchema, s as TextContent, st as RedactSchema, t as DocumentInfo, tt as PointSchema, u as InkError, ut as Suggestion, v as createHistory, vt as readonly, w as deriveRect, wt as Point, x as StoreMode, xt as PageRotation, y as AnnotationChange, yt as writable, z as AnnotationDocumentSchema, zt as translateRect } from "./document-Cywnv8Sz.mjs";
1
+ import { $ as AnnotationDefaults, $t as TextMarkupSchema, A as TextItem, At as LoupeSchema, B as createHistory, Bt as PolylineSchema, C as DocumentInfo, Cn as rectsIntersect, Ct as InkAnnotation, D as OpenOptions, Dt as LineEndingSchema, E as InkStatus, En as unionRects, Et as LineEnding, F as ImportOptions, Ft as NoteSchema, G as createAnnotationStore, Gt as ShapeAnnotation, H as AnnotationStore, Ht as RectSchema, I as ImportResult, It as PointSchema, J as SUPPORTED_SUBTYPES, Jt as StampAnnotation, K as deriveRect, Kt as ShapeSchema, L as exportAnnotations, Lt as PolyAnnotation, M as InkError, Mt as MaskSchema, N as InkErrorCode, Nt as NoteAnnotation, O as openDocument, Ot as LineSchema, P as isInkError, Pt as NoteIconSchema, Q as summarise, Qt as TextMarkupAnnotation, R as importAnnotations, Rt as PolySchema, S as createToolStyle, Sn as rectFromQuad, St as IMAGE_DATA_URL, T as InkDocument, Tn as translateRect, Tt as LineAnnotation, U as StoreMode, Ut as RedactAnnotation, V as AnnotationChange, Vt as QuadSchema, W as StoreOptions, Wt as RedactSchema, X as importedId, Xt as Suggestion, Y as importEmbeddedPage, Yt as StampSchema, Z as pdfColorToHex, Zt as SuggestionSchema, _ as StyleGroup, _n as pointsFromFlat, _t as ForeignAnnotation, a as SignatureStore, an as writable, at as Annotation, b as ToolStyle, bn as rectContainsPoint, bt as FreeTextStyle, c as createInkTemplate, cn as PdfAssets, ct as AnnotationInput, d as createSignatureLibrary, dn as Quad, dt as AnnotationSchema, en as confidenceBucket, et as cssVariableDefaults, f as normaliseInk, fn as Rect, ft as AnnotationType, g as ScopedToolStyle, gn as multiplyMatrix, gt as ExportedAnnotationSchema, h as STYLE_GROUPS, hn as invertMatrix, ht as ExportedAnnotation, i as SignatureOptions, in as readonly, it as ANNOTATION_VERSION, j as DocumentSource, jt as MaskAnnotation, k as TextContent, kt as LoupeAnnotation, l as createLocalSignatureStore, ln as Matrix, lt as AnnotationOfType, m as CurrentStyle, mn as approxEqual, mt as ConfidenceBucket, n as SIGNATURE_INK_WIDTH, nn as Writable, nt as staticDefaults, o as SignatureTemplate, on as PageInfo, ot as AnnotationDocument, p as placeSignature, pn as applyMatrix, pt as CircleSchema, q as EmbeddedSummary, qt as SquareSchema, r as SignatureLibrary, rn as derived, rt as ANNOTATION_FORMAT, s as createImageTemplate, sn as PageRotation, st as AnnotationDocumentSchema, t as DEFAULT_SIGNATURE_WIDTH, tn as Readable, tt as normalizeColor, u as createMemorySignatureStore, un as Point, ut as AnnotationPatch, v as StyleKey, vn as quadFromRect, vt as FreeTextAnnotation, w as DocumentStatus, wn as translateQuad, wt as InkSchema, x as ToolStyleDeps, xn as rectFromPoints, xt as FreeTextStyleSchema, y as StyleProps, yn as quadsFromFlat, yt as FreeTextSchema, z as History, zt as PolygonSchema } from "./signatures-BHYKTwYE.mjs";
2
+ import { z } from "zod";
2
3
  //#region src/model/events.d.ts
3
4
  export type Listener<T> = (payload: T) => void;
4
5
  export declare class Emitter<Events extends Record<string, unknown>> {
@@ -18,6 +19,68 @@ export declare class Emitter<Events extends Record<string, unknown>> {
18
19
  */
19
20
  export declare function mergeLineRects(rects: readonly Rect[], tolerance?: number, gap?: number): Quad[];
20
21
  //#endregion
22
+ //#region src/model/annotations/callout.d.ts
23
+ /**
24
+ * The insets from a free text's `rect` to its text box, in points (PDF `/RD`, XFDF `fringe`,
25
+ * both in this order).
26
+ */
27
+ export declare const FringeSchema: z.ZodObject<{
28
+ left: z.ZodNumber;
29
+ top: z.ZodNumber;
30
+ right: z.ZodNumber;
31
+ bottom: z.ZodNumber;
32
+ }, z.core.$strip>;
33
+ type Fringe = z.infer<typeof FringeSchema>;
34
+ //#endregion
35
+ //#region src/model/annotations/pdf-names.d.ts
36
+ /**
37
+ * A PDF name: a non-empty run of regular characters, so no whitespace and none of the
38
+ * delimiters `( ) < > [ ] { } / %`.
39
+ */
40
+ export declare const PDF_NAME: RegExp;
41
+ /**
42
+ * A set of PDF names Inkbar knows that stays open: any other valid PDF name loads, is kept and
43
+ * is written back unchanged. The output type keeps autocomplete for the known values.
44
+ */
45
+ export declare function pdfNameSet<const K extends readonly [string, ...string[]]>(known: K): z.ZodType<K[number] | (string & {}), K[number] | (string & {})>;
46
+ /** Line ending styles (PDF `/LE`). */
47
+ export declare const LINE_ENDINGS: readonly ["None", "Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "Butt", "ROpenArrow", "RClosedArrow", "Slash"];
48
+ /** Note icons (PDF `/Name` on a text annotation). */
49
+ export declare const NOTE_ICONS: readonly ["Comment", "Note", "Help", "Insert", "Key", "NewParagraph", "Paragraph"];
50
+ /** Annotation intents (PDF `/IT`). */
51
+ export declare const INTENTS: readonly ["FreeText", "FreeTextCallout", "FreeTextTypeWriter", "LineArrow", "LineDimension", "PolygonCloud", "PolygonDimension", "PolyLineDimension"];
52
+ /** True when `v` is one of the values in `list`. */
53
+ export declare function isKnown<K extends readonly string[]>(list: K, v: string): v is K[number];
54
+ //#endregion
55
+ //#region src/model/annotations/style-map.d.ts
56
+ type StyleKey$1 = keyof StyleProps;
57
+ /**
58
+ * The style group an annotation's type belongs to; notes belong to none. With `key`, the group
59
+ * that owns that prop on `a`: a speech bubble's outline and fill are `shape`'s, its text `text`'s.
60
+ */
61
+ export declare function styleGroupOf(a: Pick<Annotation, 'type'> & {
62
+ intent?: string | undefined;
63
+ }, key?: StyleKey$1): StyleGroup | undefined;
64
+ /** Every group that owns some prop on `a`: two for a speech bubble, else at most one. */
65
+ export declare function styleGroupsOf(a: Pick<Annotation, 'type'> & {
66
+ intent?: string | undefined;
67
+ }): StyleGroup[];
68
+ /** The types in `group`, from the same table `styleGroupOf` reads. */
69
+ export declare function typesInGroup(group: StyleGroup): AnnotationType[];
70
+ /** The style group a type belongs to. */
71
+ export declare function styleGroupOfType(type: AnnotationType): StyleGroup | undefined;
72
+ /** The control-level props `type` supports. */
73
+ export declare function supportedProps(type: AnnotationType): ReadonlySet<StyleKey$1>;
74
+ /**
75
+ * The field patch `patch` means on `type`. Props the type lacks are dropped. A `null` fill
76
+ * becomes `interiorColor: undefined` (`color` on free text), which removes the fill when the
77
+ * store applies it; so does `normal` weight or style and no decoration. Free-text text props go
78
+ * into a partial `defaultStyle`, which the store merges into the current one.
79
+ */
80
+ export declare function toFields(type: AnnotationType, patch: StyleProps): AnnotationPatch;
81
+ /** The control-level props an annotation shows, for the props its type supports. */
82
+ export declare function fromAnnotation(a: Annotation): StyleProps;
83
+ //#endregion
21
84
  //#region src/model/annotations/snapshot-history.d.ts
22
85
  interface SnapshotHistoryOptions {
23
86
  /** Proposes a list to the host. The step counts once the host applies it (seen by `observe`). */
@@ -75,25 +138,77 @@ export declare function createSnapshotHistory(opts: SnapshotHistoryOptions): Sna
75
138
  export declare function acceptSuggestion(store: AnnotationStore, id: string): Annotation | undefined;
76
139
  //#endregion
77
140
  //#region src/model/annotations/threads.d.ts
141
+ /** What a thread can hang from: a note, or text markup whose `contents` is its comment. */
142
+ type ThreadRoot = NoteAnnotation | TextMarkupAnnotation;
143
+ export declare function isThreadRoot(a: Annotation): a is ThreadRoot;
144
+ /**
145
+ * True for a reply: an annotation whose `inReplyTo` names a thread root (a note or text markup)
146
+ * in `list`. Replies show in the thread popover only, never on the page.
147
+ */
148
+ export declare function isReply(a: Annotation, list: readonly Annotation[]): boolean;
149
+ /** `list` less its replies (see `isReply`), in the same order. */
150
+ export declare function withoutReplies(list: readonly Annotation[]): Annotation[];
78
151
  /** Direct replies to `id`, in creation order. */
79
152
  export declare function repliesTo(list: readonly Annotation[], id: string): Annotation[];
80
153
  /**
81
- * The top of a note's thread: follows `inReplyTo` up through notes, stopping at a missing
82
- * parent, a parent that is not a note, or a cycle.
154
+ * The top of a thread: follows `inReplyTo` up through notes, stopping at text markup (which
155
+ * roots a thread of its own), a missing parent, a parent that cannot root a thread, or a
156
+ * cycle. Null when `start` is neither a note nor text markup.
83
157
  */
84
- export declare function threadRoot(list: readonly Annotation[], start: NoteAnnotation): NoteAnnotation;
158
+ export declare function threadRoot(list: readonly Annotation[], start: Annotation): ThreadRoot | null;
85
159
  /** The root, then every reply below it, depth first, each level in creation order. */
86
- export declare function threadOf(list: readonly Annotation[], root: NoteAnnotation): Annotation[];
87
- /** An unlocked root note with no text and no replies: nothing a reader would miss. */
88
- export declare function isAbandonedNote(list: readonly Annotation[], id: string): boolean;
160
+ export declare function threadOf(list: readonly Annotation[], root: ThreadRoot): Annotation[];
161
+ /**
162
+ * An unlocked root note with no text and no replies: nothing a reader would miss. Always
163
+ * false for text markup, which is worth keeping without a comment.
164
+ */
165
+ export declare function isAbandonedNote(a: Annotation, list: readonly Annotation[]): boolean;
89
166
  //#endregion
90
167
  //#region src/model/pdf-date.d.ts
91
168
  /** Parses a PDF date string (`D:YYYYMMDDHHmmSSOHH'mm'`) into ISO 8601. Returns `fallback` on anything unparseable. */
92
169
  export declare function parsePdfDate(value: string | null | undefined, fallback: string): string;
93
170
  //#endregion
171
+ //#region src/model/recognise.d.ts
172
+ type Recognised = {
173
+ kind: 'line';
174
+ start: Point;
175
+ end: Point;
176
+ } | {
177
+ kind: 'arrow';
178
+ start: Point;
179
+ end: Point;
180
+ } | {
181
+ kind: 'rectangle';
182
+ rect: Rect;
183
+ } | {
184
+ kind: 'ellipse';
185
+ rect: Rect;
186
+ } |
187
+ /** A triangle or other closed polygon, its vertices where the stroke's corners are. */
188
+ {
189
+ kind: 'polygon';
190
+ vertices: Point[];
191
+ } |
192
+ /** A regular star, outer and inner vertices alternating, the first tip at the top. */
193
+ {
194
+ kind: 'star';
195
+ vertices: Point[];
196
+ };
197
+ /** The score a fit needs before a stroke is tidied into its shape. */
198
+ export declare const RECOGNISE_THRESHOLD = 0.8;
199
+ /**
200
+ * The standard shape a single freehand stroke (user space points, in drawing order) is closest
201
+ * to, and how well it fits, from 0 to 1. Tidy the stroke only when the score reaches
202
+ * `RECOGNISE_THRESHOLD`. Undefined when no shape fits at all.
203
+ */
204
+ export declare function recogniseStroke(points: readonly Point[]): {
205
+ shape: Recognised;
206
+ score: number;
207
+ } | undefined;
208
+ //#endregion
94
209
  //#region src/index.d.ts
95
210
  /** The @inkbar/core version, from its package.json. */
96
211
  export declare const version: string;
97
212
  //#endregion
98
- export { ANNOTATION_FORMAT, ANNOTATION_VERSION, Annotation, AnnotationChange, AnnotationDefaults, AnnotationDocument, AnnotationDocumentSchema, AnnotationInput, AnnotationOfType, AnnotationSchema, AnnotationStore, AnnotationType, ConfidenceBucket, type DocumentInfo, type DocumentSource, type DocumentStatus, EmbeddedSummary, ForeignAnnotation, FreeTextAnnotation, FreeTextSchema, History, type ImportOptions, type ImportResult, InkAnnotation, type InkDocument, InkError, InkErrorCode, InkSchema, type InkStatus, LineAnnotation, LineEndingSchema, LineSchema, Matrix, NoteAnnotation, NoteSchema, type OpenOptions, type PageInfo, type PageRotation, type PdfAssets, Point, PointSchema, PolyAnnotation, PolySchema, Quad, QuadSchema, Readable, Rect, RectSchema, RedactAnnotation, RedactSchema, SUPPORTED_SUBTYPES, ShapeAnnotation, ShapeSchema, type SnapshotHistory, type SnapshotHistoryOptions, StoreMode, StoreOptions, Suggestion, SuggestionSchema, type TextContent, type TextItem, TextMarkupAnnotation, TextMarkupSchema, Writable, applyMatrix, approxEqual, confidenceBucket, createAnnotationStore, createHistory, cssVariableDefaults, deriveRect, derived, exportAnnotations, importAnnotations, importEmbeddedPage, importedId, invertMatrix, isInkError, multiplyMatrix, normalizeColor, openDocument, pdfColorToHex, pointsFromFlat, quadFromRect, quadsFromFlat, readonly, rectContainsPoint, rectFromPoints, rectFromQuad, rectsIntersect, staticDefaults, summarise, translateQuad, translateRect, unionRects, writable };
213
+ export { ANNOTATION_FORMAT, ANNOTATION_VERSION, Annotation, AnnotationChange, AnnotationDefaults, AnnotationDocument, AnnotationDocumentSchema, AnnotationInput, AnnotationOfType, AnnotationPatch, AnnotationSchema, AnnotationStore, AnnotationType, CircleSchema, ConfidenceBucket, type CurrentStyle, DEFAULT_SIGNATURE_WIDTH, type DocumentInfo, type DocumentSource, type DocumentStatus, EmbeddedSummary, ExportedAnnotation, ExportedAnnotationSchema, ForeignAnnotation, FreeTextAnnotation, FreeTextSchema, FreeTextStyle, FreeTextStyleSchema, type Fringe, History, IMAGE_DATA_URL, type ImportOptions, type ImportResult, InkAnnotation, type InkDocument, InkError, InkErrorCode, InkSchema, type InkStatus, LineAnnotation, LineEnding, LineEndingSchema, LineSchema, LoupeAnnotation, LoupeSchema, MaskAnnotation, MaskSchema, Matrix, NoteAnnotation, NoteIconSchema, NoteSchema, type OpenOptions, type PageInfo, type PageRotation, type PdfAssets, Point, PointSchema, PolyAnnotation, PolySchema, PolygonSchema, PolylineSchema, Quad, QuadSchema, Readable, type Recognised, Rect, RectSchema, RedactAnnotation, RedactSchema, SIGNATURE_INK_WIDTH, STYLE_GROUPS, SUPPORTED_SUBTYPES, type ScopedToolStyle, ShapeAnnotation, ShapeSchema, type SignatureLibrary, type SignatureOptions, type SignatureStore, type SignatureTemplate, type SnapshotHistory, type SnapshotHistoryOptions, SquareSchema, StampAnnotation, StampSchema, StoreMode, StoreOptions, type StyleGroup, type StyleKey, type StyleProps, Suggestion, SuggestionSchema, type TextContent, type TextItem, TextMarkupAnnotation, TextMarkupSchema, type ThreadRoot, type ToolStyle, type ToolStyleDeps, Writable, applyMatrix, approxEqual, confidenceBucket, createAnnotationStore, createHistory, createImageTemplate, createInkTemplate, createLocalSignatureStore, createMemorySignatureStore, createSignatureLibrary, createToolStyle, cssVariableDefaults, deriveRect, derived, exportAnnotations, importAnnotations, importEmbeddedPage, importedId, invertMatrix, isInkError, multiplyMatrix, normaliseInk, normalizeColor, openDocument, pdfColorToHex, placeSignature, pointsFromFlat, quadFromRect, quadsFromFlat, readonly, rectContainsPoint, rectFromPoints, rectFromQuad, rectsIntersect, staticDefaults, summarise, translateQuad, translateRect, unionRects, writable };
99
214
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/model/events.ts","../src/model/selection.ts","../src/model/annotations/snapshot-history.ts","../src/model/annotations/suggestions.ts","../src/model/annotations/threads.ts","../src/model/pdf-date.ts","../src/index.ts"],"mappings":";;YAAY,SAAS,MAAM,SAAS;qBAEvB,QAAQ,eAAe;UAC1B;EAER,GAAG,gBAAgB,QAAQ,OAAO,GAAG,IAAI,SAAS,OAAO;EAYzD,KAAK,gBAAgB,QAAQ,OAAO,GAAG,SAAS,OAAO;EAMvD;;;;;;;;;;;wBCKc,eACd,gBAAgB,QAChB,oBACA,eACC;;;UC3Bc;;EAEf,QAAQ,MAAM;;EAEd;;EAEA;;;;;;;;UASe;WACN,SAAS;WACT,SAAS;EAClB;EACA;EACA;;;;;;EAMA,QAAQ,eAAe;;;;;;;;;;;;;;;;EAgBvB,MAAM;;wBAMQ,sBAAsB,MAAM,yBAAyB;;;;;;;;;;wBC3CrD,iBACd,OAAO,iBACP,aACC;;;;wBCVa,UAAU,eAAe,cAAc,aAAa;;;;;wBAUpD,WACd,eAAe,cACf,OAAO,iBACN;;wBAaa,SACd,eAAe,cACf,MAAM,iBACL;;wBAgBa,gBAAgB,eAAe,cAAc;;;;wBC/C7C,aAAa,kCAAkC;;;;qBCGlD"}
1
+ {"version":3,"file":"index.d.mts","names":["StyleKey"],"sources":["../src/model/events.ts","../src/model/selection.ts","../src/model/annotations/callout.ts","../src/model/annotations/pdf-names.ts","../src/model/annotations/style-map.ts","../src/model/annotations/snapshot-history.ts","../src/model/annotations/suggestions.ts","../src/model/annotations/threads.ts","../src/model/pdf-date.ts","../src/model/recognise.ts","../src/index.ts"],"mappings":";;;YAAY,SAAS,MAAM,SAAS;qBAEvB,QAAQ,eAAe;UAC1B;EAER,GAAG,gBAAgB,QAAQ,OAAO,GAAG,IAAI,SAAS,OAAO;EAYzD,KAAK,gBAAgB,QAAQ,OAAO,GAAG,SAAS,OAAO;EAMvD;;;;;;;;;;;wBCKc,eACd,gBAAgB,QAChB,oBACA,eACC;;;;;;;qBClBU,cAAY,EAAA;;;;;GAKvB,EAAA,KAAA;KAEU,SAAS,EAAE,aAAa;;;;;;;qBCfvB,UAAQ;;;;;wBAML,iBAAiB,0CAA0C,OAAO,IAKzE,EAAE,QAAQ,2BAA2B;;qBAIjC;;qBAcA;;qBAWA;;wBAYG,QAAQ,6BAA6B,MAAM,GAAG,YAAY,KAAK;;;KCpD1EA,mBAAiB;;;;;wBAqHN,aACd,GAAG,KAAK;EAAwB;GAChC,MAAMA,aACL;;wBAYa,cACd,GAAG,KAAK;EAAwB;IAC/B;;wBAYa,aAAa,OAAO,aAAa;;wBAKjC,iBAAiB,MAAM,iBAAiB;;wBAKxC,eAAe,MAAM,iBAAiB,YAAYA;;;;;;;wBAuBlD,SAAS,MAAM,gBAAgB,OAAO,aAAa;;wBAmBnD,eAAe,GAAG,aAAa;;;UCvM9B;;EAEf,QAAQ,MAAM;;EAEd;;EAEA;;;;;;;;UASe;WACN,SAAS;WACT,SAAS;EAClB;EACA;EACA;;;;;;EAMA,QAAQ,eAAe;;;;;;;;;;;;;;;;EAgBvB,MAAM;;wBAMQ,sBAAsB,MAAM,yBAAyB;;;;;;;;;;wBC3CrD,iBACd,OAAO,iBACP,aACC;;;;KCRS,aAAa,iBAAiB;wBAE1B,aAAa,GAAG,aAAa,KAAK;;;;;wBAQlC,QAAQ,GAAG,YAAY,eAAe;;wBAOtC,eAAe,eAAe,eAAe;;wBAM7C,UAAU,eAAe,cAAc,aAAa;;;;;;wBAWpD,WACd,eAAe,cACf,OAAO,aACN;;wBAea,SAAS,eAAe,cAAc,MAAM,aAAa;;;;;wBAmBzD,gBAAgB,GAAG,YAAY,eAAe;;;;wBC3E9C,aAAa,kCAAkC;;;KCsBnD;EACN;EAAc,OAAO;EAAO,KAAK;;EACjC;EAAe,OAAO;EAAO,KAAK;;EAClC;EAAmB,MAAM;;EACzB;EAAiB,MAAM;;;;EAEvB;EAAiB,UAAU;;;;EAE3B;EAAc,UAAU;;;qBAGjB;;;;;;wBA6dG,gBACd,iBAAiB;EACd,OAAO;EAAY;;;;;qBC7fX"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as rectFromQuad, A as RectSchema, B as mergeLineRects, C as InkSchema, D as PointSchema, E as NoteSchema, F as confidenceBucket, G as approxEqual, H as readonly, I as parsePdfDate, J as pointsFromFlat, K as invertMatrix, L as cssVariableDefaults, M as ShapeSchema, N as SuggestionSchema, O as PolySchema, P as TextMarkupSchema, Q as rectFromPoints, R as normalizeColor, S as FreeTextSchema, T as LineSchema, U as writable, V as derived, W as applyMatrix, X as quadsFromFlat, Y as quadFromRect, Z as rectContainsPoint, _ as summarise, a as acceptSuggestion, at as InkError, b as AnnotationDocumentSchema, c as deriveRect, d as createHistory, et as rectsIntersect, f as isProduction, g as pdfColorToHex, h as importedId, i as threadRoot, it as Emitter, j as RedactSchema, k as QuadSchema, l as exportAnnotations, m as importEmbeddedPage, n as repliesTo, nt as translateRect, o as openDocument, ot as isInkError, p as SUPPORTED_SUBTYPES, q as multiplyMatrix, r as threadOf, rt as unionRects, s as createAnnotationStore, t as isAbandonedNote, tt as translateQuad, u as importAnnotations, v as ANNOTATION_FORMAT, w as LineEndingSchema, x as AnnotationSchema, y as ANNOTATION_VERSION, z as staticDefaults } from "./threads-BtvtrAhL.mjs";
1
+ import { $ as exportAnnotations, $t as derived, A as fromAnnotation, At as RedactSchema, C as repliesTo, Ct as NoteSchema, D as acceptSuggestion, Dt as PolylineSchema, E as withoutReplies, Et as PolygonSchema, F as toFields, Ft as TextMarkupSchema, Gt as PDF_NAME, Ht as INTENTS, I as typesInGroup, It as confidenceBucket, Jt as parsePdfDate, Kt as isKnown, Lt as FringeSchema, M as styleGroupOfType, Mt as SquareSchema, N as styleGroupsOf, Nt as StampSchema, O as STYLE_GROUPS, Ot as QuadSchema, P as supportedProps, Pt as SuggestionSchema, Q as deriveRect, Qt as mergeLineRects, S as isThreadRoot, St as NoteIconSchema, T as threadRoot, Tt as PolySchema, Ut as LINE_ENDINGS, Wt as NOTE_ICONS, X as openDocument, Xt as normalizeColor, Yt as cssVariableDefaults, Z as createAnnotationStore, Zt as staticDefaults, _n as InkError, _t as InkSchema, a as createLocalSignatureStore, an as multiplyMatrix, at as importedId, b as isAbandonedNote, bt as LoupeSchema, c as normaliseInk, cn as quadsFromFlat, ct as ANNOTATION_FORMAT, d as recogniseStroke, dn as rectFromQuad, dt as AnnotationSchema, en as readonly, et as importAnnotations, fn as rectsIntersect, ft as CircleSchema, gn as Emitter, gt as IMAGE_DATA_URL, hn as unionRects, ht as FreeTextStyleSchema, i as createInkTemplate, in as invertMatrix, it as importEmbeddedPage, j as styleGroupOf, jt as ShapeSchema, k as createToolStyle, kt as RectSchema, l as placeSignature, ln as rectContainsPoint, lt as ANNOTATION_VERSION, mn as translateRect, mt as FreeTextSchema, n as SIGNATURE_INK_WIDTH, nn as applyMatrix, nt as isProduction, o as createMemorySignatureStore, on as pointsFromFlat, ot as pdfColorToHex, pn as translateQuad, pt as ExportedAnnotationSchema, qt as pdfNameSet, r as createImageTemplate, rn as approxEqual, rt as SUPPORTED_SUBTYPES, s as createSignatureLibrary, sn as quadFromRect, st as summarise, t as DEFAULT_SIGNATURE_WIDTH, tn as writable, tt as createHistory, u as RECOGNISE_THRESHOLD, un as rectFromPoints, ut as AnnotationDocumentSchema, vn as isInkError, vt as LineEndingSchema, w as threadOf, wt as PointSchema, x as isReply, xt as MaskSchema, yt as LineSchema } from "./signatures-DF2VmNVa.mjs";
2
2
  //#region src/model/annotations/snapshot-history.ts
3
3
  function createSnapshotHistory(opts) {
4
4
  const limit = Math.max(1, opts.limit ?? 200);
@@ -129,8 +129,8 @@ function presentKeys(o) {
129
129
  //#endregion
130
130
  //#region src/index.ts
131
131
  /** The @inkbar/core version, from its package.json. */
132
- const version = "0.2.0";
132
+ const version = "0.4.0";
133
133
  //#endregion
134
- export { ANNOTATION_FORMAT, ANNOTATION_VERSION, AnnotationDocumentSchema, AnnotationSchema, Emitter, FreeTextSchema, InkError, InkSchema, LineEndingSchema, LineSchema, NoteSchema, PointSchema, PolySchema, QuadSchema, RectSchema, RedactSchema, SUPPORTED_SUBTYPES, ShapeSchema, SuggestionSchema, TextMarkupSchema, acceptSuggestion, applyMatrix, approxEqual, confidenceBucket, createAnnotationStore, createHistory, createSnapshotHistory, cssVariableDefaults, deriveRect, derived, exportAnnotations, importAnnotations, importEmbeddedPage, importedId, invertMatrix, isAbandonedNote, isInkError, mergeLineRects, multiplyMatrix, normalizeColor, openDocument, parsePdfDate, pdfColorToHex, pointsFromFlat, quadFromRect, quadsFromFlat, readonly, rectContainsPoint, rectFromPoints, rectFromQuad, rectsIntersect, repliesTo, staticDefaults, summarise, threadOf, threadRoot, translateQuad, translateRect, unionRects, version, writable };
134
+ export { ANNOTATION_FORMAT, ANNOTATION_VERSION, AnnotationDocumentSchema, AnnotationSchema, CircleSchema, DEFAULT_SIGNATURE_WIDTH, Emitter, ExportedAnnotationSchema, FreeTextSchema, FreeTextStyleSchema, FringeSchema, IMAGE_DATA_URL, INTENTS, InkError, InkSchema, LINE_ENDINGS, LineEndingSchema, LineSchema, LoupeSchema, MaskSchema, NOTE_ICONS, NoteIconSchema, NoteSchema, PDF_NAME, PointSchema, PolySchema, PolygonSchema, PolylineSchema, QuadSchema, RECOGNISE_THRESHOLD, RectSchema, RedactSchema, SIGNATURE_INK_WIDTH, STYLE_GROUPS, SUPPORTED_SUBTYPES, ShapeSchema, SquareSchema, StampSchema, SuggestionSchema, TextMarkupSchema, acceptSuggestion, applyMatrix, approxEqual, confidenceBucket, createAnnotationStore, createHistory, createImageTemplate, createInkTemplate, createLocalSignatureStore, createMemorySignatureStore, createSignatureLibrary, createSnapshotHistory, createToolStyle, cssVariableDefaults, deriveRect, derived, exportAnnotations, fromAnnotation, importAnnotations, importEmbeddedPage, importedId, invertMatrix, isAbandonedNote, isInkError, isKnown, isReply, isThreadRoot, mergeLineRects, multiplyMatrix, normaliseInk, normalizeColor, openDocument, parsePdfDate, pdfColorToHex, pdfNameSet, placeSignature, pointsFromFlat, quadFromRect, quadsFromFlat, readonly, recogniseStroke, rectContainsPoint, rectFromPoints, rectFromQuad, rectsIntersect, repliesTo, staticDefaults, styleGroupOf, styleGroupOfType, styleGroupsOf, summarise, supportedProps, threadOf, threadRoot, toFields, translateQuad, translateRect, typesInGroup, unionRects, version, withoutReplies, writable };
135
135
 
136
136
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/model/annotations/snapshot-history.ts","../src/index.ts"],"sourcesContent":["import { isProduction } from '../env'\nimport { derived, writable, type Readable } from '../readable'\n\nimport type { Annotation } from './types'\n\nexport interface SnapshotHistoryOptions {\n /** Proposes a list to the host. The step counts once the host applies it (seen by `observe`). */\n apply: (list: Annotation[]) => void\n /** Read on every observed change and every undo or redo. */\n enabled: () => boolean\n /** Steps kept. Default 200. */\n limit?: number | undefined\n}\n\n/**\n * Snapshot undo and redo over a host-owned annotation list, for controlled hosts. The\n * framework calls `observe` whenever the host's list changes; every change is a step. Undo and\n * redo propose an earlier list through `apply` and move the stacks only once the host applies\n * it. `canUndo` and `canRedo` report stack sizes; the framework ANDs them with its own flag.\n */\nexport interface SnapshotHistory {\n readonly canUndo: Readable<boolean>\n readonly canRedo: Readable<boolean>\n undo(): void\n redo(): void\n clear(): void\n /**\n * The host's current list, or `undefined` when the host does not control it. The first list\n * seeds the history; each later list that differs is a step. An `undefined` neither seeds\n * nor records, and the next list after one starts again without a step.\n */\n observe(list: readonly Annotation[] | undefined): void\n /**\n * Runs `fn` and records the host's changes that follow as one step. A framework may hand the\n * host's list back after `fn` returns, one list per proposal, so the batch stays open until\n * the current macrotask ends (`setTimeout(0)`) and then pushes a single step from the list\n * before `fn` to the latest one. Limit: an unrelated change the host makes in that same window\n * is folded into the step. Nested calls join; a throwing `fn` still closes the batch; when\n * history is disabled `fn` only runs. `fn` must be synchronous; a dev build warns when it\n * returns a promise.\n *\n * A batch opened while an earlier one is still settling closes the earlier one first, so the\n * two are two steps. An undo or redo still in flight (proposed, but not yet applied by the\n * host) when a batch opens is dropped: the host's list that follows counts toward the batch.\n * Undo and redo close a settling batch first. Calling `undo()` or `redo()` inside `fn` is not\n * supported.\n */\n batch(fn: () => void): void\n}\n\ntype Snapshot = readonly Annotation[]\ntype Pending = { kind: 'undo' | 'redo'; target: Snapshot }\n\nexport function createSnapshotHistory(opts: SnapshotHistoryOptions): SnapshotHistory {\n const limit = Math.max(1, opts.limit ?? 200)\n const past = writable<Snapshot[]>([])\n const future = writable<Snapshot[]>([])\n let pending: Pending | null = null\n /** Copy of the host's list as of its last change; `undefined` before the first list. */\n let current: Snapshot | undefined\n /** Open `batch` calls, and whether the batch is waiting out the task for late observes. */\n let depth = 0\n let settling: ReturnType<typeof setTimeout> | null = null\n /** The host's list when the outermost batch opened. */\n let from: Snapshot | undefined\n\n function endBatch(): void {\n if (settling !== null) clearTimeout(settling)\n settling = null\n const start = from\n from = undefined\n if (!opts.enabled() || !start || !current || sameList(current, start)) return\n past.set([...past.get(), start].slice(-limit))\n future.set([])\n }\n\n function batch(fn: () => void): void {\n if (!opts.enabled()) {\n fn()\n return\n }\n if (depth === 0) {\n // A batch still settling is closed first, so two batches are two steps.\n if (settling !== null) endBatch()\n // An undo or redo still in flight would be folded into this step; drop it.\n pending = null\n from = current\n }\n depth++\n try {\n const result: unknown = fn()\n if (\n result !== null &&\n typeof result === 'object' &&\n typeof (result as { then?: unknown }).then === 'function' &&\n !isProduction()\n ) {\n console.warn(\n '[inkbar] history.batch(fn): fn returned a promise. Changes after its first await are not part of the batch.'\n )\n }\n } finally {\n depth--\n if (depth === 0) settling = setTimeout(endBatch, 0)\n }\n }\n\n function clear(): void {\n past.set([])\n future.set([])\n pending = null\n from = undefined\n if (settling !== null) clearTimeout(settling)\n settling = null\n }\n\n function observe(next: readonly Annotation[] | undefined): void {\n const prev = current\n current = snapshot(next)\n if (!opts.enabled()) {\n // Steps taken while disabled are unknown to the stacks, which would undo to stale lists.\n if (past.get().length > 0 || future.get().length > 0 || pending) clear()\n return\n }\n // The first list only seeds; there is no step from or to an undefined list.\n if (next === undefined || prev === undefined) return\n // Inside a batch, or while it settles, changes only move `current`; `endBatch` pushes the step.\n if (from !== undefined) return\n // A new array with the same content is not a step, and leaves a pending step alone.\n if (sameList(next, prev)) return\n const step = pending\n pending = null\n if (step && sameList(next, step.target)) {\n if (step.kind === 'undo') {\n past.set(past.get().slice(0, -1))\n future.set([...future.get(), prev])\n } else {\n future.set(future.get().slice(0, -1))\n past.set([...past.get(), prev])\n }\n return\n }\n past.set([...past.get(), prev].slice(-limit))\n future.set([])\n }\n\n function propose(kind: Pending['kind'], target: Snapshot | undefined): void {\n if (!opts.enabled() || !target) return\n pending = { kind, target }\n opts.apply(clone(target) as Annotation[])\n }\n\n return {\n canUndo: derived(past, (p) => p.length > 0),\n canRedo: derived(future, (f) => f.length > 0),\n undo: () => {\n if (from !== undefined && depth === 0) endBatch()\n propose('undo', past.get().at(-1))\n },\n redo: () => {\n if (from !== undefined && depth === 0) endBatch()\n propose('redo', future.get().at(-1))\n },\n clear,\n observe,\n batch,\n }\n}\n\nfunction snapshot(list: readonly Annotation[] | undefined): Snapshot | undefined {\n return list === undefined ? undefined : clone(list)\n}\n\n/** Annotations are JSON values; this also strips framework proxies and `undefined` members. */\nfunction clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T\n}\n\n/** Same annotations in the same order, compared by payload; `modifiedAt` may be re-stamped. */\nfunction sameList(a: readonly Annotation[], b: readonly Annotation[]): boolean {\n return a.length === b.length && a.every((x, i) => sameIgnoringModifiedAt(x, b[i]!))\n}\n\nfunction sameIgnoringModifiedAt(a: Annotation, b: Annotation): boolean {\n const { modifiedAt: _a, ...restA } = a\n const { modifiedAt: _b, ...restB } = b\n return deepEqual(restA, restB)\n}\n\n/** Structural equality over JSON values; keys whose value is `undefined` count as absent. */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)\n return false\n if (Array.isArray(a) !== Array.isArray(b)) return false\n const ka = presentKeys(a)\n const kb = presentKeys(b)\n if (ka.length !== kb.length) return false\n return ka.every(\n (k) =>\n kb.includes(k) &&\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])\n )\n}\n\nfunction presentKeys(o: object): string[] {\n return Object.keys(o).filter((k) => (o as Record<string, unknown>)[k] !== undefined)\n}\n","/** Replaced at build time (tsdown) and in tests (vitest) with package.json's version. */\ndeclare const __INKBAR_VERSION__: string\n\n/** The @inkbar/core version, from its package.json. */\nexport const version: string = __INKBAR_VERSION__\n\nexport * from './model/errors'\nexport * from './model/events'\nexport * from './model/geometry'\nexport * from './model/readable'\nexport { mergeLineRects } from './model/selection'\n\nexport { openDocument } from './model/document'\nexport type {\n DocumentInfo,\n DocumentStatus,\n InkDocument,\n InkStatus,\n OpenOptions,\n} from './model/document'\nexport type { DocumentSource } from './model/source'\nexport type { PageInfo, PageRotation } from './model/pages'\nexport type { TextContent, TextItem } from './model/text'\nexport type { PdfAssets } from './pdfjs/types'\nexport * from './model/annotations/types'\nexport * from './model/annotations/defaults'\nexport * from './model/annotations/store'\nexport * from './model/annotations/history'\nexport { createSnapshotHistory } from './model/annotations/snapshot-history'\nexport type {\n SnapshotHistory,\n SnapshotHistoryOptions,\n} from './model/annotations/snapshot-history'\nexport { acceptSuggestion } from './model/annotations/suggestions'\nexport {\n isAbandonedNote,\n repliesTo,\n threadOf,\n threadRoot,\n} from './model/annotations/threads'\nexport * from './model/annotations/embedded'\nexport { parsePdfDate } from './model/pdf-date'\nexport { exportAnnotations, importAnnotations } from './model/annotations/json'\nexport type { ImportOptions, ImportResult } from './model/annotations/json'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/model/annotations/snapshot-history.ts","../src/index.ts"],"sourcesContent":["import { isProduction } from '../env'\nimport { derived, writable, type Readable } from '../readable'\n\nimport type { Annotation } from './types'\n\nexport interface SnapshotHistoryOptions {\n /** Proposes a list to the host. The step counts once the host applies it (seen by `observe`). */\n apply: (list: Annotation[]) => void\n /** Read on every observed change and every undo or redo. */\n enabled: () => boolean\n /** Steps kept. Default 200. */\n limit?: number | undefined\n}\n\n/**\n * Snapshot undo and redo over a host-owned annotation list, for controlled hosts. The\n * framework calls `observe` whenever the host's list changes; every change is a step. Undo and\n * redo propose an earlier list through `apply` and move the stacks only once the host applies\n * it. `canUndo` and `canRedo` report stack sizes; the framework ANDs them with its own flag.\n */\nexport interface SnapshotHistory {\n readonly canUndo: Readable<boolean>\n readonly canRedo: Readable<boolean>\n undo(): void\n redo(): void\n clear(): void\n /**\n * The host's current list, or `undefined` when the host does not control it. The first list\n * seeds the history; each later list that differs is a step. An `undefined` neither seeds\n * nor records, and the next list after one starts again without a step.\n */\n observe(list: readonly Annotation[] | undefined): void\n /**\n * Runs `fn` and records the host's changes that follow as one step. A framework may hand the\n * host's list back after `fn` returns, one list per proposal, so the batch stays open until\n * the current macrotask ends (`setTimeout(0)`) and then pushes a single step from the list\n * before `fn` to the latest one. Limit: an unrelated change the host makes in that same window\n * is folded into the step. Nested calls join; a throwing `fn` still closes the batch; when\n * history is disabled `fn` only runs. `fn` must be synchronous; a dev build warns when it\n * returns a promise.\n *\n * A batch opened while an earlier one is still settling closes the earlier one first, so the\n * two are two steps. An undo or redo still in flight (proposed, but not yet applied by the\n * host) when a batch opens is dropped: the host's list that follows counts toward the batch.\n * Undo and redo close a settling batch first. Calling `undo()` or `redo()` inside `fn` is not\n * supported.\n */\n batch(fn: () => void): void\n}\n\ntype Snapshot = readonly Annotation[]\ntype Pending = { kind: 'undo' | 'redo'; target: Snapshot }\n\nexport function createSnapshotHistory(opts: SnapshotHistoryOptions): SnapshotHistory {\n const limit = Math.max(1, opts.limit ?? 200)\n const past = writable<Snapshot[]>([])\n const future = writable<Snapshot[]>([])\n let pending: Pending | null = null\n /** Copy of the host's list as of its last change; `undefined` before the first list. */\n let current: Snapshot | undefined\n /** Open `batch` calls, and whether the batch is waiting out the task for late observes. */\n let depth = 0\n let settling: ReturnType<typeof setTimeout> | null = null\n /** The host's list when the outermost batch opened. */\n let from: Snapshot | undefined\n\n function endBatch(): void {\n if (settling !== null) clearTimeout(settling)\n settling = null\n const start = from\n from = undefined\n if (!opts.enabled() || !start || !current || sameList(current, start)) return\n past.set([...past.get(), start].slice(-limit))\n future.set([])\n }\n\n function batch(fn: () => void): void {\n if (!opts.enabled()) {\n fn()\n return\n }\n if (depth === 0) {\n // A batch still settling is closed first, so two batches are two steps.\n if (settling !== null) endBatch()\n // An undo or redo still in flight would be folded into this step; drop it.\n pending = null\n from = current\n }\n depth++\n try {\n const result: unknown = fn()\n if (\n result !== null &&\n typeof result === 'object' &&\n typeof (result as { then?: unknown }).then === 'function' &&\n !isProduction()\n ) {\n console.warn(\n '[inkbar] history.batch(fn): fn returned a promise. Changes after its first await are not part of the batch.'\n )\n }\n } finally {\n depth--\n if (depth === 0) settling = setTimeout(endBatch, 0)\n }\n }\n\n function clear(): void {\n past.set([])\n future.set([])\n pending = null\n from = undefined\n if (settling !== null) clearTimeout(settling)\n settling = null\n }\n\n function observe(next: readonly Annotation[] | undefined): void {\n const prev = current\n current = snapshot(next)\n if (!opts.enabled()) {\n // Steps taken while disabled are unknown to the stacks, which would undo to stale lists.\n if (past.get().length > 0 || future.get().length > 0 || pending) clear()\n return\n }\n // The first list only seeds; there is no step from or to an undefined list.\n if (next === undefined || prev === undefined) return\n // Inside a batch, or while it settles, changes only move `current`; `endBatch` pushes the step.\n if (from !== undefined) return\n // A new array with the same content is not a step, and leaves a pending step alone.\n if (sameList(next, prev)) return\n const step = pending\n pending = null\n if (step && sameList(next, step.target)) {\n if (step.kind === 'undo') {\n past.set(past.get().slice(0, -1))\n future.set([...future.get(), prev])\n } else {\n future.set(future.get().slice(0, -1))\n past.set([...past.get(), prev])\n }\n return\n }\n past.set([...past.get(), prev].slice(-limit))\n future.set([])\n }\n\n function propose(kind: Pending['kind'], target: Snapshot | undefined): void {\n if (!opts.enabled() || !target) return\n pending = { kind, target }\n opts.apply(clone(target) as Annotation[])\n }\n\n return {\n canUndo: derived(past, (p) => p.length > 0),\n canRedo: derived(future, (f) => f.length > 0),\n undo: () => {\n if (from !== undefined && depth === 0) endBatch()\n propose('undo', past.get().at(-1))\n },\n redo: () => {\n if (from !== undefined && depth === 0) endBatch()\n propose('redo', future.get().at(-1))\n },\n clear,\n observe,\n batch,\n }\n}\n\nfunction snapshot(list: readonly Annotation[] | undefined): Snapshot | undefined {\n return list === undefined ? undefined : clone(list)\n}\n\n/** Annotations are JSON values; this also strips framework proxies and `undefined` members. */\nfunction clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T\n}\n\n/** Same annotations in the same order, compared by payload; `modifiedAt` may be re-stamped. */\nfunction sameList(a: readonly Annotation[], b: readonly Annotation[]): boolean {\n return a.length === b.length && a.every((x, i) => sameIgnoringModifiedAt(x, b[i]!))\n}\n\nfunction sameIgnoringModifiedAt(a: Annotation, b: Annotation): boolean {\n const { modifiedAt: _a, ...restA } = a\n const { modifiedAt: _b, ...restB } = b\n return deepEqual(restA, restB)\n}\n\n/** Structural equality over JSON values; keys whose value is `undefined` count as absent. */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)\n return false\n if (Array.isArray(a) !== Array.isArray(b)) return false\n const ka = presentKeys(a)\n const kb = presentKeys(b)\n if (ka.length !== kb.length) return false\n return ka.every(\n (k) =>\n kb.includes(k) &&\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])\n )\n}\n\nfunction presentKeys(o: object): string[] {\n return Object.keys(o).filter((k) => (o as Record<string, unknown>)[k] !== undefined)\n}\n","/** Replaced at build time (tsdown) and in tests (vitest) with package.json's version. */\ndeclare const __INKBAR_VERSION__: string\n\n/** The @inkbar/core version, from its package.json. */\nexport const version: string = __INKBAR_VERSION__\n\nexport * from './model/errors'\nexport * from './model/events'\nexport * from './model/geometry'\nexport * from './model/readable'\nexport { mergeLineRects } from './model/selection'\n\nexport { openDocument } from './model/document'\nexport type {\n DocumentInfo,\n DocumentStatus,\n InkDocument,\n InkStatus,\n OpenOptions,\n} from './model/document'\nexport type { DocumentSource } from './model/source'\nexport type { PageInfo, PageRotation } from './model/pages'\nexport type { TextContent, TextItem } from './model/text'\nexport type { PdfAssets } from './pdfjs/types'\nexport * from './model/annotations/types'\nexport { FringeSchema, type Fringe } from './model/annotations/callout'\nexport * from './model/annotations/pdf-names'\nexport * from './model/annotations/defaults'\nexport * from './model/annotations/store'\nexport * from './model/annotations/history'\nexport { createToolStyle, STYLE_GROUPS } from './model/annotations/tool-style'\nexport type {\n CurrentStyle,\n ScopedToolStyle,\n StyleGroup,\n StyleKey,\n StyleProps,\n ToolStyle,\n ToolStyleDeps,\n} from './model/annotations/tool-style'\nexport {\n fromAnnotation,\n styleGroupOf,\n styleGroupOfType,\n styleGroupsOf,\n supportedProps,\n toFields,\n typesInGroup,\n} from './model/annotations/style-map'\nexport { createSnapshotHistory } from './model/annotations/snapshot-history'\nexport type {\n SnapshotHistory,\n SnapshotHistoryOptions,\n} from './model/annotations/snapshot-history'\nexport { acceptSuggestion } from './model/annotations/suggestions'\nexport {\n isAbandonedNote,\n isReply,\n isThreadRoot,\n repliesTo,\n threadOf,\n threadRoot,\n withoutReplies,\n} from './model/annotations/threads'\nexport type { ThreadRoot } from './model/annotations/threads'\nexport * from './model/annotations/embedded'\nexport { parsePdfDate } from './model/pdf-date'\nexport { exportAnnotations, importAnnotations } from './model/annotations/json'\nexport { recogniseStroke, RECOGNISE_THRESHOLD } from './model/recognise'\nexport type { Recognised } from './model/recognise'\nexport type { ImportOptions, ImportResult } from './model/annotations/json'\nexport {\n createImageTemplate,\n createInkTemplate,\n createLocalSignatureStore,\n createMemorySignatureStore,\n createSignatureLibrary,\n DEFAULT_SIGNATURE_WIDTH,\n normaliseInk,\n placeSignature,\n SIGNATURE_INK_WIDTH,\n} from './model/signatures'\nexport type {\n SignatureLibrary,\n SignatureOptions,\n SignatureStore,\n SignatureTemplate,\n} from './model/signatures'\n"],"mappings":"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"}