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
@@ -0,0 +1,1256 @@
1
+ import { flipY } from "./model/geometry.js";
2
+ import { buildDrawingBlock } from "./model/embedded-drawing.js";
3
+ import { stampFrame } from "./layout/shared.js";
4
+ import { inferCellValue } from "./layout/cell-typing.js";
5
+ import { throwIfAborted } from "./ports/abort.js";
6
+ import { HALF_POINT_BUCKET_PT, bucketCounts, clusterIntoLines, clusterIntoParagraphs, estimateModalLineSpacing, fontSizesClose, gapExceeds, lineBox, modeOf, paragraphToContentParagraph, pushRunsForLine, textBoxOfItem, textItemToContentRun, textItemVerticalExtent } from "./layout/reconstruct-lines.js";
7
+ import { detectGridLattice, findColumnIndex, findRowIndex } from "./layout/lattice.js";
8
+ import { denseTableRows } from "document-schema.js";
9
+ //#region src/layout/reconstruct-tables.ts
10
+ function recoverTables(page, pageIndex, structure) {
11
+ if (structure !== void 0) {
12
+ const tagged = recoverTaggedTables(page, pageIndex, structure);
13
+ if (tagged.length > 0) return tagged;
14
+ }
15
+ const lattice = recoverTable(page, pageIndex);
16
+ return lattice === void 0 ? [] : [lattice];
17
+ }
18
+ function recoverTaggedTables(page, pageIndex, structure) {
19
+ const cellsByTable = /* @__PURE__ */ new Map();
20
+ for (const item of page.items) {
21
+ if (item.kind !== "text") continue;
22
+ const cell = nearestOfType(structure.nodeOfItem(item), CELL_TYPES);
23
+ const row = nearestOfType(cell?.parent, ROW_TYPES);
24
+ const table = nearestOfType(row?.parent, TABLE_TYPES);
25
+ if (cell === void 0 || row === void 0 || table === void 0) continue;
26
+ const entry = cellsByTable.get(table.id) ?? {
27
+ table,
28
+ cellsById: /* @__PURE__ */ new Map()
29
+ };
30
+ const existing = entry.cellsById.get(cell.id);
31
+ if (existing === void 0) entry.cellsById.set(cell.id, {
32
+ table,
33
+ row,
34
+ cell,
35
+ items: [item]
36
+ });
37
+ else existing.items.push(item);
38
+ cellsByTable.set(table.id, entry);
39
+ }
40
+ if (cellsByTable.size === 0) return [];
41
+ const latticeItems = detectGridLattice(page.items)?.sourceItems ?? NO_ITEMS;
42
+ const recovered = [];
43
+ for (const { cellsById } of cellsByTable.values()) {
44
+ const cells = [...cellsById.values()];
45
+ const rowsById = /* @__PURE__ */ new Map();
46
+ for (const cellEntry of cells) {
47
+ const rowEntry = rowsById.get(cellEntry.row.id) ?? {
48
+ row: cellEntry.row,
49
+ cells: []
50
+ };
51
+ rowEntry.cells.push(cellEntry);
52
+ rowsById.set(cellEntry.row.id, rowEntry);
53
+ }
54
+ const rows = [...rowsById.values()].sort((a, b) => a.row.order - b.row.order);
55
+ for (const row of rows) row.cells.sort((a, b) => a.cell.order - b.cell.order);
56
+ const columnCount = Math.max(...rows.map((row) => row.cells.length));
57
+ const columns = [];
58
+ for (let j = 0; j < columnCount; j++) {
59
+ let minX = Number.POSITIVE_INFINITY;
60
+ let maxX = Number.NEGATIVE_INFINITY;
61
+ for (const row of rows) {
62
+ const cellEntry = row.cells[j];
63
+ if (cellEntry === void 0) continue;
64
+ for (const item of cellEntry.items) {
65
+ minX = Math.min(minX, item.xPt);
66
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
67
+ }
68
+ }
69
+ const width = maxX - minX;
70
+ columns.push({ widthPt: width > 0 ? width : 40 });
71
+ }
72
+ const allItems = cells.flatMap((cellEntry) => cellEntry.items);
73
+ const contentRows = rows.map((row) => {
74
+ const contentCells = [];
75
+ for (let j = 0; j < columnCount; j++) {
76
+ const cellEntry = row.cells[j];
77
+ const cell = { blocks: cellBlocksFromItems(cellEntry?.items ?? [], pageIndex) };
78
+ if (cellEntry !== void 0) stampFrame(cell, pageIndex, textItemsPdfBox(cellEntry.items));
79
+ contentCells.push(cell);
80
+ }
81
+ return { cells: contentCells };
82
+ });
83
+ const box = textItemsPdfBox(allItems);
84
+ const table = {
85
+ kind: "table",
86
+ rows: contentRows,
87
+ columns
88
+ };
89
+ stampFrame(table, pageIndex, box);
90
+ recovered.push({
91
+ table,
92
+ frame: flipY(box, page.heightPt),
93
+ topYPt: box.yPt + box.heightPt,
94
+ consumedText: new Set(allItems),
95
+ latticeItems
96
+ });
97
+ }
98
+ return recovered;
99
+ }
100
+ function textItemsPdfBox(items) {
101
+ let minX = Number.POSITIVE_INFINITY;
102
+ let maxX = Number.NEGATIVE_INFINITY;
103
+ let minY = Number.POSITIVE_INFINITY;
104
+ let maxY = Number.NEGATIVE_INFINITY;
105
+ for (const item of items) {
106
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
107
+ minX = Math.min(minX, item.xPt);
108
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
109
+ minY = Math.min(minY, item.yPt - descentPt);
110
+ maxY = Math.max(maxY, item.yPt + ascentPt);
111
+ }
112
+ return {
113
+ xPt: minX,
114
+ yPt: minY,
115
+ widthPt: maxX - minX,
116
+ heightPt: maxY - minY
117
+ };
118
+ }
119
+ function cellBlocksFromItems(items, pageIndex) {
120
+ return clusterIntoLines(items).map((line) => lineToParagraph(line, pageIndex));
121
+ }
122
+ function indexRegions(lattice, rowCount, columnCount) {
123
+ const regionAt = Array.from({ length: rowCount }, () => new Array(columnCount));
124
+ 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;
125
+ return regionAt;
126
+ }
127
+ function recoverTable(page, pageIndex) {
128
+ const lattice = detectGridLattice(page.items);
129
+ if (lattice === void 0) return;
130
+ const rowCount = lattice.rowBoundariesDescPt.length - 1;
131
+ const columnCount = lattice.columnBoundariesAscPt.length - 1;
132
+ const regionAt = indexRegions(lattice, rowCount, columnCount);
133
+ const textByRegion = /* @__PURE__ */ new Map();
134
+ const consumedText = /* @__PURE__ */ new Set();
135
+ for (const item of page.items) {
136
+ if (item.kind !== "text") continue;
137
+ const row = findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
138
+ const column = findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
139
+ if (row === void 0 || column === void 0) continue;
140
+ const region = regionAt[row][column];
141
+ const existing = textByRegion.get(region);
142
+ if (existing === void 0) textByRegion.set(region, [item]);
143
+ else existing.push(item);
144
+ consumedText.add(item);
145
+ }
146
+ if (consumedText.size === 0) return;
147
+ const columns = [];
148
+ for (let j = 0; j < columnCount; j++) columns.push({ widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j] });
149
+ const positionedRows = [];
150
+ for (let i = 0; i < rowCount; i++) {
151
+ const positioned = [];
152
+ for (let j = 0; j < columnCount; j++) {
153
+ const region = regionAt[i][j];
154
+ if (region.rowStart !== i || region.colStart !== j) continue;
155
+ const colSpan = region.colEnd - region.colStart;
156
+ const rowSpan = region.rowEnd - region.rowStart;
157
+ const cell = {
158
+ blocks: cellBlocksFromItems(textByRegion.get(region) ?? [], pageIndex),
159
+ colSpan: colSpan > 1 ? colSpan : void 0,
160
+ rowSpan: rowSpan > 1 ? rowSpan : void 0
161
+ };
162
+ const cellLeftXPt = lattice.columnBoundariesAscPt[region.colStart];
163
+ const cellRightXPt = lattice.columnBoundariesAscPt[region.colEnd];
164
+ const cellTopYPt = lattice.rowBoundariesDescPt[region.rowStart];
165
+ const cellBottomYPt = lattice.rowBoundariesDescPt[region.rowEnd];
166
+ stampFrame(cell, pageIndex, {
167
+ xPt: cellLeftXPt,
168
+ yPt: cellBottomYPt,
169
+ widthPt: cellRightXPt - cellLeftXPt,
170
+ heightPt: cellTopYPt - cellBottomYPt
171
+ });
172
+ positioned.push({
173
+ columnIndex: j,
174
+ cell
175
+ });
176
+ }
177
+ positionedRows.push({
178
+ cells: positioned,
179
+ heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
180
+ });
181
+ }
182
+ const rows = denseTableRows(positionedRows, columnCount);
183
+ const leftXPt = lattice.columnBoundariesAscPt[0];
184
+ const rightXPt = lattice.columnBoundariesAscPt[columnCount];
185
+ const topYPt = lattice.rowBoundariesDescPt[0];
186
+ const bottomYPt = lattice.rowBoundariesDescPt[rowCount];
187
+ const pdfBox = {
188
+ xPt: leftXPt,
189
+ yPt: bottomYPt,
190
+ widthPt: rightXPt - leftXPt,
191
+ heightPt: topYPt - bottomYPt
192
+ };
193
+ const frame = flipY(pdfBox, page.heightPt);
194
+ const table = {
195
+ kind: "table",
196
+ rows,
197
+ columns
198
+ };
199
+ stampFrame(table, pageIndex, pdfBox);
200
+ return {
201
+ table,
202
+ frame,
203
+ topYPt,
204
+ consumedText,
205
+ latticeItems: lattice.sourceItems
206
+ };
207
+ }
208
+ function joinCellText(items) {
209
+ const sorted = [...items].sort((a, b) => a.xPt - b.xPt);
210
+ let text = "";
211
+ sorted.forEach((item, i) => {
212
+ if (i > 0) {
213
+ const prev = sorted[i - 1];
214
+ if (gapExceeds(prev, item, .5)) text += " ";
215
+ }
216
+ text += item.text;
217
+ });
218
+ return text;
219
+ }
220
+ function groupKey(row, column) {
221
+ return `${row},${column}`;
222
+ }
223
+ function addToGroup(groups, row, column, item) {
224
+ const key = groupKey(row, column);
225
+ const existing = groups.get(key);
226
+ if (existing === void 0) groups.set(key, [item]);
227
+ else existing.push(item);
228
+ }
229
+ function buildCellsFromGroups(groups, pageIndex, context) {
230
+ const cells = [];
231
+ for (const [key, items] of groups) {
232
+ const displayText = joinCellText(items);
233
+ if (displayText.length === 0) continue;
234
+ const [rowPart, columnPart] = key.split(",");
235
+ const row = Number(rowPart);
236
+ const column = Number(columnPart);
237
+ const cell = {
238
+ row,
239
+ column,
240
+ value: inferredCellValue(displayText, row, column, context),
241
+ displayText
242
+ };
243
+ stampFrame(cell, pageIndex, textItemsPdfBox(items));
244
+ cells.push(cell);
245
+ }
246
+ cells.sort((a, b) => a.row - b.row || a.column - b.column);
247
+ return cells;
248
+ }
249
+ function inferredCellValue(displayText, row, column, context) {
250
+ const inference = inferCellValue(displayText);
251
+ if (inference === void 0) return {
252
+ kind: "string",
253
+ value: displayText
254
+ };
255
+ const reported = {
256
+ sheetIndex: context.sheetIndex,
257
+ row,
258
+ column,
259
+ displayText,
260
+ ...inference
261
+ };
262
+ context.sink?.(reported);
263
+ return inference.outcome === "retyped" ? inference.value : {
264
+ kind: "string",
265
+ value: displayText
266
+ };
267
+ }
268
+ function buildGridFromLattice(textItems, lattice, pageIndex, context) {
269
+ const groups = /* @__PURE__ */ new Map();
270
+ for (const item of textItems) {
271
+ const row = findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
272
+ const column = findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
273
+ if (row === void 0 || column === void 0) continue;
274
+ addToGroup(groups, row, column, item);
275
+ }
276
+ const columns = [];
277
+ for (let j = 0; j < lattice.columnBoundariesAscPt.length - 1; j++) columns.push({
278
+ index: j,
279
+ widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j]
280
+ });
281
+ const rows = [];
282
+ for (let i = 0; i < lattice.rowBoundariesDescPt.length - 1; i++) rows.push({
283
+ index: i,
284
+ heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
285
+ });
286
+ return {
287
+ cells: buildCellsFromGroups(groups, pageIndex, context),
288
+ columns,
289
+ rows,
290
+ gridlines: true
291
+ };
292
+ }
293
+ const COLUMN_ALIGNMENT_TOLERANCE_PT = 3;
294
+ const MIN_COLUMN_RECURRENCE = 2;
295
+ function detectColumnPositions(segmentsByLine) {
296
+ const allXs = segmentsByLine.flatMap((segments) => segments.map((segment) => segment.items[0].xPt));
297
+ if (allXs.length === 0) return [];
298
+ const counts = bucketCounts(allXs, COLUMN_ALIGNMENT_TOLERANCE_PT);
299
+ const recurring = [...counts.entries()].filter(([, count]) => count >= MIN_COLUMN_RECURRENCE).map(([bucket]) => bucket);
300
+ const positions = recurring.length > 0 ? recurring : [...counts.keys()];
301
+ positions.sort((a, b) => a - b);
302
+ return positions;
303
+ }
304
+ function nearestColumnIndex(positions, xPt) {
305
+ let bestIndex = 0;
306
+ let bestDistancePt = Number.POSITIVE_INFINITY;
307
+ positions.forEach((position, index) => {
308
+ const distancePt = Math.abs(position - xPt);
309
+ if (distancePt < bestDistancePt) {
310
+ bestDistancePt = distancePt;
311
+ bestIndex = index;
312
+ }
313
+ });
314
+ return bestIndex;
315
+ }
316
+ function lastColumnWidthPt(groups, columnIndex, anchorXPt) {
317
+ let maxWidthPt = 0;
318
+ for (const [key, items] of groups) {
319
+ const [, columnPart] = key.split(",");
320
+ if (Number(columnPart) !== columnIndex) continue;
321
+ for (const item of items) maxWidthPt = Math.max(maxWidthPt, item.xPt + (item.widthPt ?? 0) - anchorXPt);
322
+ }
323
+ return maxWidthPt > 0 ? maxWidthPt : 40;
324
+ }
325
+ function buildGridFromTextClustering(textItems, pageIndex, context) {
326
+ const lines = clusterIntoLines(textItems);
327
+ if (lines.length === 0) return {
328
+ cells: [],
329
+ columns: [],
330
+ rows: [],
331
+ gridlines: false
332
+ };
333
+ const segmentsByLine = lines.map((l) => splitLineByLargeGaps(l));
334
+ const columnPositions = detectColumnPositions(segmentsByLine);
335
+ const groups = /* @__PURE__ */ new Map();
336
+ segmentsByLine.forEach((segments, rowIndex) => {
337
+ for (const segment of segments) {
338
+ const key = groupKey(rowIndex, nearestColumnIndex(columnPositions, segment.items[0].xPt));
339
+ const existing = groups.get(key);
340
+ if (existing === void 0) groups.set(key, [...segment.items]);
341
+ else existing.push(...segment.items);
342
+ }
343
+ });
344
+ const nominalRowHeightPt = estimateModalLineSpacing(lines);
345
+ const rows = lines.map((line, i) => {
346
+ const nextBaselineY = lines[i + 1]?.baselineY;
347
+ const heightPt = nextBaselineY !== void 0 ? line.baselineY - nextBaselineY : nominalRowHeightPt;
348
+ return {
349
+ index: i,
350
+ heightPt: heightPt > 0 ? heightPt : nominalRowHeightPt
351
+ };
352
+ });
353
+ const columns = columnPositions.map((position, j) => {
354
+ const nextPosition = columnPositions[j + 1];
355
+ return {
356
+ index: j,
357
+ widthPt: nextPosition !== void 0 ? nextPosition - position : lastColumnWidthPt(groups, j, position)
358
+ };
359
+ });
360
+ return {
361
+ cells: buildCellsFromGroups(groups, pageIndex, context),
362
+ columns,
363
+ rows,
364
+ gridlines: false
365
+ };
366
+ }
367
+ //#endregion
368
+ //#region src/layout/reconstruct.ts
369
+ const DEFAULT_COLUMN_WIDTH_FALLBACK_PT = 40;
370
+ const NO_ITEMS = /* @__PURE__ */ new Set();
371
+ const ZERO_MARGINS = {
372
+ topPt: 0,
373
+ rightPt: 0,
374
+ bottomPt: 0,
375
+ leftPt: 0
376
+ };
377
+ function reconstructWordprocessing(doc, options) {
378
+ const signal = options?.signal;
379
+ doc = dropHiddenLayerContent(doc);
380
+ const headingLevels = headingSizeLevels(doc);
381
+ const structure = indexStructure(doc);
382
+ const sections = [];
383
+ let currentGroup = [];
384
+ let groupStartPageIndex = 0;
385
+ for (const page of doc.pages) {
386
+ throwIfAborted(signal);
387
+ if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
388
+ sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
389
+ groupStartPageIndex += currentGroup.length;
390
+ currentGroup = [];
391
+ }
392
+ currentGroup.push(page);
393
+ }
394
+ if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
395
+ return {
396
+ kind: "wordprocessing",
397
+ metadata: doc.metadata,
398
+ sections
399
+ };
400
+ }
401
+ function layerOf(item) {
402
+ return item.kind === "link" || item.kind === "internalLink" ? void 0 : item.layer;
403
+ }
404
+ function dropHiddenLayerContent(doc) {
405
+ const hidden = new Set((doc.layers ?? []).filter((layer) => !layer.visible).map((layer) => layer.name));
406
+ if (hidden.size === 0) return doc;
407
+ return {
408
+ ...doc,
409
+ pages: doc.pages.map((page) => ({
410
+ ...page,
411
+ items: page.items.filter((item) => layerOf(item) === void 0 || !hidden.has(layerOf(item)))
412
+ }))
413
+ };
414
+ }
415
+ const HEADING_LEVELS = new Map([
416
+ "H1",
417
+ "H2",
418
+ "H3",
419
+ "H4",
420
+ "H5",
421
+ "H6"
422
+ ].map((tag, index) => [tag, index + 1]));
423
+ const DIVISION_TYPES = /* @__PURE__ */ new Set([
424
+ "Part",
425
+ "Sect",
426
+ "Div"
427
+ ]);
428
+ const CELL_TYPES = /* @__PURE__ */ new Set(["TD", "TH"]);
429
+ const ROW_TYPES = /* @__PURE__ */ new Set(["TR"]);
430
+ const TABLE_TYPES = /* @__PURE__ */ new Set(["Table"]);
431
+ function indexStructure(doc) {
432
+ if (doc.structure === void 0 || doc.structure.length === 0) return;
433
+ const byId = /* @__PURE__ */ new Map();
434
+ let order = 0;
435
+ const walk = (element, parent) => {
436
+ const node = {
437
+ id: element.id,
438
+ type: element.type,
439
+ parent,
440
+ order: order++
441
+ };
442
+ byId.set(element.id, node);
443
+ for (const child of element.children) walk(child, node);
444
+ };
445
+ for (const root of doc.structure) walk(root, void 0);
446
+ return { nodeOfItem: (item) => item.kind === "link" || item.kind === "internalLink" ? void 0 : byId.get(item.structure ?? "") };
447
+ }
448
+ function nearestOfType(node, types) {
449
+ for (let current = node; current !== void 0; current = current.parent) if (types.has(current.type)) return current;
450
+ }
451
+ function nearestHeadingLevel(node) {
452
+ for (let current = node; current !== void 0; current = current.parent) {
453
+ const level = HEADING_LEVELS.get(current.type);
454
+ if (level !== void 0) return level;
455
+ }
456
+ }
457
+ function structureHeadingLevel(items, structure) {
458
+ if (items.length === 0 || items.some((item) => structure.nodeOfItem(item) === void 0)) return;
459
+ let level;
460
+ for (const item of items) {
461
+ const itemLevel = nearestHeadingLevel(structure.nodeOfItem(item));
462
+ if (itemLevel === void 0) return { level: void 0 };
463
+ if (level === void 0) level = itemLevel;
464
+ else if (level !== itemLevel) return;
465
+ }
466
+ return { level };
467
+ }
468
+ const HEADING_MIN_SIZE_DELTA_PT = 2;
469
+ const MAX_HEADING_LEVEL = 6;
470
+ function hasVisibleText(text) {
471
+ return text.trim().length > 0;
472
+ }
473
+ function headingSizeLevels(doc) {
474
+ const sizes = [];
475
+ for (const page of doc.pages) for (const item of page.items) if (item.kind === "text" && hasVisibleText(item.text)) sizes.push(item.sizePt);
476
+ if (sizes.length === 0) return /* @__PURE__ */ new Map();
477
+ const bodySizePt = modeOf(sizes, HALF_POINT_BUCKET_PT);
478
+ const headingBuckets = /* @__PURE__ */ new Set();
479
+ for (const size of sizes) {
480
+ const bucket = Math.round(size / HALF_POINT_BUCKET_PT) * HALF_POINT_BUCKET_PT;
481
+ if (bucket - bodySizePt >= HEADING_MIN_SIZE_DELTA_PT) headingBuckets.add(bucket);
482
+ }
483
+ const levels = /* @__PURE__ */ new Map();
484
+ [...headingBuckets].sort((a, b) => b - a).forEach((bucket, index) => {
485
+ levels.set(bucket, Math.min(index + 1, MAX_HEADING_LEVEL));
486
+ });
487
+ return levels;
488
+ }
489
+ function headingLevelOf(paragraph, levels) {
490
+ return levels.get(modeOf(paragraph.lines.flatMap((line) => line.items).filter((item) => hasVisibleText(item.text)).map((item) => item.sizePt), HALF_POINT_BUCKET_PT));
491
+ }
492
+ function samePageSize(a, b) {
493
+ return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
494
+ }
495
+ function buildSection(pages, startPageIndex, images, headingLevels, form, structure) {
496
+ const blocks = [];
497
+ const divisionByBlock = /* @__PURE__ */ new WeakMap();
498
+ pages.forEach((page, i) => {
499
+ if (i > 0) blocks.push({ kind: "pageBreak" });
500
+ blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form, structure, divisionByBlock));
501
+ });
502
+ return {
503
+ pageSize: {
504
+ widthPt: pages[0].widthPt,
505
+ heightPt: pages[0].heightPt
506
+ },
507
+ margins: ZERO_MARGINS,
508
+ blocks: wrapDivisionExtents(blocks, divisionByBlock)
509
+ };
510
+ }
511
+ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form, structure, divisionByBlock) {
512
+ const recoveredTables = recoverTables(page, pageIndex, structure);
513
+ const consumedText = /* @__PURE__ */ new Set();
514
+ const claimedItems = /* @__PURE__ */ new Set();
515
+ for (const recovered of recoveredTables) {
516
+ for (const item of recovered.consumedText) consumedText.add(item);
517
+ for (const item of recovered.latticeItems) claimedItems.add(item);
518
+ }
519
+ const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
520
+ const imageItems = page.items.filter((i) => i.kind === "image");
521
+ const lines = clusterIntoLines(textItems);
522
+ const paragraphs = clusterIntoParagraphs(lines);
523
+ const recordDivisions = (block, items) => {
524
+ if (structure !== void 0) divisionByBlock.set(block, divisionChainOf(items, structure));
525
+ };
526
+ const positioned = [];
527
+ for (const paragraph of paragraphs) {
528
+ const paragraphItems = paragraph.lines.flatMap((line) => line.items);
529
+ const structural = structure === void 0 ? void 0 : structureHeadingLevel(paragraphItems, structure);
530
+ const headingLevel = structural !== void 0 ? structural.level : headingLevelOf(paragraph, headingLevels);
531
+ const block = paragraphToContentParagraph(paragraph, pageIndex, headingLevel);
532
+ recordDivisions(block, paragraphItems);
533
+ positioned.push({
534
+ yPt: paragraph.lines[0].baselineY,
535
+ block
536
+ });
537
+ }
538
+ for (const img of imageItems) {
539
+ const asset = images[img.imageId];
540
+ if (asset !== void 0) {
541
+ const block = {
542
+ kind: "image",
543
+ format: asset.format,
544
+ base64: asset.base64,
545
+ widthPt: img.widthPt,
546
+ heightPt: img.heightPt
547
+ };
548
+ stampFrame(block, pageIndex, {
549
+ xPt: img.xPt,
550
+ yPt: img.yPt,
551
+ widthPt: img.widthPt,
552
+ heightPt: img.heightPt
553
+ });
554
+ recordDivisions(block, [img]);
555
+ positioned.push({
556
+ yPt: img.yPt,
557
+ block
558
+ });
559
+ }
560
+ }
561
+ for (const recovered of recoveredTables) {
562
+ recordDivisions(recovered.table, [...recovered.consumedText]);
563
+ positioned.push({
564
+ yPt: recovered.topYPt,
565
+ block: recovered.table
566
+ });
567
+ }
568
+ const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
569
+ if (recoveredVectors !== void 0) {
570
+ const vectorItems = page.items.filter((item) => !claimedItems.has(item) && layoutItemToVector(item, page.heightPt) !== void 0);
571
+ recordDivisions(recoveredVectors.block, vectorItems);
572
+ positioned.push({
573
+ yPt: recoveredVectors.topYPt,
574
+ block: recoveredVectors.block
575
+ });
576
+ }
577
+ positioned.sort((a, b) => b.yPt - a.yPt);
578
+ const blocks = positioned.map((p) => p.block);
579
+ reconcileLinks(blocks, page, pageIndex);
580
+ appendAnnotationConstructs(blocks, page, pageIndex);
581
+ appendFormFieldConstructs(blocks, form, pageIndex);
582
+ return blocks;
583
+ }
584
+ function divisionChainOf(items, structure) {
585
+ let prefix;
586
+ for (const item of items) {
587
+ const chain = [];
588
+ for (let current = structure.nodeOfItem(item); current !== void 0; current = current.parent) if (DIVISION_TYPES.has(current.type)) chain.push(current.id);
589
+ chain.reverse();
590
+ if (prefix === void 0) {
591
+ prefix = chain;
592
+ continue;
593
+ }
594
+ let shared = 0;
595
+ while (shared < prefix.length && shared < chain.length && prefix[shared] === chain[shared]) shared += 1;
596
+ prefix = prefix.slice(0, shared);
597
+ }
598
+ return prefix ?? [];
599
+ }
600
+ function wrapDivisionExtents(blocks, divisionByBlock) {
601
+ const out = [];
602
+ const open = [];
603
+ for (const block of blocks) {
604
+ const chain = divisionByBlock.get(block);
605
+ if (chain !== void 0) {
606
+ while (open.length > 0 && !chain.includes(open[open.length - 1])) {
607
+ out.push({ kind: "constructEnd" });
608
+ open.pop();
609
+ }
610
+ for (const id of chain) {
611
+ if (open.includes(id)) continue;
612
+ out.push({
613
+ kind: "constructStart",
614
+ descriptor: { kind: "division" }
615
+ });
616
+ open.push(id);
617
+ }
618
+ }
619
+ out.push(block);
620
+ }
621
+ while (open.length > 0) {
622
+ out.push({ kind: "constructEnd" });
623
+ open.pop();
624
+ }
625
+ return out;
626
+ }
627
+ function framesIntersect(a, b) {
628
+ 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;
629
+ }
630
+ function intersectionArea(a, b) {
631
+ const width = Math.min(a.xPt + a.widthPt, b.xPt + b.widthPt) - Math.max(a.xPt, b.xPt);
632
+ const height = Math.min(a.yPt + a.heightPt, b.yPt + b.heightPt) - Math.max(a.yPt, b.yPt);
633
+ return width > 0 && height > 0 ? width * height : 0;
634
+ }
635
+ function reconcileLinks(blocks, page, pageIndex) {
636
+ for (const item of page.items) {
637
+ if (item.kind !== "link" && item.kind !== "internalLink") continue;
638
+ if (item.kind === "link") {
639
+ let matchedRun = false;
640
+ for (const block of blocks) {
641
+ if (block.kind !== "paragraph") continue;
642
+ for (const run of block.runs) if ((run.frames ?? []).some((frame) => frame.pageIndex === pageIndex && framesIntersect(item, frame))) {
643
+ run.hyperlink = item.uri;
644
+ matchedRun = true;
645
+ }
646
+ }
647
+ if (matchedRun) continue;
648
+ }
649
+ wrapBestBlock(blocks, item, pageIndex, linkDescriptor(item));
650
+ }
651
+ }
652
+ function linkDescriptor(item) {
653
+ if (item.kind === "link") return {
654
+ kind: "link",
655
+ target: {
656
+ kind: "external",
657
+ uri: item.uri
658
+ },
659
+ ...item.title !== void 0 ? { title: item.title } : {}
660
+ };
661
+ return {
662
+ kind: "link",
663
+ target: {
664
+ kind: "internal",
665
+ anchor: item.destination
666
+ },
667
+ ...item.title !== void 0 ? { title: item.title } : {}
668
+ };
669
+ }
670
+ function blockFramesOn(block, pageIndex) {
671
+ return block.kind === "constructStart" || block.kind === "constructEnd" ? [] : (block.frames ?? []).filter((frame) => frame.pageIndex === pageIndex);
672
+ }
673
+ function wrapBestBlock(blocks, rect, pageIndex, descriptor) {
674
+ let bestIndex = -1;
675
+ let bestArea = 0;
676
+ blocks.forEach((block, index) => {
677
+ const area = blockFramesOn(block, pageIndex).reduce((sum, frame) => sum + intersectionArea(rect, frame), 0);
678
+ if (area > bestArea) {
679
+ bestArea = area;
680
+ bestIndex = index;
681
+ }
682
+ });
683
+ const start = {
684
+ kind: "constructStart",
685
+ descriptor
686
+ };
687
+ const end = { kind: "constructEnd" };
688
+ if (bestIndex >= 0) {
689
+ blocks.splice(bestIndex, 0, start);
690
+ blocks.splice(bestIndex + 2, 0, end);
691
+ } else blocks.push(start, end);
692
+ }
693
+ function appendAnnotationConstructs(blocks, page, pageIndex) {
694
+ (page.annotations ?? []).forEach((annotation, annotIndex) => {
695
+ const key = `pdf-annot-${String(pageIndex)}-${String(annotIndex)}`;
696
+ blocks.push({
697
+ kind: "constructStart",
698
+ descriptor: {
699
+ kind: "anchor",
700
+ anchorType: "comment",
701
+ name: key,
702
+ definition: key,
703
+ ...annotation.source !== void 0 ? { source: annotation.source } : {}
704
+ }
705
+ }, { kind: "constructEnd" });
706
+ });
707
+ }
708
+ function controlTypeOf(field) {
709
+ if (field.fieldType === "text") return "plainText";
710
+ if (field.fieldType === "button") return "button";
711
+ if (field.fieldType === "combobox") return "comboBox";
712
+ if (field.fieldType === "listbox") return "dropDown";
713
+ return "checkbox";
714
+ }
715
+ function appendFormFieldConstructs(blocks, form, pageIndex) {
716
+ const visit = (fields) => {
717
+ for (const field of fields) {
718
+ visit(field.children);
719
+ if (field.fieldType === "group" || field.fieldType === "signature") continue;
720
+ for (const widget of field.widgets) {
721
+ if (widget.pageIndex !== pageIndex) continue;
722
+ wrapBestBlock(blocks, widget, pageIndex, {
723
+ kind: "contentControl",
724
+ controlType: controlTypeOf(field),
725
+ tag: field.name,
726
+ ...field.alias !== void 0 ? { alias: field.alias } : {},
727
+ ...field.readOnly === true ? { lock: "content" } : {},
728
+ ...field.value !== void 0 ? { value: field.value } : {},
729
+ ...field.checked !== void 0 ? { checked: field.checked } : {},
730
+ ...field.options !== void 0 ? { options: [...field.options] } : {}
731
+ });
732
+ }
733
+ }
734
+ };
735
+ visit(form ?? []);
736
+ }
737
+ function reconstructSpreadsheet(doc, options) {
738
+ const signal = options?.signal;
739
+ const sheets = doc.pages.map((page, index) => {
740
+ throwIfAborted(signal);
741
+ return reconstructSheet(page, index, options?.onCellTypeInference);
742
+ });
743
+ return {
744
+ kind: "spreadsheet",
745
+ metadata: doc.metadata,
746
+ sheets
747
+ };
748
+ }
749
+ //#endregion
750
+ //#region src/layout/reconstruct-presentations-prod.ts
751
+ function reconstructPresentation(doc, options) {
752
+ const signal = options?.signal;
753
+ const structure = indexStructure(doc);
754
+ const slides = doc.pages.map((page, pageIndex) => {
755
+ throwIfAborted(signal);
756
+ return reconstructSlide(page, pageIndex, doc.images, structure);
757
+ });
758
+ return {
759
+ kind: "presentation",
760
+ metadata: doc.metadata,
761
+ slides
762
+ };
763
+ }
764
+ function reconstructSlide(page, pageIndex, images, structure) {
765
+ const recoveredTables = recoverTables(page, pageIndex, structure);
766
+ const consumedText = /* @__PURE__ */ new Set();
767
+ const claimedItems = /* @__PURE__ */ new Set();
768
+ for (const recovered of recoveredTables) {
769
+ for (const item of recovered.consumedText) consumedText.add(item);
770
+ for (const item of recovered.latticeItems) claimedItems.add(item);
771
+ }
772
+ const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
773
+ const imageItems = page.items.filter((i) => i.kind === "image");
774
+ const textShapes = clusterIntoBlocks(clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt, pageIndex));
775
+ const imageShapes = [];
776
+ for (const img of imageItems) {
777
+ const shape = imageToShape(img, page.heightPt, pageIndex, images);
778
+ if (shape !== void 0) imageShapes.push(shape);
779
+ }
780
+ const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
781
+ const vectorShapes = recoveredVectors === void 0 ? [] : [wrapBlockInShape(recoveredVectors.block, {
782
+ xPt: 0,
783
+ yPt: 0,
784
+ widthPt: page.widthPt,
785
+ heightPt: page.heightPt
786
+ }, page.heightPt, pageIndex)];
787
+ const tableShapes = recoveredTables.map((recovered) => wrapBlockInShape(recovered.table, recovered.frame, page.heightPt, pageIndex));
788
+ return {
789
+ size: {
790
+ widthPt: page.widthPt,
791
+ heightPt: page.heightPt
792
+ },
793
+ shapes: [
794
+ ...vectorShapes,
795
+ ...imageShapes,
796
+ ...tableShapes,
797
+ ...textShapes
798
+ ],
799
+ notes: page.notes ?? ""
800
+ };
801
+ }
802
+ function wrapBlockInShape(block, frame, pageHeightPt, pageIndex) {
803
+ const shape = {
804
+ frame,
805
+ insetLeftPt: 0,
806
+ insetTopPt: 0,
807
+ insetRightPt: 0,
808
+ insetBottomPt: 0,
809
+ blocks: [block]
810
+ };
811
+ stampFrame(shape, pageIndex, flipY(frame, pageHeightPt));
812
+ return shape;
813
+ }
814
+ function splitLineByLargeGaps(line) {
815
+ const segments = [];
816
+ let current = [];
817
+ line.items.forEach((item, i) => {
818
+ if (i > 0) {
819
+ const prev = line.items[i - 1];
820
+ if (gapExceeds(prev, item, 2 * item.sizePt)) {
821
+ segments.push({
822
+ items: current,
823
+ baselineY: line.baselineY
824
+ });
825
+ current = [];
826
+ }
827
+ }
828
+ current.push(item);
829
+ });
830
+ if (current.length > 0) segments.push({
831
+ items: current,
832
+ baselineY: line.baselineY
833
+ });
834
+ return segments;
835
+ }
836
+ function clusterIntoBlocks(pageLines) {
837
+ const segments = pageLines.flatMap(splitLineByLargeGaps);
838
+ const blocks = [];
839
+ for (const segment of segments) {
840
+ const leftX = segment.items[0].xPt;
841
+ const sizePt = segment.items[0].sizePt;
842
+ const matched = blocks.find((block) => {
843
+ const lastLine = block.lines[block.lines.length - 1];
844
+ const lastLeftX = lastLine.items[0].xPt;
845
+ const lastSizePt = lastLine.items[0].sizePt;
846
+ const gap = lastLine.baselineY - segment.baselineY;
847
+ if (gap <= 0) return false;
848
+ return Math.abs(leftX - lastLeftX) <= 2 && fontSizesClose(sizePt, lastSizePt) && gap <= 1.25 * lastSizePt;
849
+ });
850
+ if (matched !== void 0) matched.lines.push(segment);
851
+ else blocks.push({ lines: [segment] });
852
+ }
853
+ return blocks;
854
+ }
855
+ function computeBlockFrame(block, slideHeightPt) {
856
+ let minX = Number.POSITIVE_INFINITY;
857
+ let maxX = Number.NEGATIVE_INFINITY;
858
+ let minY = Number.POSITIVE_INFINITY;
859
+ let maxY = Number.NEGATIVE_INFINITY;
860
+ for (const line of block.lines) for (const item of line.items) {
861
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
862
+ minX = Math.min(minX, item.xPt);
863
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
864
+ minY = Math.min(minY, item.yPt - descentPt);
865
+ maxY = Math.max(maxY, item.yPt + ascentPt);
866
+ }
867
+ return flipY({
868
+ xPt: minX,
869
+ yPt: minY,
870
+ widthPt: maxX - minX,
871
+ heightPt: maxY - minY
872
+ }, slideHeightPt);
873
+ }
874
+ function lineToParagraph(line, pageIndex) {
875
+ const paragraph = {
876
+ kind: "paragraph",
877
+ runs: []
878
+ };
879
+ stampFrame(paragraph, pageIndex, lineBox(line, pageIndex));
880
+ pushRunsForLine(paragraph.runs, line, pageIndex);
881
+ return paragraph;
882
+ }
883
+ function blockToShape(block, slideHeightPt, pageIndex) {
884
+ const shape = {
885
+ frame: computeBlockFrame(block, slideHeightPt),
886
+ insetLeftPt: 0,
887
+ insetTopPt: 0,
888
+ insetRightPt: 0,
889
+ insetBottomPt: 0,
890
+ blocks: block.lines.map((line) => lineToParagraph(line, pageIndex))
891
+ };
892
+ stampFrame(shape, pageIndex, flipY(shape.frame, slideHeightPt));
893
+ return shape;
894
+ }
895
+ function imageToShape(img, slideHeightPt, pageIndex, images) {
896
+ const asset = images[img.imageId];
897
+ if (asset === void 0) return;
898
+ const frame = flipY({
899
+ xPt: img.xPt,
900
+ yPt: img.yPt,
901
+ widthPt: img.widthPt,
902
+ heightPt: img.heightPt
903
+ }, slideHeightPt);
904
+ const block = {
905
+ kind: "image",
906
+ format: asset.format,
907
+ base64: asset.base64,
908
+ widthPt: img.widthPt,
909
+ heightPt: img.heightPt
910
+ };
911
+ stampFrame(block, pageIndex, {
912
+ xPt: img.xPt,
913
+ yPt: img.yPt,
914
+ widthPt: img.widthPt,
915
+ heightPt: img.heightPt
916
+ });
917
+ const shape = {
918
+ frame,
919
+ rotationDeg: img.rotationDeg !== void 0 ? -img.rotationDeg : void 0,
920
+ insetLeftPt: 0,
921
+ insetTopPt: 0,
922
+ insetRightPt: 0,
923
+ insetBottomPt: 0,
924
+ blocks: [block]
925
+ };
926
+ stampFrame(shape, pageIndex, {
927
+ xPt: img.xPt,
928
+ yPt: img.yPt,
929
+ widthPt: img.widthPt,
930
+ heightPt: img.heightPt
931
+ });
932
+ return shape;
933
+ }
934
+ function reconstructDrawing(doc, options) {
935
+ const signal = options?.signal;
936
+ const pages = doc.pages.map((page, pageIndex) => {
937
+ throwIfAborted(signal);
938
+ return reconstructDrawPage(page, pageIndex, doc.images);
939
+ });
940
+ return {
941
+ kind: "drawing",
942
+ metadata: doc.metadata,
943
+ pages
944
+ };
945
+ }
946
+ function reconstructDrawPage(page, pageIndex, images) {
947
+ const vectors = [];
948
+ const shapes = [];
949
+ let paintOrder = 0;
950
+ for (const item of page.items) {
951
+ const vector = layoutItemToVector(item, page.heightPt);
952
+ if (vector !== void 0) {
953
+ stampVectorFrame(vector, item, pageIndex);
954
+ vectors.push({
955
+ ...vector,
956
+ paintOrder: paintOrder++
957
+ });
958
+ continue;
959
+ }
960
+ if (item.kind === "text") {
961
+ const shape = layoutTextToShape(item, page.heightPt, pageIndex);
962
+ stampFrame(shape, pageIndex, flipY(shape.frame, page.heightPt));
963
+ shapes.push({
964
+ ...shape,
965
+ paintOrder: paintOrder++
966
+ });
967
+ } else if (item.kind === "image") {
968
+ const shape = imageToShape(item, page.heightPt, pageIndex, images);
969
+ if (shape !== void 0) shapes.push({
970
+ ...shape,
971
+ paintOrder: paintOrder++
972
+ });
973
+ }
974
+ }
975
+ return {
976
+ size: {
977
+ widthPt: page.widthPt,
978
+ heightPt: page.heightPt
979
+ },
980
+ shapes,
981
+ vectors
982
+ };
983
+ }
984
+ function stampVectorFrame(vector, item, pageIndex) {
985
+ if (item.kind === "rect" || item.kind === "ellipse") {
986
+ stampFrame(vector, pageIndex, {
987
+ xPt: item.xPt,
988
+ yPt: item.yPt,
989
+ widthPt: item.widthPt,
990
+ heightPt: item.heightPt
991
+ });
992
+ return;
993
+ }
994
+ if (item.kind === "line") {
995
+ stampFrame(vector, pageIndex, {
996
+ xPt: Math.min(item.x1Pt, item.x2Pt),
997
+ yPt: Math.min(item.y1Pt, item.y2Pt),
998
+ widthPt: Math.abs(item.x2Pt - item.x1Pt),
999
+ heightPt: Math.abs(item.y2Pt - item.y1Pt)
1000
+ });
1001
+ return;
1002
+ }
1003
+ if (item.kind !== "path") return;
1004
+ const points = collectPathPoints(item.subpaths);
1005
+ let minX = Number.POSITIVE_INFINITY;
1006
+ let maxX = Number.NEGATIVE_INFINITY;
1007
+ let minY = Number.POSITIVE_INFINITY;
1008
+ let maxY = Number.NEGATIVE_INFINITY;
1009
+ for (const point of points) {
1010
+ minX = Math.min(minX, point.xPt);
1011
+ maxX = Math.max(maxX, point.xPt);
1012
+ minY = Math.min(minY, point.yPt);
1013
+ maxY = Math.max(maxY, point.yPt);
1014
+ }
1015
+ stampFrame(vector, pageIndex, {
1016
+ xPt: minX,
1017
+ yPt: minY,
1018
+ widthPt: maxX - minX,
1019
+ heightPt: maxY - minY
1020
+ });
1021
+ }
1022
+ function layoutItemToVector(item, pageHeightPt) {
1023
+ if (item.kind === "rect") return layoutRectToVector(item, pageHeightPt);
1024
+ if (item.kind === "ellipse") return layoutEllipseToVector(item, pageHeightPt);
1025
+ if (item.kind === "line") return layoutLineToVector(item, pageHeightPt);
1026
+ if (item.kind === "path") return layoutPathToVector(item, pageHeightPt);
1027
+ }
1028
+ function layoutRectToVector(item, pageHeightPt) {
1029
+ return {
1030
+ kind: "rect",
1031
+ frame: flipY({
1032
+ xPt: item.xPt,
1033
+ yPt: item.yPt,
1034
+ widthPt: item.widthPt,
1035
+ heightPt: item.heightPt
1036
+ }, pageHeightPt),
1037
+ fill: item.fill,
1038
+ stroke: item.stroke,
1039
+ sourcePath: item.sourcePath
1040
+ };
1041
+ }
1042
+ function layoutEllipseToVector(item, pageHeightPt) {
1043
+ return {
1044
+ kind: "ellipse",
1045
+ frame: flipY({
1046
+ xPt: item.xPt,
1047
+ yPt: item.yPt,
1048
+ widthPt: item.widthPt,
1049
+ heightPt: item.heightPt
1050
+ }, pageHeightPt),
1051
+ fill: item.fill,
1052
+ stroke: item.stroke,
1053
+ sourcePath: item.sourcePath
1054
+ };
1055
+ }
1056
+ function layoutLineToVector(item, pageHeightPt) {
1057
+ return {
1058
+ kind: "line",
1059
+ from: {
1060
+ xPt: item.x1Pt,
1061
+ yPt: pageHeightPt - item.y1Pt
1062
+ },
1063
+ to: {
1064
+ xPt: item.x2Pt,
1065
+ yPt: pageHeightPt - item.y2Pt
1066
+ },
1067
+ stroke: {
1068
+ color: item.color,
1069
+ widthPt: item.widthPt
1070
+ },
1071
+ sourcePath: item.sourcePath
1072
+ };
1073
+ }
1074
+ function collectPathPoints(subpaths) {
1075
+ const points = [];
1076
+ for (const subpath of subpaths) {
1077
+ points.push({
1078
+ xPt: subpath.startXPt,
1079
+ yPt: subpath.startYPt
1080
+ });
1081
+ for (const segment of subpath.segments) {
1082
+ if (segment.kind === "cubic") {
1083
+ points.push({
1084
+ xPt: segment.c1xPt,
1085
+ yPt: segment.c1yPt
1086
+ });
1087
+ points.push({
1088
+ xPt: segment.c2xPt,
1089
+ yPt: segment.c2yPt
1090
+ });
1091
+ }
1092
+ points.push({
1093
+ xPt: segment.xPt,
1094
+ yPt: segment.yPt
1095
+ });
1096
+ }
1097
+ }
1098
+ return points;
1099
+ }
1100
+ function pathBoundingFrame(points, pageHeightPt) {
1101
+ if (points.length === 0) return {
1102
+ xPt: 0,
1103
+ yPt: 0,
1104
+ widthPt: 0,
1105
+ heightPt: 0
1106
+ };
1107
+ let minX = Number.POSITIVE_INFINITY;
1108
+ let maxX = Number.NEGATIVE_INFINITY;
1109
+ let minYDown = Number.POSITIVE_INFINITY;
1110
+ let maxYDown = Number.NEGATIVE_INFINITY;
1111
+ for (const point of points) {
1112
+ const yDown = pageHeightPt - point.yPt;
1113
+ minX = Math.min(minX, point.xPt);
1114
+ maxX = Math.max(maxX, point.xPt);
1115
+ minYDown = Math.min(minYDown, yDown);
1116
+ maxYDown = Math.max(maxYDown, yDown);
1117
+ }
1118
+ return {
1119
+ xPt: minX,
1120
+ yPt: minYDown,
1121
+ widthPt: maxX - minX,
1122
+ heightPt: maxYDown - minYDown
1123
+ };
1124
+ }
1125
+ function localizePathPoint(frame, point, pageHeightPt) {
1126
+ return {
1127
+ xPt: point.xPt - frame.xPt,
1128
+ yPt: pageHeightPt - frame.yPt - point.yPt
1129
+ };
1130
+ }
1131
+ function layoutPathToVector(item, pageHeightPt) {
1132
+ const frame = pathBoundingFrame(collectPathPoints(item.subpaths), pageHeightPt);
1133
+ return {
1134
+ kind: "path",
1135
+ frame,
1136
+ subpaths: item.subpaths.map((subpath) => ({
1137
+ start: localizePathPoint(frame, {
1138
+ xPt: subpath.startXPt,
1139
+ yPt: subpath.startYPt
1140
+ }, pageHeightPt),
1141
+ closed: subpath.closed,
1142
+ segments: subpath.segments.map((segment) => {
1143
+ if (segment.kind === "line") return {
1144
+ kind: "line",
1145
+ to: localizePathPoint(frame, {
1146
+ xPt: segment.xPt,
1147
+ yPt: segment.yPt
1148
+ }, pageHeightPt)
1149
+ };
1150
+ return {
1151
+ kind: "cubic",
1152
+ control1: localizePathPoint(frame, {
1153
+ xPt: segment.c1xPt,
1154
+ yPt: segment.c1yPt
1155
+ }, pageHeightPt),
1156
+ control2: localizePathPoint(frame, {
1157
+ xPt: segment.c2xPt,
1158
+ yPt: segment.c2yPt
1159
+ }, pageHeightPt),
1160
+ to: localizePathPoint(frame, {
1161
+ xPt: segment.xPt,
1162
+ yPt: segment.yPt
1163
+ }, pageHeightPt)
1164
+ };
1165
+ })
1166
+ })),
1167
+ fill: item.fill,
1168
+ fillRule: item.fillRule,
1169
+ stroke: item.stroke,
1170
+ sourcePath: item.sourcePath
1171
+ };
1172
+ }
1173
+ function layoutTextToShape(item, pageHeightPt, pageIndex) {
1174
+ const frame = computeBlockFrame({ lines: [{
1175
+ items: [item],
1176
+ baselineY: item.yPt
1177
+ }] }, pageHeightPt);
1178
+ const run = textItemToContentRun(item);
1179
+ stampFrame(run, pageIndex, textBoxOfItem(item, pageIndex));
1180
+ const paragraph = {
1181
+ kind: "paragraph",
1182
+ runs: [run]
1183
+ };
1184
+ stampFrame(paragraph, pageIndex, textBoxOfItem(item, pageIndex));
1185
+ return {
1186
+ frame,
1187
+ rotationDeg: item.rotationDeg !== void 0 ? -item.rotationDeg : void 0,
1188
+ insetLeftPt: 0,
1189
+ insetTopPt: 0,
1190
+ insetRightPt: 0,
1191
+ insetBottomPt: 0,
1192
+ blocks: [paragraph]
1193
+ };
1194
+ }
1195
+ function vectorTopYDownPt(vector) {
1196
+ return vector.kind === "line" ? Math.min(vector.from.yPt, vector.to.yPt) : vector.frame.yPt;
1197
+ }
1198
+ function recoverPageVectors(page, pageIndex, excluded) {
1199
+ const vectors = [];
1200
+ for (const item of page.items) {
1201
+ if (excluded.has(item)) continue;
1202
+ const vector = layoutItemToVector(item, page.heightPt);
1203
+ if (vector !== void 0) {
1204
+ stampVectorFrame(vector, item, pageIndex);
1205
+ vectors.push({
1206
+ ...vector,
1207
+ paintOrder: vectors.length
1208
+ });
1209
+ }
1210
+ }
1211
+ if (vectors.length === 0) return;
1212
+ const topYDownPt = Math.min(...vectors.map(vectorTopYDownPt));
1213
+ const block = buildDrawingBlock({
1214
+ widthPt: page.widthPt,
1215
+ heightPt: page.heightPt
1216
+ }, vectors);
1217
+ stampFrame(block, pageIndex, {
1218
+ xPt: 0,
1219
+ yPt: 0,
1220
+ widthPt: page.widthPt,
1221
+ heightPt: page.heightPt
1222
+ });
1223
+ return {
1224
+ block,
1225
+ topYPt: page.heightPt - topYDownPt
1226
+ };
1227
+ }
1228
+ function reconstructSheet(page, pageIndex, sink) {
1229
+ const textItems = page.items.filter((i) => i.kind === "text");
1230
+ const lattice = detectGridLattice(page.items);
1231
+ const context = {
1232
+ sheetIndex: pageIndex,
1233
+ sink
1234
+ };
1235
+ const grid = lattice !== void 0 ? buildGridFromLattice(textItems, lattice, pageIndex, context) : buildGridFromTextClustering(textItems, pageIndex, context);
1236
+ const printSettings = {
1237
+ pageSize: {
1238
+ widthPt: page.widthPt,
1239
+ heightPt: page.heightPt
1240
+ },
1241
+ margins: ZERO_MARGINS,
1242
+ gridlines: grid.gridlines,
1243
+ headers: false,
1244
+ pageOrder: "downThenOver"
1245
+ };
1246
+ return {
1247
+ name: `Sheet${pageIndex + 1}`,
1248
+ cells: grid.cells,
1249
+ columns: grid.columns,
1250
+ rows: grid.rows,
1251
+ images: [],
1252
+ printSettings
1253
+ };
1254
+ }
1255
+ //#endregion
1256
+ export { reconstructWordprocessing as _, reconstructSheet as a, recoverTables as b, CELL_TYPES as c, ROW_TYPES as d, TABLE_TYPES as f, reconstructSpreadsheet as g, nearestOfType as h, reconstructPresentation as i, DEFAULT_COLUMN_WIDTH_FALLBACK_PT as l, indexStructure as m, lineToParagraph as n, recoverPageVectors as o, ZERO_MARGINS as p, reconstructDrawing as r, splitLineByLargeGaps as s, layoutItemToVector as t, NO_ITEMS as u, buildGridFromLattice as v, buildGridFromTextClustering as y };