js.documents 14.4.56 → 14.4.57

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 (163) hide show
  1. package/dist/codecs/read.cjs +2 -2
  2. package/dist/codecs/read.js +1 -1
  3. package/dist/composition-plan-CfvhXeOC.cjs +627 -0
  4. package/dist/composition-plan-DU9nPPN7.d.cts +102 -0
  5. package/dist/composition-plan-f0zaExUW.js +508 -0
  6. package/dist/composition-plan-l6QPO4FX.d.ts +102 -0
  7. package/dist/convert/composition-plan.cjs +7 -0
  8. package/dist/convert/composition-plan.d.cts +2 -0
  9. package/dist/convert/composition-plan.d.ts +2 -0
  10. package/dist/convert/composition-plan.js +2 -0
  11. package/dist/convert/composition-to-pdf.cjs +12 -12
  12. package/dist/convert/composition-to-pdf.d.cts +1 -1
  13. package/dist/convert/composition-to-pdf.d.ts +1 -1
  14. package/dist/convert/composition-to-pdf.js +2 -2
  15. package/dist/convert/composition.cjs +16 -511
  16. package/dist/convert/composition.d.cts +2 -85
  17. package/dist/convert/composition.d.ts +2 -85
  18. package/dist/convert/composition.js +2 -502
  19. package/dist/convert/convert.cjs +2 -2
  20. package/dist/convert/convert.js +1 -1
  21. package/dist/convert/from-package.cjs +3 -3
  22. package/dist/convert/from-package.js +2 -2
  23. package/dist/convert/from-pdf.cjs +18 -18
  24. package/dist/convert/from-pdf.js +2 -2
  25. package/dist/convert/local.cjs +3 -3
  26. package/dist/convert/local.js +1 -1
  27. package/dist/edit/odp/slide.cjs +4 -4
  28. package/dist/edit/odp/slide.d.cts +1 -1
  29. package/dist/edit/odp/slide.d.ts +1 -1
  30. package/dist/edit/odp/slide.js +1 -1
  31. package/dist/edit/odt/content.d.cts +1 -1
  32. package/dist/edit/odt/content.d.ts +1 -1
  33. package/dist/edit/odt/editor.cjs +4 -4
  34. package/dist/edit/odt/editor.d.cts +1 -1
  35. package/dist/edit/odt/editor.d.ts +1 -1
  36. package/dist/edit/odt/editor.js +1 -1
  37. package/dist/edit/odt/table-grid.cjs +23 -0
  38. package/dist/edit/odt/table-grid.d.cts +54 -0
  39. package/dist/edit/odt/table-grid.d.ts +54 -0
  40. package/dist/edit/odt/table-grid.js +2 -0
  41. package/dist/edit/odt/table.cjs +12 -653
  42. package/dist/edit/odt/table.d.cts +2 -2
  43. package/dist/edit/odt/table.d.ts +2 -2
  44. package/dist/edit/odt/table.js +2 -647
  45. package/dist/{evaluate-BbOsgdmN.d.cts → evaluate-BSEUxiUK.d.cts} +3 -1
  46. package/dist/evaluate-CEzsBx3w.cjs +564 -0
  47. package/dist/{evaluate-C7fmk69X.d.ts → evaluate-D8fG2ZeB.d.ts} +3 -1
  48. package/dist/evaluate-IK-3aMv5.js +445 -0
  49. package/dist/evaluate-columns-CyqKHkIW.d.cts +41 -0
  50. package/dist/evaluate-columns-cOo8fOfT.d.ts +41 -0
  51. package/dist/index.cjs +24 -24
  52. package/dist/index.d.cts +6 -5
  53. package/dist/index.d.ts +6 -5
  54. package/dist/index.js +8 -8
  55. package/dist/latex/lint.cjs +2 -2
  56. package/dist/latex/lint.js +1 -1
  57. package/dist/latex/lower-fold.cjs +6 -0
  58. package/dist/latex/lower-fold.d.cts +17 -0
  59. package/dist/latex/lower-fold.d.ts +17 -0
  60. package/dist/latex/lower-fold.js +2 -0
  61. package/dist/latex/lower.cjs +11 -617
  62. package/dist/latex/lower.d.cts +18 -1
  63. package/dist/latex/lower.d.ts +18 -1
  64. package/dist/latex/lower.js +2 -616
  65. package/dist/latex/symbols.d.cts +1 -15
  66. package/dist/latex/symbols.d.ts +1 -15
  67. package/dist/latex/temml.d.cts +1 -24
  68. package/dist/latex/temml.d.ts +1 -24
  69. package/dist/layout/engine.cjs +2 -2
  70. package/dist/layout/engine.js +1 -1
  71. package/dist/layout/reconstruct-lines.cjs +315 -0
  72. package/dist/layout/reconstruct-lines.d.cts +2 -0
  73. package/dist/layout/reconstruct-lines.d.ts +2 -0
  74. package/dist/layout/reconstruct-lines.js +297 -0
  75. package/dist/layout/reconstruct-presentations-prod.cjs +9 -0
  76. package/dist/layout/reconstruct-presentations-prod.d.cts +26 -0
  77. package/dist/layout/reconstruct-presentations-prod.d.ts +26 -0
  78. package/dist/layout/reconstruct-presentations-prod.js +2 -0
  79. package/dist/layout/reconstruct-tables.cjs +5 -0
  80. package/dist/layout/reconstruct-tables.d.cts +22 -0
  81. package/dist/layout/reconstruct-tables.d.ts +22 -0
  82. package/dist/layout/reconstruct-tables.js +2 -0
  83. package/dist/layout/reconstruct.cjs +11 -1545
  84. package/dist/layout/reconstruct.d.cts +2 -14
  85. package/dist/layout/reconstruct.d.ts +2 -14
  86. package/dist/layout/reconstruct.js +2 -1542
  87. package/dist/layout/shared.cjs +2 -2
  88. package/dist/layout/shared.js +1 -1
  89. package/dist/layout/sheets-render.cjs +19 -0
  90. package/dist/layout/sheets-render.d.cts +41 -0
  91. package/dist/layout/sheets-render.d.ts +41 -0
  92. package/dist/layout/sheets-render.js +2 -0
  93. package/dist/layout/sheets.cjs +10 -544
  94. package/dist/layout/sheets.d.cts +13 -2
  95. package/dist/layout/sheets.d.ts +13 -2
  96. package/dist/layout/sheets.js +2 -543
  97. package/dist/layout/slides.cjs +2 -2
  98. package/dist/layout/slides.js +1 -1
  99. package/dist/layout-DIJzJk4x.js +526 -0
  100. package/dist/layout-iuiyl_Fk.cjs +621 -0
  101. package/dist/layout-types-oSbHvZid.d.cts +13 -0
  102. package/dist/layout-types-oSbHvZid.d.ts +13 -0
  103. package/dist/lower-DCs3rWI7.js +618 -0
  104. package/dist/lower-DzOb13w4.cjs +701 -0
  105. package/dist/markdown/math.cjs +2 -2
  106. package/dist/markdown/math.js +1 -1
  107. package/dist/mathml/layout-stretch.cjs +16 -0
  108. package/dist/mathml/layout-stretch.d.cts +24 -0
  109. package/dist/mathml/layout-stretch.d.ts +24 -0
  110. package/dist/mathml/layout-stretch.js +2 -0
  111. package/dist/mathml/layout-types.d.cts +1 -12
  112. package/dist/mathml/layout-types.d.ts +1 -12
  113. package/dist/mathml/layout.cjs +3 -525
  114. package/dist/mathml/layout.d.cts +2 -2
  115. package/dist/mathml/layout.d.ts +2 -2
  116. package/dist/mathml/layout.js +1 -523
  117. package/dist/odb/formula/evaluate.d.cts +1 -1
  118. package/dist/odb/formula/evaluate.d.ts +1 -1
  119. package/dist/odb/report/render.d.cts +1 -1
  120. package/dist/odb/report/render.d.ts +1 -1
  121. package/dist/odb/report/source.cjs +2 -2
  122. package/dist/odb/report/source.d.cts +1 -1
  123. package/dist/odb/report/source.d.ts +1 -1
  124. package/dist/odb/report/source.js +1 -1
  125. package/dist/odb/sql/evaluate-columns.cjs +122 -0
  126. package/dist/odb/sql/evaluate-columns.d.cts +2 -0
  127. package/dist/odb/sql/evaluate-columns.d.ts +2 -0
  128. package/dist/odb/sql/evaluate-columns.js +114 -0
  129. package/dist/odb/sql/evaluate-predicates.cjs +16 -0
  130. package/dist/odb/sql/evaluate-predicates.d.cts +23 -0
  131. package/dist/odb/sql/evaluate-predicates.d.ts +23 -0
  132. package/dist/odb/sql/evaluate-predicates.js +2 -0
  133. package/dist/odb/sql/evaluate.cjs +7 -556
  134. package/dist/odb/sql/evaluate.d.cts +2 -2
  135. package/dist/odb/sql/evaluate.d.ts +2 -2
  136. package/dist/odb/sql/evaluate.js +2 -552
  137. package/dist/read-BSH--XB4.js +682 -0
  138. package/dist/read-CahCZMwG.cjs +759 -0
  139. package/dist/reconstruct-BKOCAedo.d.ts +29 -0
  140. package/dist/reconstruct-D4TEteZ6.d.cts +29 -0
  141. package/dist/reconstruct-lines-B7t66ICm.d.cts +33 -0
  142. package/dist/reconstruct-lines-B7t66ICm.d.ts +33 -0
  143. package/dist/reconstruct-presentations-prod-B5fkPiRZ.js +1256 -0
  144. package/dist/reconstruct-presentations-prod-X315aBmI.cjs +1375 -0
  145. package/dist/sheets-BQCpNXsE.cjs +700 -0
  146. package/dist/sheets-DWDvGN-g.js +545 -0
  147. package/dist/svg/read-geometry.cjs +10 -0
  148. package/dist/svg/read-geometry.d.cts +24 -0
  149. package/dist/svg/read-geometry.d.ts +24 -0
  150. package/dist/svg/read-geometry.js +2 -0
  151. package/dist/svg/read.cjs +6 -680
  152. package/dist/svg/read.d.cts +17 -2
  153. package/dist/svg/read.d.ts +17 -2
  154. package/dist/svg/read.js +2 -679
  155. package/dist/symbols-BlzXfLEe.d.cts +16 -0
  156. package/dist/symbols-CKm2r4D0.d.ts +16 -0
  157. package/dist/table-B5gSMY7w.js +649 -0
  158. package/dist/{table-DrE6jEWv.d.cts → table-BK_Ao-Y6.d.cts} +9 -1
  159. package/dist/{table-B5htMG3g.d.ts → table-CxY85YUj.d.ts} +9 -1
  160. package/dist/table-DqUIOSPV.cjs +840 -0
  161. package/dist/temml-1-I9N9DD.d.cts +25 -0
  162. package/dist/temml-1-I9N9DD.d.ts +25 -0
  163. package/package.json +1 -1
@@ -1,1546 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_model_geometry = require("../model/geometry.cjs");
3
- const require_model_embedded_drawing = require("../model/embedded-drawing.cjs");
4
- const require_layout_shared = require("./shared.cjs");
5
- const require_layout_cell_typing = require("./cell-typing.cjs");
6
- const require_ports_abort = require("../ports/abort.cjs");
7
- const require_layout_lattice = require("./lattice.cjs");
8
- let document_schema_js = require("document-schema.js");
9
- let pdf_codec_fonts = require("pdf-codec/fonts");
10
- let pdf_codec_afm_widths = require("pdf-codec/afm-widths");
11
- let pdf_codec_text_group = require("pdf-codec/text-group");
12
- //#region src/layout/reconstruct.ts
13
- const DEFAULT_COLUMN_WIDTH_FALLBACK_PT = 40;
14
- const NO_ITEMS = /* @__PURE__ */ new Set();
15
- const LARGE_GAP_EM_MULTIPLIER = 2;
16
- const ZERO_MARGINS = {
17
- topPt: 0,
18
- rightPt: 0,
19
- bottomPt: 0,
20
- leftPt: 0
21
- };
22
- const LINE_BASELINE_TOLERANCE_FACTOR = .5;
23
- const AFM_UNITS_PER_EM = 1e3;
24
- const HALF_POINT_BUCKET_PT = .5;
25
- function sharesBaseline(anchor, item) {
26
- return (0, pdf_codec_text_group.runsShareBaseline)(anchor, item, { baselineToleranceEm: LINE_BASELINE_TOLERANCE_FACTOR });
27
- }
28
- const DUPLICATE_PAINT_BUCKET_PT = .1;
29
- function duplicatePaintKey(item) {
30
- const xBucket = Math.round(item.xPt / DUPLICATE_PAINT_BUCKET_PT);
31
- const yBucket = Math.round(item.yPt / DUPLICATE_PAINT_BUCKET_PT);
32
- return `${item.text.trim()}|${String(xBucket)}|${String(yBucket)}`;
33
- }
34
- function dropDuplicatePaints(items) {
35
- const seen = /* @__PURE__ */ new Set();
36
- const kept = [];
37
- for (const item of items) {
38
- const key = duplicatePaintKey(item);
39
- if (seen.has(key)) continue;
40
- seen.add(key);
41
- kept.push(item);
42
- }
43
- return kept;
44
- }
45
- function dropOverlappingRepeatsWithinLine(items) {
46
- const rightEdgeByText = /* @__PURE__ */ new Map();
47
- const kept = [];
48
- for (const item of items) {
49
- const textKey = item.text.trim();
50
- const priorRightEdge = rightEdgeByText.get(textKey);
51
- if (priorRightEdge !== void 0 && item.xPt < priorRightEdge) continue;
52
- rightEdgeByText.set(textKey, item.xPt + (item.widthPt ?? 0));
53
- kept.push(item);
54
- }
55
- return kept;
56
- }
57
- const REDRAW_PASS_REWIND_TOLERANCE_PT = 2;
58
- const MIN_REDRAW_PASS_TEXT_LENGTH = 12;
59
- const REDRAW_PASS_SIMILARITY_THRESHOLD = .6;
60
- function groupByBaselineInDocumentOrder(items) {
61
- const groups = [];
62
- for (const item of items) {
63
- const group = groups.find((g) => sharesBaseline(g.anchor, item));
64
- if (group === void 0) groups.push({
65
- anchor: item,
66
- items: [item]
67
- });
68
- else group.items.push(item);
69
- }
70
- return groups.map((g) => g.items);
71
- }
72
- function splitIntoPasses(group) {
73
- const passes = [];
74
- for (const item of group) {
75
- const current = passes.at(-1);
76
- const itemRightPt = item.xPt + (item.widthPt ?? 0);
77
- if (current !== void 0 && item.xPt >= current.endXPt - REDRAW_PASS_REWIND_TOLERANCE_PT) {
78
- current.items.push(item);
79
- current.endXPt = Math.max(current.endXPt, itemRightPt);
80
- } else passes.push({
81
- items: [item],
82
- startXPt: item.xPt,
83
- endXPt: itemRightPt
84
- });
85
- }
86
- return passes;
87
- }
88
- function passText(pass) {
89
- return pass.items.map((item) => item.text).join("").trim();
90
- }
91
- function passesOverlap(a, b) {
92
- return a.startXPt < b.endXPt && b.startXPt < a.endXPt;
93
- }
94
- function levenshteinDistance(a, b) {
95
- const memo = /* @__PURE__ */ new Map();
96
- function distance(i, j) {
97
- if (i === 0) return j;
98
- if (j === 0) return i;
99
- const key = `${String(i)}:${String(j)}`;
100
- const cached = memo.get(key);
101
- if (cached !== void 0) return cached;
102
- const cost = a.charAt(i - 1) === b.charAt(j - 1) ? 0 : 1;
103
- const result = Math.min(distance(i - 1, j) + 1, distance(i, j - 1) + 1, distance(i - 1, j - 1) + cost);
104
- memo.set(key, result);
105
- return result;
106
- }
107
- return distance(a.length, b.length);
108
- }
109
- function textSimilarity(a, b) {
110
- const maxLength = Math.max(a.length, b.length);
111
- return 1 - levenshteinDistance(a, b) / maxLength;
112
- }
113
- function dropFuzzyRedrawnPasses(items) {
114
- const toDrop = /* @__PURE__ */ new Set();
115
- for (const group of groupByBaselineInDocumentOrder(items)) {
116
- const passes = splitIntoPasses(group);
117
- if (passes.length < 2) continue;
118
- const [first, ...rest] = passes;
119
- if (first === void 0) continue;
120
- const firstText = passText(first);
121
- if (firstText.length < MIN_REDRAW_PASS_TEXT_LENGTH) continue;
122
- for (const candidate of rest) {
123
- const candidateText = passText(candidate);
124
- if (candidateText.length < MIN_REDRAW_PASS_TEXT_LENGTH) continue;
125
- if (!passesOverlap(first, candidate)) continue;
126
- if (textSimilarity(firstText, candidateText) < REDRAW_PASS_SIMILARITY_THRESHOLD) continue;
127
- for (const item of candidate.items) toDrop.add(item);
128
- }
129
- }
130
- if (toDrop.size === 0) return items;
131
- return items.filter((item) => !toDrop.has(item));
132
- }
133
- function clusterIntoLines(items) {
134
- const sorted = [...dropDuplicatePaints(dropFuzzyRedrawnPasses(items))].sort((a, b) => b.yPt - a.yPt || a.xPt - b.xPt);
135
- const working = [];
136
- for (const item of sorted) {
137
- const line = working.find((l) => sharesBaseline(l.anchor, item));
138
- if (line === void 0) working.push({
139
- items: [item],
140
- baselineY: item.yPt,
141
- anchor: item
142
- });
143
- else line.items.push(item);
144
- }
145
- for (const line of working) {
146
- line.items.sort((a, b) => a.xPt - b.xPt);
147
- line.items = dropOverlappingRepeatsWithinLine(line.items);
148
- }
149
- working.sort((a, b) => b.baselineY - a.baselineY);
150
- return working;
151
- }
152
- function textItemVerticalExtent(item) {
153
- const { standardName } = (0, pdf_codec_fonts.resolveStandardFont)(item.font.family, item.font.weight === "bold", item.font.style === "italic");
154
- const metrics = pdf_codec_afm_widths.STANDARD_METRICS[standardName];
155
- return {
156
- ascentPt: metrics.ascender / AFM_UNITS_PER_EM * item.sizePt,
157
- descentPt: Math.abs(metrics.descender) / AFM_UNITS_PER_EM * item.sizePt
158
- };
159
- }
160
- function textItemToContentRun(item) {
161
- return {
162
- text: item.text,
163
- ...item.font.weight === "bold" ? { bold: true } : {},
164
- ...item.font.style === "italic" ? { italic: true } : {},
165
- fontFamily: item.font.family,
166
- sizePt: item.sizePt,
167
- color: item.color
168
- };
169
- }
170
- const MIN_WORD_GAP_PT = .5;
171
- function gapExceeds(previous, next, thresholdPt) {
172
- const gap = (0, pdf_codec_text_group.runGapPt)(previous, next);
173
- return gap !== void 0 && gap > thresholdPt;
174
- }
175
- function textBoxOfItem(item, pageIndex) {
176
- const { ascentPt, descentPt } = textItemVerticalExtent(item);
177
- return {
178
- pageIndex,
179
- xPt: item.xPt,
180
- yPt: item.yPt - descentPt,
181
- widthPt: item.widthPt ?? 0,
182
- heightPt: ascentPt + descentPt
183
- };
184
- }
185
- function lineBox(line, pageIndex) {
186
- let minX = Number.POSITIVE_INFINITY;
187
- let maxX = Number.NEGATIVE_INFINITY;
188
- let minY = Number.POSITIVE_INFINITY;
189
- let maxY = Number.NEGATIVE_INFINITY;
190
- for (const item of line.items) {
191
- const { ascentPt, descentPt } = textItemVerticalExtent(item);
192
- minX = Math.min(minX, item.xPt);
193
- maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
194
- minY = Math.min(minY, item.yPt - descentPt);
195
- maxY = Math.max(maxY, item.yPt + ascentPt);
196
- }
197
- return {
198
- pageIndex,
199
- xPt: minX,
200
- yPt: minY,
201
- widthPt: maxX - minX,
202
- heightPt: maxY - minY
203
- };
204
- }
205
- function pushRunsForLine(runs, line, pageIndex) {
206
- line.items.forEach((item, itemIndex) => {
207
- if (itemIndex > 0) {
208
- const prevItem = line.items[itemIndex - 1];
209
- if (gapExceeds(prevItem, item, LARGE_GAP_EM_MULTIPLIER * item.sizePt)) runs.push({ text: " " });
210
- else if (gapExceeds(prevItem, item, MIN_WORD_GAP_PT)) runs[runs.length - 1].text += " ";
211
- }
212
- const run = textItemToContentRun(item);
213
- require_layout_shared.stampFrame(run, pageIndex, textBoxOfItem(item, pageIndex));
214
- runs.push(run);
215
- });
216
- }
217
- function bucketCounts(values, bucketSize) {
218
- const counts = /* @__PURE__ */ new Map();
219
- for (const v of values) {
220
- const bucket = Math.round(v / bucketSize) * bucketSize;
221
- counts.set(bucket, (counts.get(bucket) ?? 0) + 1);
222
- }
223
- return counts;
224
- }
225
- function modeOf(values, bucketSize) {
226
- if (values.length === 0) return 0;
227
- const counts = bucketCounts(values, bucketSize);
228
- let bestBucket = values[0];
229
- let bestCount = 0;
230
- for (const [bucket, count] of counts) if (count > bestCount) {
231
- bestBucket = bucket;
232
- bestCount = count;
233
- }
234
- return bestBucket;
235
- }
236
- function modalLineGap(gaps) {
237
- const counts = bucketCounts(gaps, HALF_POINT_BUCKET_PT);
238
- let bestBucket = gaps[0];
239
- let bestCount = 0;
240
- for (const [bucket, count] of counts) if (count > bestCount) {
241
- bestBucket = bucket;
242
- bestCount = count;
243
- }
244
- return bestCount > 1 ? bestBucket : Math.min(...gaps);
245
- }
246
- const PARAGRAPH_GAP_MULTIPLIER = 1.25;
247
- const NOMINAL_LINE_SPACING_RATIO = 1.2;
248
- const MIN_LINES_FOR_GAP_MODE = 3;
249
- function estimateModalLineSpacing(lines) {
250
- if (lines.length < MIN_LINES_FOR_GAP_MODE) return modeOf(lines.map((l) => l.items[0].sizePt), HALF_POINT_BUCKET_PT) * NOMINAL_LINE_SPACING_RATIO;
251
- const gaps = [];
252
- for (let i = 1; i < lines.length; i++) gaps.push(lines[i - 1].baselineY - lines[i].baselineY);
253
- return modalLineGap(gaps);
254
- }
255
- function reconstructWordprocessing(doc, options) {
256
- const signal = options?.signal;
257
- doc = dropHiddenLayerContent(doc);
258
- const headingLevels = headingSizeLevels(doc);
259
- const structure = indexStructure(doc);
260
- const sections = [];
261
- let currentGroup = [];
262
- let groupStartPageIndex = 0;
263
- for (const page of doc.pages) {
264
- require_ports_abort.throwIfAborted(signal);
265
- if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
266
- sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
267
- groupStartPageIndex += currentGroup.length;
268
- currentGroup = [];
269
- }
270
- currentGroup.push(page);
271
- }
272
- if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
273
- return {
274
- kind: "wordprocessing",
275
- metadata: doc.metadata,
276
- sections
277
- };
278
- }
279
- function layerOf(item) {
280
- return item.kind === "link" || item.kind === "internalLink" ? void 0 : item.layer;
281
- }
282
- function dropHiddenLayerContent(doc) {
283
- const hidden = new Set((doc.layers ?? []).filter((layer) => !layer.visible).map((layer) => layer.name));
284
- if (hidden.size === 0) return doc;
285
- return {
286
- ...doc,
287
- pages: doc.pages.map((page) => ({
288
- ...page,
289
- items: page.items.filter((item) => layerOf(item) === void 0 || !hidden.has(layerOf(item)))
290
- }))
291
- };
292
- }
293
- const HEADING_LEVELS = new Map([
294
- "H1",
295
- "H2",
296
- "H3",
297
- "H4",
298
- "H5",
299
- "H6"
300
- ].map((tag, index) => [tag, index + 1]));
301
- const DIVISION_TYPES = /* @__PURE__ */ new Set([
302
- "Part",
303
- "Sect",
304
- "Div"
305
- ]);
306
- const CELL_TYPES = /* @__PURE__ */ new Set(["TD", "TH"]);
307
- const ROW_TYPES = /* @__PURE__ */ new Set(["TR"]);
308
- const TABLE_TYPES = /* @__PURE__ */ new Set(["Table"]);
309
- function indexStructure(doc) {
310
- if (doc.structure === void 0 || doc.structure.length === 0) return;
311
- const byId = /* @__PURE__ */ new Map();
312
- let order = 0;
313
- const walk = (element, parent) => {
314
- const node = {
315
- id: element.id,
316
- type: element.type,
317
- parent,
318
- order: order++
319
- };
320
- byId.set(element.id, node);
321
- for (const child of element.children) walk(child, node);
322
- };
323
- for (const root of doc.structure) walk(root, void 0);
324
- return { nodeOfItem: (item) => item.kind === "link" || item.kind === "internalLink" ? void 0 : byId.get(item.structure ?? "") };
325
- }
326
- function nearestOfType(node, types) {
327
- for (let current = node; current !== void 0; current = current.parent) if (types.has(current.type)) return current;
328
- }
329
- function nearestHeadingLevel(node) {
330
- for (let current = node; current !== void 0; current = current.parent) {
331
- const level = HEADING_LEVELS.get(current.type);
332
- if (level !== void 0) return level;
333
- }
334
- }
335
- function structureHeadingLevel(items, structure) {
336
- if (items.length === 0 || items.some((item) => structure.nodeOfItem(item) === void 0)) return;
337
- let level;
338
- for (const item of items) {
339
- const itemLevel = nearestHeadingLevel(structure.nodeOfItem(item));
340
- if (itemLevel === void 0) return { level: void 0 };
341
- if (level === void 0) level = itemLevel;
342
- else if (level !== itemLevel) return;
343
- }
344
- return { level };
345
- }
346
- const HEADING_MIN_SIZE_DELTA_PT = 2;
347
- const MAX_HEADING_LEVEL = 6;
348
- function hasVisibleText(text) {
349
- return text.trim().length > 0;
350
- }
351
- function headingSizeLevels(doc) {
352
- const sizes = [];
353
- for (const page of doc.pages) for (const item of page.items) if (item.kind === "text" && hasVisibleText(item.text)) sizes.push(item.sizePt);
354
- if (sizes.length === 0) return /* @__PURE__ */ new Map();
355
- const bodySizePt = modeOf(sizes, HALF_POINT_BUCKET_PT);
356
- const headingBuckets = /* @__PURE__ */ new Set();
357
- for (const size of sizes) {
358
- const bucket = Math.round(size / HALF_POINT_BUCKET_PT) * HALF_POINT_BUCKET_PT;
359
- if (bucket - bodySizePt >= HEADING_MIN_SIZE_DELTA_PT) headingBuckets.add(bucket);
360
- }
361
- const levels = /* @__PURE__ */ new Map();
362
- [...headingBuckets].sort((a, b) => b - a).forEach((bucket, index) => {
363
- levels.set(bucket, Math.min(index + 1, MAX_HEADING_LEVEL));
364
- });
365
- return levels;
366
- }
367
- function headingLevelOf(paragraph, levels) {
368
- return levels.get(modeOf(paragraph.lines.flatMap((line) => line.items).filter((item) => hasVisibleText(item.text)).map((item) => item.sizePt), HALF_POINT_BUCKET_PT));
369
- }
370
- function samePageSize(a, b) {
371
- return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
372
- }
373
- function buildSection(pages, startPageIndex, images, headingLevels, form, structure) {
374
- const blocks = [];
375
- const divisionByBlock = /* @__PURE__ */ new WeakMap();
376
- pages.forEach((page, i) => {
377
- if (i > 0) blocks.push({ kind: "pageBreak" });
378
- blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form, structure, divisionByBlock));
379
- });
380
- return {
381
- pageSize: {
382
- widthPt: pages[0].widthPt,
383
- heightPt: pages[0].heightPt
384
- },
385
- margins: ZERO_MARGINS,
386
- blocks: wrapDivisionExtents(blocks, divisionByBlock)
387
- };
388
- }
389
- function reconstructPageBlocks(page, pageIndex, images, headingLevels, form, structure, divisionByBlock) {
390
- const recoveredTables = recoverTables(page, pageIndex, structure);
391
- const consumedText = /* @__PURE__ */ new Set();
392
- const claimedItems = /* @__PURE__ */ new Set();
393
- for (const recovered of recoveredTables) {
394
- for (const item of recovered.consumedText) consumedText.add(item);
395
- for (const item of recovered.latticeItems) claimedItems.add(item);
396
- }
397
- const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
398
- const imageItems = page.items.filter((i) => i.kind === "image");
399
- const paragraphs = clusterIntoParagraphs(clusterIntoLines(textItems));
400
- const recordDivisions = (block, items) => {
401
- if (structure !== void 0) divisionByBlock.set(block, divisionChainOf(items, structure));
402
- };
403
- const positioned = [];
404
- for (const paragraph of paragraphs) {
405
- const paragraphItems = paragraph.lines.flatMap((line) => line.items);
406
- const structural = structure === void 0 ? void 0 : structureHeadingLevel(paragraphItems, structure);
407
- const block = paragraphToContentParagraph(paragraph, pageIndex, structural !== void 0 ? structural.level : headingLevelOf(paragraph, headingLevels));
408
- recordDivisions(block, paragraphItems);
409
- positioned.push({
410
- yPt: paragraph.lines[0].baselineY,
411
- block
412
- });
413
- }
414
- for (const img of imageItems) {
415
- const asset = images[img.imageId];
416
- if (asset !== void 0) {
417
- const block = {
418
- kind: "image",
419
- format: asset.format,
420
- base64: asset.base64,
421
- widthPt: img.widthPt,
422
- heightPt: img.heightPt
423
- };
424
- require_layout_shared.stampFrame(block, pageIndex, {
425
- xPt: img.xPt,
426
- yPt: img.yPt,
427
- widthPt: img.widthPt,
428
- heightPt: img.heightPt
429
- });
430
- recordDivisions(block, [img]);
431
- positioned.push({
432
- yPt: img.yPt,
433
- block
434
- });
435
- }
436
- }
437
- for (const recovered of recoveredTables) {
438
- recordDivisions(recovered.table, [...recovered.consumedText]);
439
- positioned.push({
440
- yPt: recovered.topYPt,
441
- block: recovered.table
442
- });
443
- }
444
- const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
445
- if (recoveredVectors !== void 0) {
446
- const vectorItems = page.items.filter((item) => !claimedItems.has(item) && layoutItemToVector(item, page.heightPt) !== void 0);
447
- recordDivisions(recoveredVectors.block, vectorItems);
448
- positioned.push({
449
- yPt: recoveredVectors.topYPt,
450
- block: recoveredVectors.block
451
- });
452
- }
453
- positioned.sort((a, b) => b.yPt - a.yPt);
454
- const blocks = positioned.map((p) => p.block);
455
- reconcileLinks(blocks, page, pageIndex);
456
- appendAnnotationConstructs(blocks, page, pageIndex);
457
- appendFormFieldConstructs(blocks, form, pageIndex);
458
- return blocks;
459
- }
460
- function divisionChainOf(items, structure) {
461
- let prefix;
462
- for (const item of items) {
463
- const chain = [];
464
- for (let current = structure.nodeOfItem(item); current !== void 0; current = current.parent) if (DIVISION_TYPES.has(current.type)) chain.push(current.id);
465
- chain.reverse();
466
- if (prefix === void 0) {
467
- prefix = chain;
468
- continue;
469
- }
470
- let shared = 0;
471
- while (shared < prefix.length && shared < chain.length && prefix[shared] === chain[shared]) shared += 1;
472
- prefix = prefix.slice(0, shared);
473
- }
474
- return prefix ?? [];
475
- }
476
- function wrapDivisionExtents(blocks, divisionByBlock) {
477
- const out = [];
478
- const open = [];
479
- for (const block of blocks) {
480
- const chain = divisionByBlock.get(block);
481
- if (chain !== void 0) {
482
- while (open.length > 0 && !chain.includes(open[open.length - 1])) {
483
- out.push({ kind: "constructEnd" });
484
- open.pop();
485
- }
486
- for (const id of chain) {
487
- if (open.includes(id)) continue;
488
- out.push({
489
- kind: "constructStart",
490
- descriptor: { kind: "division" }
491
- });
492
- open.push(id);
493
- }
494
- }
495
- out.push(block);
496
- }
497
- while (open.length > 0) {
498
- out.push({ kind: "constructEnd" });
499
- open.pop();
500
- }
501
- return out;
502
- }
503
- function framesIntersect(a, b) {
504
- return a.xPt < b.xPt + b.widthPt && b.xPt < a.xPt + a.widthPt && a.yPt < b.yPt + b.heightPt && b.yPt < a.yPt + a.heightPt;
505
- }
506
- function intersectionArea(a, b) {
507
- const width = Math.min(a.xPt + a.widthPt, b.xPt + b.widthPt) - Math.max(a.xPt, b.xPt);
508
- const height = Math.min(a.yPt + a.heightPt, b.yPt + b.heightPt) - Math.max(a.yPt, b.yPt);
509
- return width > 0 && height > 0 ? width * height : 0;
510
- }
511
- function reconcileLinks(blocks, page, pageIndex) {
512
- for (const item of page.items) {
513
- if (item.kind !== "link" && item.kind !== "internalLink") continue;
514
- if (item.kind === "link") {
515
- let matchedRun = false;
516
- for (const block of blocks) {
517
- if (block.kind !== "paragraph") continue;
518
- for (const run of block.runs) if ((run.frames ?? []).some((frame) => frame.pageIndex === pageIndex && framesIntersect(item, frame))) {
519
- run.hyperlink = item.uri;
520
- matchedRun = true;
521
- }
522
- }
523
- if (matchedRun) continue;
524
- }
525
- wrapBestBlock(blocks, item, pageIndex, linkDescriptor(item));
526
- }
527
- }
528
- function linkDescriptor(item) {
529
- if (item.kind === "link") return {
530
- kind: "link",
531
- target: {
532
- kind: "external",
533
- uri: item.uri
534
- },
535
- ...item.title !== void 0 ? { title: item.title } : {}
536
- };
537
- return {
538
- kind: "link",
539
- target: {
540
- kind: "internal",
541
- anchor: item.destination
542
- },
543
- ...item.title !== void 0 ? { title: item.title } : {}
544
- };
545
- }
546
- function blockFramesOn(block, pageIndex) {
547
- return block.kind === "constructStart" || block.kind === "constructEnd" ? [] : (block.frames ?? []).filter((frame) => frame.pageIndex === pageIndex);
548
- }
549
- function wrapBestBlock(blocks, rect, pageIndex, descriptor) {
550
- let bestIndex = -1;
551
- let bestArea = 0;
552
- blocks.forEach((block, index) => {
553
- const area = blockFramesOn(block, pageIndex).reduce((sum, frame) => sum + intersectionArea(rect, frame), 0);
554
- if (area > bestArea) {
555
- bestArea = area;
556
- bestIndex = index;
557
- }
558
- });
559
- const start = {
560
- kind: "constructStart",
561
- descriptor
562
- };
563
- const end = { kind: "constructEnd" };
564
- if (bestIndex >= 0) {
565
- blocks.splice(bestIndex, 0, start);
566
- blocks.splice(bestIndex + 2, 0, end);
567
- } else blocks.push(start, end);
568
- }
569
- function appendAnnotationConstructs(blocks, page, pageIndex) {
570
- (page.annotations ?? []).forEach((annotation, annotIndex) => {
571
- const key = `pdf-annot-${String(pageIndex)}-${String(annotIndex)}`;
572
- blocks.push({
573
- kind: "constructStart",
574
- descriptor: {
575
- kind: "anchor",
576
- anchorType: "comment",
577
- name: key,
578
- definition: key,
579
- ...annotation.source !== void 0 ? { source: annotation.source } : {}
580
- }
581
- }, { kind: "constructEnd" });
582
- });
583
- }
584
- function controlTypeOf(field) {
585
- if (field.fieldType === "text") return "plainText";
586
- if (field.fieldType === "button") return "button";
587
- if (field.fieldType === "combobox") return "comboBox";
588
- if (field.fieldType === "listbox") return "dropDown";
589
- return "checkbox";
590
- }
591
- function appendFormFieldConstructs(blocks, form, pageIndex) {
592
- const visit = (fields) => {
593
- for (const field of fields) {
594
- visit(field.children);
595
- if (field.fieldType === "group" || field.fieldType === "signature") continue;
596
- for (const widget of field.widgets) {
597
- if (widget.pageIndex !== pageIndex) continue;
598
- wrapBestBlock(blocks, widget, pageIndex, {
599
- kind: "contentControl",
600
- controlType: controlTypeOf(field),
601
- tag: field.name,
602
- ...field.alias !== void 0 ? { alias: field.alias } : {},
603
- ...field.readOnly === true ? { lock: "content" } : {},
604
- ...field.value !== void 0 ? { value: field.value } : {},
605
- ...field.checked !== void 0 ? { checked: field.checked } : {},
606
- ...field.options !== void 0 ? { options: [...field.options] } : {}
607
- });
608
- }
609
- }
610
- };
611
- visit(form ?? []);
612
- }
613
- function clusterIntoParagraphs(lines) {
614
- if (lines.length === 0) return [];
615
- const modalSpacing = estimateModalLineSpacing(lines);
616
- const dominantLeftX = modeOf(lines.map((l) => l.items[0].xPt), 1);
617
- const paragraphs = [{ lines: [lines[0]] }];
618
- for (let i = 1; i < lines.length; i++) {
619
- const prev = lines[i - 1];
620
- const next = lines[i];
621
- if (startsNewParagraph(prev, next, modalSpacing, dominantLeftX)) paragraphs.push({ lines: [next] });
622
- else paragraphs[paragraphs.length - 1].lines.push(next);
623
- }
624
- return paragraphs;
625
- }
626
- function startsNewParagraph(prev, next, modalSpacing, dominantLeftX) {
627
- if (prev.baselineY - next.baselineY > PARAGRAPH_GAP_MULTIPLIER * modalSpacing) return true;
628
- if (!fontSizesClose(prev.items[0].sizePt, next.items[0].sizePt)) return true;
629
- const nextLeft = next.items[0].xPt;
630
- const prevLeft = prev.items[0].xPt;
631
- const emPt = next.items[0].sizePt;
632
- const nextIndented = Math.abs(nextLeft - dominantLeftX) > emPt;
633
- const prevAtMargin = Math.abs(prevLeft - dominantLeftX) <= emPt;
634
- return nextIndented && prevAtMargin;
635
- }
636
- const LEFT_ALIGN_TOLERANCE_PT = 2;
637
- function paragraphToContentParagraph(paragraph, pageIndex, headingLevel) {
638
- const dominantLeftX = modeOf(paragraph.lines.map((l) => l.items[0].xPt), 1);
639
- const result = {
640
- kind: "paragraph",
641
- runs: [],
642
- alignment: paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0,
643
- ...headingLevel !== void 0 ? {
644
- styleId: `Heading${String(headingLevel)}`,
645
- headingLevel
646
- } : {}
647
- };
648
- paragraph.lines.forEach((line, lineIndex) => {
649
- require_layout_shared.stampFrame(result, pageIndex, lineBox(line, pageIndex));
650
- if (lineIndex > 0) {
651
- const lastRun = result.runs[result.runs.length - 1];
652
- if (lastRun !== void 0) lastRun.text += " ";
653
- }
654
- pushRunsForLine(result.runs, line, pageIndex);
655
- });
656
- if (headingLevel !== void 0) result.runs = result.runs.map((run) => {
657
- if (run.bold !== true) return run;
658
- const withoutBold = { ...run };
659
- delete withoutBold.bold;
660
- return withoutBold;
661
- });
662
- return result;
663
- }
664
- function reconstructPresentation(doc, options) {
665
- const signal = options?.signal;
666
- const structure = indexStructure(doc);
667
- const slides = doc.pages.map((page, pageIndex) => {
668
- require_ports_abort.throwIfAborted(signal);
669
- return reconstructSlide(page, pageIndex, doc.images, structure);
670
- });
671
- return {
672
- kind: "presentation",
673
- metadata: doc.metadata,
674
- slides
675
- };
676
- }
677
- function reconstructSlide(page, pageIndex, images, structure) {
678
- const recoveredTables = recoverTables(page, pageIndex, structure);
679
- const consumedText = /* @__PURE__ */ new Set();
680
- const claimedItems = /* @__PURE__ */ new Set();
681
- for (const recovered of recoveredTables) {
682
- for (const item of recovered.consumedText) consumedText.add(item);
683
- for (const item of recovered.latticeItems) claimedItems.add(item);
684
- }
685
- const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
686
- const imageItems = page.items.filter((i) => i.kind === "image");
687
- const textShapes = clusterIntoBlocks(clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt, pageIndex));
688
- const imageShapes = [];
689
- for (const img of imageItems) {
690
- const shape = imageToShape(img, page.heightPt, pageIndex, images);
691
- if (shape !== void 0) imageShapes.push(shape);
692
- }
693
- const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
694
- const vectorShapes = recoveredVectors === void 0 ? [] : [wrapBlockInShape(recoveredVectors.block, {
695
- xPt: 0,
696
- yPt: 0,
697
- widthPt: page.widthPt,
698
- heightPt: page.heightPt
699
- }, page.heightPt, pageIndex)];
700
- const tableShapes = recoveredTables.map((recovered) => wrapBlockInShape(recovered.table, recovered.frame, page.heightPt, pageIndex));
701
- return {
702
- size: {
703
- widthPt: page.widthPt,
704
- heightPt: page.heightPt
705
- },
706
- shapes: [
707
- ...vectorShapes,
708
- ...imageShapes,
709
- ...tableShapes,
710
- ...textShapes
711
- ],
712
- notes: page.notes ?? ""
713
- };
714
- }
715
- function wrapBlockInShape(block, frame, pageHeightPt, pageIndex) {
716
- const shape = {
717
- frame,
718
- insetLeftPt: 0,
719
- insetTopPt: 0,
720
- insetRightPt: 0,
721
- insetBottomPt: 0,
722
- blocks: [block]
723
- };
724
- require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(frame, pageHeightPt));
725
- return shape;
726
- }
727
- function splitLineByLargeGaps(line) {
728
- const segments = [];
729
- let current = [];
730
- line.items.forEach((item, i) => {
731
- if (i > 0) {
732
- const prev = line.items[i - 1];
733
- if (gapExceeds(prev, item, LARGE_GAP_EM_MULTIPLIER * item.sizePt)) {
734
- segments.push({
735
- items: current,
736
- baselineY: line.baselineY
737
- });
738
- current = [];
739
- }
740
- }
741
- current.push(item);
742
- });
743
- if (current.length > 0) segments.push({
744
- items: current,
745
- baselineY: line.baselineY
746
- });
747
- return segments;
748
- }
749
- const FONT_SIZE_CLOSE_TOLERANCE_PT = 1;
750
- const FONT_SIZE_CLOSE_TOLERANCE_RATIO = .15;
751
- function fontSizesClose(a, b) {
752
- return Math.abs(a - b) <= FONT_SIZE_CLOSE_TOLERANCE_PT || Math.abs(a - b) / Math.max(a, b) <= FONT_SIZE_CLOSE_TOLERANCE_RATIO;
753
- }
754
- function clusterIntoBlocks(pageLines) {
755
- const segments = pageLines.flatMap(splitLineByLargeGaps);
756
- const blocks = [];
757
- for (const segment of segments) {
758
- const leftX = segment.items[0].xPt;
759
- const sizePt = segment.items[0].sizePt;
760
- const matched = blocks.find((block) => {
761
- const lastLine = block.lines[block.lines.length - 1];
762
- const lastLeftX = lastLine.items[0].xPt;
763
- const lastSizePt = lastLine.items[0].sizePt;
764
- const gap = lastLine.baselineY - segment.baselineY;
765
- if (gap <= 0) return false;
766
- return Math.abs(leftX - lastLeftX) <= LEFT_ALIGN_TOLERANCE_PT && fontSizesClose(sizePt, lastSizePt) && gap <= PARAGRAPH_GAP_MULTIPLIER * lastSizePt;
767
- });
768
- if (matched !== void 0) matched.lines.push(segment);
769
- else blocks.push({ lines: [segment] });
770
- }
771
- return blocks;
772
- }
773
- function computeBlockFrame(block, slideHeightPt) {
774
- let minX = Number.POSITIVE_INFINITY;
775
- let maxX = Number.NEGATIVE_INFINITY;
776
- let minY = Number.POSITIVE_INFINITY;
777
- let maxY = Number.NEGATIVE_INFINITY;
778
- for (const line of block.lines) for (const item of line.items) {
779
- const { ascentPt, descentPt } = textItemVerticalExtent(item);
780
- minX = Math.min(minX, item.xPt);
781
- maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
782
- minY = Math.min(minY, item.yPt - descentPt);
783
- maxY = Math.max(maxY, item.yPt + ascentPt);
784
- }
785
- return require_model_geometry.flipY({
786
- xPt: minX,
787
- yPt: minY,
788
- widthPt: maxX - minX,
789
- heightPt: maxY - minY
790
- }, slideHeightPt);
791
- }
792
- function lineToParagraph(line, pageIndex) {
793
- const paragraph = {
794
- kind: "paragraph",
795
- runs: []
796
- };
797
- require_layout_shared.stampFrame(paragraph, pageIndex, lineBox(line, pageIndex));
798
- pushRunsForLine(paragraph.runs, line, pageIndex);
799
- return paragraph;
800
- }
801
- function blockToShape(block, slideHeightPt, pageIndex) {
802
- const shape = {
803
- frame: computeBlockFrame(block, slideHeightPt),
804
- insetLeftPt: 0,
805
- insetTopPt: 0,
806
- insetRightPt: 0,
807
- insetBottomPt: 0,
808
- blocks: block.lines.map((line) => lineToParagraph(line, pageIndex))
809
- };
810
- require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(shape.frame, slideHeightPt));
811
- return shape;
812
- }
813
- function imageToShape(img, slideHeightPt, pageIndex, images) {
814
- const asset = images[img.imageId];
815
- if (asset === void 0) return;
816
- const frame = require_model_geometry.flipY({
817
- xPt: img.xPt,
818
- yPt: img.yPt,
819
- widthPt: img.widthPt,
820
- heightPt: img.heightPt
821
- }, slideHeightPt);
822
- const block = {
823
- kind: "image",
824
- format: asset.format,
825
- base64: asset.base64,
826
- widthPt: img.widthPt,
827
- heightPt: img.heightPt
828
- };
829
- require_layout_shared.stampFrame(block, pageIndex, {
830
- xPt: img.xPt,
831
- yPt: img.yPt,
832
- widthPt: img.widthPt,
833
- heightPt: img.heightPt
834
- });
835
- const shape = {
836
- frame,
837
- rotationDeg: img.rotationDeg !== void 0 ? -img.rotationDeg : void 0,
838
- insetLeftPt: 0,
839
- insetTopPt: 0,
840
- insetRightPt: 0,
841
- insetBottomPt: 0,
842
- blocks: [block]
843
- };
844
- require_layout_shared.stampFrame(shape, pageIndex, {
845
- xPt: img.xPt,
846
- yPt: img.yPt,
847
- widthPt: img.widthPt,
848
- heightPt: img.heightPt
849
- });
850
- return shape;
851
- }
852
- function reconstructDrawing(doc, options) {
853
- const signal = options?.signal;
854
- const pages = doc.pages.map((page, pageIndex) => {
855
- require_ports_abort.throwIfAborted(signal);
856
- return reconstructDrawPage(page, pageIndex, doc.images);
857
- });
858
- return {
859
- kind: "drawing",
860
- metadata: doc.metadata,
861
- pages
862
- };
863
- }
864
- function reconstructDrawPage(page, pageIndex, images) {
865
- const vectors = [];
866
- const shapes = [];
867
- let paintOrder = 0;
868
- for (const item of page.items) {
869
- const vector = layoutItemToVector(item, page.heightPt);
870
- if (vector !== void 0) {
871
- stampVectorFrame(vector, item, pageIndex);
872
- vectors.push({
873
- ...vector,
874
- paintOrder: paintOrder++
875
- });
876
- continue;
877
- }
878
- if (item.kind === "text") {
879
- const shape = layoutTextToShape(item, page.heightPt, pageIndex);
880
- require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(shape.frame, page.heightPt));
881
- shapes.push({
882
- ...shape,
883
- paintOrder: paintOrder++
884
- });
885
- } else if (item.kind === "image") {
886
- const shape = imageToShape(item, page.heightPt, pageIndex, images);
887
- if (shape !== void 0) shapes.push({
888
- ...shape,
889
- paintOrder: paintOrder++
890
- });
891
- }
892
- }
893
- return {
894
- size: {
895
- widthPt: page.widthPt,
896
- heightPt: page.heightPt
897
- },
898
- shapes,
899
- vectors
900
- };
901
- }
902
- function stampVectorFrame(vector, item, pageIndex) {
903
- if (item.kind === "rect" || item.kind === "ellipse") {
904
- require_layout_shared.stampFrame(vector, pageIndex, {
905
- xPt: item.xPt,
906
- yPt: item.yPt,
907
- widthPt: item.widthPt,
908
- heightPt: item.heightPt
909
- });
910
- return;
911
- }
912
- if (item.kind === "line") {
913
- require_layout_shared.stampFrame(vector, pageIndex, {
914
- xPt: Math.min(item.x1Pt, item.x2Pt),
915
- yPt: Math.min(item.y1Pt, item.y2Pt),
916
- widthPt: Math.abs(item.x2Pt - item.x1Pt),
917
- heightPt: Math.abs(item.y2Pt - item.y1Pt)
918
- });
919
- return;
920
- }
921
- if (item.kind !== "path") return;
922
- const points = collectPathPoints(item.subpaths);
923
- let minX = Number.POSITIVE_INFINITY;
924
- let maxX = Number.NEGATIVE_INFINITY;
925
- let minY = Number.POSITIVE_INFINITY;
926
- let maxY = Number.NEGATIVE_INFINITY;
927
- for (const point of points) {
928
- minX = Math.min(minX, point.xPt);
929
- maxX = Math.max(maxX, point.xPt);
930
- minY = Math.min(minY, point.yPt);
931
- maxY = Math.max(maxY, point.yPt);
932
- }
933
- require_layout_shared.stampFrame(vector, pageIndex, {
934
- xPt: minX,
935
- yPt: minY,
936
- widthPt: maxX - minX,
937
- heightPt: maxY - minY
938
- });
939
- }
940
- function layoutItemToVector(item, pageHeightPt) {
941
- if (item.kind === "rect") return layoutRectToVector(item, pageHeightPt);
942
- if (item.kind === "ellipse") return layoutEllipseToVector(item, pageHeightPt);
943
- if (item.kind === "line") return layoutLineToVector(item, pageHeightPt);
944
- if (item.kind === "path") return layoutPathToVector(item, pageHeightPt);
945
- }
946
- function layoutRectToVector(item, pageHeightPt) {
947
- return {
948
- kind: "rect",
949
- frame: require_model_geometry.flipY({
950
- xPt: item.xPt,
951
- yPt: item.yPt,
952
- widthPt: item.widthPt,
953
- heightPt: item.heightPt
954
- }, pageHeightPt),
955
- fill: item.fill,
956
- stroke: item.stroke,
957
- sourcePath: item.sourcePath
958
- };
959
- }
960
- function layoutEllipseToVector(item, pageHeightPt) {
961
- return {
962
- kind: "ellipse",
963
- frame: require_model_geometry.flipY({
964
- xPt: item.xPt,
965
- yPt: item.yPt,
966
- widthPt: item.widthPt,
967
- heightPt: item.heightPt
968
- }, pageHeightPt),
969
- fill: item.fill,
970
- stroke: item.stroke,
971
- sourcePath: item.sourcePath
972
- };
973
- }
974
- function layoutLineToVector(item, pageHeightPt) {
975
- return {
976
- kind: "line",
977
- from: {
978
- xPt: item.x1Pt,
979
- yPt: pageHeightPt - item.y1Pt
980
- },
981
- to: {
982
- xPt: item.x2Pt,
983
- yPt: pageHeightPt - item.y2Pt
984
- },
985
- stroke: {
986
- color: item.color,
987
- widthPt: item.widthPt
988
- },
989
- sourcePath: item.sourcePath
990
- };
991
- }
992
- function collectPathPoints(subpaths) {
993
- const points = [];
994
- for (const subpath of subpaths) {
995
- points.push({
996
- xPt: subpath.startXPt,
997
- yPt: subpath.startYPt
998
- });
999
- for (const segment of subpath.segments) {
1000
- if (segment.kind === "cubic") {
1001
- points.push({
1002
- xPt: segment.c1xPt,
1003
- yPt: segment.c1yPt
1004
- });
1005
- points.push({
1006
- xPt: segment.c2xPt,
1007
- yPt: segment.c2yPt
1008
- });
1009
- }
1010
- points.push({
1011
- xPt: segment.xPt,
1012
- yPt: segment.yPt
1013
- });
1014
- }
1015
- }
1016
- return points;
1017
- }
1018
- function pathBoundingFrame(points, pageHeightPt) {
1019
- if (points.length === 0) return {
1020
- xPt: 0,
1021
- yPt: 0,
1022
- widthPt: 0,
1023
- heightPt: 0
1024
- };
1025
- let minX = Number.POSITIVE_INFINITY;
1026
- let maxX = Number.NEGATIVE_INFINITY;
1027
- let minYDown = Number.POSITIVE_INFINITY;
1028
- let maxYDown = Number.NEGATIVE_INFINITY;
1029
- for (const point of points) {
1030
- const yDown = pageHeightPt - point.yPt;
1031
- minX = Math.min(minX, point.xPt);
1032
- maxX = Math.max(maxX, point.xPt);
1033
- minYDown = Math.min(minYDown, yDown);
1034
- maxYDown = Math.max(maxYDown, yDown);
1035
- }
1036
- return {
1037
- xPt: minX,
1038
- yPt: minYDown,
1039
- widthPt: maxX - minX,
1040
- heightPt: maxYDown - minYDown
1041
- };
1042
- }
1043
- function localizePathPoint(frame, point, pageHeightPt) {
1044
- return {
1045
- xPt: point.xPt - frame.xPt,
1046
- yPt: pageHeightPt - frame.yPt - point.yPt
1047
- };
1048
- }
1049
- function layoutPathToVector(item, pageHeightPt) {
1050
- const frame = pathBoundingFrame(collectPathPoints(item.subpaths), pageHeightPt);
1051
- return {
1052
- kind: "path",
1053
- frame,
1054
- subpaths: item.subpaths.map((subpath) => ({
1055
- start: localizePathPoint(frame, {
1056
- xPt: subpath.startXPt,
1057
- yPt: subpath.startYPt
1058
- }, pageHeightPt),
1059
- closed: subpath.closed,
1060
- segments: subpath.segments.map((segment) => {
1061
- if (segment.kind === "line") return {
1062
- kind: "line",
1063
- to: localizePathPoint(frame, {
1064
- xPt: segment.xPt,
1065
- yPt: segment.yPt
1066
- }, pageHeightPt)
1067
- };
1068
- return {
1069
- kind: "cubic",
1070
- control1: localizePathPoint(frame, {
1071
- xPt: segment.c1xPt,
1072
- yPt: segment.c1yPt
1073
- }, pageHeightPt),
1074
- control2: localizePathPoint(frame, {
1075
- xPt: segment.c2xPt,
1076
- yPt: segment.c2yPt
1077
- }, pageHeightPt),
1078
- to: localizePathPoint(frame, {
1079
- xPt: segment.xPt,
1080
- yPt: segment.yPt
1081
- }, pageHeightPt)
1082
- };
1083
- })
1084
- })),
1085
- fill: item.fill,
1086
- fillRule: item.fillRule,
1087
- stroke: item.stroke,
1088
- sourcePath: item.sourcePath
1089
- };
1090
- }
1091
- function layoutTextToShape(item, pageHeightPt, pageIndex) {
1092
- const frame = computeBlockFrame({ lines: [{
1093
- items: [item],
1094
- baselineY: item.yPt
1095
- }] }, pageHeightPt);
1096
- const run = textItemToContentRun(item);
1097
- require_layout_shared.stampFrame(run, pageIndex, textBoxOfItem(item, pageIndex));
1098
- const paragraph = {
1099
- kind: "paragraph",
1100
- runs: [run]
1101
- };
1102
- require_layout_shared.stampFrame(paragraph, pageIndex, textBoxOfItem(item, pageIndex));
1103
- return {
1104
- frame,
1105
- rotationDeg: item.rotationDeg !== void 0 ? -item.rotationDeg : void 0,
1106
- insetLeftPt: 0,
1107
- insetTopPt: 0,
1108
- insetRightPt: 0,
1109
- insetBottomPt: 0,
1110
- blocks: [paragraph]
1111
- };
1112
- }
1113
- function vectorTopYDownPt(vector) {
1114
- return vector.kind === "line" ? Math.min(vector.from.yPt, vector.to.yPt) : vector.frame.yPt;
1115
- }
1116
- function recoverPageVectors(page, pageIndex, excluded) {
1117
- const vectors = [];
1118
- for (const item of page.items) {
1119
- if (excluded.has(item)) continue;
1120
- const vector = layoutItemToVector(item, page.heightPt);
1121
- if (vector !== void 0) {
1122
- stampVectorFrame(vector, item, pageIndex);
1123
- vectors.push({
1124
- ...vector,
1125
- paintOrder: vectors.length
1126
- });
1127
- }
1128
- }
1129
- if (vectors.length === 0) return;
1130
- const topYDownPt = Math.min(...vectors.map(vectorTopYDownPt));
1131
- const block = require_model_embedded_drawing.buildDrawingBlock({
1132
- widthPt: page.widthPt,
1133
- heightPt: page.heightPt
1134
- }, vectors);
1135
- require_layout_shared.stampFrame(block, pageIndex, {
1136
- xPt: 0,
1137
- yPt: 0,
1138
- widthPt: page.widthPt,
1139
- heightPt: page.heightPt
1140
- });
1141
- return {
1142
- block,
1143
- topYPt: page.heightPt - topYDownPt
1144
- };
1145
- }
1146
- function recoverTables(page, pageIndex, structure) {
1147
- if (structure !== void 0) {
1148
- const tagged = recoverTaggedTables(page, pageIndex, structure);
1149
- if (tagged.length > 0) return tagged;
1150
- }
1151
- const lattice = recoverTable(page, pageIndex);
1152
- return lattice === void 0 ? [] : [lattice];
1153
- }
1154
- function recoverTaggedTables(page, pageIndex, structure) {
1155
- const cellsByTable = /* @__PURE__ */ new Map();
1156
- for (const item of page.items) {
1157
- if (item.kind !== "text") continue;
1158
- const cell = nearestOfType(structure.nodeOfItem(item), CELL_TYPES);
1159
- const row = nearestOfType(cell?.parent, ROW_TYPES);
1160
- const table = nearestOfType(row?.parent, TABLE_TYPES);
1161
- if (cell === void 0 || row === void 0 || table === void 0) continue;
1162
- const entry = cellsByTable.get(table.id) ?? {
1163
- table,
1164
- cellsById: /* @__PURE__ */ new Map()
1165
- };
1166
- const existing = entry.cellsById.get(cell.id);
1167
- if (existing === void 0) entry.cellsById.set(cell.id, {
1168
- table,
1169
- row,
1170
- cell,
1171
- items: [item]
1172
- });
1173
- else existing.items.push(item);
1174
- cellsByTable.set(table.id, entry);
1175
- }
1176
- if (cellsByTable.size === 0) return [];
1177
- const latticeItems = require_layout_lattice.detectGridLattice(page.items)?.sourceItems ?? NO_ITEMS;
1178
- const recovered = [];
1179
- for (const { cellsById } of cellsByTable.values()) {
1180
- const cells = [...cellsById.values()];
1181
- const rowsById = /* @__PURE__ */ new Map();
1182
- for (const cellEntry of cells) {
1183
- const rowEntry = rowsById.get(cellEntry.row.id) ?? {
1184
- row: cellEntry.row,
1185
- cells: []
1186
- };
1187
- rowEntry.cells.push(cellEntry);
1188
- rowsById.set(cellEntry.row.id, rowEntry);
1189
- }
1190
- const rows = [...rowsById.values()].sort((a, b) => a.row.order - b.row.order);
1191
- for (const row of rows) row.cells.sort((a, b) => a.cell.order - b.cell.order);
1192
- const columnCount = Math.max(...rows.map((row) => row.cells.length));
1193
- const columns = [];
1194
- for (let j = 0; j < columnCount; j++) {
1195
- let minX = Number.POSITIVE_INFINITY;
1196
- let maxX = Number.NEGATIVE_INFINITY;
1197
- for (const row of rows) {
1198
- const cellEntry = row.cells[j];
1199
- if (cellEntry === void 0) continue;
1200
- for (const item of cellEntry.items) {
1201
- minX = Math.min(minX, item.xPt);
1202
- maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1203
- }
1204
- }
1205
- const width = maxX - minX;
1206
- columns.push({ widthPt: width > 0 ? width : DEFAULT_COLUMN_WIDTH_FALLBACK_PT });
1207
- }
1208
- const allItems = cells.flatMap((cellEntry) => cellEntry.items);
1209
- const contentRows = rows.map((row) => {
1210
- const contentCells = [];
1211
- for (let j = 0; j < columnCount; j++) {
1212
- const cellEntry = row.cells[j];
1213
- const cell = { blocks: cellBlocksFromItems(cellEntry?.items ?? [], pageIndex) };
1214
- if (cellEntry !== void 0) require_layout_shared.stampFrame(cell, pageIndex, textItemsPdfBox(cellEntry.items));
1215
- contentCells.push(cell);
1216
- }
1217
- return { cells: contentCells };
1218
- });
1219
- const box = textItemsPdfBox(allItems);
1220
- const table = {
1221
- kind: "table",
1222
- rows: contentRows,
1223
- columns
1224
- };
1225
- require_layout_shared.stampFrame(table, pageIndex, box);
1226
- recovered.push({
1227
- table,
1228
- frame: require_model_geometry.flipY(box, page.heightPt),
1229
- topYPt: box.yPt + box.heightPt,
1230
- consumedText: new Set(allItems),
1231
- latticeItems
1232
- });
1233
- }
1234
- return recovered;
1235
- }
1236
- function textItemsPdfBox(items) {
1237
- let minX = Number.POSITIVE_INFINITY;
1238
- let maxX = Number.NEGATIVE_INFINITY;
1239
- let minY = Number.POSITIVE_INFINITY;
1240
- let maxY = Number.NEGATIVE_INFINITY;
1241
- for (const item of items) {
1242
- const { ascentPt, descentPt } = textItemVerticalExtent(item);
1243
- minX = Math.min(minX, item.xPt);
1244
- maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1245
- minY = Math.min(minY, item.yPt - descentPt);
1246
- maxY = Math.max(maxY, item.yPt + ascentPt);
1247
- }
1248
- return {
1249
- xPt: minX,
1250
- yPt: minY,
1251
- widthPt: maxX - minX,
1252
- heightPt: maxY - minY
1253
- };
1254
- }
1255
- function cellBlocksFromItems(items, pageIndex) {
1256
- return clusterIntoLines(items).map((line) => lineToParagraph(line, pageIndex));
1257
- }
1258
- function indexRegions(lattice, rowCount, columnCount) {
1259
- const regionAt = Array.from({ length: rowCount }, () => new Array(columnCount));
1260
- for (const region of lattice.regions) for (let i = region.rowStart; i < region.rowEnd; i++) for (let j = region.colStart; j < region.colEnd; j++) regionAt[i][j] = region;
1261
- return regionAt;
1262
- }
1263
- function recoverTable(page, pageIndex) {
1264
- const lattice = require_layout_lattice.detectGridLattice(page.items);
1265
- if (lattice === void 0) return;
1266
- const rowCount = lattice.rowBoundariesDescPt.length - 1;
1267
- const columnCount = lattice.columnBoundariesAscPt.length - 1;
1268
- const regionAt = indexRegions(lattice, rowCount, columnCount);
1269
- const textByRegion = /* @__PURE__ */ new Map();
1270
- const consumedText = /* @__PURE__ */ new Set();
1271
- for (const item of page.items) {
1272
- if (item.kind !== "text") continue;
1273
- const row = require_layout_lattice.findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
1274
- const column = require_layout_lattice.findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
1275
- if (row === void 0 || column === void 0) continue;
1276
- const region = regionAt[row][column];
1277
- const existing = textByRegion.get(region);
1278
- if (existing === void 0) textByRegion.set(region, [item]);
1279
- else existing.push(item);
1280
- consumedText.add(item);
1281
- }
1282
- if (consumedText.size === 0) return;
1283
- const columns = [];
1284
- for (let j = 0; j < columnCount; j++) columns.push({ widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j] });
1285
- const positionedRows = [];
1286
- for (let i = 0; i < rowCount; i++) {
1287
- const positioned = [];
1288
- for (let j = 0; j < columnCount; j++) {
1289
- const region = regionAt[i][j];
1290
- if (region.rowStart !== i || region.colStart !== j) continue;
1291
- const colSpan = region.colEnd - region.colStart;
1292
- const rowSpan = region.rowEnd - region.rowStart;
1293
- const cell = {
1294
- blocks: cellBlocksFromItems(textByRegion.get(region) ?? [], pageIndex),
1295
- colSpan: colSpan > 1 ? colSpan : void 0,
1296
- rowSpan: rowSpan > 1 ? rowSpan : void 0
1297
- };
1298
- const cellLeftXPt = lattice.columnBoundariesAscPt[region.colStart];
1299
- const cellRightXPt = lattice.columnBoundariesAscPt[region.colEnd];
1300
- const cellTopYPt = lattice.rowBoundariesDescPt[region.rowStart];
1301
- const cellBottomYPt = lattice.rowBoundariesDescPt[region.rowEnd];
1302
- require_layout_shared.stampFrame(cell, pageIndex, {
1303
- xPt: cellLeftXPt,
1304
- yPt: cellBottomYPt,
1305
- widthPt: cellRightXPt - cellLeftXPt,
1306
- heightPt: cellTopYPt - cellBottomYPt
1307
- });
1308
- positioned.push({
1309
- columnIndex: j,
1310
- cell
1311
- });
1312
- }
1313
- positionedRows.push({
1314
- cells: positioned,
1315
- heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
1316
- });
1317
- }
1318
- const rows = (0, document_schema_js.denseTableRows)(positionedRows, columnCount);
1319
- const leftXPt = lattice.columnBoundariesAscPt[0];
1320
- const rightXPt = lattice.columnBoundariesAscPt[columnCount];
1321
- const topYPt = lattice.rowBoundariesDescPt[0];
1322
- const bottomYPt = lattice.rowBoundariesDescPt[rowCount];
1323
- const pdfBox = {
1324
- xPt: leftXPt,
1325
- yPt: bottomYPt,
1326
- widthPt: rightXPt - leftXPt,
1327
- heightPt: topYPt - bottomYPt
1328
- };
1329
- const frame = require_model_geometry.flipY(pdfBox, page.heightPt);
1330
- const table = {
1331
- kind: "table",
1332
- rows,
1333
- columns
1334
- };
1335
- require_layout_shared.stampFrame(table, pageIndex, pdfBox);
1336
- return {
1337
- table,
1338
- frame,
1339
- topYPt,
1340
- consumedText,
1341
- latticeItems: lattice.sourceItems
1342
- };
1343
- }
1344
- function joinCellText(items) {
1345
- const sorted = [...items].sort((a, b) => a.xPt - b.xPt);
1346
- let text = "";
1347
- sorted.forEach((item, i) => {
1348
- if (i > 0) {
1349
- const prev = sorted[i - 1];
1350
- if (gapExceeds(prev, item, MIN_WORD_GAP_PT)) text += " ";
1351
- }
1352
- text += item.text;
1353
- });
1354
- return text;
1355
- }
1356
- function groupKey(row, column) {
1357
- return `${row},${column}`;
1358
- }
1359
- function addToGroup(groups, row, column, item) {
1360
- const key = groupKey(row, column);
1361
- const existing = groups.get(key);
1362
- if (existing === void 0) groups.set(key, [item]);
1363
- else existing.push(item);
1364
- }
1365
- function buildCellsFromGroups(groups, pageIndex, context) {
1366
- const cells = [];
1367
- for (const [key, items] of groups) {
1368
- const displayText = joinCellText(items);
1369
- if (displayText.length === 0) continue;
1370
- const [rowPart, columnPart] = key.split(",");
1371
- const row = Number(rowPart);
1372
- const column = Number(columnPart);
1373
- const cell = {
1374
- row,
1375
- column,
1376
- value: inferredCellValue(displayText, row, column, context),
1377
- displayText
1378
- };
1379
- require_layout_shared.stampFrame(cell, pageIndex, textItemsPdfBox(items));
1380
- cells.push(cell);
1381
- }
1382
- cells.sort((a, b) => a.row - b.row || a.column - b.column);
1383
- return cells;
1384
- }
1385
- function inferredCellValue(displayText, row, column, context) {
1386
- const inference = require_layout_cell_typing.inferCellValue(displayText);
1387
- if (inference === void 0) return {
1388
- kind: "string",
1389
- value: displayText
1390
- };
1391
- const reported = {
1392
- sheetIndex: context.sheetIndex,
1393
- row,
1394
- column,
1395
- displayText,
1396
- ...inference
1397
- };
1398
- context.sink?.(reported);
1399
- return inference.outcome === "retyped" ? inference.value : {
1400
- kind: "string",
1401
- value: displayText
1402
- };
1403
- }
1404
- function buildGridFromLattice(textItems, lattice, pageIndex, context) {
1405
- const groups = /* @__PURE__ */ new Map();
1406
- for (const item of textItems) {
1407
- const row = require_layout_lattice.findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
1408
- const column = require_layout_lattice.findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
1409
- if (row === void 0 || column === void 0) continue;
1410
- addToGroup(groups, row, column, item);
1411
- }
1412
- const columns = [];
1413
- for (let j = 0; j < lattice.columnBoundariesAscPt.length - 1; j++) columns.push({
1414
- index: j,
1415
- widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j]
1416
- });
1417
- const rows = [];
1418
- for (let i = 0; i < lattice.rowBoundariesDescPt.length - 1; i++) rows.push({
1419
- index: i,
1420
- heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
1421
- });
1422
- return {
1423
- cells: buildCellsFromGroups(groups, pageIndex, context),
1424
- columns,
1425
- rows,
1426
- gridlines: true
1427
- };
1428
- }
1429
- const COLUMN_ALIGNMENT_TOLERANCE_PT = 3;
1430
- const MIN_COLUMN_RECURRENCE = 2;
1431
- function detectColumnPositions(segmentsByLine) {
1432
- const allXs = segmentsByLine.flatMap((segments) => segments.map((segment) => segment.items[0].xPt));
1433
- if (allXs.length === 0) return [];
1434
- const counts = bucketCounts(allXs, COLUMN_ALIGNMENT_TOLERANCE_PT);
1435
- const recurring = [...counts.entries()].filter(([, count]) => count >= MIN_COLUMN_RECURRENCE).map(([bucket]) => bucket);
1436
- const positions = recurring.length > 0 ? recurring : [...counts.keys()];
1437
- positions.sort((a, b) => a - b);
1438
- return positions;
1439
- }
1440
- function nearestColumnIndex(positions, xPt) {
1441
- let bestIndex = 0;
1442
- let bestDistancePt = Number.POSITIVE_INFINITY;
1443
- positions.forEach((position, index) => {
1444
- const distancePt = Math.abs(position - xPt);
1445
- if (distancePt < bestDistancePt) {
1446
- bestDistancePt = distancePt;
1447
- bestIndex = index;
1448
- }
1449
- });
1450
- return bestIndex;
1451
- }
1452
- function lastColumnWidthPt(groups, columnIndex, anchorXPt) {
1453
- let maxWidthPt = 0;
1454
- for (const [key, items] of groups) {
1455
- const [, columnPart] = key.split(",");
1456
- if (Number(columnPart) !== columnIndex) continue;
1457
- for (const item of items) maxWidthPt = Math.max(maxWidthPt, item.xPt + (item.widthPt ?? 0) - anchorXPt);
1458
- }
1459
- return maxWidthPt > 0 ? maxWidthPt : DEFAULT_COLUMN_WIDTH_FALLBACK_PT;
1460
- }
1461
- function buildGridFromTextClustering(textItems, pageIndex, context) {
1462
- const lines = clusterIntoLines(textItems);
1463
- if (lines.length === 0) return {
1464
- cells: [],
1465
- columns: [],
1466
- rows: [],
1467
- gridlines: false
1468
- };
1469
- const segmentsByLine = lines.map((l) => splitLineByLargeGaps(l));
1470
- const columnPositions = detectColumnPositions(segmentsByLine);
1471
- const groups = /* @__PURE__ */ new Map();
1472
- segmentsByLine.forEach((segments, rowIndex) => {
1473
- for (const segment of segments) {
1474
- const key = groupKey(rowIndex, nearestColumnIndex(columnPositions, segment.items[0].xPt));
1475
- const existing = groups.get(key);
1476
- if (existing === void 0) groups.set(key, [...segment.items]);
1477
- else existing.push(...segment.items);
1478
- }
1479
- });
1480
- const nominalRowHeightPt = estimateModalLineSpacing(lines);
1481
- const rows = lines.map((line, i) => {
1482
- const nextBaselineY = lines[i + 1]?.baselineY;
1483
- const heightPt = nextBaselineY !== void 0 ? line.baselineY - nextBaselineY : nominalRowHeightPt;
1484
- return {
1485
- index: i,
1486
- heightPt: heightPt > 0 ? heightPt : nominalRowHeightPt
1487
- };
1488
- });
1489
- const columns = columnPositions.map((position, j) => {
1490
- const nextPosition = columnPositions[j + 1];
1491
- return {
1492
- index: j,
1493
- widthPt: nextPosition !== void 0 ? nextPosition - position : lastColumnWidthPt(groups, j, position)
1494
- };
1495
- });
1496
- return {
1497
- cells: buildCellsFromGroups(groups, pageIndex, context),
1498
- columns,
1499
- rows,
1500
- gridlines: false
1501
- };
1502
- }
1503
- function reconstructSheet(page, pageIndex, sink) {
1504
- const textItems = page.items.filter((i) => i.kind === "text");
1505
- const lattice = require_layout_lattice.detectGridLattice(page.items);
1506
- const context = {
1507
- sheetIndex: pageIndex,
1508
- sink
1509
- };
1510
- const grid = lattice !== void 0 ? buildGridFromLattice(textItems, lattice, pageIndex, context) : buildGridFromTextClustering(textItems, pageIndex, context);
1511
- const printSettings = {
1512
- pageSize: {
1513
- widthPt: page.widthPt,
1514
- heightPt: page.heightPt
1515
- },
1516
- margins: ZERO_MARGINS,
1517
- gridlines: grid.gridlines,
1518
- headers: false,
1519
- pageOrder: "downThenOver"
1520
- };
1521
- return {
1522
- name: `Sheet${pageIndex + 1}`,
1523
- cells: grid.cells,
1524
- columns: grid.columns,
1525
- rows: grid.rows,
1526
- images: [],
1527
- printSettings
1528
- };
1529
- }
1530
- function reconstructSpreadsheet(doc, options) {
1531
- const signal = options?.signal;
1532
- const sheets = doc.pages.map((page, index) => {
1533
- require_ports_abort.throwIfAborted(signal);
1534
- return reconstructSheet(page, index, options?.onCellTypeInference);
1535
- });
1536
- return {
1537
- kind: "spreadsheet",
1538
- metadata: doc.metadata,
1539
- sheets
1540
- };
1541
- }
1542
- //#endregion
1543
- exports.reconstructDrawing = reconstructDrawing;
1544
- exports.reconstructPresentation = reconstructPresentation;
1545
- exports.reconstructSpreadsheet = reconstructSpreadsheet;
1546
- exports.reconstructWordprocessing = reconstructWordprocessing;
2
+ const require_reconstruct_presentations_prod = require("../reconstruct-presentations-prod-X315aBmI.cjs");
3
+ exports.CELL_TYPES = require_reconstruct_presentations_prod.CELL_TYPES;
4
+ exports.DEFAULT_COLUMN_WIDTH_FALLBACK_PT = require_reconstruct_presentations_prod.DEFAULT_COLUMN_WIDTH_FALLBACK_PT;
5
+ exports.NO_ITEMS = require_reconstruct_presentations_prod.NO_ITEMS;
6
+ exports.ROW_TYPES = require_reconstruct_presentations_prod.ROW_TYPES;
7
+ exports.TABLE_TYPES = require_reconstruct_presentations_prod.TABLE_TYPES;
8
+ exports.ZERO_MARGINS = require_reconstruct_presentations_prod.ZERO_MARGINS;
9
+ exports.indexStructure = require_reconstruct_presentations_prod.indexStructure;
10
+ exports.nearestOfType = require_reconstruct_presentations_prod.nearestOfType;
11
+ exports.reconstructSpreadsheet = require_reconstruct_presentations_prod.reconstructSpreadsheet;
12
+ exports.reconstructWordprocessing = require_reconstruct_presentations_prod.reconstructWordprocessing;