@embedpdf/engine-core 3.0.0-next.15 → 3.0.0-next.16

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 (91) hide show
  1. package/dist/{AnnotationList-CkijRHet.d.cts → AnnotationList-DcyhF2kU.d.cts} +1836 -1308
  2. package/dist/{AnnotationList-CkijRHet.d.ts → AnnotationList-DcyhF2kU.d.ts} +1836 -1308
  3. package/dist/{Change-CjImsrN0.cjs → Change-Ct-dB8D5.cjs} +115 -2
  4. package/dist/Change-Ct-dB8D5.cjs.map +1 -0
  5. package/dist/{Change-CKoxfTNY.js → Change-tMR34hTU.js} +92 -3
  6. package/dist/Change-tMR34hTU.js.map +1 -0
  7. package/dist/{DocumentRenderService-BfFdFSwI.cjs → DocumentRenderService-9IjSQEIU.cjs} +2 -1
  8. package/dist/{DocumentRenderService-BfFdFSwI.cjs.map → DocumentRenderService-9IjSQEIU.cjs.map} +1 -1
  9. package/dist/{DocumentRenderService-DV3J9lMz.js → DocumentRenderService-DFrZ9wfW.js} +2 -1
  10. package/dist/{DocumentRenderService-DV3J9lMz.js.map → DocumentRenderService-DFrZ9wfW.js.map} +1 -1
  11. package/dist/{DocumentSecurityService-e6vp2de8.d.cts → DocumentSecurityService-D2zA4NKi.d.cts} +2 -2
  12. package/dist/{DocumentSecurityService-CU1M6Q7m.d.ts → DocumentSecurityService-YJV9df8P.d.ts} +2 -2
  13. package/dist/{LocalEngine-DFoBm4B3.d.cts → LocalEngine-DBt2-GWF.d.ts} +102 -18
  14. package/dist/{LocalEngine-DPriFujS.d.ts → LocalEngine-IA9zh3Jh.d.cts} +102 -18
  15. package/dist/{authority-DLMNR7ff.cjs → authority-BFp6XM04.cjs} +373 -52
  16. package/dist/authority-BFp6XM04.cjs.map +1 -0
  17. package/dist/{authority-B3BklsB4.js → authority-PuxpGFhJ.js} +320 -53
  18. package/dist/authority-PuxpGFhJ.js.map +1 -0
  19. package/dist/{builders-CNj0POeY.js → builders-DV62HA3I.js} +6 -2
  20. package/dist/builders-DV62HA3I.js.map +1 -0
  21. package/dist/{builders-Cgdp_YCn.cjs → builders-DgTAj_tP.cjs} +6 -2
  22. package/dist/builders-DgTAj_tP.cjs.map +1 -0
  23. package/dist/{calibrate-DJBXnhLE.cjs → calibrate-DJbi1wuK.cjs} +118 -25
  24. package/dist/calibrate-DJbi1wuK.cjs.map +1 -0
  25. package/dist/{calibrate-7T3fnP8-.js → calibrate-nQFgCuki.js} +83 -26
  26. package/dist/calibrate-nQFgCuki.js.map +1 -0
  27. package/dist/charmap-Cprti1ta.js.map +1 -1
  28. package/dist/charmap-aYlefQP9.cjs.map +1 -1
  29. package/dist/conformance.cjs +1744 -75
  30. package/dist/conformance.cjs.map +1 -1
  31. package/dist/conformance.d.cts +105 -10
  32. package/dist/conformance.d.ts +105 -10
  33. package/dist/conformance.js +1738 -76
  34. package/dist/conformance.js.map +1 -1
  35. package/dist/index.cjs +25 -6
  36. package/dist/index.d.cts +2 -2
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +7 -7
  39. package/dist/public.cjs +6 -4
  40. package/dist/public.d.cts +5 -5
  41. package/dist/public.d.ts +5 -5
  42. package/dist/public.js +5 -5
  43. package/dist/{resolver-CzxmD9Ck.js → resolver-BBggAxQc.js} +6 -3
  44. package/dist/resolver-BBggAxQc.js.map +1 -0
  45. package/dist/{resolver-D2OCtE8F.cjs → resolver-BWSWSF6R.cjs} +6 -3
  46. package/dist/resolver-BWSWSF6R.cjs.map +1 -0
  47. package/dist/{runtime-Cl0v56mm.d.ts → runtime-BaDKjxiu.d.ts} +67 -140
  48. package/dist/{runtime-p1WDzDo4.d.cts → runtime-CWEuiwbk.d.cts} +67 -140
  49. package/dist/runtime.cjs +267 -7
  50. package/dist/runtime.cjs.map +1 -1
  51. package/dist/runtime.d.cts +5 -5
  52. package/dist/runtime.d.ts +5 -5
  53. package/dist/runtime.js +246 -8
  54. package/dist/runtime.js.map +1 -1
  55. package/dist/{schema-DzlUNk38.js → schema-6S2VmlAj.js} +8 -2
  56. package/dist/schema-6S2VmlAj.js.map +1 -0
  57. package/dist/{schema-C-gU4vj7.cjs → schema-miH6tWQC.cjs} +13 -1
  58. package/dist/schema-miH6tWQC.cjs.map +1 -0
  59. package/dist/{schemas-D6xOGjqg.js → schemas-BE2QGOit.js} +256 -59
  60. package/dist/schemas-BE2QGOit.js.map +1 -0
  61. package/dist/{schemas-Berf1swF.cjs → schemas-DljJR9ut.cjs} +397 -80
  62. package/dist/schemas-DljJR9ut.cjs.map +1 -0
  63. package/dist/validation.cjs +1 -1
  64. package/dist/validation.d.cts +1 -1
  65. package/dist/validation.d.ts +1 -1
  66. package/dist/validation.js +1 -1
  67. package/dist/{viewport-DlL5Bxbg.cjs → viewport-CHG9qQUb.cjs} +2 -2
  68. package/dist/{viewport-DlL5Bxbg.cjs.map → viewport-CHG9qQUb.cjs.map} +1 -1
  69. package/dist/{viewport-BJW13EGZ.js → viewport-DQR5LyX3.js} +2 -2
  70. package/dist/{viewport-BJW13EGZ.js.map → viewport-DQR5LyX3.js.map} +1 -1
  71. package/dist/wire.cjs +225 -57
  72. package/dist/wire.cjs.map +1 -1
  73. package/dist/wire.d.cts +3548 -1151
  74. package/dist/wire.d.ts +3548 -1151
  75. package/dist/wire.js +198 -53
  76. package/dist/wire.js.map +1 -1
  77. package/package.json +1 -1
  78. package/dist/Change-CKoxfTNY.js.map +0 -1
  79. package/dist/Change-CjImsrN0.cjs.map +0 -1
  80. package/dist/authority-B3BklsB4.js.map +0 -1
  81. package/dist/authority-DLMNR7ff.cjs.map +0 -1
  82. package/dist/builders-CNj0POeY.js.map +0 -1
  83. package/dist/builders-Cgdp_YCn.cjs.map +0 -1
  84. package/dist/calibrate-7T3fnP8-.js.map +0 -1
  85. package/dist/calibrate-DJBXnhLE.cjs.map +0 -1
  86. package/dist/resolver-CzxmD9Ck.js.map +0 -1
  87. package/dist/resolver-D2OCtE8F.cjs.map +0 -1
  88. package/dist/schema-C-gU4vj7.cjs.map +0 -1
  89. package/dist/schema-DzlUNk38.js.map +0 -1
  90. package/dist/schemas-Berf1swF.cjs.map +0 -1
  91. package/dist/schemas-D6xOGjqg.js.map +0 -1
@@ -1,9 +1,9 @@
1
+ const require_calibrate = require("./calibrate-DJbi1wuK.cjs");
1
2
  const require_value = require("./value-BFS1R8ek.cjs");
2
3
  const require_resolveAnnotationDraft = require("./resolveAnnotationDraft-7Ke4nV7F.cjs");
3
4
  const require_format = require("./format-Bp3QFSH1.cjs");
4
- const require_calibrate = require("./calibrate-DJBXnhLE.cjs");
5
- const require_resolver = require("./resolver-D2OCtE8F.cjs");
6
- const require_viewport = require("./viewport-DlL5Bxbg.cjs");
5
+ const require_resolver = require("./resolver-BWSWSF6R.cjs");
6
+ const require_viewport = require("./viewport-CHG9qQUb.cjs");
7
7
  //#region src/geometry/pageBoxes.ts
8
8
  /** The media box of a page that has none, which the file needs: US Letter. */
9
9
  const DEFAULT_MEDIA_BOX = {
@@ -69,6 +69,40 @@ function resolvePageLayers(options, may) {
69
69
  includeFormFields: includeFormFields ?? (includeAnnotations === false ? false : may.formFields)
70
70
  };
71
71
  }
72
+ /**
73
+ * Check what a render is for. A print picture (`usage: 'print'`) takes a
74
+ * `{ kind: 'dpi', dpi }` viewport with a DPI of 150 or 300, and no `target`,
75
+ * `rotation` or `background`: it is the whole page, upright, on white. A
76
+ * `dpi` viewport is for print pictures only. Anything else is `InvalidArg`,
77
+ * naming the option. With the caller's rights, a print they may not make is
78
+ * refused (`PermissionDenied`): any print without `doc.print`, 300 DPI
79
+ * without `doc.print.high`. Without them (a cloud caller whose rights the
80
+ * client can't know), the server decides.
81
+ */
82
+ function checkRenderUsage(options, may) {
83
+ const { usage, viewport } = options ?? {};
84
+ if (usage === void 0 || usage === "display") {
85
+ if (viewport?.kind === "dpi") invalid("viewport", "a dpi viewport is only for a print picture (usage: \"print\")");
86
+ return;
87
+ }
88
+ if (usage !== "print") invalid("usage", "usage must be \"display\" or \"print\"");
89
+ if (viewport?.kind !== "dpi" || viewport.dpi !== 150 && viewport.dpi !== 300) invalid("viewport", "a print picture needs viewport: { kind: 'dpi', dpi: 150 or 300 }");
90
+ for (const field of [
91
+ "target",
92
+ "rotation",
93
+ "background"
94
+ ]) if (options?.[field] !== void 0) invalid(field, `a print picture takes no ${field}: it is the whole page, upright, on white`);
95
+ if (may === null) return;
96
+ if (!may.print) throw new require_resolver.PermissionDenied("doc.print", "usage");
97
+ if (viewport.dpi === 300 && !may.printHigh) throw new require_resolver.PermissionDenied("doc.print.high", "viewport");
98
+ }
99
+ /** A print picture's DPI: its viewport's, when it is one; otherwise `undefined`. */
100
+ function printDpiOf(options) {
101
+ return options?.usage === "print" && options.viewport?.kind === "dpi" ? options.viewport.dpi : void 0;
102
+ }
103
+ function invalid(field, message) {
104
+ throw new require_format.EngineError(require_format.EngineErrorCode.InvalidArg, message, { details: { field } });
105
+ }
72
106
  /** `InvalidArg` unless `quality` is absent or between 0 and 1. */
73
107
  function checkImageQuality(quality) {
74
108
  if (quality === void 0 || quality >= 0 && quality <= 1) return;
@@ -116,6 +150,30 @@ function imageSourceOf(blobSource) {
116
150
  };
117
151
  }
118
152
  //#endregion
153
+ //#region src/dto/PageExtract.ts
154
+ /**
155
+ * What `pages.extract()` makes: `null` for a plain copy, else what the
156
+ * flattened copy paints. A plain copy needs `doc.download`; a flattened one
157
+ * `doc.download` or `doc.download.flattened`, and paints only what the caller
158
+ * may read, with the defaults of a page picture (`resolvePageLayers`). The
159
+ * include options belong to `flatten`: given without it, they're refused.
160
+ */
161
+ function resolvePageExtract(options, may) {
162
+ const flatten = options?.flatten;
163
+ if (flatten === void 0) {
164
+ for (const field of ["includeAnnotations", "includeFormFields"]) if (options?.[field] !== void 0) throw new require_format.EngineError(require_format.EngineErrorCode.InvalidArg, `${field} takes flatten`, { details: { field } });
165
+ if (!may.download) throw new require_resolver.PermissionDenied("doc.download");
166
+ return null;
167
+ }
168
+ const usage = flatten.usage ?? "display";
169
+ if (usage !== "display" && usage !== "print") throw new require_format.EngineError(require_format.EngineErrorCode.InvalidArg, "usage must be \"display\" or \"print\"", { details: { field: "flatten.usage" } });
170
+ if (!may.download && !may.downloadFlattened) throw new require_resolver.PermissionDenied("doc.download", "flatten", ["doc.download", "doc.download.flattened"]);
171
+ return {
172
+ usage,
173
+ ...resolvePageLayers(options, may)
174
+ };
175
+ }
176
+ //#endregion
119
177
  //#region src/dto/PdfSaveMode.ts
120
178
  const DEFAULT_PDF_SAVE_MODE = "incremental";
121
179
  //#endregion
@@ -464,6 +522,50 @@ function pageFormSnapshotOf(snapshot, boxOf) {
464
522
  };
465
523
  }
466
524
  //#endregion
525
+ //#region src/pageSpace/outline.ts
526
+ /**
527
+ * The outline between the file's coordinates and page space: only the
528
+ * destinations an item goes to change, each measured on the page it goes to.
529
+ */
530
+ /** An item, its target's and its action's destinations converted. */
531
+ function mapOutlineItem(item, convert) {
532
+ return {
533
+ ...item,
534
+ target: item.target && require_calibrate.mapLinkTarget(item.target, convert),
535
+ action: item.action && require_calibrate.mapActionTree(item.action, convert)
536
+ };
537
+ }
538
+ /** A draft or a patch, its target's destination converted. */
539
+ function mapOutlineWrite(write, convert) {
540
+ const { target, ...rest } = write;
541
+ if (target === void 0) return rest;
542
+ return {
543
+ ...rest,
544
+ target: target && target.kind === "goto" ? {
545
+ ...target,
546
+ destination: convert(target.destination)
547
+ } : target
548
+ };
549
+ }
550
+ /** The outline as a read hands it out: every destination in page space. */
551
+ function pageOutlineOf(outline, boxOf) {
552
+ return {
553
+ ...outline,
554
+ items: outline.items.map((item) => pageOutlineItemOf(item, boxOf))
555
+ };
556
+ }
557
+ function pageOutlineItemOf(item, boxOf) {
558
+ return mapOutlineItem(item, (destination) => require_calibrate.pageDestinationOf(destination, boxOf));
559
+ }
560
+ /** A draft in the file's coordinates, as the engine writes it. */
561
+ function pdfOutlineDraftOf(draft, boxOf) {
562
+ return mapOutlineWrite(draft, (destination) => require_calibrate.pdfDestinationOf(destination, boxOf));
563
+ }
564
+ /** A patch in the file's coordinates, as the engine writes it. */
565
+ function pdfOutlinePatchOf(patch, boxOf) {
566
+ return mapOutlineWrite(patch, (destination) => require_calibrate.pdfDestinationOf(destination, boxOf));
567
+ }
568
+ //#endregion
467
569
  //#region src/forms/draft.ts
468
570
  /**
469
571
  * Whether creating a field from `draft` takes `doc.forms.script`: a script
@@ -1090,7 +1192,7 @@ function indexRoles(s) {
1090
1192
  sigFields
1091
1193
  };
1092
1194
  }
1093
- function edgeKey(e) {
1195
+ function edgeKey$1(e) {
1094
1196
  return `${e.parent}:${e.label}`;
1095
1197
  }
1096
1198
  var StepContext = class {
@@ -1116,7 +1218,7 @@ var StepContext = class {
1116
1218
  }
1117
1219
  claimEdge(c, side, edge, rule, allow = true) {
1118
1220
  if (this.locked.has(c.objectNumber)) return;
1119
- const key = `${c.objectNumber}:${side}:${edgeKey(edge)}`;
1221
+ const key = `${c.objectNumber}:${side}:${edgeKey$1(edge)}`;
1120
1222
  if (!this.claims.has(key)) this.claims.set(key, {
1121
1223
  rule,
1122
1224
  allow
@@ -1132,17 +1234,17 @@ var StepContext = class {
1132
1234
  * anything hang off it.
1133
1235
  */
1134
1236
  claimStable(c, rule, allow = true) {
1135
- const oldKeys = new Set(c.usage.old.map(edgeKey));
1136
- const newKeys = new Set(c.usage.new.map(edgeKey));
1137
- for (const e of c.usage.old) if (newKeys.has(edgeKey(e))) this.claimEdge(c, "old", e, rule, allow);
1138
- for (const e of c.usage.new) if (oldKeys.has(edgeKey(e))) this.claimEdge(c, "new", e, rule, allow);
1237
+ const oldKeys = new Set(c.usage.old.map(edgeKey$1));
1238
+ const newKeys = new Set(c.usage.new.map(edgeKey$1));
1239
+ for (const e of c.usage.old) if (newKeys.has(edgeKey$1(e))) this.claimEdge(c, "old", e, rule, allow);
1240
+ for (const e of c.usage.new) if (oldKeys.has(edgeKey$1(e))) this.claimEdge(c, "new", e, rule, allow);
1139
1241
  }
1140
1242
  isClaimed(c, side, edge) {
1141
- return this.claims.has(`${c.objectNumber}:${side}:${edgeKey(edge)}`);
1243
+ return this.claims.has(`${c.objectNumber}:${side}:${edgeKey$1(edge)}`);
1142
1244
  }
1143
1245
  /** The use was inspected by a rule that allowed it. */
1144
1246
  isAllowed(c, side, edge) {
1145
- return this.claims.get(`${c.objectNumber}:${side}:${edgeKey(edge)}`)?.allow === true;
1247
+ return this.claims.get(`${c.objectNumber}:${side}:${edgeKey$1(edge)}`)?.allow === true;
1146
1248
  }
1147
1249
  permitted(c, rule, detail) {
1148
1250
  if (this.locked.has(c.objectNumber)) return;
@@ -1163,7 +1265,7 @@ var StepContext = class {
1163
1265
  rule,
1164
1266
  verdict: c.value.truncated ? "incomplete" : "forbidden",
1165
1267
  objectNumber: c.objectNumber,
1166
- edge: edge ? edgeKey(edge) : void 0,
1268
+ edge: edge ? edgeKey$1(edge) : void 0,
1167
1269
  detail: c.value.truncated ? `${detail} (judged on missing evidence: not proven)` : detail
1168
1270
  });
1169
1271
  }
@@ -1758,6 +1860,11 @@ const DEFAULT_EDGE_RESOLVER_BUDGET = {
1758
1860
  };
1759
1861
  const USAGE_INCOMPLETE = "incomplete";
1760
1862
  /**
1863
+ * The label segment that stands for a route between two members of a loop.
1864
+ * Fork labels are ASCII (keys are `#`-escaped), so it is never a key.
1865
+ */
1866
+ const LOOP_ROUTE = "…";
1867
+ /**
1761
1868
  * Resolves the raw inbound edges of an object (from the fork's referrer
1762
1869
  * index, which covers every reachable object of a revision) into edges
1763
1870
  * from *anchors*: the changed objects and the structural objects of the
@@ -1767,68 +1874,222 @@ const USAGE_INCOMPLETE = "incomplete";
1767
1874
  * appearance stream under an unchanged indirect `/AP` dictionary reads
1768
1875
  * `widget:AP/N` rather than `apDict:N`.
1769
1876
  *
1770
- * A graph traversal, not a path enumeration: results are memoised per
1771
- * object, so a lattice of shared unchanged objects costs its size, not the
1772
- * number of paths through it. Cycle edges contribute no anchors and are
1773
- * skipped; a result computed while skipping one is not memoised.
1877
+ * A graph traversal, not a path enumeration. The unchanged objects above
1878
+ * an object are read once each and split into strongly connected
1879
+ * components (loops: a structure tree, whose elements point at their
1880
+ * parent with `/P` and at their children with `/K`; an outline, whose
1881
+ * items point at their neighbours; an annotation and its popup), resolved
1882
+ * ancestors first and memoised per object, so a lattice of shared objects
1883
+ * costs its size, not the number of paths through it.
1884
+ *
1885
+ * Every member of a loop reaches every other one, so an edge into a loop
1886
+ * reaches all its members: as it is at the member it enters, and as
1887
+ * `<label>/…` at every other one, the route between them collapsed. The
1888
+ * route consists of unchanged objects, the same in both revisions, so it
1889
+ * carries no evidence; the anchor, the way in and the way out (the labels
1890
+ * either side of `…`) do, and they are kept. Edges whose label collapses
1891
+ * a route are told apart by anchor and label alone.
1774
1892
  */
1775
1893
  var EdgeResolver = class {
1776
1894
  constructor(read, anchors, budget = DEFAULT_EDGE_RESOLVER_BUDGET) {
1777
1895
  this.read = read;
1778
1896
  this.anchors = anchors;
1779
1897
  this.budget = budget;
1780
- require_format._defineProperty(this, "memo", /* @__PURE__ */ new Map());
1898
+ require_format._defineProperty(this, "referrers", /* @__PURE__ */ new Map());
1899
+ require_format._defineProperty(this, "resolved", /* @__PURE__ */ new Map());
1781
1900
  require_format._defineProperty(this, "reads", 0);
1782
1901
  require_format._defineProperty(this, "exhausted", false);
1783
1902
  }
1784
1903
  /** Anchored edges of `objectNumber`, or `incomplete` when a budget was exceeded. */
1785
1904
  resolve(objectNumber) {
1786
- if (this.exhausted) return USAGE_INCOMPLETE;
1787
- const result = this.resolveInner(objectNumber, /* @__PURE__ */ new Set());
1788
- return result === null ? USAGE_INCOMPLETE : result.edges;
1789
- }
1790
- resolveInner(n, active) {
1791
- const hit = this.memo.get(n);
1792
- if (hit) return hit;
1793
- if (active.size >= this.budget.maxDepth) return null;
1794
- if (this.reads >= this.budget.maxReads) {
1905
+ if (!this.resolved.has(objectNumber)) {
1906
+ const components = this.componentsAbove(objectNumber);
1907
+ for (const component of components ?? []) if (!this.resolveComponent(component)) break;
1908
+ }
1909
+ return this.resolved.get(objectNumber) ?? "incomplete";
1910
+ }
1911
+ readReferrers(n) {
1912
+ const known = this.referrers.get(n);
1913
+ if (known) return known;
1914
+ if (this.exhausted || this.reads >= this.budget.maxReads) {
1795
1915
  this.exhausted = true;
1796
1916
  return null;
1797
1917
  }
1798
1918
  this.reads += 1;
1799
1919
  const raw = this.read(n);
1800
- active.add(n);
1920
+ this.referrers.set(n, raw);
1921
+ return raw;
1922
+ }
1923
+ /** The parents of an object still to be resolved: unchanged, non-structural, not resolved yet. */
1924
+ pendingParents(raw) {
1925
+ const out = /* @__PURE__ */ new Set();
1926
+ for (const e of raw) if (!this.anchors.has(e.parent) && !this.resolved.has(e.parent)) out.add(e.parent);
1927
+ return [...out];
1928
+ }
1929
+ /**
1930
+ * The strongly connected components of the unresolved objects above
1931
+ * `start` (Tarjan's algorithm, iterative), ancestors first; null when the
1932
+ * read budget ran out.
1933
+ */
1934
+ componentsAbove(start) {
1935
+ const index = /* @__PURE__ */ new Map();
1936
+ const low = /* @__PURE__ */ new Map();
1937
+ const stack = [];
1938
+ const onStack = /* @__PURE__ */ new Set();
1939
+ const frames = [];
1940
+ const components = [];
1941
+ const enter = (n) => {
1942
+ const raw = this.readReferrers(n);
1943
+ if (!raw) return false;
1944
+ index.set(n, index.size);
1945
+ low.set(n, index.get(n));
1946
+ stack.push(n);
1947
+ onStack.add(n);
1948
+ frames.push({
1949
+ node: n,
1950
+ parents: this.pendingParents(raw),
1951
+ next: 0
1952
+ });
1953
+ return true;
1954
+ };
1955
+ if (!enter(start)) return null;
1956
+ while (frames.length > 0) {
1957
+ const frame = frames[frames.length - 1];
1958
+ if (frame.next < frame.parents.length) {
1959
+ const p = frame.parents[frame.next++];
1960
+ if (!index.has(p)) {
1961
+ if (!enter(p)) return null;
1962
+ } else if (onStack.has(p)) low.set(frame.node, Math.min(low.get(frame.node), index.get(p)));
1963
+ continue;
1964
+ }
1965
+ frames.pop();
1966
+ const n = frame.node;
1967
+ if (frames.length > 0) {
1968
+ const below = frames[frames.length - 1].node;
1969
+ low.set(below, Math.min(low.get(below), low.get(n)));
1970
+ }
1971
+ if (low.get(n) === index.get(n)) {
1972
+ const component = [];
1973
+ let m;
1974
+ do {
1975
+ m = stack.pop();
1976
+ onStack.delete(m);
1977
+ component.push(m);
1978
+ } while (m !== n);
1979
+ components.push(component);
1980
+ }
1981
+ }
1982
+ return components;
1983
+ }
1984
+ /** Resolve one component whose ancestors are all resolved; false when it exceeded the budget. */
1985
+ resolveComponent(component) {
1986
+ const members = new Set(component);
1987
+ const result = component.length === 1 ? this.edgesOfSingle(component[0]) : this.edgesOfLoop(component, members);
1988
+ if (!result) {
1989
+ for (const n of component) this.resolved.set(n, null);
1990
+ return false;
1991
+ }
1992
+ for (const n of component) this.resolved.set(n, result.get(n));
1993
+ return true;
1994
+ }
1995
+ /** An object outside any loop: its raw edges, each resolved through its parent. */
1996
+ edgesOfSingle(n) {
1801
1997
  const edges = [];
1802
- let cyclic = false;
1803
- try {
1804
- for (const e of raw) {
1805
- if (this.anchors.has(e.parent)) edges.push(e);
1806
- else if (active.has(e.parent)) {
1807
- cyclic = true;
1808
- continue;
1809
- } else {
1810
- const up = this.resolveInner(e.parent, active);
1811
- if (up === null) return null;
1812
- cyclic || (cyclic = up.cyclic);
1813
- for (const u of up.edges) edges.push({
1998
+ for (const e of this.referrers.get(n)) {
1999
+ if (e.parent === n) continue;
2000
+ const through = this.through(e);
2001
+ if (!through) return null;
2002
+ edges.push(...through);
2003
+ }
2004
+ const unique = withoutCollapsedDuplicates(edges);
2005
+ return unique.length > this.budget.maxEdgesPerObject ? null : /* @__PURE__ */ new Map([[n, unique]]);
2006
+ }
2007
+ /**
2008
+ * A loop: every anchored edge into it, as it is at the member it enters
2009
+ * and with the route collapsed at every other member.
2010
+ */
2011
+ edgesOfLoop(component, members) {
2012
+ const entering = /* @__PURE__ */ new Map();
2013
+ const routes = /* @__PURE__ */ new Map();
2014
+ for (const s of component) {
2015
+ const own = [];
2016
+ for (const e of this.referrers.get(s)) {
2017
+ if (members.has(e.parent)) continue;
2018
+ const through = this.through(e);
2019
+ if (!through) return null;
2020
+ for (const u of through) {
2021
+ own.push(u);
2022
+ const via = [...u.via ?? [], s];
2023
+ if (via.length >= this.budget.maxDepth) return null;
2024
+ const route = {
1814
2025
  parent: u.parent,
1815
- label: `${u.label}/${e.label}`,
1816
- via: [...u.via ?? [], e.parent]
1817
- });
2026
+ label: `${u.label}/${LOOP_ROUTE}`,
2027
+ via
2028
+ };
2029
+ const known = routes.get(edgeKey(route));
2030
+ if (!known) routes.set(edgeKey(route), [route]);
2031
+ else if (known.length === 1 && entryOf(known[0]) !== s) known.push(route);
1818
2032
  }
1819
- if (edges.length > this.budget.maxEdgesPerObject) return null;
2033
+ if (own.length > this.budget.maxEdgesPerObject) return null;
1820
2034
  }
1821
- } finally {
1822
- active.delete(n);
2035
+ if (own.length > 0) entering.set(s, withoutCollapsedDuplicates(own));
1823
2036
  }
1824
- const resolution = {
1825
- edges,
1826
- cyclic
1827
- };
1828
- if (!cyclic) this.memo.set(n, resolution);
1829
- return resolution;
2037
+ if (routes.size > this.budget.maxEdgesPerObject) return null;
2038
+ const out = /* @__PURE__ */ new Map();
2039
+ const toAny = [...routes.values()].map((entries) => entries[0]);
2040
+ for (const n of component) {
2041
+ const own = entering.get(n);
2042
+ if (!own) {
2043
+ out.set(n, toAny);
2044
+ continue;
2045
+ }
2046
+ const toThis = [];
2047
+ for (const entries of routes.values()) {
2048
+ const route = entries.find((r) => entryOf(r) !== n);
2049
+ if (route) toThis.push(route);
2050
+ }
2051
+ const edges = [...own, ...toThis];
2052
+ if (edges.length > this.budget.maxEdgesPerObject) return null;
2053
+ out.set(n, edges);
2054
+ }
2055
+ return out;
2056
+ }
2057
+ /** The anchored edges one raw edge stands for; null when its parent exceeded the budget. */
2058
+ through(e) {
2059
+ if (this.anchors.has(e.parent)) return [e];
2060
+ const above = this.resolved.get(e.parent);
2061
+ if (!above) return null;
2062
+ const out = [];
2063
+ for (const u of above) {
2064
+ const via = [...u.via ?? [], e.parent];
2065
+ if (via.length >= this.budget.maxDepth) return null;
2066
+ out.push({
2067
+ parent: u.parent,
2068
+ label: `${u.label}/${e.label}`,
2069
+ via
2070
+ });
2071
+ }
2072
+ return out;
1830
2073
  }
1831
2074
  };
2075
+ function edgeKey(e) {
2076
+ return `${e.parent}:${e.label}`;
2077
+ }
2078
+ /** The member a collapsed route enters its loop at: the last object it was resolved through. */
2079
+ function entryOf(route) {
2080
+ return route.via[route.via.length - 1];
2081
+ }
2082
+ /** Edges whose label collapses a route are told apart by anchor and label alone. */
2083
+ function withoutCollapsedDuplicates(edges) {
2084
+ const seen = /* @__PURE__ */ new Set();
2085
+ return edges.filter((e) => {
2086
+ if (!e.label.includes(LOOP_ROUTE)) return true;
2087
+ const key = edgeKey(e);
2088
+ if (seen.has(key)) return false;
2089
+ seen.add(key);
2090
+ return true;
2091
+ });
2092
+ }
1832
2093
  //#endregion
1833
2094
  //#region src/search/types.ts
1834
2095
  /** The query part of a request (or of any object that carries one): its text and flags, set flags only. */
@@ -2030,6 +2291,12 @@ function finish(h1, h2) {
2030
2291
  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
2031
2292
  }
2032
2293
  //#endregion
2294
+ //#region src/mutation/OutlineMutationResults.ts
2295
+ /** What a delete removed, as its `outline.deleted` event names it: the item first. */
2296
+ function deletedOutlineItemsOf(result) {
2297
+ return result.meta.changed;
2298
+ }
2299
+ //#endregion
2033
2300
  //#region src/auth/scope/pdf-bits.ts
2034
2301
  /**
2035
2302
  * ISO 32000 user-access permission bit positions, expressed as integer
@@ -2396,6 +2663,12 @@ Object.defineProperty(exports, "checkImageQuality", {
2396
2663
  return checkImageQuality;
2397
2664
  }
2398
2665
  });
2666
+ Object.defineProperty(exports, "checkRenderUsage", {
2667
+ enumerable: true,
2668
+ get: function() {
2669
+ return checkRenderUsage;
2670
+ }
2671
+ });
2399
2672
  Object.defineProperty(exports, "closeExportSelection", {
2400
2673
  enumerable: true,
2401
2674
  get: function() {
@@ -2438,6 +2711,12 @@ Object.defineProperty(exports, "deletedAnnotationsOf", {
2438
2711
  return deletedAnnotationsOf;
2439
2712
  }
2440
2713
  });
2714
+ Object.defineProperty(exports, "deletedOutlineItemsOf", {
2715
+ enumerable: true,
2716
+ get: function() {
2717
+ return deletedOutlineItemsOf;
2718
+ }
2719
+ });
2441
2720
  Object.defineProperty(exports, "dictEntries", {
2442
2721
  enumerable: true,
2443
2722
  get: function() {
@@ -2486,6 +2765,12 @@ Object.defineProperty(exports, "isKeptRefusal", {
2486
2765
  return isKeptRefusal;
2487
2766
  }
2488
2767
  });
2768
+ Object.defineProperty(exports, "mapOutlineItem", {
2769
+ enumerable: true,
2770
+ get: function() {
2771
+ return mapOutlineItem;
2772
+ }
2773
+ });
2489
2774
  Object.defineProperty(exports, "matchPageText", {
2490
2775
  enumerable: true,
2491
2776
  get: function() {
@@ -2552,6 +2837,18 @@ Object.defineProperty(exports, "pageListOf", {
2552
2837
  return pageListOf;
2553
2838
  }
2554
2839
  });
2840
+ Object.defineProperty(exports, "pageOutlineItemOf", {
2841
+ enumerable: true,
2842
+ get: function() {
2843
+ return pageOutlineItemOf;
2844
+ }
2845
+ });
2846
+ Object.defineProperty(exports, "pageOutlineOf", {
2847
+ enumerable: true,
2848
+ get: function() {
2849
+ return pageOutlineOf;
2850
+ }
2851
+ });
2555
2852
  Object.defineProperty(exports, "pageRotationOf", {
2556
2853
  enumerable: true,
2557
2854
  get: function() {
@@ -2582,6 +2879,18 @@ Object.defineProperty(exports, "pdfFormFieldDraftOf", {
2582
2879
  return pdfFormFieldDraftOf;
2583
2880
  }
2584
2881
  });
2882
+ Object.defineProperty(exports, "pdfOutlineDraftOf", {
2883
+ enumerable: true,
2884
+ get: function() {
2885
+ return pdfOutlineDraftOf;
2886
+ }
2887
+ });
2888
+ Object.defineProperty(exports, "pdfOutlinePatchOf", {
2889
+ enumerable: true,
2890
+ get: function() {
2891
+ return pdfOutlinePatchOf;
2892
+ }
2893
+ });
2585
2894
  Object.defineProperty(exports, "pdfRenderTargetOf", {
2586
2895
  enumerable: true,
2587
2896
  get: function() {
@@ -2612,12 +2921,24 @@ Object.defineProperty(exports, "primaryFinding", {
2612
2921
  return primaryFinding;
2613
2922
  }
2614
2923
  });
2924
+ Object.defineProperty(exports, "printDpiOf", {
2925
+ enumerable: true,
2926
+ get: function() {
2927
+ return printDpiOf;
2928
+ }
2929
+ });
2615
2930
  Object.defineProperty(exports, "refsOf", {
2616
2931
  enumerable: true,
2617
2932
  get: function() {
2618
2933
  return refsOf;
2619
2934
  }
2620
2935
  });
2936
+ Object.defineProperty(exports, "resolvePageExtract", {
2937
+ enumerable: true,
2938
+ get: function() {
2939
+ return resolvePageExtract;
2940
+ }
2941
+ });
2621
2942
  Object.defineProperty(exports, "resolvePageLayers", {
2622
2943
  enumerable: true,
2623
2944
  get: function() {
@@ -2673,4 +2994,4 @@ Object.defineProperty(exports, "worstVerdict", {
2673
2994
  }
2674
2995
  });
2675
2996
 
2676
- //# sourceMappingURL=authority-DLMNR7ff.cjs.map
2997
+ //# sourceMappingURL=authority-BFp6XM04.cjs.map