@pixerate/editor 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +101 -1
  2. package/THIRD_PARTY_NOTICES.md +40 -0
  3. package/dist/agent/index.cjs +175 -11
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +18 -4
  6. package/dist/agent/index.d.ts +18 -4
  7. package/dist/agent/index.js +168 -4
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/{arrangeShortcuts-B8O3f8-P.d.cts → arrange-BICutYPk.d.cts} +243 -29
  10. package/dist/{arrangeShortcuts-sLlD2rSX.d.ts → arrange-BICutYPk.d.ts} +243 -29
  11. package/dist/builtins-CdPcLwwF.d.cts +176 -0
  12. package/dist/builtins-Chj6zv_O.d.ts +176 -0
  13. package/dist/canvas/index.cjs +8588 -1857
  14. package/dist/canvas/index.cjs.map +1 -1
  15. package/dist/canvas/index.d.cts +1847 -9
  16. package/dist/canvas/index.d.ts +1847 -9
  17. package/dist/canvas/index.js +8577 -1846
  18. package/dist/canvas/index.js.map +1 -1
  19. package/dist/chunk-3CC7OPUQ.cjs +831 -0
  20. package/dist/chunk-3CC7OPUQ.cjs.map +1 -0
  21. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  22. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  23. package/dist/chunk-BVP3TSLH.cjs +69 -0
  24. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  25. package/dist/{chunk-OLZJXL4R.cjs → chunk-CS6NZWWA.cjs} +59 -25
  26. package/dist/chunk-CS6NZWWA.cjs.map +1 -0
  27. package/dist/{chunk-MCSJFWAO.cjs → chunk-EWCOFSCQ.cjs} +685 -100
  28. package/dist/chunk-EWCOFSCQ.cjs.map +1 -0
  29. package/dist/chunk-HDYMLS3X.cjs +409 -0
  30. package/dist/chunk-HDYMLS3X.cjs.map +1 -0
  31. package/dist/chunk-HRMEDT2L.js +1406 -0
  32. package/dist/chunk-HRMEDT2L.js.map +1 -0
  33. package/dist/{chunk-D27YFC46.cjs → chunk-IFHKKVXH.cjs} +382 -63
  34. package/dist/chunk-IFHKKVXH.cjs.map +1 -0
  35. package/dist/{chunk-PGNZKFQS.js → chunk-JOIREKL7.js} +137 -58
  36. package/dist/chunk-JOIREKL7.js.map +1 -0
  37. package/dist/chunk-KRGXUQ2Y.js +1696 -0
  38. package/dist/chunk-KRGXUQ2Y.js.map +1 -0
  39. package/dist/{chunk-3LV6RRPH.js → chunk-MHEPLBFB.js} +2 -2
  40. package/dist/chunk-MR2764X2.js +831 -0
  41. package/dist/chunk-MR2764X2.js.map +1 -0
  42. package/dist/{chunk-XNORY7M6.cjs → chunk-NFVBT3UZ.cjs} +166 -87
  43. package/dist/chunk-NFVBT3UZ.cjs.map +1 -0
  44. package/dist/chunk-NQF32I6Z.cjs +6478 -0
  45. package/dist/chunk-NQF32I6Z.cjs.map +1 -0
  46. package/dist/chunk-O5RYH2PG.js +69 -0
  47. package/dist/chunk-O5RYH2PG.js.map +1 -0
  48. package/dist/{chunk-ITBSKI26.js → chunk-Q2OHWD2A.js} +1064 -360
  49. package/dist/chunk-Q2OHWD2A.js.map +1 -0
  50. package/dist/{chunk-FODNLX5N.js → chunk-QJSOZFCZ.js} +38 -4
  51. package/dist/chunk-QJSOZFCZ.js.map +1 -0
  52. package/dist/{chunk-SML64VJG.cjs → chunk-RRREAOVM.cjs} +4 -4
  53. package/dist/{chunk-SML64VJG.cjs.map → chunk-RRREAOVM.cjs.map} +1 -1
  54. package/dist/{chunk-5S3Z4PPF.js → chunk-SWE3NPOU.js} +347 -28
  55. package/dist/chunk-SWE3NPOU.js.map +1 -0
  56. package/dist/chunk-TXXNBDQX.cjs +1696 -0
  57. package/dist/chunk-TXXNBDQX.cjs.map +1 -0
  58. package/dist/chunk-UBCFIABU.js +409 -0
  59. package/dist/chunk-UBCFIABU.js.map +1 -0
  60. package/dist/chunk-X7HXL2SB.js +6478 -0
  61. package/dist/chunk-X7HXL2SB.js.map +1 -0
  62. package/dist/{chunk-SBCZ6RN5.cjs → chunk-YOMYSFJU.cjs} +1163 -459
  63. package/dist/chunk-YOMYSFJU.cjs.map +1 -0
  64. package/dist/{chunk-3CN2WD3X.js → chunk-ZRNHGAQT.js} +661 -76
  65. package/dist/chunk-ZRNHGAQT.js.map +1 -0
  66. package/dist/commands/index.cjs +425 -4
  67. package/dist/commands/index.cjs.map +1 -1
  68. package/dist/commands/index.d.cts +39 -77
  69. package/dist/commands/index.d.ts +39 -77
  70. package/dist/commands/index.js +424 -3
  71. package/dist/commands/index.js.map +1 -1
  72. package/dist/compare/index.cjs +3 -3
  73. package/dist/compare/index.d.cts +1 -1
  74. package/dist/compare/index.d.ts +1 -1
  75. package/dist/compare/index.js +2 -2
  76. package/dist/controller-CxXGOEmy.d.cts +2038 -0
  77. package/dist/controller-CxXGOEmy.d.ts +2038 -0
  78. package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
  79. package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
  80. package/dist/export/index.cjs +36 -0
  81. package/dist/export/index.cjs.map +1 -0
  82. package/dist/export/index.d.cts +243 -0
  83. package/dist/export/index.d.ts +243 -0
  84. package/dist/export/index.js +36 -0
  85. package/dist/export/index.js.map +1 -0
  86. package/dist/extensions/index.cjs +101 -6
  87. package/dist/extensions/index.cjs.map +1 -1
  88. package/dist/extensions/index.d.cts +18 -5
  89. package/dist/extensions/index.d.ts +18 -5
  90. package/dist/extensions/index.js +101 -6
  91. package/dist/generation/index.cjs +1013 -69
  92. package/dist/generation/index.cjs.map +1 -1
  93. package/dist/generation/index.d.cts +474 -13
  94. package/dist/generation/index.d.ts +474 -13
  95. package/dist/generation/index.js +976 -32
  96. package/dist/generation/index.js.map +1 -1
  97. package/dist/image-editor/index.cjs +3385 -1275
  98. package/dist/image-editor/index.cjs.map +1 -1
  99. package/dist/image-editor/index.d.cts +693 -128
  100. package/dist/image-editor/index.d.ts +693 -128
  101. package/dist/image-editor/index.js +3325 -1215
  102. package/dist/image-editor/index.js.map +1 -1
  103. package/dist/{index-fJrlkJCd.d.ts → index-B273Zllk.d.ts} +500 -7
  104. package/dist/{index-BhJBSm2d.d.cts → index-jcJwmBYt.d.cts} +500 -7
  105. package/dist/index.cjs +1603 -45
  106. package/dist/index.cjs.map +1 -1
  107. package/dist/index.d.cts +154 -27
  108. package/dist/index.d.ts +154 -27
  109. package/dist/index.js +1584 -26
  110. package/dist/index.js.map +1 -1
  111. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  112. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  113. package/dist/model-C1zApQM8.d.cts +219 -0
  114. package/dist/model-C1zApQM8.d.ts +219 -0
  115. package/dist/persistence/index.d.cts +3 -120
  116. package/dist/persistence/index.d.ts +3 -120
  117. package/dist/registry-CED5C0lA.d.cts +204 -0
  118. package/dist/registry-CED5C0lA.d.ts +204 -0
  119. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
  120. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
  121. package/dist/{registry-D32LpIc4.d.cts → registry-D0GADKc7.d.cts} +1 -1
  122. package/dist/{registry-evKTP4ls.d.ts → registry-DhVUZioj.d.ts} +1 -1
  123. package/dist/serializers/index.cjs +12 -4
  124. package/dist/serializers/index.cjs.map +1 -1
  125. package/dist/serializers/index.d.cts +41 -13
  126. package/dist/serializers/index.d.ts +41 -13
  127. package/dist/serializers/index.js +12 -4
  128. package/dist/spreadsheet/index.cjs +157 -3
  129. package/dist/spreadsheet/index.cjs.map +1 -1
  130. package/dist/spreadsheet/index.d.cts +534 -11
  131. package/dist/spreadsheet/index.d.ts +534 -11
  132. package/dist/spreadsheet/index.js +157 -3
  133. package/dist/storage-BpFfspHm.d.cts +120 -0
  134. package/dist/storage-BpFfspHm.d.ts +120 -0
  135. package/dist/tokens/index.cjs +115 -0
  136. package/dist/tokens/index.cjs.map +1 -0
  137. package/dist/tokens/index.d.cts +212 -0
  138. package/dist/tokens/index.d.ts +212 -0
  139. package/dist/tokens/index.js +115 -0
  140. package/dist/tokens/index.js.map +1 -0
  141. package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
  142. package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
  143. package/package.json +15 -1
  144. package/dist/chunk-3CN2WD3X.js.map +0 -1
  145. package/dist/chunk-5S3Z4PPF.js.map +0 -1
  146. package/dist/chunk-D27YFC46.cjs.map +0 -1
  147. package/dist/chunk-FODNLX5N.js.map +0 -1
  148. package/dist/chunk-ITBSKI26.js.map +0 -1
  149. package/dist/chunk-MA2F5KHF.cjs +0 -3223
  150. package/dist/chunk-MA2F5KHF.cjs.map +0 -1
  151. package/dist/chunk-MCSJFWAO.cjs.map +0 -1
  152. package/dist/chunk-OLZJXL4R.cjs.map +0 -1
  153. package/dist/chunk-PGNZKFQS.js.map +0 -1
  154. package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
  155. package/dist/chunk-U5KWZU4X.js +0 -3223
  156. package/dist/chunk-U5KWZU4X.js.map +0 -1
  157. package/dist/chunk-XNORY7M6.cjs.map +0 -1
  158. package/dist/controller-BhLLAoi8.d.cts +0 -1000
  159. package/dist/controller-BhLLAoi8.d.ts +0 -1000
  160. package/dist/types-DX4Mh4SL.d.cts +0 -217
  161. package/dist/types-DX4Mh4SL.d.ts +0 -217
  162. /package/dist/{chunk-3LV6RRPH.js.map → chunk-MHEPLBFB.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,4 +1,21 @@
1
1
  import "./chunk-HLIMTC6N.js";
2
+ import {
3
+ DOCX_ANONYMOUS_AUTHOR,
4
+ DOCX_EXPORT_MIME_TYPE,
5
+ DocxExportController,
6
+ XmlWriter,
7
+ createDocxExportController,
8
+ createDocxParts,
9
+ deflateRaw,
10
+ docxFileName,
11
+ downloadBlob,
12
+ escapeXmlAttr,
13
+ escapeXmlText,
14
+ exportDocx,
15
+ exportDocxBlob,
16
+ stripInvalidXmlChars,
17
+ writeZip
18
+ } from "./chunk-KRGXUQ2Y.js";
2
19
  import {
3
20
  FIELD_ALIASES,
4
21
  MAX_DATA_SOURCE_FIELDS,
@@ -40,14 +57,14 @@ import {
40
57
  Autocorrect,
41
58
  BUILT_IN_IMPORT_ADAPTERS,
42
59
  Bookmark,
60
+ CHARACTER_STYLE_MARK_NAME,
43
61
  COMMENT_MARK_NAME,
62
+ CharacterStyle,
44
63
  ColorHighlighter,
45
64
  Comments,
46
65
  CrossReference,
47
66
  DEFAULT_AUTOCORRECT_EXCEPTIONS,
48
67
  DEFAULT_DOCX_MAX_IMAGE_SIZE,
49
- DEFAULT_ZIP_MAX_ENTRIES,
50
- DEFAULT_ZIP_MAX_TOTAL_SIZE,
51
68
  DOCX_MIME_TYPES,
52
69
  DocumentCompare,
53
70
  EMPTY_FIND_REPLACE_SNAPSHOT,
@@ -69,19 +86,21 @@ import {
69
86
  Markdown,
70
87
  Mention,
71
88
  Outline,
89
+ ParagraphStyles,
72
90
  RichClipboard,
73
91
  SMILIE_REPLACEMENTS,
92
+ STYLE_ID_ATTRIBUTE,
74
93
  SlashCommands,
75
94
  SmilieReplacer,
76
95
  TableOfContents,
77
96
  TemplateSuggestions,
78
- ZipArchive,
79
- ZipError,
80
97
  applyDocumentComparison,
98
+ applyImportedReviewData,
81
99
  applyReplacements,
82
100
  autocorrectPluginKey,
83
101
  buildOutlineTree,
84
102
  capitalizeSentenceRules,
103
+ captureSelectionFormat,
85
104
  commentsPluginKey,
86
105
  compareInEditor,
87
106
  compileFindPattern,
@@ -92,8 +111,10 @@ import {
92
111
  createImportContext,
93
112
  createMentionExtension,
94
113
  createOutlineStore,
114
+ createParagraphStylesStore,
95
115
  createRichTextPreset,
96
116
  createSearchBudget,
117
+ createTableCommands,
97
118
  crossReferencePluginKey,
98
119
  defaultAutocorrectRules,
99
120
  defaultImportRegistry,
@@ -125,7 +146,10 @@ import {
125
146
  getFindReplaceStore,
126
147
  getFootnotes,
127
148
  getImportAccept,
149
+ getMentionNodes,
128
150
  getOutline,
151
+ getParagraphStyleAt,
152
+ getStyleRegistry,
129
153
  getTableOfContentsEntries,
130
154
  handleImageInsertion,
131
155
  htmlImportAdapter,
@@ -136,18 +160,19 @@ import {
136
160
  insertImageNode,
137
161
  insertImportedDocument,
138
162
  isInsidePromptToken,
139
- isUnsafeZipPath,
163
+ isParagraphStyleAvailable,
140
164
  markdownImportAdapter,
141
165
  navigateToHeading,
142
166
  outlinePluginKey,
167
+ paragraphStylesPluginKey,
143
168
  parseReplacement,
144
169
  plainTextImportAdapter,
145
- readZip,
146
170
  registerImportAdapter,
147
171
  removeImageNode,
148
172
  richClipboardPluginKey,
149
173
  rtfImportAdapter,
150
174
  searchDocument,
175
+ setMentionRoleAt,
151
176
  smartQuoteRules,
152
177
  smilieAutocorrectRules,
153
178
  symbolRules,
@@ -158,15 +183,29 @@ import {
158
183
  unregisterImportAdapter,
159
184
  updateImageSrc,
160
185
  validateFindPattern,
161
- writeRichClipboard,
162
- zipCrc32
163
- } from "./chunk-ITBSKI26.js";
186
+ writeRichClipboard
187
+ } from "./chunk-Q2OHWD2A.js";
164
188
  import {
165
189
  compareDocuments,
166
190
  compareHtml,
167
191
  diffChanges,
168
192
  diffSequences
169
- } from "./chunk-FODNLX5N.js";
193
+ } from "./chunk-QJSOZFCZ.js";
194
+ import {
195
+ DEFAULT_STYLES,
196
+ DEFAULT_ZIP_MAX_ENTRIES,
197
+ DEFAULT_ZIP_MAX_TOTAL_SIZE,
198
+ NORMAL_STYLE_ID,
199
+ StyleRegistry,
200
+ ZipArchive,
201
+ ZipError,
202
+ createStyleRegistry,
203
+ isUnsafeZipPath,
204
+ isValidStyleId,
205
+ readZip,
206
+ safeCSSValue,
207
+ zipCrc32
208
+ } from "./chunk-MR2764X2.js";
170
209
  import {
171
210
  INSTRUCTION_REGEX,
172
211
  TEMPLATE_REGEX,
@@ -201,20 +240,44 @@ import {
201
240
  rtfToPlainText,
202
241
  sanitizeImportedHtml,
203
242
  serializeRichClipboardPayload
204
- } from "./chunk-3LV6RRPH.js";
243
+ } from "./chunk-MHEPLBFB.js";
205
244
  import {
245
+ CONDITIONAL_FORMAT_ICON_SETS,
246
+ CONDITIONAL_FORMAT_PRESETS,
247
+ CONDITIONAL_FORMAT_STYLE_PRESETS,
248
+ CONDITIONAL_FORMAT_TIME_PERIODS,
249
+ ConditionalFormatEngine,
250
+ DATA_VALIDATION_ERROR_STYLE_OPTIONS,
251
+ DATA_VALIDATION_OPERATOR_OPTIONS,
252
+ DATA_VALIDATION_TYPE_OPTIONS,
206
253
  DEFAULT_COLUMN_WIDTH,
254
+ DEFAULT_CONDITIONAL_FORMAT_STYLE,
255
+ DEFAULT_DATA_VALIDATION_MESSAGE,
256
+ DEFAULT_DATA_VALIDATION_TITLE,
207
257
  DEFAULT_ROW_HEIGHT,
208
258
  DataSourceBinder,
209
259
  DependencyGraph,
260
+ EMPTY_CONDITIONAL_FORMAT_OVERLAY,
261
+ IntervalIndex,
262
+ MAX_DEFINED_NAME_LENGTH,
263
+ MAX_SHEET_NAME_LENGTH,
210
264
  NUMBER_FORMAT_PRESETS,
211
265
  SPREADSHEET_CLIPBOARD_MIME,
266
+ SPREADSHEET_COLUMN_HEADER_HEIGHT,
267
+ SPREADSHEET_DEFAULT_VIEWPORT,
268
+ SPREADSHEET_GROUP_ROW_HEIGHT,
212
269
  SPREADSHEET_IMPORT_ADAPTERS,
270
+ SPREADSHEET_ROW_HEADER_WIDTH,
213
271
  SPREADSHEET_TABLE_ACTIONS,
272
+ SPREADSHEET_VIRTUAL_COLUMN_THRESHOLD,
273
+ SPREADSHEET_VIRTUAL_ROW_THRESHOLD,
214
274
  SpreadsheetController,
275
+ adjustRangeForStructuralChange,
276
+ adjustRangesForStructuralChange,
215
277
  aggregateValues,
216
278
  applyFormulaSuggestion,
217
279
  bindSpreadsheetTableActions,
280
+ blendConditionalFormatColors,
218
281
  buildSpreadsheetView,
219
282
  cellFormatForNumberFormat,
220
283
  clampMenuPosition,
@@ -222,44 +285,94 @@ import {
222
285
  compareCellValues,
223
286
  computeFillTarget,
224
287
  computeRowGroups,
288
+ conditionalFormatContrastColor,
289
+ conditionalFormatIconCount,
290
+ conditionalFormatNumber,
291
+ conditionalFormatStyleString,
292
+ copySheetName,
293
+ createConditionalFormatRule,
225
294
  createSpreadsheetClipboardData,
226
295
  csvImportAdapter,
296
+ defaultIconThresholds,
297
+ deleteSheetInFormula,
298
+ describeConditionalFormat,
299
+ describeDataValidation,
300
+ evaluateConditionalFormats,
227
301
  extractCellDependencies,
302
+ extractNameDependencies,
303
+ extractReferenceDependencies,
228
304
  fillSeries,
305
+ findDataValidation,
306
+ findInvalidCells,
307
+ forEachRangeCell,
229
308
  formatCellDisplay,
230
309
  formatCellForDisplay,
310
+ formatRuleRanges,
311
+ formatSheetPrefix,
231
312
  formatValueWithCode,
313
+ formulaIdentifiers,
314
+ fullSpreadsheetViewWindow,
315
+ getConditionalFormatCss,
316
+ getConditionalFormatIcon,
317
+ getDataBarCss,
232
318
  getFillDirection,
233
319
  getFormulaCaretContext,
234
320
  getFormulaHints,
321
+ getNameManagerRows,
235
322
  getRowSection,
323
+ getSheetTabMenuItems,
236
324
  getSpreadsheetMenuItems,
325
+ getSpreadsheetScrollToCell,
326
+ getSpreadsheetViewWindow,
237
327
  getTableSections,
328
+ getValidationListValues,
238
329
  importFileIntoSpreadsheet,
239
330
  isBlankValue,
240
331
  isGeneralNumberFormat,
332
+ isLambdaDefinition,
241
333
  isSingleCellRange,
242
334
  mapFormulaReferences,
243
335
  matchesFilterRule,
336
+ matchesTimePeriod,
337
+ measureSpreadsheetView,
338
+ nextSheetName,
244
339
  normalizeRange,
245
340
  numberFormatForCellFormat,
246
341
  offsetFormulaReferences,
247
342
  parseHtmlTable,
343
+ parseRuleRanges,
344
+ quoteSheetName,
248
345
  rangeContains,
249
346
  rangeContainsRange,
347
+ rangeDependencyKey,
348
+ rangesContain,
250
349
  rangesIntersect,
251
350
  readSpreadsheetClipboard,
252
351
  rebaseClipboardRows,
253
352
  registerSpreadsheetImportAdapters,
254
353
  remapFormulaReferences,
354
+ renameNameInFormula,
355
+ renameSheetInFormula,
255
356
  roundFloat,
256
357
  rowPassesFilters,
358
+ ruleAnchor,
359
+ ruleFormulaAt,
257
360
  runSpreadsheetMenuItem,
361
+ sameSpreadsheetViewWindow,
258
362
  serializeHtmlTable,
363
+ sheetDropIndex,
364
+ sheetNameNeedsQuotes,
259
365
  shiftFormulaReferences,
366
+ shiftRuleFormula,
367
+ shouldVirtualizeSpreadsheet,
368
+ subtractRange,
369
+ subtractRangeFromRanges,
260
370
  toNumber,
261
- tsvImportAdapter
262
- } from "./chunk-U5KWZU4X.js";
371
+ tsvImportAdapter,
372
+ validateCellInput,
373
+ validateDefinedName,
374
+ validateSheetName
375
+ } from "./chunk-X7HXL2SB.js";
263
376
  import {
264
377
  escapeCsvField,
265
378
  parseCsv,
@@ -276,9 +389,31 @@ import {
276
389
  defaultIsEqual,
277
390
  withoutDirty
278
391
  } from "./chunk-2H7ZHPEJ.js";
392
+ import {
393
+ DEFAULT_TABLE_OPTIONS,
394
+ DEFAULT_TABLE_TOOLBAR,
395
+ EMPTY_TABLE_STATE,
396
+ MAX_TABLE_COLUMNS,
397
+ MAX_TABLE_ROWS,
398
+ TABLE_ACTIONS,
399
+ Table,
400
+ TableCell,
401
+ TableHeader,
402
+ TableRow,
403
+ createTableExtensions,
404
+ createTableStore,
405
+ getTableActionState,
406
+ getTableState,
407
+ isGfmTable,
408
+ isSelectionInTable,
409
+ isTableEnabled,
410
+ normalizeTableCellAlignment,
411
+ normalizeTableCellColor,
412
+ runTableAction,
413
+ shouldShowTableBubbleMenu
414
+ } from "./chunk-UBCFIABU.js";
279
415
  import {
280
416
  MARKDOWN_MENTION_SPLIT_REGEX,
281
- MENTION_REGEX,
282
417
  escapeHtml,
283
418
  extractMentions,
284
419
  extractMentionsFromDoc,
@@ -293,13 +428,22 @@ import {
293
428
  preprocessMarkdownMentions,
294
429
  sanitizeHtml,
295
430
  stripMarkdownCode
296
- } from "./chunk-PGNZKFQS.js";
431
+ } from "./chunk-JOIREKL7.js";
432
+ import {
433
+ MENTION_REGEX,
434
+ findTextMentions,
435
+ formatMentionText,
436
+ setMentionRoleInText
437
+ } from "./chunk-O5RYH2PG.js";
297
438
  import {
298
439
  BLOCK_CHANGE_ATTRIBUTE,
299
440
  CommentStore,
300
441
  DELETION_MARK_NAME,
301
442
  FORMAT_CHANGE_MARK_NAME,
302
443
  INSERTION_MARK_NAME,
444
+ MOVE_FROM_CLASS,
445
+ MOVE_ID_ATTRIBUTE,
446
+ MOVE_TO_CLASS,
303
447
  TRACK_CHANGES_SKIP_META,
304
448
  TrackChanges,
305
449
  TrackChangesStore,
@@ -314,15 +458,19 @@ import {
314
458
  getTrackChangesStore,
315
459
  getTrackedChangeAt,
316
460
  getTrackedChanges,
461
+ isMoveSized,
317
462
  isTrackChangesEnabled,
318
463
  resolveTrackedChanges,
319
- trackChangesPluginKey
320
- } from "./chunk-5S3Z4PPF.js";
464
+ trackChangesPluginKey,
465
+ trackedChangeLabel
466
+ } from "./chunk-SWE3NPOU.js";
321
467
  import {
322
468
  FORMULA_ERRORS,
323
469
  FormulaEvaluator,
470
+ FormulaLambda,
324
471
  FormulaParser,
325
472
  MAX_FORMULA_ARRAY_SIZE,
473
+ MAX_LAMBDA_DEPTH,
326
474
  MAX_NUMBER_FORMAT_CODE_CHARS,
327
475
  NumberFormat,
328
476
  WHOLE_COLUMN_END_ROW,
@@ -344,6 +492,7 @@ import {
344
492
  getFormulaSignatureParts,
345
493
  indexToColName,
346
494
  isFormulaError,
495
+ isFormulaLambda,
347
496
  listFormulaFunctions,
348
497
  numberFormatColorToCss,
349
498
  numberToText,
@@ -360,7 +509,7 @@ import {
360
509
  tokenizeFormula,
361
510
  unregisterFormulaFunction,
362
511
  wildcardToRegExp
363
- } from "./chunk-3CN2WD3X.js";
512
+ } from "./chunk-ZRNHGAQT.js";
364
513
 
365
514
  // src/controller.ts
366
515
  import { Editor } from "@tiptap/core";
@@ -600,10 +749,1026 @@ var FileImportController = class {
600
749
  function createFileImportController(getTarget, options) {
601
750
  return new FileImportController(getTarget, options);
602
751
  }
752
+ function summarizeImportStructure(outcomes) {
753
+ const reports = outcomes.map((outcome) => outcome.result?.structure).filter((report) => !!report);
754
+ if (!reports.length) return null;
755
+ const modes = new Set(reports.map((report) => report.mode));
756
+ const sum = (pick) => reports.reduce((total, report) => total + pick(report), 0);
757
+ return {
758
+ files: reports.length,
759
+ mode: modes.size > 1 ? "mixed" : reports[0].mode,
760
+ headings: sum((r) => r.counts.headings),
761
+ lists: sum((r) => r.counts.lists),
762
+ tables: sum((r) => r.counts.tables),
763
+ paragraphs: sum((r) => r.counts.paragraphs),
764
+ multiColumnPages: sum((r) => r.multiColumnPages),
765
+ confidence: Math.round(sum((r) => r.confidence) / reports.length * 100) / 100
766
+ };
767
+ }
768
+
769
+ // src/import/pdf-layout.ts
770
+ var MAX_COLS = 63;
771
+ var MAX_TABLE_ROWS2 = 2e3;
772
+ var MAX_RULES = 2e3;
773
+ var MAX_DEPTH = 4;
774
+ var BULLET_GLYPH_RE = /^[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]\s*/;
775
+ var BULLET_DASH_RE = /^[-–—*]\s+/;
776
+ var ORDERED_RE = /^(?:\((\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})\)|(\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])\s+/;
777
+ var MARKER_ONLY_RE = /^(?:[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]|\(?(?:\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])$/;
778
+ var PAGE_NUMBER_RE = /^(?:page\s+)?(?:\d{1,4}|[ivxlcdm]{1,7})(?:\s*(?:of|\/)\s*\d{1,4})?$/i;
779
+ var DASHED_PAGE_NUMBER_RE = /^[-–—]\s*\d{1,4}\s*[-–—]$/;
780
+ var SENTENCE_END_RE = /[.!?:;]["'”’)\]]?$/;
781
+ var BOLD_FONT_RE = /bold|black|heavy|semibold|demi/i;
782
+ var ITALIC_FONT_RE = /italic|oblique/i;
783
+ function minOf(list, fn) {
784
+ let min = Infinity;
785
+ for (const item of list) min = Math.min(min, fn(item));
786
+ return min;
787
+ }
788
+ function maxOf(list, fn) {
789
+ let max = -Infinity;
790
+ for (const item of list) max = Math.max(max, fn(item));
791
+ return max;
792
+ }
793
+ function lowerBound(values, target) {
794
+ let lo = 0;
795
+ let hi = values.length;
796
+ while (lo < hi) {
797
+ const mid = lo + hi >> 1;
798
+ if (values[mid] < target) lo = mid + 1;
799
+ else hi = mid;
800
+ }
801
+ return lo;
802
+ }
803
+ function median(values) {
804
+ if (!values.length) return 0;
805
+ const sorted = [...values].sort((a, b) => a - b);
806
+ const mid = sorted.length >> 1;
807
+ return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
808
+ }
809
+ var countWords = (text) => {
810
+ let words = 0;
811
+ let inWord = false;
812
+ for (let i = 0; i < text.length; i++) {
813
+ const space = text.charCodeAt(i) <= 32;
814
+ if (!space && !inWord) words++;
815
+ inWord = !space;
816
+ }
817
+ return words;
818
+ };
819
+ var collapse = (text) => text.replace(/\s+/g, " ").trim();
820
+ function runSize(run) {
821
+ if (run.fontSize && run.fontSize > 0) return run.fontSize;
822
+ if (run.height && run.height > 0) return run.height;
823
+ return 10;
824
+ }
825
+ function buildFragments(runs) {
826
+ const items = runs.filter((run) => typeof run.text === "string" && run.text.trim() !== "" && Number.isFinite(run.x) && Number.isFinite(run.y)).map((run) => {
827
+ const size = runSize(run);
828
+ const width = run.width !== void 0 && run.width >= 0 ? run.width : run.text.length * size * 0.5;
829
+ return {
830
+ text: run.text,
831
+ x0: run.x,
832
+ x1: run.x + width,
833
+ y: run.y,
834
+ size,
835
+ bold: run.bold ?? BOLD_FONT_RE.test(run.fontName ?? ""),
836
+ italic: run.italic ?? ITALIC_FONT_RE.test(run.fontName ?? "")
837
+ };
838
+ });
839
+ items.sort((a, b) => b.y - a.y || a.x0 - b.x0);
840
+ const frags = [];
841
+ let i = 0;
842
+ while (i < items.length) {
843
+ const anchor = items[i];
844
+ let j = i + 1;
845
+ while (j < items.length && anchor.y - items[j].y <= Math.max(1, Math.min(anchor.size, items[j].size) * 0.5)) j++;
846
+ const row = items.slice(i, j).sort((a, b) => a.x0 - b.x0);
847
+ i = j;
848
+ let current = null;
849
+ const finish = () => {
850
+ if (!current) return;
851
+ let best = "";
852
+ let bestChars = -1;
853
+ current.styleChars.forEach((chars, key) => {
854
+ if (chars > bestChars) {
855
+ best = key;
856
+ bestChars = chars;
857
+ }
858
+ });
859
+ const [size, bold, italic] = best.split("|");
860
+ current.size = Number(size);
861
+ current.bold = bold === "1";
862
+ current.italic = italic === "1";
863
+ current.text = collapse(current.text);
864
+ current.words = countWords(current.text);
865
+ current.top = current.y + current.size * 0.8;
866
+ current.bottom = current.y - current.size * 0.2;
867
+ if (current.text) frags.push(current);
868
+ current = null;
869
+ };
870
+ for (const item of row) {
871
+ if (current) {
872
+ const gap = item.x0 - current.x1;
873
+ const em = Math.max(current.size, item.size);
874
+ const markerOnly = MARKER_ONLY_RE.test(collapse(current.text));
875
+ if (gap > em * (markerOnly ? 6 : 1)) finish();
876
+ }
877
+ if (!current) {
878
+ current = {
879
+ text: item.text,
880
+ x0: item.x0,
881
+ x1: item.x1,
882
+ y: item.y,
883
+ top: 0,
884
+ bottom: 0,
885
+ size: item.size,
886
+ bold: item.bold,
887
+ italic: item.italic,
888
+ words: 0,
889
+ styleChars: /* @__PURE__ */ new Map()
890
+ };
891
+ } else {
892
+ const gap = item.x0 - current.x1;
893
+ if (gap > Math.max(current.size, item.size) * 0.15 && !/\s$/.test(current.text) && !/^\s/.test(item.text)) {
894
+ current.text += " ";
895
+ }
896
+ current.text += item.text;
897
+ current.x1 = Math.max(current.x1, item.x1);
898
+ }
899
+ const key = `${Math.round(item.size * 2) / 2}|${item.bold ? 1 : 0}|${item.italic ? 1 : 0}`;
900
+ current.styleChars.set(key, (current.styleChars.get(key) ?? 0) + item.text.trim().length);
901
+ }
902
+ finish();
903
+ }
904
+ return frags;
905
+ }
906
+ function baselineRows(frags) {
907
+ const rows = [];
908
+ for (const frag of frags) {
909
+ const row = rows[rows.length - 1];
910
+ if (row && Math.abs(row[0].y - frag.y) <= Math.max(1, Math.min(row[0].size, frag.size) * 0.5)) row.push(frag);
911
+ else rows.push([frag]);
912
+ }
913
+ return rows;
914
+ }
915
+ var edgeKey = (row) => collapse(row.map((f) => f.text).join(" ")).toLowerCase().replace(/\d+/g, "#");
916
+ function removeHeadersAndFooters(pages) {
917
+ const removed = { headers: 0, footers: 0, pageNumbers: 0 };
918
+ const pageRows = pages.map((frags) => baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0)));
919
+ const counts = /* @__PURE__ */ new Map();
920
+ const candidates = [];
921
+ pageRows.forEach((rows, page) => {
922
+ const n = rows.length;
923
+ const picks = [];
924
+ for (let k = 0; k < Math.min(2, n); k++) picks.push([k, "top"]);
925
+ for (let k = Math.max(Math.min(2, n), n - 2); k < n; k++) picks.push([k, "bottom"]);
926
+ for (const [index, edge] of picks) {
927
+ const row = rows[index];
928
+ const extreme = edge === "top" ? index === 0 : index === n - 1;
929
+ const neighbour = edge === "top" ? rows[index + 1] : rows[index - 1];
930
+ const gap = neighbour ? Math.abs(row[0].y - neighbour[0].y) / row[0].size : Infinity;
931
+ candidates.push({ page, row, edge, extreme, gap });
932
+ const key = `${edge}:${edgeKey(row)}`;
933
+ if (!counts.has(key)) counts.set(key, /* @__PURE__ */ new Set());
934
+ counts.get(key).add(page);
935
+ }
936
+ });
937
+ const minPages = Math.max(2, Math.ceil(pages.length * 0.5));
938
+ const drop = /* @__PURE__ */ new Set();
939
+ for (const candidate of candidates) {
940
+ const text = collapse(candidate.row.map((f) => f.text).join(" "));
941
+ const isPageNumber = candidate.extreme && (PAGE_NUMBER_RE.test(text) || DASHED_PAGE_NUMBER_RE.test(text));
942
+ const repeated = (counts.get(`${candidate.edge}:${edgeKey(candidate.row)}`)?.size ?? 0) >= minPages;
943
+ let kind = null;
944
+ if (isPageNumber && (pages.length > 1 || candidate.gap > 2.5)) kind = "pageNumbers";
945
+ else if (repeated && pages.length > 1) kind = candidate.edge === "top" ? "headers" : "footers";
946
+ if (!kind || candidate.row.some((f) => drop.has(f))) continue;
947
+ candidate.row.forEach((f) => drop.add(f));
948
+ removed[kind]++;
949
+ }
950
+ if (drop.size) {
951
+ pages.forEach((frags, index) => {
952
+ pages[index] = frags.filter((f) => !drop.has(f));
953
+ });
954
+ }
955
+ return removed;
956
+ }
957
+ function splitRules(rules) {
958
+ const h = [];
959
+ const v = [];
960
+ for (const rule of rules.slice(0, MAX_RULES)) {
961
+ const { x1, y1, x2, y2 } = rule;
962
+ if (![x1, y1, x2, y2].every(Number.isFinite)) continue;
963
+ const dx = Math.abs(x2 - x1);
964
+ const dy = Math.abs(y2 - y1);
965
+ if (dy <= 1.5 && dx >= 6) h.push({ y: (y1 + y2) / 2, x0: Math.min(x1, x2), x1: Math.max(x1, x2) });
966
+ else if (dx <= 1.5 && dy >= 6) v.push({ x: (x1 + x2) / 2, y0: Math.min(y1, y2), y1: Math.max(y1, y2) });
967
+ }
968
+ return { h, v };
969
+ }
970
+ function clusterValues(values, tol) {
971
+ const sorted = [...values].sort((a, b) => a - b);
972
+ const out = [];
973
+ for (const value of sorted) {
974
+ const cluster = out[out.length - 1];
975
+ if (cluster && value - cluster.last <= tol) {
976
+ cluster.sum += value;
977
+ cluster.n++;
978
+ cluster.last = value;
979
+ } else out.push({ sum: value, n: 1, last: value });
980
+ }
981
+ return out.map((c) => c.sum / c.n);
982
+ }
983
+ function find(parent, i) {
984
+ while (parent[i] !== i) {
985
+ parent[i] = parent[parent[i]];
986
+ i = parent[i];
987
+ }
988
+ return i;
989
+ }
990
+ var cellText = (frags, dehyphenate, stats) => {
991
+ const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);
992
+ let text = "";
993
+ let lastY = Infinity;
994
+ for (const frag of sorted) {
995
+ if (!text) text = frag.text;
996
+ else if (Math.abs(lastY - frag.y) > frag.size * 0.5) text = joinLines(text, frag.text, dehyphenate, stats);
997
+ else text += ` ${frag.text}`;
998
+ lastY = frag.y;
999
+ }
1000
+ return collapse(text);
1001
+ };
1002
+ var NUMERIC_RE = /^[-+−(]?[$€£¥]?\s?\d[\d,.\s]*%?\)?$/;
1003
+ function headerRowCount(rowFrags) {
1004
+ if (rowFrags.length < 2) return 0;
1005
+ const cells = (row) => row.filter((cell) => cell.length > 0);
1006
+ const first = cells(rowFrags[0]);
1007
+ if (!first.length) return 0;
1008
+ const rest = rowFrags.slice(1).flatMap(cells);
1009
+ const allBold = (list) => list.length > 0 && list.every((cell) => cell.every((f) => f.bold));
1010
+ if (allBold(first) && !allBold(rest)) return 1;
1011
+ const numeric = (cell) => NUMERIC_RE.test(collapse(cell.map((f) => f.text).join(" ")));
1012
+ if (first.every((cell) => !numeric(cell))) {
1013
+ const columns = rowFrags[0].length;
1014
+ for (let c = 0; c < columns; c++) {
1015
+ const body = rowFrags.slice(1).map((row) => row[c]).filter((cell) => cell && cell.length > 0);
1016
+ if (rowFrags[0][c].length && body.length >= 2 && body.every(numeric)) return 1;
1017
+ }
1018
+ }
1019
+ const firstSize = maxOf(first.flat(), (f) => f.size);
1020
+ const restSize = median(rest.flat().map((f) => f.size));
1021
+ if (restSize > 0 && firstSize >= restSize * 1.1) return 1;
1022
+ return 0;
1023
+ }
1024
+ function ruledTables(frags, rules, page, dehyphenate, stats) {
1025
+ const consumed = /* @__PURE__ */ new Set();
1026
+ const atoms = [];
1027
+ const { h, v } = splitRules(rules);
1028
+ if (h.length < 2) return { atoms, consumed };
1029
+ const n = h.length + v.length;
1030
+ const parent = Array.from({ length: n }, (_, i) => i);
1031
+ const union = (a, b) => {
1032
+ const ra = find(parent, a);
1033
+ const rb = find(parent, b);
1034
+ if (ra !== rb) parent[ra] = rb;
1035
+ };
1036
+ const tol = 2;
1037
+ const vOrder = v.map((_, i) => i).sort((a, b) => v[a].x - v[b].x);
1038
+ const vxs = vOrder.map((i) => v[i].x);
1039
+ h.forEach((seg, hi) => {
1040
+ let lo = 0;
1041
+ let hiIdx = vxs.length;
1042
+ while (lo < hiIdx) {
1043
+ const mid = lo + hiIdx >> 1;
1044
+ if (vxs[mid] < seg.x0 - tol) lo = mid + 1;
1045
+ else hiIdx = mid;
1046
+ }
1047
+ for (let k = lo; k < vxs.length && vxs[k] <= seg.x1 + tol; k++) {
1048
+ const vs = v[vOrder[k]];
1049
+ if (seg.y >= vs.y0 - tol && seg.y <= vs.y1 + tol) union(hi, h.length + vOrder[k]);
1050
+ }
1051
+ });
1052
+ const hOrder = h.map((_, i) => i).sort((a, b) => h[a].x0 - h[b].x0 || h[a].x1 - h[b].x1 || h[b].y - h[a].y);
1053
+ for (let k = 1; k < hOrder.length; k++) {
1054
+ const a = h[hOrder[k - 1]];
1055
+ const b = h[hOrder[k]];
1056
+ if (Math.abs(a.x0 - b.x0) <= 4 && Math.abs(a.x1 - b.x1) <= 4) union(hOrder[k - 1], hOrder[k]);
1057
+ }
1058
+ const groups = /* @__PURE__ */ new Map();
1059
+ h.forEach((seg, i) => {
1060
+ const root = find(parent, i);
1061
+ if (!groups.has(root)) groups.set(root, { h: [], v: [] });
1062
+ groups.get(root).h.push(seg);
1063
+ });
1064
+ v.forEach((seg, i) => {
1065
+ const root = find(parent, h.length + i);
1066
+ groups.get(root)?.v.push(seg);
1067
+ });
1068
+ const byY = [...frags].sort((a, b) => a.y - b.y);
1069
+ const ys = byY.map((f) => f.y);
1070
+ const inRange = (y0, y1) => {
1071
+ let lo = 0;
1072
+ let hi = ys.length;
1073
+ while (lo < hi) {
1074
+ const mid = lo + hi >> 1;
1075
+ if (ys[mid] < y0) lo = mid + 1;
1076
+ else hi = mid;
1077
+ }
1078
+ const out = [];
1079
+ for (let k = lo; k < ys.length && ys[k] <= y1; k++) out.push(byY[k]);
1080
+ return out;
1081
+ };
1082
+ groups.forEach((group) => {
1083
+ const hys = clusterValues(group.h.map((s) => s.y), 1.5).sort((a, b) => b - a);
1084
+ if (hys.length < 2) return;
1085
+ const x0 = Math.min(...group.h.map((s) => s.x0), ...group.v.map((s) => s.x));
1086
+ const x1 = Math.max(...group.h.map((s) => s.x1), ...group.v.map((s) => s.x));
1087
+ const top = Math.max(hys[0], ...group.v.map((s) => s.y1));
1088
+ const bottom = Math.min(hys[hys.length - 1], ...group.v.map((s) => s.y0));
1089
+ const inside = inRange(bottom, top).filter((f) => {
1090
+ if (consumed.has(f)) return false;
1091
+ const cx = (f.x0 + f.x1) / 2;
1092
+ return cx >= x0 - 1 && cx <= x1 + 1;
1093
+ });
1094
+ if (inside.length < 2) return;
1095
+ const vxsGroup = clusterValues(group.v.map((s) => s.x), 1.5);
1096
+ let table = null;
1097
+ if (vxsGroup.length >= 3 || vxsGroup.length >= 2 && hys.length >= 3 && vxsGroup.some((x) => x > x0 + 4 && x < x1 - 4)) {
1098
+ table = gridTable(inside, group, hys, vxsGroup, x0, x1, top, bottom, page, dehyphenate, stats);
1099
+ }
1100
+ if (!table) {
1101
+ const result = alignedTable(inside, page, 2, dehyphenate, stats, hys.length >= 3 ? hys[1] : void 0);
1102
+ if (result && !result.leftover.length && !result.before.length) table = { ...result.table, ruled: true, confidence: 0.85 };
1103
+ }
1104
+ if (!table) return;
1105
+ inside.forEach((f) => consumed.add(f));
1106
+ atoms.push({
1107
+ text: "",
1108
+ x0,
1109
+ x1,
1110
+ y: bottom,
1111
+ top,
1112
+ bottom,
1113
+ size: median(inside.map((f) => f.size)),
1114
+ bold: false,
1115
+ italic: false,
1116
+ words: 0,
1117
+ table
1118
+ });
1119
+ });
1120
+ return { atoms, consumed };
1121
+ }
1122
+ function gridTable(inside, group, hys, vxsIn, x0, x1, top, bottom, page, dehyphenate, stats) {
1123
+ const xs = [...vxsIn];
1124
+ if (xs[0] > x0 + 4) xs.unshift(x0);
1125
+ if (xs[xs.length - 1] < x1 - 4) xs.push(x1);
1126
+ const rowsY = [...hys];
1127
+ if (rowsY[0] < top - 4) rowsY.unshift(top);
1128
+ if (rowsY[rowsY.length - 1] > bottom + 4) rowsY.push(bottom);
1129
+ const cols = xs.length - 1;
1130
+ const rows = rowsY.length - 1;
1131
+ if (cols < 2 || rows < 1 || cols > MAX_COLS || rows > MAX_TABLE_ROWS2) return null;
1132
+ const grid = Array.from({ length: rows }, () => Array.from({ length: cols }, () => []));
1133
+ const ascRows = [...rowsY].reverse();
1134
+ for (const frag of inside) {
1135
+ const x = frag.x0 + Math.min(2, (frag.x1 - frag.x0) / 2);
1136
+ const c = lowerBound(xs, x + 1e-9) - 1;
1137
+ const yProbe = frag.y + frag.size * 0.3;
1138
+ const r = rows - (lowerBound(ascRows, yProbe + 1e-9) - 1) - 1;
1139
+ if (c >= 0 && c < cols && r >= 0 && r < rows) grid[r][c].push(frag);
1140
+ }
1141
+ const filled = grid.flat().filter((cell) => cell.length).length;
1142
+ if (filled < 2 || rows < 2 && cols < 2) return null;
1143
+ const vAt = xs.map(() => []);
1144
+ for (const seg of group.v) {
1145
+ const k = lowerBound(xs, seg.x - 2);
1146
+ if (k < xs.length && Math.abs(xs[k] - seg.x) <= 2) vAt[k].push(seg);
1147
+ }
1148
+ const hAt = rowsY.map(() => []);
1149
+ for (const seg of group.h) {
1150
+ const k = rows - lowerBound(ascRows, seg.y - 2);
1151
+ if (k >= 0 && k <= rows && Math.abs(rowsY[k] - seg.y) <= 2) hAt[k].push(seg);
1152
+ }
1153
+ const hasV = (k, y) => vAt[k].some((s) => y >= s.y0 - 2 && y <= s.y1 + 2);
1154
+ const hasH = (k, x) => hAt[k].some((s) => x >= s.x0 - 2 && x <= s.x1 + 2);
1155
+ const covered = grid.map((row) => row.map(() => false));
1156
+ const header = headerRowCount(grid);
1157
+ const out = [];
1158
+ for (let r = 0; r < rows; r++) {
1159
+ const midY = (rowsY[r] + rowsY[r + 1]) / 2;
1160
+ const row = [];
1161
+ for (let c = 0; c < cols; c++) {
1162
+ if (covered[r][c]) continue;
1163
+ let colSpan = 1;
1164
+ while (c + colSpan < cols && !hasV(c + colSpan, midY) && !grid[r][c + colSpan].length && !covered[r][c + colSpan]) colSpan++;
1165
+ let rowSpan = 1;
1166
+ const midX = (xs[c] + xs[c + colSpan]) / 2;
1167
+ while (r + rowSpan < rows && !hasH(r + rowSpan, midX) && !covered[r + rowSpan].slice(c, c + colSpan).some(Boolean) && grid[r + rowSpan].slice(c, c + colSpan).every((cell) => !cell.length)) {
1168
+ rowSpan++;
1169
+ }
1170
+ for (let rr = r; rr < r + rowSpan; rr++) for (let cc = c; cc < c + colSpan; cc++) covered[rr][cc] = true;
1171
+ row.push({ text: cellText(grid[r][c], dehyphenate, stats), colSpan, rowSpan, header: r < header });
1172
+ }
1173
+ out.push(row);
1174
+ }
1175
+ return { type: "table", page, confidence: 0.95, ruled: true, rows: out, columns: cols, headerRows: header };
1176
+ }
1177
+ function alignedTable(frags, page, minRows, dehyphenate, stats, headerRuleY) {
1178
+ const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);
1179
+ let rows = baselineRows(sorted).map((row) => row.sort((a, b) => a.x0 - b.x0));
1180
+ if (rows.length < minRows) return null;
1181
+ const multi = rows.filter((row) => row.length >= 2);
1182
+ if (multi.length < Math.min(minRows, 2)) return null;
1183
+ const spans = multi.flat().map((f) => [f.x0, f.x1]).sort((a, b) => a[0] - b[0]);
1184
+ const merged = [];
1185
+ for (const [a, b] of spans) {
1186
+ const last = merged[merged.length - 1];
1187
+ if (last && a <= last[1] + 1) last[1] = Math.max(last[1], b);
1188
+ else merged.push([a, b]);
1189
+ }
1190
+ if (merged.length < 2 || merged.length > MAX_COLS) return null;
1191
+ const edges = merged.map((m) => m[0]);
1192
+ const cols = merged.length;
1193
+ const colOf = (x) => {
1194
+ let c = 0;
1195
+ while (c + 1 < cols && x >= merged[c + 1][0] - 1) c++;
1196
+ return c;
1197
+ };
1198
+ const spanOf = (f, c) => {
1199
+ let span = 1;
1200
+ while (c + span < cols && f.x1 > merged[c + span][0] + 2) span++;
1201
+ return span;
1202
+ };
1203
+ const rowIsCells = (row) => {
1204
+ if (row.length >= 2) return true;
1205
+ const f = row[0];
1206
+ const c = colOf(f.x0);
1207
+ return spanOf(f, c) >= 2 && f.words <= 8 && Math.abs(f.x0 - edges[c]) <= Math.max(4, f.size * 0.6);
1208
+ };
1209
+ const before = [];
1210
+ const leftover = [];
1211
+ let first = 0;
1212
+ let end = rows.length;
1213
+ while (first < end && !rowIsCells(rows[first])) first++;
1214
+ while (end > first && !rowIsCells(rows[end - 1])) end--;
1215
+ rows.slice(0, first).forEach((row) => before.push(...row));
1216
+ rows.slice(end).forEach((row) => leftover.push(...row));
1217
+ rows = rows.slice(first, end);
1218
+ if (rows.length < minRows || rows.length > MAX_TABLE_ROWS2) return null;
1219
+ const grid = [];
1220
+ const spansGrid = [];
1221
+ let prevRow = null;
1222
+ for (const row of rows) {
1223
+ const cells = Array.from({ length: cols }, () => []);
1224
+ const spanRow = Array.from({ length: cols }, () => 1);
1225
+ for (const f of row) {
1226
+ const c = colOf(f.x0);
1227
+ cells[c].push(f);
1228
+ spanRow[c] = Math.max(spanRow[c], row.length === 1 ? spanOf(f, c) : 1);
1229
+ }
1230
+ const continuation = prevRow !== null && grid.length > 0 && cells[0].length === 0 && grid[grid.length - 1][0].length > 0 && cells.every((cell, c) => !cell.length || grid[grid.length - 1][c].length > 0) && minOf(prevRow, (f) => f.bottom) - maxOf(row, (f) => f.top) < row[0].size * 0.5;
1231
+ if (continuation) {
1232
+ cells.forEach((cell, c) => grid[grid.length - 1][c].push(...cell));
1233
+ } else {
1234
+ grid.push(cells);
1235
+ spansGrid.push(spanRow);
1236
+ }
1237
+ prevRow = row;
1238
+ }
1239
+ if (grid.length < minRows) return null;
1240
+ const full = grid.filter((cells) => cells.filter((c) => c.length).length >= 2).length;
1241
+ if (full / grid.length < 0.6) return null;
1242
+ const cellsWithText = grid.flat().filter((c) => c.length);
1243
+ const meanWords = cellsWithText.reduce((sum, cell) => sum + cell.reduce((s, f) => s + f.words, 0), 0) / cellsWithText.length;
1244
+ if (meanWords > 12) return null;
1245
+ let header = headerRowCount(grid);
1246
+ if (headerRuleY !== void 0) {
1247
+ const above = rows.filter((row) => row[0].y > headerRuleY).length;
1248
+ if (above > 0 && above < grid.length) header = Math.max(header, Math.min(above, grid.length - 1));
1249
+ }
1250
+ const out = grid.map((cells, r) => {
1251
+ const row = [];
1252
+ for (let c = 0; c < cols; ) {
1253
+ const span = Math.min(spansGrid[r][c], cols - c);
1254
+ row.push({ text: cellText(cells[c], dehyphenate, stats), colSpan: span, rowSpan: 1, header: r < header });
1255
+ c += span;
1256
+ }
1257
+ return row;
1258
+ });
1259
+ const confidence = Math.min(
1260
+ 0.9,
1261
+ 0.5 + (grid.length >= 5 ? 0.1 : 0) + (cols >= 3 ? 0.1 : 0) + 0.2 * (full / grid.length) - (cols === 2 ? 0.05 : 0)
1262
+ );
1263
+ return {
1264
+ table: { type: "table", page, confidence, ruled: false, rows: out, columns: cols, headerRows: header },
1265
+ leftover,
1266
+ before
1267
+ };
1268
+ }
1269
+ function readingOrder(items, body, detectColumns, depth, columnPages) {
1270
+ const byTop = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);
1271
+ if (!detectColumns || items.length < 2 || depth > MAX_DEPTH) return [{ kind: "flow", items: byTop }];
1272
+ const left = minOf(items, (f) => f.x0);
1273
+ const right = maxOf(items, (f) => f.x1);
1274
+ const width = right - left;
1275
+ const isNarrow = (f) => f.x1 - f.x0 < width * 0.55;
1276
+ const narrow = items.filter(isNarrow);
1277
+ const minGutter = Math.max(body * 0.9, 6);
1278
+ const allowed = Math.max(1, Math.floor(narrow.length * 0.08));
1279
+ const events = [];
1280
+ for (const f of narrow) events.push([f.x0, 1], [f.x1, -1]);
1281
+ events.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
1282
+ const candidates = [];
1283
+ let depthNow = 0;
1284
+ let seenContent = false;
1285
+ let start = null;
1286
+ for (const [x, delta] of events) {
1287
+ depthNow += delta;
1288
+ if (depthNow > allowed) {
1289
+ if (start !== null && seenContent && x - start >= minGutter) candidates.push([start, x]);
1290
+ start = null;
1291
+ seenContent = true;
1292
+ } else if (start === null) start = x;
1293
+ }
1294
+ const ends = narrow.map((f) => f.x1).sort((a, b) => a - b);
1295
+ const starts = narrow.map((f) => f.x0).sort((a, b) => a - b);
1296
+ const gutters = [];
1297
+ for (const [a, b] of candidates) {
1298
+ const endBelow = lowerBound(ends, b) - 1;
1299
+ const left2 = endBelow >= 0 && ends[endBelow] > a ? ends[endBelow] : a;
1300
+ const startAbove = lowerBound(starts, a + 1e-9);
1301
+ const right2 = startAbove < starts.length && starts[startAbove] < b ? starts[startAbove] : b;
1302
+ if (right2 - left2 < minGutter) continue;
1303
+ const onLeft = lowerBound(ends, left2 + 1e-6);
1304
+ const onRight = starts.length - lowerBound(starts, right2 - 1e-6);
1305
+ const strays = narrow.length - onLeft - onRight;
1306
+ if (strays < Math.min(onLeft, onRight)) gutters.push([left2, right2]);
1307
+ }
1308
+ if (!gutters.length) return [{ kind: "flow", items: byTop }];
1309
+ const gutterEnds = gutters.map((g) => g[1]);
1310
+ const crosses = (f) => {
1311
+ const k = lowerBound(gutterEnds, f.x0 + 1 + 1e-9);
1312
+ return k < gutters.length && f.x1 > gutters[k][0] + 1 && f.x0 < gutters[k][1] - 1;
1313
+ };
1314
+ const columnOf = (f) => lowerBound(gutterEnds, f.x0 + 1 + 1e-9);
1315
+ const bands = [];
1316
+ for (const f of byTop) {
1317
+ const spanning = crosses(f);
1318
+ const band = bands[bands.length - 1];
1319
+ if (band && band.spanning === spanning) band.items.push(f);
1320
+ else bands.push({ spanning, items: [f] });
1321
+ }
1322
+ const segments = [];
1323
+ let sealed = false;
1324
+ const pushFlow = (list) => {
1325
+ if (!list.length) return;
1326
+ const last = segments[segments.length - 1];
1327
+ if (last && last.kind === "flow" && !sealed) last.items.push(...list);
1328
+ else segments.push({ kind: "flow", items: list });
1329
+ sealed = false;
1330
+ };
1331
+ let multiColumn = false;
1332
+ const isShortSpan = (f) => !f.table && isNarrow(f) && f.words <= 8;
1333
+ for (const band of bands) {
1334
+ const last = segments[segments.length - 1];
1335
+ if (band.spanning) {
1336
+ const lead = band.items[0];
1337
+ if (last && last.kind === "grid" && isShortSpan(lead) && minOf(last.items, (f) => f.bottom) - lead.top <= lead.size * 2) {
1338
+ last.items.push(lead);
1339
+ pushFlow(band.items.slice(1));
1340
+ } else pushFlow(band.items);
1341
+ continue;
1342
+ }
1343
+ const columns = Array.from({ length: gutters.length + 1 }, () => []);
1344
+ band.items.forEach((f) => columns[columnOf(f)].push(f));
1345
+ const used = columns.filter((c) => c.length);
1346
+ if (used.length < 2) {
1347
+ pushFlow(band.items);
1348
+ continue;
1349
+ }
1350
+ const prose = used.every((col) => {
1351
+ const text = col.filter((f) => !f.table);
1352
+ if (text.length < 2) return text.length === 0;
1353
+ const colLeft = minOf(text, (f) => f.x0);
1354
+ const colRight = maxOf(text, (f) => f.x1);
1355
+ const fill = text.reduce((sum, f) => sum + (f.x1 - f.x0), 0) / text.length / Math.max(1, colRight - colLeft);
1356
+ const words = text.reduce((sum, f) => sum + f.words, 0) / text.length;
1357
+ return fill >= 0.55 && words >= 3;
1358
+ });
1359
+ const tops = used.map((col) => [minOf(col, (f) => f.bottom), maxOf(col, (f) => f.top)]);
1360
+ const overlapping = tops.every(([b, t], i) => i === 0 || Math.min(t, tops[0][1]) - Math.max(b, tops[0][0]) > 0);
1361
+ if (prose && overlapping) {
1362
+ multiColumn = true;
1363
+ for (const col of used) segments.push(...readingOrder(col, body, detectColumns, depth + 1, columnPages));
1364
+ sealed = true;
1365
+ continue;
1366
+ }
1367
+ const pulled = [];
1368
+ if (last && last.kind === "flow" && !sealed) {
1369
+ const tail = last.items[last.items.length - 1];
1370
+ if (isShortSpan(tail) && tail.bottom - maxOf(band.items, (f) => f.top) <= tail.size * 2) {
1371
+ pulled.push(last.items.pop());
1372
+ if (!last.items.length) segments.pop();
1373
+ }
1374
+ }
1375
+ const prevSegment = segments[segments.length - 1];
1376
+ if (prevSegment && prevSegment.kind === "grid" && (pulled.length || prevSegment === last)) {
1377
+ prevSegment.items.push(...pulled, ...band.items);
1378
+ } else segments.push({ kind: "grid", items: [...pulled, ...band.items] });
1379
+ sealed = false;
1380
+ }
1381
+ if (multiColumn && depth === 0) columnPages.count++;
1382
+ return segments;
1383
+ }
1384
+ function flowLines(items, page) {
1385
+ const lines = [];
1386
+ const sorted = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);
1387
+ for (const f of sorted) {
1388
+ if (f.table) {
1389
+ lines.push({ text: "", x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: false, page, table: f.table });
1390
+ continue;
1391
+ }
1392
+ const last = lines[lines.length - 1];
1393
+ if (last && !last.table && Math.abs(last.y - f.y) <= Math.min(last.size, f.size) * 0.5) {
1394
+ last.text = `${last.text} ${f.text}`;
1395
+ last.x0 = Math.min(last.x0, f.x0);
1396
+ last.x1 = Math.max(last.x1, f.x1);
1397
+ } else {
1398
+ lines.push({ text: f.text, x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: f.bold, page });
1399
+ }
1400
+ }
1401
+ return lines;
1402
+ }
1403
+ function joinLines(prev, next, dehyphenate, stats) {
1404
+ if (prev.endsWith("\xAD")) {
1405
+ stats.dehyphenated++;
1406
+ return prev.slice(0, -1) + next;
1407
+ }
1408
+ if (dehyphenate && /[A-Za-zÀ-ɏ]-$/.test(prev) && /^[a-zß-ɏ]/.test(next)) {
1409
+ stats.dehyphenated++;
1410
+ return prev.slice(0, -1) + next;
1411
+ }
1412
+ return `${prev} ${next}`;
1413
+ }
1414
+ function listMarker(text) {
1415
+ const glyph = BULLET_GLYPH_RE.exec(text);
1416
+ if (glyph) return { kind: "glyph", rest: text.slice(glyph[0].length), ordered: false };
1417
+ const dash = BULLET_DASH_RE.exec(text);
1418
+ if (dash) return { kind: "dash", rest: text.slice(dash[0].length), ordered: false };
1419
+ const ordered = ORDERED_RE.exec(text);
1420
+ if (ordered) {
1421
+ const token = ordered[1] ?? ordered[2];
1422
+ const kind = /^\d+$/.test(token) ? "num" : /^[ivxlc]{2,}$/i.test(token) || /^i$/i.test(token) ? "roman" : "alpha";
1423
+ return { kind, rest: text.slice(ordered[0].length), ordered: true, value: kind === "num" ? Number(token) : void 0 };
1424
+ }
1425
+ return null;
1426
+ }
1427
+ function headingStyle(line, next, segRight, ctx) {
1428
+ if (!ctx.options.detectHeadings || line.table) return null;
1429
+ const text = line.text;
1430
+ const words = countWords(text);
1431
+ if (text.length > 200 || words > 25 || !/\p{L}/u.test(text)) return null;
1432
+ if (words > 15 && SENTENCE_END_RE.test(text)) return null;
1433
+ const ratio = line.size / ctx.body;
1434
+ if (ratio >= 1.15) {
1435
+ const confidence = Math.min(0.95, 0.6 + (ratio - 1.15) * 0.8 + (line.bold ? 0.1 : 0));
1436
+ return { key: Math.round(line.size * 2) / 2 + (line.bold ? 0.25 : 0), confidence, boldOnly: false };
1437
+ }
1438
+ const runsOn = !!next && !next.table && next.bold && Math.abs(next.size - line.size) < 0.5 && line.x1 >= segRight - 2 * line.size;
1439
+ if (line.bold && !ctx.boldBody && !runsOn && ratio >= 0.95 && text.length <= 100 && !/[.,;]$/.test(text)) {
1440
+ return { key: Math.round(line.size * 2) / 2 + 0.25, confidence: 0.6, boldOnly: true };
1441
+ }
1442
+ return null;
1443
+ }
1444
+ function buildBlocks(lines, ctx) {
1445
+ const textLines = lines.filter((l) => !l.table);
1446
+ const segLeft = textLines.length ? minOf(textLines, (l) => l.x0) : 0;
1447
+ const segRight = textLines.length ? maxOf(textLines, (l) => l.x1) : 0;
1448
+ const kindCounts = /* @__PURE__ */ new Map();
1449
+ const markers = lines.map((line) => {
1450
+ if (!ctx.options.detectLists || line.table) return null;
1451
+ const marker = listMarker(line.text);
1452
+ if (marker) kindCounts.set(marker.kind, (kindCounts.get(marker.kind) ?? 0) + 1);
1453
+ return marker;
1454
+ });
1455
+ let list = null;
1456
+ let listStack = [];
1457
+ let lastItemLine = null;
1458
+ let para = null;
1459
+ let heading = null;
1460
+ const closeAll = () => {
1461
+ if (para) {
1462
+ const last = para.lines[para.lines.length - 1];
1463
+ const ended = SENTENCE_END_RE.test(last.text) || last.x1 < segRight - 3 * last.size;
1464
+ ctx.open = ended ? null : { block: para.block, size: last.size, lastText: para.block.text };
1465
+ } else ctx.open = null;
1466
+ para = null;
1467
+ list = null;
1468
+ listStack = [];
1469
+ lastItemLine = null;
1470
+ heading = null;
1471
+ };
1472
+ lines.forEach((line, index) => {
1473
+ const prev = index > 0 ? lines[index - 1] : null;
1474
+ if (line.table) {
1475
+ closeAll();
1476
+ ctx.open = null;
1477
+ ctx.blocks.push(line.table);
1478
+ return;
1479
+ }
1480
+ const style = headingStyle(line, lines[index + 1], segRight, ctx);
1481
+ if (style) {
1482
+ if (heading && heading.key === style.key && heading.lines < 3 && prev === heading.line && prev.y - line.y <= line.size * 1.6) {
1483
+ heading.block.text = joinLines(heading.block.text, line.text, ctx.options.dehyphenate, ctx.stats);
1484
+ heading.line = line;
1485
+ heading.lines++;
1486
+ return;
1487
+ }
1488
+ closeAll();
1489
+ ctx.open = null;
1490
+ const block2 = { type: "heading", level: 1, text: line.text, page: line.page, confidence: style.confidence };
1491
+ ctx.blocks.push(block2);
1492
+ ctx.headings.push({ block: block2, key: style.key, boldOnly: style.boldOnly });
1493
+ heading = { block: block2, line, key: style.key, lines: 1 };
1494
+ return;
1495
+ }
1496
+ heading = null;
1497
+ const marker = markers[index];
1498
+ const validMarker = marker && (marker.kind === "glyph" || (kindCounts.get(marker.kind) ?? 0) >= 2) && marker.rest.trim() !== "";
1499
+ if (validMarker) {
1500
+ const gapOk = lastItemLine && lastItemLine.y - line.y <= Math.max(ctx.pitch(line.size) * 2.2, line.size * 2.4);
1501
+ if (!list || !gapOk) {
1502
+ closeAll();
1503
+ ctx.open = null;
1504
+ list = { type: "list", page: line.page, confidence: 0.6, items: [] };
1505
+ ctx.blocks.push(list);
1506
+ listStack = [line.x0];
1507
+ }
1508
+ const tol = line.size * 0.5;
1509
+ while (listStack.length > 1 && line.x0 < listStack[listStack.length - 1] - tol) listStack.pop();
1510
+ if (line.x0 > listStack[listStack.length - 1] + tol) listStack.push(line.x0);
1511
+ else listStack[listStack.length - 1] = Math.min(listStack[listStack.length - 1], line.x0);
1512
+ const prevDepth = list.items.length ? list.items[list.items.length - 1].depth : -1;
1513
+ const depth = Math.min(listStack.length - 1, prevDepth + 1);
1514
+ const item = {
1515
+ text: collapse(marker.rest),
1516
+ depth,
1517
+ ordered: marker.ordered
1518
+ };
1519
+ if (marker.value !== void 0) item.start = marker.value;
1520
+ list.items.push(item);
1521
+ list.confidence = Math.min(0.95, (marker.kind === "glyph" ? 0.75 : 0.6) + 0.05 * list.items.length);
1522
+ lastItemLine = line;
1523
+ para = null;
1524
+ return;
1525
+ }
1526
+ if (list && lastItemLine && prev) {
1527
+ const markerX = listStack[listStack.length - 1];
1528
+ const continues = line.x0 > markerX + line.size * 0.3 && line.x0 <= markerX + line.size * 5 && prev.y - line.y <= ctx.pitch(line.size) * ctx.options.paragraphGap;
1529
+ if (continues) {
1530
+ const item = list.items[list.items.length - 1];
1531
+ item.text = joinLines(item.text, line.text, ctx.options.dehyphenate, ctx.stats);
1532
+ lastItemLine = line;
1533
+ return;
1534
+ }
1535
+ closeAll();
1536
+ }
1537
+ if (!para && ctx.open && index === 0 && /^[a-z]/.test(line.text) && Math.abs(ctx.open.size - line.size) <= line.size * 0.12) {
1538
+ ctx.open.block.text = joinLines(ctx.open.block.text, line.text, ctx.options.dehyphenate, ctx.stats);
1539
+ para = { block: ctx.open.block, lines: [line] };
1540
+ ctx.open = null;
1541
+ return;
1542
+ }
1543
+ if (para && prev && !prev.table) {
1544
+ const last = para.lines[para.lines.length - 1];
1545
+ const gap = last.y - line.y;
1546
+ const sameSize = Math.abs(last.size - line.size) <= last.size * 0.12;
1547
+ const closeEnough = gap > 0 && gap <= ctx.pitch(line.size) * ctx.options.paragraphGap;
1548
+ const indentEm = line.size * 0.8;
1549
+ const indented = line.x0 - segLeft >= indentEm && last.x0 - segLeft < indentEm && line.x0 - segLeft < line.size * 8;
1550
+ const shortEnded = last.x1 < segRight - 3 * last.size && SENTENCE_END_RE.test(last.text);
1551
+ if (sameSize && closeEnough && !indented && !shortEnded) {
1552
+ para.block.text = joinLines(para.block.text, line.text, ctx.options.dehyphenate, ctx.stats);
1553
+ para.lines.push(line);
1554
+ return;
1555
+ }
1556
+ }
1557
+ closeAll();
1558
+ ctx.open = null;
1559
+ const block = { type: "paragraph", text: line.text, page: line.page };
1560
+ ctx.blocks.push(block);
1561
+ para = { block, lines: [line] };
1562
+ });
1563
+ closeAll();
1564
+ }
1565
+ function assignHeadingLevels(headings) {
1566
+ const keys = Array.from(new Set(headings.map((h) => h.key))).sort((a, b) => b - a);
1567
+ const levelOf = new Map(keys.map((key, i) => [key, Math.min(6, i + 1)]));
1568
+ headings.forEach((h) => {
1569
+ h.block.level = levelOf.get(h.key);
1570
+ });
1571
+ }
1572
+ var DEFAULTS = {
1573
+ paragraphGap: 1.4,
1574
+ removeHeadersAndFooters: true,
1575
+ detectColumns: true,
1576
+ detectHeadings: true,
1577
+ detectLists: true,
1578
+ detectTables: true,
1579
+ dehyphenate: true
1580
+ };
1581
+ function analyzePdfLayout(pages, options = {}) {
1582
+ const opts = { ...DEFAULTS };
1583
+ Object.keys(options).forEach((key) => {
1584
+ if (options[key] !== void 0) opts[key] = options[key];
1585
+ });
1586
+ const fragPages = pages.map((page) => buildFragments(page.runs ?? []));
1587
+ const removed = opts.removeHeadersAndFooters ? removeHeadersAndFooters(fragPages) : { headers: 0, footers: 0, pageNumbers: 0 };
1588
+ const bySize = /* @__PURE__ */ new Map();
1589
+ let boldChars = 0;
1590
+ let totalChars = 0;
1591
+ fragPages.flat().forEach((f) => {
1592
+ const key = Math.round(f.size * 2) / 2;
1593
+ bySize.set(key, (bySize.get(key) ?? 0) + f.text.length);
1594
+ });
1595
+ let body = 10;
1596
+ let bodyChars = -1;
1597
+ bySize.forEach((chars, size) => {
1598
+ if (chars > bodyChars) {
1599
+ body = size;
1600
+ bodyChars = chars;
1601
+ }
1602
+ });
1603
+ fragPages.flat().forEach((f) => {
1604
+ if (Math.abs(f.size - body) <= body * 0.05) {
1605
+ totalChars += f.text.length;
1606
+ if (f.bold) boldChars += f.text.length;
1607
+ }
1608
+ });
1609
+ const pitches = /* @__PURE__ */ new Map();
1610
+ fragPages.forEach((frags) => {
1611
+ const rows = baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0));
1612
+ for (let k = 1; k < rows.length; k++) {
1613
+ const a = rows[k - 1][0];
1614
+ const b = rows[k][0];
1615
+ if (Math.abs(a.size - b.size) > 0.5) continue;
1616
+ const d = a.y - b.y;
1617
+ if (d > 0 && d < a.size * 3) {
1618
+ const key = Math.round(b.size * 2) / 2;
1619
+ if (!pitches.has(key)) pitches.set(key, []);
1620
+ pitches.get(key).push(d);
1621
+ }
1622
+ }
1623
+ });
1624
+ const pitchMedians = /* @__PURE__ */ new Map();
1625
+ pitches.forEach((values, key) => pitchMedians.set(key, median(values)));
1626
+ const stats = { dehyphenated: 0 };
1627
+ const ctx = {
1628
+ body,
1629
+ boldBody: totalChars > 0 && boldChars / totalChars > 0.5,
1630
+ pitch: (size) => {
1631
+ const known = pitchMedians.get(Math.round(size * 2) / 2);
1632
+ return known && known >= size * 0.9 ? known : size * 1.2;
1633
+ },
1634
+ options: opts,
1635
+ stats,
1636
+ blocks: [],
1637
+ headings: [],
1638
+ open: null
1639
+ };
1640
+ const columnPages = { count: 0 };
1641
+ const items = [];
1642
+ fragPages.forEach((frags, pageIndex) => {
1643
+ const page = pageIndex + 1;
1644
+ let flowFrags = frags;
1645
+ const atoms = [];
1646
+ if (opts.detectTables && pages[pageIndex].rules?.length) {
1647
+ const ruled = ruledTables(frags, pages[pageIndex].rules, page, opts.dehyphenate, stats);
1648
+ flowFrags = frags.filter((f) => !ruled.consumed.has(f));
1649
+ atoms.push(...ruled.atoms);
1650
+ }
1651
+ const before = columnPages.count;
1652
+ const segments = readingOrder([...flowFrags, ...atoms], body, opts.detectColumns, 0, columnPages);
1653
+ if (columnPages.count > before) items.push({ type: "columns", page, confidence: 0.8, detail: "multi-column layout" });
1654
+ const units = [];
1655
+ let carry = [];
1656
+ for (const segment of segments) {
1657
+ if (segment.kind === "grid" && opts.detectTables) {
1658
+ const result = alignedTable(segment.items.filter((f) => !f.table), page, 3, opts.dehyphenate, stats);
1659
+ if (result) {
1660
+ const last = units[units.length - 1];
1661
+ if (result.before.length && last && last.kind === "flow") last.items.push(...carry, ...result.before);
1662
+ else if (result.before.length || carry.length) units.push({ kind: "flow", items: [...carry, ...result.before] });
1663
+ units.push({ kind: "table", table: result.table });
1664
+ carry = [...segment.items.filter((f) => f.table), ...result.leftover];
1665
+ continue;
1666
+ }
1667
+ }
1668
+ units.push({ kind: "flow", items: [...carry, ...segment.items] });
1669
+ carry = [];
1670
+ }
1671
+ if (carry.length) units.push({ kind: "flow", items: carry });
1672
+ for (const unit of units) {
1673
+ if (unit.kind === "table") {
1674
+ ctx.open = null;
1675
+ ctx.blocks.push(unit.table);
1676
+ } else buildBlocks(flowLines(unit.items, page), ctx);
1677
+ }
1678
+ });
1679
+ assignHeadingLevels(ctx.headings);
1680
+ const counts = { headings: 0, lists: 0, tables: 0, paragraphs: 0 };
1681
+ const confidences = [];
1682
+ ctx.blocks.forEach((block) => {
1683
+ if (block.type === "heading") {
1684
+ counts.headings++;
1685
+ confidences.push(block.confidence);
1686
+ items.push({ type: "heading", page: block.page, confidence: block.confidence, detail: `H${block.level} "${truncate(block.text)}"` });
1687
+ } else if (block.type === "list") {
1688
+ counts.lists++;
1689
+ confidences.push(block.confidence);
1690
+ const depth = maxOf(block.items, (i) => i.depth) + 1;
1691
+ items.push({
1692
+ type: "list",
1693
+ page: block.page,
1694
+ confidence: block.confidence,
1695
+ detail: `${block.items[0]?.ordered ? "numbered" : "bulleted"} list, ${block.items.length} items${depth > 1 ? `, ${depth} levels` : ""}`
1696
+ });
1697
+ } else if (block.type === "table") {
1698
+ counts.tables++;
1699
+ confidences.push(block.confidence);
1700
+ items.push({
1701
+ type: "table",
1702
+ page: block.page,
1703
+ confidence: block.confidence,
1704
+ detail: `${block.rows.length}\xD7${block.columns} table${block.ruled ? " (ruled)" : ""}${block.headerRows ? ", header row" : ""}`
1705
+ });
1706
+ } else counts.paragraphs++;
1707
+ });
1708
+ items.sort((a, b) => a.page - b.page);
1709
+ return {
1710
+ blocks: ctx.blocks,
1711
+ report: {
1712
+ mode: "structured",
1713
+ pages: pages.length,
1714
+ counts,
1715
+ multiColumnPages: columnPages.count,
1716
+ confidence: confidences.length ? Math.round(confidences.reduce((a, b) => a + b, 0) / confidences.length * 100) / 100 : 1,
1717
+ items,
1718
+ removed,
1719
+ dehyphenated: stats.dehyphenated
1720
+ }
1721
+ };
1722
+ }
1723
+ var truncate = (text) => text.length > 60 ? `${text.slice(0, 57)}\u2026` : text;
1724
+ function listHtml(items) {
1725
+ let html = "";
1726
+ const stack = [];
1727
+ for (const item of items) {
1728
+ const level = item.depth + 1;
1729
+ while (stack.length > level) html += `</li></${stack.pop()}>`;
1730
+ const tag = item.ordered ? "ol" : "ul";
1731
+ if (stack.length === level) {
1732
+ if (stack[stack.length - 1] !== tag) {
1733
+ html += `</li></${stack.pop()}>`;
1734
+ } else html += "</li>";
1735
+ }
1736
+ while (stack.length < level) {
1737
+ const start = item.ordered && item.start !== void 0 && item.start !== 1 ? ` start="${item.start}"` : "";
1738
+ html += `<${tag}${start}>`;
1739
+ stack.push(tag);
1740
+ }
1741
+ html += `<li><p>${escapeHtml(item.text)}</p>`;
1742
+ }
1743
+ while (stack.length) html += `</li></${stack.pop()}>`;
1744
+ return html;
1745
+ }
1746
+ function pdfLayoutBlocksToHtml(blocks) {
1747
+ let html = "";
1748
+ for (const block of blocks) {
1749
+ if (block.type === "heading") html += `<h${block.level}>${escapeHtml(block.text)}</h${block.level}>`;
1750
+ else if (block.type === "paragraph") html += `<p>${escapeHtml(block.text)}</p>`;
1751
+ else if (block.type === "list") html += listHtml(block.items);
1752
+ else {
1753
+ html += "<table><tbody>";
1754
+ for (const row of block.rows) {
1755
+ html += "<tr>";
1756
+ for (const cell of row) {
1757
+ const tag = cell.header ? "th" : "td";
1758
+ const attrs = `${cell.colSpan > 1 ? ` colspan="${cell.colSpan}"` : ""}${cell.rowSpan > 1 ? ` rowspan="${cell.rowSpan}"` : ""}`;
1759
+ html += `<${tag}${attrs}><p>${escapeHtml(cell.text)}</p></${tag}>`;
1760
+ }
1761
+ html += "</tr>";
1762
+ }
1763
+ html += "</tbody></table>";
1764
+ }
1765
+ }
1766
+ return html || "<p></p>";
1767
+ }
603
1768
 
604
1769
  // src/import/pdf.ts
605
1770
  var isTextItem = (item) => typeof item.str === "string";
606
- function median(values) {
1771
+ function median2(values) {
607
1772
  if (!values.length) return 0;
608
1773
  const sorted = [...values].sort((a, b) => a - b);
609
1774
  const mid = sorted.length >> 1;
@@ -646,7 +1811,7 @@ function pdfTextItemsToParagraphs(items, options = {}) {
646
1811
  const gap = lines[i - 1].y - lines[i].y;
647
1812
  if (gap > 0) gaps.push(gap);
648
1813
  }
649
- const typical = median(gaps);
1814
+ const typical = median2(gaps);
650
1815
  const factor = options.paragraphGap ?? 1.4;
651
1816
  const paragraphs = [];
652
1817
  let current = [];
@@ -673,6 +1838,228 @@ function pdfTextItemsToParagraphs(items, options = {}) {
673
1838
  flush();
674
1839
  return paragraphs;
675
1840
  }
1841
+ function pdfTextItemsToRuns(items, font) {
1842
+ const runs = [];
1843
+ const cache = /* @__PURE__ */ new Map();
1844
+ for (const item of items) {
1845
+ if (!isTextItem(item) || !item.str.trim()) continue;
1846
+ const t = item.transform ?? [];
1847
+ const fontSize = Math.hypot(t[2] ?? 0, t[3] ?? 0) || item.height || 10;
1848
+ let info;
1849
+ if (item.fontName && font) {
1850
+ if (!cache.has(item.fontName)) cache.set(item.fontName, font(item.fontName));
1851
+ info = cache.get(item.fontName);
1852
+ }
1853
+ runs.push({
1854
+ text: item.str,
1855
+ x: t[4] ?? 0,
1856
+ y: t[5] ?? 0,
1857
+ width: item.width,
1858
+ fontSize,
1859
+ fontName: info?.name ?? item.fontName,
1860
+ bold: info?.bold,
1861
+ italic: info?.italic
1862
+ });
1863
+ }
1864
+ return runs;
1865
+ }
1866
+ var DEFAULT_OPS = {
1867
+ save: 10,
1868
+ restore: 11,
1869
+ transform: 12,
1870
+ moveTo: 13,
1871
+ lineTo: 14,
1872
+ curveTo: 15,
1873
+ curveTo2: 16,
1874
+ curveTo3: 17,
1875
+ closePath: 18,
1876
+ rectangle: 19,
1877
+ stroke: 20,
1878
+ closeStroke: 21,
1879
+ fill: 22,
1880
+ eoFill: 23,
1881
+ fillStroke: 24,
1882
+ eoFillStroke: 25,
1883
+ closeFillStroke: 26,
1884
+ closeEOFillStroke: 27,
1885
+ endPath: 28,
1886
+ constructPath: 91
1887
+ };
1888
+ var DRAW_OPS = { moveTo: 0, lineTo: 1, curveTo: 2, quadraticCurveTo: 3, closePath: 4 };
1889
+ var MAX_PAGE_RULES = 5e3;
1890
+ var IDENTITY = [1, 0, 0, 1, 0, 0];
1891
+ var multiply = (m, c) => [
1892
+ m[0] * c[0] + m[1] * c[2],
1893
+ m[0] * c[1] + m[1] * c[3],
1894
+ m[2] * c[0] + m[3] * c[2],
1895
+ m[2] * c[1] + m[3] * c[3],
1896
+ m[4] * c[0] + m[5] * c[2] + c[4],
1897
+ m[4] * c[1] + m[5] * c[3] + c[5]
1898
+ ];
1899
+ var apply = (m, x, y) => [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
1900
+ function pdfOperatorListToRules(list, opsTable) {
1901
+ const OPS = { ...DEFAULT_OPS, ...opsTable ?? {} };
1902
+ const stroking = /* @__PURE__ */ new Set([OPS.stroke, OPS.closeStroke, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);
1903
+ const filling = /* @__PURE__ */ new Set([OPS.fill, OPS.eoFill, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);
1904
+ const rules = [];
1905
+ const stack = [];
1906
+ let ctm = IDENTITY;
1907
+ let lines = [];
1908
+ let rects = [];
1909
+ const num = (value) => typeof value === "number" && Number.isFinite(value) ? value : NaN;
1910
+ const addLine = (x1, y1, x2, y2) => {
1911
+ const [a, b] = apply(ctm, x1, y1);
1912
+ const [c, d] = apply(ctm, x2, y2);
1913
+ lines.push([a, b, c, d]);
1914
+ };
1915
+ const addRect = (x, y, w, h) => {
1916
+ const corners = [apply(ctm, x, y), apply(ctm, x + w, y), apply(ctm, x + w, y + h), apply(ctm, x, y + h)];
1917
+ const xs = corners.map((p) => p[0]);
1918
+ const ys = corners.map((p) => p[1]);
1919
+ rects.push([Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)]);
1920
+ };
1921
+ const paint = (op) => {
1922
+ const stroke = stroking.has(op);
1923
+ const fill = filling.has(op);
1924
+ if (stroke) {
1925
+ for (const [x1, y1, x2, y2] of lines) rules.push({ x1, y1, x2, y2 });
1926
+ for (const [x0, y0, x1, y1] of rects) {
1927
+ rules.push({ x1: x0, y1: y0, x2: x1, y2: y0 }, { x1: x0, y1, x2: x1, y2: y1 });
1928
+ rules.push({ x1: x0, y1: y0, x2: x0, y2: y1 }, { x1, y1: y0, x2: x1, y2: y1 });
1929
+ }
1930
+ } else if (fill) {
1931
+ for (const [x0, y0, x1, y1] of rects) {
1932
+ if (y1 - y0 <= 2 && x1 - x0 > 2) rules.push({ x1: x0, y1: (y0 + y1) / 2, x2: x1, y2: (y0 + y1) / 2 });
1933
+ else if (x1 - x0 <= 2 && y1 - y0 > 2) rules.push({ x1: (x0 + x1) / 2, y1: y0, x2: (x0 + x1) / 2, y2: y1 });
1934
+ }
1935
+ }
1936
+ lines = [];
1937
+ rects = [];
1938
+ };
1939
+ const readPath = (subOps, subArgs) => {
1940
+ let k = 0;
1941
+ let cx = 0;
1942
+ let cy = 0;
1943
+ let sx = 0;
1944
+ let sy = 0;
1945
+ for (let i = 0; i < subOps.length; i++) {
1946
+ const op = subOps[i];
1947
+ if (op === OPS.moveTo) {
1948
+ cx = sx = num(subArgs[k++]);
1949
+ cy = sy = num(subArgs[k++]);
1950
+ } else if (op === OPS.lineTo) {
1951
+ const x = num(subArgs[k++]);
1952
+ const y = num(subArgs[k++]);
1953
+ addLine(cx, cy, x, y);
1954
+ cx = x;
1955
+ cy = y;
1956
+ } else if (op === OPS.rectangle) {
1957
+ addRect(num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]));
1958
+ } else if (op === OPS.curveTo) {
1959
+ k += 4;
1960
+ cx = num(subArgs[k++]);
1961
+ cy = num(subArgs[k++]);
1962
+ } else if (op === OPS.curveTo2 || op === OPS.curveTo3) {
1963
+ k += 2;
1964
+ cx = num(subArgs[k++]);
1965
+ cy = num(subArgs[k++]);
1966
+ } else if (op === OPS.closePath) {
1967
+ if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);
1968
+ cx = sx;
1969
+ cy = sy;
1970
+ }
1971
+ }
1972
+ };
1973
+ const readDrawBuffer = (data) => {
1974
+ let cx = 0;
1975
+ let cy = 0;
1976
+ let sx = 0;
1977
+ let sy = 0;
1978
+ for (let k = 0; k < data.length; ) {
1979
+ const code = data[k++];
1980
+ if (code === DRAW_OPS.moveTo) {
1981
+ cx = sx = data[k++];
1982
+ cy = sy = data[k++];
1983
+ } else if (code === DRAW_OPS.lineTo) {
1984
+ const x = data[k++];
1985
+ const y = data[k++];
1986
+ addLine(cx, cy, x, y);
1987
+ cx = x;
1988
+ cy = y;
1989
+ } else if (code === DRAW_OPS.curveTo) {
1990
+ k += 4;
1991
+ cx = data[k++];
1992
+ cy = data[k++];
1993
+ } else if (code === DRAW_OPS.quadraticCurveTo) {
1994
+ k += 2;
1995
+ cx = data[k++];
1996
+ cy = data[k++];
1997
+ } else if (code === DRAW_OPS.closePath) {
1998
+ if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);
1999
+ cx = sx;
2000
+ cy = sy;
2001
+ } else break;
2002
+ }
2003
+ };
2004
+ for (let i = 0; i < list.fnArray.length && rules.length < MAX_PAGE_RULES; i++) {
2005
+ const fn = list.fnArray[i];
2006
+ const args = list.argsArray[i];
2007
+ if (fn === OPS.save) stack.push(ctm);
2008
+ else if (fn === OPS.restore) ctm = stack.pop() ?? IDENTITY;
2009
+ else if (fn === OPS.transform && args && args.length >= 6) {
2010
+ const m = Array.from({ length: 6 }, (_, k) => num(args[k]));
2011
+ if (m.every(Number.isFinite)) ctm = multiply(m, ctm);
2012
+ } else if (fn === OPS.constructPath && args) {
2013
+ const first = args[0];
2014
+ if (typeof first === "number") {
2015
+ const buffers = args[1];
2016
+ const data = buffers?.[0];
2017
+ if (data && typeof data.length === "number") readDrawBuffer(data);
2018
+ paint(first);
2019
+ } else if (first && typeof first.length === "number") {
2020
+ readPath(first, args[1] ?? []);
2021
+ }
2022
+ } else if (stroking.has(fn) || filling.has(fn)) paint(fn);
2023
+ else if (fn === OPS.endPath) {
2024
+ lines = [];
2025
+ rects = [];
2026
+ }
2027
+ }
2028
+ return rules.filter((rule) => [rule.x1, rule.y1, rule.x2, rule.y2].every(Number.isFinite));
2029
+ }
2030
+ function fontResolver(page, content) {
2031
+ return (fontName) => {
2032
+ let info;
2033
+ try {
2034
+ if (page.commonObjs && (!page.commonObjs.has || page.commonObjs.has(fontName))) {
2035
+ const font = page.commonObjs.get(fontName);
2036
+ if (font && typeof font === "object") {
2037
+ info = {
2038
+ name: typeof font.name === "string" ? font.name : void 0,
2039
+ bold: font.bold || font.black ? true : void 0,
2040
+ italic: font.italic ? true : void 0
2041
+ };
2042
+ }
2043
+ }
2044
+ } catch {
2045
+ }
2046
+ const family = content.styles?.[fontName]?.fontFamily;
2047
+ if (!info?.name && family) info = { ...info, name: family };
2048
+ return info;
2049
+ };
2050
+ }
2051
+ function plainReport(paragraphs, pages) {
2052
+ return {
2053
+ mode: "plain",
2054
+ pages,
2055
+ counts: { headings: 0, lists: 0, tables: 0, paragraphs },
2056
+ multiColumnPages: 0,
2057
+ confidence: 1,
2058
+ items: [],
2059
+ removed: { headers: 0, footers: 0, pageNumbers: 0 },
2060
+ dehyphenated: 0
2061
+ };
2062
+ }
676
2063
  function createPdfImportAdapter(pdfjs, options = {}) {
677
2064
  return {
678
2065
  id: options.id ?? "pdf",
@@ -681,22 +2068,47 @@ function createPdfImportAdapter(pdfjs, options = {}) {
681
2068
  extensions: [".pdf"],
682
2069
  target: "document",
683
2070
  async import(_input, context) {
2071
+ const call = context.options && typeof context.options === "object" ? context.options : {};
2072
+ const opts = { ...options, ...call, layout: { ...options.layout, ...call.layout } };
2073
+ const structured = opts.structure !== false;
684
2074
  const data = new Uint8Array((await context.readArrayBuffer()).slice(0));
685
- const doc = await pdfjs.getDocument({ ...options.documentParams, data }).promise;
2075
+ const doc = await pdfjs.getDocument({ ...opts.documentParams, data }).promise;
686
2076
  const paragraphs = [];
2077
+ const layoutPages = [];
2078
+ let pages = 0;
687
2079
  try {
688
- const pages = Math.min(doc.numPages, options.maxPages ?? Infinity);
2080
+ pages = Math.min(doc.numPages, opts.maxPages ?? Infinity);
689
2081
  for (let n = 1; n <= pages; n++) {
690
2082
  const page = await doc.getPage(n);
691
- const content = await page.getTextContent();
692
- paragraphs.push(...pdfTextItemsToParagraphs(content.items, options));
2083
+ if (!structured) {
2084
+ const content = await page.getTextContent();
2085
+ paragraphs.push(...pdfTextItemsToParagraphs(content.items, opts));
2086
+ } else {
2087
+ let rules = [];
2088
+ if (opts.rulingLines !== false && typeof page.getOperatorList === "function") {
2089
+ try {
2090
+ rules = pdfOperatorListToRules(await page.getOperatorList(), pdfjs.OPS);
2091
+ } catch {
2092
+ rules = [];
2093
+ }
2094
+ }
2095
+ const content = await page.getTextContent();
2096
+ layoutPages.push({ runs: pdfTextItemsToRuns(content.items, fontResolver(page, content)), rules });
2097
+ }
693
2098
  page.cleanup?.();
694
2099
  }
695
2100
  } finally {
696
2101
  await doc.destroy?.();
697
2102
  }
698
- const text = paragraphs.join("\n");
699
- return { html: plainTextToParagraphHtml(text), text };
2103
+ if (!structured) {
2104
+ const text = paragraphs.join("\n");
2105
+ return { html: plainTextToParagraphHtml(text), text, structure: plainReport(paragraphs.length, pages) };
2106
+ }
2107
+ const layout = { ...opts.layout };
2108
+ if (layout.paragraphGap === void 0 && opts.paragraphGap !== void 0) layout.paragraphGap = opts.paragraphGap;
2109
+ const { blocks, report } = analyzePdfLayout(layoutPages, layout);
2110
+ const html = sanitizeImportedHtml(pdfLayoutBlocksToHtml(blocks));
2111
+ return { html, text: htmlToPlainText(html), structure: report };
700
2112
  }
701
2113
  };
702
2114
  }
@@ -795,24 +2207,45 @@ export {
795
2207
  BLOCK_CHANGE_ATTRIBUTE,
796
2208
  BUILT_IN_IMPORT_ADAPTERS,
797
2209
  Bookmark,
2210
+ CHARACTER_STYLE_MARK_NAME,
798
2211
  COMMENT_MARK_NAME,
2212
+ CONDITIONAL_FORMAT_ICON_SETS,
2213
+ CONDITIONAL_FORMAT_PRESETS,
2214
+ CONDITIONAL_FORMAT_STYLE_PRESETS,
2215
+ CONDITIONAL_FORMAT_TIME_PERIODS,
2216
+ CharacterStyle,
799
2217
  ColorHighlighter,
800
2218
  CommentStore,
801
2219
  Comments,
2220
+ ConditionalFormatEngine,
802
2221
  CrossReference,
2222
+ DATA_VALIDATION_ERROR_STYLE_OPTIONS,
2223
+ DATA_VALIDATION_OPERATOR_OPTIONS,
2224
+ DATA_VALIDATION_TYPE_OPTIONS,
803
2225
  DEFAULT_AUTOCORRECT_EXCEPTIONS,
804
2226
  DEFAULT_COLUMN_WIDTH,
2227
+ DEFAULT_CONDITIONAL_FORMAT_STYLE,
2228
+ DEFAULT_DATA_VALIDATION_MESSAGE,
2229
+ DEFAULT_DATA_VALIDATION_TITLE,
805
2230
  DEFAULT_DOCX_MAX_IMAGE_SIZE,
806
2231
  DEFAULT_ROW_HEIGHT,
2232
+ DEFAULT_STYLES,
2233
+ DEFAULT_TABLE_OPTIONS,
2234
+ DEFAULT_TABLE_TOOLBAR,
807
2235
  DEFAULT_ZIP_MAX_ENTRIES,
808
2236
  DEFAULT_ZIP_MAX_TOTAL_SIZE,
809
2237
  DELETION_MARK_NAME,
2238
+ DOCX_ANONYMOUS_AUTHOR,
2239
+ DOCX_EXPORT_MIME_TYPE,
810
2240
  DOCX_MIME_TYPES,
811
2241
  DataSourceBinder,
812
2242
  DependencyGraph,
813
2243
  DirtyTracker,
814
2244
  DocumentCompare,
2245
+ DocxExportController,
2246
+ EMPTY_CONDITIONAL_FORMAT_OVERLAY,
815
2247
  EMPTY_FIND_REPLACE_SNAPSHOT,
2248
+ EMPTY_TABLE_STATE,
816
2249
  EditorController,
817
2250
  FIELD_ALIASES,
818
2251
  FIND_OPTION_TOGGLES,
@@ -828,6 +2261,7 @@ export {
828
2261
  FootnoteReference,
829
2262
  Footnotes,
830
2263
  FormulaEvaluator,
2264
+ FormulaLambda,
831
2265
  FormulaParser,
832
2266
  GradientText,
833
2267
  HistoryManager,
@@ -836,35 +2270,59 @@ export {
836
2270
  Image,
837
2271
  ImportAdapterRegistry,
838
2272
  ImportError,
2273
+ IntervalIndex,
839
2274
  LoadingNode,
840
2275
  MARKDOWN_MENTION_SPLIT_REGEX,
841
2276
  MAX_DATA_SOURCE_FIELDS,
842
2277
  MAX_DATA_SOURCE_RECORDS,
2278
+ MAX_DEFINED_NAME_LENGTH,
843
2279
  MAX_FIND_PATTERN_LENGTH,
844
2280
  MAX_FORMULA_ARRAY_SIZE,
2281
+ MAX_LAMBDA_DEPTH,
845
2282
  MAX_MERGE_LENGTH,
846
2283
  MAX_MERGE_OUTPUTS,
847
2284
  MAX_NUMBER_FORMAT_CODE_CHARS,
2285
+ MAX_SHEET_NAME_LENGTH,
2286
+ MAX_TABLE_COLUMNS,
2287
+ MAX_TABLE_ROWS,
848
2288
  MENTION_REGEX,
2289
+ MOVE_FROM_CLASS,
2290
+ MOVE_ID_ATTRIBUTE,
2291
+ MOVE_TO_CLASS,
849
2292
  Markdown,
850
2293
  Mention,
2294
+ NORMAL_STYLE_ID,
851
2295
  NUMBER_FORMAT_PRESETS,
852
2296
  NumberFormat,
853
2297
  Outline,
854
2298
  PIXERATE_DOCUMENT_MIME,
2299
+ ParagraphStyles,
855
2300
  RichClipboard,
856
2301
  SMILIE_REPLACEMENTS,
857
2302
  SPREADSHEET_CLIPBOARD_MIME,
2303
+ SPREADSHEET_COLUMN_HEADER_HEIGHT,
2304
+ SPREADSHEET_DEFAULT_VIEWPORT,
2305
+ SPREADSHEET_GROUP_ROW_HEIGHT,
858
2306
  SPREADSHEET_IMPORT_ADAPTERS,
2307
+ SPREADSHEET_ROW_HEADER_WIDTH,
859
2308
  SPREADSHEET_TABLE_ACTIONS,
2309
+ SPREADSHEET_VIRTUAL_COLUMN_THRESHOLD,
2310
+ SPREADSHEET_VIRTUAL_ROW_THRESHOLD,
2311
+ STYLE_ID_ATTRIBUTE,
860
2312
  SlashCommands,
861
2313
  SmilieReplacer,
862
2314
  SpreadsheetController,
2315
+ StyleRegistry,
2316
+ TABLE_ACTIONS,
863
2317
  TEMPLATE_DEPTH_ERROR,
864
2318
  TEMPLATE_LOOP_ERROR,
865
2319
  TEMPLATE_REGEX,
866
2320
  TRACK_CHANGES_SKIP_META,
2321
+ Table,
2322
+ TableCell,
2323
+ TableHeader,
867
2324
  TableOfContents,
2325
+ TableRow,
868
2326
  TemplateSuggestions,
869
2327
  TrackChanges,
870
2328
  TrackChangesStore,
@@ -873,20 +2331,27 @@ export {
873
2331
  TrackedInsertion,
874
2332
  VARIABLE_REGEX,
875
2333
  WHOLE_COLUMN_END_ROW,
2334
+ XmlWriter,
876
2335
  ZipArchive,
877
2336
  ZipError,
2337
+ adjustRangeForStructuralChange,
2338
+ adjustRangesForStructuralChange,
878
2339
  aggregateValues,
2340
+ analyzePdfLayout,
879
2341
  applyDocumentComparison,
880
2342
  applyFormulaSuggestion,
2343
+ applyImportedReviewData,
881
2344
  applyReplacements,
882
2345
  autocorrectPluginKey,
883
2346
  bindDirtyToHistory,
884
2347
  bindSpreadsheetTableActions,
2348
+ blendConditionalFormatColors,
885
2349
  buildOutlineTree,
886
2350
  buildSpreadsheetView,
887
2351
  builtinNumberFormat,
888
2352
  builtinNumberFormatId,
889
2353
  capitalizeSentenceRules,
2354
+ captureSelectionFormat,
890
2355
  cellFormatForNumberFormat,
891
2356
  checkFormulaArgumentCount,
892
2357
  clampMenuPosition,
@@ -907,9 +2372,17 @@ export {
907
2372
  computeOutline,
908
2373
  computeRowGroups,
909
2374
  conditionSubject,
2375
+ conditionalFormatContrastColor,
2376
+ conditionalFormatIconCount,
2377
+ conditionalFormatNumber,
2378
+ conditionalFormatStyleString,
2379
+ copySheetName,
910
2380
  createCommentStore,
2381
+ createConditionalFormatRule,
911
2382
  createDirtyTracker,
2383
+ createDocxExportController,
912
2384
  createDocxImportAdapter,
2385
+ createDocxParts,
913
2386
  createEditor,
914
2387
  createFileImportController,
915
2388
  createFindReplaceCommands,
@@ -918,39 +2391,58 @@ export {
918
2391
  createImportContext,
919
2392
  createMentionExtension,
920
2393
  createOutlineStore,
2394
+ createParagraphStylesStore,
921
2395
  createPdfImportAdapter,
922
2396
  createReviewId,
923
2397
  createRichTextPreset,
924
2398
  createSearchBudget,
925
2399
  createSpreadsheetClipboardData,
2400
+ createStyleRegistry,
2401
+ createTableCommands,
2402
+ createTableExtensions,
2403
+ createTableStore,
926
2404
  createZipImportAdapter,
927
2405
  crossReferencePluginKey,
928
2406
  csvImportAdapter,
929
2407
  dateValueToSerial,
930
2408
  defaultAutocorrectRules,
2409
+ defaultIconThresholds,
931
2410
  defaultImportRegistry,
932
2411
  defaultIsEqual,
2412
+ deflateRaw,
2413
+ deleteSheetInFormula,
933
2414
  describeBlockChange,
2415
+ describeConditionalFormat,
934
2416
  describeConditionalTag,
2417
+ describeDataValidation,
935
2418
  describeFormatChange,
936
2419
  describeFormulaError,
937
2420
  detectDelimiter,
938
2421
  diffChanges,
939
2422
  diffSequences,
940
2423
  documentStructureCommandItems,
2424
+ docxFileName,
941
2425
  docxImportAdapter,
942
2426
  docxToDocumentImport,
2427
+ downloadBlob,
943
2428
  escapeCsvField,
944
2429
  escapeHtml,
945
2430
  escapeVariableText,
2431
+ escapeXmlAttr,
2432
+ escapeXmlText,
946
2433
  evaluateCondition,
947
2434
  evaluateConditionExpression,
2435
+ evaluateConditionalFormats,
948
2436
  evaluatePromptTokens,
949
2437
  expandReplacement,
2438
+ exportDocx,
2439
+ exportDocxBlob,
950
2440
  extractCellDependencies,
951
2441
  extractInstructionNames,
952
2442
  extractMentions,
953
2443
  extractMentionsFromDoc,
2444
+ extractNameDependencies,
2445
+ extractReferenceDependencies,
954
2446
  extractTemplateNames,
955
2447
  extractVariableNames,
956
2448
  extractVariables,
@@ -959,23 +2451,32 @@ export {
959
2451
  findAllMatches,
960
2452
  findAutocorrection,
961
2453
  findCommentRanges,
2454
+ findDataValidation,
962
2455
  findHexColors,
963
2456
  findImportAdapter,
2457
+ findInvalidCells,
964
2458
  findReplacePluginKey,
2459
+ findTextMentions,
965
2460
  foldCodePoint,
966
2461
  footnotesMarkdownIt,
967
2462
  footnotesPluginKey,
2463
+ forEachRangeCell,
968
2464
  formatCellDisplay,
969
2465
  formatCellForDisplay,
970
2466
  formatComparisonOperand,
971
2467
  formatConditionalTag,
972
2468
  formatFindStatus,
973
2469
  formatGeneralFit,
2470
+ formatMentionText,
974
2471
  formatNumberFormatValue,
975
2472
  formatReviewTime,
2473
+ formatRuleRanges,
2474
+ formatSheetPrefix,
976
2475
  formatTextFunction,
977
2476
  formatValueWithCode,
2477
+ formulaIdentifiers,
978
2478
  fractionRules,
2479
+ fullSpreadsheetViewWindow,
979
2480
  getActiveHeading,
980
2481
  getBookmarks,
981
2482
  getClipboardData,
@@ -983,7 +2484,10 @@ export {
983
2484
  getCommentAuthor,
984
2485
  getCommentIdsAt,
985
2486
  getCommentStore,
2487
+ getConditionalFormatCss,
2488
+ getConditionalFormatIcon,
986
2489
  getCrossReferenceTargets,
2490
+ getDataBarCss,
987
2491
  getDocumentStructureCommandItems,
988
2492
  getEditorMarkdown,
989
2493
  getEditorText,
@@ -999,18 +2503,28 @@ export {
999
2503
  getFormulaSignatureParts,
1000
2504
  getImportAccept,
1001
2505
  getLatestVersion,
2506
+ getMentionNodes,
2507
+ getNameManagerRows,
1002
2508
  getOutline,
2509
+ getParagraphStyleAt,
1003
2510
  getPromptDiagnostics,
1004
2511
  getRowSection,
1005
2512
  getSchemaSignature,
2513
+ getSheetTabMenuItems,
1006
2514
  getSpreadsheetMenuItems,
2515
+ getSpreadsheetScrollToCell,
2516
+ getSpreadsheetViewWindow,
2517
+ getStyleRegistry,
1007
2518
  getSuppliedValue,
2519
+ getTableActionState,
1008
2520
  getTableOfContentsEntries,
1009
2521
  getTableSections,
2522
+ getTableState,
1010
2523
  getTemplateBody,
1011
2524
  getTrackChangesStore,
1012
2525
  getTrackedChangeAt,
1013
2526
  getTrackedChanges,
2527
+ getValidationListValues,
1014
2528
  getVariableFormFields,
1015
2529
  handleImageInsertion,
1016
2530
  htmlImportAdapter,
@@ -1026,12 +2540,20 @@ export {
1026
2540
  instructionRegex,
1027
2541
  isBlankValue,
1028
2542
  isFormulaError,
2543
+ isFormulaLambda,
1029
2544
  isGeneralNumberFormat,
2545
+ isGfmTable,
1030
2546
  isInsidePromptToken,
2547
+ isLambdaDefinition,
2548
+ isMoveSized,
2549
+ isParagraphStyleAvailable,
1031
2550
  isPromptValueSet,
2551
+ isSelectionInTable,
1032
2552
  isSingleCellRange,
2553
+ isTableEnabled,
1033
2554
  isTrackChangesEnabled,
1034
2555
  isUnsafeZipPath,
2556
+ isValidStyleId,
1035
2557
  listFormulaFunctions,
1036
2558
  mapFormulaReferences,
1037
2559
  mapRawOffsetToResolved,
@@ -1041,16 +2563,22 @@ export {
1041
2563
  matchConditionalTags,
1042
2564
  matchFields,
1043
2565
  matchesFilterRule,
2566
+ matchesTimePeriod,
2567
+ measureSpreadsheetView,
1044
2568
  mergeRecords,
1045
2569
  navigateToHeading,
2570
+ nextSheetName,
1046
2571
  normalizeFieldKey,
1047
2572
  normalizeFieldNames,
1048
2573
  normalizeRange,
2574
+ normalizeTableCellAlignment,
2575
+ normalizeTableCellColor,
1049
2576
  numberFormatColorToCss,
1050
2577
  numberFormatForCellFormat,
1051
2578
  numberToText,
1052
2579
  offsetFormulaReferences,
1053
2580
  outlinePluginKey,
2581
+ paragraphStylesPluginKey,
1054
2582
  parseCellInput,
1055
2583
  parseCellReference,
1056
2584
  parseComparison,
@@ -1065,9 +2593,13 @@ export {
1065
2593
  parseRange,
1066
2594
  parseReplacement,
1067
2595
  parseRichClipboardPayload,
2596
+ parseRuleRanges,
1068
2597
  parseTsv,
1069
2598
  parseVariableBody,
2599
+ pdfLayoutBlocksToHtml,
2600
+ pdfOperatorListToRules,
1070
2601
  pdfTextItemsToParagraphs,
2602
+ pdfTextItemsToRuns,
1071
2603
  pickImportFiles,
1072
2604
  plainTextImportAdapter,
1073
2605
  plainTextToParagraphHtml,
@@ -1075,8 +2607,11 @@ export {
1075
2607
  plainTextToTipTapHtml,
1076
2608
  preprocessMarkdownFileLinks,
1077
2609
  preprocessMarkdownMentions,
2610
+ quoteSheetName,
1078
2611
  rangeContains,
1079
2612
  rangeContainsRange,
2613
+ rangeDependencyKey,
2614
+ rangesContain,
1080
2615
  rangesIntersect,
1081
2616
  readRichClipboard,
1082
2617
  readSpreadsheetClipboard,
@@ -1088,6 +2623,8 @@ export {
1088
2623
  registerSpreadsheetImportAdapters,
1089
2624
  remapFormulaReferences,
1090
2625
  removeImageNode,
2626
+ renameNameInFormula,
2627
+ renameSheetInFormula,
1091
2628
  resolvePrompt,
1092
2629
  resolveTemplates,
1093
2630
  resolveTemplatesWithMapping,
@@ -1098,7 +2635,12 @@ export {
1098
2635
  rowPassesFilters,
1099
2636
  rtfImportAdapter,
1100
2637
  rtfToPlainText,
2638
+ ruleAnchor,
2639
+ ruleFormulaAt,
1101
2640
  runSpreadsheetMenuItem,
2641
+ runTableAction,
2642
+ safeCSSValue,
2643
+ sameSpreadsheetViewWindow,
1102
2644
  sanitizeHtml,
1103
2645
  sanitizeImportedHtml,
1104
2646
  searchDocument,
@@ -1109,12 +2651,23 @@ export {
1109
2651
  serializeMergeOutputs,
1110
2652
  serializeRichClipboardPayload,
1111
2653
  serializeTsv,
2654
+ setMentionRoleAt,
2655
+ setMentionRoleInText,
2656
+ sheetDropIndex,
2657
+ sheetNameNeedsQuotes,
1112
2658
  shiftFormulaReferences,
2659
+ shiftRuleFormula,
2660
+ shouldShowTableBubbleMenu,
2661
+ shouldVirtualizeSpreadsheet,
1113
2662
  smartQuoteRules,
1114
2663
  smilieAutocorrectRules,
1115
2664
  sortCompareValues,
1116
2665
  sortZipEntryNames,
2666
+ stripInvalidXmlChars,
1117
2667
  stripMarkdownCode,
2668
+ subtractRange,
2669
+ subtractRangeFromRanges,
2670
+ summarizeImportStructure,
1118
2671
  symbolRules,
1119
2672
  syncFootnotes,
1120
2673
  tableOfContentsMarkdownIt,
@@ -1125,17 +2678,22 @@ export {
1125
2678
  tokenizePrompt,
1126
2679
  tokenizePromptWithDiagnostics,
1127
2680
  trackChangesPluginKey,
2681
+ trackedChangeLabel,
1128
2682
  tsvImportAdapter,
1129
2683
  twoInitialCapitalsRules,
1130
2684
  unescapeVariableText,
1131
2685
  unregisterFormulaFunction,
1132
2686
  unregisterImportAdapter,
1133
2687
  updateImageSrc,
2688
+ validateCellInput,
2689
+ validateDefinedName,
1134
2690
  validateFindPattern,
2691
+ validateSheetName,
1135
2692
  variableRegex,
1136
2693
  wildcardToRegExp,
1137
2694
  withoutDirty,
1138
2695
  writeRichClipboard,
2696
+ writeZip,
1139
2697
  zipCrc32,
1140
2698
  zipEntryTitle,
1141
2699
  zipImportAdapter