@reportwright/pdf 0.1.0-beta.1 → 0.1.0-beta.3

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.js CHANGED
@@ -2266,12 +2266,12 @@ function textBox(str3, o) {
2266
2266
  s = -1;
2267
2267
  lw = 0;
2268
2268
  };
2269
- for (const word of para.split(" ")) {
2269
+ for (const word2 of para.split(" ")) {
2270
2270
  if (lines.length > stop) break paras;
2271
- const ws = q, we = q + word.length;
2271
+ const ws = q, we = q + word2.length;
2272
2272
  q = we + 1;
2273
- if (!word && s < 0) continue;
2274
- const ww = width(word);
2273
+ if (!word2 && s < 0) continue;
2274
+ const ww = width(word2);
2275
2275
  if (s >= 0) {
2276
2276
  const add2 = width(" ") + ww;
2277
2277
  if (lw + add2 <= W + EPS2) {
@@ -2280,7 +2280,7 @@ function textBox(str3, o) {
2280
2280
  continue;
2281
2281
  }
2282
2282
  commit(false);
2283
- if (!word) continue;
2283
+ if (!word2) continue;
2284
2284
  }
2285
2285
  s = ws;
2286
2286
  e = we;
@@ -2288,7 +2288,7 @@ function textBox(str3, o) {
2288
2288
  if (lw <= W + EPS2) continue;
2289
2289
  let acc = 0;
2290
2290
  e = s;
2291
- for (const ch of word) {
2291
+ for (const ch of word2) {
2292
2292
  const cw = width(ch);
2293
2293
  if (acc + cw > W + EPS2 && e > s) {
2294
2294
  if (lines.length > stop) break paras;
@@ -3489,6 +3489,7 @@ function readPng(b) {
3489
3489
  return png;
3490
3490
  }
3491
3491
  async function inflateExact(idat, size, onData, drain = null) {
3492
+ if (NODE_ZLIB2 && size <= SYNC_MAX) return inflateNode(idat, size, onData, drain);
3492
3493
  let n = 0, done = false, total = 0;
3493
3494
  const z = new Unzlib((chunk, final) => {
3494
3495
  if (n + chunk.length > size) throw new TypeError(`PNG: the image data inflates past the ${size.toLocaleString("en")} bytes its header allows (corrupt, or a zip bomb)`);
@@ -3521,6 +3522,37 @@ async function inflateExact(idat, size, onData, drain = null) {
3521
3522
  if (!(rest instanceof Uint8Array) || typeof bit !== "number") throw new Error("PNG: internal: the inflater does not report where the zlib stream ends");
3522
3523
  return total - rest.length + (bit ? 1 : 0);
3523
3524
  }
3525
+ async function inflateNode(idat, size, onData, drain = null) {
3526
+ let total = 0;
3527
+ for (const d of idat) total += d.length;
3528
+ let src = idat[0];
3529
+ if (idat.length > 1) {
3530
+ src = new Uint8Array(total);
3531
+ let at = 0;
3532
+ for (const d of idat) {
3533
+ src.set(d, at);
3534
+ at += d.length;
3535
+ }
3536
+ }
3537
+ let r;
3538
+ try {
3539
+ r = NODE_ZLIB2.inflateSync(src, { info: true, maxOutputLength: Math.max(1, size) });
3540
+ } catch (e) {
3541
+ const code = (
3542
+ /** @type {any} */
3543
+ e.code
3544
+ );
3545
+ if (code === "ERR_BUFFER_TOO_LARGE") throw new TypeError(`PNG: the image data inflates past the ${size.toLocaleString("en")} bytes its header allows (corrupt, or a zip bomb)`);
3546
+ if (code === "Z_BUF_ERROR") throw new TypeError(`PNG: truncated image data (the zlib stream ends early)`);
3547
+ throw new TypeError(`PNG: corrupt image data (${/** @type {Error} */
3548
+ e.message})`);
3549
+ }
3550
+ const out = new Uint8Array(r.buffer.buffer, r.buffer.byteOffset, r.buffer.length);
3551
+ if (out.length !== size) throw new TypeError(`PNG: truncated image data (${out.length.toLocaleString("en")} of ${size.toLocaleString("en")} bytes)`);
3552
+ if (onData) onData(out, 0);
3553
+ if (drain) await drain();
3554
+ return r.engine.bytesWritten;
3555
+ }
3524
3556
  function unfilterRow(f, c, p, bpp) {
3525
3557
  const rb = c.length;
3526
3558
  if (f > 4) throw new TypeError(`PNG: unknown row filter ${f}`);
@@ -3545,29 +3577,58 @@ function unfilterRow(f, c, p, bpp) {
3545
3577
  }
3546
3578
  }
3547
3579
  function filterRow(x2, up, bpp, out, o, t) {
3548
- const rb = x2.length;
3549
- let bestSum = Infinity;
3550
- for (let f = 0; f <= 4; f++) {
3551
- if (f === 3) continue;
3552
- let sum = 0;
3553
- for (let i2 = 0; i2 < rb; i2++) {
3554
- const a = i2 >= bpp ? x2[i2 - bpp] : 0, u = up ? up[i2] : 0, c = up && i2 >= bpp ? up[i2 - bpp] : 0;
3555
- let p = 0;
3556
- if (f === 1) p = a;
3557
- else if (f === 2) p = u;
3558
- else if (f === 4) {
3559
- const pp = a + u - c, pa = Math.abs(pp - a), pb = Math.abs(pp - u), pc = Math.abs(pp - c);
3560
- p = pa <= pb && pa <= pc ? a : pb <= pc ? u : c;
3561
- }
3562
- const v = x2[i2] - p & 255;
3563
- t[i2] = v;
3564
- sum += v < 128 ? v : 256 - v;
3565
- }
3566
- if (sum < bestSum) {
3567
- bestSum = sum;
3568
- out.set(t, o + 1);
3569
- out[o] = f;
3570
- }
3580
+ const rb = x2.length, m = Math.min(bpp, rb);
3581
+ let best = 0, sum = 0;
3582
+ for (let i2 = 0; i2 < rb; i2++) {
3583
+ const v = x2[i2];
3584
+ sum += v < 128 ? v : 256 - v;
3585
+ }
3586
+ out[o] = 0;
3587
+ out.set(x2, o + 1);
3588
+ best = sum;
3589
+ sum = 0;
3590
+ for (let i2 = 0; i2 < m; i2++) {
3591
+ const v = x2[i2];
3592
+ t[i2] = v;
3593
+ sum += v < 128 ? v : 256 - v;
3594
+ }
3595
+ for (let i2 = m; i2 < rb; i2++) {
3596
+ const v = x2[i2] - x2[i2 - bpp] & 255;
3597
+ t[i2] = v;
3598
+ sum += v < 128 ? v : 256 - v;
3599
+ }
3600
+ if (sum < best) {
3601
+ best = sum;
3602
+ out[o] = 1;
3603
+ out.set(t, o + 1);
3604
+ }
3605
+ if (!up) return;
3606
+ sum = 0;
3607
+ for (let i2 = 0; i2 < rb; i2++) {
3608
+ const v = x2[i2] - up[i2] & 255;
3609
+ t[i2] = v;
3610
+ sum += v < 128 ? v : 256 - v;
3611
+ }
3612
+ if (sum < best) {
3613
+ best = sum;
3614
+ out[o] = 2;
3615
+ out.set(t, o + 1);
3616
+ }
3617
+ sum = 0;
3618
+ for (let i2 = 0; i2 < m; i2++) {
3619
+ const v = x2[i2] - up[i2] & 255;
3620
+ t[i2] = v;
3621
+ sum += v < 128 ? v : 256 - v;
3622
+ }
3623
+ for (let i2 = m; i2 < rb; i2++) {
3624
+ const a = x2[i2 - bpp], u = up[i2], c = up[i2 - bpp], pa = Math.abs(u - c), pb = Math.abs(a - c), pc = Math.abs(a + u - c - c);
3625
+ const v = x2[i2] - (pa <= pb && pa <= pc ? a : pb <= pc ? u : c) & 255;
3626
+ t[i2] = v;
3627
+ sum += v < 128 ? v : 256 - v;
3628
+ }
3629
+ if (sum < best) {
3630
+ out[o] = 4;
3631
+ out.set(t, o + 1);
3571
3632
  }
3572
3633
  }
3573
3634
  async function decodePng(p, maxDecoded = MAX_DECODED) {
@@ -3685,7 +3746,7 @@ async function decodePng(p, maxDecoded = MAX_DECODED) {
3685
3746
  };
3686
3747
  return { ...head, filtered: false, alpha: hasAlpha, rows };
3687
3748
  }
3688
- var MAX_SIDE, MAX_PIXELS, MAX_DECODED, STEP, DEPTHS, CHANNELS, ADAM7, CRC_TABLE, isPng, rawSize, filterBytes;
3749
+ var MAX_SIDE, MAX_PIXELS, MAX_DECODED, STEP, NODE_ZLIB2, SYNC_MAX, DEPTHS, CHANNELS, ADAM7, CRC_TABLE, isPng, rawSize, filterBytes;
3689
3750
  var init_png = __esm({
3690
3751
  "src/images/png.js"() {
3691
3752
  init_browser();
@@ -3693,6 +3754,9 @@ var init_png = __esm({
3693
3754
  MAX_PIXELS = 1e8;
3694
3755
  MAX_DECODED = 64 << 20;
3695
3756
  STEP = 1024;
3757
+ NODE_ZLIB2 = /** @type {any} */
3758
+ globalThis.process?.getBuiltinModule?.("node:zlib");
3759
+ SYNC_MAX = 32 << 20;
3696
3760
  DEPTHS = { 0: [1, 2, 4, 8, 16], 2: [8, 16], 3: [1, 2, 4, 8], 4: [8, 16], 6: [8, 16] };
3697
3761
  CHANNELS = { 0: 1, 2: 3, 3: 1, 4: 2, 6: 4 };
3698
3762
  ADAM7 = [[0, 0, 8, 8], [4, 0, 8, 8], [0, 4, 4, 8], [2, 0, 4, 4], [0, 2, 2, 4], [1, 0, 2, 2], [0, 1, 1, 2]];
@@ -3789,13 +3853,38 @@ var init_jpeg = __esm({
3789
3853
  // src/images/image.js
3790
3854
  async function embedImage(doc, bytes, opt = {}) {
3791
3855
  const b = toBytes(bytes, "embedImage");
3792
- const own2 = (k) => opt != null && Object.hasOwn(opt, k) ? (
3856
+ const own2 = (k2) => opt != null && Object.hasOwn(opt, k2) ? (
3793
3857
  /** @type {any} */
3794
- opt[k]
3858
+ opt[k2]
3795
3859
  ) : void 0;
3796
3860
  const o = { colorSpace: own2("colorSpace"), maxDecodedBytes: own2("maxDecodedBytes") ?? MAX_DECODED };
3797
3861
  if (!(Number.isSafeInteger(o.maxDecodedBytes) && o.maxDecodedBytes > 0)) throw new TypeError("embedImage: maxDecodedBytes is a whole number of bytes > 0");
3798
3862
  if (b.length > MAX_INPUT) throw new RangeError(`embedImage: at most ${MAX_INPUT >> 20} MB`);
3863
+ let seen = SEEN.get(doc);
3864
+ if (!seen) SEEN.set(doc, seen = /* @__PURE__ */ new Map());
3865
+ const { key, copy } = await digest(b);
3866
+ const k = `${key} ${o.colorSpace == null ? "-" : idOf(o.colorSpace)} ${o.maxDecodedBytes}`;
3867
+ const hit = seen.get(k);
3868
+ if (hit && (!hit.copy || same(hit.copy, b))) return hit.img;
3869
+ const img = embed(doc, b, o);
3870
+ if (!hit) seen.set(k, { img, copy });
3871
+ img.catch(() => {
3872
+ if (seen.get(k)?.img === img) seen.delete(k);
3873
+ });
3874
+ return img;
3875
+ }
3876
+ async function digest(b) {
3877
+ if (NODE_CRYPTO) return { key: NODE_CRYPTO.createHash("sha256").update(b).digest("hex"), copy: null };
3878
+ const subtle = globalThis.crypto?.subtle;
3879
+ if (subtle) return { key: Array.from(new Uint8Array(await subtle.digest("SHA-256", b.slice())), (x2) => x2.toString(16).padStart(2, "0")).join(""), copy: null };
3880
+ let h1 = 2166136261, h2 = 2538058380;
3881
+ for (let i2 = 0; i2 < b.length; i2++) {
3882
+ h1 = Math.imul(h1 ^ b[i2], 16777619);
3883
+ h2 = Math.imul(h2 ^ b[i2], 1540483477) ^ h2 >>> 15;
3884
+ }
3885
+ return { key: `f${b.length}:${(h1 >>> 0).toString(16)}${(h2 >>> 0).toString(16)}`, copy: b.slice() };
3886
+ }
3887
+ async function embed(doc, b, o) {
3799
3888
  const space = (n) => {
3800
3889
  if (o.colorSpace != null) {
3801
3890
  const icc = unbrand(o.colorSpace, "icc", doc, "ICC colour space (pdf.iccColorSpace)");
@@ -3926,7 +4015,7 @@ function image(img, o = {}) {
3926
4015
  else draw();
3927
4016
  return page;
3928
4017
  }
3929
- var MAX_INPUT, ORIENT;
4018
+ var MAX_INPUT, ORIENT, SEEN, IDS, nextId, idOf, NODE_CRYPTO, same;
3930
4019
  var init_image = __esm({
3931
4020
  "src/images/image.js"() {
3932
4021
  init_serialize();
@@ -3950,6 +4039,19 @@ var init_image = __esm({
3950
4039
  [0, 1, 1, 0, 0, 0],
3951
4040
  [0, 1, -1, 0, 1, 0]
3952
4041
  ];
4042
+ SEEN = /** @type {WeakMap<any, Map<string, { img: Promise<any>, copy: Uint8Array | null }>>} */
4043
+ /* @__PURE__ */ new WeakMap();
4044
+ IDS = /** @type {WeakMap<object, number>} */
4045
+ /* @__PURE__ */ new WeakMap();
4046
+ nextId = 0;
4047
+ idOf = (v) => v !== null && typeof v === "object" ? IDS.get(v) ?? (IDS.set(v, ++nextId), nextId) : `?${String(v)}`;
4048
+ NODE_CRYPTO = /** @type {any} */
4049
+ globalThis.process?.getBuiltinModule?.("node:crypto");
4050
+ same = (a, b) => {
4051
+ if (a.length !== b.length) return false;
4052
+ for (let i2 = 0; i2 < a.length; i2++) if (a[i2] !== b[i2]) return false;
4053
+ return true;
4054
+ };
3953
4055
  }
3954
4056
  });
3955
4057
 
@@ -4773,12 +4875,12 @@ function checkOptions(type, o) {
4773
4875
  k
4774
4876
  );
4775
4877
  if (o.lang != null && (typeof o.lang !== "string" || !/^[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8}){0,8}$/.test(o.lang))) throw new TypeError(`page.tag: lang is a language tag like "en" or "fr-CA", not ${JSON.stringify(o.lang)}`);
4776
- if (o.id != null) idOf(o.id);
4878
+ if (o.id != null) idOf2(o.id);
4777
4879
  if (o.scope != null && type !== "TH") throw new TypeError("page.tag: scope is for TH");
4778
4880
  if (o.headers != null) {
4779
4881
  if (type !== "TH" && type !== "TD") throw new TypeError("page.tag: headers is for TD and TH");
4780
4882
  if (!Array.isArray(o.headers) || !o.headers.length || o.headers.length > 64) throw new TypeError("page.tag: headers is an array of 1–64 TH ids");
4781
- o.headers.forEach(idOf);
4883
+ o.headers.forEach(idOf2);
4782
4884
  }
4783
4885
  for (
4784
4886
  const k of
@@ -4809,7 +4911,7 @@ function artifact(o, fn) {
4809
4911
  if (typeof fn !== "function") throw new TypeError("page.artifact: fn is a function that draws");
4810
4912
  return this.doc.tags ? this.doc.tags.artifact(this, o, fn) : fn();
4811
4913
  }
4812
- var STRUCTURE_TYPES, ART, PARENTS, NUMBERING, ARTIFACT_TYPES, ARTIFACT_SUBTYPES, MAX_TEXT2, MAX_IDS, str, idOf;
4914
+ var STRUCTURE_TYPES, ART, PARENTS, NUMBERING, ARTIFACT_TYPES, ARTIFACT_SUBTYPES, MAX_TEXT2, MAX_IDS, str, idOf2;
4813
4915
  var init_tags = __esm({
4814
4916
  "src/tags/tags.js"() {
4815
4917
  init_serialize();
@@ -4894,7 +4996,7 @@ var init_tags = __esm({
4894
4996
  if (typeof v !== "string" || v.length > MAX_TEXT2) throw new TypeError(`page.tag: ${k} is a string of at most ${MAX_TEXT2} characters`);
4895
4997
  return v;
4896
4998
  };
4897
- idOf = (v) => {
4999
+ idOf2 = (v) => {
4898
5000
  if (typeof v !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(v)) throw new TypeError(`page.tag: an id is 1–64 letters, digits, _ . : or -, not ${JSON.stringify(v)}`);
4899
5001
  return v;
4900
5002
  };
@@ -10101,27 +10203,27 @@ function standardFont(doc, key) {
10101
10203
  items(text3, o) {
10102
10204
  const draw = !o.measure;
10103
10205
  if (!o.rtl) {
10104
- let a2 = 0, n2 = 0, sp2 = 0, same = true;
10206
+ let a2 = 0, n2 = 0, sp2 = 0, same2 = true;
10105
10207
  for (let i2 = 0; i2 < text3.length; i2++) {
10106
10208
  const c = text3.charCodeAt(i2);
10107
10209
  if (c > 255) {
10108
- same = false;
10210
+ same2 = false;
10109
10211
  break;
10110
10212
  }
10111
10213
  const w = W8[c];
10112
10214
  if (w < 0) {
10113
- same = false;
10215
+ same2 = false;
10114
10216
  break;
10115
10217
  }
10116
10218
  a2 += w;
10117
10219
  n2++;
10118
10220
  if (c === 32 && SP32) sp2++;
10119
10221
  if (!SAME[c]) {
10120
- same = false;
10222
+ same2 = false;
10121
10223
  break;
10122
10224
  }
10123
10225
  }
10124
- if (same) return { body: draw ? text3 : "", a: a2, n: n2, sp: sp2 };
10226
+ if (same2) return { body: draw ? text3 : "", a: a2, n: n2, sp: sp2 };
10125
10227
  }
10126
10228
  let body = "", a = 0, n = 0, sp = 0;
10127
10229
  for (const ch of o.rtl ? [...text3].reverse() : text3) {
@@ -10974,6 +11076,8 @@ function embedFont(doc, input, opt = {}) {
10974
11076
  const f = parseFont(bytes);
10975
11077
  const shaper = opt.shaper;
10976
11078
  if (shaper != null && typeof shaper !== "function") throw new TypeError("embedFont: shaper is a function (text, font, { direction, kerning }) => glyphs");
11079
+ const textMapping = opt.textMapping ?? "carrier";
11080
+ if (textMapping !== "carrier" && textMapping !== "actualText") throw new TypeError(`embedFont: textMapping is 'carrier' or 'actualText', not ${JSON.stringify(textMapping)}`);
10977
11081
  const cffTable = f.tables.get("CFF ");
10978
11082
  const parsed = cffTable ? parseCff(cffTable, f.numGlyphs) : null, cidKeyed = !!parsed?.cids;
10979
11083
  const sub = opt.subset ?? true;
@@ -11139,7 +11243,7 @@ function embedFont(doc, input, opt = {}) {
11139
11243
  glued = null;
11140
11244
  const glue = !o.rtl && !!t0 && t0 !== " " && j < gl.length && at(j)[1] === " " && at(j)[0] - j === 1 && at(j)[0] < gl.length && MN.test(at(at(j)[0])[1]);
11141
11245
  const t = glue ? `${t0} ` : t0;
11142
- let lead = -1, span = glue;
11246
+ let lead = -1, li = -1, span = glue;
11143
11247
  if (t0) {
11144
11248
  for (let q = i2; q < j; q++) if ((gl[q].g || !strict) && (lead < 0 || gl[q].ax > gl[lead].ax)) lead = q;
11145
11249
  }
@@ -11155,6 +11259,7 @@ function embedFont(doc, input, opt = {}) {
11155
11259
  }
11156
11260
  const [c, exact] = o.measure ? [g, true] : code(g, q !== lead ? "⁠" : o.rtl && RTL3.test(t) ? [...t].reverse().join("") : t);
11157
11261
  if (!exact) span = true;
11262
+ if (q === lead) li = out.length;
11158
11263
  if (q !== lead && Math.abs(ax * k) >= 1) span ||= !o.rtl;
11159
11264
  out.push({ b: two(c), w: W(g), a: ax * k, dx: dx * k, dy: dy * k, sp: q === lead && t === " ", c: q !== lead && Math.abs(ax * k) < 1 || void 0 });
11160
11265
  }
@@ -11166,6 +11271,7 @@ function embedFont(doc, input, opt = {}) {
11166
11271
  flow[0].n = flow.length;
11167
11272
  if (glue) glued = flow[0];
11168
11273
  }
11274
+ if (textMapping === "actualText" && li >= 0 && !out[li].c) out[li].b = two(code(gl[lead].g, "⁠")[0]);
11169
11275
  } else if (glue) glued = /** @type {any} */
11170
11276
  {};
11171
11277
  i2 = j;
@@ -12896,8 +13002,8 @@ function createSigning(doc, form, o) {
12896
13002
  head: `<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /${sf} ${BYTERANGE} /Contents `,
12897
13003
  after: ` /M ${pdfDate(date)}${s}${ref} >>`,
12898
13004
  /** @param {Uint8Array} digest */
12899
- async sign(digest) {
12900
- const cms = await raced(Promise.resolve().then(() => signer({ digest, hash: o.hash, subFilter: sf, date, timestamp: timestamp ?? void 0, signal: doc.signal })), doc.signal);
13005
+ async sign(digest2) {
13006
+ const cms = await raced(Promise.resolve().then(() => signer({ digest: digest2, hash: o.hash, subFilter: sf, date, timestamp: timestamp ?? void 0, signal: doc.signal })), doc.signal);
12901
13007
  if (cms instanceof Uint8Array && cms.length > size) throw new RangeError(`${who}: the signer's CMS is ${cms.length} bytes, more than the ${size} reserved: pass a larger reserve (at most ${MAX_RESERVE})`);
12902
13008
  checkContentInfo(cms, size, `${who}: the signer's CMS`);
12903
13009
  if (timestamp && !has(cms, TST_OID)) throw new Error(`${who}: a timestamp was asked for but the signer's CMS has no id-aa-timeStampToken (nodeSigner and cmsSigner add it; a custom signer must call r.timestamp)`);
@@ -13022,6 +13128,12 @@ function latin12(b) {
13022
13128
  for (let i2 = 0; i2 < b.length; i2 += 8192) s += String.fromCharCode(...b.subarray(i2, i2 + 8192));
13023
13129
  return s;
13024
13130
  }
13131
+ function word(b, i2, j) {
13132
+ if (j - i2 > 24) return latin12(b.subarray(i2, j));
13133
+ let s = "";
13134
+ for (let k = i2; k < j; k++) s += String.fromCharCode(b[k]);
13135
+ return s;
13136
+ }
13025
13137
  function parseValue(lx) {
13026
13138
  const stack = [];
13027
13139
  for (; ; ) {
@@ -13117,7 +13229,21 @@ function add(top, v) {
13117
13229
  }
13118
13230
  function indexOf(buf, needle, from, to = buf.length) {
13119
13231
  const n0 = needle.charCodeAt(0), L = needle.length;
13120
- outer: for (let i2 = Math.max(0, from); i2 + L <= to; i2++) {
13232
+ from = Math.max(0, from);
13233
+ to = Math.min(to, buf.length);
13234
+ if (to - from > 64) {
13235
+ if (NodeBuffer) {
13236
+ const i2 = NodeBuffer.from(buf.buffer, buf.byteOffset, to).indexOf(needle, from, "latin1");
13237
+ return i2;
13238
+ }
13239
+ for (let i2 = buf.indexOf(n0, from); i2 >= 0 && i2 + L <= to; i2 = buf.indexOf(n0, i2 + 1)) {
13240
+ let j = 1;
13241
+ while (j < L && buf[i2 + j] === needle.charCodeAt(j)) j++;
13242
+ if (j === L) return i2;
13243
+ }
13244
+ return -1;
13245
+ }
13246
+ outer: for (let i2 = from; i2 + L <= to; i2++) {
13121
13247
  if (buf[i2] !== n0) continue;
13122
13248
  for (let j = 1; j < L; j++) if (buf[i2 + j] !== needle.charCodeAt(j)) continue outer;
13123
13249
  return i2;
@@ -13132,7 +13258,7 @@ function lastIndexOf(buf, needle, to, span = to) {
13132
13258
  }
13133
13259
  return -1;
13134
13260
  }
13135
- var MAX_DEPTH4, MAX_ITEMS, Ref, PdfString, PdfStream, Op, CLASS, T, HEX, Lexer, parseValueEnd;
13261
+ var MAX_DEPTH4, MAX_ITEMS, Ref, PdfString, PdfStream, Op, CLASS, T, HEX, Lexer, parseValueEnd, NodeBuffer;
13136
13262
  var init_lexer = __esm({
13137
13263
  "src/reader/lexer.js"() {
13138
13264
  init_budget();
@@ -13244,19 +13370,25 @@ var init_lexer = __esm({
13244
13370
  while (j < e && CLASS[b[j]] === 0) j++;
13245
13371
  this.pos = j;
13246
13372
  if (c >= 48 && c <= 57 || c === 43 || c === 45 || c === 46) {
13247
- let s2 = "";
13248
- for (let k = i2; k < j && k < i2 + 64; k++) s2 += String.fromCharCode(b[k]);
13249
- let v = Number(s2);
13373
+ if (j - i2 < 10) {
13374
+ let v2 = 0, k = i2;
13375
+ while (k < j && b[k] >= 48 && b[k] <= 57) v2 = v2 * 10 + b[k++] - 48;
13376
+ if (k === j && k > i2) {
13377
+ this.val = v2;
13378
+ return T.NUM;
13379
+ }
13380
+ }
13381
+ let s = "";
13382
+ for (let k = i2; k < j && k < i2 + 64; k++) s += String.fromCharCode(b[k]);
13383
+ let v = Number(s);
13250
13384
  if (!Number.isFinite(v)) {
13251
- const m = /^[+-]?(\d+\.?\d*|\.\d+)/.exec(s2.replace(/^([+-])[+-]+/, "$1"));
13385
+ const m = /^[+-]?(\d+\.?\d*|\.\d+)/.exec(s.replace(/^([+-])[+-]+/, "$1"));
13252
13386
  v = m ? Number(m[0]) : 0;
13253
13387
  }
13254
13388
  this.val = Number.isFinite(v) ? v : 0;
13255
13389
  return T.NUM;
13256
13390
  }
13257
- let s = "";
13258
- for (let k = i2; k < j && k < i2 + 128; k++) s += String.fromCharCode(b[k]);
13259
- this.val = s;
13391
+ this.val = j - i2 <= 128 ? word(b, i2, j) : word(b, i2, i2 + 128);
13260
13392
  return T.KW;
13261
13393
  }
13262
13394
  /** @param {number} i after "(" */
@@ -13325,8 +13457,15 @@ var init_lexer = __esm({
13325
13457
  /** @param {number} i after "/" */
13326
13458
  name(i2) {
13327
13459
  const b = this.buf, e = this.end;
13328
- let s = "";
13329
13460
  let j = i2;
13461
+ while (j < e && CLASS[b[j]] === 0 && b[j] !== 35 && j - i2 < 4096) j++;
13462
+ if (j - i2 < 4096 && (j >= e || b[j] !== 35)) {
13463
+ this.pos = j;
13464
+ this.val = word(b, i2, j);
13465
+ return T.NAME;
13466
+ }
13467
+ let s = "";
13468
+ j = i2;
13330
13469
  while (j < e && CLASS[b[j]] === 0 && j - i2 < 4096) {
13331
13470
  if (b[j] === 35 && j + 2 < e && HEX[b[j + 1]] >= 0 && HEX[b[j + 2]] >= 0) {
13332
13471
  s += String.fromCharCode(HEX[b[j + 1]] << 4 | HEX[b[j + 2]]);
@@ -13342,6 +13481,8 @@ var init_lexer = __esm({
13342
13481
  }
13343
13482
  };
13344
13483
  parseValueEnd = () => void 0;
13484
+ NodeBuffer = /** @type {any} */
13485
+ globalThis.Buffer;
13345
13486
  }
13346
13487
  });
13347
13488
 
@@ -13957,11 +14098,11 @@ async function openSource(bytes, budget, o = {}) {
13957
14098
  if (loading.has(n)) return null;
13958
14099
  loading.add(n);
13959
14100
  try {
13960
- let v = load(n);
14101
+ let v = load2(n);
13961
14102
  if (v === void 0 && !recovered) {
13962
14103
  recover();
13963
14104
  recoverDeep();
13964
- v = load(n);
14105
+ v = load2(n);
13965
14106
  }
13966
14107
  v ??= null;
13967
14108
  cache.set(n, v);
@@ -13970,7 +14111,7 @@ async function openSource(bytes, budget, o = {}) {
13970
14111
  loading.delete(n);
13971
14112
  }
13972
14113
  }
13973
- function load(n) {
14114
+ function load2(n) {
13974
14115
  const e = xref.get(n);
13975
14116
  if (e === void 0) return null;
13976
14117
  const [t, a, b] = unpack(e);
@@ -14219,7 +14360,7 @@ async function openSource(bytes, budget, o = {}) {
14219
14360
  )[0] !== 1) continue;
14220
14361
  let v;
14221
14362
  try {
14222
- v = load(n);
14363
+ v = load2(n);
14223
14364
  } catch (e) {
14224
14365
  if (e instanceof PdfReadError && (e.code === "E_TIMEOUT" || e.code === "E_ABORTED" || e.code === "E_BUDGET")) throw e;
14225
14366
  continue;
@@ -14388,12 +14529,12 @@ async function openSource(bytes, budget, o = {}) {
14388
14529
  return r.end;
14389
14530
  }
14390
14531
  const lx = new Lexer(bytes, budget);
14391
- let last = [];
14532
+ let int1 = false, int2 = false, start1 = -1, start2 = -1, seen = 0;
14392
14533
  for (; ; ) {
14393
14534
  const k = lx.next();
14394
14535
  if (k === T.EOF) break;
14395
- if (k === T.KW && lx.val === "obj" && last.length === 2 && last.every((t) => t.k === T.NUM && Number.isInteger(t.v) && t.v >= 0)) {
14396
- const off = last[0].start;
14536
+ if (k === T.KW && lx.val === "obj" && seen >= 2 && int1 && int2) {
14537
+ const off = start1;
14397
14538
  const end = yield* read3(off);
14398
14539
  if (end === false) unreadable(`The object at byte ${off} cannot be read`);
14399
14540
  lx.pos = Math.max(
@@ -14401,11 +14542,15 @@ async function openSource(bytes, budget, o = {}) {
14401
14542
  /** @type {number} */
14402
14543
  end
14403
14544
  );
14404
- last = [];
14545
+ seen = 0;
14546
+ int1 = int2 = false;
14405
14547
  continue;
14406
14548
  }
14407
- last.push({ k, v: lx.val, start: lx.start });
14408
- if (last.length > 2) last.shift();
14549
+ int1 = int2;
14550
+ start1 = start2;
14551
+ int2 = k === T.NUM && Number.isInteger(lx.val) && lx.val >= 0;
14552
+ start2 = lx.start;
14553
+ seen++;
14409
14554
  }
14410
14555
  const inStream = inRegion(regions, budget);
14411
14556
  const hits = scanObjects().sort((x2, y) => x2[2] - y[2]);
@@ -14698,7 +14843,7 @@ function fontOf(src, font, held = (
14698
14843
  }
14699
14844
  for (let k = 0; k < L && i2 + k < b.length; k++) c = c * 256 + b[i2 + k];
14700
14845
  i2 += L;
14701
- emit(toU?.get(c) ?? fromFont(c) ?? NONE, W.get(c) ?? dw, false);
14846
+ emit(toU?.get(c) ?? fromFont(c) ?? (toU ? "" : NONE), W.get(c) ?? dw, false);
14702
14847
  }
14703
14848
  }
14704
14849
  };
@@ -14721,7 +14866,7 @@ function fontOf(src, font, held = (
14721
14866
  for (const x0 of d.slice(0, 4096)) {
14722
14867
  const x2 = R(x0);
14723
14868
  if (typeof x2 === "number") c = x2;
14724
- else if (typeof x2 === "string") diff.set(c++ & 255, x2 === ".notdef" ? "" : glyphText(x2) || NONE);
14869
+ else if (typeof x2 === "string") diff.set(c++ & 255, x2 === ".notdef" ? "" : glyphText(x2) || (toU ? "" : NONE));
14725
14870
  }
14726
14871
  }
14727
14872
  const symbolic = base3 === "Symbol" || base3 === "ZapfDingbats";
@@ -14741,7 +14886,7 @@ function fontOf(src, font, held = (
14741
14886
  if (t === void 0) t = diff.get(c);
14742
14887
  if (t === void 0) {
14743
14888
  const u = symMap ? symMap.get(c) : baseFn(c);
14744
- t = u === void 0 ? NONE : String.fromCodePoint(u);
14889
+ t = u === void 0 ? toU ? "" : NONE : String.fromCodePoint(u);
14745
14890
  }
14746
14891
  let w = Array.isArray(widths) && typeof fc === "number" && c >= fc && c - fc < widths.length ? R(widths[c - fc]) : std ? std.widths[c] : 500;
14747
14892
  if (typeof w !== "number" || !Number.isFinite(w)) w = 0;
@@ -14793,6 +14938,7 @@ function contentBytes(src, contents) {
14793
14938
  ) throw e;
14794
14939
  }
14795
14940
  }
14941
+ if (parts.length === 1) return parts[0];
14796
14942
  let n = parts.length;
14797
14943
  for (const p of parts) n += p.length;
14798
14944
  const out = new Uint8Array(n);
@@ -14869,20 +15015,22 @@ function pageText(src, pageDict, resources, raw = false) {
14869
15015
  let chars2 = 0;
14870
15016
  let moved = true;
14871
15017
  const fonts = /* @__PURE__ */ new Map();
14872
- const add2 = (x2, y, end, size, text3, dir) => {
15018
+ const add2 = (x2, y, end, size, text3, d0, d1, d2, d3) => {
14873
15019
  if (PT.length >= budget.maxTextItems) throw new PdfReadError("E_BUDGET", `A page has more than ${budget.maxTextItems.toLocaleString("en")} pieces of text (budget.maxTextItems)`);
14874
15020
  if ((chars2 += text3.length) > MAX_TEXT_CHARS) throw new PdfReadError("E_BUDGET", `A page makes more than ${MAX_TEXT_CHARS.toLocaleString("en")} characters of text`);
14875
- PX.push(x2);
14876
- PY.push(y);
14877
- PE.push(end);
15021
+ if (raw) {
15022
+ PX.push(x2);
15023
+ PY.push(y);
15024
+ PE.push(end);
15025
+ }
14878
15026
  PS.push(size);
14879
15027
  PT.push(text3);
14880
15028
  PG.push(moved ? 2 : 0);
14881
15029
  moved = false;
14882
- PA.push(dir[0]);
14883
- PAE.push(dir[1]);
14884
- PC.push(dir[2]);
14885
- PD.push(dir[3]);
15030
+ PA.push(d0);
15031
+ PAE.push(d1);
15032
+ PC.push(d2);
15033
+ PD.push(d3);
14886
15034
  };
14887
15035
  const held = (
14888
15036
  /** @type {Held} */
@@ -14917,24 +15065,26 @@ function pageText(src, pageDict, resources, raw = false) {
14917
15065
  let k = 0;
14918
15066
  ts.font.decode(b, (text3, w, space) => {
14919
15067
  if ((++k & 1023) === 0) budget.tick(1024);
14920
- const M0 = mul2([ts.size * ts.Th, 0, 0, ts.size, 0, ts.Ts], mul2(Tm, ctm));
14921
- const x2 = M0[4], y = M0[5], size = Math.hypot(M0[2], M0[3]) || ts.size;
15068
+ const sx = ts.size * ts.Th, sy = ts.size, rise = ts.Ts;
15069
+ const M0 = mul6(sx, 0, 0, sy, 0, rise, mul2(Tm, ctm, C0), G0);
15070
+ const x2 = M0[4], y = M0[5], size = (M0[2] === 0 ? Math.abs(M0[3]) : Math.hypot(M0[2], M0[3])) || ts.size;
14922
15071
  const tx = (w / 1e3 * ts.size + ts.Tc + (space ? ts.Tw : 0)) * ts.Th;
14923
- Tm = mul2([1, 0, 0, 1, tx, 0], Tm);
14924
- const M1 = mul2([ts.size * ts.Th, 0, 0, ts.size, 0, ts.Ts], mul2(Tm, ctm)), end = M1[4];
14925
- const L = Math.hypot(M0[0], M0[1]), ux = L ? M0[0] / L : 1, uy = L ? M0[1] / L : 0;
14926
- const dir = [x2 * ux + y * uy, M1[4] * ux + M1[5] * uy, y * ux - x2 * uy, Math.round(Math.atan2(uy, ux) * 180 / Math.PI)];
15072
+ Tm = mul6(1, 0, 0, 1, tx, 0, Tm);
15073
+ const M1 = mul6(sx, 0, 0, sy, 0, rise, mul2(Tm, ctm, C0), G1), end = M1[4];
15074
+ const L = M0[1] === 0 ? Math.abs(M0[0]) : Math.hypot(M0[0], M0[1]), ux = L ? M0[0] / L : 1, uy = L ? M0[1] / L : 0;
15075
+ const d0 = x2 * ux + y * uy, d1 = M1[4] * ux + M1[5] * uy, d2 = y * ux - x2 * uy, d3 = uy === 0 && ux > 0 ? uy : Math.round(Math.atan2(uy, ux) * 180 / Math.PI);
14927
15076
  if (actual) {
14928
- if (!actual.seen) Object.assign(actual, { x: x2, y, size, dir, seen: true });
15077
+ if (!actual.seen) Object.assign(actual, { x: x2, y, size, dir: [d0, d1, d2, d3], seen: true });
14929
15078
  actual.end = end;
14930
- actual.dir[1] = dir[1];
15079
+ actual.dir[1] = d1;
14931
15080
  return;
14932
15081
  }
14933
15082
  const n = PT.length - 1;
14934
- if (text3) add2(x2, y, end, size, text3, dir);
14935
- else if (n >= 0 && PAE[n] < dir[1] && PD[n] === dir[3] && Math.abs(PC[n] - dir[2]) < 0.01) {
14936
- PE[n] = end;
14937
- PAE[n] = dir[1];
15083
+ if (text3.includes("⁠")) text3 = text3.replaceAll("⁠", "");
15084
+ if (text3) add2(x2, y, end, size, text3, d0, d1, d2, d3);
15085
+ else if (n >= 0 && PAE[n] < d1 && PD[n] === d3 && Math.abs(PC[n] - d2) < 0.01) {
15086
+ if (raw) PE[n] = end;
15087
+ PAE[n] = d1;
14938
15088
  }
14939
15089
  });
14940
15090
  budget.tick(1 + (k & 1023));
@@ -14999,7 +15149,7 @@ function pageText(src, pageDict, resources, raw = false) {
14999
15149
  if (typeof a[1] === "number") ts = { ...ts, TL: -a[1] };
15000
15150
  // falls through
15001
15151
  case "Td":
15002
- if (typeof a[0] === "number" && typeof a[1] === "number") Tm = Tlm = mul2([1, 0, 0, 1, a[0], a[1]], Tlm);
15152
+ if (typeof a[0] === "number" && typeof a[1] === "number") Tm = Tlm = mul6(1, 0, 0, 1, a[0], a[1], Tlm);
15003
15153
  moved = true;
15004
15154
  break;
15005
15155
  case "Tm": {
@@ -15009,7 +15159,7 @@ function pageText(src, pageDict, resources, raw = false) {
15009
15159
  break;
15010
15160
  }
15011
15161
  case "T*":
15012
- Tm = Tlm = mul2([1, 0, 0, 1, 0, -ts.TL], Tlm);
15162
+ Tm = Tlm = mul6(1, 0, 0, 1, 0, -ts.TL, Tlm);
15013
15163
  moved = true;
15014
15164
  break;
15015
15165
  case "Tj":
@@ -15017,13 +15167,13 @@ function pageText(src, pageDict, resources, raw = false) {
15017
15167
  break;
15018
15168
  case "'":
15019
15169
  moved = true;
15020
- Tm = Tlm = mul2([1, 0, 0, 1, 0, -ts.TL], Tlm);
15170
+ Tm = Tlm = mul6(1, 0, 0, 1, 0, -ts.TL, Tlm);
15021
15171
  if (a[0] instanceof PdfString) show(a[0].bytes, f.ctm);
15022
15172
  break;
15023
15173
  case '"':
15024
15174
  if (typeof a[0] === "number") ts = { ...ts, Tw: a[0] };
15025
15175
  if (typeof a[1] === "number") ts = { ...ts, Tc: a[1] };
15026
- Tm = Tlm = mul2([1, 0, 0, 1, 0, -ts.TL], Tlm);
15176
+ Tm = Tlm = mul6(1, 0, 0, 1, 0, -ts.TL, Tlm);
15027
15177
  moved = true;
15028
15178
  if (a[2] instanceof PdfString) show(a[2].bytes, f.ctm);
15029
15179
  break;
@@ -15031,7 +15181,7 @@ function pageText(src, pageDict, resources, raw = false) {
15031
15181
  if (Array.isArray(a[0])) for (const x2 of a[0]) {
15032
15182
  if (x2 instanceof PdfString) show(x2.bytes, f.ctm);
15033
15183
  else if (typeof x2 === "number") {
15034
- Tm = mul2([1, 0, 0, 1, -x2 / 1e3 * ts.size * ts.Th, 0], Tm);
15184
+ Tm = mul6(1, 0, 0, 1, -x2 / 1e3 * ts.size * ts.Th, 0, Tm);
15035
15185
  if (x2 < -180 && PT.length) PG[PT.length - 1] |= 1;
15036
15186
  }
15037
15187
  }
@@ -15060,7 +15210,7 @@ function pageText(src, pageDict, resources, raw = false) {
15060
15210
  const m = marks.pop();
15061
15211
  if (m && m === actual) {
15062
15212
  actual = null;
15063
- if (m.seen && m.at) add2(m.x, m.y, m.end, m.size, m.at, m.dir);
15213
+ if (m.seen && m.at) add2(m.x, m.y, m.end, m.size, m.at, m.dir[0], m.dir[1], m.dir[2], m.dir[3]);
15064
15214
  }
15065
15215
  break;
15066
15216
  }
@@ -15123,7 +15273,7 @@ function pageText(src, pageDict, resources, raw = false) {
15123
15273
  }
15124
15274
  return out.join("");
15125
15275
  }
15126
- var MAX_FORMS, MAX_CMAP, MAX_MARKS, MAX_ACTUAL, MAX_TEXT_CHARS, MAX_DST, MAX_CMAP_CHARS, MAX_HELD, MAX_W, MAX_DO, TEXT_TIMEOUT_MS, DOC, WIN, MAC_HIGH, BASE, STD_HIGH, NAMES2, ACCENT, own, STD_ALIAS, NONE, stops, MAX_CMAP_FONTS, mul2, ID, matrixOf, RTL2, STRONG_L, NUM, rev2;
15276
+ var MAX_FORMS, MAX_CMAP, MAX_MARKS, MAX_ACTUAL, MAX_TEXT_CHARS, MAX_DST, MAX_CMAP_CHARS, MAX_HELD, MAX_W, MAX_DO, TEXT_TIMEOUT_MS, DOC, WIN, WIN_T, MAC_HIGH, BASE, STD_HIGH, NAMES2, ACCENT, own, STD_ALIAS, NONE, stops, MAX_CMAP_FONTS, mul6, mul2, ID, matrixOf, C0, G0, G1, RTL2, STRONG_L, NUM, rev2;
15127
15277
  var init_text2 = __esm({
15128
15278
  "src/reader/text.js"() {
15129
15279
  init_lexer();
@@ -15189,9 +15339,13 @@ var init_text2 = __esm({
15189
15339
  for (let i2 = 0; i2 < p.length; i2 += 2) WIN.set(p[i2 + 1], p[i2]);
15190
15340
  WIN.set(173, 173);
15191
15341
  }
15342
+ WIN_T = new Int32Array(256).map((_, c) => WIN.get(c) ?? (c >= 32 && c < 127 ? c : -1));
15192
15343
  MAC_HIGH = "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ";
15193
15344
  BASE = {
15194
- WinAnsiEncoding: (c) => WIN.get(c) ?? (c >= 32 && c < 127 ? c : void 0),
15345
+ WinAnsiEncoding: (c) => {
15346
+ const u = WIN_T[c & 255];
15347
+ return c < 256 && u >= 0 ? u : WIN.get(c) ?? (c >= 32 && c < 127 ? c : void 0);
15348
+ },
15195
15349
  MacRomanEncoding: (c) => c >= 128 ? MAC_HIGH.codePointAt(c - 128) : c >= 32 && c < 127 ? c : void 0,
15196
15350
  StandardEncoding: (c) => c === 39 ? 8217 : c === 96 ? 8216 : c >= 32 && c < 127 ? c : STD_HIGH.get(c),
15197
15351
  PDFDocEncoding: (c) => DOC.get(c) ?? c
@@ -15342,16 +15496,22 @@ var init_text2 = __esm({
15342
15496
  NONE = "�";
15343
15497
  stops = (e) => e?.code === "E_TIMEOUT" || e?.code === "E_ABORTED" || e?.code === "E_BUDGET";
15344
15498
  MAX_CMAP_FONTS = 100;
15345
- mul2 = (A, B) => (
15346
- /** @type {M} */
15347
- [A[0] * B[0] + A[1] * B[2], A[0] * B[1] + A[1] * B[3], A[2] * B[0] + A[3] * B[2], A[2] * B[1] + A[3] * B[3], A[4] * B[0] + A[5] * B[2] + B[4], A[4] * B[1] + A[5] * B[3] + B[5]]
15348
- );
15349
- ID = /** @type {M} */
15350
- [1, 0, 0, 1, 0, 0];
15351
- matrixOf = (a) => a.length >= 6 && a.slice(0, 6).every((x2) => typeof x2 === "number" && Number.isFinite(x2)) ? (
15352
- /** @type {M} */
15353
- a.slice(0, 6)
15354
- ) : null;
15499
+ mul6 = (a0, a1, a2, a3, a4, a5, B, o = new Float64Array(6)) => {
15500
+ const b0 = B[0], b1 = B[1], b2 = B[2], b3 = B[3], b4 = B[4], b5 = B[5];
15501
+ o[0] = a0 * b0 + a1 * b2;
15502
+ o[1] = a0 * b1 + a1 * b3;
15503
+ o[2] = a2 * b0 + a3 * b2;
15504
+ o[3] = a2 * b1 + a3 * b3;
15505
+ o[4] = a4 * b0 + a5 * b2 + b4;
15506
+ o[5] = a4 * b1 + a5 * b3 + b5;
15507
+ return o;
15508
+ };
15509
+ mul2 = (A, B, o = new Float64Array(6)) => mul6(A[0], A[1], A[2], A[3], A[4], A[5], B, o);
15510
+ ID = Float64Array.of(1, 0, 0, 1, 0, 0);
15511
+ matrixOf = (a) => a.length >= 6 && a.slice(0, 6).every((x2) => typeof x2 === "number" && Number.isFinite(x2)) ? Float64Array.from(a.slice(0, 6)) : null;
15512
+ C0 = new Float64Array(6);
15513
+ G0 = new Float64Array(6);
15514
+ G1 = new Float64Array(6);
15355
15515
  RTL2 = /[\u0590-\u05ff\u0600-\u065f\u066a-\u06ef\u06fa-\u08ff\ufb1d-\ufdff\ufe70-\ufeff]/;
15356
15516
  STRONG_L = /[\p{L}]/u;
15357
15517
  NUM = /^[\p{Nd}.,٫٬]+$/u;
@@ -15724,27 +15884,34 @@ function createCopier(t) {
15724
15884
  const out = [];
15725
15885
  const stack = [v];
15726
15886
  const budget = owner.r.src.budget;
15887
+ const text3 = refText !== null && refText !== AUDIT;
15727
15888
  while (stack.length) {
15728
15889
  const x2 = stack.pop();
15729
15890
  budget.tick();
15730
15891
  if (x2 instanceof Raw) {
15731
- if (refText) out.push(x2.s);
15892
+ if (text3) out.push(x2.s);
15732
15893
  continue;
15733
15894
  }
15734
15895
  if (x2 instanceof Ref) {
15735
15896
  if (found) found.push([owner, x2.n]);
15736
- if (refText) out.push(refText(owner, x2));
15897
+ if (text3) out.push(
15898
+ /** @type {any} */
15899
+ refText(owner, x2)
15900
+ );
15737
15901
  continue;
15738
15902
  }
15739
15903
  if (x2 instanceof Foreign) {
15740
15904
  if (found) found.push([x2.owner, x2.ref.n]);
15741
- if (refText) out.push(refText(x2.owner, x2.ref));
15905
+ if (text3) out.push(
15906
+ /** @type {any} */
15907
+ refText(x2.owner, x2.ref)
15908
+ );
15742
15909
  continue;
15743
15910
  }
15744
15911
  if (Array.isArray(x2)) {
15745
- stack.push(CLOSE_A);
15912
+ if (text3) stack.push(CLOSE_A);
15746
15913
  for (let i2 = x2.length - 1; i2 >= 0; i2--) stack.push(x2[i2]);
15747
- stack.push(OPEN_A);
15914
+ if (text3) stack.push(OPEN_A);
15748
15915
  continue;
15749
15916
  }
15750
15917
  if (x2 instanceof Map) {
@@ -15754,7 +15921,7 @@ function createCopier(t) {
15754
15921
  if ("why" in r) {
15755
15922
  if (refText) {
15756
15923
  t.report(r.why);
15757
- out.push("null");
15924
+ if (text3) out.push("null");
15758
15925
  }
15759
15926
  continue;
15760
15927
  }
@@ -15766,16 +15933,18 @@ function createCopier(t) {
15766
15933
  }
15767
15934
  }
15768
15935
  }
15769
- stack.push(CLOSE_D);
15770
15936
  const es = entries(owner, x2);
15771
- for (let i2 = es.length - 1; i2 >= 0; i2--) {
15772
- stack.push(es[i2][1]);
15773
- stack.push(new Raw(nameText(es[i2][0])));
15774
- }
15775
- stack.push(OPEN_D);
15937
+ if (text3) {
15938
+ stack.push(CLOSE_D);
15939
+ for (let i2 = es.length - 1; i2 >= 0; i2--) {
15940
+ stack.push(es[i2][1]);
15941
+ stack.push(new Raw(nameText(es[i2][0])));
15942
+ }
15943
+ stack.push(OPEN_D);
15944
+ } else for (let i2 = es.length - 1; i2 >= 0; i2--) stack.push(es[i2][1]);
15776
15945
  continue;
15777
15946
  }
15778
- if (!refText) continue;
15947
+ if (!text3) continue;
15779
15948
  if (x2 instanceof PdfString) out.push(hexText(x2.bytes));
15780
15949
  else if (typeof x2 === "string") out.push(nameText(x2));
15781
15950
  else if (typeof x2 === "number") out.push(numText(x2));
@@ -15861,7 +16030,7 @@ function createCopier(t) {
15861
16030
  if (t.dedupe && early === void 0 && !open && shareable(v)) {
15862
16031
  key = `${dict.length} ${fnv(dict)} ${raw ? `${raw.length} ${fnv(raw)}` : ""}`;
15863
16032
  const hit = seen.get(key);
15864
- if (hit && hit.dict === dict && same(hit.raw(), raw)) {
16033
+ if (hit && hit.dict === dict && same2(hit.raw(), raw)) {
15865
16034
  m.set(f.n, hit.n);
15866
16035
  continue;
15867
16036
  }
@@ -15879,7 +16048,7 @@ function createCopier(t) {
15879
16048
  m.set(f.n, n);
15880
16049
  }
15881
16050
  }
15882
- const same = (a, b) => {
16051
+ const same2 = (a, b) => {
15883
16052
  if (a === b) return true;
15884
16053
  if (!a || !b || a.length !== b.length) return false;
15885
16054
  for (let i2 = 0; i2 < a.length; i2++) if (a[i2] !== b[i2]) return false;
@@ -15955,7 +16124,7 @@ function createCopier(t) {
15955
16124
  }
15956
16125
  auditing = treeOf(owner).nums.has(n);
15957
16126
  try {
15958
- walk(owner, v instanceof PdfStream ? v.dict : v, () => "null", null);
16127
+ walk(owner, v instanceof PdfStream ? v.dict : v, AUDIT, null);
15959
16128
  } finally {
15960
16129
  auditing = false;
15961
16130
  }
@@ -15967,7 +16136,7 @@ function createCopier(t) {
15967
16136
  }
15968
16137
  };
15969
16138
  }
15970
- var SHARE, GRAY, HEXD, Raw, Foreign, OPEN_A, CLOSE_A, OPEN_D, CLOSE_D;
16139
+ var SHARE, GRAY, HEXD, Raw, Foreign, AUDIT, OPEN_A, CLOSE_A, OPEN_D, CLOSE_D;
15971
16140
  var init_copy = __esm({
15972
16141
  "src/reader/copy.js"() {
15973
16142
  init_lexer();
@@ -15991,6 +16160,7 @@ var init_copy = __esm({
15991
16160
  this.ref = ref;
15992
16161
  }
15993
16162
  };
16163
+ AUDIT = () => "null";
15994
16164
  OPEN_A = new Raw("[");
15995
16165
  CLOSE_A = new Raw("]");
15996
16166
  OPEN_D = new Raw("<<");
@@ -16289,6 +16459,8 @@ async function run(self, sink, o) {
16289
16459
  signal: o.signal,
16290
16460
  timeoutMs: o.timeoutMs,
16291
16461
  creationDate: created,
16462
+ metadata: !!(level || self.edits.xmp != null || self.xmp() != null),
16463
+ // an XMP packet only when the source had one or PDF/A needs one: a file split into pages is not a kilobyte of XMP each
16292
16464
  title: info.title ?? void 0,
16293
16465
  author: info.author ?? void 0,
16294
16466
  subject: info.subject ?? void 0,
@@ -16923,8 +17095,8 @@ ${xrefAt}
16923
17095
  const H = hasher(sig.hash);
16924
17096
  H.update(bytes.subarray(0, a));
16925
17097
  H.update(bytes.subarray(b));
16926
- const digest = await H.digest();
16927
- const cms = await Promise.resolve().then(() => sig.signer({ digest, hash: sig.hash, subFilter: sig.subFilter, date: sig.date, timestamp: sig.timestamp ?? void 0 }));
17098
+ const digest2 = await H.digest();
17099
+ const cms = await Promise.resolve().then(() => sig.signer({ digest: digest2, hash: sig.hash, subFilter: sig.subFilter, date: sig.date, timestamp: sig.timestamp ?? void 0 }));
16928
17100
  checkContentInfo(cms, size, `${who}: the signer's CMS`);
16929
17101
  if (sig.timestamp && !has(cms, TST_OID)) throw new Error(`${who}: a timestamp was asked for but the signer's CMS has no id-aa-timeStampToken`);
16930
17102
  bytes.set(latin1(hex(cms).padEnd(2 * size, "0")), a + 1);
@@ -17900,6 +18072,136 @@ var init_pdf = __esm({
17900
18072
  }
17901
18073
  });
17902
18074
 
18075
+ // src/bulk.js
18076
+ function bytesOf2(b) {
18077
+ if (b instanceof Uint8Array) return b;
18078
+ if (b instanceof ArrayBuffer) return new Uint8Array(b);
18079
+ throw new TypeError("bulk: an input is a Uint8Array or an ArrayBuffer");
18080
+ }
18081
+ async function runOne(task, input, o) {
18082
+ try {
18083
+ return { ok: true, value: await TASKS[task](input, o) };
18084
+ } catch (e) {
18085
+ return { ok: false, error: errorOf(e) };
18086
+ }
18087
+ }
18088
+ async function bulk(inputs, task, o = {}) {
18089
+ if (!Object.hasOwn(TASKS, task)) throw new TypeError(`bulk: task is one of ${BULK_TASKS.join(", ")}`);
18090
+ if (o == null || typeof o !== "object") throw new TypeError("bulk: options are { workers, memoryMb, password, budget, timeoutMs, encrypt, save }");
18091
+ const list = [...inputs];
18092
+ const { workers: w0, memoryMb = 512, onResult, ...taskOpts } = o;
18093
+ const node = (
18094
+ /** @type {any} */
18095
+ globalThis.process?.getBuiltinModule
18096
+ );
18097
+ const wt = node?.("node:worker_threads"), os = node?.("node:os");
18098
+ const auto = os ? Math.max(1, (os.availableParallelism?.() ?? os.cpus().length) - 1) : 1;
18099
+ const n = Math.min(list.length, w0 == null ? auto : w0);
18100
+ if (!Number.isInteger(n) || n < 0) throw new TypeError("bulk: workers is a positive integer");
18101
+ if (!Number.isFinite(memoryMb) || memoryMb < 16) throw new TypeError("bulk: memoryMb is at least 16");
18102
+ const results = new Array(list.length);
18103
+ const done = (i2, r) => {
18104
+ results[i2] = r;
18105
+ onResult?.(i2, r);
18106
+ };
18107
+ if (!wt || n <= 1) {
18108
+ for (let i2 = 0; i2 < list.length; i2++) done(i2, await runOne(task, list[i2], taskOpts));
18109
+ return results;
18110
+ }
18111
+ let next = 0;
18112
+ const url = import.meta.url;
18113
+ const spawn = () => new wt.Worker(`import(${JSON.stringify(url)}).then((m) => m.__bulkWorker())`, { eval: true, resourceLimits: { maxOldGenerationSizeMb: memoryMb } });
18114
+ const lane = async () => {
18115
+ let worker = spawn();
18116
+ try {
18117
+ while (next < list.length) {
18118
+ const i2 = next++;
18119
+ const r = await new Promise((resolve2) => {
18120
+ const off = () => {
18121
+ worker.off("message", ok);
18122
+ worker.off("error", bad);
18123
+ worker.off("exit", gone);
18124
+ };
18125
+ const ok = (m) => {
18126
+ off();
18127
+ resolve2(m);
18128
+ };
18129
+ const bad = (e) => {
18130
+ off();
18131
+ resolve2({ ok: false, error: { ...errorOf(e), code: "E_WORKER" }, dead: true });
18132
+ };
18133
+ const gone = (c) => {
18134
+ off();
18135
+ resolve2({ ok: false, error: { name: "Error", code: "E_WORKER", message: `the worker stopped (exit ${c}), out of memory (memoryMb) or crashed` }, dead: true });
18136
+ };
18137
+ worker.on("message", ok);
18138
+ worker.once("error", bad);
18139
+ worker.once("exit", gone);
18140
+ worker.postMessage({ task, input: list[i2], o: taskOpts });
18141
+ });
18142
+ if (r.dead) {
18143
+ worker.terminate();
18144
+ worker = spawn();
18145
+ delete r.dead;
18146
+ }
18147
+ done(i2, r);
18148
+ }
18149
+ } finally {
18150
+ await worker.terminate();
18151
+ }
18152
+ };
18153
+ await Promise.all(Array.from({ length: n }, lane));
18154
+ return results;
18155
+ }
18156
+ function __bulkWorker() {
18157
+ const { parentPort } = (
18158
+ /** @type {any} */
18159
+ globalThis.process.getBuiltinModule("node:worker_threads")
18160
+ );
18161
+ parentPort.on("message", async (m) => {
18162
+ const r = await runOne(m.task, m.input, m.o);
18163
+ const v = r.ok ? r.value : null;
18164
+ const transfer = v instanceof Uint8Array ? [v.buffer] : Array.isArray(v) ? v.filter((x2) => x2 instanceof Uint8Array).map((x2) => x2.buffer) : [];
18165
+ try {
18166
+ parentPort.postMessage(r, [...new Set(transfer)].filter((b) => b instanceof ArrayBuffer));
18167
+ } catch {
18168
+ parentPort.postMessage(r);
18169
+ }
18170
+ });
18171
+ }
18172
+ var TASKS, BULK_TASKS, load, errorOf;
18173
+ var init_bulk = __esm({
18174
+ "src/bulk.js"() {
18175
+ init_pdf();
18176
+ TASKS = {
18177
+ /** bytes → the text of every page ('\f' between pages) */
18178
+ extractText: async (input, o) => (await loadPdf(bytesOf2(input), load(o))).extractText(),
18179
+ /** [bytes, bytes, …] → one file */
18180
+ merge: async (input, o) => {
18181
+ if (!Array.isArray(input) || !input.length) throw new TypeError("bulk merge: each input is an array of files");
18182
+ const docs = [];
18183
+ for (const b of input) docs.push(await loadPdf(bytesOf2(b), load(o)));
18184
+ return (await docs[0].fork().merge(docs.slice(1)).save(o.save)).bytes;
18185
+ },
18186
+ /** bytes → one file per page */
18187
+ split: async (input, o) => {
18188
+ const d = await loadPdf(bytesOf2(input), load(o));
18189
+ const out = [];
18190
+ for (let i2 = 0; i2 < d.pageCount; i2++) out.push((await d.fork().reorder([i2]).save(o.save)).bytes);
18191
+ return out;
18192
+ },
18193
+ /** bytes → the file encrypted with o.encrypt (save()'s encrypt option) */
18194
+ encrypt: async (input, o) => {
18195
+ if (o.encrypt == null || typeof o.encrypt !== "object") throw new TypeError("bulk encrypt: options.encrypt is save()'s encrypt option");
18196
+ return (await (await loadPdf(bytesOf2(input), load(o))).save({ ...o.save, encrypt: o.encrypt })).bytes;
18197
+ }
18198
+ };
18199
+ BULK_TASKS = Object.freeze(Object.keys(TASKS));
18200
+ load = (o) => ({ ...o.password != null && { password: o.password }, ...o.budget && { budget: o.budget }, ...o.timeoutMs && { timeoutMs: o.timeoutMs } });
18201
+ errorOf = (e) => ({ name: String(e?.name ?? "Error"), code: e?.code == null ? void 0 : String(e.code), message: String(e?.message ?? e) });
18202
+ }
18203
+ });
18204
+
17903
18205
  // src/index.js
17904
18206
  async function mergePdfs(docs, o) {
17905
18207
  if (!Array.isArray(docs) || !docs.length) throw new TypeError("mergePdfs: an array of documents from loadPdf");
@@ -18120,13 +18422,17 @@ var init_index = __esm({
18120
18422
  init_cms();
18121
18423
  init_pdf();
18122
18424
  init_budget();
18425
+ init_bulk();
18123
18426
  }
18124
18427
  });
18125
18428
  init_index();
18126
18429
  export {
18430
+ BULK_TASKS,
18127
18431
  Page,
18128
18432
  PdfReadError,
18129
18433
  STANDARD_NAMES,
18434
+ __bulkWorker,
18435
+ bulk,
18130
18436
  cmsSigner,
18131
18437
  cmyk,
18132
18438
  createPdf,