@scanfit/browser 0.1.0-alpha.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/pdf.js ADDED
@@ -0,0 +1,493 @@
1
+ import { S as P, a as B } from "./chunks/types-Bf5l1UNl.js";
2
+ var K = [
3
+ 278,
4
+ 278,
5
+ 355,
6
+ 556,
7
+ 556,
8
+ 889,
9
+ 667,
10
+ 191,
11
+ 333,
12
+ 333,
13
+ 389,
14
+ 584,
15
+ 278,
16
+ 333,
17
+ 278,
18
+ 278,
19
+ 556,
20
+ 556,
21
+ 556,
22
+ 556,
23
+ 556,
24
+ 556,
25
+ 556,
26
+ 556,
27
+ 556,
28
+ 556,
29
+ 278,
30
+ 278,
31
+ 584,
32
+ 584,
33
+ 584,
34
+ 556,
35
+ 1015,
36
+ 667,
37
+ 667,
38
+ 722,
39
+ 722,
40
+ 667,
41
+ 611,
42
+ 778,
43
+ 722,
44
+ 278,
45
+ 500,
46
+ 667,
47
+ 556,
48
+ 833,
49
+ 722,
50
+ 778,
51
+ 667,
52
+ 778,
53
+ 722,
54
+ 667,
55
+ 611,
56
+ 722,
57
+ 667,
58
+ 944,
59
+ 667,
60
+ 667,
61
+ 611,
62
+ 278,
63
+ 278,
64
+ 278,
65
+ 469,
66
+ 556,
67
+ 333,
68
+ 556,
69
+ 556,
70
+ 500,
71
+ 556,
72
+ 556,
73
+ 278,
74
+ 556,
75
+ 556,
76
+ 222,
77
+ 222,
78
+ 500,
79
+ 222,
80
+ 833,
81
+ 556,
82
+ 556,
83
+ 556,
84
+ 556,
85
+ 333,
86
+ 500,
87
+ 278,
88
+ 556,
89
+ 500,
90
+ 722,
91
+ 500,
92
+ 500,
93
+ 500,
94
+ 334,
95
+ 260,
96
+ 334,
97
+ 584
98
+ ], X = /* @__PURE__ */ new Map([
99
+ [8364, 128],
100
+ [8218, 130],
101
+ [402, 131],
102
+ [8222, 132],
103
+ [8230, 133],
104
+ [8224, 134],
105
+ [8225, 135],
106
+ [710, 136],
107
+ [8240, 137],
108
+ [352, 138],
109
+ [8249, 139],
110
+ [338, 140],
111
+ [381, 142],
112
+ [8216, 145],
113
+ [8217, 146],
114
+ [8220, 147],
115
+ [8221, 148],
116
+ [8226, 149],
117
+ [8211, 150],
118
+ [8212, 151],
119
+ [732, 152],
120
+ [8482, 153],
121
+ [353, 154],
122
+ [8250, 155],
123
+ [339, 156],
124
+ [382, 158],
125
+ [376, 159]
126
+ ]);
127
+ class V {
128
+ value;
129
+ constructor(t) {
130
+ this.value = t;
131
+ }
132
+ }
133
+ function W(e, t) {
134
+ N("Text size", t);
135
+ let n = 0;
136
+ for (const i of e) {
137
+ const w = H(i);
138
+ n += w >= 32 && w <= 126 ? K[w - 32] : 556;
139
+ }
140
+ return n * t / 1e3;
141
+ }
142
+ function A(e, ...t) {
143
+ if (t.some((n) => !Number.isFinite(n)))
144
+ throw new TypeError(`${e} values must be finite numbers`);
145
+ }
146
+ function N(e, ...t) {
147
+ if (A(e, ...t), t.some((n) => n <= 0))
148
+ throw new RangeError(`${e} values must be greater than zero`);
149
+ }
150
+ function H(e) {
151
+ const t = e.codePointAt(0), n = t <= 127 || t >= 160 && t <= 255 ? t : X.get(t);
152
+ if (n === void 0)
153
+ throw new TypeError(`Unsupported character U+${t.toString(16).toUpperCase().padStart(4, "0")}; Helvetica text is limited to WinAnsi`);
154
+ return n;
155
+ }
156
+ function U(e) {
157
+ return !e || e === "none" || (e = e.replace(/^#/, ""), e.length === 3 && (e = e[0] + e[0] + e[1] + e[1] + e[2] + e[2]), !/^[0-9a-fA-F]{6}$/.test(e)) ? null : [parseInt(e.slice(0, 2), 16) / 255, parseInt(e.slice(2, 4), 16) / 255, parseInt(e.slice(4, 6), 16) / 255];
158
+ }
159
+ function O(e, t) {
160
+ return e ? `${e[0].toFixed(3)} ${e[1].toFixed(3)} ${e[2].toFixed(3)} ${t}` : "";
161
+ }
162
+ function Y(e) {
163
+ if (e.length < 2 || e[0] !== 255 || e[1] !== 216)
164
+ throw new Error("Invalid JPEG: missing SOI marker");
165
+ let t = 2;
166
+ for (; t < e.length - 1; ) {
167
+ if (e[t] !== 255) {
168
+ t++;
169
+ continue;
170
+ }
171
+ const n = e[t + 1];
172
+ if (n === 218)
173
+ break;
174
+ if (n >= 192 && n <= 207 && ![196, 200, 204].includes(n)) {
175
+ if (t + 9 >= e.length)
176
+ break;
177
+ const h = e[t + 5] << 8 | e[t + 6], F = e[t + 7] << 8 | e[t + 8], m = e[t + 9];
178
+ if (F && h)
179
+ return { width: F, height: h, colorSpace: m === 1 ? "/DeviceGray" : m === 4 ? "/DeviceCMYK" : "/DeviceRGB" };
180
+ }
181
+ if (t + 3 >= e.length)
182
+ break;
183
+ const w = e[t + 2] << 8 | e[t + 3];
184
+ t += 2 + w;
185
+ }
186
+ throw new Error("Invalid JPEG: no valid SOF marker found");
187
+ }
188
+ function v(e) {
189
+ let t = "(";
190
+ for (const n of e) {
191
+ const i = H(n);
192
+ i === 92 || i === 40 || i === 41 ? t += "\\" + String.fromCharCode(i) : i === 13 ? t += "\\r" : i === 10 ? t += "\\n" : i < 32 || i >= 127 ? t += `\\${i.toString(8).padStart(3, "0")}` : t += String.fromCharCode(i);
193
+ }
194
+ return t + ")";
195
+ }
196
+ function M(e) {
197
+ return e == null ? "null" : typeof e == "boolean" ? e ? "true" : "false" : typeof e == "number" ? Number.isInteger(e) ? String(e) : e.toFixed(4).replace(/\.?0+$/, "") : typeof e == "string" ? e : e instanceof V ? v(e.value) : Array.isArray(e) ? "[" + e.map(M).join(" ") + "]" : e instanceof J ? `${e.id} 0 R` : typeof e == "object" ? `<<
198
+ ` + Object.entries(e).filter(([n, i]) => i !== void 0).map(([n, i]) => `/${n} ${M(i)}`).join(`
199
+ `) + `
200
+ >>` : String(e);
201
+ }
202
+ class J {
203
+ id;
204
+ constructor(t) {
205
+ this.id = t;
206
+ }
207
+ }
208
+ function Z() {
209
+ const e = [], t = [];
210
+ let n = 1;
211
+ function i(o, r = null) {
212
+ const c = n++;
213
+ return e.push({ id: c, dict: o, stream: r }), new J(c);
214
+ }
215
+ function w(o, r, c) {
216
+ let a, b, s;
217
+ if (typeof o == "function" ? (a = 612, b = 792, s = o) : (a = o, b = r, s = c), N("Page dimensions", a, b), typeof s != "function")
218
+ throw new TypeError("page() requires a callback");
219
+ const l = [], u = [], x = [];
220
+ let T = 0;
221
+ s({
222
+ text(f, d, g, p, $ = {}) {
223
+ A("Text coordinates", d, g), N("Text size", p);
224
+ const { align: y = "left", width: S, color: _ = "#000000" } = $;
225
+ let L = d;
226
+ if (y !== "left" && S !== void 0) {
227
+ A("Text width", S);
228
+ const G = W(f, p);
229
+ y === "center" && (L = d + (S - G) / 2), y === "right" && (L = d + S - G);
230
+ }
231
+ const q = O(U(_), "rg") || "0.000 0.000 0.000 rg";
232
+ l.push(q, "BT", `/F1 ${p} Tf`, `${L.toFixed(2)} ${g.toFixed(2)} Td`, `${v(f)} Tj`, "ET");
233
+ },
234
+ rect(f, d, g, p, $) {
235
+ A("Rectangle coordinates", f, d), N("Rectangle dimensions", g, p);
236
+ const y = O(U($), "rg");
237
+ y && l.push(y, `${f.toFixed(2)} ${d.toFixed(2)} ${g.toFixed(2)} ${p.toFixed(2)} re`, "f");
238
+ },
239
+ line(f, d, g, p, $, y = 1) {
240
+ A("Line coordinates", f, d, g, p), N("Line width", y);
241
+ const S = O(U($), "RG");
242
+ S && l.push(`${y.toFixed(2)} w`, S, `${f.toFixed(2)} ${d.toFixed(2)} m`, `${g.toFixed(2)} ${p.toFixed(2)} l`, "S");
243
+ },
244
+ image(f, d, g, p, $) {
245
+ A("Image coordinates", d, g), N("Image dimensions", p, $);
246
+ const { width: y, height: S, colorSpace: _ } = Y(f), L = `/Im${T++}`, q = i({
247
+ Type: "/XObject",
248
+ Subtype: "/Image",
249
+ Width: y,
250
+ Height: S,
251
+ ColorSpace: _,
252
+ BitsPerComponent: 8,
253
+ Filter: "/DCTDecode",
254
+ Length: f.length
255
+ }, f);
256
+ u.push({ name: L, ref: q }), l.push("q", `${p.toFixed(2)} 0 0 ${$.toFixed(2)} ${d.toFixed(2)} ${g.toFixed(2)} cm`, `${L} Do`, "Q");
257
+ },
258
+ link(f, d, g, p, $, y = {}) {
259
+ if (A("Link coordinates", d, g), N("Link dimensions", p, $), x.push({ url: f, rect: [d, g, d + p, g + $] }), y.underline) {
260
+ const S = O(U(y.underline), "RG");
261
+ S && l.push("0.75 w", S, `${d.toFixed(2)} ${(g + 2).toFixed(2)} m`, `${(d + p).toFixed(2)} ${(g + 2).toFixed(2)} l`, "S");
262
+ }
263
+ }
264
+ });
265
+ const E = l.join(`
266
+ `), z = new TextEncoder().encode(E), C = i({ Length: z.length }, z), R = {};
267
+ for (const f of u)
268
+ R[f.name.slice(1)] = f.ref;
269
+ const j = x.map((f) => i({
270
+ Type: "/Annot",
271
+ Subtype: "/Link",
272
+ Rect: f.rect,
273
+ Border: [0, 0, 0],
274
+ A: { Type: "/Action", S: "/URI", URI: new V(f.url) }
275
+ }));
276
+ t.push(i({
277
+ Type: "/Page",
278
+ Parent: null,
279
+ MediaBox: [0, 0, a, b],
280
+ Contents: C,
281
+ Resources: { Font: { F1: null }, XObject: Object.keys(R).length > 0 ? R : void 0 },
282
+ Annots: j.length > 0 ? j : void 0
283
+ }));
284
+ }
285
+ let h = !1;
286
+ function F() {
287
+ if (!t.length)
288
+ throw new Error("PDF must have at least one page");
289
+ if (h)
290
+ throw new Error("build() can only be called once");
291
+ h = !0;
292
+ const o = i({ Type: "/Font", Subtype: "/Type1", BaseFont: "/Helvetica", Encoding: "/WinAnsiEncoding" }), r = i({ Type: "/Pages", Kids: t, Count: t.length });
293
+ for (const c of e)
294
+ if (c.dict.Type === "/Page") {
295
+ c.dict.Parent = r;
296
+ const a = c.dict.Resources;
297
+ a?.Font && (a.Font.F1 = o);
298
+ }
299
+ return i({ Type: "/Catalog", Pages: r });
300
+ }
301
+ function* m(o) {
302
+ const r = new TextEncoder(), c = [];
303
+ let a = 0;
304
+ const b = r.encode(`%PDF-1.4
305
+ %ÿÿÿÿ
306
+ `);
307
+ a += b.length, yield b;
308
+ for (const u of e) {
309
+ c[u.id] = a;
310
+ const x = `${u.id} 0 obj
311
+ ${M(u.dict)}
312
+ `;
313
+ if (u.stream) {
314
+ const T = r.encode(x + `stream
315
+ `), D = u.stream, E = r.encode(`
316
+ endstream
317
+ endobj
318
+ `);
319
+ a += T.length, yield T, a += D.length, yield D, a += E.length, u.stream = null, yield E;
320
+ } else {
321
+ const T = r.encode(x + `endobj
322
+ `);
323
+ a += T.length, yield T;
324
+ }
325
+ }
326
+ const s = a;
327
+ let l = `xref
328
+ 0 ${e.length + 1}
329
+ 0000000000 65535 f
330
+ `;
331
+ for (let u = 1; u <= e.length; u++)
332
+ l += String(c[u]).padStart(10, "0") + ` 00000 n
333
+ `;
334
+ l += `trailer
335
+ ${M({ Size: e.length + 1, Root: o })}
336
+ `, l += `startxref
337
+ ${s}
338
+ %%EOF
339
+ `, yield r.encode(l);
340
+ }
341
+ function I() {
342
+ const o = [];
343
+ let r = 0;
344
+ for (const b of m(F()))
345
+ o.push(b), r += b.length;
346
+ const c = new Uint8Array(r);
347
+ let a = 0;
348
+ for (const b of o)
349
+ c.set(b, a), a += b.length;
350
+ return c;
351
+ }
352
+ function k() {
353
+ const o = m(F());
354
+ return new ReadableStream({
355
+ pull(r) {
356
+ const { done: c, value: a } = o.next();
357
+ c ? r.close() : r.enqueue(a);
358
+ }
359
+ });
360
+ }
361
+ return { page: w, build: I, buildStream: k, measureText: W };
362
+ }
363
+ function ee(e) {
364
+ if (!Number.isSafeInteger(e.maxBytes) || e.maxBytes < 1)
365
+ throw new P(
366
+ "INVALID_INPUT",
367
+ "maxBytes must be a positive integer number of bytes."
368
+ );
369
+ const t = e.minQuality ?? 0.65, n = e.minLongEdge ?? 1600;
370
+ if (!Number.isFinite(t) || t < 0.1 || t > 0.9)
371
+ throw new P(
372
+ "INVALID_INPUT",
373
+ "minQuality must be between 0.1 and 0.9."
374
+ );
375
+ if (!Number.isSafeInteger(n) || n < 128 || n > 2400)
376
+ throw new P(
377
+ "INVALID_INPUT",
378
+ "minLongEdge must be an integer between 128 and 2400."
379
+ );
380
+ if (e.pageSize && !["a4", "letter", "image"].includes(e.pageSize))
381
+ throw new P("INVALID_INPUT", "Unknown PDF page size.");
382
+ }
383
+ async function Q(e, t = "a4") {
384
+ if (!e.length)
385
+ throw new P(
386
+ "INVALID_INPUT",
387
+ "Add at least one page before exporting."
388
+ );
389
+ const n = Z();
390
+ for (const i of e) {
391
+ const w = new Uint8Array(await i.jpeg.arrayBuffer());
392
+ if (i.jpeg.type !== "image/jpeg" || w[0] !== 255 || w[1] !== 216)
393
+ throw new P(
394
+ "PROCESSING_FAILED",
395
+ "The browser did not produce a valid JPEG."
396
+ );
397
+ const h = t === "a4" ? [595.28, 841.89] : t === "letter" ? [612, 792] : [i.width * 0.75, i.height * 0.75], F = Math.min(h[0] / i.width, h[1] / i.height), m = i.width * F, I = i.height * F;
398
+ n.page(
399
+ h[0],
400
+ h[1],
401
+ (k) => k.image(w, (h[0] - m) / 2, (h[1] - I) / 2, m, I)
402
+ );
403
+ }
404
+ return new Response(n.buildStream(), {
405
+ headers: { "Content-Type": "application/pdf" }
406
+ }).blob();
407
+ }
408
+ async function ne(e, t, n, i) {
409
+ if (ee(n), !e.length)
410
+ throw new P(
411
+ "INVALID_INPUT",
412
+ "Add at least one page before exporting."
413
+ );
414
+ const w = e.map(() => 0), h = n.pageSize ?? "a4", F = async (o, r, c) => {
415
+ if (B(n.signal), w[o] >= 12)
416
+ throw new P(
417
+ "PROCESSING_FAILED",
418
+ "Encoding attempt limit reached."
419
+ );
420
+ w[o]++;
421
+ const a = await t.encode(o, r, c);
422
+ return B(n.signal), a;
423
+ }, m = [];
424
+ for (let o = 0; o < e.length; o++)
425
+ m.push(await F(o, 2400, 0.9)), i?.((o + 1) / e.length * 0.35);
426
+ let I = await Q(m, h);
427
+ if (B(n.signal), I.size > n.maxBytes) {
428
+ const o = m.map((s) => s.jpeg.size);
429
+ let r = Math.max(
430
+ 0,
431
+ n.maxBytes - (I.size - o.reduce((s, l) => s + l, 0)) - 1024
432
+ ), c = o.reduce((s, l) => s + l, 0);
433
+ const a = n.minQuality ?? 0.65, b = [
434
+ ...new Set(
435
+ [0.9, 0.8, 0.7, a].filter((s) => s >= a)
436
+ )
437
+ ];
438
+ for (let s = 0; s < e.length; s++) {
439
+ const l = Math.max(
440
+ 0,
441
+ Math.floor(r * o[s] / c)
442
+ ), u = m[s], x = Math.max(u.width, u.height), T = Math.min(x, n.minLongEdge ?? 1600), D = [
443
+ .../* @__PURE__ */ new Set([x, Math.round((x + T) / 2), T])
444
+ ];
445
+ let E = u, z = u.jpeg.size <= l;
446
+ e: for (const C of D)
447
+ for (const R of b) {
448
+ if (z) break e;
449
+ if (C === x && R === 0.9) continue;
450
+ const j = await F(s, C, R);
451
+ if (j.jpeg.size < E.jpeg.size && (E = j), j.jpeg.size <= l) {
452
+ E = j, z = !0;
453
+ break e;
454
+ }
455
+ }
456
+ m[s] = E, r -= E.jpeg.size, c -= o[s], i?.(0.35 + (s + 1) / e.length * 0.6);
457
+ }
458
+ I = await Q(m, h);
459
+ }
460
+ B(n.signal);
461
+ const k = {
462
+ bytes: I.size,
463
+ maxBytes: n.maxBytes,
464
+ pageSize: h,
465
+ limits: {
466
+ minQuality: n.minQuality ?? 0.65,
467
+ minLongEdge: n.minLongEdge ?? 1600,
468
+ maxEncodesPerPage: 12
469
+ },
470
+ pages: m.map(
471
+ (o, r) => ({
472
+ id: o.id,
473
+ imageBytes: o.jpeg.size,
474
+ width: o.width,
475
+ height: o.height,
476
+ quality: o.quality,
477
+ attempts: w[r],
478
+ warnings: o.warnings,
479
+ preview: o.jpeg
480
+ })
481
+ )
482
+ };
483
+ return i?.(1), {
484
+ status: I.size <= n.maxBytes ? "ready" : "cannot-fit",
485
+ blob: I,
486
+ report: k
487
+ };
488
+ }
489
+ export {
490
+ Q as buildPdf,
491
+ ne as fitPdf,
492
+ ee as validateExportOptions
493
+ };