@pixerate/editor 0.23.0 → 0.25.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 (187) hide show
  1. package/README.md +167 -2
  2. package/THIRD_PARTY_NOTICES.md +80 -0
  3. package/dist/agent/index.cjs +10 -8
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +4 -3
  6. package/dist/agent/index.d.ts +4 -3
  7. package/dist/agent/index.js +4 -2
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +4437 -411
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +934 -4
  12. package/dist/canvas/index.d.ts +934 -4
  13. package/dist/canvas/index.js +4309 -283
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  16. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  17. package/dist/chunk-664LQYFJ.js +115 -0
  18. package/dist/chunk-664LQYFJ.js.map +1 -0
  19. package/dist/chunk-7WISYZFO.cjs +740 -0
  20. package/dist/chunk-7WISYZFO.cjs.map +1 -0
  21. package/dist/chunk-AL6JMGWW.cjs +783 -0
  22. package/dist/chunk-AL6JMGWW.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-RIKBJLS2.cjs → chunk-C7P22VIP.cjs} +2001 -279
  26. package/dist/chunk-C7P22VIP.cjs.map +1 -0
  27. package/dist/chunk-D6FH2YAX.cjs +131 -0
  28. package/dist/chunk-D6FH2YAX.cjs.map +1 -0
  29. package/dist/chunk-ECCCYKGL.js +740 -0
  30. package/dist/chunk-ECCCYKGL.js.map +1 -0
  31. package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
  32. package/dist/chunk-FD4LPFAE.cjs.map +1 -0
  33. package/dist/{chunk-QBJ22YZR.js → chunk-FH6F67DN.js} +1999 -277
  34. package/dist/chunk-FH6F67DN.js.map +1 -0
  35. package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
  36. package/dist/chunk-FPENXAEJ.js.map +1 -0
  37. package/dist/chunk-HLIMTC6N.js +1 -0
  38. package/dist/chunk-HLIMTC6N.js.map +1 -0
  39. package/dist/chunk-HRMEDT2L.js +1406 -0
  40. package/dist/chunk-HRMEDT2L.js.map +1 -0
  41. package/dist/{chunk-QGHGJ56O.js → chunk-IXHSYOVY.js} +2518 -122
  42. package/dist/chunk-IXHSYOVY.js.map +1 -0
  43. package/dist/chunk-MKA3AHLV.cjs +256 -0
  44. package/dist/chunk-MKA3AHLV.cjs.map +1 -0
  45. package/dist/chunk-NAXVVS5I.js +783 -0
  46. package/dist/chunk-NAXVVS5I.js.map +1 -0
  47. package/dist/chunk-O5RYH2PG.js +69 -0
  48. package/dist/chunk-O5RYH2PG.js.map +1 -0
  49. package/dist/chunk-OXSV64JX.js +689 -0
  50. package/dist/chunk-OXSV64JX.js.map +1 -0
  51. package/dist/chunk-P3RQ5UJE.cjs +689 -0
  52. package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
  53. package/dist/chunk-P6ODPZ4W.js +256 -0
  54. package/dist/chunk-P6ODPZ4W.js.map +1 -0
  55. package/dist/chunk-PL4JB3BF.cjs +1 -0
  56. package/dist/chunk-PL4JB3BF.cjs.map +1 -0
  57. package/dist/{chunk-GVSMRPHB.cjs → chunk-PO6A6QQH.cjs} +2607 -211
  58. package/dist/chunk-PO6A6QQH.cjs.map +1 -0
  59. package/dist/{chunk-JJDLPEWL.js → chunk-QGYDWPRM.js} +2 -2
  60. package/dist/chunk-RR7F5GUM.js +5726 -0
  61. package/dist/chunk-RR7F5GUM.js.map +1 -0
  62. package/dist/chunk-TNNJXF46.cjs +115 -0
  63. package/dist/chunk-TNNJXF46.cjs.map +1 -0
  64. package/dist/chunk-U5HZSFCS.js +131 -0
  65. package/dist/chunk-U5HZSFCS.js.map +1 -0
  66. package/dist/{chunk-MJZBNWG7.js → chunk-UAKDG62Z.js} +309 -581
  67. package/dist/chunk-UAKDG62Z.js.map +1 -0
  68. package/dist/{chunk-CL37JGFW.cjs → chunk-V3CHHWOE.cjs} +4 -4
  69. package/dist/{chunk-CL37JGFW.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
  70. package/dist/chunk-WSQKHXW7.cjs +5726 -0
  71. package/dist/chunk-WSQKHXW7.cjs.map +1 -0
  72. package/dist/{chunk-AA4ZEVCC.cjs → chunk-X4N4WUKB.cjs} +336 -608
  73. package/dist/chunk-X4N4WUKB.cjs.map +1 -0
  74. package/dist/commands/index.cjs +74 -1
  75. package/dist/commands/index.cjs.map +1 -1
  76. package/dist/commands/index.d.cts +38 -353
  77. package/dist/commands/index.d.ts +38 -353
  78. package/dist/commands/index.js +73 -0
  79. package/dist/commands/index.js.map +1 -1
  80. package/dist/comment-store-BEMgVlAA.d.cts +135 -0
  81. package/dist/comment-store-BEMgVlAA.d.ts +135 -0
  82. package/dist/compare/index.cjs +15 -0
  83. package/dist/compare/index.cjs.map +1 -0
  84. package/dist/compare/index.d.cts +58 -0
  85. package/dist/compare/index.d.ts +58 -0
  86. package/dist/compare/index.js +15 -0
  87. package/dist/compare/index.js.map +1 -0
  88. package/dist/controller-BIJiNoVs.d.cts +1842 -0
  89. package/dist/controller-BIJiNoVs.d.ts +1842 -0
  90. package/dist/documents-CHT1U5Vs.d.ts +86 -0
  91. package/dist/documents-Gp7wb0Me.d.cts +86 -0
  92. package/dist/extensions/index.cjs +100 -5
  93. package/dist/extensions/index.cjs.map +1 -1
  94. package/dist/extensions/index.d.cts +16 -4
  95. package/dist/extensions/index.d.ts +16 -4
  96. package/dist/extensions/index.js +100 -5
  97. package/dist/generation/index.cjs +2317 -0
  98. package/dist/generation/index.cjs.map +1 -0
  99. package/dist/generation/index.d.cts +1015 -0
  100. package/dist/generation/index.d.ts +1015 -0
  101. package/dist/generation/index.js +2317 -0
  102. package/dist/generation/index.js.map +1 -0
  103. package/dist/grammar/index.cjs +48 -3
  104. package/dist/grammar/index.cjs.map +1 -1
  105. package/dist/grammar/index.d.cts +322 -100
  106. package/dist/grammar/index.d.ts +322 -100
  107. package/dist/grammar/index.js +54 -9
  108. package/dist/image-editor/index.cjs +4392 -481
  109. package/dist/image-editor/index.cjs.map +1 -1
  110. package/dist/image-editor/index.d.cts +1249 -97
  111. package/dist/image-editor/index.d.ts +1249 -97
  112. package/dist/image-editor/index.js +4281 -370
  113. package/dist/image-editor/index.js.map +1 -1
  114. package/dist/index-7a6bHTLy.d.ts +1754 -0
  115. package/dist/index-Csd5qI8u.d.cts +1754 -0
  116. package/dist/index.cjs +1682 -99
  117. package/dist/index.cjs.map +1 -1
  118. package/dist/index.d.cts +118 -21
  119. package/dist/index.d.ts +118 -21
  120. package/dist/index.js +1630 -47
  121. package/dist/index.js.map +1 -1
  122. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  123. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  124. package/dist/migrate-iTlm3a8h.d.cts +112 -0
  125. package/dist/migrate-iTlm3a8h.d.ts +112 -0
  126. package/dist/model-C1zApQM8.d.cts +219 -0
  127. package/dist/model-C1zApQM8.d.ts +219 -0
  128. package/dist/persistence/index.cjs +676 -0
  129. package/dist/persistence/index.cjs.map +1 -0
  130. package/dist/persistence/index.d.cts +230 -0
  131. package/dist/persistence/index.d.ts +230 -0
  132. package/dist/persistence/index.js +676 -0
  133. package/dist/persistence/index.js.map +1 -0
  134. package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
  135. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.cts} +12 -1
  136. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.ts} +12 -1
  137. package/dist/registry-D32LpIc4.d.cts +354 -0
  138. package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
  139. package/dist/registry-evKTP4ls.d.ts +354 -0
  140. package/dist/schema-DYDGdYL9.d.cts +41 -0
  141. package/dist/schema-DYDGdYL9.d.ts +41 -0
  142. package/dist/serializers/index.cjs +12 -3
  143. package/dist/serializers/index.cjs.map +1 -1
  144. package/dist/serializers/index.d.cts +40 -12
  145. package/dist/serializers/index.d.ts +40 -12
  146. package/dist/serializers/index.js +12 -3
  147. package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
  148. package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
  149. package/dist/spreadsheet/index.cjs +161 -3
  150. package/dist/spreadsheet/index.cjs.map +1 -1
  151. package/dist/spreadsheet/index.d.cts +611 -20
  152. package/dist/spreadsheet/index.d.ts +611 -20
  153. package/dist/spreadsheet/index.js +168 -10
  154. package/dist/storage-BpFfspHm.d.cts +120 -0
  155. package/dist/storage-BpFfspHm.d.ts +120 -0
  156. package/dist/tokens/index.cjs +115 -0
  157. package/dist/tokens/index.cjs.map +1 -0
  158. package/dist/tokens/index.d.cts +212 -0
  159. package/dist/tokens/index.d.ts +212 -0
  160. package/dist/tokens/index.js +115 -0
  161. package/dist/tokens/index.js.map +1 -0
  162. package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
  163. package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
  164. package/dist/{track-changes-BSF58RK0.d.cts → track-changes-D_VAPELi.d.cts} +110 -144
  165. package/dist/{track-changes-BSF58RK0.d.ts → track-changes-Db_fGEvx.d.ts} +110 -144
  166. package/package.json +21 -1
  167. package/dist/chunk-4SUNJZWB.cjs.map +0 -1
  168. package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
  169. package/dist/chunk-AXV2ZW34.cjs +0 -118
  170. package/dist/chunk-AXV2ZW34.cjs.map +0 -1
  171. package/dist/chunk-B2ZRLN4S.js +0 -118
  172. package/dist/chunk-B2ZRLN4S.js.map +0 -1
  173. package/dist/chunk-GVSMRPHB.cjs.map +0 -1
  174. package/dist/chunk-K3R5NG2D.js +0 -3100
  175. package/dist/chunk-K3R5NG2D.js.map +0 -1
  176. package/dist/chunk-MJZBNWG7.js.map +0 -1
  177. package/dist/chunk-OYXSKQFR.js.map +0 -1
  178. package/dist/chunk-QBJ22YZR.js.map +0 -1
  179. package/dist/chunk-QGHGJ56O.js.map +0 -1
  180. package/dist/chunk-RIKBJLS2.cjs.map +0 -1
  181. package/dist/chunk-XDMXXC4Z.cjs +0 -3100
  182. package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
  183. package/dist/controller-pePCJLT1.d.cts +0 -959
  184. package/dist/controller-pePCJLT1.d.ts +0 -959
  185. package/dist/index-CCr_z9kF.d.cts +0 -899
  186. package/dist/index-Ck6ajwXh.d.ts +0 -899
  187. /package/dist/{chunk-JJDLPEWL.js.map → chunk-QGYDWPRM.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,39 +1,64 @@
1
+ import "./chunk-HLIMTC6N.js";
1
2
  import {
2
- TEMPLATE_DEPTH_ERROR,
3
- TEMPLATE_LOOP_ERROR,
3
+ FIELD_ALIASES,
4
+ MAX_DATA_SOURCE_FIELDS,
5
+ MAX_DATA_SOURCE_RECORDS,
6
+ MAX_MERGE_LENGTH,
7
+ MAX_MERGE_OUTPUTS,
4
8
  compactVariableValues,
5
- evaluatePromptTokens,
9
+ detectDelimiter,
6
10
  extractInstructionNames,
7
11
  extractTemplateNames,
8
12
  extractVariableNames,
9
13
  extractVariables,
10
- getLatestVersion,
11
- getPromptDiagnostics,
12
- getTemplateBody,
13
14
  getVariableFormFields,
14
15
  mapRawOffsetToResolved,
15
16
  mapResolvedOffsetToRaw,
16
- resolvePrompt,
17
+ matchFields,
18
+ mergeRecords,
19
+ normalizeFieldKey,
20
+ normalizeFieldNames,
21
+ parseDataSource,
22
+ recordToValues,
17
23
  resolveTemplates,
18
24
  resolveTemplatesWithMapping,
19
25
  resolveVariables,
26
+ serializeMergeOutputs
27
+ } from "./chunk-OXSV64JX.js";
28
+ import {
29
+ TEMPLATE_DEPTH_ERROR,
30
+ TEMPLATE_LOOP_ERROR,
31
+ evaluatePromptTokens,
32
+ getLatestVersion,
33
+ getPromptDiagnostics,
34
+ getTemplateBody,
35
+ resolvePrompt,
20
36
  tokenizePrompt,
21
37
  tokenizePromptWithDiagnostics
22
- } from "./chunk-OYXSKQFR.js";
38
+ } from "./chunk-FPENXAEJ.js";
23
39
  import {
24
40
  Autocorrect,
25
41
  BUILT_IN_IMPORT_ADAPTERS,
26
42
  Bookmark,
43
+ CHARACTER_STYLE_MARK_NAME,
27
44
  COMMENT_MARK_NAME,
45
+ CharacterStyle,
28
46
  ColorHighlighter,
29
47
  Comments,
30
48
  CrossReference,
31
49
  DEFAULT_AUTOCORRECT_EXCEPTIONS,
32
50
  DEFAULT_DOCX_MAX_IMAGE_SIZE,
51
+ DEFAULT_STYLES,
33
52
  DEFAULT_ZIP_MAX_ENTRIES,
34
53
  DEFAULT_ZIP_MAX_TOTAL_SIZE,
35
54
  DOCX_MIME_TYPES,
55
+ DocumentCompare,
56
+ EMPTY_FIND_REPLACE_SNAPSHOT,
57
+ FIND_OPTION_TOGGLES,
58
+ FIND_PARAGRAPH_MARK,
36
59
  FileImport,
60
+ FindReplace,
61
+ FindReplaceStore,
37
62
  FontSize,
38
63
  Footnote,
39
64
  FootnoteReference,
@@ -43,41 +68,60 @@ import {
43
68
  ImportAdapterRegistry,
44
69
  ImportError,
45
70
  LoadingNode,
71
+ MAX_FIND_PATTERN_LENGTH,
46
72
  Markdown,
47
73
  Mention,
74
+ NORMAL_STYLE_ID,
48
75
  Outline,
76
+ ParagraphStyles,
49
77
  RichClipboard,
50
78
  SMILIE_REPLACEMENTS,
79
+ STYLE_ID_ATTRIBUTE,
51
80
  SlashCommands,
52
81
  SmilieReplacer,
82
+ StyleRegistry,
53
83
  TableOfContents,
54
84
  TemplateSuggestions,
55
85
  ZipArchive,
56
86
  ZipError,
87
+ applyDocumentComparison,
88
+ applyReplacements,
57
89
  autocorrectPluginKey,
58
90
  buildOutlineTree,
59
91
  capitalizeSentenceRules,
92
+ captureSelectionFormat,
60
93
  commentsPluginKey,
94
+ compareInEditor,
95
+ compileFindPattern,
61
96
  computeOutline,
62
97
  createDocxImportAdapter,
98
+ createFindReplaceCommands,
63
99
  createImportAdapterRegistry,
64
100
  createImportContext,
65
101
  createMentionExtension,
66
102
  createOutlineStore,
103
+ createParagraphStylesStore,
67
104
  createRichTextPreset,
105
+ createSearchBudget,
106
+ createStyleRegistry,
68
107
  crossReferencePluginKey,
69
108
  defaultAutocorrectRules,
70
109
  defaultImportRegistry,
71
110
  documentStructureCommandItems,
72
111
  docxImportAdapter,
73
112
  docxToDocumentImport,
113
+ expandReplacement,
74
114
  fileImportPluginKey,
115
+ findAllMatches,
75
116
  findAutocorrection,
76
117
  findCommentRanges,
77
118
  findHexColors,
78
119
  findImportAdapter,
120
+ findReplacePluginKey,
121
+ foldCodePoint,
79
122
  footnotesMarkdownIt,
80
123
  footnotesPluginKey,
124
+ formatFindStatus,
81
125
  fractionRules,
82
126
  getActiveHeading,
83
127
  getBookmarks,
@@ -87,9 +131,14 @@ import {
87
131
  getCommentStore,
88
132
  getCrossReferenceTargets,
89
133
  getDocumentStructureCommandItems,
134
+ getFindReplaceState,
135
+ getFindReplaceStore,
90
136
  getFootnotes,
91
137
  getImportAccept,
138
+ getMentionNodes,
92
139
  getOutline,
140
+ getParagraphStyleAt,
141
+ getStyleRegistry,
93
142
  getTableOfContentsEntries,
94
143
  handleImageInsertion,
95
144
  htmlImportAdapter,
@@ -100,16 +149,23 @@ import {
100
149
  insertImageNode,
101
150
  insertImportedDocument,
102
151
  isInsidePromptToken,
152
+ isParagraphStyleAvailable,
103
153
  isUnsafeZipPath,
154
+ isValidStyleId,
104
155
  markdownImportAdapter,
105
156
  navigateToHeading,
106
157
  outlinePluginKey,
158
+ paragraphStylesPluginKey,
159
+ parseReplacement,
107
160
  plainTextImportAdapter,
108
161
  readZip,
109
162
  registerImportAdapter,
110
163
  removeImageNode,
111
164
  richClipboardPluginKey,
112
165
  rtfImportAdapter,
166
+ safeCSSValue,
167
+ searchDocument,
168
+ setMentionRoleAt,
113
169
  smartQuoteRules,
114
170
  smilieAutocorrectRules,
115
171
  symbolRules,
@@ -119,24 +175,39 @@ import {
119
175
  twoInitialCapitalsRules,
120
176
  unregisterImportAdapter,
121
177
  updateImageSrc,
178
+ validateFindPattern,
122
179
  writeRichClipboard,
123
180
  zipCrc32
124
- } from "./chunk-QGHGJ56O.js";
181
+ } from "./chunk-IXHSYOVY.js";
182
+ import {
183
+ compareDocuments,
184
+ compareHtml,
185
+ diffChanges,
186
+ diffSequences
187
+ } from "./chunk-NAXVVS5I.js";
125
188
  import {
126
189
  INSTRUCTION_REGEX,
127
190
  TEMPLATE_REGEX,
128
191
  VARIABLE_REGEX,
192
+ compareConditionValues,
193
+ conditionSubject,
194
+ describeConditionalTag,
129
195
  escapeVariableText,
130
196
  evaluateCondition,
197
+ evaluateConditionExpression,
198
+ formatComparisonOperand,
199
+ formatConditionalTag,
131
200
  getSuppliedValue,
132
201
  instructionRegex,
133
202
  isPromptValueSet,
134
203
  matchConditionalTags,
204
+ parseComparison,
205
+ parseConditionExpression,
135
206
  parseVariableBody,
136
207
  templateRegex,
137
208
  unescapeVariableText,
138
209
  variableRegex
139
- } from "./chunk-B2ZRLN4S.js";
210
+ } from "./chunk-P6ODPZ4W.js";
140
211
  import "./chunk-N7FG6CBO.js";
141
212
  import {
142
213
  PIXERATE_DOCUMENT_MIME,
@@ -148,62 +219,131 @@ import {
148
219
  rtfToPlainText,
149
220
  sanitizeImportedHtml,
150
221
  serializeRichClipboardPayload
151
- } from "./chunk-JJDLPEWL.js";
222
+ } from "./chunk-QGYDWPRM.js";
152
223
  import {
224
+ CONDITIONAL_FORMAT_ICON_SETS,
225
+ CONDITIONAL_FORMAT_PRESETS,
226
+ CONDITIONAL_FORMAT_STYLE_PRESETS,
227
+ CONDITIONAL_FORMAT_TIME_PERIODS,
228
+ ConditionalFormatEngine,
229
+ DATA_VALIDATION_ERROR_STYLE_OPTIONS,
230
+ DATA_VALIDATION_OPERATOR_OPTIONS,
231
+ DATA_VALIDATION_TYPE_OPTIONS,
153
232
  DEFAULT_COLUMN_WIDTH,
233
+ DEFAULT_CONDITIONAL_FORMAT_STYLE,
234
+ DEFAULT_DATA_VALIDATION_MESSAGE,
235
+ DEFAULT_DATA_VALIDATION_TITLE,
154
236
  DEFAULT_ROW_HEIGHT,
155
237
  DataSourceBinder,
156
238
  DependencyGraph,
239
+ EMPTY_CONDITIONAL_FORMAT_OVERLAY,
240
+ MAX_DEFINED_NAME_LENGTH,
241
+ MAX_SHEET_NAME_LENGTH,
242
+ NUMBER_FORMAT_PRESETS,
157
243
  SPREADSHEET_CLIPBOARD_MIME,
158
244
  SPREADSHEET_IMPORT_ADAPTERS,
159
245
  SPREADSHEET_TABLE_ACTIONS,
160
246
  SpreadsheetController,
247
+ adjustRangeForStructuralChange,
248
+ adjustRangesForStructuralChange,
161
249
  aggregateValues,
162
250
  applyFormulaSuggestion,
163
251
  bindSpreadsheetTableActions,
252
+ blendConditionalFormatColors,
164
253
  buildSpreadsheetView,
254
+ cellFormatForNumberFormat,
165
255
  clampMenuPosition,
166
256
  columnDependencyKey,
167
257
  compareCellValues,
168
258
  computeFillTarget,
169
259
  computeRowGroups,
260
+ conditionalFormatContrastColor,
261
+ conditionalFormatIconCount,
262
+ conditionalFormatNumber,
263
+ conditionalFormatStyleString,
264
+ copySheetName,
265
+ createConditionalFormatRule,
170
266
  createSpreadsheetClipboardData,
171
267
  csvImportAdapter,
172
- escapeCsvField,
268
+ defaultIconThresholds,
269
+ deleteSheetInFormula,
270
+ describeConditionalFormat,
271
+ describeDataValidation,
272
+ evaluateConditionalFormats,
173
273
  extractCellDependencies,
274
+ extractNameDependencies,
174
275
  fillSeries,
276
+ findDataValidation,
277
+ findInvalidCells,
278
+ forEachRangeCell,
279
+ formatCellDisplay,
280
+ formatCellForDisplay,
281
+ formatRuleRanges,
282
+ formatSheetPrefix,
283
+ formatValueWithCode,
284
+ formulaIdentifiers,
285
+ getConditionalFormatCss,
286
+ getConditionalFormatIcon,
287
+ getDataBarCss,
175
288
  getFillDirection,
176
289
  getFormulaCaretContext,
177
290
  getFormulaHints,
291
+ getNameManagerRows,
178
292
  getRowSection,
293
+ getSheetTabMenuItems,
179
294
  getSpreadsheetMenuItems,
180
295
  getTableSections,
296
+ getValidationListValues,
181
297
  importFileIntoSpreadsheet,
182
298
  isBlankValue,
299
+ isGeneralNumberFormat,
300
+ isLambdaDefinition,
183
301
  isSingleCellRange,
184
302
  mapFormulaReferences,
185
303
  matchesFilterRule,
304
+ matchesTimePeriod,
305
+ nextSheetName,
186
306
  normalizeRange,
307
+ numberFormatForCellFormat,
187
308
  offsetFormulaReferences,
188
- parseCsv,
189
309
  parseHtmlTable,
190
- parseTsv,
310
+ parseRuleRanges,
311
+ quoteSheetName,
191
312
  rangeContains,
192
313
  rangeContainsRange,
314
+ rangesContain,
193
315
  rangesIntersect,
194
316
  readSpreadsheetClipboard,
195
317
  rebaseClipboardRows,
196
318
  registerSpreadsheetImportAdapters,
197
319
  remapFormulaReferences,
320
+ renameNameInFormula,
321
+ renameSheetInFormula,
198
322
  roundFloat,
199
323
  rowPassesFilters,
200
- serializeCsv,
324
+ ruleAnchor,
325
+ ruleFormulaAt,
326
+ runSpreadsheetMenuItem,
201
327
  serializeHtmlTable,
202
- serializeTsv,
328
+ sheetDropIndex,
329
+ sheetNameNeedsQuotes,
203
330
  shiftFormulaReferences,
331
+ shiftRuleFormula,
332
+ subtractRange,
333
+ subtractRangeFromRanges,
204
334
  toNumber,
205
- tsvImportAdapter
206
- } from "./chunk-K3R5NG2D.js";
335
+ tsvImportAdapter,
336
+ validateCellInput,
337
+ validateDefinedName,
338
+ validateSheetName
339
+ } from "./chunk-RR7F5GUM.js";
340
+ import {
341
+ escapeCsvField,
342
+ parseCsv,
343
+ parseTsv,
344
+ serializeCsv,
345
+ serializeTsv
346
+ } from "./chunk-664LQYFJ.js";
207
347
  import {
208
348
  DirtyTracker,
209
349
  HistoryManager,
@@ -213,14 +353,38 @@ import {
213
353
  defaultIsEqual,
214
354
  withoutDirty
215
355
  } from "./chunk-2H7ZHPEJ.js";
356
+ import {
357
+ MARKDOWN_MENTION_SPLIT_REGEX,
358
+ escapeHtml,
359
+ extractMentions,
360
+ extractMentionsFromDoc,
361
+ getEditorMarkdown,
362
+ getEditorText,
363
+ htmlToPlainText,
364
+ markdownToTipTapHtml,
365
+ parseMentionSegments,
366
+ plainTextToSlice,
367
+ plainTextToTipTapHtml,
368
+ preprocessMarkdownFileLinks,
369
+ preprocessMarkdownMentions,
370
+ sanitizeHtml,
371
+ stripMarkdownCode
372
+ } from "./chunk-ECCCYKGL.js";
373
+ import {
374
+ MENTION_REGEX,
375
+ findTextMentions,
376
+ formatMentionText,
377
+ setMentionRoleInText
378
+ } from "./chunk-O5RYH2PG.js";
216
379
  import {
217
380
  BLOCK_CHANGE_ATTRIBUTE,
218
381
  CommentStore,
219
382
  DELETION_MARK_NAME,
220
383
  FORMAT_CHANGE_MARK_NAME,
221
384
  INSERTION_MARK_NAME,
222
- MARKDOWN_MENTION_SPLIT_REGEX,
223
- MENTION_REGEX,
385
+ MOVE_FROM_CLASS,
386
+ MOVE_ID_ATTRIBUTE,
387
+ MOVE_TO_CLASS,
224
388
  TRACK_CHANGES_SKIP_META,
225
389
  TrackChanges,
226
390
  TrackChangesStore,
@@ -231,48 +395,47 @@ import {
231
395
  createReviewId,
232
396
  describeBlockChange,
233
397
  describeFormatChange,
234
- escapeHtml,
235
- extractMentions,
236
- extractMentionsFromDoc,
237
398
  formatReviewTime,
238
- getEditorMarkdown,
239
- getEditorText,
240
399
  getTrackChangesStore,
241
400
  getTrackedChangeAt,
242
401
  getTrackedChanges,
243
- htmlToPlainText,
402
+ isMoveSized,
244
403
  isTrackChangesEnabled,
245
- markdownToTipTapHtml,
246
- parseMentionSegments,
247
- plainTextToSlice,
248
- plainTextToTipTapHtml,
249
- preprocessMarkdownFileLinks,
250
- preprocessMarkdownMentions,
251
404
  resolveTrackedChanges,
252
- sanitizeHtml,
253
- stripMarkdownCode,
254
- trackChangesPluginKey
255
- } from "./chunk-MJZBNWG7.js";
405
+ trackChangesPluginKey,
406
+ trackedChangeLabel
407
+ } from "./chunk-UAKDG62Z.js";
256
408
  import {
257
409
  FORMULA_ERRORS,
258
410
  FormulaEvaluator,
411
+ FormulaLambda,
259
412
  FormulaParser,
260
413
  MAX_FORMULA_ARRAY_SIZE,
414
+ MAX_LAMBDA_DEPTH,
415
+ MAX_NUMBER_FORMAT_CODE_CHARS,
416
+ NumberFormat,
261
417
  WHOLE_COLUMN_END_ROW,
418
+ builtinNumberFormat,
419
+ builtinNumberFormatId,
262
420
  checkFormulaArgumentCount,
421
+ clearNumberFormatCache,
263
422
  colNameToIndex,
264
423
  compareNumbers,
265
424
  compareValues,
425
+ dateValueToSerial,
266
426
  describeFormulaError,
267
- formatCellDisplay,
268
- formatValueWithCode,
427
+ formatGeneralFit,
428
+ formatNumberFormatValue,
429
+ formatTextFunction,
269
430
  getFormulaArgumentSpecIndex,
270
431
  getFormulaFunction,
271
432
  getFormulaSignature,
272
433
  getFormulaSignatureParts,
273
434
  indexToColName,
274
435
  isFormulaError,
436
+ isFormulaLambda,
275
437
  listFormulaFunctions,
438
+ numberFormatColorToCss,
276
439
  numberToText,
277
440
  parseCellInput,
278
441
  parseCellReference,
@@ -287,7 +450,7 @@ import {
287
450
  tokenizeFormula,
288
451
  unregisterFormulaFunction,
289
452
  wildcardToRegExp
290
- } from "./chunk-QBJ22YZR.js";
453
+ } from "./chunk-FH6F67DN.js";
291
454
 
292
455
  // src/controller.ts
293
456
  import { Editor } from "@tiptap/core";
@@ -527,10 +690,1026 @@ var FileImportController = class {
527
690
  function createFileImportController(getTarget, options) {
528
691
  return new FileImportController(getTarget, options);
529
692
  }
693
+ function summarizeImportStructure(outcomes) {
694
+ const reports = outcomes.map((outcome) => outcome.result?.structure).filter((report) => !!report);
695
+ if (!reports.length) return null;
696
+ const modes = new Set(reports.map((report) => report.mode));
697
+ const sum = (pick) => reports.reduce((total, report) => total + pick(report), 0);
698
+ return {
699
+ files: reports.length,
700
+ mode: modes.size > 1 ? "mixed" : reports[0].mode,
701
+ headings: sum((r) => r.counts.headings),
702
+ lists: sum((r) => r.counts.lists),
703
+ tables: sum((r) => r.counts.tables),
704
+ paragraphs: sum((r) => r.counts.paragraphs),
705
+ multiColumnPages: sum((r) => r.multiColumnPages),
706
+ confidence: Math.round(sum((r) => r.confidence) / reports.length * 100) / 100
707
+ };
708
+ }
709
+
710
+ // src/import/pdf-layout.ts
711
+ var MAX_COLS = 63;
712
+ var MAX_TABLE_ROWS = 2e3;
713
+ var MAX_RULES = 2e3;
714
+ var MAX_DEPTH = 4;
715
+ var BULLET_GLYPH_RE = /^[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]\s*/;
716
+ var BULLET_DASH_RE = /^[-–—*]\s+/;
717
+ var ORDERED_RE = /^(?:\((\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})\)|(\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])\s+/;
718
+ var MARKER_ONLY_RE = /^(?:[•◦▪▫●○■□‣⁃∙·➢►▶✓✔❖]|\(?(?:\d{1,3}|[a-zA-Z]|[ivxlcIVXLC]{1,6})[.)])$/;
719
+ var PAGE_NUMBER_RE = /^(?:page\s+)?(?:\d{1,4}|[ivxlcdm]{1,7})(?:\s*(?:of|\/)\s*\d{1,4})?$/i;
720
+ var DASHED_PAGE_NUMBER_RE = /^[-–—]\s*\d{1,4}\s*[-–—]$/;
721
+ var SENTENCE_END_RE = /[.!?:;]["'”’)\]]?$/;
722
+ var BOLD_FONT_RE = /bold|black|heavy|semibold|demi/i;
723
+ var ITALIC_FONT_RE = /italic|oblique/i;
724
+ function minOf(list, fn) {
725
+ let min = Infinity;
726
+ for (const item of list) min = Math.min(min, fn(item));
727
+ return min;
728
+ }
729
+ function maxOf(list, fn) {
730
+ let max = -Infinity;
731
+ for (const item of list) max = Math.max(max, fn(item));
732
+ return max;
733
+ }
734
+ function lowerBound(values, target) {
735
+ let lo = 0;
736
+ let hi = values.length;
737
+ while (lo < hi) {
738
+ const mid = lo + hi >> 1;
739
+ if (values[mid] < target) lo = mid + 1;
740
+ else hi = mid;
741
+ }
742
+ return lo;
743
+ }
744
+ function median(values) {
745
+ if (!values.length) return 0;
746
+ const sorted = [...values].sort((a, b) => a - b);
747
+ const mid = sorted.length >> 1;
748
+ return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
749
+ }
750
+ var countWords = (text) => {
751
+ let words = 0;
752
+ let inWord = false;
753
+ for (let i = 0; i < text.length; i++) {
754
+ const space = text.charCodeAt(i) <= 32;
755
+ if (!space && !inWord) words++;
756
+ inWord = !space;
757
+ }
758
+ return words;
759
+ };
760
+ var collapse = (text) => text.replace(/\s+/g, " ").trim();
761
+ function runSize(run) {
762
+ if (run.fontSize && run.fontSize > 0) return run.fontSize;
763
+ if (run.height && run.height > 0) return run.height;
764
+ return 10;
765
+ }
766
+ function buildFragments(runs) {
767
+ const items = runs.filter((run) => typeof run.text === "string" && run.text.trim() !== "" && Number.isFinite(run.x) && Number.isFinite(run.y)).map((run) => {
768
+ const size = runSize(run);
769
+ const width = run.width !== void 0 && run.width >= 0 ? run.width : run.text.length * size * 0.5;
770
+ return {
771
+ text: run.text,
772
+ x0: run.x,
773
+ x1: run.x + width,
774
+ y: run.y,
775
+ size,
776
+ bold: run.bold ?? BOLD_FONT_RE.test(run.fontName ?? ""),
777
+ italic: run.italic ?? ITALIC_FONT_RE.test(run.fontName ?? "")
778
+ };
779
+ });
780
+ items.sort((a, b) => b.y - a.y || a.x0 - b.x0);
781
+ const frags = [];
782
+ let i = 0;
783
+ while (i < items.length) {
784
+ const anchor = items[i];
785
+ let j = i + 1;
786
+ while (j < items.length && anchor.y - items[j].y <= Math.max(1, Math.min(anchor.size, items[j].size) * 0.5)) j++;
787
+ const row = items.slice(i, j).sort((a, b) => a.x0 - b.x0);
788
+ i = j;
789
+ let current = null;
790
+ const finish = () => {
791
+ if (!current) return;
792
+ let best = "";
793
+ let bestChars = -1;
794
+ current.styleChars.forEach((chars, key) => {
795
+ if (chars > bestChars) {
796
+ best = key;
797
+ bestChars = chars;
798
+ }
799
+ });
800
+ const [size, bold, italic] = best.split("|");
801
+ current.size = Number(size);
802
+ current.bold = bold === "1";
803
+ current.italic = italic === "1";
804
+ current.text = collapse(current.text);
805
+ current.words = countWords(current.text);
806
+ current.top = current.y + current.size * 0.8;
807
+ current.bottom = current.y - current.size * 0.2;
808
+ if (current.text) frags.push(current);
809
+ current = null;
810
+ };
811
+ for (const item of row) {
812
+ if (current) {
813
+ const gap = item.x0 - current.x1;
814
+ const em = Math.max(current.size, item.size);
815
+ const markerOnly = MARKER_ONLY_RE.test(collapse(current.text));
816
+ if (gap > em * (markerOnly ? 6 : 1)) finish();
817
+ }
818
+ if (!current) {
819
+ current = {
820
+ text: item.text,
821
+ x0: item.x0,
822
+ x1: item.x1,
823
+ y: item.y,
824
+ top: 0,
825
+ bottom: 0,
826
+ size: item.size,
827
+ bold: item.bold,
828
+ italic: item.italic,
829
+ words: 0,
830
+ styleChars: /* @__PURE__ */ new Map()
831
+ };
832
+ } else {
833
+ const gap = item.x0 - current.x1;
834
+ if (gap > Math.max(current.size, item.size) * 0.15 && !/\s$/.test(current.text) && !/^\s/.test(item.text)) {
835
+ current.text += " ";
836
+ }
837
+ current.text += item.text;
838
+ current.x1 = Math.max(current.x1, item.x1);
839
+ }
840
+ const key = `${Math.round(item.size * 2) / 2}|${item.bold ? 1 : 0}|${item.italic ? 1 : 0}`;
841
+ current.styleChars.set(key, (current.styleChars.get(key) ?? 0) + item.text.trim().length);
842
+ }
843
+ finish();
844
+ }
845
+ return frags;
846
+ }
847
+ function baselineRows(frags) {
848
+ const rows = [];
849
+ for (const frag of frags) {
850
+ const row = rows[rows.length - 1];
851
+ if (row && Math.abs(row[0].y - frag.y) <= Math.max(1, Math.min(row[0].size, frag.size) * 0.5)) row.push(frag);
852
+ else rows.push([frag]);
853
+ }
854
+ return rows;
855
+ }
856
+ var edgeKey = (row) => collapse(row.map((f) => f.text).join(" ")).toLowerCase().replace(/\d+/g, "#");
857
+ function removeHeadersAndFooters(pages) {
858
+ const removed = { headers: 0, footers: 0, pageNumbers: 0 };
859
+ const pageRows = pages.map((frags) => baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0)));
860
+ const counts = /* @__PURE__ */ new Map();
861
+ const candidates = [];
862
+ pageRows.forEach((rows, page) => {
863
+ const n = rows.length;
864
+ const picks = [];
865
+ for (let k = 0; k < Math.min(2, n); k++) picks.push([k, "top"]);
866
+ for (let k = Math.max(Math.min(2, n), n - 2); k < n; k++) picks.push([k, "bottom"]);
867
+ for (const [index, edge] of picks) {
868
+ const row = rows[index];
869
+ const extreme = edge === "top" ? index === 0 : index === n - 1;
870
+ const neighbour = edge === "top" ? rows[index + 1] : rows[index - 1];
871
+ const gap = neighbour ? Math.abs(row[0].y - neighbour[0].y) / row[0].size : Infinity;
872
+ candidates.push({ page, row, edge, extreme, gap });
873
+ const key = `${edge}:${edgeKey(row)}`;
874
+ if (!counts.has(key)) counts.set(key, /* @__PURE__ */ new Set());
875
+ counts.get(key).add(page);
876
+ }
877
+ });
878
+ const minPages = Math.max(2, Math.ceil(pages.length * 0.5));
879
+ const drop = /* @__PURE__ */ new Set();
880
+ for (const candidate of candidates) {
881
+ const text = collapse(candidate.row.map((f) => f.text).join(" "));
882
+ const isPageNumber = candidate.extreme && (PAGE_NUMBER_RE.test(text) || DASHED_PAGE_NUMBER_RE.test(text));
883
+ const repeated = (counts.get(`${candidate.edge}:${edgeKey(candidate.row)}`)?.size ?? 0) >= minPages;
884
+ let kind = null;
885
+ if (isPageNumber && (pages.length > 1 || candidate.gap > 2.5)) kind = "pageNumbers";
886
+ else if (repeated && pages.length > 1) kind = candidate.edge === "top" ? "headers" : "footers";
887
+ if (!kind || candidate.row.some((f) => drop.has(f))) continue;
888
+ candidate.row.forEach((f) => drop.add(f));
889
+ removed[kind]++;
890
+ }
891
+ if (drop.size) {
892
+ pages.forEach((frags, index) => {
893
+ pages[index] = frags.filter((f) => !drop.has(f));
894
+ });
895
+ }
896
+ return removed;
897
+ }
898
+ function splitRules(rules) {
899
+ const h = [];
900
+ const v = [];
901
+ for (const rule of rules.slice(0, MAX_RULES)) {
902
+ const { x1, y1, x2, y2 } = rule;
903
+ if (![x1, y1, x2, y2].every(Number.isFinite)) continue;
904
+ const dx = Math.abs(x2 - x1);
905
+ const dy = Math.abs(y2 - y1);
906
+ if (dy <= 1.5 && dx >= 6) h.push({ y: (y1 + y2) / 2, x0: Math.min(x1, x2), x1: Math.max(x1, x2) });
907
+ else if (dx <= 1.5 && dy >= 6) v.push({ x: (x1 + x2) / 2, y0: Math.min(y1, y2), y1: Math.max(y1, y2) });
908
+ }
909
+ return { h, v };
910
+ }
911
+ function clusterValues(values, tol) {
912
+ const sorted = [...values].sort((a, b) => a - b);
913
+ const out = [];
914
+ for (const value of sorted) {
915
+ const cluster = out[out.length - 1];
916
+ if (cluster && value - cluster.last <= tol) {
917
+ cluster.sum += value;
918
+ cluster.n++;
919
+ cluster.last = value;
920
+ } else out.push({ sum: value, n: 1, last: value });
921
+ }
922
+ return out.map((c) => c.sum / c.n);
923
+ }
924
+ function find(parent, i) {
925
+ while (parent[i] !== i) {
926
+ parent[i] = parent[parent[i]];
927
+ i = parent[i];
928
+ }
929
+ return i;
930
+ }
931
+ var cellText = (frags, dehyphenate, stats) => {
932
+ const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);
933
+ let text = "";
934
+ let lastY = Infinity;
935
+ for (const frag of sorted) {
936
+ if (!text) text = frag.text;
937
+ else if (Math.abs(lastY - frag.y) > frag.size * 0.5) text = joinLines(text, frag.text, dehyphenate, stats);
938
+ else text += ` ${frag.text}`;
939
+ lastY = frag.y;
940
+ }
941
+ return collapse(text);
942
+ };
943
+ var NUMERIC_RE = /^[-+−(]?[$€£¥]?\s?\d[\d,.\s]*%?\)?$/;
944
+ function headerRowCount(rowFrags) {
945
+ if (rowFrags.length < 2) return 0;
946
+ const cells = (row) => row.filter((cell) => cell.length > 0);
947
+ const first = cells(rowFrags[0]);
948
+ if (!first.length) return 0;
949
+ const rest = rowFrags.slice(1).flatMap(cells);
950
+ const allBold = (list) => list.length > 0 && list.every((cell) => cell.every((f) => f.bold));
951
+ if (allBold(first) && !allBold(rest)) return 1;
952
+ const numeric = (cell) => NUMERIC_RE.test(collapse(cell.map((f) => f.text).join(" ")));
953
+ if (first.every((cell) => !numeric(cell))) {
954
+ const columns = rowFrags[0].length;
955
+ for (let c = 0; c < columns; c++) {
956
+ const body = rowFrags.slice(1).map((row) => row[c]).filter((cell) => cell && cell.length > 0);
957
+ if (rowFrags[0][c].length && body.length >= 2 && body.every(numeric)) return 1;
958
+ }
959
+ }
960
+ const firstSize = maxOf(first.flat(), (f) => f.size);
961
+ const restSize = median(rest.flat().map((f) => f.size));
962
+ if (restSize > 0 && firstSize >= restSize * 1.1) return 1;
963
+ return 0;
964
+ }
965
+ function ruledTables(frags, rules, page, dehyphenate, stats) {
966
+ const consumed = /* @__PURE__ */ new Set();
967
+ const atoms = [];
968
+ const { h, v } = splitRules(rules);
969
+ if (h.length < 2) return { atoms, consumed };
970
+ const n = h.length + v.length;
971
+ const parent = Array.from({ length: n }, (_, i) => i);
972
+ const union = (a, b) => {
973
+ const ra = find(parent, a);
974
+ const rb = find(parent, b);
975
+ if (ra !== rb) parent[ra] = rb;
976
+ };
977
+ const tol = 2;
978
+ const vOrder = v.map((_, i) => i).sort((a, b) => v[a].x - v[b].x);
979
+ const vxs = vOrder.map((i) => v[i].x);
980
+ h.forEach((seg, hi) => {
981
+ let lo = 0;
982
+ let hiIdx = vxs.length;
983
+ while (lo < hiIdx) {
984
+ const mid = lo + hiIdx >> 1;
985
+ if (vxs[mid] < seg.x0 - tol) lo = mid + 1;
986
+ else hiIdx = mid;
987
+ }
988
+ for (let k = lo; k < vxs.length && vxs[k] <= seg.x1 + tol; k++) {
989
+ const vs = v[vOrder[k]];
990
+ if (seg.y >= vs.y0 - tol && seg.y <= vs.y1 + tol) union(hi, h.length + vOrder[k]);
991
+ }
992
+ });
993
+ 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);
994
+ for (let k = 1; k < hOrder.length; k++) {
995
+ const a = h[hOrder[k - 1]];
996
+ const b = h[hOrder[k]];
997
+ if (Math.abs(a.x0 - b.x0) <= 4 && Math.abs(a.x1 - b.x1) <= 4) union(hOrder[k - 1], hOrder[k]);
998
+ }
999
+ const groups = /* @__PURE__ */ new Map();
1000
+ h.forEach((seg, i) => {
1001
+ const root = find(parent, i);
1002
+ if (!groups.has(root)) groups.set(root, { h: [], v: [] });
1003
+ groups.get(root).h.push(seg);
1004
+ });
1005
+ v.forEach((seg, i) => {
1006
+ const root = find(parent, h.length + i);
1007
+ groups.get(root)?.v.push(seg);
1008
+ });
1009
+ const byY = [...frags].sort((a, b) => a.y - b.y);
1010
+ const ys = byY.map((f) => f.y);
1011
+ const inRange = (y0, y1) => {
1012
+ let lo = 0;
1013
+ let hi = ys.length;
1014
+ while (lo < hi) {
1015
+ const mid = lo + hi >> 1;
1016
+ if (ys[mid] < y0) lo = mid + 1;
1017
+ else hi = mid;
1018
+ }
1019
+ const out = [];
1020
+ for (let k = lo; k < ys.length && ys[k] <= y1; k++) out.push(byY[k]);
1021
+ return out;
1022
+ };
1023
+ groups.forEach((group) => {
1024
+ const hys = clusterValues(group.h.map((s) => s.y), 1.5).sort((a, b) => b - a);
1025
+ if (hys.length < 2) return;
1026
+ const x0 = Math.min(...group.h.map((s) => s.x0), ...group.v.map((s) => s.x));
1027
+ const x1 = Math.max(...group.h.map((s) => s.x1), ...group.v.map((s) => s.x));
1028
+ const top = Math.max(hys[0], ...group.v.map((s) => s.y1));
1029
+ const bottom = Math.min(hys[hys.length - 1], ...group.v.map((s) => s.y0));
1030
+ const inside = inRange(bottom, top).filter((f) => {
1031
+ if (consumed.has(f)) return false;
1032
+ const cx = (f.x0 + f.x1) / 2;
1033
+ return cx >= x0 - 1 && cx <= x1 + 1;
1034
+ });
1035
+ if (inside.length < 2) return;
1036
+ const vxsGroup = clusterValues(group.v.map((s) => s.x), 1.5);
1037
+ let table = null;
1038
+ if (vxsGroup.length >= 3 || vxsGroup.length >= 2 && hys.length >= 3 && vxsGroup.some((x) => x > x0 + 4 && x < x1 - 4)) {
1039
+ table = gridTable(inside, group, hys, vxsGroup, x0, x1, top, bottom, page, dehyphenate, stats);
1040
+ }
1041
+ if (!table) {
1042
+ const result = alignedTable(inside, page, 2, dehyphenate, stats, hys.length >= 3 ? hys[1] : void 0);
1043
+ if (result && !result.leftover.length && !result.before.length) table = { ...result.table, ruled: true, confidence: 0.85 };
1044
+ }
1045
+ if (!table) return;
1046
+ inside.forEach((f) => consumed.add(f));
1047
+ atoms.push({
1048
+ text: "",
1049
+ x0,
1050
+ x1,
1051
+ y: bottom,
1052
+ top,
1053
+ bottom,
1054
+ size: median(inside.map((f) => f.size)),
1055
+ bold: false,
1056
+ italic: false,
1057
+ words: 0,
1058
+ table
1059
+ });
1060
+ });
1061
+ return { atoms, consumed };
1062
+ }
1063
+ function gridTable(inside, group, hys, vxsIn, x0, x1, top, bottom, page, dehyphenate, stats) {
1064
+ const xs = [...vxsIn];
1065
+ if (xs[0] > x0 + 4) xs.unshift(x0);
1066
+ if (xs[xs.length - 1] < x1 - 4) xs.push(x1);
1067
+ const rowsY = [...hys];
1068
+ if (rowsY[0] < top - 4) rowsY.unshift(top);
1069
+ if (rowsY[rowsY.length - 1] > bottom + 4) rowsY.push(bottom);
1070
+ const cols = xs.length - 1;
1071
+ const rows = rowsY.length - 1;
1072
+ if (cols < 2 || rows < 1 || cols > MAX_COLS || rows > MAX_TABLE_ROWS) return null;
1073
+ const grid = Array.from({ length: rows }, () => Array.from({ length: cols }, () => []));
1074
+ const ascRows = [...rowsY].reverse();
1075
+ for (const frag of inside) {
1076
+ const x = frag.x0 + Math.min(2, (frag.x1 - frag.x0) / 2);
1077
+ const c = lowerBound(xs, x + 1e-9) - 1;
1078
+ const yProbe = frag.y + frag.size * 0.3;
1079
+ const r = rows - (lowerBound(ascRows, yProbe + 1e-9) - 1) - 1;
1080
+ if (c >= 0 && c < cols && r >= 0 && r < rows) grid[r][c].push(frag);
1081
+ }
1082
+ const filled = grid.flat().filter((cell) => cell.length).length;
1083
+ if (filled < 2 || rows < 2 && cols < 2) return null;
1084
+ const vAt = xs.map(() => []);
1085
+ for (const seg of group.v) {
1086
+ const k = lowerBound(xs, seg.x - 2);
1087
+ if (k < xs.length && Math.abs(xs[k] - seg.x) <= 2) vAt[k].push(seg);
1088
+ }
1089
+ const hAt = rowsY.map(() => []);
1090
+ for (const seg of group.h) {
1091
+ const k = rows - lowerBound(ascRows, seg.y - 2);
1092
+ if (k >= 0 && k <= rows && Math.abs(rowsY[k] - seg.y) <= 2) hAt[k].push(seg);
1093
+ }
1094
+ const hasV = (k, y) => vAt[k].some((s) => y >= s.y0 - 2 && y <= s.y1 + 2);
1095
+ const hasH = (k, x) => hAt[k].some((s) => x >= s.x0 - 2 && x <= s.x1 + 2);
1096
+ const covered = grid.map((row) => row.map(() => false));
1097
+ const header = headerRowCount(grid);
1098
+ const out = [];
1099
+ for (let r = 0; r < rows; r++) {
1100
+ const midY = (rowsY[r] + rowsY[r + 1]) / 2;
1101
+ const row = [];
1102
+ for (let c = 0; c < cols; c++) {
1103
+ if (covered[r][c]) continue;
1104
+ let colSpan = 1;
1105
+ while (c + colSpan < cols && !hasV(c + colSpan, midY) && !grid[r][c + colSpan].length && !covered[r][c + colSpan]) colSpan++;
1106
+ let rowSpan = 1;
1107
+ const midX = (xs[c] + xs[c + colSpan]) / 2;
1108
+ 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)) {
1109
+ rowSpan++;
1110
+ }
1111
+ for (let rr = r; rr < r + rowSpan; rr++) for (let cc = c; cc < c + colSpan; cc++) covered[rr][cc] = true;
1112
+ row.push({ text: cellText(grid[r][c], dehyphenate, stats), colSpan, rowSpan, header: r < header });
1113
+ }
1114
+ out.push(row);
1115
+ }
1116
+ return { type: "table", page, confidence: 0.95, ruled: true, rows: out, columns: cols, headerRows: header };
1117
+ }
1118
+ function alignedTable(frags, page, minRows, dehyphenate, stats, headerRuleY) {
1119
+ const sorted = [...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0);
1120
+ let rows = baselineRows(sorted).map((row) => row.sort((a, b) => a.x0 - b.x0));
1121
+ if (rows.length < minRows) return null;
1122
+ const multi = rows.filter((row) => row.length >= 2);
1123
+ if (multi.length < Math.min(minRows, 2)) return null;
1124
+ const spans = multi.flat().map((f) => [f.x0, f.x1]).sort((a, b) => a[0] - b[0]);
1125
+ const merged = [];
1126
+ for (const [a, b] of spans) {
1127
+ const last = merged[merged.length - 1];
1128
+ if (last && a <= last[1] + 1) last[1] = Math.max(last[1], b);
1129
+ else merged.push([a, b]);
1130
+ }
1131
+ if (merged.length < 2 || merged.length > MAX_COLS) return null;
1132
+ const edges = merged.map((m) => m[0]);
1133
+ const cols = merged.length;
1134
+ const colOf = (x) => {
1135
+ let c = 0;
1136
+ while (c + 1 < cols && x >= merged[c + 1][0] - 1) c++;
1137
+ return c;
1138
+ };
1139
+ const spanOf = (f, c) => {
1140
+ let span = 1;
1141
+ while (c + span < cols && f.x1 > merged[c + span][0] + 2) span++;
1142
+ return span;
1143
+ };
1144
+ const rowIsCells = (row) => {
1145
+ if (row.length >= 2) return true;
1146
+ const f = row[0];
1147
+ const c = colOf(f.x0);
1148
+ return spanOf(f, c) >= 2 && f.words <= 8 && Math.abs(f.x0 - edges[c]) <= Math.max(4, f.size * 0.6);
1149
+ };
1150
+ const before = [];
1151
+ const leftover = [];
1152
+ let first = 0;
1153
+ let end = rows.length;
1154
+ while (first < end && !rowIsCells(rows[first])) first++;
1155
+ while (end > first && !rowIsCells(rows[end - 1])) end--;
1156
+ rows.slice(0, first).forEach((row) => before.push(...row));
1157
+ rows.slice(end).forEach((row) => leftover.push(...row));
1158
+ rows = rows.slice(first, end);
1159
+ if (rows.length < minRows || rows.length > MAX_TABLE_ROWS) return null;
1160
+ const grid = [];
1161
+ const spansGrid = [];
1162
+ let prevRow = null;
1163
+ for (const row of rows) {
1164
+ const cells = Array.from({ length: cols }, () => []);
1165
+ const spanRow = Array.from({ length: cols }, () => 1);
1166
+ for (const f of row) {
1167
+ const c = colOf(f.x0);
1168
+ cells[c].push(f);
1169
+ spanRow[c] = Math.max(spanRow[c], row.length === 1 ? spanOf(f, c) : 1);
1170
+ }
1171
+ 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;
1172
+ if (continuation) {
1173
+ cells.forEach((cell, c) => grid[grid.length - 1][c].push(...cell));
1174
+ } else {
1175
+ grid.push(cells);
1176
+ spansGrid.push(spanRow);
1177
+ }
1178
+ prevRow = row;
1179
+ }
1180
+ if (grid.length < minRows) return null;
1181
+ const full = grid.filter((cells) => cells.filter((c) => c.length).length >= 2).length;
1182
+ if (full / grid.length < 0.6) return null;
1183
+ const cellsWithText = grid.flat().filter((c) => c.length);
1184
+ const meanWords = cellsWithText.reduce((sum, cell) => sum + cell.reduce((s, f) => s + f.words, 0), 0) / cellsWithText.length;
1185
+ if (meanWords > 12) return null;
1186
+ let header = headerRowCount(grid);
1187
+ if (headerRuleY !== void 0) {
1188
+ const above = rows.filter((row) => row[0].y > headerRuleY).length;
1189
+ if (above > 0 && above < grid.length) header = Math.max(header, Math.min(above, grid.length - 1));
1190
+ }
1191
+ const out = grid.map((cells, r) => {
1192
+ const row = [];
1193
+ for (let c = 0; c < cols; ) {
1194
+ const span = Math.min(spansGrid[r][c], cols - c);
1195
+ row.push({ text: cellText(cells[c], dehyphenate, stats), colSpan: span, rowSpan: 1, header: r < header });
1196
+ c += span;
1197
+ }
1198
+ return row;
1199
+ });
1200
+ const confidence = Math.min(
1201
+ 0.9,
1202
+ 0.5 + (grid.length >= 5 ? 0.1 : 0) + (cols >= 3 ? 0.1 : 0) + 0.2 * (full / grid.length) - (cols === 2 ? 0.05 : 0)
1203
+ );
1204
+ return {
1205
+ table: { type: "table", page, confidence, ruled: false, rows: out, columns: cols, headerRows: header },
1206
+ leftover,
1207
+ before
1208
+ };
1209
+ }
1210
+ function readingOrder(items, body, detectColumns, depth, columnPages) {
1211
+ const byTop = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);
1212
+ if (!detectColumns || items.length < 2 || depth > MAX_DEPTH) return [{ kind: "flow", items: byTop }];
1213
+ const left = minOf(items, (f) => f.x0);
1214
+ const right = maxOf(items, (f) => f.x1);
1215
+ const width = right - left;
1216
+ const isNarrow = (f) => f.x1 - f.x0 < width * 0.55;
1217
+ const narrow = items.filter(isNarrow);
1218
+ const minGutter = Math.max(body * 0.9, 6);
1219
+ const allowed = Math.max(1, Math.floor(narrow.length * 0.08));
1220
+ const events = [];
1221
+ for (const f of narrow) events.push([f.x0, 1], [f.x1, -1]);
1222
+ events.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
1223
+ const candidates = [];
1224
+ let depthNow = 0;
1225
+ let seenContent = false;
1226
+ let start = null;
1227
+ for (const [x, delta] of events) {
1228
+ depthNow += delta;
1229
+ if (depthNow > allowed) {
1230
+ if (start !== null && seenContent && x - start >= minGutter) candidates.push([start, x]);
1231
+ start = null;
1232
+ seenContent = true;
1233
+ } else if (start === null) start = x;
1234
+ }
1235
+ const ends = narrow.map((f) => f.x1).sort((a, b) => a - b);
1236
+ const starts = narrow.map((f) => f.x0).sort((a, b) => a - b);
1237
+ const gutters = [];
1238
+ for (const [a, b] of candidates) {
1239
+ const endBelow = lowerBound(ends, b) - 1;
1240
+ const left2 = endBelow >= 0 && ends[endBelow] > a ? ends[endBelow] : a;
1241
+ const startAbove = lowerBound(starts, a + 1e-9);
1242
+ const right2 = startAbove < starts.length && starts[startAbove] < b ? starts[startAbove] : b;
1243
+ if (right2 - left2 < minGutter) continue;
1244
+ const onLeft = lowerBound(ends, left2 + 1e-6);
1245
+ const onRight = starts.length - lowerBound(starts, right2 - 1e-6);
1246
+ const strays = narrow.length - onLeft - onRight;
1247
+ if (strays < Math.min(onLeft, onRight)) gutters.push([left2, right2]);
1248
+ }
1249
+ if (!gutters.length) return [{ kind: "flow", items: byTop }];
1250
+ const gutterEnds = gutters.map((g) => g[1]);
1251
+ const crosses = (f) => {
1252
+ const k = lowerBound(gutterEnds, f.x0 + 1 + 1e-9);
1253
+ return k < gutters.length && f.x1 > gutters[k][0] + 1 && f.x0 < gutters[k][1] - 1;
1254
+ };
1255
+ const columnOf = (f) => lowerBound(gutterEnds, f.x0 + 1 + 1e-9);
1256
+ const bands = [];
1257
+ for (const f of byTop) {
1258
+ const spanning = crosses(f);
1259
+ const band = bands[bands.length - 1];
1260
+ if (band && band.spanning === spanning) band.items.push(f);
1261
+ else bands.push({ spanning, items: [f] });
1262
+ }
1263
+ const segments = [];
1264
+ let sealed = false;
1265
+ const pushFlow = (list) => {
1266
+ if (!list.length) return;
1267
+ const last = segments[segments.length - 1];
1268
+ if (last && last.kind === "flow" && !sealed) last.items.push(...list);
1269
+ else segments.push({ kind: "flow", items: list });
1270
+ sealed = false;
1271
+ };
1272
+ let multiColumn = false;
1273
+ const isShortSpan = (f) => !f.table && isNarrow(f) && f.words <= 8;
1274
+ for (const band of bands) {
1275
+ const last = segments[segments.length - 1];
1276
+ if (band.spanning) {
1277
+ const lead = band.items[0];
1278
+ if (last && last.kind === "grid" && isShortSpan(lead) && minOf(last.items, (f) => f.bottom) - lead.top <= lead.size * 2) {
1279
+ last.items.push(lead);
1280
+ pushFlow(band.items.slice(1));
1281
+ } else pushFlow(band.items);
1282
+ continue;
1283
+ }
1284
+ const columns = Array.from({ length: gutters.length + 1 }, () => []);
1285
+ band.items.forEach((f) => columns[columnOf(f)].push(f));
1286
+ const used = columns.filter((c) => c.length);
1287
+ if (used.length < 2) {
1288
+ pushFlow(band.items);
1289
+ continue;
1290
+ }
1291
+ const prose = used.every((col) => {
1292
+ const text = col.filter((f) => !f.table);
1293
+ if (text.length < 2) return text.length === 0;
1294
+ const colLeft = minOf(text, (f) => f.x0);
1295
+ const colRight = maxOf(text, (f) => f.x1);
1296
+ const fill = text.reduce((sum, f) => sum + (f.x1 - f.x0), 0) / text.length / Math.max(1, colRight - colLeft);
1297
+ const words = text.reduce((sum, f) => sum + f.words, 0) / text.length;
1298
+ return fill >= 0.55 && words >= 3;
1299
+ });
1300
+ const tops = used.map((col) => [minOf(col, (f) => f.bottom), maxOf(col, (f) => f.top)]);
1301
+ const overlapping = tops.every(([b, t], i) => i === 0 || Math.min(t, tops[0][1]) - Math.max(b, tops[0][0]) > 0);
1302
+ if (prose && overlapping) {
1303
+ multiColumn = true;
1304
+ for (const col of used) segments.push(...readingOrder(col, body, detectColumns, depth + 1, columnPages));
1305
+ sealed = true;
1306
+ continue;
1307
+ }
1308
+ const pulled = [];
1309
+ if (last && last.kind === "flow" && !sealed) {
1310
+ const tail = last.items[last.items.length - 1];
1311
+ if (isShortSpan(tail) && tail.bottom - maxOf(band.items, (f) => f.top) <= tail.size * 2) {
1312
+ pulled.push(last.items.pop());
1313
+ if (!last.items.length) segments.pop();
1314
+ }
1315
+ }
1316
+ const prevSegment = segments[segments.length - 1];
1317
+ if (prevSegment && prevSegment.kind === "grid" && (pulled.length || prevSegment === last)) {
1318
+ prevSegment.items.push(...pulled, ...band.items);
1319
+ } else segments.push({ kind: "grid", items: [...pulled, ...band.items] });
1320
+ sealed = false;
1321
+ }
1322
+ if (multiColumn && depth === 0) columnPages.count++;
1323
+ return segments;
1324
+ }
1325
+ function flowLines(items, page) {
1326
+ const lines = [];
1327
+ const sorted = [...items].sort((a, b) => b.top - a.top || a.x0 - b.x0);
1328
+ for (const f of sorted) {
1329
+ if (f.table) {
1330
+ lines.push({ text: "", x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: false, page, table: f.table });
1331
+ continue;
1332
+ }
1333
+ const last = lines[lines.length - 1];
1334
+ if (last && !last.table && Math.abs(last.y - f.y) <= Math.min(last.size, f.size) * 0.5) {
1335
+ last.text = `${last.text} ${f.text}`;
1336
+ last.x0 = Math.min(last.x0, f.x0);
1337
+ last.x1 = Math.max(last.x1, f.x1);
1338
+ } else {
1339
+ lines.push({ text: f.text, x0: f.x0, x1: f.x1, y: f.y, top: f.top, size: f.size, bold: f.bold, page });
1340
+ }
1341
+ }
1342
+ return lines;
1343
+ }
1344
+ function joinLines(prev, next, dehyphenate, stats) {
1345
+ if (prev.endsWith("\xAD")) {
1346
+ stats.dehyphenated++;
1347
+ return prev.slice(0, -1) + next;
1348
+ }
1349
+ if (dehyphenate && /[A-Za-zÀ-ɏ]-$/.test(prev) && /^[a-zß-ɏ]/.test(next)) {
1350
+ stats.dehyphenated++;
1351
+ return prev.slice(0, -1) + next;
1352
+ }
1353
+ return `${prev} ${next}`;
1354
+ }
1355
+ function listMarker(text) {
1356
+ const glyph = BULLET_GLYPH_RE.exec(text);
1357
+ if (glyph) return { kind: "glyph", rest: text.slice(glyph[0].length), ordered: false };
1358
+ const dash = BULLET_DASH_RE.exec(text);
1359
+ if (dash) return { kind: "dash", rest: text.slice(dash[0].length), ordered: false };
1360
+ const ordered = ORDERED_RE.exec(text);
1361
+ if (ordered) {
1362
+ const token = ordered[1] ?? ordered[2];
1363
+ const kind = /^\d+$/.test(token) ? "num" : /^[ivxlc]{2,}$/i.test(token) || /^i$/i.test(token) ? "roman" : "alpha";
1364
+ return { kind, rest: text.slice(ordered[0].length), ordered: true, value: kind === "num" ? Number(token) : void 0 };
1365
+ }
1366
+ return null;
1367
+ }
1368
+ function headingStyle(line, next, segRight, ctx) {
1369
+ if (!ctx.options.detectHeadings || line.table) return null;
1370
+ const text = line.text;
1371
+ const words = countWords(text);
1372
+ if (text.length > 200 || words > 25 || !/\p{L}/u.test(text)) return null;
1373
+ if (words > 15 && SENTENCE_END_RE.test(text)) return null;
1374
+ const ratio = line.size / ctx.body;
1375
+ if (ratio >= 1.15) {
1376
+ const confidence = Math.min(0.95, 0.6 + (ratio - 1.15) * 0.8 + (line.bold ? 0.1 : 0));
1377
+ return { key: Math.round(line.size * 2) / 2 + (line.bold ? 0.25 : 0), confidence, boldOnly: false };
1378
+ }
1379
+ const runsOn = !!next && !next.table && next.bold && Math.abs(next.size - line.size) < 0.5 && line.x1 >= segRight - 2 * line.size;
1380
+ if (line.bold && !ctx.boldBody && !runsOn && ratio >= 0.95 && text.length <= 100 && !/[.,;]$/.test(text)) {
1381
+ return { key: Math.round(line.size * 2) / 2 + 0.25, confidence: 0.6, boldOnly: true };
1382
+ }
1383
+ return null;
1384
+ }
1385
+ function buildBlocks(lines, ctx) {
1386
+ const textLines = lines.filter((l) => !l.table);
1387
+ const segLeft = textLines.length ? minOf(textLines, (l) => l.x0) : 0;
1388
+ const segRight = textLines.length ? maxOf(textLines, (l) => l.x1) : 0;
1389
+ const kindCounts = /* @__PURE__ */ new Map();
1390
+ const markers = lines.map((line) => {
1391
+ if (!ctx.options.detectLists || line.table) return null;
1392
+ const marker = listMarker(line.text);
1393
+ if (marker) kindCounts.set(marker.kind, (kindCounts.get(marker.kind) ?? 0) + 1);
1394
+ return marker;
1395
+ });
1396
+ let list = null;
1397
+ let listStack = [];
1398
+ let lastItemLine = null;
1399
+ let para = null;
1400
+ let heading = null;
1401
+ const closeAll = () => {
1402
+ if (para) {
1403
+ const last = para.lines[para.lines.length - 1];
1404
+ const ended = SENTENCE_END_RE.test(last.text) || last.x1 < segRight - 3 * last.size;
1405
+ ctx.open = ended ? null : { block: para.block, size: last.size, lastText: para.block.text };
1406
+ } else ctx.open = null;
1407
+ para = null;
1408
+ list = null;
1409
+ listStack = [];
1410
+ lastItemLine = null;
1411
+ heading = null;
1412
+ };
1413
+ lines.forEach((line, index) => {
1414
+ const prev = index > 0 ? lines[index - 1] : null;
1415
+ if (line.table) {
1416
+ closeAll();
1417
+ ctx.open = null;
1418
+ ctx.blocks.push(line.table);
1419
+ return;
1420
+ }
1421
+ const style = headingStyle(line, lines[index + 1], segRight, ctx);
1422
+ if (style) {
1423
+ if (heading && heading.key === style.key && heading.lines < 3 && prev === heading.line && prev.y - line.y <= line.size * 1.6) {
1424
+ heading.block.text = joinLines(heading.block.text, line.text, ctx.options.dehyphenate, ctx.stats);
1425
+ heading.line = line;
1426
+ heading.lines++;
1427
+ return;
1428
+ }
1429
+ closeAll();
1430
+ ctx.open = null;
1431
+ const block2 = { type: "heading", level: 1, text: line.text, page: line.page, confidence: style.confidence };
1432
+ ctx.blocks.push(block2);
1433
+ ctx.headings.push({ block: block2, key: style.key, boldOnly: style.boldOnly });
1434
+ heading = { block: block2, line, key: style.key, lines: 1 };
1435
+ return;
1436
+ }
1437
+ heading = null;
1438
+ const marker = markers[index];
1439
+ const validMarker = marker && (marker.kind === "glyph" || (kindCounts.get(marker.kind) ?? 0) >= 2) && marker.rest.trim() !== "";
1440
+ if (validMarker) {
1441
+ const gapOk = lastItemLine && lastItemLine.y - line.y <= Math.max(ctx.pitch(line.size) * 2.2, line.size * 2.4);
1442
+ if (!list || !gapOk) {
1443
+ closeAll();
1444
+ ctx.open = null;
1445
+ list = { type: "list", page: line.page, confidence: 0.6, items: [] };
1446
+ ctx.blocks.push(list);
1447
+ listStack = [line.x0];
1448
+ }
1449
+ const tol = line.size * 0.5;
1450
+ while (listStack.length > 1 && line.x0 < listStack[listStack.length - 1] - tol) listStack.pop();
1451
+ if (line.x0 > listStack[listStack.length - 1] + tol) listStack.push(line.x0);
1452
+ else listStack[listStack.length - 1] = Math.min(listStack[listStack.length - 1], line.x0);
1453
+ const prevDepth = list.items.length ? list.items[list.items.length - 1].depth : -1;
1454
+ const depth = Math.min(listStack.length - 1, prevDepth + 1);
1455
+ const item = {
1456
+ text: collapse(marker.rest),
1457
+ depth,
1458
+ ordered: marker.ordered
1459
+ };
1460
+ if (marker.value !== void 0) item.start = marker.value;
1461
+ list.items.push(item);
1462
+ list.confidence = Math.min(0.95, (marker.kind === "glyph" ? 0.75 : 0.6) + 0.05 * list.items.length);
1463
+ lastItemLine = line;
1464
+ para = null;
1465
+ return;
1466
+ }
1467
+ if (list && lastItemLine && prev) {
1468
+ const markerX = listStack[listStack.length - 1];
1469
+ 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;
1470
+ if (continues) {
1471
+ const item = list.items[list.items.length - 1];
1472
+ item.text = joinLines(item.text, line.text, ctx.options.dehyphenate, ctx.stats);
1473
+ lastItemLine = line;
1474
+ return;
1475
+ }
1476
+ closeAll();
1477
+ }
1478
+ if (!para && ctx.open && index === 0 && /^[a-z]/.test(line.text) && Math.abs(ctx.open.size - line.size) <= line.size * 0.12) {
1479
+ ctx.open.block.text = joinLines(ctx.open.block.text, line.text, ctx.options.dehyphenate, ctx.stats);
1480
+ para = { block: ctx.open.block, lines: [line] };
1481
+ ctx.open = null;
1482
+ return;
1483
+ }
1484
+ if (para && prev && !prev.table) {
1485
+ const last = para.lines[para.lines.length - 1];
1486
+ const gap = last.y - line.y;
1487
+ const sameSize = Math.abs(last.size - line.size) <= last.size * 0.12;
1488
+ const closeEnough = gap > 0 && gap <= ctx.pitch(line.size) * ctx.options.paragraphGap;
1489
+ const indentEm = line.size * 0.8;
1490
+ const indented = line.x0 - segLeft >= indentEm && last.x0 - segLeft < indentEm && line.x0 - segLeft < line.size * 8;
1491
+ const shortEnded = last.x1 < segRight - 3 * last.size && SENTENCE_END_RE.test(last.text);
1492
+ if (sameSize && closeEnough && !indented && !shortEnded) {
1493
+ para.block.text = joinLines(para.block.text, line.text, ctx.options.dehyphenate, ctx.stats);
1494
+ para.lines.push(line);
1495
+ return;
1496
+ }
1497
+ }
1498
+ closeAll();
1499
+ ctx.open = null;
1500
+ const block = { type: "paragraph", text: line.text, page: line.page };
1501
+ ctx.blocks.push(block);
1502
+ para = { block, lines: [line] };
1503
+ });
1504
+ closeAll();
1505
+ }
1506
+ function assignHeadingLevels(headings) {
1507
+ const keys = Array.from(new Set(headings.map((h) => h.key))).sort((a, b) => b - a);
1508
+ const levelOf = new Map(keys.map((key, i) => [key, Math.min(6, i + 1)]));
1509
+ headings.forEach((h) => {
1510
+ h.block.level = levelOf.get(h.key);
1511
+ });
1512
+ }
1513
+ var DEFAULTS = {
1514
+ paragraphGap: 1.4,
1515
+ removeHeadersAndFooters: true,
1516
+ detectColumns: true,
1517
+ detectHeadings: true,
1518
+ detectLists: true,
1519
+ detectTables: true,
1520
+ dehyphenate: true
1521
+ };
1522
+ function analyzePdfLayout(pages, options = {}) {
1523
+ const opts = { ...DEFAULTS };
1524
+ Object.keys(options).forEach((key) => {
1525
+ if (options[key] !== void 0) opts[key] = options[key];
1526
+ });
1527
+ const fragPages = pages.map((page) => buildFragments(page.runs ?? []));
1528
+ const removed = opts.removeHeadersAndFooters ? removeHeadersAndFooters(fragPages) : { headers: 0, footers: 0, pageNumbers: 0 };
1529
+ const bySize = /* @__PURE__ */ new Map();
1530
+ let boldChars = 0;
1531
+ let totalChars = 0;
1532
+ fragPages.flat().forEach((f) => {
1533
+ const key = Math.round(f.size * 2) / 2;
1534
+ bySize.set(key, (bySize.get(key) ?? 0) + f.text.length);
1535
+ });
1536
+ let body = 10;
1537
+ let bodyChars = -1;
1538
+ bySize.forEach((chars, size) => {
1539
+ if (chars > bodyChars) {
1540
+ body = size;
1541
+ bodyChars = chars;
1542
+ }
1543
+ });
1544
+ fragPages.flat().forEach((f) => {
1545
+ if (Math.abs(f.size - body) <= body * 0.05) {
1546
+ totalChars += f.text.length;
1547
+ if (f.bold) boldChars += f.text.length;
1548
+ }
1549
+ });
1550
+ const pitches = /* @__PURE__ */ new Map();
1551
+ fragPages.forEach((frags) => {
1552
+ const rows = baselineRows([...frags].sort((a, b) => b.y - a.y || a.x0 - b.x0));
1553
+ for (let k = 1; k < rows.length; k++) {
1554
+ const a = rows[k - 1][0];
1555
+ const b = rows[k][0];
1556
+ if (Math.abs(a.size - b.size) > 0.5) continue;
1557
+ const d = a.y - b.y;
1558
+ if (d > 0 && d < a.size * 3) {
1559
+ const key = Math.round(b.size * 2) / 2;
1560
+ if (!pitches.has(key)) pitches.set(key, []);
1561
+ pitches.get(key).push(d);
1562
+ }
1563
+ }
1564
+ });
1565
+ const pitchMedians = /* @__PURE__ */ new Map();
1566
+ pitches.forEach((values, key) => pitchMedians.set(key, median(values)));
1567
+ const stats = { dehyphenated: 0 };
1568
+ const ctx = {
1569
+ body,
1570
+ boldBody: totalChars > 0 && boldChars / totalChars > 0.5,
1571
+ pitch: (size) => {
1572
+ const known = pitchMedians.get(Math.round(size * 2) / 2);
1573
+ return known && known >= size * 0.9 ? known : size * 1.2;
1574
+ },
1575
+ options: opts,
1576
+ stats,
1577
+ blocks: [],
1578
+ headings: [],
1579
+ open: null
1580
+ };
1581
+ const columnPages = { count: 0 };
1582
+ const items = [];
1583
+ fragPages.forEach((frags, pageIndex) => {
1584
+ const page = pageIndex + 1;
1585
+ let flowFrags = frags;
1586
+ const atoms = [];
1587
+ if (opts.detectTables && pages[pageIndex].rules?.length) {
1588
+ const ruled = ruledTables(frags, pages[pageIndex].rules, page, opts.dehyphenate, stats);
1589
+ flowFrags = frags.filter((f) => !ruled.consumed.has(f));
1590
+ atoms.push(...ruled.atoms);
1591
+ }
1592
+ const before = columnPages.count;
1593
+ const segments = readingOrder([...flowFrags, ...atoms], body, opts.detectColumns, 0, columnPages);
1594
+ if (columnPages.count > before) items.push({ type: "columns", page, confidence: 0.8, detail: "multi-column layout" });
1595
+ const units = [];
1596
+ let carry = [];
1597
+ for (const segment of segments) {
1598
+ if (segment.kind === "grid" && opts.detectTables) {
1599
+ const result = alignedTable(segment.items.filter((f) => !f.table), page, 3, opts.dehyphenate, stats);
1600
+ if (result) {
1601
+ const last = units[units.length - 1];
1602
+ if (result.before.length && last && last.kind === "flow") last.items.push(...carry, ...result.before);
1603
+ else if (result.before.length || carry.length) units.push({ kind: "flow", items: [...carry, ...result.before] });
1604
+ units.push({ kind: "table", table: result.table });
1605
+ carry = [...segment.items.filter((f) => f.table), ...result.leftover];
1606
+ continue;
1607
+ }
1608
+ }
1609
+ units.push({ kind: "flow", items: [...carry, ...segment.items] });
1610
+ carry = [];
1611
+ }
1612
+ if (carry.length) units.push({ kind: "flow", items: carry });
1613
+ for (const unit of units) {
1614
+ if (unit.kind === "table") {
1615
+ ctx.open = null;
1616
+ ctx.blocks.push(unit.table);
1617
+ } else buildBlocks(flowLines(unit.items, page), ctx);
1618
+ }
1619
+ });
1620
+ assignHeadingLevels(ctx.headings);
1621
+ const counts = { headings: 0, lists: 0, tables: 0, paragraphs: 0 };
1622
+ const confidences = [];
1623
+ ctx.blocks.forEach((block) => {
1624
+ if (block.type === "heading") {
1625
+ counts.headings++;
1626
+ confidences.push(block.confidence);
1627
+ items.push({ type: "heading", page: block.page, confidence: block.confidence, detail: `H${block.level} "${truncate(block.text)}"` });
1628
+ } else if (block.type === "list") {
1629
+ counts.lists++;
1630
+ confidences.push(block.confidence);
1631
+ const depth = maxOf(block.items, (i) => i.depth) + 1;
1632
+ items.push({
1633
+ type: "list",
1634
+ page: block.page,
1635
+ confidence: block.confidence,
1636
+ detail: `${block.items[0]?.ordered ? "numbered" : "bulleted"} list, ${block.items.length} items${depth > 1 ? `, ${depth} levels` : ""}`
1637
+ });
1638
+ } else if (block.type === "table") {
1639
+ counts.tables++;
1640
+ confidences.push(block.confidence);
1641
+ items.push({
1642
+ type: "table",
1643
+ page: block.page,
1644
+ confidence: block.confidence,
1645
+ detail: `${block.rows.length}\xD7${block.columns} table${block.ruled ? " (ruled)" : ""}${block.headerRows ? ", header row" : ""}`
1646
+ });
1647
+ } else counts.paragraphs++;
1648
+ });
1649
+ items.sort((a, b) => a.page - b.page);
1650
+ return {
1651
+ blocks: ctx.blocks,
1652
+ report: {
1653
+ mode: "structured",
1654
+ pages: pages.length,
1655
+ counts,
1656
+ multiColumnPages: columnPages.count,
1657
+ confidence: confidences.length ? Math.round(confidences.reduce((a, b) => a + b, 0) / confidences.length * 100) / 100 : 1,
1658
+ items,
1659
+ removed,
1660
+ dehyphenated: stats.dehyphenated
1661
+ }
1662
+ };
1663
+ }
1664
+ var truncate = (text) => text.length > 60 ? `${text.slice(0, 57)}\u2026` : text;
1665
+ function listHtml(items) {
1666
+ let html = "";
1667
+ const stack = [];
1668
+ for (const item of items) {
1669
+ const level = item.depth + 1;
1670
+ while (stack.length > level) html += `</li></${stack.pop()}>`;
1671
+ const tag = item.ordered ? "ol" : "ul";
1672
+ if (stack.length === level) {
1673
+ if (stack[stack.length - 1] !== tag) {
1674
+ html += `</li></${stack.pop()}>`;
1675
+ } else html += "</li>";
1676
+ }
1677
+ while (stack.length < level) {
1678
+ const start = item.ordered && item.start !== void 0 && item.start !== 1 ? ` start="${item.start}"` : "";
1679
+ html += `<${tag}${start}>`;
1680
+ stack.push(tag);
1681
+ }
1682
+ html += `<li><p>${escapeHtml(item.text)}</p>`;
1683
+ }
1684
+ while (stack.length) html += `</li></${stack.pop()}>`;
1685
+ return html;
1686
+ }
1687
+ function pdfLayoutBlocksToHtml(blocks) {
1688
+ let html = "";
1689
+ for (const block of blocks) {
1690
+ if (block.type === "heading") html += `<h${block.level}>${escapeHtml(block.text)}</h${block.level}>`;
1691
+ else if (block.type === "paragraph") html += `<p>${escapeHtml(block.text)}</p>`;
1692
+ else if (block.type === "list") html += listHtml(block.items);
1693
+ else {
1694
+ html += "<table><tbody>";
1695
+ for (const row of block.rows) {
1696
+ html += "<tr>";
1697
+ for (const cell of row) {
1698
+ const tag = cell.header ? "th" : "td";
1699
+ const attrs = `${cell.colSpan > 1 ? ` colspan="${cell.colSpan}"` : ""}${cell.rowSpan > 1 ? ` rowspan="${cell.rowSpan}"` : ""}`;
1700
+ html += `<${tag}${attrs}><p>${escapeHtml(cell.text)}</p></${tag}>`;
1701
+ }
1702
+ html += "</tr>";
1703
+ }
1704
+ html += "</tbody></table>";
1705
+ }
1706
+ }
1707
+ return html || "<p></p>";
1708
+ }
530
1709
 
531
1710
  // src/import/pdf.ts
532
1711
  var isTextItem = (item) => typeof item.str === "string";
533
- function median(values) {
1712
+ function median2(values) {
534
1713
  if (!values.length) return 0;
535
1714
  const sorted = [...values].sort((a, b) => a - b);
536
1715
  const mid = sorted.length >> 1;
@@ -573,7 +1752,7 @@ function pdfTextItemsToParagraphs(items, options = {}) {
573
1752
  const gap = lines[i - 1].y - lines[i].y;
574
1753
  if (gap > 0) gaps.push(gap);
575
1754
  }
576
- const typical = median(gaps);
1755
+ const typical = median2(gaps);
577
1756
  const factor = options.paragraphGap ?? 1.4;
578
1757
  const paragraphs = [];
579
1758
  let current = [];
@@ -600,6 +1779,228 @@ function pdfTextItemsToParagraphs(items, options = {}) {
600
1779
  flush();
601
1780
  return paragraphs;
602
1781
  }
1782
+ function pdfTextItemsToRuns(items, font) {
1783
+ const runs = [];
1784
+ const cache = /* @__PURE__ */ new Map();
1785
+ for (const item of items) {
1786
+ if (!isTextItem(item) || !item.str.trim()) continue;
1787
+ const t = item.transform ?? [];
1788
+ const fontSize = Math.hypot(t[2] ?? 0, t[3] ?? 0) || item.height || 10;
1789
+ let info;
1790
+ if (item.fontName && font) {
1791
+ if (!cache.has(item.fontName)) cache.set(item.fontName, font(item.fontName));
1792
+ info = cache.get(item.fontName);
1793
+ }
1794
+ runs.push({
1795
+ text: item.str,
1796
+ x: t[4] ?? 0,
1797
+ y: t[5] ?? 0,
1798
+ width: item.width,
1799
+ fontSize,
1800
+ fontName: info?.name ?? item.fontName,
1801
+ bold: info?.bold,
1802
+ italic: info?.italic
1803
+ });
1804
+ }
1805
+ return runs;
1806
+ }
1807
+ var DEFAULT_OPS = {
1808
+ save: 10,
1809
+ restore: 11,
1810
+ transform: 12,
1811
+ moveTo: 13,
1812
+ lineTo: 14,
1813
+ curveTo: 15,
1814
+ curveTo2: 16,
1815
+ curveTo3: 17,
1816
+ closePath: 18,
1817
+ rectangle: 19,
1818
+ stroke: 20,
1819
+ closeStroke: 21,
1820
+ fill: 22,
1821
+ eoFill: 23,
1822
+ fillStroke: 24,
1823
+ eoFillStroke: 25,
1824
+ closeFillStroke: 26,
1825
+ closeEOFillStroke: 27,
1826
+ endPath: 28,
1827
+ constructPath: 91
1828
+ };
1829
+ var DRAW_OPS = { moveTo: 0, lineTo: 1, curveTo: 2, quadraticCurveTo: 3, closePath: 4 };
1830
+ var MAX_PAGE_RULES = 5e3;
1831
+ var IDENTITY = [1, 0, 0, 1, 0, 0];
1832
+ var multiply = (m, c) => [
1833
+ m[0] * c[0] + m[1] * c[2],
1834
+ m[0] * c[1] + m[1] * c[3],
1835
+ m[2] * c[0] + m[3] * c[2],
1836
+ m[2] * c[1] + m[3] * c[3],
1837
+ m[4] * c[0] + m[5] * c[2] + c[4],
1838
+ m[4] * c[1] + m[5] * c[3] + c[5]
1839
+ ];
1840
+ var apply = (m, x, y) => [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
1841
+ function pdfOperatorListToRules(list, opsTable) {
1842
+ const OPS = { ...DEFAULT_OPS, ...opsTable ?? {} };
1843
+ const stroking = /* @__PURE__ */ new Set([OPS.stroke, OPS.closeStroke, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);
1844
+ const filling = /* @__PURE__ */ new Set([OPS.fill, OPS.eoFill, OPS.fillStroke, OPS.eoFillStroke, OPS.closeFillStroke, OPS.closeEOFillStroke]);
1845
+ const rules = [];
1846
+ const stack = [];
1847
+ let ctm = IDENTITY;
1848
+ let lines = [];
1849
+ let rects = [];
1850
+ const num = (value) => typeof value === "number" && Number.isFinite(value) ? value : NaN;
1851
+ const addLine = (x1, y1, x2, y2) => {
1852
+ const [a, b] = apply(ctm, x1, y1);
1853
+ const [c, d] = apply(ctm, x2, y2);
1854
+ lines.push([a, b, c, d]);
1855
+ };
1856
+ const addRect = (x, y, w, h) => {
1857
+ const corners = [apply(ctm, x, y), apply(ctm, x + w, y), apply(ctm, x + w, y + h), apply(ctm, x, y + h)];
1858
+ const xs = corners.map((p) => p[0]);
1859
+ const ys = corners.map((p) => p[1]);
1860
+ rects.push([Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)]);
1861
+ };
1862
+ const paint = (op) => {
1863
+ const stroke = stroking.has(op);
1864
+ const fill = filling.has(op);
1865
+ if (stroke) {
1866
+ for (const [x1, y1, x2, y2] of lines) rules.push({ x1, y1, x2, y2 });
1867
+ for (const [x0, y0, x1, y1] of rects) {
1868
+ rules.push({ x1: x0, y1: y0, x2: x1, y2: y0 }, { x1: x0, y1, x2: x1, y2: y1 });
1869
+ rules.push({ x1: x0, y1: y0, x2: x0, y2: y1 }, { x1, y1: y0, x2: x1, y2: y1 });
1870
+ }
1871
+ } else if (fill) {
1872
+ for (const [x0, y0, x1, y1] of rects) {
1873
+ if (y1 - y0 <= 2 && x1 - x0 > 2) rules.push({ x1: x0, y1: (y0 + y1) / 2, x2: x1, y2: (y0 + y1) / 2 });
1874
+ else if (x1 - x0 <= 2 && y1 - y0 > 2) rules.push({ x1: (x0 + x1) / 2, y1: y0, x2: (x0 + x1) / 2, y2: y1 });
1875
+ }
1876
+ }
1877
+ lines = [];
1878
+ rects = [];
1879
+ };
1880
+ const readPath = (subOps, subArgs) => {
1881
+ let k = 0;
1882
+ let cx = 0;
1883
+ let cy = 0;
1884
+ let sx = 0;
1885
+ let sy = 0;
1886
+ for (let i = 0; i < subOps.length; i++) {
1887
+ const op = subOps[i];
1888
+ if (op === OPS.moveTo) {
1889
+ cx = sx = num(subArgs[k++]);
1890
+ cy = sy = num(subArgs[k++]);
1891
+ } else if (op === OPS.lineTo) {
1892
+ const x = num(subArgs[k++]);
1893
+ const y = num(subArgs[k++]);
1894
+ addLine(cx, cy, x, y);
1895
+ cx = x;
1896
+ cy = y;
1897
+ } else if (op === OPS.rectangle) {
1898
+ addRect(num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]), num(subArgs[k++]));
1899
+ } else if (op === OPS.curveTo) {
1900
+ k += 4;
1901
+ cx = num(subArgs[k++]);
1902
+ cy = num(subArgs[k++]);
1903
+ } else if (op === OPS.curveTo2 || op === OPS.curveTo3) {
1904
+ k += 2;
1905
+ cx = num(subArgs[k++]);
1906
+ cy = num(subArgs[k++]);
1907
+ } else if (op === OPS.closePath) {
1908
+ if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);
1909
+ cx = sx;
1910
+ cy = sy;
1911
+ }
1912
+ }
1913
+ };
1914
+ const readDrawBuffer = (data) => {
1915
+ let cx = 0;
1916
+ let cy = 0;
1917
+ let sx = 0;
1918
+ let sy = 0;
1919
+ for (let k = 0; k < data.length; ) {
1920
+ const code = data[k++];
1921
+ if (code === DRAW_OPS.moveTo) {
1922
+ cx = sx = data[k++];
1923
+ cy = sy = data[k++];
1924
+ } else if (code === DRAW_OPS.lineTo) {
1925
+ const x = data[k++];
1926
+ const y = data[k++];
1927
+ addLine(cx, cy, x, y);
1928
+ cx = x;
1929
+ cy = y;
1930
+ } else if (code === DRAW_OPS.curveTo) {
1931
+ k += 4;
1932
+ cx = data[k++];
1933
+ cy = data[k++];
1934
+ } else if (code === DRAW_OPS.quadraticCurveTo) {
1935
+ k += 2;
1936
+ cx = data[k++];
1937
+ cy = data[k++];
1938
+ } else if (code === DRAW_OPS.closePath) {
1939
+ if (cx !== sx || cy !== sy) addLine(cx, cy, sx, sy);
1940
+ cx = sx;
1941
+ cy = sy;
1942
+ } else break;
1943
+ }
1944
+ };
1945
+ for (let i = 0; i < list.fnArray.length && rules.length < MAX_PAGE_RULES; i++) {
1946
+ const fn = list.fnArray[i];
1947
+ const args = list.argsArray[i];
1948
+ if (fn === OPS.save) stack.push(ctm);
1949
+ else if (fn === OPS.restore) ctm = stack.pop() ?? IDENTITY;
1950
+ else if (fn === OPS.transform && args && args.length >= 6) {
1951
+ const m = Array.from({ length: 6 }, (_, k) => num(args[k]));
1952
+ if (m.every(Number.isFinite)) ctm = multiply(m, ctm);
1953
+ } else if (fn === OPS.constructPath && args) {
1954
+ const first = args[0];
1955
+ if (typeof first === "number") {
1956
+ const buffers = args[1];
1957
+ const data = buffers?.[0];
1958
+ if (data && typeof data.length === "number") readDrawBuffer(data);
1959
+ paint(first);
1960
+ } else if (first && typeof first.length === "number") {
1961
+ readPath(first, args[1] ?? []);
1962
+ }
1963
+ } else if (stroking.has(fn) || filling.has(fn)) paint(fn);
1964
+ else if (fn === OPS.endPath) {
1965
+ lines = [];
1966
+ rects = [];
1967
+ }
1968
+ }
1969
+ return rules.filter((rule) => [rule.x1, rule.y1, rule.x2, rule.y2].every(Number.isFinite));
1970
+ }
1971
+ function fontResolver(page, content) {
1972
+ return (fontName) => {
1973
+ let info;
1974
+ try {
1975
+ if (page.commonObjs && (!page.commonObjs.has || page.commonObjs.has(fontName))) {
1976
+ const font = page.commonObjs.get(fontName);
1977
+ if (font && typeof font === "object") {
1978
+ info = {
1979
+ name: typeof font.name === "string" ? font.name : void 0,
1980
+ bold: font.bold || font.black ? true : void 0,
1981
+ italic: font.italic ? true : void 0
1982
+ };
1983
+ }
1984
+ }
1985
+ } catch {
1986
+ }
1987
+ const family = content.styles?.[fontName]?.fontFamily;
1988
+ if (!info?.name && family) info = { ...info, name: family };
1989
+ return info;
1990
+ };
1991
+ }
1992
+ function plainReport(paragraphs, pages) {
1993
+ return {
1994
+ mode: "plain",
1995
+ pages,
1996
+ counts: { headings: 0, lists: 0, tables: 0, paragraphs },
1997
+ multiColumnPages: 0,
1998
+ confidence: 1,
1999
+ items: [],
2000
+ removed: { headers: 0, footers: 0, pageNumbers: 0 },
2001
+ dehyphenated: 0
2002
+ };
2003
+ }
603
2004
  function createPdfImportAdapter(pdfjs, options = {}) {
604
2005
  return {
605
2006
  id: options.id ?? "pdf",
@@ -608,22 +2009,47 @@ function createPdfImportAdapter(pdfjs, options = {}) {
608
2009
  extensions: [".pdf"],
609
2010
  target: "document",
610
2011
  async import(_input, context) {
2012
+ const call = context.options && typeof context.options === "object" ? context.options : {};
2013
+ const opts = { ...options, ...call, layout: { ...options.layout, ...call.layout } };
2014
+ const structured = opts.structure !== false;
611
2015
  const data = new Uint8Array((await context.readArrayBuffer()).slice(0));
612
- const doc = await pdfjs.getDocument({ ...options.documentParams, data }).promise;
2016
+ const doc = await pdfjs.getDocument({ ...opts.documentParams, data }).promise;
613
2017
  const paragraphs = [];
2018
+ const layoutPages = [];
2019
+ let pages = 0;
614
2020
  try {
615
- const pages = Math.min(doc.numPages, options.maxPages ?? Infinity);
2021
+ pages = Math.min(doc.numPages, opts.maxPages ?? Infinity);
616
2022
  for (let n = 1; n <= pages; n++) {
617
2023
  const page = await doc.getPage(n);
618
- const content = await page.getTextContent();
619
- paragraphs.push(...pdfTextItemsToParagraphs(content.items, options));
2024
+ if (!structured) {
2025
+ const content = await page.getTextContent();
2026
+ paragraphs.push(...pdfTextItemsToParagraphs(content.items, opts));
2027
+ } else {
2028
+ let rules = [];
2029
+ if (opts.rulingLines !== false && typeof page.getOperatorList === "function") {
2030
+ try {
2031
+ rules = pdfOperatorListToRules(await page.getOperatorList(), pdfjs.OPS);
2032
+ } catch {
2033
+ rules = [];
2034
+ }
2035
+ }
2036
+ const content = await page.getTextContent();
2037
+ layoutPages.push({ runs: pdfTextItemsToRuns(content.items, fontResolver(page, content)), rules });
2038
+ }
620
2039
  page.cleanup?.();
621
2040
  }
622
2041
  } finally {
623
2042
  await doc.destroy?.();
624
2043
  }
625
- const text = paragraphs.join("\n");
626
- return { html: plainTextToParagraphHtml(text), text };
2044
+ if (!structured) {
2045
+ const text = paragraphs.join("\n");
2046
+ return { html: plainTextToParagraphHtml(text), text, structure: plainReport(paragraphs.length, pages) };
2047
+ }
2048
+ const layout = { ...opts.layout };
2049
+ if (layout.paragraphGap === void 0 && opts.paragraphGap !== void 0) layout.paragraphGap = opts.paragraphGap;
2050
+ const { blocks, report } = analyzePdfLayout(layoutPages, layout);
2051
+ const html = sanitizeImportedHtml(pdfLayoutBlocksToHtml(blocks));
2052
+ return { html, text: htmlToPlainText(html), structure: report };
627
2053
  }
628
2054
  };
629
2055
  }
@@ -722,15 +2148,29 @@ export {
722
2148
  BLOCK_CHANGE_ATTRIBUTE,
723
2149
  BUILT_IN_IMPORT_ADAPTERS,
724
2150
  Bookmark,
2151
+ CHARACTER_STYLE_MARK_NAME,
725
2152
  COMMENT_MARK_NAME,
2153
+ CONDITIONAL_FORMAT_ICON_SETS,
2154
+ CONDITIONAL_FORMAT_PRESETS,
2155
+ CONDITIONAL_FORMAT_STYLE_PRESETS,
2156
+ CONDITIONAL_FORMAT_TIME_PERIODS,
2157
+ CharacterStyle,
726
2158
  ColorHighlighter,
727
2159
  CommentStore,
728
2160
  Comments,
2161
+ ConditionalFormatEngine,
729
2162
  CrossReference,
2163
+ DATA_VALIDATION_ERROR_STYLE_OPTIONS,
2164
+ DATA_VALIDATION_OPERATOR_OPTIONS,
2165
+ DATA_VALIDATION_TYPE_OPTIONS,
730
2166
  DEFAULT_AUTOCORRECT_EXCEPTIONS,
731
2167
  DEFAULT_COLUMN_WIDTH,
2168
+ DEFAULT_CONDITIONAL_FORMAT_STYLE,
2169
+ DEFAULT_DATA_VALIDATION_MESSAGE,
2170
+ DEFAULT_DATA_VALIDATION_TITLE,
732
2171
  DEFAULT_DOCX_MAX_IMAGE_SIZE,
733
2172
  DEFAULT_ROW_HEIGHT,
2173
+ DEFAULT_STYLES,
734
2174
  DEFAULT_ZIP_MAX_ENTRIES,
735
2175
  DEFAULT_ZIP_MAX_TOTAL_SIZE,
736
2176
  DELETION_MARK_NAME,
@@ -738,16 +2178,25 @@ export {
738
2178
  DataSourceBinder,
739
2179
  DependencyGraph,
740
2180
  DirtyTracker,
2181
+ DocumentCompare,
2182
+ EMPTY_CONDITIONAL_FORMAT_OVERLAY,
2183
+ EMPTY_FIND_REPLACE_SNAPSHOT,
741
2184
  EditorController,
2185
+ FIELD_ALIASES,
2186
+ FIND_OPTION_TOGGLES,
2187
+ FIND_PARAGRAPH_MARK,
742
2188
  FORMAT_CHANGE_MARK_NAME,
743
2189
  FORMULA_ERRORS,
744
2190
  FileImport,
745
2191
  FileImportController,
2192
+ FindReplace,
2193
+ FindReplaceStore,
746
2194
  FontSize,
747
2195
  Footnote,
748
2196
  FootnoteReference,
749
2197
  Footnotes,
750
2198
  FormulaEvaluator,
2199
+ FormulaLambda,
751
2200
  FormulaParser,
752
2201
  GradientText,
753
2202
  HistoryManager,
@@ -758,20 +2207,38 @@ export {
758
2207
  ImportError,
759
2208
  LoadingNode,
760
2209
  MARKDOWN_MENTION_SPLIT_REGEX,
2210
+ MAX_DATA_SOURCE_FIELDS,
2211
+ MAX_DATA_SOURCE_RECORDS,
2212
+ MAX_DEFINED_NAME_LENGTH,
2213
+ MAX_FIND_PATTERN_LENGTH,
761
2214
  MAX_FORMULA_ARRAY_SIZE,
2215
+ MAX_LAMBDA_DEPTH,
2216
+ MAX_MERGE_LENGTH,
2217
+ MAX_MERGE_OUTPUTS,
2218
+ MAX_NUMBER_FORMAT_CODE_CHARS,
2219
+ MAX_SHEET_NAME_LENGTH,
762
2220
  MENTION_REGEX,
2221
+ MOVE_FROM_CLASS,
2222
+ MOVE_ID_ATTRIBUTE,
2223
+ MOVE_TO_CLASS,
763
2224
  Markdown,
764
2225
  Mention,
2226
+ NORMAL_STYLE_ID,
2227
+ NUMBER_FORMAT_PRESETS,
2228
+ NumberFormat,
765
2229
  Outline,
766
2230
  PIXERATE_DOCUMENT_MIME,
2231
+ ParagraphStyles,
767
2232
  RichClipboard,
768
2233
  SMILIE_REPLACEMENTS,
769
2234
  SPREADSHEET_CLIPBOARD_MIME,
770
2235
  SPREADSHEET_IMPORT_ADAPTERS,
771
2236
  SPREADSHEET_TABLE_ACTIONS,
2237
+ STYLE_ID_ATTRIBUTE,
772
2238
  SlashCommands,
773
2239
  SmilieReplacer,
774
2240
  SpreadsheetController,
2241
+ StyleRegistry,
775
2242
  TEMPLATE_DEPTH_ERROR,
776
2243
  TEMPLATE_LOOP_ERROR,
777
2244
  TEMPLATE_REGEX,
@@ -787,49 +2254,85 @@ export {
787
2254
  WHOLE_COLUMN_END_ROW,
788
2255
  ZipArchive,
789
2256
  ZipError,
2257
+ adjustRangeForStructuralChange,
2258
+ adjustRangesForStructuralChange,
790
2259
  aggregateValues,
2260
+ analyzePdfLayout,
2261
+ applyDocumentComparison,
791
2262
  applyFormulaSuggestion,
2263
+ applyReplacements,
792
2264
  autocorrectPluginKey,
793
2265
  bindDirtyToHistory,
794
2266
  bindSpreadsheetTableActions,
2267
+ blendConditionalFormatColors,
795
2268
  buildOutlineTree,
796
2269
  buildSpreadsheetView,
2270
+ builtinNumberFormat,
2271
+ builtinNumberFormatId,
797
2272
  capitalizeSentenceRules,
2273
+ captureSelectionFormat,
2274
+ cellFormatForNumberFormat,
798
2275
  checkFormulaArgumentCount,
799
2276
  clampMenuPosition,
2277
+ clearNumberFormatCache,
800
2278
  colNameToIndex,
801
2279
  columnDependencyKey,
802
2280
  commentsPluginKey,
803
2281
  compactVariableValues,
804
2282
  compareCellValues,
2283
+ compareConditionValues,
2284
+ compareDocuments,
2285
+ compareHtml,
2286
+ compareInEditor,
805
2287
  compareNumbers,
806
2288
  compareValues,
2289
+ compileFindPattern,
807
2290
  computeFillTarget,
808
2291
  computeOutline,
809
2292
  computeRowGroups,
2293
+ conditionSubject,
2294
+ conditionalFormatContrastColor,
2295
+ conditionalFormatIconCount,
2296
+ conditionalFormatNumber,
2297
+ conditionalFormatStyleString,
2298
+ copySheetName,
810
2299
  createCommentStore,
2300
+ createConditionalFormatRule,
811
2301
  createDirtyTracker,
812
2302
  createDocxImportAdapter,
813
2303
  createEditor,
814
2304
  createFileImportController,
2305
+ createFindReplaceCommands,
815
2306
  createHistoryManager,
816
2307
  createImportAdapterRegistry,
817
2308
  createImportContext,
818
2309
  createMentionExtension,
819
2310
  createOutlineStore,
2311
+ createParagraphStylesStore,
820
2312
  createPdfImportAdapter,
821
2313
  createReviewId,
822
2314
  createRichTextPreset,
2315
+ createSearchBudget,
823
2316
  createSpreadsheetClipboardData,
2317
+ createStyleRegistry,
824
2318
  createZipImportAdapter,
825
2319
  crossReferencePluginKey,
826
2320
  csvImportAdapter,
2321
+ dateValueToSerial,
827
2322
  defaultAutocorrectRules,
2323
+ defaultIconThresholds,
828
2324
  defaultImportRegistry,
829
2325
  defaultIsEqual,
2326
+ deleteSheetInFormula,
830
2327
  describeBlockChange,
2328
+ describeConditionalFormat,
2329
+ describeConditionalTag,
2330
+ describeDataValidation,
831
2331
  describeFormatChange,
832
2332
  describeFormulaError,
2333
+ detectDelimiter,
2334
+ diffChanges,
2335
+ diffSequences,
833
2336
  documentStructureCommandItems,
834
2337
  docxImportAdapter,
835
2338
  docxToDocumentImport,
@@ -837,25 +2340,47 @@ export {
837
2340
  escapeHtml,
838
2341
  escapeVariableText,
839
2342
  evaluateCondition,
2343
+ evaluateConditionExpression,
2344
+ evaluateConditionalFormats,
840
2345
  evaluatePromptTokens,
2346
+ expandReplacement,
841
2347
  extractCellDependencies,
842
2348
  extractInstructionNames,
843
2349
  extractMentions,
844
2350
  extractMentionsFromDoc,
2351
+ extractNameDependencies,
845
2352
  extractTemplateNames,
846
2353
  extractVariableNames,
847
2354
  extractVariables,
848
2355
  fileImportPluginKey,
849
2356
  fillSeries,
2357
+ findAllMatches,
850
2358
  findAutocorrection,
851
2359
  findCommentRanges,
2360
+ findDataValidation,
852
2361
  findHexColors,
853
2362
  findImportAdapter,
2363
+ findInvalidCells,
2364
+ findReplacePluginKey,
2365
+ findTextMentions,
2366
+ foldCodePoint,
854
2367
  footnotesMarkdownIt,
855
2368
  footnotesPluginKey,
2369
+ forEachRangeCell,
856
2370
  formatCellDisplay,
2371
+ formatCellForDisplay,
2372
+ formatComparisonOperand,
2373
+ formatConditionalTag,
2374
+ formatFindStatus,
2375
+ formatGeneralFit,
2376
+ formatMentionText,
2377
+ formatNumberFormatValue,
857
2378
  formatReviewTime,
2379
+ formatRuleRanges,
2380
+ formatSheetPrefix,
2381
+ formatTextFunction,
858
2382
  formatValueWithCode,
2383
+ formulaIdentifiers,
859
2384
  fractionRules,
860
2385
  getActiveHeading,
861
2386
  getBookmarks,
@@ -864,11 +2389,16 @@ export {
864
2389
  getCommentAuthor,
865
2390
  getCommentIdsAt,
866
2391
  getCommentStore,
2392
+ getConditionalFormatCss,
2393
+ getConditionalFormatIcon,
867
2394
  getCrossReferenceTargets,
2395
+ getDataBarCss,
868
2396
  getDocumentStructureCommandItems,
869
2397
  getEditorMarkdown,
870
2398
  getEditorText,
871
2399
  getFillDirection,
2400
+ getFindReplaceState,
2401
+ getFindReplaceStore,
872
2402
  getFootnotes,
873
2403
  getFormulaArgumentSpecIndex,
874
2404
  getFormulaCaretContext,
@@ -878,11 +2408,16 @@ export {
878
2408
  getFormulaSignatureParts,
879
2409
  getImportAccept,
880
2410
  getLatestVersion,
2411
+ getMentionNodes,
2412
+ getNameManagerRows,
881
2413
  getOutline,
2414
+ getParagraphStyleAt,
882
2415
  getPromptDiagnostics,
883
2416
  getRowSection,
884
2417
  getSchemaSignature,
2418
+ getSheetTabMenuItems,
885
2419
  getSpreadsheetMenuItems,
2420
+ getStyleRegistry,
886
2421
  getSuppliedValue,
887
2422
  getTableOfContentsEntries,
888
2423
  getTableSections,
@@ -890,6 +2425,7 @@ export {
890
2425
  getTrackChangesStore,
891
2426
  getTrackedChangeAt,
892
2427
  getTrackedChanges,
2428
+ getValidationListValues,
893
2429
  getVariableFormFields,
894
2430
  handleImageInsertion,
895
2431
  htmlImportAdapter,
@@ -905,11 +2441,17 @@ export {
905
2441
  instructionRegex,
906
2442
  isBlankValue,
907
2443
  isFormulaError,
2444
+ isFormulaLambda,
2445
+ isGeneralNumberFormat,
908
2446
  isInsidePromptToken,
2447
+ isLambdaDefinition,
2448
+ isMoveSized,
2449
+ isParagraphStyleAvailable,
909
2450
  isPromptValueSet,
910
2451
  isSingleCellRange,
911
2452
  isTrackChangesEnabled,
912
2453
  isUnsafeZipPath,
2454
+ isValidStyleId,
913
2455
  listFormulaFunctions,
914
2456
  mapFormulaReferences,
915
2457
  mapRawOffsetToResolved,
@@ -917,25 +2459,42 @@ export {
917
2459
  markdownImportAdapter,
918
2460
  markdownToTipTapHtml,
919
2461
  matchConditionalTags,
2462
+ matchFields,
920
2463
  matchesFilterRule,
2464
+ matchesTimePeriod,
2465
+ mergeRecords,
921
2466
  navigateToHeading,
2467
+ nextSheetName,
2468
+ normalizeFieldKey,
2469
+ normalizeFieldNames,
922
2470
  normalizeRange,
2471
+ numberFormatColorToCss,
2472
+ numberFormatForCellFormat,
923
2473
  numberToText,
924
2474
  offsetFormulaReferences,
925
2475
  outlinePluginKey,
2476
+ paragraphStylesPluginKey,
926
2477
  parseCellInput,
927
2478
  parseCellReference,
2479
+ parseComparison,
2480
+ parseConditionExpression,
928
2481
  parseCriteria,
929
2482
  parseCsv,
2483
+ parseDataSource,
930
2484
  parseFormula,
931
2485
  parseHtmlTable,
932
2486
  parseMentionSegments,
933
2487
  parseNumberText,
934
2488
  parseRange,
2489
+ parseReplacement,
935
2490
  parseRichClipboardPayload,
2491
+ parseRuleRanges,
936
2492
  parseTsv,
937
2493
  parseVariableBody,
2494
+ pdfLayoutBlocksToHtml,
2495
+ pdfOperatorListToRules,
938
2496
  pdfTextItemsToParagraphs,
2497
+ pdfTextItemsToRuns,
939
2498
  pickImportFiles,
940
2499
  plainTextImportAdapter,
941
2500
  plainTextToParagraphHtml,
@@ -943,18 +2502,23 @@ export {
943
2502
  plainTextToTipTapHtml,
944
2503
  preprocessMarkdownFileLinks,
945
2504
  preprocessMarkdownMentions,
2505
+ quoteSheetName,
946
2506
  rangeContains,
947
2507
  rangeContainsRange,
2508
+ rangesContain,
948
2509
  rangesIntersect,
949
2510
  readRichClipboard,
950
2511
  readSpreadsheetClipboard,
951
2512
  readZip,
952
2513
  rebaseClipboardRows,
2514
+ recordToValues,
953
2515
  registerFormulaFunction,
954
2516
  registerImportAdapter,
955
2517
  registerSpreadsheetImportAdapters,
956
2518
  remapFormulaReferences,
957
2519
  removeImageNode,
2520
+ renameNameInFormula,
2521
+ renameSheetInFormula,
958
2522
  resolvePrompt,
959
2523
  resolveTemplates,
960
2524
  resolveTemplatesWithMapping,
@@ -965,20 +2529,34 @@ export {
965
2529
  rowPassesFilters,
966
2530
  rtfImportAdapter,
967
2531
  rtfToPlainText,
2532
+ ruleAnchor,
2533
+ ruleFormulaAt,
2534
+ runSpreadsheetMenuItem,
2535
+ safeCSSValue,
968
2536
  sanitizeHtml,
969
2537
  sanitizeImportedHtml,
2538
+ searchDocument,
970
2539
  searchFormulaFunctions,
971
2540
  serialFromYmd,
972
2541
  serializeCsv,
973
2542
  serializeHtmlTable,
2543
+ serializeMergeOutputs,
974
2544
  serializeRichClipboardPayload,
975
2545
  serializeTsv,
2546
+ setMentionRoleAt,
2547
+ setMentionRoleInText,
2548
+ sheetDropIndex,
2549
+ sheetNameNeedsQuotes,
976
2550
  shiftFormulaReferences,
2551
+ shiftRuleFormula,
977
2552
  smartQuoteRules,
978
2553
  smilieAutocorrectRules,
979
2554
  sortCompareValues,
980
2555
  sortZipEntryNames,
981
2556
  stripMarkdownCode,
2557
+ subtractRange,
2558
+ subtractRangeFromRanges,
2559
+ summarizeImportStructure,
982
2560
  symbolRules,
983
2561
  syncFootnotes,
984
2562
  tableOfContentsMarkdownIt,
@@ -989,12 +2567,17 @@ export {
989
2567
  tokenizePrompt,
990
2568
  tokenizePromptWithDiagnostics,
991
2569
  trackChangesPluginKey,
2570
+ trackedChangeLabel,
992
2571
  tsvImportAdapter,
993
2572
  twoInitialCapitalsRules,
994
2573
  unescapeVariableText,
995
2574
  unregisterFormulaFunction,
996
2575
  unregisterImportAdapter,
997
2576
  updateImageSrc,
2577
+ validateCellInput,
2578
+ validateDefinedName,
2579
+ validateFindPattern,
2580
+ validateSheetName,
998
2581
  variableRegex,
999
2582
  wildcardToRegExp,
1000
2583
  withoutDirty,