@reportwright/viewer 0.12.0 → 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.
Files changed (89) hide show
  1. package/CHANGELOG.md +133 -1
  2. package/README.md +43 -6
  3. package/THIRD-PARTY-NOTICES.md +52 -0
  4. package/dist/{chunk-SBD55ZES.js → chunk-BF7GCWZY.js} +103 -41
  5. package/dist/chunk-BF7GCWZY.js.map +6 -0
  6. package/dist/chunk-BR5K6SBL.js +324 -0
  7. package/dist/chunk-BR5K6SBL.js.map +6 -0
  8. package/dist/chunk-CNDUJ7IV.js +758 -0
  9. package/dist/chunk-CNDUJ7IV.js.map +6 -0
  10. package/dist/{chunk-RYHJUQSV.js → chunk-DXHLIJEY.js} +2 -2
  11. package/dist/{chunk-M6GENFAH.js → chunk-EK5CJY22.js} +4021 -4631
  12. package/dist/chunk-EK5CJY22.js.map +6 -0
  13. package/dist/{chunk-KJTRZJHN.js → chunk-F5EPQTPF.js} +4 -3
  14. package/dist/chunk-F5EPQTPF.js.map +6 -0
  15. package/dist/{chunk-SR2TQ2ZK.js → chunk-F6RMRXIN.js} +2 -2
  16. package/dist/chunk-F6RMRXIN.js.map +6 -0
  17. package/dist/chunk-FEM2QVOO.js +18 -0
  18. package/dist/{chunk-ODREGGKA.js → chunk-IFYCJZNS.js} +9 -6
  19. package/dist/chunk-IFYCJZNS.js.map +6 -0
  20. package/dist/{chunk-EOVGKHAS.js → chunk-L6YEIVVD.js} +86 -57
  21. package/dist/chunk-L6YEIVVD.js.map +6 -0
  22. package/dist/{chunk-APRPSQOD.js → chunk-PQNM6ET7.js} +28 -9
  23. package/dist/chunk-PQNM6ET7.js.map +6 -0
  24. package/dist/chunk-QFLVVM3H.js +856 -0
  25. package/dist/chunk-QFLVVM3H.js.map +6 -0
  26. package/dist/{chunk-5N6OFCHJ.js → chunk-TZXEEVKE.js} +1319 -76
  27. package/dist/chunk-TZXEEVKE.js.map +6 -0
  28. package/dist/{chunk-FARG6X2U.js → chunk-UHHURTSV.js} +15 -9
  29. package/dist/chunk-UHHURTSV.js.map +6 -0
  30. package/dist/chunk-UJL7C2AS.js +546 -0
  31. package/dist/chunk-UJL7C2AS.js.map +6 -0
  32. package/dist/chunk-YIX3OJXU.js +34 -0
  33. package/dist/designer.d.ts +19 -4
  34. package/dist/designer.js +616 -405
  35. package/dist/designer.js.map +3 -3
  36. package/dist/{peer/chunk-GBITRNHE.js → engine.worker.js} +11006 -9030
  37. package/dist/engine.worker.js.map +6 -0
  38. package/dist/peer/{chunk-NPYKZINU.js → chunk-2CD5COHN.js} +66 -37
  39. package/dist/peer/chunk-2CD5COHN.js.map +6 -0
  40. package/dist/peer/{chunk-IPU2YRL2.js → chunk-3CBV5SAI.js} +28 -9
  41. package/dist/peer/chunk-3CBV5SAI.js.map +6 -0
  42. package/dist/peer/{chunk-MCJPN2KL.js → chunk-45GVDKP5.js} +15 -9
  43. package/dist/peer/chunk-45GVDKP5.js.map +6 -0
  44. package/dist/peer/{chunk-76ZABVTI.js → chunk-LWXQX3NJ.js} +4 -3
  45. package/dist/peer/chunk-MKY3SDXU.js +758 -0
  46. package/dist/peer/chunk-MKY3SDXU.js.map +6 -0
  47. package/dist/peer/chunk-S6LSPHSU.js +17 -0
  48. package/dist/peer/chunk-S6LSPHSU.js.map +6 -0
  49. package/dist/peer/{chunk-M4AGFUWE.js → chunk-V42KN7HD.js} +2 -2
  50. package/dist/peer/{chunk-KBT6ZGGO.js → chunk-VZHHNQYB.js} +1319 -76
  51. package/dist/peer/chunk-VZHHNQYB.js.map +6 -0
  52. package/dist/peer/{chunk-Y5CAHLXS.js → chunk-YITWGAR4.js} +9 -6
  53. package/dist/peer/chunk-YITWGAR4.js.map +6 -0
  54. package/dist/peer/chunk-Z5II55QT.js +33 -0
  55. package/dist/peer/chunk-Z5II55QT.js.map +6 -0
  56. package/dist/peer/designer.js +473 -262
  57. package/dist/peer/designer.js.map +3 -3
  58. package/dist/peer/engine.worker.js +16782 -0
  59. package/dist/peer/engine.worker.js.map +6 -0
  60. package/dist/peer/viewer.js +17 -7
  61. package/dist/peer/viewer.js.map +1 -1
  62. package/dist/viewer.d.ts +11 -2
  63. package/dist/viewer.js +17 -7
  64. package/dist/viewer.js.map +1 -1
  65. package/package.json +4 -2
  66. package/dist/chunk-3D43XGIN.js +0 -1167
  67. package/dist/chunk-3D43XGIN.js.map +0 -6
  68. package/dist/chunk-5N6OFCHJ.js.map +0 -6
  69. package/dist/chunk-AH47FS6Y.js +0 -13
  70. package/dist/chunk-APRPSQOD.js.map +0 -6
  71. package/dist/chunk-EOVGKHAS.js.map +0 -6
  72. package/dist/chunk-FARG6X2U.js.map +0 -6
  73. package/dist/chunk-M6GENFAH.js.map +0 -6
  74. package/dist/chunk-ODREGGKA.js.map +0 -6
  75. package/dist/chunk-SBD55ZES.js.map +0 -6
  76. package/dist/chunk-SR2TQ2ZK.js.map +0 -6
  77. package/dist/peer/chunk-76ZABVTI.js.map +0 -6
  78. package/dist/peer/chunk-GBITRNHE.js.map +0 -6
  79. package/dist/peer/chunk-IMQRHDR4.js +0 -12
  80. package/dist/peer/chunk-IPU2YRL2.js.map +0 -6
  81. package/dist/peer/chunk-KBT6ZGGO.js.map +0 -6
  82. package/dist/peer/chunk-MCJPN2KL.js.map +0 -6
  83. package/dist/peer/chunk-NPYKZINU.js.map +0 -6
  84. package/dist/peer/chunk-Y5CAHLXS.js.map +0 -6
  85. /package/dist/{chunk-RYHJUQSV.js.map → chunk-DXHLIJEY.js.map} +0 -0
  86. /package/dist/{chunk-AH47FS6Y.js.map → chunk-FEM2QVOO.js.map} +0 -0
  87. /package/dist/{peer/chunk-IMQRHDR4.js.map → chunk-YIX3OJXU.js.map} +0 -0
  88. /package/dist/{chunk-KJTRZJHN.js.map → peer/chunk-LWXQX3NJ.js.map} +0 -0
  89. /package/dist/peer/{chunk-M4AGFUWE.js.map → chunk-V42KN7HD.js.map} +0 -0
@@ -1,36 +1,58 @@
1
+ import {
2
+ FORMAT_CHAR
3
+ } from "../chunk-EK5CJY22.js";
4
+ import "../chunk-BR5K6SBL.js";
1
5
  import {
2
6
  asciiUrl,
3
7
  drillUrl,
4
8
  safeUrl
5
9
  } from "../chunk-72S6DETS.js";
10
+ import "../chunk-GJS242RR.js";
6
11
  import {
7
12
  withDeadline
8
13
  } from "../chunk-D2NTLAKL.js";
9
14
  import {
10
15
  needsTableData,
11
16
  visualLines
12
- } from "../chunk-SR2TQ2ZK.js";
17
+ } from "../chunk-F6RMRXIN.js";
13
18
  import {
14
- IMAGE_LIMITS,
15
19
  altOf,
16
20
  cellVisuals,
21
+ figures,
22
+ parseColor
23
+ } from "../chunk-UJL7C2AS.js";
24
+ import {
25
+ IMAGE_LIMITS,
26
+ PDFArray,
27
+ PDFBool,
28
+ PDFDict,
29
+ PDFDocument,
30
+ PDFHexString,
31
+ PDFName,
32
+ PDFNumber,
33
+ PDFRawStream,
34
+ PDFStream,
35
+ PDFString,
36
+ concatTransformationMatrix,
17
37
  dataUriBytes,
18
38
  dataUriBytesOf,
19
- figures,
39
+ embeddedFace,
40
+ fontCss,
41
+ fontkit,
20
42
  imageInfoOf,
21
- parseColor,
43
+ isStandard,
44
+ loadFontkit,
45
+ loadPdfLib,
46
+ popGraphicsState,
47
+ pushGraphicsState,
48
+ rgb,
22
49
  svgLength,
23
50
  svgRootAttrs,
24
51
  xmlAttrs,
25
52
  xmlTags
26
- } from "../chunk-3D43XGIN.js";
27
-
28
- // src/exporters/pdf.js
29
- import { PDFDocument, PDFName as PDFName3, PDFString as PDFString4, PDFHexString as PDFHexString5, PDFRawStream as PDFRawStream2, rgb as rgb3 } from "pdf-lib";
30
- import fontkitModule from "@pdf-lib/fontkit";
53
+ } from "../chunk-QFLVVM3H.js";
31
54
 
32
55
  // src/exporters/pdfa.js
33
- import { PDFName, PDFNumber, PDFString, PDFHexString, PDFArray, PDFDict } from "pdf-lib";
34
56
  var xml = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
35
57
  function makePdfA(doc, { icc, title = "Report", author, created = /* @__PURE__ */ new Date(), conformance = "B", ua = false, id } = {}) {
36
58
  if (!icc?.length) throw new Error("PDF/A needs an sRGB colour profile: pass pdfa.icc (public/icc/sRGB-v2-magic.icc)");
@@ -101,7 +123,6 @@ function setUaMetadata(doc, { title = "Report", author = void 0, created = /* @_
101
123
  }
102
124
 
103
125
  // src/exporters/svgimage.js
104
- import { pushGraphicsState, popGraphicsState, concatTransformationMatrix, rgb } from "pdf-lib";
105
126
  var mul = (a, b) => [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], a[0] * b[4] + a[2] * b[5] + a[4], a[1] * b[4] + a[3] * b[5] + a[5]];
106
127
  var I = [1, 0, 0, 1, 0, 0];
107
128
  var TRANSFORMS = /* @__PURE__ */ new Set(["matrix", "translate", "scale", "rotate", "skewX", "skewY"]);
@@ -258,7 +279,6 @@ function drawSvg(page, svg, at) {
258
279
  }
259
280
 
260
281
  // src/exporters/encrypt.js
261
- import { PDFArray as PDFArray2, PDFDict as PDFDict2, PDFNumber as PDFNumber2, PDFString as PDFString2, PDFHexString as PDFHexString2, PDFRawStream, PDFStream, PDFBool } from "pdf-lib";
262
282
  var subtle = () => {
263
283
  const s = globalThis.crypto?.subtle;
264
284
  if (!s) throw new Error("PDF encryption needs WebCrypto (a browser, or Node 20 or later)");
@@ -332,12 +352,12 @@ async function encryptPdf(doc, opt) {
332
352
  };
333
353
  const seen = /* @__PURE__ */ new Set();
334
354
  const walk = async (obj) => {
335
- if (obj instanceof PDFString2 || obj instanceof PDFHexString2) return PDFHexString2.of(hex(await enc(obj.asBytes())));
336
- if (obj instanceof PDFArray2) {
355
+ if (obj instanceof PDFString || obj instanceof PDFHexString) return PDFHexString.of(hex(await enc(obj.asBytes())));
356
+ if (obj instanceof PDFArray) {
337
357
  for (let i = 0; i < obj.size(); i++) obj.set(i, await walk(obj.get(i)));
338
358
  return obj;
339
359
  }
340
- if (obj instanceof PDFDict2) {
360
+ if (obj instanceof PDFDict) {
341
361
  if (seen.has(obj)) return obj;
342
362
  seen.add(obj);
343
363
  for (const [k, v] of obj.entries()) obj.set(k, await walk(v));
@@ -362,21 +382,20 @@ async function encryptPdf(doc, opt) {
362
382
  CF: { StdCF: { AuthEvent: "DocOpen", CFM: "AESV3", Length: 32 } },
363
383
  StmF: "StdCF",
364
384
  StrF: "StdCF",
365
- O: PDFHexString2.of(hex(O)),
366
- U: PDFHexString2.of(hex(U)),
367
- OE: PDFHexString2.of(hex(OE)),
368
- UE: PDFHexString2.of(hex(UE)),
369
- P: PDFNumber2.of(P),
370
- Perms: PDFHexString2.of(hex(Perms)),
385
+ O: PDFHexString.of(hex(O)),
386
+ U: PDFHexString.of(hex(U)),
387
+ OE: PDFHexString.of(hex(OE)),
388
+ UE: PDFHexString.of(hex(UE)),
389
+ P: PDFNumber.of(P),
390
+ Perms: PDFHexString.of(hex(Perms)),
371
391
  EncryptMetadata: PDFBool.True
372
392
  });
373
393
  ctx.trailerInfo.Encrypt = ctx.register(encrypt);
374
- const id = PDFHexString2.of(hex(random(16)));
394
+ const id = PDFHexString.of(hex(random(16)));
375
395
  ctx.trailerInfo.ID = ctx.obj([id, id]);
376
396
  }
377
397
 
378
398
  // src/exporters/pdfua.js
379
- import { PDFName as PDFName2, PDFNumber as PDFNumber3, PDFHexString as PDFHexString3, PDFDict as PDFDict3, PDFArray as PDFArray3, PDFString as PDFString3 } from "pdf-lib";
380
399
  var MARKER = /^\s*(?:[•◦▪▫‣·○●■□–—-]|\d{1,4}[.)]|[a-zA-Z][.)]|[ivxlcdmIVXLCDM]{1,6}[.)])\s*$/;
381
400
  function createTagger(model, doc) {
382
401
  const ctx = doc.context;
@@ -406,6 +425,11 @@ function createTagger(model, doc) {
406
425
  /** A link annotation of item ii (or a field's widget): its structure element; returns its StructParent key. */
407
426
  annot(pi, ii, ref, kind) {
408
427
  const p = plans[pi].get(ii);
428
+ if (p?.link) {
429
+ p.link.kids.push({ objr: ref, pi });
430
+ annots.push({ ref, el: p.link, pi });
431
+ return;
432
+ }
409
433
  const el = node(kind === "field" ? "Form" : "Link");
410
434
  (p?.near || root).kids.push(el);
411
435
  el.parent = p?.near || root;
@@ -430,14 +454,14 @@ function createTagger(model, doc) {
430
454
  let key = 0;
431
455
  pages.forEach((pg, pi) => {
432
456
  if (!mcids[pi].length) return;
433
- pg.node.set(PDFName2.of("StructParents"), PDFNumber3.of(key));
434
- nums.push(PDFNumber3.of(key++), ctx.obj(mcids[pi].map((n) => refOf.get(n))));
457
+ pg.node.set(PDFName.of("StructParents"), PDFNumber.of(key));
458
+ nums.push(PDFNumber.of(key++), ctx.obj(mcids[pi].map((n) => refOf.get(n))));
435
459
  });
436
460
  for (const a of annots) {
437
461
  const d = ctx.lookup(a.ref);
438
- if (d instanceof PDFDict3) d.set(PDFName2.of("StructParent"), PDFNumber3.of(key));
439
- nums.push(PDFNumber3.of(key++), refOf.get(a.el));
440
- pages[a.pi]?.node.set(PDFName2.of("Tabs"), PDFName2.of("S"));
462
+ if (d instanceof PDFDict) d.set(PDFName.of("StructParent"), PDFNumber.of(key));
463
+ nums.push(PDFNumber.of(key++), refOf.get(a.el));
464
+ pages[a.pi]?.node.set(PDFName.of("Tabs"), PDFName.of("S"));
441
465
  }
442
466
  const treeRef = ctx.nextRef();
443
467
  for (const n of all) {
@@ -445,20 +469,20 @@ function createTagger(model, doc) {
445
469
  const K = n.kids.map((k) => {
446
470
  if (k.S) return refOf.get(k);
447
471
  if (k.objr) return ctx.obj({ Type: "OBJR", Obj: k.objr, Pg: pages[k.pi].ref });
448
- return k.pi === pgOf ? PDFNumber3.of(k.mcid) : ctx.obj({ Type: "MCR", Pg: pages[k.pi].ref, MCID: k.mcid });
472
+ return k.pi === pgOf ? PDFNumber.of(k.mcid) : ctx.obj({ Type: "MCR", Pg: pages[k.pi].ref, MCID: k.mcid });
449
473
  });
450
474
  const d = ctx.obj({ Type: "StructElem", S: n.S, P: n === root ? treeRef : refOf.get(n.parent || root), K });
451
- if (pgOf != null) d.set(PDFName2.of("Pg"), pages[pgOf].ref);
452
- if (n.alt != null) d.set(PDFName2.of("Alt"), PDFHexString3.fromText(n.alt));
453
- if (n.attrs) d.set(PDFName2.of("A"), ctx.obj(n.attrs));
475
+ if (pgOf != null) d.set(PDFName.of("Pg"), pages[pgOf].ref);
476
+ if (n.alt != null) d.set(PDFName.of("Alt"), PDFHexString.fromText(n.alt));
477
+ if (n.attrs) d.set(PDFName.of("A"), ctx.obj(n.attrs));
454
478
  ctx.assign(refOf.get(n), d);
455
479
  }
456
480
  ctx.assign(treeRef, ctx.obj({ Type: "StructTreeRoot", K: refOf.get(root), ParentTree: ctx.obj({ Nums: nums }), ParentTreeNextKey: key }));
457
481
  const cat2 = doc.catalog;
458
- cat2.set(PDFName2.of("StructTreeRoot"), treeRef);
459
- cat2.set(PDFName2.of("MarkInfo"), ctx.obj({ Marked: true }));
460
- cat2.set(PDFName2.of("Lang"), PDFString3.of(String(lang).replace(/[^A-Za-z0-9-]/g, "") || "en"));
461
- cat2.set(PDFName2.of("ViewerPreferences"), ctx.obj({ DisplayDocTitle: true }));
482
+ cat2.set(PDFName.of("StructTreeRoot"), treeRef);
483
+ cat2.set(PDFName.of("MarkInfo"), ctx.obj({ Marked: true }));
484
+ cat2.set(PDFName.of("Lang"), PDFString.of(String(lang).replace(/[^A-Za-z0-9-]/g, "") || "en"));
485
+ cat2.set(PDFName.of("ViewerPreferences"), ctx.obj({ DisplayDocTitle: true }));
462
486
  doc.setTitle(title, { showInWindowTitleBar: true });
463
487
  }
464
488
  };
@@ -510,8 +534,38 @@ function plan(model, pg, pi, root) {
510
534
  return el;
511
535
  };
512
536
  let lastText = null;
537
+ const tocLink = (e) => {
538
+ const toc = root.toc || (root.toc = { el: null, last: -1, entries: /* @__PURE__ */ new Map() });
539
+ if (!toc.el || e < toc.last) {
540
+ toc.el = add(node("TOC"));
541
+ toc.entries = /* @__PURE__ */ new Map();
542
+ }
543
+ toc.last = Math.max(toc.last, e);
544
+ let link = toc.entries.get(e);
545
+ if (!link) {
546
+ const toci = node("TOCI"), ref = node("Reference");
547
+ link = node("Link");
548
+ toci.parent = toc.el;
549
+ toc.el.kids.push(toci);
550
+ ref.parent = toci;
551
+ toci.kids.push(ref);
552
+ link.parent = ref;
553
+ ref.kids.push(link);
554
+ toc.entries.set(e, link);
555
+ }
556
+ return link;
557
+ };
513
558
  items.forEach((it, i) => {
514
559
  if (it.t === "bookmark") return;
560
+ if (it.tocEntry != null && (it.t === "text" || it.t === "link") && !it.art) {
561
+ const link = tocLink(it.tocEntry);
562
+ out.set(i, it.t === "link" ? { link } : { el: link });
563
+ return;
564
+ }
565
+ if (it.tocTitle && it.t === "text" && it.lines?.length) {
566
+ out.set(i, { el: add(node("H1")) });
567
+ return;
568
+ }
515
569
  if (it.t === "link" || it.t === "field") {
516
570
  out.set(i, { near: lastText && overlaps(lastText.it, it) ? lastText.el : null });
517
571
  return;
@@ -743,8 +797,285 @@ function pngProblem(b) {
743
797
  return null;
744
798
  }
745
799
 
800
+ // src/exporters/pdfstream.js
801
+ import { Zlib } from "fflate";
802
+
803
+ // src/exporters/pdfstreamtags.js
804
+ function createStreamTagger(w, { maxElements = Infinity } = {}) {
805
+ let count = 0;
806
+ const made = () => {
807
+ if (++count > maxElements) throw Object.assign(new Error(`The tagged PDF has more than ${maxElements.toLocaleString("en-US")} structure elements (tagged.maxElements). Filter the data, or export it untagged.`), { status: 413 });
808
+ };
809
+ const rootRef = w.reserve(), docRef = w.reserve();
810
+ const docKids = [];
811
+ let table = (
812
+ /** @type {null | { ref: number, cols: number, rows: Int32Array, n: number }} */
813
+ null
814
+ );
815
+ let headerDone = false;
816
+ let nums = new Int32Array(1024), nn = 0, key = 0;
817
+ const num3 = (k, ref) => {
818
+ if (nn + 2 > nums.length) {
819
+ const b = new Int32Array(nums.length * 2);
820
+ b.set(nums);
821
+ nums = b;
822
+ }
823
+ nums[nn++] = k;
824
+ nums[nn++] = ref;
825
+ };
826
+ const addRow = (ref) => {
827
+ const t = (
828
+ /** @type {any} */
829
+ table
830
+ );
831
+ if (t.n === t.rows.length) {
832
+ const b = new Int32Array(t.n * 2);
833
+ b.set(t.rows);
834
+ t.rows = b;
835
+ }
836
+ t.rows[t.n++] = ref;
837
+ };
838
+ let mcids = (
839
+ /** @type {number[]} */
840
+ []
841
+ );
842
+ let rows = /* @__PURE__ */ new Map();
843
+ let els = (
844
+ /** @type {any[]} */
845
+ []
846
+ );
847
+ let last = (
848
+ /** @type {any} */
849
+ null
850
+ );
851
+ let links = false, win = 0;
852
+ const el = (S, parent, attrs2) => {
853
+ made();
854
+ const e = { ref: w.reserve(), S, parent, mcid: (
855
+ /** @type {number[]} */
856
+ []
857
+ ), kids: (
858
+ /** @type {any[]} */
859
+ []
860
+ ), attrs: attrs2 };
861
+ els.push(e);
862
+ return e;
863
+ };
864
+ const mark = (e) => {
865
+ const m = mcids.length;
866
+ mcids.push(e.ref);
867
+ e.mcid.push(m);
868
+ return `/${e.S} <</MCID ${m}>> BDC
869
+ `;
870
+ };
871
+ return {
872
+ /** structure elements so far */
873
+ get count() {
874
+ return count;
875
+ },
876
+ /** a new page (window: the paged window it came from; row ids are its own) @param {number} window */
877
+ page(window) {
878
+ mcids = [];
879
+ rows = /* @__PURE__ */ new Map();
880
+ els = [];
881
+ last = null;
882
+ links = false;
883
+ win = window;
884
+ },
885
+ /**
886
+ * The marked content that opens item it: a structure element's MCID, or an artifact; null for a link.
887
+ * @param {any} it
888
+ */
889
+ open(it) {
890
+ if (it.t === "link" || it.t === "bookmark") return null;
891
+ if (it.art) return "/Artifact <</Type /Pagination>> BDC\n";
892
+ if (it.t !== "text" || !it.lines?.some((l) => String(l.text).trim())) return "/Artifact BMC\n";
893
+ const c = it.cell;
894
+ if (!c) {
895
+ const h = it.tag?.h ? Math.min(6, Math.max(1, it.tag.h)) : 0;
896
+ const e = el(h ? `H${h}` : "P", docRef);
897
+ docKids.push(e.ref);
898
+ last = { e, it };
899
+ return mark(e);
900
+ }
901
+ if (c.kind === "header" && headerDone) return "/Artifact <</Type /Pagination>> BDC\n";
902
+ if (!table) {
903
+ table = { ref: w.reserve(), cols: c.cols.length, rows: new Int32Array(4096), n: 0 };
904
+ docKids.push(table.ref);
905
+ }
906
+ const rk = `${win}:${c.row}`;
907
+ let r = rows.get(rk);
908
+ if (!r) {
909
+ made();
910
+ r = { ref: w.reserve(), kind: c.kind, cells: /* @__PURE__ */ new Map() };
911
+ rows.set(rk, r);
912
+ addRow(r.ref);
913
+ }
914
+ let cell = r.cells.get(c.col);
915
+ if (!cell) {
916
+ const attrs2 = c.kind === "header" || c.span > 1 ? { O: "/Table", ...c.kind === "header" ? { Scope: "/Column" } : {}, ...c.span > 1 ? { ColSpan: c.span } : {} } : null;
917
+ cell = el(c.kind === "header" ? "TH" : "TD", r.ref, attrs2);
918
+ r.cells.set(c.col, cell);
919
+ }
920
+ last = { e: cell, it };
921
+ return mark(cell);
922
+ },
923
+ /**
924
+ * A link annotation of the page: its Link element (in the element of the text it covers, else the Document).
925
+ * @returns {number} the annotation's StructParent
926
+ * @param {any} it @param {number} annot the annotation's object number
927
+ */
928
+ link(it, annot) {
929
+ const near = last && overlaps2(last.it, it) ? last.e : null;
930
+ const e = el("Link", near ? near.ref : docRef);
931
+ e.kids.push(`<< /Type /OBJR /Obj ${annot} 0 R >>`);
932
+ (near ? near.kids : docKids).push(near ? `${e.ref} 0 R` : e.ref);
933
+ links = true;
934
+ num3(key, e.ref);
935
+ return key++;
936
+ },
937
+ /**
938
+ * The page is drawn: its elements and parent-tree array are written. @returns {Promise<string>} the page's entries
939
+ * @param {number} pageRef
940
+ */
941
+ async end(pageRef) {
942
+ for (const r of rows.values()) {
943
+ const kids = [];
944
+ for (let col2 = 0; col2 < /** @type {any} */
945
+ table.cols; ) {
946
+ let cell = r.cells.get(col2);
947
+ if (!cell) {
948
+ cell = el(r.kind === "header" ? "TH" : "TD", r.ref, r.kind === "header" ? { O: "/Table", Scope: "/Column" } : null);
949
+ }
950
+ kids.push(cell.ref);
951
+ col2 += Math.max(1, cell.attrs?.ColSpan || 1);
952
+ }
953
+ for (const [col2, cell] of r.cells) if (!kids.includes(cell.ref)) {
954
+ void col2;
955
+ kids.push(cell.ref);
956
+ }
957
+ await w.objectAt(r.ref, `<< /S /TR /P ${/** @type {any} */
958
+ table.ref} 0 R /K [${kids.map((k) => `${k} 0 R`).join(" ")}] >>`);
959
+ }
960
+ if (rows.size && [...rows.values()].some((r) => r.kind === "header")) headerDone = true;
961
+ for (const e of els) {
962
+ const K = [...e.mcid.map(String), ...e.kids].join(" ");
963
+ const A = e.attrs ? ` /A << ${Object.entries(e.attrs).map(([k, v]) => `/${k} ${v}`).join(" ")} >>` : "";
964
+ const P = e.parent === docRef ? docRef : e.parent;
965
+ await w.objectAt(e.ref, `<< /S /${e.S} /P ${P} 0 R${e.mcid.length || e.S === "Link" ? ` /Pg ${pageRef} 0 R` : ""} /K [${K}]${A} >>`);
966
+ }
967
+ let extra = "";
968
+ if (mcids.length) {
969
+ const arr = await w.object(`[${mcids.map((r) => `${r} 0 R`).join(" ")}]`);
970
+ num3(key, arr);
971
+ extra += ` /StructParents ${key++}`;
972
+ }
973
+ if (links) extra += " /Tabs /S";
974
+ return extra;
975
+ },
976
+ /**
977
+ * The tree's top: Table, Document, the parent tree, the root. @returns {Promise<string>} the catalog's entries
978
+ * @param {{ lang?: string }} o
979
+ */
980
+ async finish({ lang = "en" } = {}) {
981
+ const t = table;
982
+ if (t) await w.bigObject(t.ref, `<< /Type /StructElem /S /Table /P ${docRef} 0 R /K [`, refs(t.rows, t.n), "] >>");
983
+ await w.objectAt(docRef, `<< /Type /StructElem /S /Document /P ${rootRef} 0 R /K [${docKids.map((k) => typeof k === "string" ? k : `${k} 0 R`).join(" ")}] >>`);
984
+ const pt = w.reserve();
985
+ await w.bigObject(pt, "<< /Nums [", pairs(nums, nn), "] >>");
986
+ await w.objectAt(rootRef, `<< /Type /StructTreeRoot /K ${docRef} 0 R /ParentTree ${pt} 0 R /ParentTreeNextKey ${key} >>`);
987
+ return ` /StructTreeRoot ${rootRef} 0 R /MarkInfo << /Marked true >> /Lang (${String(lang).replace(/[^A-Za-z0-9-]/g, "") || "en"}) /ViewerPreferences << /DisplayDocTitle true >>`;
988
+ }
989
+ };
990
+ }
991
+ function* refs(a, n) {
992
+ for (let i = 0; i < n; i += 4096) {
993
+ let s = "";
994
+ for (let j = i; j < Math.min(n, i + 4096); j++) s += `${a[j]} 0 R `;
995
+ yield s;
996
+ }
997
+ }
998
+ function* pairs(a, n) {
999
+ for (let i = 0; i < n; i += 4096) {
1000
+ let s = "";
1001
+ for (let j = i; j < Math.min(n, i + 4096); j += 2) s += `${a[j]} ${a[j + 1]} 0 R `;
1002
+ yield s;
1003
+ }
1004
+ }
1005
+ function overlaps2(t, l) {
1006
+ const c = t.clip || { x: t.lines[0].x, y: t.lines[0].y - t.size, w: t.lines[0].w || 0, h: t.size * 1.3 };
1007
+ return l.x < c.x + c.w && c.x < l.x + l.w && l.y < c.y + c.h && c.y < l.y + l.h;
1008
+ }
1009
+
1010
+ // src/exporters/pdfstandard.js
1011
+ function standardFontEntries(f) {
1012
+ return {
1013
+ Type: "Font",
1014
+ Subtype: "Type1",
1015
+ BaseFont: f.postscriptName,
1016
+ ...f.winAnsi ? { Encoding: "WinAnsiEncoding" } : {},
1017
+ FirstChar: 32,
1018
+ LastChar: 255,
1019
+ Widths: f.widths.slice(32, 256)
1020
+ };
1021
+ }
1022
+ function standardFontDict(f) {
1023
+ const e = standardFontEntries(f);
1024
+ return `<< /Type /Font /Subtype /Type1 /BaseFont /${e.BaseFont}${e.Encoding ? ` /Encoding /${e.Encoding}` : ""} /FirstChar 32 /LastChar 255 /Widths [${e.Widths.join(" ")}] >>`;
1025
+ }
1026
+ var standIns = (store) => [...new Set([...store.fonts.keys()].filter(isStandard).map(embeddedFace))];
1027
+ var esc = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
1028
+ function standardLiteral(f, text) {
1029
+ let out = "";
1030
+ for (const ch of text) out += esc(f.glyphForCodePoint(
1031
+ /** @type {number} */
1032
+ ch.codePointAt(0)
1033
+ ).id);
1034
+ return out;
1035
+ }
1036
+ function embeddedPage(pg, fontOf, families) {
1037
+ const line = (l, key, size) => {
1038
+ const runs = l.runs || [{ font: key, x: 0, text: l.text, glyphs: null }];
1039
+ if (!runs.some((r) => isStandard(r.font))) return l;
1040
+ return { ...l, runs: runs.map((r) => {
1041
+ if (!isStandard(r.font)) return r;
1042
+ families.add(fontCss(r.font).family);
1043
+ const std = fontOf(r.font), sub = embeddedFace(r.font), emb = fontOf(sub);
1044
+ const glyphs = [];
1045
+ if (r.glyphs) {
1046
+ for (let i = 0; i < r.glyphs.length; i += 4) glyphs.push(emb.glyphForCodePoint(r.text.codePointAt(r.glyphs[i + 3])).id, r.glyphs[i + 1], r.glyphs[i + 2], r.glyphs[i + 3]);
1047
+ return { ...r, font: sub, glyphs };
1048
+ }
1049
+ let pen = 0;
1050
+ for (let i = 0; i < r.text.length; ) {
1051
+ const cp = (
1052
+ /** @type {number} */
1053
+ r.text.codePointAt(i)
1054
+ );
1055
+ glyphs.push(emb.glyphForCodePoint(cp).id, pen, 0, i);
1056
+ pen += std.glyphForCodePoint(cp).advanceWidth * size / 1e3;
1057
+ i += cp > 65535 ? 2 : 1;
1058
+ }
1059
+ return { ...r, font: sub, w: pen, glyphs };
1060
+ }) };
1061
+ };
1062
+ const item = (it) => {
1063
+ if (it.t === "field") {
1064
+ const draw = it.draw.map(item);
1065
+ return draw.some((d, i) => d !== it.draw[i]) ? { ...it, draw } : it;
1066
+ }
1067
+ if (it.t !== "text") return it;
1068
+ const lines = it.lines.map((l) => line(l, it.font, it.size));
1069
+ return lines.some((l, i) => l !== it.lines[i]) ? { ...it, lines } : it;
1070
+ };
1071
+ const items = pg.items.map(item);
1072
+ return items.some((x, i) => x !== pg.items[i]) ? { ...pg, items } : pg;
1073
+ }
1074
+ function embeddedWarnings(families) {
1075
+ return [...families].map((f) => `PDF/A and PDF/UA need embedded fonts, and "${f}" is a standard font that is not embedded: its text is drawn in ${fontCss(embeddedFace(f)).family} at ${f}'s spacing (no metric-compatible font ships, so the letters' widths differ).`);
1076
+ }
1077
+
746
1078
  // src/exporters/pdfpaint.js
747
- import { PDFHexString as PDFHexString4, rgb as rgb2 } from "pdf-lib";
748
1079
  var colors = /* @__PURE__ */ new Map();
749
1080
  var col = (c) => {
750
1081
  if (colors.has(c)) return colors.get(c);
@@ -753,16 +1084,31 @@ var col = (c) => {
753
1084
  return v;
754
1085
  };
755
1086
  var BLACK = { color: rgb2(0, 0, 0), opacity: 1, rgb: "0 0 0" };
1087
+ function rgb2(red, green, blue) {
1088
+ return { type: (
1089
+ /** @type {any} */
1090
+ "RGB"
1091
+ ), red, green, blue };
1092
+ }
1093
+ var hexText = (s) => {
1094
+ let h = "<FEFF";
1095
+ for (let i = 0; i < s.length; i++) h += s.charCodeAt(i).toString(16).toUpperCase().padStart(4, "0");
1096
+ return `${h}>`;
1097
+ };
756
1098
  var n2 = (v) => Math.round(v * 100) / 100;
757
1099
  var n3 = (v) => Math.round(v * 1e3) / 1e3;
758
1100
  var n4 = (v) => Math.round(v * 1e4) / 1e4;
759
1101
  var hex4 = (id) => id.toString(16).padStart(4, "0");
760
1102
  var KAPPA = 4 * ((Math.SQRT2 - 1) / 3);
761
1103
  var cleanText = (t) => t.replace(/\t|\u0085|\u2028|\u2029/g, " ").replace(/[\b\v]/g, "");
1104
+ var formatAt = (run, cl) => {
1105
+ const cp = run.text.codePointAt(cl);
1106
+ return cp !== void 0 && FORMAT_CHAR.test(String.fromCodePoint(cp));
1107
+ };
762
1108
  function drawRun(c, run, x, y, size, pf, color, spans, texts) {
763
1109
  const f = pf.embedder.font;
764
1110
  const per = 1e3 / size;
765
- const span = (text) => `/Span <</ActualText ${PDFHexString4.fromText(text).toString()}>> BDC
1111
+ const span = (text) => `/Span <</ActualText ${hexText(text)}>> BDC
766
1112
  `;
767
1113
  c.et();
768
1114
  c.paint(color, null);
@@ -811,9 +1157,9 @@ function drawRun(c, run, x, y, size, pf, color, spans, texts) {
811
1157
  rise = gy;
812
1158
  }
813
1159
  const adj = Math.round((pen - gx) * per * 1e3) / 1e3;
814
- if (id === 0 && c.tagged) pen = gx;
1160
+ if (id === 0 && (c.tagged || formatAt(run, cl))) pen = gx;
815
1161
  else {
816
- arr += (adj ? `${adj}` : "") + `<${hex4(id)}>`;
1162
+ arr += (adj ? `${adj}` : "") + `<${f.standard ? id.toString(16).padStart(2, "0") : hex4(id)}>`;
817
1163
  pen = gx + adv(id) * size / f.unitsPerEm;
818
1164
  }
819
1165
  if (inSpan && (i + 4 >= g.length || (quietAt < 0 || i + 4 < quietAt) && g[i + 7] !== cl || i + 4 === quietAt)) {
@@ -870,6 +1216,7 @@ var Content = class {
870
1216
  this.saved = [];
871
1217
  this.lines = null;
872
1218
  this.tagged = false;
1219
+ this.artLines = false;
873
1220
  }
874
1221
  /**
875
1222
  * The operators so far. Any other drawing reads or appends to it, so the lines waiting are drawn first: the text
@@ -888,7 +1235,7 @@ var Content = class {
888
1235
  * ponytail: lines move after the text drawn just after them; both are thin and do not cover each other.
889
1236
  */
890
1237
  line(stroke, w, dash, x1, y1, x2, y2) {
891
- if (this.tagged) {
1238
+ if (this.tagged && !this.artLines) {
892
1239
  this.paint(null, stroke, w, dash);
893
1240
  this._s += `${n2(x1)} ${n2(y1)} m ${n2(x2)} ${n2(y2)} l S
894
1241
  `;
@@ -908,6 +1255,8 @@ var Content = class {
908
1255
  if (!L) return;
909
1256
  this.lines = null;
910
1257
  this.et();
1258
+ const end = this.artLines ? "EMC\n" : "";
1259
+ if (end) this._s += "/Artifact BMC\n";
911
1260
  this.paint(null, L.stroke, L.w, L.dash);
912
1261
  const g = L.segs;
913
1262
  const dy = g.length > 2 ? Math.round((g[1][1] - g[0][1]) * 100) : 0;
@@ -916,10 +1265,10 @@ var Content = class {
916
1265
  `;
917
1266
  this._s += `q
918
1267
  ${one}${`1 0 0 1 0 ${dy / 100} cm ${one}`.repeat(g.length - 1)}Q
919
- `;
1268
+ ${end}`;
920
1269
  return;
921
1270
  }
922
- this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n";
1271
+ this._s += g.map(([a, b, c, d]) => `${n2(a)} ${n2(b)} m ${n2(c)} ${n2(d)} l`).join(" ") + " S\n" + end;
923
1272
  }
924
1273
  q() {
925
1274
  this.et();
@@ -1069,11 +1418,852 @@ async function deflateNow(bytes) {
1069
1418
  return new Uint8Array(await new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate"))).arrayBuffer());
1070
1419
  }
1071
1420
 
1421
+ // src/exporters/pdfstream.js
1422
+ var CHUNK = 64 * 1024;
1423
+ var LEAF = 64;
1424
+ var OBJSTM = 100;
1425
+ var TAGGED_LARGE = 1e6;
1426
+ var IN_FLIGHT = 8;
1427
+ var hex42 = (id) => id.toString(16).padStart(4, "0");
1428
+ var num2 = (v) => String(Math.round(v * 1e3) / 1e3);
1429
+ var fontRes = (key) => `F_${key.replace(/[^A-Za-z0-9.-]/g, "_")}`;
1430
+ var esc2 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
1431
+ function written(sink, r) {
1432
+ const s = (
1433
+ /** @type {any} */
1434
+ sink
1435
+ );
1436
+ if (r !== false || !s.once) return Promise.resolve(r);
1437
+ return new Promise((ok, fail) => {
1438
+ const off = () => {
1439
+ s.off?.("drain", onDrain);
1440
+ s.off?.("error", onError);
1441
+ s.off?.("close", onClose);
1442
+ };
1443
+ const onDrain = () => {
1444
+ off();
1445
+ ok(void 0);
1446
+ };
1447
+ const onError = (e) => {
1448
+ off();
1449
+ fail(e);
1450
+ };
1451
+ const onClose = () => {
1452
+ off();
1453
+ fail(Object.assign(new Error("The sink closed before the PDF was written"), { code: "ERR_STREAM_PREMATURE_CLOSE" }));
1454
+ };
1455
+ s.once("drain", onDrain);
1456
+ s.once("error", onError);
1457
+ s.once("close", onClose);
1458
+ });
1459
+ }
1460
+ function raced(p, signal) {
1461
+ if (!signal) return p;
1462
+ if (signal.aborted) {
1463
+ p.catch(() => {
1464
+ });
1465
+ return Promise.reject(signal.reason);
1466
+ }
1467
+ return new Promise((ok, fail) => {
1468
+ const on = () => fail(signal.reason);
1469
+ signal.addEventListener("abort", on, { once: true });
1470
+ p.then((v) => {
1471
+ signal.removeEventListener("abort", on);
1472
+ ok(v);
1473
+ }, (e) => {
1474
+ signal.removeEventListener("abort", on);
1475
+ fail(e);
1476
+ });
1477
+ });
1478
+ }
1479
+ function createPdfStream(sink, opt) {
1480
+ const { fontStore } = opt;
1481
+ let pos = 0, nextNum = 1;
1482
+ let kind = new Uint8Array(4096), loc = new Uint32Array(4096), idx = new Uint16Array(4096);
1483
+ const place = (n, k, l, i = 0) => {
1484
+ if (n >= kind.length) {
1485
+ let L = kind.length;
1486
+ while (L <= n) L *= 2;
1487
+ const k2 = new Uint8Array(L), l2 = new Uint32Array(L), i2 = new Uint16Array(L);
1488
+ k2.set(kind);
1489
+ l2.set(loc);
1490
+ i2.set(idx);
1491
+ kind = k2;
1492
+ loc = l2;
1493
+ idx = i2;
1494
+ }
1495
+ kind[n] = k;
1496
+ loc[n] = l;
1497
+ idx[n] = i;
1498
+ };
1499
+ let parts = [];
1500
+ let size = 0;
1501
+ const reserve = () => nextNum++;
1502
+ const flush = async () => {
1503
+ if (!size) return;
1504
+ const all = new Uint8Array(size);
1505
+ let at = 0;
1506
+ for (const p of parts) {
1507
+ all.set(p, at);
1508
+ at += p.length;
1509
+ }
1510
+ parts = [];
1511
+ size = 0;
1512
+ await raced(written(sink, sink.write(all)), opt.signal);
1513
+ };
1514
+ const put = (x) => {
1515
+ const u8 = typeof x === "string" ? latin12(x) : x;
1516
+ parts.push(u8);
1517
+ size += u8.length;
1518
+ pos += u8.length;
1519
+ return size >= CHUNK ? flush() : void 0;
1520
+ };
1521
+ let batch = [];
1522
+ const writeBatch = async () => {
1523
+ if (!batch.length) return;
1524
+ const b = batch;
1525
+ batch = [];
1526
+ const sn = reserve();
1527
+ let head = "", body = "";
1528
+ b.forEach(([n, d], i) => {
1529
+ head += `${n} ${body.length} `;
1530
+ body += `${d}
1531
+ `;
1532
+ place(n, 2, sn, i);
1533
+ });
1534
+ const raw = latin12(head + body);
1535
+ await writeObj(sn, `<< /Type /ObjStm /N ${b.length} /First ${head.length} /Filter /FlateDecode >>`, await deflate(raw));
1536
+ };
1537
+ const writeObj = async (n, dict, stream) => {
1538
+ if (!stream) {
1539
+ batch.push([n, dict]);
1540
+ place(n, 3, 0);
1541
+ return batch.length >= OBJSTM ? writeBatch() : void 0;
1542
+ }
1543
+ place(n, 1, pos);
1544
+ await put(`${n} 0 obj
1545
+ ${dict.replace(/>>\s*$/, `/Length ${stream.length} >>`)}
1546
+ stream
1547
+ `);
1548
+ await put(stream);
1549
+ return put("\nendstream\nendobj\n");
1550
+ };
1551
+ put("%PDF-1.7\n%âãÏÓ\n");
1552
+ const fonts = /* @__PURE__ */ new Map();
1553
+ let pages = 0, done = false;
1554
+ const inFlight = [];
1555
+ const fontOf = (key) => {
1556
+ let f = fonts.get(key);
1557
+ if (!f) {
1558
+ if (done) throw new Error("The PDF is finished");
1559
+ fonts.set(key, f = { name: fontRes(key), ref: reserve(), font: fontStore.get(key), cps: /* @__PURE__ */ new Set([32]), glyphs: /* @__PURE__ */ new Map(), memo: /* @__PURE__ */ new Map(), lit: /* @__PURE__ */ new Map() });
1560
+ }
1561
+ return f;
1562
+ };
1563
+ const resRef = reserve();
1564
+ for (const key of opt.fonts || []) fontOf(key);
1565
+ const res = /* @__PURE__ */ new Map();
1566
+ const totals = [];
1567
+ const pageRefs = [];
1568
+ const leaves = [];
1569
+ const w = {
1570
+ /** @param {string} key @returns {string} the font's resource name (F1…) */
1571
+ fontName: (key) => fontOf(key).name,
1572
+ /**
1573
+ * The text's glyphs, one per character (as the engine measured it: no layout features), as hex for <…> Tj, with
1574
+ * the glyphs recorded for the subset, W and ToUnicode.
1575
+ * @param {string} key @param {string} text
1576
+ */
1577
+ encode(key, text) {
1578
+ const F = fontOf(key);
1579
+ let out = "";
1580
+ for (const ch of text) {
1581
+ const cp = (
1582
+ /** @type {number} */
1583
+ ch.codePointAt(0)
1584
+ );
1585
+ let h = F.memo.get(cp);
1586
+ if (h === void 0) {
1587
+ const id = F.font.glyphForCodePoint(cp).id;
1588
+ F.memo.set(cp, h = F.font.standard ? id.toString(16).padStart(2, "0") : hex42(id));
1589
+ F.cps.add(cp);
1590
+ if (!F.glyphs.has(id)) F.glyphs.set(id, ch);
1591
+ }
1592
+ out += h;
1593
+ }
1594
+ return out;
1595
+ },
1596
+ /**
1597
+ * The same glyphs as a literal string's body, two bytes each, escaped (as pdf.js draws plain text): ( … ) Tj.
1598
+ * @param {string} key @param {string} text
1599
+ */
1600
+ literal(key, text) {
1601
+ const F = fontOf(key);
1602
+ let out = "";
1603
+ for (const ch of text) {
1604
+ const cp = (
1605
+ /** @type {number} */
1606
+ ch.codePointAt(0)
1607
+ );
1608
+ let b = F.lit.get(cp);
1609
+ if (b === void 0) {
1610
+ const id = parseInt(w.encode(key, ch), 16);
1611
+ F.lit.set(cp, b = F.font.standard ? esc2(id) : esc2(id >> 8) + esc2(id & 255));
1612
+ }
1613
+ out += b;
1614
+ }
1615
+ return out;
1616
+ },
1617
+ /**
1618
+ * Shaped glyphs drawn by ID (conjuncts, joined forms): [glyph ID, the text it stands for ('' for none)].
1619
+ * @param {string} key @param {Iterable<[number, string]>} glyphs
1620
+ */
1621
+ addGlyphs(key, glyphs) {
1622
+ const F = fontOf(key);
1623
+ for (const [id, text] of glyphs) if (!F.glyphs.has(id)) F.glyphs.set(id, text);
1624
+ },
1625
+ /**
1626
+ * A name in the shared Resources dictionary for a value (an indirect ref "12 0 R" or an inline dictionary).
1627
+ * @param {'ExtGState'|'XObject'|'Pattern'|'Shading'|'ColorSpace'} kind @param {string} value
1628
+ */
1629
+ resource(kind2, value, name = void 0) {
1630
+ let m = res.get(kind2);
1631
+ if (!m) res.set(kind2, m = /* @__PURE__ */ new Map());
1632
+ let n = m.get(value);
1633
+ if (!n) m.set(value, n = name || `${kind2 === "ExtGState" ? "GS" : kind2[0]}${m.size + 1}`);
1634
+ return n;
1635
+ },
1636
+ /**
1637
+ * The ExtGState name for fill and stroke opacity, named by its values (the same name in every writer: pages
1638
+ * painted elsewhere, parallel.js, use it too). @param {number} ca @param {number} CA
1639
+ */
1640
+ gs: (ca, CA) => w.resource("ExtGState", `<< /Type /ExtGState /ca ${num2(ca)} /CA ${num2(CA)} >>`, `GS${num2(ca)}_${num2(CA)}`),
1641
+ /** What this writer's pages used, for another writer to take over (pages painted elsewhere). */
1642
+ used: () => ({ fonts: [...fonts].map(([key, F]) => [key, [...F.cps], [...F.glyphs]]), gs: [...res.get("ExtGState")?.keys() || []] }),
1643
+ /** Take over what pages painted elsewhere used (used() of their writer). @param {any} u */
1644
+ take(u) {
1645
+ for (const [key, cps, glyphs] of u.fonts) {
1646
+ const F = fontOf(key);
1647
+ for (const cp of cps) F.cps.add(cp);
1648
+ for (const [id, t] of glyphs) if (!F.glyphs.has(id)) F.glyphs.set(id, t);
1649
+ }
1650
+ for (const v of u.gs) {
1651
+ const m = (
1652
+ /** @type {any} */
1653
+ v.match(/\/ca (\S+) \/CA (\S+)/)
1654
+ );
1655
+ w.gs(Number(m[1]), Number(m[2]));
1656
+ }
1657
+ },
1658
+ /**
1659
+ * Write an object now (an image: its dictionary and its stream, already filtered). @returns {Promise<number>} its number
1660
+ * @param {string} dict @param {Uint8Array} [stream]
1661
+ */
1662
+ async object(dict, stream) {
1663
+ const n = reserve();
1664
+ await writeObj(n, dict, stream);
1665
+ return n;
1666
+ },
1667
+ /** An object number to write later (objectAt). */
1668
+ reserve: () => reserve(),
1669
+ /** Write a reserved object. @param {number} n @param {string} dict @param {Uint8Array} [stream] */
1670
+ objectAt: (n, dict, stream) => writeObj(n, dict, stream),
1671
+ /**
1672
+ * Write a reserved object whose text may be long (an array of every row's element): head, the parts as they come,
1673
+ * tail; written out in place, never held whole. @param {number} n @param {string} head @param {Iterable<string>} parts @param {string} tail
1674
+ */
1675
+ async bigObject(n, head, parts2, tail) {
1676
+ place(n, 1, pos);
1677
+ await put(`${n} 0 obj
1678
+ ${head}`);
1679
+ for (const x of parts2) await put(x);
1680
+ await put(`${tail}
1681
+ endobj
1682
+ `);
1683
+ },
1684
+ /** The object number of page i (0-based), written or not: links and outline entries may point ahead. @param {number} i */
1685
+ pageRef(i) {
1686
+ return pageRefs[i] ?? (pageRefs[i] = reserve());
1687
+ },
1688
+ /**
1689
+ * The total page count, drawn at the end: a Form XObject whose origin is the text's baseline at the box's left;
1690
+ * draw it with `q 1 0 0 1 x y cm /<name> Do Q`. align: within width.
1691
+ * @param {{ font: string, size: number, width: number, align?: 'left'|'center'|'right', color?: string }} o
1692
+ */
1693
+ totalPages(o) {
1694
+ fontOf(o.font);
1695
+ const ref = reserve();
1696
+ totals.push({ ref, font: o.font, size: o.size, width: o.width, align: o.align || "left", color: o.color || "0 0 0" });
1697
+ return w.resource("XObject", `${ref} 0 R`);
1698
+ },
1699
+ /**
1700
+ * Write a page: its content stream (deflated) and its dictionary, now. Nothing of it stays but two offsets.
1701
+ * @param {{ width: number, height: number, content?: string | Uint8Array, deflated?: Uint8Array, annots?: (string | { ref: number, dict: string })[], extra?: string }} p
1702
+ * deflated: the content stream already compressed (zlib), as pages painted elsewhere come.
1703
+ * content: the page's operators (a string holds bytes 0–255, as pdf.js's Content makes). annots: annotation
1704
+ * dictionaries (with a reserved number: { ref, dict }). extra: more entries for the page dictionary (/StructParents 3).
1705
+ */
1706
+ async addPage(p) {
1707
+ if (done) throw new Error("The PDF is finished");
1708
+ const i = pages++;
1709
+ const ref = w.pageRef(i);
1710
+ if (i % LEAF === 0) leaves.push(reserve());
1711
+ const contents = reserve(), parent = leaves[leaves.length - 1];
1712
+ const z = p.deflated ? Promise.resolve(p.deflated) : deflate(typeof p.content === "string" ? latin12(p.content) : p.content);
1713
+ z.catch(() => {
1714
+ });
1715
+ inFlight.push({ ref, contents, parent, p: { width: p.width, height: p.height, annots: p.annots, extra: p.extra }, z });
1716
+ while (inFlight.length > IN_FLIGHT) await writeNext();
1717
+ },
1718
+ /**
1719
+ * The end of the file: totals, fonts, resources, page tree, outline, catalog, Info, xref, trailer.
1720
+ * @param {{ outline?: OutlineEntry[], info?: { title?: string, author?: string, subject?: string, creationDate?: Date }, catalog?: string }} [o]
1721
+ * catalog: more entries for the catalog (the structure tree, metadata, output intents).
1722
+ * @returns {Promise<{ pages: number, bytes: number }>}
1723
+ */
1724
+ async finish(o = {}) {
1725
+ if (done) throw new Error("The PDF is finished");
1726
+ if (!pages) await w.addPage({ width: 595.28, height: 841.89, content: "" });
1727
+ while (inFlight.length) await writeNext();
1728
+ done = true;
1729
+ for (const t of totals) {
1730
+ const F = fontOf(t.font), text = String(pages), hex2 = w.encode(t.font, text);
1731
+ let adv = 0;
1732
+ for (const ch of text) adv += F.font.glyphForCodePoint(
1733
+ /** @type {number} */
1734
+ ch.codePointAt(0)
1735
+ ).advanceWidth;
1736
+ const tw = adv * t.size / F.font.unitsPerEm;
1737
+ const dx = t.align === "right" ? t.width - tw : t.align === "center" ? (t.width - tw) / 2 : 0;
1738
+ await writeObj(
1739
+ t.ref,
1740
+ `<< /Type /XObject /Subtype /Form /BBox [${num2(Math.min(0, dx))} ${num2(-t.size)} ${num2(Math.max(t.width, dx + tw))} ${num2(2 * t.size)}] /Resources << /Font << /${F.name} ${F.ref} 0 R >> >> /Filter /FlateDecode >>`,
1741
+ await deflate(latin12(`${t.color} rg BT /${F.name} ${num2(t.size)} Tf ${num2(dx)} 0 Td <${hex2}> Tj ET`))
1742
+ );
1743
+ }
1744
+ const fontDict = [];
1745
+ for (const [key, F] of fonts) {
1746
+ if (F.glyphs.size) {
1747
+ await writeFont(key, F);
1748
+ fontDict.push(`/${F.name} ${F.ref} 0 R`);
1749
+ }
1750
+ }
1751
+ let resDict = `<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << ${fontDict.join(" ")} >>`;
1752
+ for (const [kind2, m] of res) resDict += ` /${kind2} << ${[...m].map(([v, n]) => `/${n} ${v}`).join(" ")} >>`;
1753
+ await writeObj(resRef, resDict + " >>");
1754
+ let level = leaves.map((ref, k) => ({ ref, kids: pageRefs.slice(k * LEAF, Math.min(pages, (k + 1) * LEAF)), count: Math.min(LEAF, pages - k * LEAF) }));
1755
+ while (level.length > 1) {
1756
+ const up = [];
1757
+ for (let k = 0; k < level.length; k += LEAF) {
1758
+ const kids = level.slice(k, k + LEAF);
1759
+ up.push({ ref: reserve(), kids: kids.map((x) => x.ref), count: kids.reduce((s, x) => s + x.count, 0), below: kids });
1760
+ }
1761
+ for (const node2 of up) for (const kid of node2.below) kid.parent = node2.ref;
1762
+ await writeNodes(level);
1763
+ level = /** @type {any} */
1764
+ up;
1765
+ }
1766
+ await writeNodes(level);
1767
+ const pagesRoot = level[0].ref;
1768
+ const outline = await writeOutline(o.outline || []);
1769
+ const catalog = reserve();
1770
+ await writeObj(catalog, `<< /Type /Catalog /Pages ${pagesRoot} 0 R /PageLabels << /Nums [0 << /S /D /St 1 >>] >>${outline ? ` /Outlines ${outline} 0 R /PageMode /UseOutlines` : ""}${o.catalog || ""} >>`);
1771
+ const info = reserve(), I2 = o.info || {};
1772
+ await writeObj(info, `<< /Producer ${pdfText("ReportWright")} /Creator ${pdfText("ReportWright")} /Title ${pdfText(I2.title || "Report")}${I2.author ? ` /Author ${pdfText(I2.author)}` : ""}${I2.subject ? ` /Subject ${pdfText(I2.subject)}` : ""} /CreationDate ${pdfDate(I2.creationDate || /* @__PURE__ */ new Date())} /ModDate ${pdfDate(I2.creationDate || /* @__PURE__ */ new Date())} >>`);
1773
+ for (let n = 1; n < nextNum; n++) if (n >= kind.length || !kind[n]) await writeObj(n, "null");
1774
+ await writeBatch();
1775
+ const xn = reserve(), size2 = nextNum, xref = pos;
1776
+ place(xn, 1, xref);
1777
+ const out = (
1778
+ /** @type {Uint8Array[]} */
1779
+ []
1780
+ );
1781
+ const zs = new Zlib({ level: 6 }, (d) => {
1782
+ out.push(d);
1783
+ });
1784
+ const prev = new Uint8Array(7), row = new Uint8Array(7);
1785
+ for (let from = 0; from < size2; from += 65536) {
1786
+ const to = Math.min(size2, from + 65536), rows = new Uint8Array((to - from) * 8);
1787
+ for (let n = from; n < to; n++) {
1788
+ row.fill(0);
1789
+ const l = loc[n];
1790
+ if (n === 0) {
1791
+ row[5] = 255;
1792
+ row[6] = 255;
1793
+ } else {
1794
+ row[0] = kind[n];
1795
+ row[1] = l >>> 24 & 255;
1796
+ row[2] = l >>> 16 & 255;
1797
+ row[3] = l >>> 8 & 255;
1798
+ row[4] = l & 255;
1799
+ if (kind[n] === 2) {
1800
+ row[5] = idx[n] >> 8;
1801
+ row[6] = idx[n] & 255;
1802
+ }
1803
+ }
1804
+ const at = (n - from) * 8;
1805
+ rows[at] = 2;
1806
+ for (let b = 0; b < 7; b++) {
1807
+ rows[at + 1 + b] = row[b] - prev[b] & 255;
1808
+ prev[b] = row[b];
1809
+ }
1810
+ }
1811
+ zs.push(rows, to === size2);
1812
+ }
1813
+ let zn = 0;
1814
+ for (const c of out) zn += c.length;
1815
+ const z = new Uint8Array(zn);
1816
+ zn = 0;
1817
+ for (const c of out) {
1818
+ z.set(c, zn);
1819
+ zn += c.length;
1820
+ }
1821
+ const id = opt.id || [...globalThis.crypto.getRandomValues(new Uint8Array(16))].map((b) => b.toString(16).padStart(2, "0")).join("");
1822
+ await put(`${xn} 0 obj
1823
+ << /Type /XRef /Size ${size2} /W [1 4 2] /DecodeParms << /Columns 7 /Predictor 12 >> /Root ${catalog} 0 R /Info ${info} 0 R /ID [<${id}> <${id}>] /Filter /FlateDecode /Length ${z.length} >>
1824
+ stream
1825
+ `);
1826
+ await put(z);
1827
+ await put(`
1828
+ endstream
1829
+ endobj
1830
+ startxref
1831
+ ${xref}
1832
+ %%EOF
1833
+ `);
1834
+ await flush();
1835
+ return { pages, bytes: pos };
1836
+ }
1837
+ };
1838
+ async function writeNext() {
1839
+ const { ref, contents, parent, p, z } = (
1840
+ /** @type {any} */
1841
+ inFlight.shift()
1842
+ );
1843
+ await writeObj(contents, "<< /Filter /FlateDecode >>", await z);
1844
+ const annots = [];
1845
+ for (const a of p.annots || []) annots.push(typeof a === "string" ? await w.object(a) : (await writeObj(a.ref, a.dict), a.ref));
1846
+ await writeObj(ref, `<< /Type /Page /Parent ${parent} 0 R /MediaBox [0 0 ${num2(p.width)} ${num2(p.height)}] /Resources ${resRef} 0 R /Contents ${contents} 0 R${annots.length ? ` /Annots [${annots.map((a) => `${a} 0 R`).join(" ")}]` : ""}${p.extra || ""} >>`);
1847
+ }
1848
+ async function writeNodes(nodes) {
1849
+ for (const n of nodes) await writeObj(n.ref, `<< /Type /Pages${n.parent ? ` /Parent ${n.parent} 0 R` : ""} /Kids [${n.kids.map((k) => `${k} 0 R`).join(" ")}] /Count ${n.count} >>`);
1850
+ }
1851
+ async function writeFont(key, F) {
1852
+ if (F.font.standard) {
1853
+ await writeObj(F.ref, standardFontDict(F.font));
1854
+ return;
1855
+ }
1856
+ await loadFontkit();
1857
+ const f = F.font, full = (
1858
+ /** @type {Uint8Array} */
1859
+ fontStore.bytes.get(key)
1860
+ );
1861
+ let bytes = full;
1862
+ if (opt.subset && !f["OS/2"]?.fsType?.noSubsetting) {
1863
+ try {
1864
+ const sub = await opt.subset(full, F.cps, { glyphs: F.glyphs.keys() });
1865
+ const padded = new Uint8Array(sub.length + 16);
1866
+ padded.set(sub);
1867
+ const check = fontkit.create(padded);
1868
+ for (const id of F.glyphs.keys()) void check.getGlyph(id).advanceWidth;
1869
+ bytes = sub;
1870
+ } catch {
1871
+ }
1872
+ }
1873
+ const cff = "CFF " in f.directory.tables || "CFF2" in f.directory.tables;
1874
+ const base = `${bytes === full ? "" : `${subsetTag(bytes)}+`}${String(f.postscriptName || "Font").replace(/[^A-Za-z0-9_.-]/g, "")}`;
1875
+ const k = 1e3 / f.unitsPerEm, s = (v) => String(v * k);
1876
+ const desc = reserve(), file = reserve(), cid = reserve(), cmap = reserve();
1877
+ const fileDict = cff ? "<< /Subtype /OpenType /Filter /FlateDecode >>" : `<< /Length1 ${bytes.length} /Filter /FlateDecode >>`;
1878
+ await writeObj(file, fileDict, await deflate(bytes));
1879
+ const bb = f.bbox, italic = f.italicAngle || 0;
1880
+ const flags = (f.post?.isFixedPitch ? 1 : 0) | 4 | (italic ? 64 : 0);
1881
+ await writeObj(desc, `<< /Type /FontDescriptor /FontName /${base} /Flags ${flags} /FontBBox [${s(bb.minX)} ${s(bb.minY)} ${s(bb.maxX)} ${s(bb.maxY)}] /ItalicAngle ${num2(italic)} /Ascent ${s(f.ascent)} /Descent ${s(f.descent)} /CapHeight ${s(f.capHeight || f.ascent)} /XHeight ${s(f.xHeight || 0)} /StemV 0 /${cff ? "FontFile3" : "FontFile2"} ${file} 0 R >>`);
1882
+ const ids = [...F.glyphs.keys()].sort((a, b) => a - b);
1883
+ let W = "";
1884
+ for (let i = 0; i < ids.length; ) {
1885
+ let j = i;
1886
+ while (j + 1 < ids.length && ids[j + 1] === ids[j] + 1) j++;
1887
+ W += `${ids[i]} [${ids.slice(i, j + 1).map((id) => s(f.getGlyph(id).advanceWidth)).join(" ")}] `;
1888
+ i = j + 1;
1889
+ }
1890
+ await writeObj(cid, `<< /Type /Font /Subtype /${cff ? "CIDFontType0" : "CIDFontType2"} /BaseFont /${base} /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor ${desc} 0 R /W [${W}]${cff ? "" : " /CIDToGIDMap /Identity"} >>`);
1891
+ await writeObj(cmap, "<< /Filter /FlateDecode >>", await deflate(latin12(toUnicode(F.glyphs))));
1892
+ await writeObj(F.ref, `<< /Type /Font /Subtype /Type0 /BaseFont /${base} /Encoding /Identity-H /DescendantFonts [${cid} 0 R] /ToUnicode ${cmap} 0 R >>`);
1893
+ }
1894
+ async function writeOutline(entries) {
1895
+ const root = { ref: 0, level: -1, kids: [] };
1896
+ const stack = [root];
1897
+ for (const e of entries) {
1898
+ if (!(e.page >= 1 && e.page <= pages)) continue;
1899
+ const level = Math.max(0, Math.min(9, Number(e.level) || 0));
1900
+ while (stack[stack.length - 1].level >= level) stack.pop();
1901
+ const node2 = { ref: reserve(), level, kids: [], title: e.title, dest: `[${pageRefs[e.page - 1]} 0 R ${e.top == null ? "/Fit" : `/XYZ null ${num2(e.top)} null`}]` };
1902
+ stack[stack.length - 1].kids.push(node2);
1903
+ stack.push(node2);
1904
+ }
1905
+ if (!root.kids.length) return 0;
1906
+ root.ref = reserve();
1907
+ const count = (n) => n.kids.reduce((t, c) => t + 1 + count(c), 0);
1908
+ const children = (n) => n.kids.length ? ` /First ${n.kids[0].ref} 0 R /Last ${n.kids[n.kids.length - 1].ref} 0 R /Count ${count(n)}` : "";
1909
+ const write = async (n) => {
1910
+ for (let i = 0; i < n.kids.length; i++) {
1911
+ const c = n.kids[i];
1912
+ await writeObj(c.ref, `<< /Title ${pdfText(c.title)} /Parent ${n.ref} 0 R /Dest ${c.dest}${i ? ` /Prev ${n.kids[i - 1].ref} 0 R` : ""}${i < n.kids.length - 1 ? ` /Next ${n.kids[i + 1].ref} 0 R` : ""}${children(c)} >>`);
1913
+ await write(c);
1914
+ }
1915
+ };
1916
+ await write(root);
1917
+ await writeObj(root.ref, `<< /Type /Outlines${children(root)} >>`);
1918
+ return root.ref;
1919
+ }
1920
+ return w;
1921
+ }
1922
+ function toUnicode(glyphs) {
1923
+ const entries = [...glyphs].filter(([, t]) => t).sort((a, b) => a[0] - b[0]);
1924
+ let body = "";
1925
+ for (let i = 0; i < entries.length; i += 100) {
1926
+ const chunk = entries.slice(i, i + 100);
1927
+ body += `${chunk.length} beginbfchar
1928
+ ${chunk.map(([id, t]) => `<${hex42(id)}> <${utf16(t)}>`).join("\n")}
1929
+ endbfchar
1930
+ `;
1931
+ }
1932
+ return `/CIDInit /ProcSet findresource begin
1933
+ 12 dict begin
1934
+ begincmap
1935
+ /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def
1936
+ /CMapName /Adobe-Identity-UCS def
1937
+ /CMapType 2 def
1938
+ 1 begincodespacerange
1939
+ <0000> <ffff>
1940
+ endcodespacerange
1941
+ ${body}endcmap
1942
+ CMapName currentdict /CMap defineresource pop
1943
+ end
1944
+ end
1945
+ `;
1946
+ }
1947
+ var utf16 = (t) => {
1948
+ let h = "";
1949
+ for (let i = 0; i < t.length; i++) h += hex42(t.charCodeAt(i));
1950
+ return h;
1951
+ };
1952
+ var pdfText = (t) => `<feff${utf16(String(t ?? ""))}>`;
1953
+ var pdfDate = (d) => `(D:${d.toISOString().replace(/\D/g, "").slice(0, 14)}+00'00')`;
1954
+ function subsetTag(bytes) {
1955
+ let h = 2166136261;
1956
+ for (let i = 0; i < bytes.length; i++) h = Math.imul(h ^ bytes[i], 16777619);
1957
+ let tag = "";
1958
+ for (let i = 0; i < 6; i++) {
1959
+ tag += String.fromCharCode(65 + (h >>> 0) % 26);
1960
+ h = Math.imul(h ^ i, 16777619) >>> 0;
1961
+ }
1962
+ return tag;
1963
+ }
1964
+ function latin12(s) {
1965
+ const B = (
1966
+ /** @type {any} */
1967
+ globalThis.Buffer
1968
+ );
1969
+ if (B) return B.from(s, "latin1");
1970
+ const out = new Uint8Array(s.length);
1971
+ for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
1972
+ return out;
1973
+ }
1974
+ async function writePagedPdf(plan2, opts, sink) {
1975
+ const { fontStore } = opts;
1976
+ if (opts.pdfa || opts.tagged) await fontStore.load(standIns(fontStore));
1977
+ const w = createPdfStream(sink, { fontStore, subset: opts.subset, id: opts.id, signal: opts.signal });
1978
+ const { info, pages } = (
1979
+ /** @type {any} */
1980
+ plan2
1981
+ );
1982
+ const tags = opts.tagged ? createStreamTagger(w, { maxElements: Number(opts.tagged.maxElements) || Infinity }) : null;
1983
+ const env = paintEnv(w, fontStore, { drillBase: opts.drillBase, tags, embedAll: !!(opts.pdfa || tags) });
1984
+ const { shaped } = env;
1985
+ const pool = !tags && Number(opts.parallel) > 1 ? paintPool(Number(opts.parallel), fontStore, opts, info) : null;
1986
+ let pi = -1;
1987
+ const it = pages(pool ? { run: pool.run, parallel: pool.size } : {})[Symbol.asyncIterator]();
1988
+ let pending = false;
1989
+ try {
1990
+ for (; ; ) {
1991
+ opts.signal?.throwIfAborted();
1992
+ pending = true;
1993
+ const x = await raced(it.next(), opts.signal);
1994
+ pending = false;
1995
+ if (x.done) break;
1996
+ const pg = x.value;
1997
+ pi++;
1998
+ const H = pg.height ?? info.height;
1999
+ if (pg.deflated) {
2000
+ for (const f of pg.embedded || []) env.embedded?.add(f);
2001
+ if (pg.used) {
2002
+ w.take(pg.used);
2003
+ for (const [k, g] of pg.shaped) {
2004
+ const m = env.shapedOf(k);
2005
+ for (const [id, t] of g) if (!m.has(id)) m.set(id, t);
2006
+ }
2007
+ }
2008
+ const annots2 = pg.annots.map((a) => a.replace(/@@P(\d+)@@/g, (_, i) => String(w.pageRef(Number(i)))));
2009
+ await w.addPage({ width: pg.width ?? info.width, height: H, deflated: pg.deflated, annots: annots2 });
2010
+ continue;
2011
+ }
2012
+ const { content, annots } = paintPage(pg, H, env);
2013
+ await w.addPage({ width: pg.width ?? info.width, height: H, content, annots, extra: tags ? await tags.end(w.pageRef(pi)) : void 0 });
2014
+ }
2015
+ } finally {
2016
+ if (pending) it.return?.(void 0)?.catch(() => {
2017
+ });
2018
+ else await it.return?.(void 0);
2019
+ await pool?.close();
2020
+ }
2021
+ for (const [key, g] of shaped) w.addGlyphs(key, g);
2022
+ const seen = /* @__PURE__ */ new Set();
2023
+ const outline = [...info.bookmarks, ...info.headings].map((b, i) => ({ b, i })).sort((p, q) => p.b.page - q.b.page || (p.b.y ?? 0) - (q.b.y ?? 0) || p.i - q.i).map(({ b }) => b).filter((b) => {
2024
+ const k = `${b.page}|${Math.round(b.y ?? 0)}|${b.label}`;
2025
+ if (seen.has(k)) return false;
2026
+ seen.add(k);
2027
+ return true;
2028
+ }).map((b) => ({ title: b.label, page: b.page, top: info.height - b.y + 4, level: b.level }));
2029
+ const title = opts.title || "Report", when = new Date(Math.floor((opts.creationDate || /* @__PURE__ */ new Date()).getTime() / 1e3) * 1e3);
2030
+ let catalog = tags ? await tags.finish({ lang: opts.tagged.lang }) : "";
2031
+ if (opts.pdfa || tags) {
2032
+ const xmp = new TextEncoder().encode(xmpPacket({ title, author: opts.author, stamp: when.toISOString().replace(".000Z", "Z"), pdfa: opts.pdfa ? tags ? "A" : "B" : null, ua: !!tags }));
2033
+ catalog += ` /Metadata ${await w.object("<< /Type /Metadata /Subtype /XML >>", xmp)} 0 R`;
2034
+ }
2035
+ if (opts.pdfa) {
2036
+ const icc = await w.object("<< /N 3 /Filter /FlateDecode >>", await deflate(opts.pdfa.icc));
2037
+ catalog += ` /OutputIntents [${await w.object(`<< /Type /OutputIntent /S /GTS_PDFA1 /OutputConditionIdentifier (sRGB) /Info (sRGB IEC61966-2.1) /DestOutputProfile ${icc} 0 R >>`)} 0 R]`;
2038
+ }
2039
+ const res = await w.finish({ outline, catalog, info: { title, author: opts.author, creationDate: when } });
2040
+ for (const x of env.embedded ? embeddedWarnings(env.embedded) : []) info.warnings.push(x);
2041
+ if (tags && tags.count > TAGGED_LARGE) info.warnings.push(`The tagged PDF has ${tags.count.toLocaleString("en-US")} structure elements (${res.pages.toLocaleString("en-US")} pages): readers open it, but tools that load every object of a file (qpdf, pikepdf) may run out of memory on it. tagged.maxElements caps it.`);
2042
+ return { pages: res.pages, warnings: info.warnings };
2043
+ }
2044
+ var lit = (v) => `(${String(v).replace(/[\\()]/g, "\\$&")})`;
2045
+ function coveredText(items, box) {
2046
+ const lines = [];
2047
+ for (const t of items) if (t.t === "text" && t.lines) {
2048
+ for (const l of t.lines) if (l.text?.trim() && l.x >= box.x && l.x <= box.x + box.w && l.y >= box.y && l.y <= box.y + box.h) lines.push(l);
2049
+ }
2050
+ return lines.sort((a, b) => a.y - b.y || a.x - b.x).map((l) => l.text.trim()).join(" ");
2051
+ }
2052
+ function paintPage(pg, H, env) {
2053
+ if (env.embedded) pg = embeddedPage(pg, env.font, env.embedded);
2054
+ const annots = [];
2055
+ const c = new Content(env.shared);
2056
+ const { tags } = env;
2057
+ if (tags) {
2058
+ c.tagged = true;
2059
+ c.artLines = true;
2060
+ tags.page(pg.win ?? 0);
2061
+ }
2062
+ for (const it of pg.items) {
2063
+ const mark = tags && it.t !== "line" && tags.open(it);
2064
+ const inText = mark && it.t === "text" && !it.rotate && it.lines.every((l) => !l.runs) && !(it.clip && !insideClip(it, env.vmetrics(it.font)));
2065
+ if (inText) {
2066
+ if (!c.bt) {
2067
+ c._s += "BT\n";
2068
+ c.bt = true;
2069
+ c.tx = 0;
2070
+ c.ty = 0;
2071
+ }
2072
+ c._s += mark;
2073
+ } else if (mark) {
2074
+ c.et();
2075
+ c.s += mark;
2076
+ }
2077
+ if (it.t !== "text" && it.t !== "line" || it.rotate) c.et();
2078
+ if (it.rotate) {
2079
+ const t = -it.rotate.a * Math.PI / 180, cs = Math.cos(t), sn = Math.sin(t);
2080
+ const px = it.rotate.cx, py = H - it.rotate.cy;
2081
+ c.q();
2082
+ c.s += `${n4(cs)} ${n4(sn)} ${n4(-sn)} ${n4(cs)} ${n2(px - px * cs + py * sn)} ${n2(py - px * sn - py * cs)} cm
2083
+ `;
2084
+ }
2085
+ switch (it.t) {
2086
+ case "rect": {
2087
+ const fill = col(it.fill), stroke = col(it.stroke);
2088
+ if (!fill && !stroke) break;
2089
+ if (it.radius) throw new Error("rounded boxes do not stream yet");
2090
+ c.paint(fill, stroke, it.strokeWidth || 1, it.dash);
2091
+ const x = n2(it.x), y = n2(H - it.y - it.h), rw = n2(it.w), rh = n2(it.h);
2092
+ c.s += (stroke && it.dash?.length ? `${x} ${y} m ${x} ${n2(y + rh)} l ${n2(x + rw)} ${n2(y + rh)} l ${n2(x + rw)} ${y} l h` : `${x} ${y} ${rw} ${rh} re`) + (fill && stroke ? " B\n" : fill ? " f\n" : " S\n");
2093
+ break;
2094
+ }
2095
+ case "ellipse": {
2096
+ const fill = col(it.fill), stroke = col(it.stroke);
2097
+ if (!fill && !stroke) break;
2098
+ c.paint(fill, stroke, it.strokeWidth || 1, it.dash);
2099
+ const cx = it.cx, cy = H - it.cy, rx = it.rx, ry = it.ry, ox = rx * KAPPA, oy = ry * KAPPA;
2100
+ c.s += `${n2(cx - rx)} ${n2(cy)} m ${n2(cx - rx)} ${n2(cy - oy)} ${n2(cx - ox)} ${n2(cy - ry)} ${n2(cx)} ${n2(cy - ry)} c ${n2(cx + ox)} ${n2(cy - ry)} ${n2(cx + rx)} ${n2(cy - oy)} ${n2(cx + rx)} ${n2(cy)} c ${n2(cx + rx)} ${n2(cy + oy)} ${n2(cx + ox)} ${n2(cy + ry)} ${n2(cx)} ${n2(cy + ry)} c ${n2(cx - ox)} ${n2(cy + ry)} ${n2(cx - rx)} ${n2(cy + oy)} ${n2(cx - rx)} ${n2(cy)} c h ${fill &&
2101
+ stroke ? "B" : fill ? "f" : "S"}
2102
+ `;
2103
+ break;
2104
+ }
2105
+ case "line": {
2106
+ const st = col(it.stroke);
2107
+ if (st) c.line(st, it.strokeWidth || 1, it.dash, it.x1, H - it.y1, it.x2, H - it.y2);
2108
+ break;
2109
+ }
2110
+ case "text": {
2111
+ const color = col(it.color) || BLACK;
2112
+ const clipped = it.clip && !insideClip(it, env.vmetrics(it.font));
2113
+ if (clipped) {
2114
+ c.q();
2115
+ c.s += `${n2(it.clip.x)} ${n2(H - it.clip.y - it.clip.h)} ${n2(it.clip.w)} ${n2(it.clip.h)} re W n
2116
+ `;
2117
+ }
2118
+ for (const l of it.lines) {
2119
+ if (!l.runs) {
2120
+ c.text(env.pf(it.font), it.size, color, l.x, H - l.y, env.literal(it.font, cleanText(l.text)));
2121
+ continue;
2122
+ }
2123
+ for (const r of l.runs) {
2124
+ const g = env.shapedOf(r.font), spans = /* @__PURE__ */ new WeakMap();
2125
+ glyphText(r, env.font(r.font), g, spans);
2126
+ if (r.text.trim()) drawRun(c, r, l.x + r.x, H - l.y, it.size, env.pf(r.font), color, spans.get(r), g);
2127
+ }
2128
+ }
2129
+ if (clipped) c.Q();
2130
+ break;
2131
+ }
2132
+ case "link": {
2133
+ const rect = `[${[it.x, H - it.y - it.h, it.x + it.w, H - it.y].map(n2).join(" ")}]`;
2134
+ const a = it.action;
2135
+ const href = a?.type === "url" && safeUrl(a.href) ? a.href : a?.type === "drill" ? drillUrl(env.drillBase, a) : null;
2136
+ const to = href ? `/A << /Type /Action /S /URI /URI ${lit(asciiUrl(href))} >>` : a?.type === "bookmark" && a.page ? `/Dest [${env.pageRef(a.page - 1)} 0 R /XYZ null ${n2(H - a.y + 4)} null]` : null;
2137
+ if (!to) break;
2138
+ if (!tags) {
2139
+ annots.push(`<< /Type /Annot /Subtype /Link /F 4 /Rect ${rect} /Border [0 0 0] ${to} >>`);
2140
+ break;
2141
+ }
2142
+ const ref = env.reserve(), key = tags.link(it, ref);
2143
+ const say = coveredText(pg.items, it) || it.tip || href || (a.target ? `Go to ${a.target}` : `Go to page ${a.page}`);
2144
+ annots.push({ ref, dict: `<< /Type /Annot /Subtype /Link /F 4 /Rect ${rect} /Border [0 0 0] ${to} /Contents ${pdfText(say)} /StructParent ${key} >>` });
2145
+ break;
2146
+ }
2147
+ default:
2148
+ throw new Error(`A ${it.t} item does not stream yet`);
2149
+ }
2150
+ if (it.rotate) c.Q();
2151
+ if (inText) c._s += "EMC\n";
2152
+ else if (mark) {
2153
+ c.et();
2154
+ c.s += "EMC\n";
2155
+ }
2156
+ }
2157
+ c.et();
2158
+ return { content: c.s, annots };
2159
+ }
2160
+ function paintEnv(w, fontStore, o = {}) {
2161
+ const pfs = /* @__PURE__ */ new Map();
2162
+ const shaped = /* @__PURE__ */ new Map();
2163
+ const vm = /* @__PURE__ */ new Map();
2164
+ return {
2165
+ shared: { font: (f) => w.fontName(f.key), gs: (ca, CA) => w.gs(ca, CA), image: () => {
2166
+ throw new Error("images do not stream yet");
2167
+ } },
2168
+ pf: (key) => {
2169
+ let f = pfs.get(key);
2170
+ if (!f) pfs.set(key, f = { key, embedder: { font: fontStore.get(key) } });
2171
+ return f;
2172
+ },
2173
+ font: (key) => fontStore.get(key),
2174
+ shaped,
2175
+ shapedOf: (key) => {
2176
+ let g = shaped.get(key);
2177
+ if (!g) shaped.set(key, g = /* @__PURE__ */ new Map());
2178
+ return g;
2179
+ },
2180
+ vmetrics: (key) => {
2181
+ let m = vm.get(key);
2182
+ if (!m) {
2183
+ const f = fontStore.get(key), u = f?.unitsPerEm || 1e3;
2184
+ vm.set(key, m = { asc: (f?.ascent ?? u) / u, desc: -(f?.descent ?? 0) / u });
2185
+ }
2186
+ return m;
2187
+ },
2188
+ literal: (key, text) => w.literal(key, text),
2189
+ pageRef: o.pageRef || ((i) => w.pageRef(i)),
2190
+ reserve: () => w.reserve(),
2191
+ drillBase: o.drillBase,
2192
+ tags: o.tags || null,
2193
+ /** PDF/A, PDF/UA: standard fonts drawn in embedded stand-ins; the families that were @type {Set<string>|null} */
2194
+ embedded: o.embedAll ? /* @__PURE__ */ new Set() : null
2195
+ };
2196
+ }
2197
+ function paintPool(size, fontStore, opts, info) {
2198
+ const wt = (
2199
+ /** @type {any} */
2200
+ globalThis.process?.getBuiltinModule?.("node:worker_threads")
2201
+ );
2202
+ if (!wt) return null;
2203
+ let workers = [];
2204
+ let seq = 0, turn = 0;
2205
+ const waiting = /* @__PURE__ */ new Map();
2206
+ const clean = (r) => {
2207
+ if (!r) return r;
2208
+ const { __i, ...o } = r;
2209
+ return o;
2210
+ };
2211
+ const start = async () => {
2212
+ const fonts = [...fontStore.bytes];
2213
+ if (fontStore.shaper) fonts.push(["harfbuzz", await fontStore.loader("harfbuzz")]);
2214
+ workers = Array.from({ length: size }, () => {
2215
+ const w = new wt.Worker(new URL("./pdfstreamworker.js", import.meta.url), { workerData: { fonts } });
2216
+ w.on("message", (m) => {
2217
+ const p = waiting.get(m.id);
2218
+ waiting.delete(m.id);
2219
+ if (m.error) p.fail(Object.assign(new Error(m.error.message), { status: m.error.status, timeout: m.error.timeout }));
2220
+ else p.ok(m);
2221
+ });
2222
+ w.on("error", (e) => {
2223
+ for (const p of waiting.values()) p.fail(e);
2224
+ waiting.clear();
2225
+ });
2226
+ return w;
2227
+ });
2228
+ };
2229
+ let started = null;
2230
+ const pick = ["parameters", "now", "timeZone", "state", "target", "deadline", "timeoutMs"];
2231
+ return {
2232
+ size,
2233
+ /** @param {any} job */
2234
+ async run(job) {
2235
+ await (started || (started = start()));
2236
+ const id = ++seq;
2237
+ const pw = job.pageWindow;
2238
+ const msg = {
2239
+ id,
2240
+ def: job.def,
2241
+ rows: job.rows.map(clean),
2242
+ keep: job.keep,
2243
+ drillBase: opts.drillBase,
2244
+ embedAll: !!opts.pdfa,
2245
+ height: info.height,
2246
+ opts: Object.fromEntries(pick.filter((k) => opts[k] !== void 0).map((k) => [k, opts[k]])),
2247
+ pageWindow: { ...pw, first: clean(pw.first), cont: pw.cont.map((c) => c && { first: clean(c.first), before: c.before }) }
2248
+ };
2249
+ const r = await new Promise((ok, fail) => {
2250
+ waiting.set(id, { ok, fail });
2251
+ workers[turn++ % workers.length].postMessage(msg);
2252
+ });
2253
+ if (r.pages.length) {
2254
+ r.pages[0].used = r.used;
2255
+ r.pages[0].shaped = r.shaped;
2256
+ r.pages[0].embedded = r.embedded;
2257
+ }
2258
+ return r;
2259
+ },
2260
+ async close() {
2261
+ await Promise.all(workers.map((w) => w.terminate()));
2262
+ }
2263
+ };
2264
+ }
2265
+
1072
2266
  // src/exporters/pdf.js
1073
- var fontkit = (
1074
- /** @type {any} */
1075
- fontkitModule.default || fontkitModule
1076
- );
1077
2267
  function exportPdf(model, fontStore, opt = {}) {
1078
2268
  return withDeadline(
1079
2269
  pdfOf(model, fontStore, opt),
@@ -1082,6 +2272,8 @@ function exportPdf(model, fontStore, opt = {}) {
1082
2272
  );
1083
2273
  }
1084
2274
  async function pdfOf(model, fontStore, opt) {
2275
+ if (ownWriterFits(model, opt)) return ownWriter(model, fontStore, opt);
2276
+ await loadPdfLib();
1085
2277
  const fixed = fixedDate(opt);
1086
2278
  const when = fixed ?? /* @__PURE__ */ new Date();
1087
2279
  const fileId = fixed ? await contentId(model, opt, when) : void 0;
@@ -1092,7 +2284,13 @@ async function pdfOf(model, fontStore, opt) {
1092
2284
  doc.setCreator("ReportWright");
1093
2285
  if (opt.author) doc.setAuthor(opt.author);
1094
2286
  setInfoDates(doc, when);
1095
- if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString5.of(fileId), PDFHexString5.of(fileId)]);
2287
+ if (fileId) doc.context.trailerInfo.ID = doc.context.obj([PDFHexString.of(fileId), PDFHexString.of(fileId)]);
2288
+ if (opt.pdfa || opt.tagged || model.pages.some((pg) => pg.items.some((i) => i.t === "field"))) await fontStore.load(standIns(fontStore));
2289
+ if (opt.pdfa || opt.tagged) {
2290
+ const families = /* @__PURE__ */ new Set();
2291
+ model = { ...model, pages: model.pages.map((pg) => embeddedPage(pg, (k) => fontStore.get(k), families)) };
2292
+ for (const w of embeddedWarnings(families)) opt.onWarning?.(w);
2293
+ }
1096
2294
  const used = /* @__PURE__ */ new Map();
1097
2295
  const shaped = /* @__PURE__ */ new Map();
1098
2296
  const spans = /* @__PURE__ */ new WeakMap();
@@ -1133,6 +2331,13 @@ async function pdfOf(model, fontStore, opt) {
1133
2331
  for (const pg of model.pages) for (const it of pg.items) if (it.t === "field") fieldFonts.add(fieldFont(it));
1134
2332
  const fonts = /* @__PURE__ */ new Map();
1135
2333
  const font = async (key) => {
2334
+ if (!fonts.has(key) && isStandard(key)) {
2335
+ const f = fontStore.get(key);
2336
+ fonts.set(key, { ref: doc.context.register(doc.context.obj(
2337
+ /** @type {any} */
2338
+ standardFontEntries(f)
2339
+ )), embedder: { font: f, literalOf: (t) => standardLiteral(f, t), tjOf: () => null } });
2340
+ }
1136
2341
  if (!fonts.has(key)) {
1137
2342
  const full = fontStore.bytes.get(key);
1138
2343
  let bytes = full;
@@ -1149,14 +2354,14 @@ async function pdfOf(model, fontStore, opt) {
1149
2354
  } catch {
1150
2355
  }
1151
2356
  }
1152
- const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag(bytes)}+${fontStore.get(key).postscriptName || "Font"}` });
2357
+ const pf = await doc.embedFont(bytes, { subset: false, customName: bytes === full ? void 0 : `${subsetTag2(bytes)}+${fontStore.get(key).postscriptName || "Font"}` });
1153
2358
  plainEncoding(pf);
1154
2359
  if (glyphs) addGlyphs(pf, glyphs, !!opt.tagged);
1155
2360
  const file = bytes, e = (
1156
2361
  /** @type {any} */
1157
2362
  pf.embedder
1158
2363
  );
1159
- if (!e.isCFF()) e.embedFontStream = async (c) => c.register(PDFRawStream2.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
2364
+ if (!e.isCFF()) e.embedFontStream = async (c) => c.register(PDFRawStream.of(c.obj({ Filter: "FlateDecode", Length1: file.length }), await deflate(file)));
1160
2365
  fonts.set(key, pf);
1161
2366
  }
1162
2367
  return fonts.get(key);
@@ -1197,7 +2402,7 @@ async function pdfOf(model, fontStore, opt) {
1197
2402
  if (!n) {
1198
2403
  n = `${kind[0]}${names.size + 1}`;
1199
2404
  names.set(key, n);
1200
- res.get(PDFName3.of(kind)).set(PDFName3.of(n), value());
2405
+ res.get(PDFName.of(kind)).set(PDFName.of(n), value());
1201
2406
  }
1202
2407
  return n;
1203
2408
  };
@@ -1232,7 +2437,7 @@ async function pdfOf(model, fontStore, opt) {
1232
2437
  const H = pg.height ?? model.height;
1233
2438
  const p = doc.addPage([pg.width ?? model.width, H]);
1234
2439
  p.node.normalize();
1235
- p.node.set(PDFName3.of("Resources"), resRef);
2440
+ p.node.set(PDFName.of("Resources"), resRef);
1236
2441
  const c = new Content(shared);
1237
2442
  if (tags) c.tagged = true;
1238
2443
  p.maybeEmbedGraphicsState = (o) => c.gsFor(o.opacity ?? 1, o.borderOpacity ?? 1);
@@ -1339,7 +2544,7 @@ async function pdfOf(model, fontStore, opt) {
1339
2544
  const form = doc.getForm();
1340
2545
  const f = await font(fieldFont(it));
1341
2546
  const name = uniqueName(it.name);
1342
- const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb3(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb3(1, 1, 1) };
2547
+ const box = { x: it.x, y: H - it.y - it.h, width: it.w, height: it.h, borderColor: rgb(0.61, 0.64, 0.69), borderWidth: 0.75, backgroundColor: rgb(1, 1, 1) };
1343
2548
  let field;
1344
2549
  if (it.kind === "checkbox") {
1345
2550
  field = form.createCheckBox(name);
@@ -1396,7 +2601,8 @@ async function pdfOf(model, fontStore, opt) {
1396
2601
  if (it.required) field.enableRequired();
1397
2602
  if (it.readOnly) field.enableReadOnly();
1398
2603
  if (tags) {
1399
- field.acroField.dict.set(PDFName3.of("TU"), PDFHexString5.fromText(it.label || it.name || name));
2604
+ if (!it.label) opt.onWarning?.(`Form field "${name}" has no label, so a screen reader announces its name; give it a label`);
2605
+ field.acroField.dict.set(PDFName.of("TU"), PDFHexString.fromText(it.label || it.name || name));
1400
2606
  const w = field.acroField.getWidgets()[0];
1401
2607
  const ref2 = w && doc.context.getObjectRef(w.dict);
1402
2608
  if (ref2) tags.annot(pi, ii, ref2, "field");
@@ -1405,7 +2611,7 @@ async function pdfOf(model, fontStore, opt) {
1405
2611
  }
1406
2612
  case "link": {
1407
2613
  const rect = [it.x, H - it.y - it.h, it.x + it.w, H - it.y];
1408
- const text = tags ? coveredText(pg.items, it) : "";
2614
+ const text = tags ? coveredText2(pg.items, it) : "";
1409
2615
  if (it.action?.type === "url" && safeUrl(it.action.href)) links.push({ page: p, rect, href: it.action.href, pi, ii, tip: it.tip, text });
1410
2616
  else if (it.action?.type === "drill") {
1411
2617
  const href = drillUrl(opt.drillBase, it.action);
@@ -1458,24 +2664,24 @@ async function pdfOf(model, fontStore, opt) {
1458
2664
  );
1459
2665
  if (own) ctx.delete(own);
1460
2666
  const ref = ctx.nextRef();
1461
- p.node.set(PDFName3.of("Contents"), ref);
1462
- contents.push(deflate(latin1(c.s)).then((z) => ctx.assign(ref, PDFRawStream2.of(ctx.obj({ Filter: "FlateDecode" }), z))));
2667
+ p.node.set(PDFName.of("Contents"), ref);
2668
+ contents.push(deflate(latin1(c.s)).then((z) => ctx.assign(ref, PDFRawStream.of(ctx.obj({ Filter: "FlateDecode" }), z))));
1463
2669
  if (NODE_ZLIB && contents.length > 8) await contents[contents.length - 9];
1464
2670
  }
1465
2671
  await Promise.all(contents);
1466
2672
  const pageH = (n) => model.pages[n - 1]?.height ?? model.height;
1467
2673
  const pages = doc.getPages();
1468
- const dest = (b) => pages[b.page - 1] && [pages[b.page - 1].ref, PDFName3.of("XYZ"), null, pageH(b.page) - b.y + 4, null];
2674
+ const dest = (b) => pages[b.page - 1] && [pages[b.page - 1].ref, PDFName.of("XYZ"), null, pageH(b.page) - b.y + 4, null];
1469
2675
  for (const l of links) {
1470
2676
  const to = l.href ? { A: { Type: "Action", S: "URI", URI: pdfLiteral(asciiUrl(l.href)) } } : { Dest: dest(l.to) };
1471
2677
  if (!l.href && !to.Dest) continue;
1472
2678
  const annot = doc.context.obj({ Type: "Annot", Subtype: "Link", F: 4, Rect: l.rect, Border: [0, 0, 0], ...to });
1473
- if (tags) annot.set(PDFName3.of("Contents"), PDFHexString5.fromText(String(l.text || l.tip || l.href || "Link")));
2679
+ if (tags) annot.set(PDFName.of("Contents"), PDFHexString.fromText(String(l.text || l.tip || l.href || "Link")));
1474
2680
  const ref = doc.context.register(annot);
1475
2681
  if (tags) tags.annot(l.pi, l.ii, ref, "link");
1476
- const annots = l.page.node.lookup(PDFName3.of("Annots"));
2682
+ const annots = l.page.node.lookup(PDFName.of("Annots"));
1477
2683
  if (annots) annots.push(ref);
1478
- else l.page.node.set(PDFName3.of("Annots"), doc.context.obj([ref]));
2684
+ else l.page.node.set(PDFName.of("Annots"), doc.context.obj([ref]));
1479
2685
  }
1480
2686
  const marks = outlineEntries(model);
1481
2687
  if (marks.length) addOutline(doc, marks, dest);
@@ -1492,7 +2698,44 @@ async function pdfOf(model, fontStore, opt) {
1492
2698
  }
1493
2699
  return doc.save({ updateFieldAppearances: false, ...opt.save || {} });
1494
2700
  }
1495
- function coveredText(items, box) {
2701
+ function ownWriterFits(model, opt) {
2702
+ if (opt.pdfa || opt.tagged || opt.encrypt || opt.prepare || opt.save || !model.pages.length) return false;
2703
+ if ((model.pageStarts || []).some((i) => i > 0)) return false;
2704
+ for (const pg of model.pages) {
2705
+ if ((pg.height ?? model.height) !== model.height) return false;
2706
+ for (const it of pg.items) {
2707
+ if (it.t === "text") {
2708
+ if (!isStandard(it.font) || it.lines.some((l) => l.runs)) return false;
2709
+ } else if (it.t === "link") {
2710
+ const a = it.action;
2711
+ if (a?.type === "bookmark" && !(a.page >= 1 && a.page <= model.pages.length)) return false;
2712
+ } else if (!(it.t === "line" || it.t === "ellipse" || it.t === "rect" && !it.radius)) return false;
2713
+ }
2714
+ }
2715
+ return true;
2716
+ }
2717
+ async function ownWriter(model, fontStore, opt) {
2718
+ const fixed = fixedDate(opt), when = fixed ?? /* @__PURE__ */ new Date();
2719
+ const parts = [];
2720
+ const info = { width: model.width, height: model.height, bookmarks: model.bookmarks || [], headings: model.headings || [], warnings: [] };
2721
+ await writePagedPdf(
2722
+ { info, pages: async function* () {
2723
+ yield* model.pages;
2724
+ } },
2725
+ { fontStore, subset: opt.subset, id: fixed ? await contentId(model, opt, when) : void 0, title: opt.title, author: opt.author, creationDate: when, drillBase: opt.drillBase },
2726
+ { write: (u8) => {
2727
+ parts.push(u8);
2728
+ } }
2729
+ );
2730
+ const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
2731
+ let at = 0;
2732
+ for (const p of parts) {
2733
+ out.set(p, at);
2734
+ at += p.length;
2735
+ }
2736
+ return out;
2737
+ }
2738
+ function coveredText2(items, box) {
1496
2739
  const lines = [];
1497
2740
  for (const t of items) if (t.t === "text" && t.lines) {
1498
2741
  for (const l of t.lines) if (l.text?.trim() && l.x >= box.x && l.x <= box.x + box.w && l.y >= box.y && l.y <= box.y + box.h) lines.push(l);
@@ -1514,11 +2757,11 @@ async function contentId(model, opt, when) {
1514
2757
  }
1515
2758
  function fieldFont(it) {
1516
2759
  for (const d of it.draw) if (d.t === "text") {
1517
- for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return r.font;
2760
+ for (const l of d.lines) for (const r of l.runs || []) if (r.font !== it.font && r.text.trim()) return embeddedFace(r.font);
1518
2761
  }
1519
- return it.font;
2762
+ return embeddedFace(it.font);
1520
2763
  }
1521
- var pdfLiteral = (s) => PDFString4.of(String(s).replace(/[\\()]/g, "\\$&"));
2764
+ var pdfLiteral = (s) => PDFString.of(String(s).replace(/[\\()]/g, "\\$&"));
1522
2765
  function plainEncoding(pf) {
1523
2766
  const e = pf.embedder, f = e.font, memo = /* @__PURE__ */ new Map();
1524
2767
  e.hexOf = (text) => {
@@ -1534,7 +2777,7 @@ function plainEncoding(pf) {
1534
2777
  }
1535
2778
  return hex2;
1536
2779
  };
1537
- e.encodeText = (text) => PDFHexString5.of(e.hexOf(text));
2780
+ e.encodeText = (text) => PDFHexString.of(e.hexOf(text));
1538
2781
  e.widthOfTextAtSize = (text, size) => {
1539
2782
  let w = 0;
1540
2783
  for (const ch of text) w += f.glyphForCodePoint(
@@ -1543,8 +2786,8 @@ function plainEncoding(pf) {
1543
2786
  ).advanceWidth || 0;
1544
2787
  return w * size / f.unitsPerEm;
1545
2788
  };
1546
- const lit = /* @__PURE__ */ new Map();
1547
- const esc = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
2789
+ const lit2 = /* @__PURE__ */ new Map();
2790
+ const esc3 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
1548
2791
  e.tjOf = (text) => {
1549
2792
  let out = "", cur = "", any = false;
1550
2793
  for (const ch of text) {
@@ -1570,10 +2813,10 @@ function plainEncoding(pf) {
1570
2813
  /** @type {number} */
1571
2814
  ch.codePointAt(0)
1572
2815
  );
1573
- let b = lit.get(cp);
2816
+ let b = lit2.get(cp);
1574
2817
  if (b === void 0) {
1575
2818
  const id = f.glyphForCodePoint(cp).id;
1576
- lit.set(cp, b = esc(id >> 8) + esc(id & 255));
2819
+ lit2.set(cp, b = esc3(id >> 8) + esc3(id & 255));
1577
2820
  }
1578
2821
  out += b;
1579
2822
  }
@@ -1611,7 +2854,7 @@ function pageLabels(doc, model) {
1611
2854
  const starts = [.../* @__PURE__ */ new Set([0, ...model.pageStarts || []])].filter((i) => i >= 0 && i < n).sort((a, b) => a - b);
1612
2855
  const ctx = doc.context;
1613
2856
  const nums = starts.flatMap((i) => [i, ctx.obj({ S: "D", St: 1 })]);
1614
- doc.catalog.set(PDFName3.of("PageLabels"), ctx.obj({ Nums: nums }));
2857
+ doc.catalog.set(PDFName.of("PageLabels"), ctx.obj({ Nums: nums }));
1615
2858
  }
1616
2859
  function addOutline(doc, bookmarks, dest) {
1617
2860
  const ctx = doc.context;
@@ -1625,7 +2868,7 @@ function addOutline(doc, bookmarks, dest) {
1625
2868
  if (!Dest) continue;
1626
2869
  const level = Math.max(0, Math.min(9, Number(b.level) || 0));
1627
2870
  while (stack[stack.length - 1].level >= level) stack.pop();
1628
- const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString5.fromText(b.label), Dest };
2871
+ const node2 = { ref: ctx.nextRef(), level, kids: [], Title: PDFHexString.fromText(b.label), Dest };
1629
2872
  stack[stack.length - 1].kids.push(node2);
1630
2873
  stack.push(node2);
1631
2874
  }
@@ -1638,15 +2881,15 @@ function addOutline(doc, bookmarks, dest) {
1638
2881
  });
1639
2882
  write(root);
1640
2883
  ctx.assign(root.ref, ctx.obj({ Type: "Outlines", ...children(root) }));
1641
- doc.catalog.set(PDFName3.of("Outlines"), root.ref);
1642
- doc.catalog.set(PDFName3.of("PageMode"), PDFName3.of("UseOutlines"));
2884
+ doc.catalog.set(PDFName.of("Outlines"), root.ref);
2885
+ doc.catalog.set(PDFName.of("PageMode"), PDFName.of("UseOutlines"));
1643
2886
  }
1644
2887
  function withPadding(font) {
1645
2888
  const out = new Uint8Array(font.length + 16);
1646
2889
  out.set(font);
1647
2890
  return out;
1648
2891
  }
1649
- function subsetTag(bytes) {
2892
+ function subsetTag2(bytes) {
1650
2893
  let h = 2166136261;
1651
2894
  for (let i = 0; i < bytes.length; i++) h = Math.imul(h ^ bytes[i], 16777619);
1652
2895
  let tag = "";
@@ -1663,4 +2906,4 @@ function roundRect(x, y, w, h, r) {
1663
2906
  export {
1664
2907
  exportPdf
1665
2908
  };
1666
- //# sourceMappingURL=chunk-KBT6ZGGO.js.map
2909
+ //# sourceMappingURL=chunk-VZHHNQYB.js.map