@doccloak/core 0.12.1 → 0.13.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/CHANGELOG.md +333 -0
- package/NOTICE +5 -0
- package/README.md +131 -9
- package/dist/dom/errors.d.ts +1 -1
- package/dist/dom/ocr.d.ts +33 -7
- package/dist/dom/ocr.js +98 -4
- package/dist/dom/office.d.ts +20 -6
- package/dist/dom/office.js +44 -11
- package/dist/engine.js +4 -5
- package/dist/env.d.ts +3 -3
- package/dist/pdf/cmap.d.ts +83 -0
- package/dist/pdf/cmap.js +659 -0
- package/dist/pdf/encodings.d.ts +49 -0
- package/dist/pdf/encodings.js +181 -0
- package/dist/pdf/extract.d.ts +106 -0
- package/dist/pdf/extract.js +1064 -0
- package/dist/pdf/fallback-fonts.d.ts +146 -0
- package/dist/pdf/fallback-fonts.js +312 -0
- package/dist/pdf/fit.d.ts +35 -0
- package/dist/pdf/fit.js +60 -0
- package/dist/pdf/fonts.d.ts +82 -0
- package/dist/pdf/fonts.js +465 -0
- package/dist/pdf/glyphlist.d.ts +37 -0
- package/dist/pdf/glyphlist.js +485 -0
- package/dist/pdf/index.d.ts +21 -0
- package/dist/pdf/index.js +7 -0
- package/dist/pdf/lexer.d.ts +61 -0
- package/dist/pdf/lexer.js +554 -0
- package/dist/pdf/objects.d.ts +57 -0
- package/dist/pdf/objects.js +217 -0
- package/dist/pdf/oracle.d.ts +149 -0
- package/dist/pdf/oracle.js +384 -0
- package/dist/pdf/raster.d.ts +45 -0
- package/dist/pdf/raster.js +89 -0
- package/dist/pdf/read.d.ts +36 -0
- package/dist/pdf/read.js +65 -0
- package/dist/pdf/serializer.d.ts +21 -0
- package/dist/pdf/serializer.js +106 -0
- package/dist/pdf/standard-metrics.d.ts +27 -0
- package/dist/pdf/standard-metrics.js +72 -0
- package/dist/pdf/surgery.d.ts +131 -0
- package/dist/pdf/surgery.js +847 -0
- package/dist/pdf/textstate.d.ts +77 -0
- package/dist/pdf/textstate.js +280 -0
- package/dist/pdf/types.d.ts +191 -0
- package/dist/pdf/types.js +11 -0
- package/dist/pdf/verify.d.ts +33 -0
- package/dist/pdf/verify.js +446 -0
- package/dist/pdf/write.d.ts +52 -0
- package/dist/pdf/write.js +644 -0
- package/dist/pipeline.d.ts +15 -0
- package/dist/pipeline.js +123 -8
- package/dist/providers/bardsai.d.ts +1 -1
- package/dist/providers/bardsai.js +5 -1
- package/dist/providers/gliner-base.d.ts +1 -1
- package/dist/providers/gliner-base.js +5 -1
- package/dist/providers/gliner.d.ts +1 -1
- package/dist/providers/gliner.js +5 -1
- package/dist/regex/rules.data.js +13 -8
- package/dist/types.d.ts +17 -2
- package/dist/types.js +17 -0
- package/dist/worker-protocol.d.ts +11 -0
- package/dist/worker-protocol.js +41 -8
- package/fonts/liberation/LICENSE +102 -0
- package/fonts/liberation/LiberationMono-Bold.ttf +0 -0
- package/fonts/liberation/LiberationMono-BoldItalic.ttf +0 -0
- package/fonts/liberation/LiberationMono-Italic.ttf +0 -0
- package/fonts/liberation/LiberationMono-Regular.ttf +0 -0
- package/fonts/liberation/LiberationSans-Bold.ttf +0 -0
- package/fonts/liberation/LiberationSans-BoldItalic.ttf +0 -0
- package/fonts/liberation/LiberationSans-Italic.ttf +0 -0
- package/fonts/liberation/LiberationSans-Regular.ttf +0 -0
- package/fonts/liberation/LiberationSerif-Bold.ttf +0 -0
- package/fonts/liberation/LiberationSerif-BoldItalic.ttf +0 -0
- package/fonts/liberation/LiberationSerif-Italic.ttf +0 -0
- package/fonts/liberation/LiberationSerif-Regular.ttf +0 -0
- package/package.json +11 -2
- package/rules/pl.json +7 -3
- package/rules/universal.json +6 -5
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @doccloak/core/pdf - typed helpers over the pdf-lib object model (T206).
|
|
3
|
+
*
|
|
4
|
+
* pdf-lib (@cantoo/pdf-lib) parses the file into PDFContext objects; these
|
|
5
|
+
* helpers resolve indirect references and coerce values so the rest of the
|
|
6
|
+
* module never touches raw PDFObject subclasses in ad-hoc ways. All getters
|
|
7
|
+
* return undefined for missing or wrong-typed values instead of throwing:
|
|
8
|
+
* callers decide whether a missing value is an "unsafe page" or a default.
|
|
9
|
+
*/
|
|
10
|
+
import { PDFArray, PDFBool, PDFContext, PDFDict, PDFHexString, PDFName, PDFNumber, PDFObject, PDFRawStream, PDFRef, PDFStream, PDFString, decodePDFRawStream, } from '@cantoo/pdf-lib';
|
|
11
|
+
export { PDFName, PDFNumber, PDFString, PDFHexString, PDFRawStream, PDFBool, PDFArray, PDFDict, PDFRef, PDFStream };
|
|
12
|
+
/** Follow indirect references (bounded, refs can be chained). */
|
|
13
|
+
export function resolve(ctx, obj) {
|
|
14
|
+
let cur = obj;
|
|
15
|
+
for (let i = 0; i < 32 && cur instanceof PDFRef; i++)
|
|
16
|
+
cur = ctx.lookup(cur);
|
|
17
|
+
return cur instanceof PDFRef ? undefined : cur;
|
|
18
|
+
}
|
|
19
|
+
export function getDict(ctx, dict, key) {
|
|
20
|
+
if (!dict)
|
|
21
|
+
return undefined;
|
|
22
|
+
const v = resolve(ctx, dict.get(PDFName.of(key)));
|
|
23
|
+
if (v instanceof PDFDict)
|
|
24
|
+
return v;
|
|
25
|
+
if (v instanceof PDFStream)
|
|
26
|
+
return v.dict;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
export function getStream(ctx, dict, key) {
|
|
30
|
+
if (!dict)
|
|
31
|
+
return undefined;
|
|
32
|
+
const v = resolve(ctx, dict.get(PDFName.of(key)));
|
|
33
|
+
return v instanceof PDFStream ? v : undefined;
|
|
34
|
+
}
|
|
35
|
+
export function getArray(ctx, dict, key) {
|
|
36
|
+
if (!dict)
|
|
37
|
+
return undefined;
|
|
38
|
+
const v = resolve(ctx, dict.get(PDFName.of(key)));
|
|
39
|
+
return v instanceof PDFArray ? v : undefined;
|
|
40
|
+
}
|
|
41
|
+
export function getName(ctx, dict, key) {
|
|
42
|
+
if (!dict)
|
|
43
|
+
return undefined;
|
|
44
|
+
const v = resolve(ctx, dict.get(PDFName.of(key)));
|
|
45
|
+
return v instanceof PDFName ? v.decodeText() : undefined;
|
|
46
|
+
}
|
|
47
|
+
export function getNumber(ctx, dict, key) {
|
|
48
|
+
if (!dict)
|
|
49
|
+
return undefined;
|
|
50
|
+
const v = resolve(ctx, dict.get(PDFName.of(key)));
|
|
51
|
+
return v instanceof PDFNumber ? v.asNumber() : undefined;
|
|
52
|
+
}
|
|
53
|
+
export function getBool(ctx, dict, key) {
|
|
54
|
+
if (!dict)
|
|
55
|
+
return undefined;
|
|
56
|
+
const v = resolve(ctx, dict.get(PDFName.of(key)));
|
|
57
|
+
return v instanceof PDFBool ? v.asBoolean() : undefined;
|
|
58
|
+
}
|
|
59
|
+
/** Raw bytes of a string object (literal or hex), without text decoding. */
|
|
60
|
+
export function stringBytes(obj) {
|
|
61
|
+
if (obj instanceof PDFHexString)
|
|
62
|
+
return obj.asBytes();
|
|
63
|
+
if (obj instanceof PDFString)
|
|
64
|
+
return obj.asBytes();
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
/** Decoded text of a string object (PDFDocEncoding / UTF-16 BOM aware). */
|
|
68
|
+
export function stringText(obj) {
|
|
69
|
+
if (obj instanceof PDFHexString || obj instanceof PDFString) {
|
|
70
|
+
try {
|
|
71
|
+
return obj.decodeText();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
export function getString(ctx, dict, key) {
|
|
80
|
+
if (!dict)
|
|
81
|
+
return undefined;
|
|
82
|
+
return stringText(resolve(ctx, dict.get(PDFName.of(key))));
|
|
83
|
+
}
|
|
84
|
+
/** Numbers of an array (non-numbers skipped). */
|
|
85
|
+
export function numbersOf(ctx, arr) {
|
|
86
|
+
if (!arr)
|
|
87
|
+
return [];
|
|
88
|
+
const out = [];
|
|
89
|
+
for (let i = 0; i < arr.size(); i++) {
|
|
90
|
+
const v = resolve(ctx, arr.get(i));
|
|
91
|
+
if (v instanceof PDFNumber)
|
|
92
|
+
out.push(v.asNumber());
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
/** Elements of an array, references resolved. */
|
|
97
|
+
export function itemsOf(ctx, arr) {
|
|
98
|
+
if (!arr)
|
|
99
|
+
return [];
|
|
100
|
+
const out = [];
|
|
101
|
+
for (let i = 0; i < arr.size(); i++) {
|
|
102
|
+
const v = resolve(ctx, arr.get(i));
|
|
103
|
+
if (v)
|
|
104
|
+
out.push(v);
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/** Names of a name-or-array-of-names value (e.g. /Filter). */
|
|
109
|
+
export function namesOf(ctx, obj) {
|
|
110
|
+
const v = resolve(ctx, obj);
|
|
111
|
+
if (v instanceof PDFName)
|
|
112
|
+
return [v.decodeText()];
|
|
113
|
+
if (v instanceof PDFArray) {
|
|
114
|
+
return itemsOf(ctx, v).filter((x) => x instanceof PDFName).map((n) => n.decodeText());
|
|
115
|
+
}
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
/** Filters that decodePDFRawStream understands (image codecs are left encoded). */
|
|
119
|
+
const DECODABLE_FILTERS = new Set(['FlateDecode', 'Fl', 'LZWDecode', 'LZW', 'ASCIIHexDecode', 'AHx', 'ASCII85Decode', 'A85', 'RunLengthDecode', 'RL']);
|
|
120
|
+
export class StreamDecodeError extends Error {
|
|
121
|
+
constructor(message) {
|
|
122
|
+
super(message);
|
|
123
|
+
this.name = 'StreamDecodeError';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Fully decoded bytes of a stream. Throws StreamDecodeError when a filter is
|
|
128
|
+
* not decodable (JPX, DCT, CCITT, JBIG2, Crypt) or the data is corrupt, so
|
|
129
|
+
* the caller can treat the page as unsafe instead of reading garbage.
|
|
130
|
+
*/
|
|
131
|
+
export function decodeStream(ctx, stream) {
|
|
132
|
+
if (stream instanceof PDFRawStream) {
|
|
133
|
+
const filters = namesOf(ctx, stream.dict.get(PDFName.of('Filter')));
|
|
134
|
+
for (const f of filters) {
|
|
135
|
+
if (!DECODABLE_FILTERS.has(f))
|
|
136
|
+
throw new StreamDecodeError(`undecodable filter /${f}`);
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
return decodePDFRawStream(stream).decode();
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
throw new StreamDecodeError(`stream decode failed: ${err.message}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// pdf-lib's own stream classes (created streams): getContents is the decoded form
|
|
146
|
+
// for PDFContentStream; for PDFFlateStream it is the encoded form, so avoid them.
|
|
147
|
+
const maybe = stream;
|
|
148
|
+
if (typeof maybe.getUnencodedContents === 'function')
|
|
149
|
+
return maybe.getUnencodedContents();
|
|
150
|
+
if (typeof maybe.getContents === 'function')
|
|
151
|
+
return maybe.getContents();
|
|
152
|
+
throw new StreamDecodeError('unknown stream class');
|
|
153
|
+
}
|
|
154
|
+
/** True when the filter list contains an image codec (the stream holds pixels, not operators). */
|
|
155
|
+
export function isImageEncoded(ctx, stream) {
|
|
156
|
+
const filters = namesOf(ctx, stream.dict.get(PDFName.of('Filter')));
|
|
157
|
+
return filters.some((f) => !DECODABLE_FILTERS.has(f));
|
|
158
|
+
}
|
|
159
|
+
/** Stable key for an object: 'r<num>g<gen>' for refs, or a synthetic key. */
|
|
160
|
+
export function refKey(ref) {
|
|
161
|
+
return `r${ref.objectNumber}g${ref.generationNumber}`;
|
|
162
|
+
}
|
|
163
|
+
/** Find the ref of an object stored directly in a dict entry (undefined for direct objects). */
|
|
164
|
+
export function refOf(dict, key) {
|
|
165
|
+
const v = dict.get(PDFName.of(key));
|
|
166
|
+
return v instanceof PDFRef ? v : undefined;
|
|
167
|
+
}
|
|
168
|
+
/** Iterate (key, value) pairs of a dict with references resolved. */
|
|
169
|
+
export function entriesOf(ctx, dict) {
|
|
170
|
+
const out = [];
|
|
171
|
+
for (const [k, v] of dict.entries()) {
|
|
172
|
+
const r = resolve(ctx, v);
|
|
173
|
+
if (r)
|
|
174
|
+
out.push([k.decodeText(), r]);
|
|
175
|
+
}
|
|
176
|
+
return out;
|
|
177
|
+
}
|
|
178
|
+
/** The content streams of a page: /Contents may be a stream or an array of streams. */
|
|
179
|
+
export function pageContentStreams(ctx, pageDict) {
|
|
180
|
+
const raw = pageDict.get(PDFName.of('Contents'));
|
|
181
|
+
const resolved = resolve(ctx, raw);
|
|
182
|
+
if (resolved instanceof PDFStream)
|
|
183
|
+
return [{ ref: raw instanceof PDFRef ? raw : undefined, stream: resolved }];
|
|
184
|
+
if (resolved instanceof PDFArray) {
|
|
185
|
+
const out = [];
|
|
186
|
+
for (let i = 0; i < resolved.size(); i++) {
|
|
187
|
+
const item = resolved.get(i);
|
|
188
|
+
const s = resolve(ctx, item);
|
|
189
|
+
if (s instanceof PDFStream)
|
|
190
|
+
out.push({ ref: item instanceof PDFRef ? item : undefined, stream: s });
|
|
191
|
+
}
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
/** Resources dict of a page, walking up the /Parent chain when inherited. */
|
|
197
|
+
export function pageResources(ctx, pageDict) {
|
|
198
|
+
let node = pageDict;
|
|
199
|
+
for (let depth = 0; node && depth < 64; depth++) {
|
|
200
|
+
const res = getDict(ctx, node, 'Resources');
|
|
201
|
+
if (res)
|
|
202
|
+
return res;
|
|
203
|
+
node = getDict(ctx, node, 'Parent');
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
/** Inherited page attribute (MediaBox, CropBox, Rotate). */
|
|
208
|
+
export function inheritedPageValue(ctx, pageDict, key) {
|
|
209
|
+
let node = pageDict;
|
|
210
|
+
for (let depth = 0; node && depth < 64; depth++) {
|
|
211
|
+
const v = resolve(ctx, node.get(PDFName.of(key)));
|
|
212
|
+
if (v)
|
|
213
|
+
return v;
|
|
214
|
+
node = getDict(ctx, node, 'Parent');
|
|
215
|
+
}
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @doccloak/core/pdf - pdf.js oracle (T212).
|
|
3
|
+
*
|
|
4
|
+
* pdf.js is the INDEPENDENT second extractor. It never edits anything; it is
|
|
5
|
+
* used (1) before a page is touched, to confirm that our own decoder read the
|
|
6
|
+
* same text pdf.js reads, (2) after writing, to verify that no redacted value
|
|
7
|
+
* is extractable from the output, and (3) to render pages for the rasterize
|
|
8
|
+
* fallback (see raster.ts).
|
|
9
|
+
*
|
|
10
|
+
* Runtime configuration:
|
|
11
|
+
* - The legacy build (`pdfjs-dist/legacy/build/pdf.mjs`) is imported lazily in
|
|
12
|
+
* every environment: it carries the Node factories (fs-backed asset fetch,
|
|
13
|
+
* `@napi-rs/canvas` canvas factory) as well as the browser ones and is the
|
|
14
|
+
* build the package's typings describe. It is loaded on first use so hosts
|
|
15
|
+
* that never open a PDF never pay for it.
|
|
16
|
+
* - Node: no worker; pdf.js runs its "fake worker" on the calling thread.
|
|
17
|
+
* `cMapUrl` / `standardFontDataUrl` are file-system paths (or file: URLs).
|
|
18
|
+
* - Browsers: the host serves the worker file and passes its URL through
|
|
19
|
+
* `PdfAssetPaths.pdfjsWorkerUrl`; it is applied to
|
|
20
|
+
* `GlobalWorkerOptions.workerSrc` once. Without it pdf.js throws
|
|
21
|
+
* 'No "GlobalWorkerOptions.workerSrc" specified.' in a browser.
|
|
22
|
+
* - Fonts are never taken from the system (`useSystemFonts: false`). pdf.js 6
|
|
23
|
+
* no longer has an eval-based PostScript compiler (`isEvalSupported` is gone).
|
|
24
|
+
* - `disableFontFace` is true wherever there is no `document` (Node, Web
|
|
25
|
+
* Workers): glyphs are then drawn as paths, which also makes rendering
|
|
26
|
+
* deterministic across hosts.
|
|
27
|
+
*/
|
|
28
|
+
import type { PdfAssetPaths } from './types.js';
|
|
29
|
+
/** A 2D context as far as the raster code and pdf.js need it. */
|
|
30
|
+
export type Canvas2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
|
31
|
+
/** A canvas created by a {@link CanvasFactory}: pdf.js draws on `context`, the raster code reads the result back. */
|
|
32
|
+
export interface CanvasHandle {
|
|
33
|
+
/** The canvas object itself (HTMLCanvasElement, OffscreenCanvas, @napi-rs/canvas Canvas, or a test double). pdf.js calls `getContext('2d')` on it. */
|
|
34
|
+
canvas: unknown;
|
|
35
|
+
/** The 2D context of `canvas`. */
|
|
36
|
+
context: Canvas2D;
|
|
37
|
+
/** Encode the current pixels as PNG. */
|
|
38
|
+
toPng(): Promise<Uint8Array>;
|
|
39
|
+
/** RGBA pixels of the whole canvas, row-major, 4 bytes per pixel. */
|
|
40
|
+
getImageData(): Uint8ClampedArray;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates canvases for pdf.js. The default implementation uses OffscreenCanvas
|
|
44
|
+
* (browsers, main thread or worker) and falls back to a DOM canvas; Node
|
|
45
|
+
* hosts and tests inject their own (e.g. one built on `@napi-rs/canvas`).
|
|
46
|
+
* pdf.js also asks the factory for temporary canvases (patterns, transparency
|
|
47
|
+
* groups, smoothed images), so `create` may be called several times per page.
|
|
48
|
+
*/
|
|
49
|
+
export interface CanvasFactory {
|
|
50
|
+
create(width: number, height: number): CanvasHandle;
|
|
51
|
+
}
|
|
52
|
+
/** Result of {@link OracleDocument.render}. */
|
|
53
|
+
export interface RenderedPage {
|
|
54
|
+
/** Canvas pixel size (the viewport size rounded up). */
|
|
55
|
+
widthPx: number;
|
|
56
|
+
heightPx: number;
|
|
57
|
+
/** Page size in points as displayed, i.e. the CropBox with /Rotate applied (swapped for 90/270). */
|
|
58
|
+
widthPt: number;
|
|
59
|
+
heightPt: number;
|
|
60
|
+
/** pdf.js `viewport.transform` [a b c d e f]: maps PDF user space to canvas pixels (includes the y flip, scale and /Rotate). */
|
|
61
|
+
transform: number[];
|
|
62
|
+
/** The canvas pdf.js drew on; still open for further drawing (the raster fallback paints its black boxes here). */
|
|
63
|
+
canvas: CanvasHandle;
|
|
64
|
+
}
|
|
65
|
+
/** One pdf.js text item with its geometry (see pdf.js TextItem). */
|
|
66
|
+
export interface OracleTextItem {
|
|
67
|
+
str: string;
|
|
68
|
+
/** pdf.js bidi direction of the item ('ltr', 'rtl' or 'ttb'); `str` of an 'rtl' item is in visual order. */
|
|
69
|
+
dir?: string;
|
|
70
|
+
/** [a b c d e f]: text-space to user-space; (e, f) is the item origin, hypot(c, d) the font size. */
|
|
71
|
+
transform: number[];
|
|
72
|
+
/** Width and height in user-space units. */
|
|
73
|
+
width: number;
|
|
74
|
+
height: number;
|
|
75
|
+
hasEOL: boolean;
|
|
76
|
+
fontName: string;
|
|
77
|
+
}
|
|
78
|
+
export interface OracleDocument {
|
|
79
|
+
pageCount: number;
|
|
80
|
+
/** Raw pdf.js text items of the page joined in order, with '\n' appended after items flagged `hasEOL`. No normalisation: compare through {@link normalizeForCompare}. */
|
|
81
|
+
pageText(index: number): Promise<string>;
|
|
82
|
+
/** The pdf.js text items of the page with geometry (for raster-only pages). */
|
|
83
|
+
pageItems(index: number): Promise<OracleTextItem[]>;
|
|
84
|
+
/** Unrotated page box in points (pdf.js `view`, i.e. the CropBox clipped to the MediaBox) and the normalised /Rotate (0, 90, 180, 270). */
|
|
85
|
+
pageSize(index: number): Promise<{
|
|
86
|
+
width: number;
|
|
87
|
+
height: number;
|
|
88
|
+
rotate: number;
|
|
89
|
+
}>;
|
|
90
|
+
/** Render the page at `scale` (1 = 72 dpi) with /Rotate applied, annotations excluded. */
|
|
91
|
+
render(index: number, scale: number, canvasFactory?: CanvasFactory): Promise<RenderedPage>;
|
|
92
|
+
close(): Promise<void>;
|
|
93
|
+
}
|
|
94
|
+
/** Deadline for one pdf.js page operation (text, render). */
|
|
95
|
+
export declare const ORACLE_DEADLINE_MS = 60000;
|
|
96
|
+
/**
|
|
97
|
+
* Browser default: OffscreenCanvas when available (works in Web Workers and
|
|
98
|
+
* on the main thread), else an HTMLCanvasElement. Node has neither: inject a
|
|
99
|
+
* factory (tests use a recording double; hosts can wrap `@napi-rs/canvas`).
|
|
100
|
+
*/
|
|
101
|
+
export declare function defaultCanvasFactory(): CanvasFactory;
|
|
102
|
+
/**
|
|
103
|
+
* Open `bytes` with pdf.js. The buffer is copied because pdf.js transfers
|
|
104
|
+
* (and thereby neuters) the ArrayBuffer it is given. Password-protected files
|
|
105
|
+
* without the right password raise UnsupportedDocumentError('encrypted');
|
|
106
|
+
* files pdf.js cannot parse at all raise 'invalid-package'.
|
|
107
|
+
*/
|
|
108
|
+
export declare function openWithOracle(bytes: Uint8Array, assets?: PdfAssetPaths, password?: string): Promise<OracleDocument>;
|
|
109
|
+
/** Text of every page, in page order (see {@link OracleDocument.pageText}). */
|
|
110
|
+
export declare function oracleText(doc: OracleDocument): Promise<string[]>;
|
|
111
|
+
/**
|
|
112
|
+
* Bring two extractors' output onto common ground: NFC, typographic
|
|
113
|
+
* ligatures spelled out, and every whitespace / soft-hyphen / zero-width
|
|
114
|
+
* character removed. Case and punctuation are kept.
|
|
115
|
+
*/
|
|
116
|
+
export declare function normalizeForCompare(text: string): string;
|
|
117
|
+
/**
|
|
118
|
+
* The text of a glyph as a detector should see it: typographic ligatures spelled out
|
|
119
|
+
* (fi -> fi) and CJK compatibility forms unified. Applied when glyphs are decoded, so plainText,
|
|
120
|
+
* the oracle comparison and the layer-zero search all agree.
|
|
121
|
+
*/
|
|
122
|
+
export declare function foldGlyphText(text: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* The same folding as {@link normalizeForCompare} plus a length-preserving
|
|
125
|
+
* lower-casing, with an offset map back into the input, so a search in the
|
|
126
|
+
* folded text can be turned into a replacement range of the original. Used
|
|
127
|
+
* by the writer's layer zero so that it covers exactly what the verifier
|
|
128
|
+
* would flag (a value wrapped over a line end, spaced differently, or
|
|
129
|
+
* written with a typographic ligature).
|
|
130
|
+
*/
|
|
131
|
+
export declare function foldForSearch(text: string): {
|
|
132
|
+
folded: string;
|
|
133
|
+
offsets: number[];
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Every occurrence of `value` in `text` as [start, end) ranges of the original text, found in
|
|
137
|
+
* the search fold (whitespace, hyphens and zero-width characters dropped, ligatures spelled
|
|
138
|
+
* out, case folded). A value that begins or ends with a letter or digit must begin or end at a
|
|
139
|
+
* token boundary of the original text ("Nowak" is not found inside "Nowakowski", but is found
|
|
140
|
+
* in "Nowak," and across a line end); a value like "(c)" needs no boundary.
|
|
141
|
+
*/
|
|
142
|
+
export interface SearchIndex {
|
|
143
|
+
text: string;
|
|
144
|
+
folded: string;
|
|
145
|
+
offsets: number[];
|
|
146
|
+
}
|
|
147
|
+
/** The search fold of a text, reusable across many values (folding a long text once). */
|
|
148
|
+
export declare function searchIndex(text: string): SearchIndex;
|
|
149
|
+
export declare function findOccurrences(source: string | SearchIndex, value: string): Array<[number, number]>;
|