@stll/folio-core 0.0.1-placeholder.0 → 0.1.1

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 (683) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE.md +29 -0
  3. package/README.md +41 -0
  4. package/dist/_virtual/_rolldown/runtime.js +13 -0
  5. package/dist/ai-edits/apply.d.ts +35 -0
  6. package/dist/ai-edits/apply.js +683 -0
  7. package/dist/ai-edits/clean-text.d.ts +28 -0
  8. package/dist/ai-edits/clean-text.js +23 -0
  9. package/dist/ai-edits/headless.d.ts +225 -0
  10. package/dist/ai-edits/headless.js +513 -0
  11. package/dist/ai-edits/index.d.ts +6 -0
  12. package/dist/ai-edits/index.js +5 -0
  13. package/dist/ai-edits/inline-emphasis.d.ts +38 -0
  14. package/dist/ai-edits/inline-emphasis.js +78 -0
  15. package/dist/ai-edits/snapshot.d.ts +9 -0
  16. package/dist/ai-edits/snapshot.js +195 -0
  17. package/dist/ai-edits/types.d.ts +156 -0
  18. package/dist/ai-edits/types.js +0 -0
  19. package/dist/ai-edits/word-diff.d.ts +20 -0
  20. package/dist/ai-edits/word-diff.js +77 -0
  21. package/dist/ai-suggestions/apply.d.ts +17 -0
  22. package/dist/ai-suggestions/apply.js +64 -0
  23. package/dist/ai-suggestions/conflict.d.ts +22 -0
  24. package/dist/ai-suggestions/conflict.js +67 -0
  25. package/dist/ai-suggestions/text-positions.d.ts +21 -0
  26. package/dist/ai-suggestions/text-positions.js +48 -0
  27. package/dist/ai-suggestions/types.d.ts +199 -0
  28. package/dist/ai-suggestions/types.js +59 -0
  29. package/dist/content-controls/errors.d.ts +52 -0
  30. package/dist/content-controls/errors.js +36 -0
  31. package/dist/content-controls/findContentControls.d.ts +55 -0
  32. package/dist/content-controls/findContentControls.js +75 -0
  33. package/dist/content-controls/index.d.ts +4 -0
  34. package/dist/content-controls/index.js +4 -0
  35. package/dist/content-controls/mutateContentControls.d.ts +51 -0
  36. package/dist/content-controls/mutateContentControls.js +377 -0
  37. package/dist/controller/folioEditor.d.ts +21 -0
  38. package/dist/controller/folioEditor.js +29 -0
  39. package/dist/controller/folioEditorEvents.d.ts +23 -0
  40. package/dist/controller/folioEditorEvents.js +24 -0
  41. package/dist/controller/hiddenEditorApi.d.ts +35 -0
  42. package/dist/controller/hiddenEditorApi.js +112 -0
  43. package/dist/controller/hiddenEditorManager.d.ts +93 -0
  44. package/dist/controller/hiddenEditorManager.js +308 -0
  45. package/dist/controller/layoutPipeline.d.ts +63 -0
  46. package/dist/controller/layoutPipeline.js +406 -0
  47. package/dist/controller/layoutScheduler.d.ts +41 -0
  48. package/dist/controller/layoutScheduler.js +59 -0
  49. package/dist/controller/layoutSession.d.ts +24 -0
  50. package/dist/controller/layoutSession.js +13 -0
  51. package/dist/docx/blockContentParser.d.ts +13 -0
  52. package/dist/docx/blockContentParser.js +289 -0
  53. package/dist/docx/bookmarkParser.d.ts +178 -0
  54. package/dist/docx/bookmarkParser.js +246 -0
  55. package/dist/docx/bookmarkPlacement.d.ts +10 -0
  56. package/dist/docx/bookmarkPlacement.js +50 -0
  57. package/dist/docx/bulletMarkers.d.ts +4 -0
  58. package/dist/docx/bulletMarkers.js +42 -0
  59. package/dist/docx/commentParser.d.ts +34 -0
  60. package/dist/docx/commentParser.js +127 -0
  61. package/dist/docx/commentReferenceNormalization.d.ts +25 -0
  62. package/dist/docx/commentReferenceNormalization.js +97 -0
  63. package/dist/docx/commentReplyMarkers.d.ts +20 -0
  64. package/dist/docx/commentReplyMarkers.js +123 -0
  65. package/dist/docx/compatibility.d.ts +12 -0
  66. package/dist/docx/compatibility.js +77 -0
  67. package/dist/docx/documentParser.d.ts +65 -0
  68. package/dist/docx/documentParser.js +209 -0
  69. package/dist/docx/drawingUtils.d.ts +56 -0
  70. package/dist/docx/drawingUtils.js +305 -0
  71. package/dist/docx/fieldParser.d.ts +228 -0
  72. package/dist/docx/fieldParser.js +559 -0
  73. package/dist/docx/footnoteParser.d.ts +109 -0
  74. package/dist/docx/footnoteParser.js +270 -0
  75. package/dist/docx/headerFooterParser.d.ts +119 -0
  76. package/dist/docx/headerFooterParser.js +266 -0
  77. package/dist/docx/headerFooterRefParser.d.ts +22 -0
  78. package/dist/docx/headerFooterRefParser.js +52 -0
  79. package/dist/docx/headerFooterReferenceNormalization.d.ts +19 -0
  80. package/dist/docx/headerFooterReferenceNormalization.js +64 -0
  81. package/dist/docx/hyperlinkParser.d.ts +108 -0
  82. package/dist/docx/hyperlinkParser.js +230 -0
  83. package/dist/docx/imageParser.d.ts +93 -0
  84. package/dist/docx/imageParser.js +522 -0
  85. package/dist/docx/mathToMathml.d.ts +15 -0
  86. package/dist/docx/mathToMathml.js +357 -0
  87. package/dist/docx/modelValidation.d.ts +13 -0
  88. package/dist/docx/modelValidation.js +21 -0
  89. package/dist/docx/normalizeBaseDirection.d.ts +12 -0
  90. package/dist/docx/normalizeBaseDirection.js +81 -0
  91. package/dist/docx/notePropertiesParser.d.ts +16 -0
  92. package/dist/docx/notePropertiesParser.js +99 -0
  93. package/dist/docx/numberingParser.d.ts +86 -0
  94. package/dist/docx/numberingParser.js +735 -0
  95. package/dist/docx/numberingReferenceNormalization.d.ts +25 -0
  96. package/dist/docx/numberingReferenceNormalization.js +22 -0
  97. package/dist/docx/paragraphParser.d.ts +86 -0
  98. package/dist/docx/paragraphParser.js +1132 -0
  99. package/dist/docx/paragraphTraversal.d.ts +19 -0
  100. package/dist/docx/paragraphTraversal.js +76 -0
  101. package/dist/docx/parser.d.ts +67 -0
  102. package/dist/docx/parser.js +391 -0
  103. package/dist/docx/parserEnums.d.ts +45 -0
  104. package/dist/docx/parserEnums.js +70 -0
  105. package/dist/docx/relsParser.d.ts +160 -0
  106. package/dist/docx/relsParser.js +235 -0
  107. package/dist/docx/replyToComment.d.ts +29 -0
  108. package/dist/docx/replyToComment.js +73 -0
  109. package/dist/docx/rezip.d.ts +166 -0
  110. package/dist/docx/rezip.js +1194 -0
  111. package/dist/docx/runConsolidator.d.ts +57 -0
  112. package/dist/docx/runConsolidator.js +224 -0
  113. package/dist/docx/runParser.d.ts +78 -0
  114. package/dist/docx/runParser.js +661 -0
  115. package/dist/docx/sdtProperties.d.ts +15 -0
  116. package/dist/docx/sdtProperties.js +290 -0
  117. package/dist/docx/sdtPropertiesPatch.d.ts +16 -0
  118. package/dist/docx/sdtPropertiesPatch.js +144 -0
  119. package/dist/docx/sectionParser.d.ts +95 -0
  120. package/dist/docx/sectionParser.js +534 -0
  121. package/dist/docx/selectiveSave.d.ts +25 -0
  122. package/dist/docx/selectiveSave.js +247 -0
  123. package/dist/docx/selectiveSaveFlags.d.ts +33 -0
  124. package/dist/docx/selectiveSaveFlags.js +11 -0
  125. package/dist/docx/selectiveSaveTripwire.d.ts +33 -0
  126. package/dist/docx/selectiveSaveTripwire.js +79 -0
  127. package/dist/docx/selectiveXmlPatch.d.ts +103 -0
  128. package/dist/docx/selectiveXmlPatch.js +493 -0
  129. package/dist/docx/serializer/blockSdtSerializer.d.ts +6 -0
  130. package/dist/docx/serializer/blockSdtSerializer.js +88 -0
  131. package/dist/docx/serializer/borderSerializer.d.ts +25 -0
  132. package/dist/docx/serializer/borderSerializer.js +44 -0
  133. package/dist/docx/serializer/commentSerializer.d.ts +31 -0
  134. package/dist/docx/serializer/commentSerializer.js +184 -0
  135. package/dist/docx/serializer/documentSerializer.d.ts +65 -0
  136. package/dist/docx/serializer/documentSerializer.js +199 -0
  137. package/dist/docx/serializer/headerFooterSerializer.d.ts +12 -0
  138. package/dist/docx/serializer/headerFooterSerializer.js +84 -0
  139. package/dist/docx/serializer/noteSerializer.d.ts +19 -0
  140. package/dist/docx/serializer/noteSerializer.js +70 -0
  141. package/dist/docx/serializer/numberingSerializer.d.ts +12 -0
  142. package/dist/docx/serializer/numberingSerializer.js +93 -0
  143. package/dist/docx/serializer/paragraphSerializer.d.ts +48 -0
  144. package/dist/docx/serializer/paragraphSerializer.js +559 -0
  145. package/dist/docx/serializer/runSerializer.d.ts +56 -0
  146. package/dist/docx/serializer/runSerializer.js +621 -0
  147. package/dist/docx/serializer/sectionPropertiesSerializer.d.ts +6 -0
  148. package/dist/docx/serializer/sectionPropertiesSerializer.js +187 -0
  149. package/dist/docx/serializer/tableSerializer.d.ts +79 -0
  150. package/dist/docx/serializer/tableSerializer.js +422 -0
  151. package/dist/docx/serializer/xmlUtils.d.ts +20 -0
  152. package/dist/docx/serializer/xmlUtils.js +25 -0
  153. package/dist/docx/settingsParser.d.ts +8 -0
  154. package/dist/docx/settingsParser.js +36 -0
  155. package/dist/docx/shapeParser.d.ts +20 -0
  156. package/dist/docx/shapeParser.js +272 -0
  157. package/dist/docx/styleParser.d.ts +50 -0
  158. package/dist/docx/styleParser.js +905 -0
  159. package/dist/docx/tableParser.d.ts +202 -0
  160. package/dist/docx/tableParser.js +811 -0
  161. package/dist/docx/textBoxParser.d.ts +117 -0
  162. package/dist/docx/textBoxParser.js +262 -0
  163. package/dist/docx/themeParser.d.ts +77 -0
  164. package/dist/docx/themeParser.js +330 -0
  165. package/dist/docx/trackedMoveRangeNormalization.d.ts +22 -0
  166. package/dist/docx/trackedMoveRangeNormalization.js +100 -0
  167. package/dist/docx/unzip.d.ts +118 -0
  168. package/dist/docx/unzip.js +383 -0
  169. package/dist/docx/vmlImageParser.d.ts +16 -0
  170. package/dist/docx/vmlImageParser.js +100 -0
  171. package/dist/docx/watermarkParser.d.ts +45 -0
  172. package/dist/docx/watermarkParser.js +348 -0
  173. package/dist/docx/wrapTypes.d.ts +29 -0
  174. package/dist/docx/wrapTypes.js +48 -0
  175. package/dist/docx/xmlParser.d.ts +297 -0
  176. package/dist/docx/xmlParser.js +527 -0
  177. package/dist/fields/bookmarkPages.d.ts +13 -0
  178. package/dist/fields/bookmarkPages.js +66 -0
  179. package/dist/fields/bookmarkText.d.ts +16 -0
  180. package/dist/fields/bookmarkText.js +61 -0
  181. package/dist/fields/evaluateField.d.ts +23 -0
  182. package/dist/fields/evaluateField.js +77 -0
  183. package/dist/fields/fieldContext.d.ts +21 -0
  184. package/dist/fields/fieldContext.js +0 -0
  185. package/dist/fields/resolveFieldValues.d.ts +44 -0
  186. package/dist/fields/resolveFieldValues.js +204 -0
  187. package/dist/fields/sectionPageCounts.d.ts +11 -0
  188. package/dist/fields/sectionPageCounts.js +16 -0
  189. package/dist/fields/seqValues.d.ts +14 -0
  190. package/dist/fields/seqValues.js +36 -0
  191. package/dist/fonts/embeddedFontTable.d.ts +42 -0
  192. package/dist/fonts/embeddedFontTable.js +80 -0
  193. package/dist/fonts/embeddedFonts.d.ts +46 -0
  194. package/dist/fonts/embeddedFonts.js +112 -0
  195. package/dist/fonts/fontDeobfuscation.d.ts +30 -0
  196. package/dist/fonts/fontDeobfuscation.js +57 -0
  197. package/dist/index.d.ts +28 -0
  198. package/dist/index.js +23 -0
  199. package/dist/layout-bridge/convert/footnoteLayout.d.ts +57 -0
  200. package/dist/layout-bridge/convert/footnoteLayout.js +316 -0
  201. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +74 -0
  202. package/dist/layout-bridge/convert/headerFooterLayout.js +432 -0
  203. package/dist/layout-bridge/convert/templatePreviewFlow.d.ts +36 -0
  204. package/dist/layout-bridge/convert/templatePreviewFlow.js +176 -0
  205. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +65 -0
  206. package/dist/layout-bridge/convert/toFlowBlocks.js +1309 -0
  207. package/dist/layout-bridge/convert/wrapEditorViewAsSurface.d.ts +17 -0
  208. package/dist/layout-bridge/convert/wrapEditorViewAsSurface.js +36 -0
  209. package/dist/layout-bridge/dom/clickToPositionDom.d.ts +66 -0
  210. package/dist/layout-bridge/dom/clickToPositionDom.js +304 -0
  211. package/dist/layout-bridge/dom/findBodyPmSpans.d.ts +7 -0
  212. package/dist/layout-bridge/dom/findBodyPmSpans.js +17 -0
  213. package/dist/layout-bridge/dom/findHfPmSpans.d.ts +62 -0
  214. package/dist/layout-bridge/dom/findHfPmSpans.js +197 -0
  215. package/dist/layout-bridge/engine/clickToPosition.d.ts +66 -0
  216. package/dist/layout-bridge/engine/clickToPosition.js +403 -0
  217. package/dist/layout-bridge/engine/hitTest.d.ts +135 -0
  218. package/dist/layout-bridge/engine/hitTest.js +375 -0
  219. package/dist/layout-bridge/engine/measuring/index.d.ts +10 -0
  220. package/dist/layout-bridge/engine/measuring/index.js +9 -0
  221. package/dist/layout-bridge/engine/selectionRects.d.ts +59 -0
  222. package/dist/layout-bridge/engine/selectionRects.js +485 -0
  223. package/dist/layout-bridge/engine/tableWidthUtils.d.ts +7 -0
  224. package/dist/layout-bridge/engine/tableWidthUtils.js +25 -0
  225. package/dist/layout-engine/index.d.ts +44 -0
  226. package/dist/layout-engine/index.js +691 -0
  227. package/dist/layout-engine/keep-together.d.ts +43 -0
  228. package/dist/layout-engine/keep-together.js +98 -0
  229. package/dist/layout-engine/layoutInstrumentation.d.ts +50 -0
  230. package/dist/layout-engine/layoutInstrumentation.js +43 -0
  231. package/dist/layout-engine/lineFlow.d.ts +8 -0
  232. package/dist/layout-engine/lineFlow.js +17 -0
  233. package/dist/layout-engine/measure/cache.d.ts +93 -0
  234. package/dist/layout-engine/measure/cache.js +245 -0
  235. package/dist/layout-engine/measure/clampFloatingWrapMargins.d.ts +20 -0
  236. package/dist/layout-engine/measure/clampFloatingWrapMargins.js +29 -0
  237. package/dist/layout-engine/measure/featureFlags.d.ts +44 -0
  238. package/dist/layout-engine/measure/featureFlags.js +19 -0
  239. package/dist/layout-engine/measure/floatingZones.d.ts +89 -0
  240. package/dist/layout-engine/measure/floatingZones.js +152 -0
  241. package/dist/layout-engine/measure/font-metrics.worker.d.ts +17 -0
  242. package/dist/layout-engine/measure/font-metrics.worker.js +104 -0
  243. package/dist/layout-engine/measure/index.d.ts +9 -0
  244. package/dist/layout-engine/measure/index.js +8 -0
  245. package/dist/layout-engine/measure/listMarkerWidth.d.ts +40 -0
  246. package/dist/layout-engine/measure/listMarkerWidth.js +76 -0
  247. package/dist/layout-engine/measure/measureBlocks.d.ts +25 -0
  248. package/dist/layout-engine/measure/measureBlocks.js +450 -0
  249. package/dist/layout-engine/measure/measureContainer.d.ts +24 -0
  250. package/dist/layout-engine/measure/measureContainer.js +280 -0
  251. package/dist/layout-engine/measure/measureHelpers.d.ts +82 -0
  252. package/dist/layout-engine/measure/measureHelpers.js +156 -0
  253. package/dist/layout-engine/measure/measureParagraph.d.ts +61 -0
  254. package/dist/layout-engine/measure/measureParagraph.js +724 -0
  255. package/dist/layout-engine/measure/measureProvider.d.ts +23 -0
  256. package/dist/layout-engine/measure/measureProvider.js +35 -0
  257. package/dist/layout-engine/measure/measureTypes.d.ts +61 -0
  258. package/dist/layout-engine/measure/measureTypes.js +0 -0
  259. package/dist/layout-engine/measure/measureWorker.d.ts +54 -0
  260. package/dist/layout-engine/measure/measureWorker.js +249 -0
  261. package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +88 -0
  262. package/dist/layout-engine/measure/measureWorkerProtocol.js +20 -0
  263. package/dist/layout-engine/measure/tableCellFloating.d.ts +26 -0
  264. package/dist/layout-engine/measure/tableCellFloating.js +99 -0
  265. package/dist/layout-engine/paginator.d.ts +84 -0
  266. package/dist/layout-engine/paginator.js +348 -0
  267. package/dist/layout-engine/paragraphFragmentRange.d.ts +9 -0
  268. package/dist/layout-engine/paragraphFragmentRange.js +40 -0
  269. package/dist/layout-engine/section-breaks.d.ts +78 -0
  270. package/dist/layout-engine/section-breaks.js +182 -0
  271. package/dist/layout-engine/tableRowBreak.d.ts +23 -0
  272. package/dist/layout-engine/tableRowBreak.js +147 -0
  273. package/dist/layout-engine/textBoxFlow.d.ts +50 -0
  274. package/dist/layout-engine/textBoxFlow.js +160 -0
  275. package/dist/layout-engine/types.d.ts +1031 -0
  276. package/dist/layout-engine/types.js +100 -0
  277. package/dist/layout-painter/documentColors.d.ts +4 -0
  278. package/dist/layout-painter/documentColors.js +40 -0
  279. package/dist/layout-painter/index.d.ts +110 -0
  280. package/dist/layout-painter/index.js +182 -0
  281. package/dist/layout-painter/registry/modules/image.d.ts +6 -0
  282. package/dist/layout-painter/registry/modules/image.js +17 -0
  283. package/dist/layout-painter/registry/modules/paragraph.d.ts +6 -0
  284. package/dist/layout-painter/registry/modules/paragraph.js +18 -0
  285. package/dist/layout-painter/registry/modules/table.d.ts +6 -0
  286. package/dist/layout-painter/registry/modules/table.js +16 -0
  287. package/dist/layout-painter/registry/modules/textBox.d.ts +6 -0
  288. package/dist/layout-painter/registry/modules/textBox.js +13 -0
  289. package/dist/layout-painter/registry/modules.d.ts +6 -0
  290. package/dist/layout-painter/registry/modules.js +26 -0
  291. package/dist/layout-painter/registry/registry.d.ts +24 -0
  292. package/dist/layout-painter/registry/registry.js +53 -0
  293. package/dist/layout-painter/registry/types.d.ts +61 -0
  294. package/dist/layout-painter/registry/types.js +0 -0
  295. package/dist/layout-painter/renderFragment.d.ts +32 -0
  296. package/dist/layout-painter/renderFragment.js +114 -0
  297. package/dist/layout-painter/renderImage.d.ts +88 -0
  298. package/dist/layout-painter/renderImage.js +130 -0
  299. package/dist/layout-painter/renderPage.d.ts +264 -0
  300. package/dist/layout-painter/renderPage.js +1795 -0
  301. package/dist/layout-painter/renderParagraph.d.ts +93 -0
  302. package/dist/layout-painter/renderParagraph.js +1300 -0
  303. package/dist/layout-painter/renderTable.d.ts +36 -0
  304. package/dist/layout-painter/renderTable.js +432 -0
  305. package/dist/layout-painter/renderTextBox.d.ts +22 -0
  306. package/dist/layout-painter/renderTextBox.js +67 -0
  307. package/dist/layout-painter/renderUtils.d.ts +42 -0
  308. package/dist/layout-painter/renderUtils.js +30 -0
  309. package/dist/layout-painter/renderWatermark.d.ts +16 -0
  310. package/dist/layout-painter/renderWatermark.js +61 -0
  311. package/dist/layout-painter/sdtBoundary.d.ts +6 -0
  312. package/dist/layout-painter/sdtBoundary.js +28 -0
  313. package/dist/managers/ContextMenuManager.d.ts +28 -0
  314. package/dist/managers/ContextMenuManager.js +48 -0
  315. package/dist/managers/DocumentLoaderManager.d.ts +47 -0
  316. package/dist/managers/DocumentLoaderManager.js +69 -0
  317. package/dist/managers/EditorModeManager.d.ts +28 -0
  318. package/dist/managers/EditorModeManager.js +50 -0
  319. package/dist/managers/ErrorManager.d.ts +26 -0
  320. package/dist/managers/ErrorManager.js +85 -0
  321. package/dist/managers/FindReplaceManager.d.ts +54 -0
  322. package/dist/managers/FindReplaceManager.js +104 -0
  323. package/dist/managers/HistoryManager.d.ts +92 -0
  324. package/dist/managers/HistoryManager.js +193 -0
  325. package/dist/managers/Subscribable.d.ts +34 -0
  326. package/dist/managers/Subscribable.js +46 -0
  327. package/dist/managers/TableSelectionManager.d.ts +74 -0
  328. package/dist/managers/TableSelectionManager.js +225 -0
  329. package/dist/managers/editorShortcuts.d.ts +42 -0
  330. package/dist/managers/editorShortcuts.js +60 -0
  331. package/dist/managers/types.d.ts +41 -0
  332. package/dist/managers/types.js +0 -0
  333. package/dist/markdown/annotations.d.ts +14 -0
  334. package/dist/markdown/annotations.js +42 -0
  335. package/dist/markdown/escape.d.ts +36 -0
  336. package/dist/markdown/escape.js +59 -0
  337. package/dist/markdown/fromMarkdown.d.ts +11 -0
  338. package/dist/markdown/fromMarkdown.js +223 -0
  339. package/dist/markdown/headings.d.ts +13 -0
  340. package/dist/markdown/headings.js +20 -0
  341. package/dist/markdown/images.d.ts +13 -0
  342. package/dist/markdown/images.js +63 -0
  343. package/dist/markdown/index.d.ts +18 -0
  344. package/dist/markdown/index.js +33 -0
  345. package/dist/markdown/internals.d.ts +15 -0
  346. package/dist/markdown/internals.js +35 -0
  347. package/dist/markdown/renderBlock.d.ts +7 -0
  348. package/dist/markdown/renderBlock.js +68 -0
  349. package/dist/markdown/renderParagraph.d.ts +11 -0
  350. package/dist/markdown/renderParagraph.js +64 -0
  351. package/dist/markdown/renderRuns.d.ts +11 -0
  352. package/dist/markdown/renderRuns.js +265 -0
  353. package/dist/markdown/renderTable.d.ts +8 -0
  354. package/dist/markdown/renderTable.js +229 -0
  355. package/dist/markdown/trailers.d.ts +13 -0
  356. package/dist/markdown/trailers.js +54 -0
  357. package/dist/markdown/types.d.ts +118 -0
  358. package/dist/markdown/types.js +0 -0
  359. package/dist/model.d.ts +13 -0
  360. package/dist/model.js +4 -0
  361. package/dist/paged-layout/LayoutSelectionGate.d.ts +80 -0
  362. package/dist/paged-layout/LayoutSelectionGate.js +131 -0
  363. package/dist/paged-layout/headerFooterMargins.d.ts +73 -0
  364. package/dist/paged-layout/headerFooterMargins.js +120 -0
  365. package/dist/paged-layout/hiddenEditorScroll.d.ts +4 -0
  366. package/dist/paged-layout/hiddenEditorScroll.js +4 -0
  367. package/dist/paged-layout/incrementalMeasure.d.ts +33 -0
  368. package/dist/paged-layout/incrementalMeasure.js +56 -0
  369. package/dist/paged-layout/rangeProjection.d.ts +51 -0
  370. package/dist/paged-layout/rangeProjection.js +153 -0
  371. package/dist/paged-layout/readOnlyEditAttempt.d.ts +5 -0
  372. package/dist/paged-layout/readOnlyEditAttempt.js +22 -0
  373. package/dist/paged-layout/scrollNavigation.d.ts +23 -0
  374. package/dist/paged-layout/scrollNavigation.js +31 -0
  375. package/dist/paged-layout/scrollPageInfo.d.ts +41 -0
  376. package/dist/paged-layout/scrollPageInfo.js +34 -0
  377. package/dist/paged-layout/scrollToPmPosition.d.ts +17 -0
  378. package/dist/paged-layout/scrollToPmPosition.js +95 -0
  379. package/dist/paged-layout/sectionBlockWidths.d.ts +35 -0
  380. package/dist/paged-layout/sectionBlockWidths.js +52 -0
  381. package/dist/paged-layout/sectionGeometry.d.ts +21 -0
  382. package/dist/paged-layout/sectionGeometry.js +36 -0
  383. package/dist/paged-layout/selectionViewportRect.d.ts +29 -0
  384. package/dist/paged-layout/selectionViewportRect.js +55 -0
  385. package/dist/paged-layout/tableColumnResize.d.ts +19 -0
  386. package/dist/paged-layout/tableColumnResize.js +28 -0
  387. package/dist/paged-layout/tableInsertButtonGeometry.d.ts +15 -0
  388. package/dist/paged-layout/tableInsertButtonGeometry.js +15 -0
  389. package/dist/paged-layout/transactionDirtyRange.d.ts +7 -0
  390. package/dist/paged-layout/transactionDirtyRange.js +27 -0
  391. package/dist/paged-layout/zoomScrollAnchor.d.ts +40 -0
  392. package/dist/paged-layout/zoomScrollAnchor.js +25 -0
  393. package/dist/prosemirror/attrs/index.d.ts +80 -0
  394. package/dist/prosemirror/attrs/index.js +1218 -0
  395. package/dist/prosemirror/autospacingBase.d.ts +11 -0
  396. package/dist/prosemirror/autospacingBase.js +16 -0
  397. package/dist/prosemirror/commands/comments.d.ts +93 -0
  398. package/dist/prosemirror/commands/comments.js +435 -0
  399. package/dist/prosemirror/commands/contentControls.d.ts +45 -0
  400. package/dist/prosemirror/commands/contentControls.js +294 -0
  401. package/dist/prosemirror/commands/contentControlsBlockFill.d.ts +15 -0
  402. package/dist/prosemirror/commands/contentControlsBlockFill.js +19 -0
  403. package/dist/prosemirror/commands/formatPainter.d.ts +31 -0
  404. package/dist/prosemirror/commands/formatPainter.js +130 -0
  405. package/dist/prosemirror/commands/formatting.d.ts +32 -0
  406. package/dist/prosemirror/commands/formatting.js +45 -0
  407. package/dist/prosemirror/commands/hyperlink.d.ts +31 -0
  408. package/dist/prosemirror/commands/hyperlink.js +79 -0
  409. package/dist/prosemirror/commands/image.d.ts +59 -0
  410. package/dist/prosemirror/commands/image.js +219 -0
  411. package/dist/prosemirror/commands/index.d.ts +13 -0
  412. package/dist/prosemirror/commands/index.js +13 -0
  413. package/dist/prosemirror/commands/pageBreak.d.ts +10 -0
  414. package/dist/prosemirror/commands/pageBreak.js +47 -0
  415. package/dist/prosemirror/commands/paragraph.d.ts +39 -0
  416. package/dist/prosemirror/commands/paragraph.js +64 -0
  417. package/dist/prosemirror/commands/pastePlainText.d.ts +39 -0
  418. package/dist/prosemirror/commands/pastePlainText.js +67 -0
  419. package/dist/prosemirror/commands/table.d.ts +83 -0
  420. package/dist/prosemirror/commands/table.js +105 -0
  421. package/dist/prosemirror/conversion/fromProseDoc.d.ts +27 -0
  422. package/dist/prosemirror/conversion/fromProseDoc.js +1550 -0
  423. package/dist/prosemirror/conversion/index.d.ts +4 -0
  424. package/dist/prosemirror/conversion/index.js +4 -0
  425. package/dist/prosemirror/conversion/runShadingMark.d.ts +16 -0
  426. package/dist/prosemirror/conversion/runShadingMark.js +39 -0
  427. package/dist/prosemirror/conversion/toProseDoc.d.ts +39 -0
  428. package/dist/prosemirror/conversion/toProseDoc.js +1404 -0
  429. package/dist/prosemirror/extensions/ExtensionManager.d.ts +43 -0
  430. package/dist/prosemirror/extensions/ExtensionManager.js +86 -0
  431. package/dist/prosemirror/extensions/StarterKit.d.ts +16 -0
  432. package/dist/prosemirror/extensions/StarterKit.js +132 -0
  433. package/dist/prosemirror/extensions/core/DocExtension.d.ts +9 -0
  434. package/dist/prosemirror/extensions/core/DocExtension.js +12 -0
  435. package/dist/prosemirror/extensions/core/HistoryExtension.d.ts +13 -0
  436. package/dist/prosemirror/extensions/core/HistoryExtension.js +28 -0
  437. package/dist/prosemirror/extensions/core/ParagraphExtension.d.ts +25 -0
  438. package/dist/prosemirror/extensions/core/ParagraphExtension.js +619 -0
  439. package/dist/prosemirror/extensions/core/TextExtension.d.ts +9 -0
  440. package/dist/prosemirror/extensions/core/TextExtension.js +12 -0
  441. package/dist/prosemirror/extensions/create.d.ts +17 -0
  442. package/dist/prosemirror/extensions/create.js +129 -0
  443. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +23 -0
  444. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +106 -0
  445. package/dist/prosemirror/extensions/features/BaseKeymapExtension.d.ts +8 -0
  446. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +172 -0
  447. package/dist/prosemirror/extensions/features/BidiShortcutExtension.d.ts +16 -0
  448. package/dist/prosemirror/extensions/features/BidiShortcutExtension.js +38 -0
  449. package/dist/prosemirror/extensions/features/ContentControlWidgetsExtension.d.ts +16 -0
  450. package/dist/prosemirror/extensions/features/ContentControlWidgetsExtension.js +21 -0
  451. package/dist/prosemirror/extensions/features/DropCursorExtension.d.ts +12 -0
  452. package/dist/prosemirror/extensions/features/DropCursorExtension.js +20 -0
  453. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.d.ts +8 -0
  454. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +44 -0
  455. package/dist/prosemirror/extensions/features/GapCursorExtension.d.ts +19 -0
  456. package/dist/prosemirror/extensions/features/GapCursorExtension.js +24 -0
  457. package/dist/prosemirror/extensions/features/ImageDragExtension.d.ts +15 -0
  458. package/dist/prosemirror/extensions/features/ImageDragExtension.js +66 -0
  459. package/dist/prosemirror/extensions/features/ImagePasteExtension.d.ts +12 -0
  460. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +91 -0
  461. package/dist/prosemirror/extensions/features/ListExtension.d.ts +14 -0
  462. package/dist/prosemirror/extensions/features/ListExtension.js +340 -0
  463. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +9 -0
  464. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +60 -0
  465. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +35 -0
  466. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +188 -0
  467. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +20 -0
  468. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +34 -0
  469. package/dist/prosemirror/extensions/features/PasteStyleInlinerExtension.d.ts +20 -0
  470. package/dist/prosemirror/extensions/features/PasteStyleInlinerExtension.js +145 -0
  471. package/dist/prosemirror/extensions/features/SelectionTrackerExtension.d.ts +10 -0
  472. package/dist/prosemirror/extensions/features/SelectionTrackerExtension.js +17 -0
  473. package/dist/prosemirror/extensions/features/bidiShortcutController.d.ts +31 -0
  474. package/dist/prosemirror/extensions/features/bidiShortcutController.js +27 -0
  475. package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +31 -0
  476. package/dist/prosemirror/extensions/features/pasteCleanup.js +159 -0
  477. package/dist/prosemirror/extensions/marks/AllCapsExtension.d.ts +9 -0
  478. package/dist/prosemirror/extensions/marks/AllCapsExtension.js +24 -0
  479. package/dist/prosemirror/extensions/marks/BoldExtension.d.ts +9 -0
  480. package/dist/prosemirror/extensions/marks/BoldExtension.js +41 -0
  481. package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.d.ts +14 -0
  482. package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.js +64 -0
  483. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +23 -0
  484. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +47 -0
  485. package/dist/prosemirror/extensions/marks/CommentExtension.d.ts +12 -0
  486. package/dist/prosemirror/extensions/marks/CommentExtension.js +38 -0
  487. package/dist/prosemirror/extensions/marks/FontFamilyExtension.d.ts +9 -0
  488. package/dist/prosemirror/extensions/marks/FontFamilyExtension.js +55 -0
  489. package/dist/prosemirror/extensions/marks/FontSizeExtension.d.ts +9 -0
  490. package/dist/prosemirror/extensions/marks/FontSizeExtension.js +47 -0
  491. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.d.ts +11 -0
  492. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +92 -0
  493. package/dist/prosemirror/extensions/marks/HiddenTextExtension.d.ts +23 -0
  494. package/dist/prosemirror/extensions/marks/HiddenTextExtension.js +35 -0
  495. package/dist/prosemirror/extensions/marks/HighlightExtension.d.ts +10 -0
  496. package/dist/prosemirror/extensions/marks/HighlightExtension.js +115 -0
  497. package/dist/prosemirror/extensions/marks/HyperlinkExtension.d.ts +13 -0
  498. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +146 -0
  499. package/dist/prosemirror/extensions/marks/ItalicExtension.d.ts +9 -0
  500. package/dist/prosemirror/extensions/marks/ItalicExtension.js +34 -0
  501. package/dist/prosemirror/extensions/marks/RtlExtension.d.ts +6 -0
  502. package/dist/prosemirror/extensions/marks/RtlExtension.js +21 -0
  503. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +11 -0
  504. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +75 -0
  505. package/dist/prosemirror/extensions/marks/RunShadingExtension.d.ts +6 -0
  506. package/dist/prosemirror/extensions/marks/RunShadingExtension.js +38 -0
  507. package/dist/prosemirror/extensions/marks/SmallCapsExtension.d.ts +9 -0
  508. package/dist/prosemirror/extensions/marks/SmallCapsExtension.js +24 -0
  509. package/dist/prosemirror/extensions/marks/StrikeExtension.d.ts +9 -0
  510. package/dist/prosemirror/extensions/marks/StrikeExtension.js +33 -0
  511. package/dist/prosemirror/extensions/marks/SubscriptExtension.d.ts +9 -0
  512. package/dist/prosemirror/extensions/marks/SubscriptExtension.js +25 -0
  513. package/dist/prosemirror/extensions/marks/SuperscriptExtension.d.ts +9 -0
  514. package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +25 -0
  515. package/dist/prosemirror/extensions/marks/TextColorExtension.d.ts +9 -0
  516. package/dist/prosemirror/extensions/marks/TextColorExtension.js +50 -0
  517. package/dist/prosemirror/extensions/marks/TextEffectExtension.d.ts +6 -0
  518. package/dist/prosemirror/extensions/marks/TextEffectExtension.js +35 -0
  519. package/dist/prosemirror/extensions/marks/TextEffectsExtensions.d.ts +31 -0
  520. package/dist/prosemirror/extensions/marks/TextEffectsExtensions.js +134 -0
  521. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.d.ts +22 -0
  522. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +113 -0
  523. package/dist/prosemirror/extensions/marks/UnderlineExtension.d.ts +9 -0
  524. package/dist/prosemirror/extensions/marks/UnderlineExtension.js +60 -0
  525. package/dist/prosemirror/extensions/marks/markUtils.d.ts +34 -0
  526. package/dist/prosemirror/extensions/marks/markUtils.js +233 -0
  527. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +22 -0
  528. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +122 -0
  529. package/dist/prosemirror/extensions/nodes/FieldExtension.d.ts +12 -0
  530. package/dist/prosemirror/extensions/nodes/FieldExtension.js +87 -0
  531. package/dist/prosemirror/extensions/nodes/HardBreakExtension.d.ts +9 -0
  532. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +38 -0
  533. package/dist/prosemirror/extensions/nodes/HorizontalRuleExtension.d.ts +9 -0
  534. package/dist/prosemirror/extensions/nodes/HorizontalRuleExtension.js +18 -0
  535. package/dist/prosemirror/extensions/nodes/ImageExtension.d.ts +9 -0
  536. package/dist/prosemirror/extensions/nodes/ImageExtension.js +132 -0
  537. package/dist/prosemirror/extensions/nodes/MathExtension.d.ts +13 -0
  538. package/dist/prosemirror/extensions/nodes/MathExtension.js +56 -0
  539. package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +9 -0
  540. package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +20 -0
  541. package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +12 -0
  542. package/dist/prosemirror/extensions/nodes/SdtExtension.js +107 -0
  543. package/dist/prosemirror/extensions/nodes/ShapeExtension.d.ts +30 -0
  544. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +502 -0
  545. package/dist/prosemirror/extensions/nodes/TabExtension.d.ts +9 -0
  546. package/dist/prosemirror/extensions/nodes/TabExtension.js +27 -0
  547. package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +34 -0
  548. package/dist/prosemirror/extensions/nodes/TableExtension.js +1972 -0
  549. package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +34 -0
  550. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +150 -0
  551. package/dist/prosemirror/extensions/types.d.ts +101 -0
  552. package/dist/prosemirror/extensions/types.js +10 -0
  553. package/dist/prosemirror/findReplaceSelection.d.ts +23 -0
  554. package/dist/prosemirror/findReplaceSelection.js +86 -0
  555. package/dist/prosemirror/index.d.ts +25 -0
  556. package/dist/prosemirror/index.js +23 -0
  557. package/dist/prosemirror/insertOperations.d.ts +12 -0
  558. package/dist/prosemirror/insertOperations.js +19 -0
  559. package/dist/prosemirror/paragraphDirection.d.ts +42 -0
  560. package/dist/prosemirror/paragraphDirection.js +33 -0
  561. package/dist/prosemirror/plugins/aiCitationDecorations.d.ts +40 -0
  562. package/dist/prosemirror/plugins/aiCitationDecorations.js +90 -0
  563. package/dist/prosemirror/plugins/aiSuggestionDecorations.d.ts +42 -0
  564. package/dist/prosemirror/plugins/aiSuggestionDecorations.js +135 -0
  565. package/dist/prosemirror/plugins/anonymizationDecorations.d.ts +60 -0
  566. package/dist/prosemirror/plugins/anonymizationDecorations.js +120 -0
  567. package/dist/prosemirror/plugins/autocompleteSuggestion.d.ts +123 -0
  568. package/dist/prosemirror/plugins/autocompleteSuggestion.js +283 -0
  569. package/dist/prosemirror/plugins/contentControlWidgets.d.ts +56 -0
  570. package/dist/prosemirror/plugins/contentControlWidgets.js +192 -0
  571. package/dist/prosemirror/plugins/createDocScanPlugin.d.ts +37 -0
  572. package/dist/prosemirror/plugins/createDocScanPlugin.js +55 -0
  573. package/dist/prosemirror/plugins/documentStyles.d.ts +18 -0
  574. package/dist/prosemirror/plugins/documentStyles.js +46 -0
  575. package/dist/prosemirror/plugins/index.d.ts +3 -0
  576. package/dist/prosemirror/plugins/index.js +3 -0
  577. package/dist/prosemirror/plugins/pmTextScan.d.ts +19 -0
  578. package/dist/prosemirror/plugins/pmTextScan.js +39 -0
  579. package/dist/prosemirror/plugins/selectionTracker.d.ts +43 -0
  580. package/dist/prosemirror/plugins/selectionTracker.js +179 -0
  581. package/dist/prosemirror/plugins/suggestionMode.d.ts +70 -0
  582. package/dist/prosemirror/plugins/suggestionMode.js +489 -0
  583. package/dist/prosemirror/plugins/templateDirectives.d.ts +25 -0
  584. package/dist/prosemirror/plugins/templateDirectives.js +67 -0
  585. package/dist/prosemirror/plugins/templatePreviewValues.d.ts +49 -0
  586. package/dist/prosemirror/plugins/templatePreviewValues.js +117 -0
  587. package/dist/prosemirror/plugins/templateSlashMenu.d.ts +57 -0
  588. package/dist/prosemirror/plugins/templateSlashMenu.js +184 -0
  589. package/dist/prosemirror/schema/index.d.ts +15 -0
  590. package/dist/prosemirror/schema/index.js +20 -0
  591. package/dist/prosemirror/schema/marks.d.ts +118 -0
  592. package/dist/prosemirror/schema/marks.js +0 -0
  593. package/dist/prosemirror/schema/nodes.d.ts +389 -0
  594. package/dist/prosemirror/schema/nodes.js +0 -0
  595. package/dist/prosemirror/selectionState.d.ts +23 -0
  596. package/dist/prosemirror/selectionState.js +111 -0
  597. package/dist/prosemirror/styles/index.d.ts +2 -0
  598. package/dist/prosemirror/styles/index.js +2 -0
  599. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +32 -0
  600. package/dist/prosemirror/styles/resolvedStyleAttrs.js +108 -0
  601. package/dist/prosemirror/styles/styleResolver.d.ts +94 -0
  602. package/dist/prosemirror/styles/styleResolver.js +200 -0
  603. package/dist/prosemirror/utils/findParagraphByParaId.d.ts +26 -0
  604. package/dist/prosemirror/utils/findParagraphByParaId.js +37 -0
  605. package/dist/prosemirror/utils/tabCalculator.d.ts +110 -0
  606. package/dist/prosemirror/utils/tabCalculator.js +137 -0
  607. package/dist/prosemirror/validation.d.ts +20 -0
  608. package/dist/prosemirror/validation.js +177 -0
  609. package/dist/server.d.ts +7 -0
  610. package/dist/server.js +6 -0
  611. package/dist/style-engine/index.d.ts +3 -0
  612. package/dist/style-engine/index.js +2 -0
  613. package/dist/style-engine/styleEngine.d.ts +67 -0
  614. package/dist/style-engine/styleEngine.js +70 -0
  615. package/dist/types/block-id.d.ts +66 -0
  616. package/dist/types/block-id.js +73 -0
  617. package/dist/types/colors.d.ts +2 -0
  618. package/dist/types/colors.js +0 -0
  619. package/dist/types/content.d.ts +2 -0
  620. package/dist/types/content.js +0 -0
  621. package/dist/types/document.d.ts +7 -0
  622. package/dist/types/document.js +0 -0
  623. package/dist/types/documentEnumValues.d.ts +89 -0
  624. package/dist/types/documentEnumValues.js +693 -0
  625. package/dist/types/formatting.d.ts +2 -0
  626. package/dist/types/formatting.js +0 -0
  627. package/dist/types/index.d.ts +107 -0
  628. package/dist/types/index.js +0 -0
  629. package/dist/utils/authorColors.d.ts +16 -0
  630. package/dist/utils/authorColors.js +30 -0
  631. package/dist/utils/baseDirection.d.ts +23 -0
  632. package/dist/utils/baseDirection.js +34 -0
  633. package/dist/utils/clipboard.d.ts +126 -0
  634. package/dist/utils/clipboard.js +622 -0
  635. package/dist/utils/colorResolver.d.ts +158 -0
  636. package/dist/utils/colorResolver.js +557 -0
  637. package/dist/utils/createDocument.d.ts +50 -0
  638. package/dist/utils/createDocument.js +262 -0
  639. package/dist/utils/documentLoaderBehavior.d.ts +22 -0
  640. package/dist/utils/documentLoaderBehavior.js +14 -0
  641. package/dist/utils/docxInput.d.ts +22 -0
  642. package/dist/utils/docxInput.js +16 -0
  643. package/dist/utils/domGuards.d.ts +59 -0
  644. package/dist/utils/domGuards.js +82 -0
  645. package/dist/utils/fontFamilyMerge.d.ts +7 -0
  646. package/dist/utils/fontFamilyMerge.js +31 -0
  647. package/dist/utils/fontLoader.d.ts +50 -0
  648. package/dist/utils/fontLoader.js +177 -0
  649. package/dist/utils/fontResolver.d.ts +61 -0
  650. package/dist/utils/fontResolver.js +651 -0
  651. package/dist/utils/fontWeights.d.ts +4 -0
  652. package/dist/utils/fontWeights.js +4 -0
  653. package/dist/utils/formatToStyle.d.ts +103 -0
  654. package/dist/utils/formatToStyle.js +289 -0
  655. package/dist/utils/headerFooter.d.ts +74 -0
  656. package/dist/utils/headerFooter.js +257 -0
  657. package/dist/utils/headingCollector.d.ts +22 -0
  658. package/dist/utils/headingCollector.js +36 -0
  659. package/dist/utils/hexId.d.ts +33 -0
  660. package/dist/utils/hexId.js +37 -0
  661. package/dist/utils/imageValidation.d.ts +5 -0
  662. package/dist/utils/imageValidation.js +31 -0
  663. package/dist/utils/paragraphFormattingMerge.d.ts +14 -0
  664. package/dist/utils/paragraphFormattingMerge.js +68 -0
  665. package/dist/utils/replaceText.d.ts +17 -0
  666. package/dist/utils/replaceText.js +161 -0
  667. package/dist/utils/rotationBoundingBox.d.ts +12 -0
  668. package/dist/utils/rotationBoundingBox.js +36 -0
  669. package/dist/utils/scriptSegments.d.ts +36 -0
  670. package/dist/utils/scriptSegments.js +52 -0
  671. package/dist/utils/tableOperations.d.ts +87 -0
  672. package/dist/utils/tableOperations.js +259 -0
  673. package/dist/utils/textFormattingMerge.d.ts +6 -0
  674. package/dist/utils/textFormattingMerge.js +31 -0
  675. package/dist/utils/tiffConverter.d.ts +18 -0
  676. package/dist/utils/tiffConverter.js +83 -0
  677. package/dist/utils/units.d.ts +99 -0
  678. package/dist/utils/units.js +139 -0
  679. package/dist/utils/urlSecurity.d.ts +7 -0
  680. package/dist/utils/urlSecurity.js +65 -0
  681. package/dist/watermark/index.d.ts +39 -0
  682. package/dist/watermark/index.js +149 -0
  683. package/package.json +122 -2
@@ -0,0 +1,1795 @@
1
+ import { eighthsToPixels, pointsToPixels } from "../utils/units.js";
2
+ import { resolveFontFamily } from "../utils/fontResolver.js";
3
+ import { floatingTextBoxReservesBand, floatingTextBoxWrapsText, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun } from "../layout-engine/types.js";
4
+ import { rectsToFloatingZones } from "../layout-engine/measure/floatingZones.js";
5
+ import { measureParagraph } from "../layout-engine/measure/measureParagraph.js";
6
+ import { borderToStyle } from "../utils/formatToStyle.js";
7
+ import { renderFragment } from "./renderFragment.js";
8
+ import { applyImageVisualAttrs, hasImageVisualAttrs, renderImageFragment } from "./renderImage.js";
9
+ import { emuToPixels } from "./renderUtils.js";
10
+ import { renderParagraphFragment } from "./renderParagraph.js";
11
+ import { renderTableFragment } from "./renderTable.js";
12
+ import { renderTextBoxFragment } from "./renderTextBox.js";
13
+ import { renderWatermarkLayer } from "./renderWatermark.js";
14
+ import { panic } from "better-result";
15
+ //#region src/layout-painter/renderPage.ts
16
+ /**
17
+ * Page Renderer
18
+ *
19
+ * Renders a single page from Layout data to DOM elements.
20
+ * Each page contains positioned fragments within a content area.
21
+ */
22
+ /**
23
+ * CSS class names for page elements
24
+ */
25
+ const PAGE_CLASS_NAMES = {
26
+ page: "layout-page",
27
+ content: "layout-page-content",
28
+ header: "layout-page-header",
29
+ footer: "layout-page-footer"
30
+ };
31
+ const getDefaultPageFontFamily = () => resolveFontFamily("Calibri").cssFallback;
32
+ /**
33
+ * Apply page styles to an element
34
+ */
35
+ function applyPageStyles(element, width, height, options) {
36
+ element.style.position = "relative";
37
+ element.style.width = `${width}px`;
38
+ element.style.height = `${height}px`;
39
+ element.style.backgroundColor = options.backgroundColor ?? "var(--doc-canvas, #ffffff)";
40
+ element.style.color = "var(--doc-canvas-text, #1f2937)";
41
+ element.style.overflow = "hidden";
42
+ element.style.border = "none";
43
+ element.style.boxShadow = "none";
44
+ element.style.outline = "none";
45
+ element.style.fontFamily = getDefaultPageFontFamily();
46
+ element.style.fontSize = `${1056 / 72}px`;
47
+ element.style.color = "var(--doc-canvas-text, #000)";
48
+ }
49
+ function pageBorderShouldRender(pageNumber, display) {
50
+ switch (display ?? "allPages") {
51
+ case "firstPage": return pageNumber === 1;
52
+ case "notFirstPage": return pageNumber !== 1;
53
+ case "allPages": return true;
54
+ }
55
+ }
56
+ function pageBorderSpacePx(border) {
57
+ return border?.space !== void 0 ? pointsToPixels(border.space) : 0;
58
+ }
59
+ /**
60
+ * Effective rendered border width in pixels. Mirrors `borderToStyle` (1px
61
+ * floor for hairlines) and the 3px floor applied to double borders in
62
+ * `applyPageBorderSide`, so callers can shift the overlay outward by the
63
+ * exact stroke they will see on screen.
64
+ */
65
+ function pageBorderWidthPx(border) {
66
+ if (!border || border.style === "none" || border.style === "nil") return 0;
67
+ const widthPx = border.size !== void 0 && border.size !== 0 ? eighthsToPixels(border.size) : 1;
68
+ const floored = Math.max(1, widthPx);
69
+ return border.style === "double" ? Math.max(3, floored) : floored;
70
+ }
71
+ function applyPageBorderSide(element, border, side, theme) {
72
+ if (!border || border.style === "none" || border.style === "nil") return;
73
+ const styles = borderToStyle(border, side, theme);
74
+ for (const [key, value] of Object.entries(styles)) element.style[key] = String(value);
75
+ const styleKey = `border${side}Style`;
76
+ const widthKey = `border${side}Width`;
77
+ if (element.style[styleKey] === "double") {
78
+ const widthValue = Number.parseFloat(element.style[widthKey] ?? "");
79
+ if (!Number.isFinite(widthValue) || widthValue < 3) element.style[widthKey] = "3px";
80
+ }
81
+ }
82
+ function renderPageBorderOverlay(page, options, doc) {
83
+ const pb = options.pageBorders;
84
+ if (!pb || !pageBorderShouldRender(page.number, pb.display)) return null;
85
+ if (![
86
+ pb.top,
87
+ pb.bottom,
88
+ pb.left,
89
+ pb.right
90
+ ].some((border) => border && border.style !== "none" && border.style !== "nil")) return null;
91
+ const offsetFrom = pb.offsetFrom ?? "text";
92
+ const topOffset = pageBorderSpacePx(pb.top);
93
+ const rightOffset = pageBorderSpacePx(pb.right);
94
+ const bottomOffset = pageBorderSpacePx(pb.bottom);
95
+ const leftOffset = pageBorderSpacePx(pb.left);
96
+ const overlay = doc.createElement("div");
97
+ overlay.className = "layout-page-border";
98
+ overlay.style.position = "absolute";
99
+ overlay.style.pointerEvents = "none";
100
+ overlay.style.boxSizing = "border-box";
101
+ overlay.style.zIndex = pb.zOrder === "back" ? "0" : "20";
102
+ if (offsetFrom === "page") {
103
+ overlay.style.top = `${topOffset}px`;
104
+ overlay.style.right = `${rightOffset}px`;
105
+ overlay.style.bottom = `${bottomOffset}px`;
106
+ overlay.style.left = `${leftOffset}px`;
107
+ } else {
108
+ const topWidth = pageBorderWidthPx(pb.top);
109
+ const rightWidth = pageBorderWidthPx(pb.right);
110
+ const bottomWidth = pageBorderWidthPx(pb.bottom);
111
+ const leftWidth = pageBorderWidthPx(pb.left);
112
+ overlay.style.top = `${Math.max(0, page.margins.top - topOffset - topWidth)}px`;
113
+ overlay.style.right = `${Math.max(0, page.margins.right - rightOffset - rightWidth)}px`;
114
+ overlay.style.bottom = `${Math.max(0, page.margins.bottom - bottomOffset - bottomWidth)}px`;
115
+ overlay.style.left = `${Math.max(0, page.margins.left - leftOffset - leftWidth)}px`;
116
+ }
117
+ applyPageBorderSide(overlay, pb.top, "Top", options.theme);
118
+ applyPageBorderSide(overlay, pb.bottom, "Bottom", options.theme);
119
+ applyPageBorderSide(overlay, pb.left, "Left", options.theme);
120
+ applyPageBorderSide(overlay, pb.right, "Right", options.theme);
121
+ return overlay;
122
+ }
123
+ /**
124
+ * Refresh the page-border overlay on an existing page shell so incremental
125
+ * rerenders pick up changes to size, margins, page number, or pageBorders
126
+ * options. Removes any stale `.layout-page-border` child before re-attaching
127
+ * with the current z-order (back → first child, front → last child).
128
+ */
129
+ function syncPageBorderOverlay(pageEl, page, options, doc) {
130
+ for (const stale of Array.from(pageEl.querySelectorAll(":scope > .layout-page-border"))) stale.remove();
131
+ const overlay = renderPageBorderOverlay(page, options, doc);
132
+ if (!overlay) return;
133
+ if (options.pageBorders?.zOrder === "back") pageEl.prepend(overlay);
134
+ else pageEl.append(overlay);
135
+ }
136
+ /**
137
+ * Refresh the watermark overlay on a rendered page shell. Incremental
138
+ * rerenders replace only the body content area, so the watermark sibling
139
+ * must be reconciled separately when per-section header resolution changes.
140
+ */
141
+ function syncPageWatermarkOverlay(pageEl, page, options, doc) {
142
+ for (const stale of Array.from(pageEl.querySelectorAll(":scope > .layout-page-watermark"))) stale.remove();
143
+ const watermark = options.watermark;
144
+ if (!watermark) return;
145
+ const overlay = renderWatermarkLayer(watermark, page, doc, options.watermarkImageSrc !== void 0 ? { imageSrc: options.watermarkImageSrc } : {});
146
+ if (!overlay) return;
147
+ const contentEl = pageEl.querySelector(`:scope > .${PAGE_CLASS_NAMES.content}`);
148
+ if (contentEl) {
149
+ contentEl.before(overlay);
150
+ return;
151
+ }
152
+ pageEl.append(overlay);
153
+ }
154
+ function floatingZonesForFragment(pageWideZones, scopedZones, fragmentIndex) {
155
+ if (scopedZones.length === 0) return pageWideZones;
156
+ let activeZones;
157
+ for (const scopedZone of scopedZones) {
158
+ if (scopedZone.startsAtFragmentIndex > fragmentIndex) continue;
159
+ activeZones ??= [...pageWideZones];
160
+ activeZones.push(scopedZone.zone);
161
+ }
162
+ return activeZones ?? pageWideZones;
163
+ }
164
+ /**
165
+ * Apply content area styles to an element
166
+ */
167
+ function applyContentAreaStyles(element, page) {
168
+ const margins = page.margins;
169
+ element.style.position = "absolute";
170
+ element.style.top = `${margins.top}px`;
171
+ element.style.left = `${margins.left}px`;
172
+ element.style.right = `${margins.right}px`;
173
+ element.style.bottom = `${margins.bottom}px`;
174
+ element.style.overflow = "visible";
175
+ }
176
+ function getPositionAlignment(position) {
177
+ return position?.align ?? position?.alignment;
178
+ }
179
+ function resolveHeaderFooterFloatTop(floatImg, layout) {
180
+ const v = floatImg.position.vertical;
181
+ if (!v) return floatImg.paragraphY;
182
+ const align = getPositionAlignment(v);
183
+ const offsetPx = v.posOffset !== void 0 ? emuToPixels(v.posOffset) : void 0;
184
+ if (v.relativeTo === "page") {
185
+ if (offsetPx !== void 0) return offsetPx - layout.flowTop;
186
+ if (align === "top") return -layout.flowTop;
187
+ if (align === "bottom") return layout.pageHeight - floatImg.height - layout.flowTop;
188
+ if (align === "center") return (layout.pageHeight - floatImg.height) / 2 - layout.flowTop;
189
+ }
190
+ if (v.relativeTo === "margin") {
191
+ const marginTop = layout.margins.top;
192
+ const marginHeight = layout.pageHeight - layout.margins.top - layout.margins.bottom;
193
+ if (offsetPx !== void 0) return marginTop + offsetPx - layout.flowTop;
194
+ if (align === "top") return marginTop - layout.flowTop;
195
+ if (align === "bottom") return marginTop + marginHeight - floatImg.height - layout.flowTop;
196
+ if (align === "center") return marginTop + (marginHeight - floatImg.height) / 2 - layout.flowTop;
197
+ }
198
+ if (offsetPx !== void 0) return floatImg.paragraphY + offsetPx;
199
+ return floatImg.paragraphY;
200
+ }
201
+ /**
202
+ * Resolve the on-page position of a floating header/footer table
203
+ * (`<w:tbl><w:tblpPr ...>`). ECMA-376 §17.4.57. Returns coordinates
204
+ * relative to the HF container (which itself is positioned at the page's
205
+ * header or footer slot).
206
+ */
207
+ function resolveHeaderFooterFloatingTablePosition(floating, measure, layout, sourceY) {
208
+ const horzAnchor = floating.horzAnchor ?? "margin";
209
+ const vertAnchor = floating.vertAnchor ?? "margin";
210
+ const horzFrameWidth = horzAnchor === "page" ? layout.pageWidth : layout.contentWidth;
211
+ const horzFrameOffset = horzAnchor === "page" ? -layout.flowLeft : 0;
212
+ const vertFrameHeight = vertAnchor === "page" ? layout.pageHeight : layout.pageHeight - layout.margins.top - layout.margins.bottom;
213
+ const vertFrameOffset = vertAnchor === "page" ? -layout.flowTop : layout.margins.top - layout.flowTop;
214
+ let left = 0;
215
+ const xSpec = floating.tblpXSpec;
216
+ if (xSpec === "left" || xSpec === "inside") left = horzFrameOffset;
217
+ else if (xSpec === "right" || xSpec === "outside") left = horzFrameOffset + horzFrameWidth - measure.totalWidth;
218
+ else if (xSpec === "center") left = horzFrameOffset + (horzFrameWidth - measure.totalWidth) / 2;
219
+ else if (floating.tblpX !== void 0) left = horzFrameOffset + floating.tblpX;
220
+ let top = sourceY;
221
+ if (floating.tblpYSpec === "top") top = vertFrameOffset;
222
+ else if (floating.tblpYSpec === "bottom") top = vertFrameOffset + vertFrameHeight - measure.totalHeight;
223
+ else if (floating.tblpYSpec === "center") top = vertFrameOffset + (vertFrameHeight - measure.totalHeight) / 2;
224
+ else if (floating.tblpY !== void 0) top = vertFrameOffset + floating.tblpY;
225
+ return {
226
+ left,
227
+ top
228
+ };
229
+ }
230
+ /**
231
+ * Resolve the CSS `left` (px string) for an anchored object (image or text box)
232
+ * in a header/footer, honoring `wp:positionH` (relativeTo page/margin, align
233
+ * left/center/right, or posOffset). Shared by floating images and text boxes so
234
+ * a page-centered banner in the header lands centered like Word, not pinned to
235
+ * the left. Ported from eigenpal/docx-editor#700.
236
+ */
237
+ function resolveHeaderFooterFloatLeft(width, h, layout) {
238
+ if (!h) return "0";
239
+ let align = getPositionAlignment(h);
240
+ if (align === "inside") align = "left";
241
+ else if (align === "outside") align = "right";
242
+ if (h.relativeTo === "page") {
243
+ if (h.posOffset !== void 0) return `${emuToPixels(h.posOffset) - layout.flowLeft}px`;
244
+ if (align === "right") return `${layout.pageWidth - width - layout.flowLeft}px`;
245
+ if (align === "center") return `${(layout.pageWidth - width) / 2 - layout.flowLeft}px`;
246
+ if (align === "left") return `${-layout.flowLeft}px`;
247
+ }
248
+ if (h.posOffset !== void 0) return `${emuToPixels(h.posOffset)}px`;
249
+ if (align === "right") return `${layout.contentWidth - width}px`;
250
+ if (align === "center") return `${(layout.contentWidth - width) / 2}px`;
251
+ return "0";
252
+ }
253
+ function applyHeaderFooterFloatHorizontalPosition(img, floatImg, layout) {
254
+ img.style.left = resolveHeaderFooterFloatLeft(floatImg.width, floatImg.position.horizontal, layout);
255
+ }
256
+ /**
257
+ * Apply fragment positioning styles
258
+ * Note: Fragment x/y include page margins, but fragments are positioned
259
+ * inside the content area which already has margin offsets applied.
260
+ * So we subtract the margins to get content-area-relative positions.
261
+ */
262
+ function applyFragmentStyles(element, fragment, margins) {
263
+ element.style.position = "absolute";
264
+ element.style.left = `${fragment.x - margins.left}px`;
265
+ element.style.top = `${fragment.y - margins.top}px`;
266
+ element.style.width = `${fragment.width}px`;
267
+ if ("height" in fragment) element.style.height = `${fragment.height}px`;
268
+ }
269
+ function resolveHorizontalBand(relativeTo, geometry) {
270
+ switch (relativeTo) {
271
+ case "page": return {
272
+ baseX: -geometry.marginLeft,
273
+ bandWidth: geometry.pageWidth
274
+ };
275
+ case "leftMargin":
276
+ case "insideMargin": return {
277
+ baseX: -geometry.marginLeft,
278
+ bandWidth: geometry.marginLeft
279
+ };
280
+ case "rightMargin":
281
+ case "outsideMargin": return {
282
+ baseX: geometry.contentWidth,
283
+ bandWidth: geometry.marginRight
284
+ };
285
+ case "character": return {
286
+ baseX: 0,
287
+ bandWidth: 0
288
+ };
289
+ default: return {
290
+ baseX: 0,
291
+ bandWidth: geometry.contentWidth
292
+ };
293
+ }
294
+ }
295
+ function resolveVerticalBand(relativeTo, fragmentY, geometry) {
296
+ switch (relativeTo) {
297
+ case "page": return {
298
+ baseY: -geometry.marginTop,
299
+ bandHeight: geometry.pageHeight
300
+ };
301
+ case "topMargin": return {
302
+ baseY: -geometry.marginTop,
303
+ bandHeight: geometry.marginTop
304
+ };
305
+ case "bottomMargin": return {
306
+ baseY: geometry.contentHeight,
307
+ bandHeight: geometry.marginBottom
308
+ };
309
+ case "paragraph":
310
+ case "line": return {
311
+ baseY: fragmentY,
312
+ bandHeight: 0
313
+ };
314
+ default: return {
315
+ baseY: 0,
316
+ bandHeight: geometry.contentHeight
317
+ };
318
+ }
319
+ }
320
+ /**
321
+ * Resolve the on-page coordinates of an anchored floating image.
322
+ *
323
+ * Pure function — no DOM, no side effects — so the math is unit-testable
324
+ * without spinning up a full page render. Used by
325
+ * `extractFloatingImagesFromParagraph` for body anchors; mirrors the
326
+ * upstream painter helper introduced in eigenpal #424.
327
+ *
328
+ * The OOXML position is `posOffset` (EMUs from the relativeFrom origin)
329
+ * XOR `align` (symbolic top|center|bottom / left|center|right). When
330
+ * neither is present, the spec means "anchor at the band origin"; for
331
+ * paragraph/line that's the paragraph itself, otherwise the band origin
332
+ * picked by `relativeFrom`.
333
+ */
334
+ function resolveAnchoredImagePosition(imgRun, fragmentY, geometry) {
335
+ const position = imgRun.position;
336
+ const contentWidth = geometry.contentWidth;
337
+ let side = "left";
338
+ let x = 0;
339
+ if (position?.horizontal) {
340
+ const h = position.horizontal;
341
+ const { baseX, bandWidth } = resolveHorizontalBand(h.relativeTo, geometry);
342
+ const horizontalHasBand = h.relativeTo !== "character";
343
+ if (h.align === "right" || h.align === "outside") {
344
+ side = "right";
345
+ x = horizontalHasBand ? baseX + bandWidth - imgRun.width : 0;
346
+ } else if (h.align === "left" || h.align === "inside") {
347
+ side = "left";
348
+ x = baseX;
349
+ } else if (h.align === "center") {
350
+ side = "left";
351
+ x = horizontalHasBand ? baseX + (bandWidth - imgRun.width) / 2 : 0;
352
+ } else if (h.posOffset !== void 0) {
353
+ x = baseX + emuToPixels(h.posOffset);
354
+ side = x > contentWidth / 2 ? "right" : "left";
355
+ } else x = baseX;
356
+ } else if (imgRun.cssFloat === "right") {
357
+ side = "right";
358
+ x = contentWidth - imgRun.width;
359
+ }
360
+ let y;
361
+ if (position?.vertical) {
362
+ const v = position.vertical;
363
+ const { baseY, bandHeight } = resolveVerticalBand(v.relativeTo, fragmentY, geometry);
364
+ const verticalHasBand = v.relativeTo !== "paragraph" && v.relativeTo !== "line";
365
+ if (v.align === "top" || v.align === "inside") y = baseY;
366
+ else if (v.align === "center") y = verticalHasBand ? baseY + (bandHeight - imgRun.height) / 2 : fragmentY;
367
+ else if (v.align === "bottom" || v.align === "outside") y = verticalHasBand ? baseY + bandHeight - imgRun.height : fragmentY;
368
+ else if (v.posOffset !== void 0) y = baseY + emuToPixels(v.posOffset);
369
+ else y = verticalHasBand ? baseY : fragmentY;
370
+ } else y = fragmentY;
371
+ return {
372
+ x,
373
+ y,
374
+ side
375
+ };
376
+ }
377
+ /**
378
+ * Extract floating images from a paragraph block and determine their page-level positions.
379
+ * Returns extracted images and info for the paragraph about space reserved.
380
+ */
381
+ function extractFloatingImagesFromParagraph(block, fragmentY, geometry) {
382
+ const floatingImages = [];
383
+ for (const run of block.runs) {
384
+ if (run.kind !== "image") continue;
385
+ const imgRun = run;
386
+ if (!isFloatingImageRun(imgRun)) continue;
387
+ const distTop = imgRun.distTop ?? 0;
388
+ const distBottom = imgRun.distBottom ?? 0;
389
+ const distLeft = imgRun.distLeft ?? 12;
390
+ const distRight = imgRun.distRight ?? 12;
391
+ const { x, y, side } = resolveAnchoredImagePosition(imgRun, fragmentY, geometry);
392
+ let wrapText;
393
+ if (imgRun.cssFloat === "left") wrapText = "right";
394
+ else if (imgRun.cssFloat === "right") wrapText = "left";
395
+ floatingImages.push({
396
+ src: imgRun.src,
397
+ width: imgRun.width,
398
+ height: imgRun.height,
399
+ ...imgRun.alt !== void 0 ? { alt: imgRun.alt } : {},
400
+ ...imgRun.transform !== void 0 ? { transform: imgRun.transform } : {},
401
+ ...imgRun.opacity != null ? { opacity: imgRun.opacity } : {},
402
+ side,
403
+ x,
404
+ y,
405
+ distTop,
406
+ distBottom,
407
+ distLeft,
408
+ distRight,
409
+ ...imgRun.pmStart !== void 0 ? { pmStart: imgRun.pmStart } : {},
410
+ ...imgRun.pmEnd !== void 0 ? { pmEnd: imgRun.pmEnd } : {},
411
+ ...wrapText !== void 0 ? { wrapText } : {},
412
+ ...imgRun.wrapType !== void 0 ? { wrapType: imgRun.wrapType } : {},
413
+ affectsTextWrap: isTextWrappingFloatingImageRun(imgRun),
414
+ behindDoc: imgRun.wrapType === "behind"
415
+ });
416
+ }
417
+ return floatingImages;
418
+ }
419
+ /**
420
+ * Render floating images into a page-level layer.
421
+ *
422
+ * `layerMode === "behind"` paints below body text (used for `behindDoc`
423
+ * wrapNone images, e.g. full-page letterhead backgrounds). `"front"` paints
424
+ * above text (default for `inFront` wrapNone and side-wrapping images).
425
+ */
426
+ function renderFloatingImagesLayer(floatingImages, doc, layerMode = "front") {
427
+ const layer = doc.createElement("div");
428
+ layer.className = layerMode === "behind" ? "layout-floating-images-layer layout-floating-images-layer-behind" : "layout-floating-images-layer";
429
+ layer.style.position = "absolute";
430
+ layer.style.top = "0";
431
+ layer.style.left = "0";
432
+ layer.style.right = "0";
433
+ layer.style.bottom = "0";
434
+ layer.style.pointerEvents = "none";
435
+ if (layerMode === "front") layer.style.zIndex = "10";
436
+ for (const floatImg of floatingImages) {
437
+ const container = doc.createElement("div");
438
+ container.className = "layout-page-floating-image";
439
+ container.style.position = "absolute";
440
+ container.style.pointerEvents = "auto";
441
+ container.style.top = `${floatImg.y}px`;
442
+ container.style.left = `${floatImg.x}px`;
443
+ if (floatImg.pmStart !== void 0) container.dataset["pmStart"] = String(floatImg.pmStart);
444
+ if (floatImg.pmEnd !== void 0) container.dataset["pmEnd"] = String(floatImg.pmEnd);
445
+ const img = doc.createElement("img");
446
+ img.src = floatImg.src;
447
+ img.style.width = `${floatImg.width}px`;
448
+ img.style.height = `${floatImg.height}px`;
449
+ img.style.display = "block";
450
+ img.style.maxWidth = "none";
451
+ img.style.maxHeight = "none";
452
+ if (floatImg.alt) img.alt = floatImg.alt;
453
+ if (floatImg.transform) img.style.transform = floatImg.transform;
454
+ if (hasImageVisualAttrs(floatImg)) applyImageVisualAttrs(img, floatImg);
455
+ container.append(img);
456
+ layer.append(container);
457
+ }
458
+ return layer;
459
+ }
460
+ /**
461
+ * Render header or footer content
462
+ */
463
+ function renderHeaderFooterContent(content, context, options, layout) {
464
+ const doc = options.document ?? document;
465
+ const containerEl = doc.createElement("div");
466
+ containerEl.style.position = "relative";
467
+ const contentWidth = context.contentWidth ?? 600;
468
+ const floatingImages = [];
469
+ let cursorY = 0;
470
+ const hfContext = {
471
+ ...context,
472
+ positioning: "absolute"
473
+ };
474
+ for (let i = 0; i < content.blocks.length; i++) {
475
+ const block = content.blocks[i];
476
+ const measure = content.measures[i];
477
+ if (!block || !measure) continue;
478
+ if (block.kind === "paragraph" && measure.kind === "paragraph") {
479
+ const paragraphBlock = block;
480
+ const paragraphMeasure = measure;
481
+ const paragraphStartY = cursorY;
482
+ const inlineRuns = [];
483
+ for (const run of paragraphBlock.runs) if (run.kind === "image" && (isFloatingImageRun(run) || run.position)) floatingImages.push({
484
+ src: run.src,
485
+ width: run.width,
486
+ height: run.height,
487
+ ...run.alt !== void 0 ? { alt: run.alt } : {},
488
+ ...run.opacity != null ? { opacity: run.opacity } : {},
489
+ ...run.pmStart !== void 0 ? { pmStart: run.pmStart } : {},
490
+ ...run.pmEnd !== void 0 ? { pmEnd: run.pmEnd } : {},
491
+ paragraphY: paragraphStartY,
492
+ behindDoc: run.wrapType === "behind",
493
+ position: run.position ?? {}
494
+ });
495
+ else inlineRuns.push(run);
496
+ const inlineBlock = {
497
+ ...paragraphBlock,
498
+ runs: inlineRuns
499
+ };
500
+ const fragEl = renderParagraphFragment({
501
+ kind: "paragraph",
502
+ blockId: paragraphBlock.id,
503
+ x: 0,
504
+ y: cursorY,
505
+ width: contentWidth,
506
+ height: paragraphMeasure.totalHeight,
507
+ fromLine: 0,
508
+ toLine: paragraphMeasure.lines.length
509
+ }, inlineBlock, paragraphMeasure, hfContext, { document: doc });
510
+ const spaceBefore = paragraphBlock.attrs?.spacingExplicit?.before === true ? paragraphBlock.attrs?.spacing?.before ?? 0 : 0;
511
+ fragEl.style.position = "absolute";
512
+ fragEl.style.top = `${cursorY + spaceBefore}px`;
513
+ fragEl.style.left = "0";
514
+ fragEl.style.width = `${contentWidth}px`;
515
+ containerEl.append(fragEl);
516
+ cursorY += paragraphMeasure.totalHeight;
517
+ } else if (block.kind === "table" && measure.kind === "table") {
518
+ const fragEl = renderTableFragment({
519
+ kind: "table",
520
+ blockId: block.id,
521
+ x: 0,
522
+ y: cursorY,
523
+ width: measure.totalWidth,
524
+ height: measure.totalHeight,
525
+ fromRow: 0,
526
+ toRow: measure.rows.length,
527
+ ...block.pmStart !== void 0 ? { pmStart: block.pmStart } : {},
528
+ ...block.pmEnd !== void 0 ? { pmEnd: block.pmEnd } : {}
529
+ }, block, measure, hfContext, { document: doc });
530
+ if (block.floating) {
531
+ const { left, top } = resolveHeaderFooterFloatingTablePosition(block.floating, measure, layout, cursorY);
532
+ fragEl.style.position = "absolute";
533
+ fragEl.style.top = `${top}px`;
534
+ fragEl.style.left = `${left}px`;
535
+ containerEl.append(fragEl);
536
+ } else {
537
+ let inlineLeft = 0;
538
+ if (block.justification === "center") inlineLeft = (contentWidth - measure.totalWidth) / 2;
539
+ else if (block.justification === "right") inlineLeft = contentWidth - measure.totalWidth;
540
+ else if (block.indent) inlineLeft = block.indent;
541
+ fragEl.style.position = "absolute";
542
+ fragEl.style.top = `${cursorY}px`;
543
+ fragEl.style.left = `${inlineLeft}px`;
544
+ containerEl.append(fragEl);
545
+ cursorY += measure.totalHeight;
546
+ }
547
+ } else if (block.kind === "textBox" && measure.kind === "textBox") {
548
+ const fragEl = renderTextBoxFragment({
549
+ kind: "textBox",
550
+ blockId: block.id,
551
+ x: 0,
552
+ y: cursorY,
553
+ width: measure.width,
554
+ height: measure.height,
555
+ ...block.pmStart !== void 0 ? { pmStart: block.pmStart } : {},
556
+ ...block.pmEnd !== void 0 ? { pmEnd: block.pmEnd } : {}
557
+ }, block, measure, hfContext, { document: doc });
558
+ fragEl.style.top = `${cursorY}px`;
559
+ fragEl.style.left = resolveHeaderFooterFloatLeft(measure.width, block.position?.horizontal, layout);
560
+ if (block.wrapType === "behind") fragEl.style.zIndex = "-1";
561
+ containerEl.append(fragEl);
562
+ if (!isPositionedHeaderFooterTextBoxBlock(block)) cursorY += measure.height;
563
+ }
564
+ }
565
+ for (const floatImg of floatingImages) {
566
+ const img = doc.createElement("img");
567
+ img.src = floatImg.src;
568
+ img.width = floatImg.width;
569
+ img.height = floatImg.height;
570
+ if (floatImg.alt) img.alt = floatImg.alt;
571
+ img.classList.add("layout-run", "layout-run-image");
572
+ if (floatImg.pmStart !== void 0) img.dataset["pmStart"] = String(floatImg.pmStart);
573
+ if (floatImg.pmEnd !== void 0) img.dataset["pmEnd"] = String(floatImg.pmEnd);
574
+ img.style.position = "absolute";
575
+ img.style.display = "block";
576
+ img.style.width = `${floatImg.width}px`;
577
+ img.style.height = `${floatImg.height}px`;
578
+ img.style.maxWidth = "none";
579
+ img.style.maxHeight = "none";
580
+ if (floatImg.behindDoc) img.style.zIndex = "-1";
581
+ if (hasImageVisualAttrs(floatImg)) applyImageVisualAttrs(img, floatImg);
582
+ applyHeaderFooterFloatHorizontalPosition(img, floatImg, layout);
583
+ img.style.top = `${resolveHeaderFooterFloatTop(floatImg, layout)}px`;
584
+ containerEl.append(img);
585
+ }
586
+ return containerEl;
587
+ }
588
+ function isPositionedHeaderFooterTextBoxBlock(block) {
589
+ if (block.displayMode === "block" || block.displayMode === "inline") return false;
590
+ return isFloatingTextBoxBlock(block);
591
+ }
592
+ /**
593
+ * Calculate the painter's actual footnote-area height in pixels:
594
+ * separator slot + per-footnote content (or fallback line) + per-footnote
595
+ * `marginBottom` spacing the painter applies in `renderFootnoteArea`. Used
596
+ * to clamp the paginator's reservation if it under-estimated, so dense
597
+ * stacks never overflow past the page bottom. Mirrors the upstream helper
598
+ * from eigenpal/docx-editor#485, extended for folio's fallback rendering
599
+ * and any wrapper margin so the helper matches the painted stack.
600
+ */
601
+ function calculateFootnoteAreaRenderHeight(footnotes) {
602
+ let height = 12;
603
+ for (const fn of footnotes) {
604
+ const entryHeight = fn.content ? fn.content.height : 13;
605
+ height += entryHeight + 0;
606
+ }
607
+ return height;
608
+ }
609
+ /**
610
+ * Render the footnote area at the bottom of a page.
611
+ * Includes a separator line (33% width) and footnote entries.
612
+ */
613
+ function renderFootnoteArea(footnotes, contentWidth, doc, context) {
614
+ const container = doc.createElement("div");
615
+ container.className = "layout-footnote-area";
616
+ container.style.width = `${contentWidth}px`;
617
+ const separator = doc.createElement("div");
618
+ const separatorRuleHeight = .5;
619
+ const separatorMargin = (12 - separatorRuleHeight) / 2;
620
+ separator.style.width = "33%";
621
+ separator.style.height = `${separatorRuleHeight}px`;
622
+ separator.style.backgroundColor = "var(--doc-canvas-text, #000)";
623
+ separator.style.marginTop = `${separatorMargin}px`;
624
+ separator.style.marginBottom = `${separatorMargin}px`;
625
+ container.append(separator);
626
+ for (const fn of footnotes) {
627
+ const fnEl = doc.createElement("div");
628
+ fnEl.style.marginBottom = `0px`;
629
+ fnEl.style.color = "var(--doc-canvas-text, #000)";
630
+ if (fn.content) {
631
+ const contentEl = renderFootnoteContent(fn, contentWidth, doc, context);
632
+ fnEl.append(contentEl);
633
+ } else {
634
+ fnEl.style.fontSize = "10px";
635
+ fnEl.style.lineHeight = `${13 / 10}`;
636
+ const sup = doc.createElement("sup");
637
+ sup.textContent = fn.displayNumber;
638
+ sup.style.fontSize = "7px";
639
+ sup.style.marginRight = "2px";
640
+ fnEl.append(sup);
641
+ const textNode = doc.createTextNode(` ${fn.text ?? ""}`);
642
+ fnEl.append(textNode);
643
+ }
644
+ container.append(fnEl);
645
+ }
646
+ return container;
647
+ }
648
+ function renderFootnoteContent(footnote, contentWidth, doc, context) {
649
+ const content = footnote.content;
650
+ if (!content) panic("Missing structured footnote content");
651
+ const wrapper = doc.createElement("div");
652
+ wrapper.className = "layout-footnote-content";
653
+ wrapper.style.position = "relative";
654
+ wrapper.style.width = `${contentWidth}px`;
655
+ wrapper.style.height = `${content.height}px`;
656
+ const renderContext = {
657
+ pageNumber: context?.pageNumber ?? 0,
658
+ totalPages: context?.totalPages ?? 0,
659
+ section: context?.section ?? "body",
660
+ contentWidth
661
+ };
662
+ let y = 0;
663
+ for (let index = 0; index < content.blocks.length; index++) {
664
+ const block = content.blocks[index];
665
+ const measure = content.measures[index];
666
+ if (!block || !measure) continue;
667
+ const blockEl = renderFootnoteBlock(block, measure, contentWidth, y, renderContext, doc);
668
+ if (!blockEl) continue;
669
+ wrapper.append(blockEl);
670
+ y += getFootnoteMeasureHeight(measure);
671
+ }
672
+ return wrapper;
673
+ }
674
+ function renderFootnoteBlock(block, measure, contentWidth, y, context, doc) {
675
+ const renderBlock = stripFootnotePmAnchors(block);
676
+ if (renderBlock.kind === "paragraph" && measure.kind === "paragraph") {
677
+ const element = renderParagraphFragment({
678
+ kind: "paragraph",
679
+ blockId: renderBlock.id,
680
+ x: 0,
681
+ y,
682
+ width: contentWidth,
683
+ height: measure.totalHeight,
684
+ fromLine: 0,
685
+ toLine: measure.lines.length
686
+ }, renderBlock, measure, context, { document: doc });
687
+ positionFootnoteBlock(element, y, contentWidth, measure.totalHeight);
688
+ return element;
689
+ }
690
+ if (renderBlock.kind === "table" && measure.kind === "table") {
691
+ const element = renderTableFragment({
692
+ kind: "table",
693
+ blockId: renderBlock.id,
694
+ x: 0,
695
+ y,
696
+ width: measure.totalWidth,
697
+ height: measure.totalHeight,
698
+ fromRow: 0,
699
+ toRow: renderBlock.rows.length
700
+ }, renderBlock, measure, context, { document: doc });
701
+ positionFootnoteBlock(element, y, measure.totalWidth, measure.totalHeight);
702
+ return element;
703
+ }
704
+ if (renderBlock.kind === "image" && measure.kind === "image") {
705
+ const element = renderImageFragment({
706
+ kind: "image",
707
+ blockId: renderBlock.id,
708
+ x: 0,
709
+ y,
710
+ width: measure.width,
711
+ height: measure.height
712
+ }, renderBlock, measure, context, { document: doc });
713
+ positionFootnoteBlock(element, y, measure.width, measure.height);
714
+ return element;
715
+ }
716
+ if (renderBlock.kind === "textBox" && measure.kind === "textBox") {
717
+ const element = renderTextBoxFragment({
718
+ kind: "textBox",
719
+ blockId: renderBlock.id,
720
+ x: 0,
721
+ y,
722
+ width: measure.width,
723
+ height: measure.height
724
+ }, renderBlock, measure, context, { document: doc });
725
+ positionFootnoteBlock(element, y, measure.width, measure.height);
726
+ return element;
727
+ }
728
+ return null;
729
+ }
730
+ function stripFootnotePmAnchors(block) {
731
+ switch (block.kind) {
732
+ case "paragraph": return stripFootnoteParagraphPmAnchors(block);
733
+ case "table": {
734
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...table } = block;
735
+ return {
736
+ ...table,
737
+ rows: table.rows.map(stripFootnoteTableRowPmAnchors)
738
+ };
739
+ }
740
+ case "image": {
741
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...image } = block;
742
+ return image;
743
+ }
744
+ case "textBox": {
745
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...textBox } = block;
746
+ return {
747
+ ...textBox,
748
+ content: textBox.content.map(stripFootnoteParagraphPmAnchors)
749
+ };
750
+ }
751
+ case "pageBreak":
752
+ case "columnBreak": {
753
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...breakBlock } = block;
754
+ return breakBlock;
755
+ }
756
+ case "sectionBreak": return block;
757
+ default: return block;
758
+ }
759
+ }
760
+ function stripFootnoteTableRowPmAnchors(row) {
761
+ return {
762
+ ...row,
763
+ cells: row.cells.map(stripFootnoteTableCellPmAnchors)
764
+ };
765
+ }
766
+ function stripFootnoteTableCellPmAnchors(cell) {
767
+ return {
768
+ ...cell,
769
+ blocks: cell.blocks.map(stripFootnotePmAnchors)
770
+ };
771
+ }
772
+ function stripFootnoteParagraphPmAnchors(block) {
773
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...paragraph } = block;
774
+ return {
775
+ ...paragraph,
776
+ runs: paragraph.runs.map(stripFootnoteRunPmAnchors)
777
+ };
778
+ }
779
+ function stripFootnoteRunPmAnchors(run) {
780
+ switch (run.kind) {
781
+ case "text": {
782
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...textRun } = run;
783
+ return textRun;
784
+ }
785
+ case "tab": {
786
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...tabRun } = run;
787
+ return tabRun;
788
+ }
789
+ case "image": {
790
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...imageRun } = run;
791
+ return imageRun;
792
+ }
793
+ case "lineBreak": {
794
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...lineBreakRun } = run;
795
+ return lineBreakRun;
796
+ }
797
+ case "field": {
798
+ const { pmStart: _pmStart, pmEnd: _pmEnd, ...fieldRun } = run;
799
+ return fieldRun;
800
+ }
801
+ default: return run;
802
+ }
803
+ }
804
+ function positionFootnoteBlock(element, top, width, height) {
805
+ element.style.position = "absolute";
806
+ element.style.left = "0";
807
+ element.style.top = `${top}px`;
808
+ element.style.width = `${width}px`;
809
+ element.style.height = `${height}px`;
810
+ }
811
+ function getFootnoteMeasureHeight(measure) {
812
+ if (measure.kind === "paragraph" || measure.kind === "table") return measure.totalHeight;
813
+ if (measure.kind === "image" || measure.kind === "textBox") return measure.height;
814
+ return 0;
815
+ }
816
+ /**
817
+ * Render a single page to DOM
818
+ *
819
+ * @param page - The page to render
820
+ * @param context - Rendering context
821
+ * @param options - Rendering options
822
+ * @returns The page DOM element
823
+ */
824
+ function renderPage(page, context, options = {}) {
825
+ const doc = options.document ?? document;
826
+ const pageEl = doc.createElement("div");
827
+ pageEl.className = options.pageClassName ?? PAGE_CLASS_NAMES.page;
828
+ pageEl.dataset["pageNumber"] = String(page.number);
829
+ applyPageStyles(pageEl, page.size.w, page.size.h, options);
830
+ const pageBorderEl = renderPageBorderOverlay(page, options, doc);
831
+ if (pageBorderEl && options.pageBorders?.zOrder === "back") pageEl.append(pageBorderEl);
832
+ if (options.watermark) {
833
+ const watermarkEl = renderWatermarkLayer(options.watermark, page, doc, options.watermarkImageSrc !== void 0 ? { imageSrc: options.watermarkImageSrc } : {});
834
+ if (watermarkEl) pageEl.append(watermarkEl);
835
+ }
836
+ const contentEl = doc.createElement("div");
837
+ contentEl.className = PAGE_CLASS_NAMES.content;
838
+ applyContentAreaStyles(contentEl, page);
839
+ const contentWidth = page.size.w - page.margins.left - page.margins.right;
840
+ const allFloatingImages = [];
841
+ const floatingRects = [];
842
+ const scopedFloatingRects = [];
843
+ const pageGeometry = {
844
+ pageWidth: page.size.w,
845
+ pageHeight: page.size.h,
846
+ marginLeft: page.margins.left,
847
+ marginTop: page.margins.top,
848
+ marginRight: page.margins.right,
849
+ marginBottom: page.margins.bottom,
850
+ contentWidth,
851
+ contentHeight: page.size.h - page.margins.top - page.margins.bottom
852
+ };
853
+ for (const fragment of page.fragments) if (fragment.kind === "paragraph" && options.blockLookup) {
854
+ const blockData = options.blockLookup.get(String(fragment.blockId));
855
+ if (blockData?.block.kind === "paragraph") {
856
+ const paragraphBlock = blockData.block;
857
+ const extracted = extractFloatingImagesFromParagraph(paragraphBlock, fragment.y - page.margins.top, pageGeometry);
858
+ allFloatingImages.push(...extracted);
859
+ }
860
+ }
861
+ for (const img of allFloatingImages) {
862
+ if (!img.affectsTextWrap) continue;
863
+ floatingRects.push({
864
+ side: img.side,
865
+ x: img.x,
866
+ y: img.y,
867
+ width: img.width,
868
+ height: img.height,
869
+ distTop: img.distTop,
870
+ distBottom: img.distBottom,
871
+ distLeft: img.distLeft,
872
+ distRight: img.distRight,
873
+ ...img.wrapText !== void 0 ? { wrapText: img.wrapText } : {},
874
+ ...img.wrapType !== void 0 ? { wrapType: img.wrapType } : {}
875
+ });
876
+ }
877
+ if (options.blockLookup) for (const fragment of page.fragments) {
878
+ if (fragment.kind !== "table") continue;
879
+ const blockData = options.blockLookup.get(String(fragment.blockId));
880
+ if (blockData?.block.kind !== "table") continue;
881
+ const floating = blockData.block.floating;
882
+ if (!floating) continue;
883
+ const contentX = fragment.x - page.margins.left;
884
+ const contentY = fragment.y - page.margins.top;
885
+ const distTop = floating.topFromText ?? 0;
886
+ const distBottom = floating.bottomFromText ?? 0;
887
+ const distLeft = floating.leftFromText ?? 12;
888
+ const distRight = floating.rightFromText ?? 12;
889
+ const side = contentX < contentWidth / 2 ? "left" : "right";
890
+ floatingRects.push({
891
+ side,
892
+ x: contentX,
893
+ y: contentY,
894
+ width: fragment.width,
895
+ height: fragment.height,
896
+ distTop,
897
+ distBottom,
898
+ distLeft,
899
+ distRight
900
+ });
901
+ }
902
+ if (options.blockLookup) for (let fragmentIndex = 0; fragmentIndex < page.fragments.length; fragmentIndex++) {
903
+ const fragment = page.fragments[fragmentIndex];
904
+ if (fragment.kind !== "textBox") continue;
905
+ const blockData = options.blockLookup.get(String(fragment.blockId));
906
+ if (blockData?.block.kind !== "textBox") continue;
907
+ const textBoxBlock = blockData.block;
908
+ if (!isFloatingTextBoxBlock(textBoxBlock)) continue;
909
+ const reservesBand = floatingTextBoxReservesBand(textBoxBlock);
910
+ if (!reservesBand && !floatingTextBoxWrapsText(textBoxBlock)) continue;
911
+ const contentX = fragment.x - page.margins.left;
912
+ const contentY = fragment.y - page.margins.top;
913
+ const distTop = textBoxBlock.distTop ?? 0;
914
+ const distBottom = textBoxBlock.distBottom ?? 0;
915
+ const distLeft = textBoxBlock.distLeft ?? 12;
916
+ const distRight = textBoxBlock.distRight ?? 12;
917
+ let side = contentX < contentWidth / 2 ? "left" : "right";
918
+ if (textBoxBlock.cssFloat === "left") side = "left";
919
+ else if (textBoxBlock.cssFloat === "right") side = "right";
920
+ const rect = {
921
+ side,
922
+ x: contentX,
923
+ y: contentY,
924
+ width: fragment.width,
925
+ height: fragment.height,
926
+ distTop,
927
+ distBottom,
928
+ distLeft,
929
+ distRight
930
+ };
931
+ if (textBoxBlock.wrapText !== void 0) rect.wrapText = textBoxBlock.wrapText;
932
+ if (textBoxBlock.wrapType !== void 0) rect.wrapType = textBoxBlock.wrapType;
933
+ if (reservesBand) scopedFloatingRects.push({
934
+ startsAtFragmentIndex: fragmentIndex,
935
+ rect
936
+ });
937
+ else floatingRects.push(rect);
938
+ }
939
+ const floatingZones = floatingRects.length > 0 ? rectsToFloatingZones(floatingRects, contentWidth) : [];
940
+ const scopedFloatingZones = scopedFloatingRects.flatMap(({ startsAtFragmentIndex, rect }) => rectsToFloatingZones([rect], contentWidth).map((zone) => ({
941
+ startsAtFragmentIndex,
942
+ zone
943
+ })));
944
+ const behindFloatingImages = allFloatingImages.filter((img) => img.behindDoc);
945
+ const frontFloatingImages = allFloatingImages.filter((img) => !img.behindDoc);
946
+ if (behindFloatingImages.length > 0) {
947
+ const behindLayer = renderFloatingImagesLayer(behindFloatingImages, doc, "behind");
948
+ contentEl.append(behindLayer);
949
+ }
950
+ const getParaBorders = (frag) => {
951
+ if (frag.kind !== "paragraph" || !options.blockLookup || !frag.blockId) return;
952
+ const blockData = options.blockLookup.get(String(frag.blockId));
953
+ if (blockData?.block.kind === "paragraph") return blockData.block.attrs?.borders;
954
+ };
955
+ let prevParagraphBorders;
956
+ const renderedInlineImageKeysByBlock = /* @__PURE__ */ new Map();
957
+ for (let i = 0; i < page.fragments.length; i++) {
958
+ const fragment = page.fragments[i];
959
+ let fragmentEl;
960
+ const fragmentContext = {
961
+ ...context,
962
+ section: "body",
963
+ contentWidth
964
+ };
965
+ const fragmentContentY = fragment.y - page.margins.top;
966
+ if (options.blockLookup && fragment.blockId) {
967
+ const blockData = options.blockLookup.get(String(fragment.blockId));
968
+ if (fragment.kind === "paragraph" && blockData?.block.kind === "paragraph" && blockData.measure.kind === "paragraph") {
969
+ const paragraphBlock = blockData.block;
970
+ const nextBorders = i + 1 < page.fragments.length ? getParaBorders(page.fragments[i + 1]) : void 0;
971
+ const blockKey = String(fragment.blockId);
972
+ let renderedInlineImageKeys = renderedInlineImageKeysByBlock.get(blockKey);
973
+ if (!renderedInlineImageKeys) {
974
+ renderedInlineImageKeys = /* @__PURE__ */ new Set();
975
+ renderedInlineImageKeysByBlock.set(blockKey, renderedInlineImageKeys);
976
+ }
977
+ let paragraphMeasure = blockData.measure;
978
+ const fragmentFloatingZones = floatingZonesForFragment(floatingZones, scopedFloatingZones, i);
979
+ if (fragmentFloatingZones.length > 0) paragraphMeasure = measureParagraph(paragraphBlock, contentWidth, {
980
+ floatingZones: fragmentFloatingZones,
981
+ paragraphYOffset: fragmentContentY
982
+ });
983
+ fragmentEl = renderParagraphFragment(fragment, paragraphBlock, paragraphMeasure, fragmentContext, {
984
+ document: doc,
985
+ fragmentContentY,
986
+ ...prevParagraphBorders !== void 0 ? { prevBorders: prevParagraphBorders } : {},
987
+ ...nextBorders !== void 0 ? { nextBorders } : {},
988
+ renderedInlineImageKeys
989
+ });
990
+ prevParagraphBorders = paragraphBlock.attrs?.borders;
991
+ } else if (fragment.kind === "table" && blockData?.block.kind === "table" && blockData.measure.kind === "table") {
992
+ fragmentEl = renderTableFragment(fragment, blockData.block, blockData.measure, fragmentContext, { document: doc });
993
+ prevParagraphBorders = void 0;
994
+ } else if (fragment.kind === "image" && blockData?.block.kind === "image" && blockData.measure.kind === "image") {
995
+ fragmentEl = renderImageFragment(fragment, blockData.block, blockData.measure, fragmentContext, { document: doc });
996
+ prevParagraphBorders = void 0;
997
+ } else if (fragment.kind === "textBox" && blockData?.block.kind === "textBox" && blockData.measure.kind === "textBox") {
998
+ fragmentEl = renderTextBoxFragment(fragment, blockData.block, blockData.measure, fragmentContext, { document: doc });
999
+ prevParagraphBorders = void 0;
1000
+ } else {
1001
+ fragmentEl = renderFragment(fragment, fragmentContext, { document: doc });
1002
+ prevParagraphBorders = void 0;
1003
+ }
1004
+ } else {
1005
+ fragmentEl = renderFragment(fragment, fragmentContext, { document: doc });
1006
+ prevParagraphBorders = void 0;
1007
+ }
1008
+ applyFragmentStyles(fragmentEl, fragment, {
1009
+ left: page.margins.left,
1010
+ top: page.margins.top
1011
+ });
1012
+ contentEl.append(fragmentEl);
1013
+ }
1014
+ if (frontFloatingImages.length > 0) {
1015
+ const frontLayer = renderFloatingImagesLayer(frontFloatingImages, doc, "front");
1016
+ contentEl.append(frontLayer);
1017
+ }
1018
+ if (page.columns && page.columns.separator && page.columns.count > 1) {
1019
+ const colCount = page.columns.count;
1020
+ const colGap = page.columns.gap;
1021
+ const colWidth = (contentWidth - (colCount - 1) * colGap) / colCount;
1022
+ const contentHeight = page.size.h - page.margins.top - page.margins.bottom;
1023
+ for (let col = 0; col < colCount - 1; col++) {
1024
+ const lineX = (col + 1) * colWidth + col * colGap + colGap / 2;
1025
+ const line = doc.createElement("div");
1026
+ line.style.position = "absolute";
1027
+ line.style.left = `${lineX}px`;
1028
+ line.style.top = "0";
1029
+ line.style.height = `${contentHeight}px`;
1030
+ line.style.width = "0.5px";
1031
+ line.style.backgroundColor = "var(--doc-canvas-text, #000)";
1032
+ line.style.pointerEvents = "none";
1033
+ contentEl.append(line);
1034
+ }
1035
+ }
1036
+ if (options.footnoteArea && options.footnoteArea.length > 0) {
1037
+ const fnAreaEl = renderFootnoteArea(options.footnoteArea, contentWidth, doc, context);
1038
+ fnAreaEl.style.position = "absolute";
1039
+ const reservedHeight = Math.max(page.footnoteReservedHeight ?? 0, calculateFootnoteAreaRenderHeight(options.footnoteArea));
1040
+ const contentAreaBottom = page.size.h - page.margins.bottom - page.margins.top;
1041
+ fnAreaEl.style.top = `${Math.max(-page.margins.top, contentAreaBottom - reservedHeight)}px`;
1042
+ fnAreaEl.style.left = "0";
1043
+ fnAreaEl.style.right = "0";
1044
+ contentEl.append(fnAreaEl);
1045
+ }
1046
+ pageEl.append(contentEl);
1047
+ {
1048
+ const headerDistance = options.headerDistance ?? page.margins.header ?? 48;
1049
+ const headerContentWidth = page.size.w - page.margins.left - page.margins.right;
1050
+ const availableHeaderHeight = Math.max(page.margins.top - headerDistance, 48);
1051
+ const headerVisualTop = options.headerContent?.visualTop ?? 0;
1052
+ const headerVisualBottom = options.headerContent?.visualBottom ?? options.headerContent?.height ?? 0;
1053
+ const headerFlowHeight = options.headerContent?.height ?? 0;
1054
+ const interactiveHeaderHeight = Math.max(headerFlowHeight - Math.min(0, headerVisualTop), 24);
1055
+ const headerOverflows = headerVisualBottom > availableHeaderHeight;
1056
+ const headerContentFitsBox = headerVisualBottom - headerVisualTop <= interactiveHeaderHeight;
1057
+ const headerEl = doc.createElement("div");
1058
+ headerEl.className = PAGE_CLASS_NAMES.header;
1059
+ if (options.headerContent?.rId) headerEl.dataset["rid"] = options.headerContent.rId;
1060
+ headerEl.style.position = "absolute";
1061
+ headerEl.style.top = `${headerDistance + headerVisualTop}px`;
1062
+ headerEl.style.left = `${page.margins.left}px`;
1063
+ headerEl.style.right = `${page.margins.right}px`;
1064
+ headerEl.style.width = `${headerContentWidth}px`;
1065
+ headerEl.style.height = `${interactiveHeaderHeight}px`;
1066
+ headerEl.style.minHeight = `${interactiveHeaderHeight}px`;
1067
+ headerEl.style.opacity = "0.62";
1068
+ let shouldClipHeader = !headerOverflows && headerContentFitsBox;
1069
+ if (options.headerContent && options.headerContent.blocks.length > 0) {
1070
+ const headerContentEl = renderHeaderFooterContent(options.headerContent, {
1071
+ ...context,
1072
+ section: "header",
1073
+ contentWidth: headerContentWidth
1074
+ }, options, {
1075
+ flowTop: headerDistance,
1076
+ flowLeft: page.margins.left,
1077
+ contentWidth: headerContentWidth,
1078
+ pageWidth: page.size.w,
1079
+ pageHeight: page.size.h,
1080
+ margins: page.margins
1081
+ });
1082
+ headerContentEl.style.top = `${-headerVisualTop}px`;
1083
+ if (headerContentEl.querySelector("img")) shouldClipHeader = false;
1084
+ headerEl.append(headerContentEl);
1085
+ }
1086
+ if (shouldClipHeader) {
1087
+ headerEl.style.maxHeight = `${availableHeaderHeight}px`;
1088
+ headerEl.style.overflow = "hidden";
1089
+ }
1090
+ pageEl.append(headerEl);
1091
+ moveBehindHeaderFooterElementsToPage(headerEl, pageEl, headerDistance, page.margins.left);
1092
+ }
1093
+ {
1094
+ const footerDistance = options.footerDistance ?? page.margins.footer ?? 48;
1095
+ const footerContentWidth = page.size.w - page.margins.left - page.margins.right;
1096
+ const availableFooterHeight = Math.max(page.margins.bottom - footerDistance, 48);
1097
+ const footerFlowHeight = options.footerContent?.height ?? 0;
1098
+ const footerVisualTop = options.footerContent?.visualTop ?? 0;
1099
+ const footerVisualBottom = options.footerContent?.visualBottom ?? footerFlowHeight;
1100
+ const footerOverflows = Math.max(footerVisualBottom - footerVisualTop, 24) > availableFooterHeight;
1101
+ const interactiveFooterHeight = Math.max(footerFlowHeight, 24);
1102
+ const footerNaturalTop = page.size.h - footerDistance - footerFlowHeight;
1103
+ const footerEl = doc.createElement("div");
1104
+ footerEl.className = PAGE_CLASS_NAMES.footer;
1105
+ if (options.footerContent?.rId) footerEl.dataset["rid"] = options.footerContent.rId;
1106
+ footerEl.style.position = "absolute";
1107
+ footerEl.style.top = `${footerNaturalTop}px`;
1108
+ footerEl.style.left = `${page.margins.left}px`;
1109
+ footerEl.style.right = `${page.margins.right}px`;
1110
+ footerEl.style.width = `${footerContentWidth}px`;
1111
+ footerEl.style.height = `${interactiveFooterHeight}px`;
1112
+ footerEl.style.minHeight = `${interactiveFooterHeight}px`;
1113
+ footerEl.style.opacity = "0.62";
1114
+ const footerContentFitsBox = footerVisualBottom - footerVisualTop <= interactiveFooterHeight;
1115
+ let shouldClipFooter = !footerOverflows && footerContentFitsBox;
1116
+ if (options.footerContent && options.footerContent.blocks.length > 0) {
1117
+ const footerContentEl = renderHeaderFooterContent(options.footerContent, {
1118
+ ...context,
1119
+ section: "footer",
1120
+ contentWidth: footerContentWidth
1121
+ }, options, {
1122
+ flowTop: footerNaturalTop,
1123
+ flowLeft: page.margins.left,
1124
+ contentWidth: footerContentWidth,
1125
+ pageWidth: page.size.w,
1126
+ pageHeight: page.size.h,
1127
+ margins: page.margins
1128
+ });
1129
+ footerContentEl.style.top = "0px";
1130
+ if (footerContentEl.querySelector("img")) shouldClipFooter = false;
1131
+ footerEl.append(footerContentEl);
1132
+ }
1133
+ if (shouldClipFooter) {
1134
+ footerEl.style.maxHeight = `${availableFooterHeight}px`;
1135
+ footerEl.style.overflow = "hidden";
1136
+ }
1137
+ pageEl.append(footerEl);
1138
+ moveBehindHeaderFooterElementsToPage(footerEl, pageEl, footerNaturalTop, page.margins.left);
1139
+ }
1140
+ if (pageBorderEl && options.pageBorders?.zOrder !== "back") pageEl.append(pageBorderEl);
1141
+ return pageEl;
1142
+ }
1143
+ function moveBehindHeaderFooterElementsToPage(slotEl, pageEl, contentTop, contentLeft) {
1144
+ const slotKind = slotEl.className.split(" ").includes(PAGE_CLASS_NAMES.header) ? "header" : "footer";
1145
+ const slotRId = slotEl.dataset["rid"];
1146
+ for (const element of Array.from(slotEl.querySelectorAll("img[style*=\"z-index\"], .layout-textbox[style*=\"z-index\"]"))) {
1147
+ if (element.style.zIndex !== "-1") continue;
1148
+ const currentTop = Number.parseFloat(element.style.top) || 0;
1149
+ const currentLeft = Number.parseFloat(element.style.left) || 0;
1150
+ element.style.top = `${currentTop + contentTop}px`;
1151
+ element.style.left = `${currentLeft + contentLeft}px`;
1152
+ if (slotRId) {
1153
+ element.dataset["hfSlotKind"] = slotKind;
1154
+ element.dataset["hfRid"] = slotRId;
1155
+ }
1156
+ element.style.zIndex = "0";
1157
+ pageEl.prepend(element);
1158
+ }
1159
+ }
1160
+ function applySectionHeaderFooterOptions(page, pageOptions, options) {
1161
+ const refs = page.headerFooterRefs;
1162
+ if (!refs) return false;
1163
+ const isFirstSectionPage = page.sectionPageNumber === 1;
1164
+ const useFirst = refs.titlePg === true && isFirstSectionPage;
1165
+ const useEven = (page.sectionPageNumber ?? page.number) % 2 === 0;
1166
+ const headerRId = (() => {
1167
+ if (useFirst) return refs.headerFirst;
1168
+ if (useEven && refs.headerEven) return refs.headerEven;
1169
+ return refs.headerDefault;
1170
+ })();
1171
+ const footerRId = (() => {
1172
+ if (useFirst) return refs.footerFirst;
1173
+ if (useEven && refs.footerEven) return refs.footerEven;
1174
+ return refs.footerDefault;
1175
+ })();
1176
+ if (headerRId) {
1177
+ const content = options.headerContentByRId?.get(headerRId);
1178
+ if (content) pageOptions.headerContent = content;
1179
+ else delete pageOptions.headerContent;
1180
+ } else delete pageOptions.headerContent;
1181
+ if (footerRId) {
1182
+ const content = options.footerContentByRId?.get(footerRId);
1183
+ if (content) pageOptions.footerContent = content;
1184
+ else delete pageOptions.footerContent;
1185
+ } else delete pageOptions.footerContent;
1186
+ const watermarkByRId = options.watermarkByHeaderRId;
1187
+ if (watermarkByRId) {
1188
+ const pageWatermark = headerRId ? watermarkByRId.get(headerRId) : void 0;
1189
+ if (pageWatermark) pageOptions.watermark = pageWatermark;
1190
+ else delete pageOptions.watermark;
1191
+ }
1192
+ return true;
1193
+ }
1194
+ /** SECTIONPAGES context fragment for `page`: the page count of its section, or
1195
+ * nothing when section counts were not supplied (field then falls back). */
1196
+ function sectionPagesContext(page, counts) {
1197
+ if (!counts) return {};
1198
+ const value = counts.get(page.sectionIndex ?? 0);
1199
+ return value === void 0 ? {} : { sectionPages: value };
1200
+ }
1201
+ /**
1202
+ * Build a RenderContext and resolved page options (with footnotes) for a page.
1203
+ * Centralises logic shared by populatePageShell, repopulatePageContent, and the eager render path.
1204
+ */
1205
+ function buildPageRenderArgs(page, totalPages, options) {
1206
+ const context = {
1207
+ pageNumber: page.number,
1208
+ totalPages,
1209
+ section: "body",
1210
+ ...options.bookmarkPages ? { bookmarkPages: options.bookmarkPages } : {},
1211
+ ...options.bookmarkText ? { bookmarkText: options.bookmarkText } : {},
1212
+ ...options.seqValues ? { seqValues: options.seqValues } : {},
1213
+ ...sectionPagesContext(page, options.sectionPageCounts)
1214
+ };
1215
+ const pageOptions = { ...options };
1216
+ if (!applySectionHeaderFooterOptions(page, pageOptions, options) && options.titlePg && page.number === 1) {
1217
+ if (options.firstPageHeaderContent !== void 0) pageOptions.headerContent = options.firstPageHeaderContent;
1218
+ else delete pageOptions.headerContent;
1219
+ if (options.firstPageFooterContent !== void 0) pageOptions.footerContent = options.firstPageFooterContent;
1220
+ else delete pageOptions.footerContent;
1221
+ }
1222
+ if (options.footnotesByPage) {
1223
+ const fns = options.footnotesByPage.get(page.number);
1224
+ if (fns && fns.length > 0) pageOptions.footnoteArea = fns;
1225
+ }
1226
+ return {
1227
+ context,
1228
+ pageOptions
1229
+ };
1230
+ }
1231
+ /**
1232
+ * Compute a fingerprint string for a page that changes when its content changes.
1233
+ * Used to detect which pages need re-rendering on incremental updates.
1234
+ */
1235
+ function computePageFingerprint(page, blockLookup) {
1236
+ return computePageFingerprintInternal(page, blockLookup, { includePmPositions: true });
1237
+ }
1238
+ function computePageRenderFingerprint(page, blockLookup) {
1239
+ return computePageFingerprintInternal(page, blockLookup, { includePmPositions: false });
1240
+ }
1241
+ function computePageFingerprintInternal(page, blockLookup, options) {
1242
+ const parts = [];
1243
+ parts.push(`s:${page.size.w},${page.size.h}`);
1244
+ parts.push(`m:${page.margins.top},${page.margins.right},${page.margins.bottom},${page.margins.left}`);
1245
+ parts.push(`n:${page.number}`);
1246
+ if (page.sectionIndex !== void 0) parts.push(`si:${page.sectionIndex}`);
1247
+ if (page.sectionPageNumber !== void 0) parts.push(`sp:${page.sectionPageNumber}`);
1248
+ if (page.headerFooterRefs) parts.push(`hf:${JSON.stringify(page.headerFooterRefs)}`);
1249
+ if (page.footnoteReservedHeight) parts.push(`fn:${page.footnoteReservedHeight}`);
1250
+ for (const frag of page.fragments) {
1251
+ let fp = `${frag.kind}:${frag.blockId},${frag.x},${frag.y},${frag.width},${frag.height}`;
1252
+ if (options.includePmPositions && frag.pmStart !== void 0) fp += `,ps:${frag.pmStart}`;
1253
+ if (options.includePmPositions && frag.pmEnd !== void 0) fp += `,pe:${frag.pmEnd}`;
1254
+ if (frag.kind === "paragraph") fp += `,fl:${frag.fromLine},tl:${frag.toLine}`;
1255
+ else if (frag.kind === "table") {
1256
+ fp += `,fr:${frag.fromRow},tr:${frag.toRow}`;
1257
+ if (frag.headerRowCount !== void 0) fp += `,hr:${frag.headerRowCount}`;
1258
+ if (frag.topClip !== void 0) fp += `,tc:${frag.topClip}`;
1259
+ if (frag.bottomClip !== void 0) fp += `,bc:${frag.bottomClip}`;
1260
+ if (frag.continuesFromPrev) fp += ",cfp";
1261
+ if (frag.continuesOnNext) fp += ",con";
1262
+ }
1263
+ if (blockLookup) {
1264
+ const block = blockLookup.get(String(frag.blockId))?.block;
1265
+ const annotationFingerprint = block ? computeAnnotationFingerprint(block, options.includePmPositions) : "";
1266
+ if (annotationFingerprint) fp += `,ann:${annotationFingerprint}`;
1267
+ const contentFingerprint = block ? computeContentFingerprint(block) : "";
1268
+ if (contentFingerprint) fp += `,c:${contentFingerprint}`;
1269
+ }
1270
+ parts.push(fp);
1271
+ }
1272
+ return parts.join("|");
1273
+ }
1274
+ function computeAnnotationFingerprint(block, includePmPositions) {
1275
+ const parts = [];
1276
+ collectAnnotationFingerprint(block, parts, includePmPositions);
1277
+ return parts.join(";");
1278
+ }
1279
+ /**
1280
+ * Fingerprint of run-level content + formatting that the painter applies via
1281
+ * `applyRunStyles`. Geometry alone is insufficient: a mark-only edit (toggle
1282
+ * bold/italic/color/etc.) can leave fragment width/height/line counts
1283
+ * identical, in which case the geometry fingerprint matches and the
1284
+ * incremental render path would skip repopulating the page, leaving the new
1285
+ * formatting unpainted.
1286
+ */
1287
+ function computeContentFingerprint(block) {
1288
+ const parts = [];
1289
+ collectContentFingerprint(block, parts);
1290
+ return parts.join(";");
1291
+ }
1292
+ function collectAnnotationFingerprint(block, parts, includePmPositions) {
1293
+ if (block.kind === "paragraph") {
1294
+ for (let index = 0; index < block.runs.length; index++) {
1295
+ const run = block.runs[index];
1296
+ if (!run) continue;
1297
+ if (run.kind !== "text" && run.kind !== "tab" && run.kind !== "field") continue;
1298
+ const runParts = [];
1299
+ if (run.commentIds?.length) runParts.push(`c:${run.commentIds.join(",")}`);
1300
+ if (run.isInsertion) runParts.push(`ins:${run.changeRevisionId ?? ""}`);
1301
+ if (run.isDeletion) runParts.push(`del:${run.changeRevisionId ?? ""}`);
1302
+ if (runParts.length > 0) parts.push(includePmPositions ? `${index}:${run.pmStart ?? ""}-${run.pmEnd ?? ""}:${runParts.join("|")}` : `${index}:${runParts.join("|")}`);
1303
+ }
1304
+ return;
1305
+ }
1306
+ if (block.kind === "table") {
1307
+ for (const row of block.rows) for (const cell of row.cells) for (const child of cell.blocks) collectAnnotationFingerprint(child, parts, includePmPositions);
1308
+ return;
1309
+ }
1310
+ if (block.kind === "textBox") for (const child of block.content) collectAnnotationFingerprint(child, parts, includePmPositions);
1311
+ }
1312
+ function collectContentFingerprint(block, parts) {
1313
+ if (block.kind === "paragraph") {
1314
+ if (block.attrs?.styleId) parts.push(`p:st:${block.attrs.styleId}`);
1315
+ if (block.attrs?.alignment) parts.push(`p:al:${block.attrs.alignment}`);
1316
+ for (let index = 0; index < block.runs.length; index++) {
1317
+ const run = block.runs[index];
1318
+ if (!run) continue;
1319
+ parts.push(`${index}:${runContentKey(run)}`);
1320
+ }
1321
+ return;
1322
+ }
1323
+ if (block.kind === "table") {
1324
+ for (const row of block.rows) for (const cell of row.cells) for (const child of cell.blocks) collectContentFingerprint(child, parts);
1325
+ return;
1326
+ }
1327
+ if (block.kind === "textBox") for (const child of block.content) collectContentFingerprint(child, parts);
1328
+ }
1329
+ function runContentKey(run) {
1330
+ if (run.kind === "lineBreak") return "lb";
1331
+ if (run.kind === "image") return `img:${run.src}|${run.width}x${run.height}${run.transform ? `|tr:${run.transform}` : ""}`;
1332
+ const parts = [run.kind];
1333
+ if (run.kind === "text") {
1334
+ parts.push(`t:${run.text}`);
1335
+ if (run.templatePreview) parts.push(`tp:${run.templatePreview}`);
1336
+ } else if (run.kind === "tab") {
1337
+ if (run.width !== void 0) parts.push(`w:${run.width}`);
1338
+ } else if (run.kind === "math") {
1339
+ parts.push(`md:${run.display}`);
1340
+ parts.push(`mx:${run.ommlXml}`);
1341
+ } else {
1342
+ parts.push(`ft:${run.fieldType}`);
1343
+ if (run.instruction !== void 0) parts.push(`fi:${run.instruction}`);
1344
+ if (run.fallback !== void 0) parts.push(`fb:${run.fallback}`);
1345
+ if (run.fldLock) parts.push("fl");
1346
+ }
1347
+ if (run.bold) parts.push("b");
1348
+ if (run.italic) parts.push("i");
1349
+ if (run.underline) parts.push(typeof run.underline === "boolean" ? "u" : `u:${run.underline.style ?? ""}:${run.underline.color ?? ""}`);
1350
+ if (run.strike) parts.push("s");
1351
+ if (run.color) parts.push(`c:${run.color}`);
1352
+ if (run.highlight) parts.push(`hi:${run.highlight}`);
1353
+ if (run.fontFamily) parts.push(`ff:${run.fontFamily}`);
1354
+ if (run.eastAsiaFontFamily) parts.push(`ea:${run.eastAsiaFontFamily}`);
1355
+ if (run.fontSize !== void 0) parts.push(`fs:${run.fontSize}`);
1356
+ if (run.letterSpacing !== void 0) parts.push(`ls:${run.letterSpacing}`);
1357
+ if (run.superscript) parts.push("sup");
1358
+ if (run.subscript) parts.push("sub");
1359
+ if (run.allCaps) parts.push("ac");
1360
+ if (run.smallCaps) parts.push("sc");
1361
+ if (run.positionPx !== void 0) parts.push(`pp:${run.positionPx}`);
1362
+ if (run.horizontalScale !== void 0 && run.horizontalScale !== 100) parts.push(`hs:${run.horizontalScale}`);
1363
+ if (run.imprint) parts.push("imp");
1364
+ if (run.emboss) parts.push("emb");
1365
+ if (run.textShadow) parts.push("sh");
1366
+ if (run.textOutline) parts.push("ol");
1367
+ if (run.emphasisMark) parts.push(`emk:${run.emphasisMark}`);
1368
+ if (run.hyperlink) parts.push(`hl:${run.hyperlink.href}`);
1369
+ return parts.join("|");
1370
+ }
1371
+ function headerFooterContentFingerprint(prefix, entries) {
1372
+ if (!entries) return [];
1373
+ return Array.from(entries.entries()).toSorted(([left], [right]) => left.localeCompare(right)).map(([rId, content]) => `${prefix}:${rId},${content.blocks.length},${content.height},${content.visualTop ?? 0},${content.visualBottom ?? content.height},${content.textSig ?? ""}`);
1374
+ }
1375
+ /**
1376
+ * Compute a hash for render options that affect all pages globally.
1377
+ * When this changes, all pages need a full re-render.
1378
+ */
1379
+ function computeOptionsHash(options) {
1380
+ const parts = [];
1381
+ if (options.headerContent) parts.push(`hdr:${options.headerContent.blocks.length},${options.headerContent.height},${options.headerContent.visualTop ?? 0},${options.headerContent.visualBottom ?? options.headerContent.height},${options.headerContent.rId ?? ""},${options.headerContent.textSig ?? ""}`);
1382
+ if (options.footerContent) parts.push(`ftr:${options.footerContent.blocks.length},${options.footerContent.height},${options.footerContent.visualTop ?? 0},${options.footerContent.visualBottom ?? options.footerContent.height},${options.footerContent.rId ?? ""},${options.footerContent.textSig ?? ""}`);
1383
+ parts.push(...headerFooterContentFingerprint("hdr-map", options.headerContentByRId));
1384
+ parts.push(...headerFooterContentFingerprint("ftr-map", options.footerContentByRId));
1385
+ if (options.firstPageHeaderContent) parts.push(`fp-hdr:${options.firstPageHeaderContent.blocks.length},${options.firstPageHeaderContent.height},${options.firstPageHeaderContent.rId ?? ""},${options.firstPageHeaderContent.textSig ?? ""}`);
1386
+ if (options.firstPageFooterContent) parts.push(`fp-ftr:${options.firstPageFooterContent.blocks.length},${options.firstPageFooterContent.height},${options.firstPageFooterContent.rId ?? ""},${options.firstPageFooterContent.textSig ?? ""}`);
1387
+ if (options.titlePg) parts.push("titlePg");
1388
+ if (options.theme) parts.push(`thm:${options.theme.name ?? "default"}`);
1389
+ if (options.pageBorders) parts.push(`pb:${JSON.stringify(options.pageBorders)}`);
1390
+ if (options.headerDistance !== void 0) parts.push(`hd:${options.headerDistance}`);
1391
+ if (options.footerDistance !== void 0) parts.push(`fd:${options.footerDistance}`);
1392
+ if (options.watermark) parts.push(`wm:${JSON.stringify(options.watermark)}`);
1393
+ if (options.watermarkImageSrc !== void 0) parts.push(`wmsrc:${options.watermarkImageSrc}`);
1394
+ if (options.watermarkByHeaderRId) {
1395
+ const entries = [];
1396
+ for (const [rId, wm] of options.watermarkByHeaderRId) entries.push([rId, wm]);
1397
+ entries.sort(([a], [b]) => a.localeCompare(b));
1398
+ parts.push(`wm-map:${JSON.stringify(entries)}`);
1399
+ }
1400
+ return parts.join("|");
1401
+ }
1402
+ function sortedMapFingerprint(prefix, map) {
1403
+ if (!map || map.size === 0) return [];
1404
+ const entries = [];
1405
+ for (const [key, value] of map) entries.push(`${String(key)}=${String(value)}`);
1406
+ entries.sort();
1407
+ return [`${prefix}:${entries.join(",")}`];
1408
+ }
1409
+ function computeFieldContextHash(options) {
1410
+ const parts = [];
1411
+ parts.push(...sortedMapFingerprint("bm-page", options.bookmarkPages));
1412
+ parts.push(...sortedMapFingerprint("bm-text", options.bookmarkText));
1413
+ parts.push(...sortedMapFingerprint("seq", options.seqValues));
1414
+ parts.push(...sortedMapFingerprint("section-pages", options.sectionPageCounts));
1415
+ return parts.join("|");
1416
+ }
1417
+ /**
1418
+ * Apply standard container styles for the pages wrapper.
1419
+ */
1420
+ function applyContainerStyles(container, pageGap) {
1421
+ container.style.display = "flex";
1422
+ container.style.flexDirection = "column";
1423
+ container.style.alignItems = "center";
1424
+ container.style.gap = `${pageGap}px`;
1425
+ container.style.padding = "0";
1426
+ container.style.backgroundColor = "transparent";
1427
+ }
1428
+ /**
1429
+ * Number of pages to render above and below the visible area.
1430
+ * Keeps nearby pages ready for smooth scrolling.
1431
+ */
1432
+ const VIRTUALIZATION_BUFFER = 1;
1433
+ const VIRTUALIZATION_ROOT_MARGIN_PX = 1e3;
1434
+ const INITIAL_EAGER_RENDER_PAGES = 3;
1435
+ /**
1436
+ * Minimum page count before virtualization kicks in.
1437
+ * Small documents render all pages eagerly for simplicity.
1438
+ */
1439
+ const VIRTUALIZATION_THRESHOLD = 8;
1440
+ /**
1441
+ * Render multiple pages to a container with virtualization for large documents.
1442
+ *
1443
+ * For documents with fewer than VIRTUALIZATION_THRESHOLD pages, all pages
1444
+ * are rendered eagerly. For larger documents, only pages near the visible
1445
+ * viewport are fully rendered — off-screen pages are lightweight shells
1446
+ * with correct dimensions to preserve scroll position.
1447
+ *
1448
+ * An IntersectionObserver watches page elements and populates/clears
1449
+ * content as pages scroll into and out of view.
1450
+ */
1451
+ function renderPages(pages, container, options = {}) {
1452
+ const totalPages = pages.length;
1453
+ const pageGap = options.pageGap ?? 24;
1454
+ const pc = container;
1455
+ const prevState = pc.__pageRenderState;
1456
+ const currentOptionsHash = computeOptionsHash(options);
1457
+ const currentFieldContextHash = computeFieldContextHash(options);
1458
+ const useVirtualization = totalPages >= VIRTUALIZATION_THRESHOLD;
1459
+ if (prevState && prevState.optionsHash === currentOptionsHash && useVirtualization) {
1460
+ const prevShells = prevState.pageStates;
1461
+ const prevDataMap = prevState.pageDataMap;
1462
+ const observer = pc.__pageObserver;
1463
+ const totalPagesChanged = prevState.totalPages !== totalPages;
1464
+ const fieldContextChanged = prevState.fieldContextHash !== currentFieldContextHash;
1465
+ const commonCount = Math.min(prevShells.length, pages.length);
1466
+ for (let i = 0; i < commonCount; i++) {
1467
+ const prev = prevShells[i];
1468
+ const page = pages[i];
1469
+ const data = prevDataMap.get(prev.element);
1470
+ if (!data) continue;
1471
+ const oldPage = data.page;
1472
+ data.page = page;
1473
+ if (!data.rendered) {
1474
+ prev.fingerprint = null;
1475
+ prev.renderFingerprint = null;
1476
+ applyPageStyles(prev.element, page.size.w, page.size.h, options);
1477
+ syncPageBorderOverlay(prev.element, page, options, options.document ?? document);
1478
+ prev.element.dataset["pageNumber"] = String(page.number);
1479
+ continue;
1480
+ }
1481
+ const newFp = computePageFingerprint(page, options.blockLookup);
1482
+ if (prev.fingerprint === newFp && !totalPagesChanged && !fieldContextChanged) continue;
1483
+ const shell = prev.element;
1484
+ if (totalPagesChanged || fieldContextChanged) {
1485
+ shell.innerHTML = "";
1486
+ data.rendered = false;
1487
+ populatePageShell(shell, prevDataMap, totalPages, options);
1488
+ applyPageStyles(shell, page.size.w, page.size.h, options);
1489
+ syncPageBorderOverlay(shell, page, options, options.document ?? document);
1490
+ shell.dataset["pageNumber"] = String(page.number);
1491
+ continue;
1492
+ }
1493
+ const newRenderFp = computePageRenderFingerprint(page, options.blockLookup);
1494
+ if (!(!(prev.renderFingerprint !== newRenderFp) && syncRenderedPmPositionData(shell, oldPage, data.page))) repopulatePageContent(shell, prevDataMap, totalPages, options);
1495
+ prev.fingerprint = newFp;
1496
+ prev.renderFingerprint = newRenderFp;
1497
+ applyPageStyles(shell, page.size.w, page.size.h, options);
1498
+ syncPageBorderOverlay(shell, page, options, options.document ?? document);
1499
+ shell.dataset["pageNumber"] = String(page.number);
1500
+ }
1501
+ if (pages.length > prevShells.length) {
1502
+ const doc = options.document ?? document;
1503
+ for (let i = prevShells.length; i < pages.length; i++) {
1504
+ const page = pages[i];
1505
+ const pageEl = doc.createElement("div");
1506
+ pageEl.className = options.pageClassName ?? PAGE_CLASS_NAMES.page;
1507
+ pageEl.dataset["pageNumber"] = String(page.number);
1508
+ pageEl.dataset["pageIndex"] = String(i);
1509
+ applyPageStyles(pageEl, page.size.w, page.size.h, options);
1510
+ syncPageBorderOverlay(pageEl, page, options, doc);
1511
+ container.append(pageEl);
1512
+ prevShells.push({
1513
+ element: pageEl,
1514
+ fingerprint: null,
1515
+ renderFingerprint: null
1516
+ });
1517
+ prevDataMap.set(pageEl, {
1518
+ page,
1519
+ index: i,
1520
+ rendered: false
1521
+ });
1522
+ if (observer) observer.observe(pageEl);
1523
+ }
1524
+ }
1525
+ if (pages.length < prevShells.length) {
1526
+ for (let i = prevShells.length - 1; i >= pages.length; i--) {
1527
+ const shell = prevShells[i].element;
1528
+ if (observer) observer.unobserve(shell);
1529
+ prevDataMap.delete(shell);
1530
+ shell.remove();
1531
+ }
1532
+ prevShells.length = pages.length;
1533
+ }
1534
+ for (let i = 0; i < prevShells.length; i++) {
1535
+ const data = prevDataMap.get(prevShells[i].element);
1536
+ if (data) data.index = i;
1537
+ }
1538
+ prevState.totalPages = totalPages;
1539
+ prevState.fieldContextHash = currentFieldContextHash;
1540
+ prevState.currentOptions = options;
1541
+ emitPainterPainted(container);
1542
+ return;
1543
+ }
1544
+ const prevObserver = pc.__pageObserver;
1545
+ if (prevObserver) {
1546
+ prevObserver.disconnect();
1547
+ delete pc.__pageObserver;
1548
+ }
1549
+ const pageShellClass = options.pageClassName ?? PAGE_CLASS_NAMES.page;
1550
+ const isPageShell = (el) => el.className.split(/\s+/u).includes(pageShellClass);
1551
+ const existingChildren = Array.from(container.children);
1552
+ const overlayBefore = existingChildren.find((el) => !isPageShell(el)) ?? null;
1553
+ for (const el of existingChildren) if (isPageShell(el)) el.remove();
1554
+ delete pc.__pageRenderState;
1555
+ applyContainerStyles(container, pageGap);
1556
+ const pageShells = [];
1557
+ for (let i = 0; i < pages.length; i++) {
1558
+ const page = pages[i];
1559
+ if (!useVirtualization) {
1560
+ const { context, pageOptions } = buildPageRenderArgs(page, totalPages, options);
1561
+ const pageEl = renderPage(page, context, pageOptions);
1562
+ container.insertBefore(pageEl, overlayBefore);
1563
+ pageShells.push(pageEl);
1564
+ } else {
1565
+ const doc = options.document ?? document;
1566
+ const pageEl = doc.createElement("div");
1567
+ pageEl.className = options.pageClassName ?? PAGE_CLASS_NAMES.page;
1568
+ pageEl.dataset["pageNumber"] = String(page.number);
1569
+ pageEl.dataset["pageIndex"] = String(i);
1570
+ applyPageStyles(pageEl, page.size.w, page.size.h, options);
1571
+ syncPageBorderOverlay(pageEl, page, options, doc);
1572
+ container.insertBefore(pageEl, overlayBefore);
1573
+ pageShells.push(pageEl);
1574
+ }
1575
+ }
1576
+ if (!useVirtualization) {
1577
+ emitPainterPainted(container);
1578
+ return;
1579
+ }
1580
+ const pageDataMap = /* @__PURE__ */ new Map();
1581
+ for (let i = 0; i < pages.length; i++) pageDataMap.set(pageShells[i], {
1582
+ page: pages[i],
1583
+ index: i,
1584
+ rendered: false
1585
+ });
1586
+ const observer = new IntersectionObserver((entries) => {
1587
+ const renderState = pc.__pageRenderState;
1588
+ if (!renderState) return;
1589
+ const { currentOptions: liveOptions, totalPages: liveTotalPages, pageDataMap: liveDataMap } = renderState;
1590
+ for (const entry of entries) {
1591
+ if (!(entry.target instanceof HTMLElement)) continue;
1592
+ const shell = entry.target;
1593
+ const data = liveDataMap.get(shell);
1594
+ if (!data) continue;
1595
+ if (entry.isIntersecting) {
1596
+ populatePageShell(shell, liveDataMap, liveTotalPages, liveOptions);
1597
+ for (let offset = -1; offset <= VIRTUALIZATION_BUFFER; offset++) {
1598
+ const neighborIdx = data.index + offset;
1599
+ if (neighborIdx >= 0 && neighborIdx < renderState.pageStates.length && neighborIdx !== data.index) populatePageShell(renderState.pageStates[neighborIdx].element, liveDataMap, liveTotalPages, liveOptions);
1600
+ }
1601
+ }
1602
+ }
1603
+ const viewportHeight = window.innerHeight;
1604
+ const nearThreshold = viewportHeight * 3;
1605
+ const nearIndices = /* @__PURE__ */ new Set();
1606
+ for (const [el, data] of liveDataMap) {
1607
+ if (!data.rendered) continue;
1608
+ const rect = el.getBoundingClientRect();
1609
+ if (rect.bottom > -nearThreshold && rect.top < viewportHeight + nearThreshold) nearIndices.add(data.index);
1610
+ }
1611
+ for (const [el, data] of liveDataMap) {
1612
+ if (!data.rendered) continue;
1613
+ let keepRendered = false;
1614
+ for (const nearIdx of nearIndices) if (Math.abs(data.index - nearIdx) <= 2) {
1615
+ keepRendered = true;
1616
+ break;
1617
+ }
1618
+ if (!keepRendered && nearIndices.size > 0) depopulatePageShell(el, liveDataMap);
1619
+ }
1620
+ }, {
1621
+ root: null,
1622
+ rootMargin: `${VIRTUALIZATION_ROOT_MARGIN_PX}px 0px ${VIRTUALIZATION_ROOT_MARGIN_PX}px 0px`
1623
+ });
1624
+ for (const shell of pageShells) observer.observe(shell);
1625
+ pc.__pageObserver = observer;
1626
+ pc.__pageRenderState = {
1627
+ pageStates: pageShells.map((el) => ({
1628
+ element: el,
1629
+ fingerprint: null,
1630
+ renderFingerprint: null
1631
+ })),
1632
+ totalPages,
1633
+ optionsHash: currentOptionsHash,
1634
+ fieldContextHash: currentFieldContextHash,
1635
+ pageDataMap,
1636
+ currentOptions: options
1637
+ };
1638
+ const initialRenderCount = Math.min(pages.length, INITIAL_EAGER_RENDER_PAGES);
1639
+ for (let i = 0; i < initialRenderCount; i++) populatePageShell(pageShells[i], pageDataMap, totalPages, options);
1640
+ emitPainterPainted(container);
1641
+ }
1642
+ const PAINTER_PAINTED_EVENT = "painter:painted";
1643
+ function emitPainterPainted(container) {
1644
+ const pageCount = container.querySelectorAll(`.${PAGE_CLASS_NAMES.page}`).length;
1645
+ const event = new CustomEvent(PAINTER_PAINTED_EVENT, {
1646
+ detail: {
1647
+ container,
1648
+ pageCount
1649
+ },
1650
+ bubbles: true,
1651
+ cancelable: false
1652
+ });
1653
+ container.dispatchEvent(event);
1654
+ }
1655
+ /**
1656
+ * Populate a page shell with full rendered content.
1657
+ */
1658
+ function populatePageShell(shell, pageDataMap, totalPages, options) {
1659
+ const data = pageDataMap.get(shell);
1660
+ if (!data || data.rendered) return;
1661
+ const { context, pageOptions } = buildPageRenderArgs(data.page, totalPages, options);
1662
+ const fullPageEl = renderPage(data.page, context, pageOptions);
1663
+ for (const stale of Array.from(shell.querySelectorAll(":scope > .layout-page-border"))) stale.remove();
1664
+ while (fullPageEl.firstChild) shell.append(fullPageEl.firstChild);
1665
+ data.rendered = true;
1666
+ syncPageShellFingerprints(shell, data, options);
1667
+ const container = shell.parentElement;
1668
+ if (container instanceof HTMLElement) emitPainterPainted(container);
1669
+ }
1670
+ /**
1671
+ * Surgically replace only the content area of a rendered page shell.
1672
+ * Preserves header/footer elements to avoid blinking.
1673
+ */
1674
+ function repopulatePageContent(shell, pageDataMap, totalPages, options) {
1675
+ const data = pageDataMap.get(shell);
1676
+ if (!data) return;
1677
+ const { context, pageOptions } = buildPageRenderArgs(data.page, totalPages, options);
1678
+ const newContentEl = renderPage(data.page, context, pageOptions).querySelector(`.${PAGE_CLASS_NAMES.content}`);
1679
+ const oldContentEl = shell.querySelector(`.${PAGE_CLASS_NAMES.content}`);
1680
+ if (newContentEl && oldContentEl) {
1681
+ oldContentEl.replaceWith(newContentEl);
1682
+ syncPageWatermarkOverlay(shell, data.page, pageOptions, options.document ?? document);
1683
+ return;
1684
+ }
1685
+ shell.innerHTML = "";
1686
+ data.rendered = false;
1687
+ populatePageShell(shell, pageDataMap, totalPages, options);
1688
+ }
1689
+ function syncRenderedPmPositionData(shell, oldPage, newPage) {
1690
+ const delta = getUniformPagePositionDelta(oldPage, newPage);
1691
+ if (delta === null) return false;
1692
+ if (delta === 0) return true;
1693
+ for (const element of shell.querySelectorAll("[data-pm-start], [data-pm-end], [data-table-pm-start]")) {
1694
+ shiftNumericDatasetValue(element, "pmStart", delta);
1695
+ shiftNumericDatasetValue(element, "pmEnd", delta);
1696
+ shiftNumericDatasetValue(element, "tablePmStart", delta);
1697
+ }
1698
+ return true;
1699
+ }
1700
+ function getUniformPagePositionDelta(oldPage, newPage) {
1701
+ if (oldPage.fragments.length !== newPage.fragments.length) return null;
1702
+ let delta = null;
1703
+ for (let i = 0; i < oldPage.fragments.length; i++) {
1704
+ const oldFragment = oldPage.fragments[i];
1705
+ const newFragment = newPage.fragments[i];
1706
+ if (!oldFragment || !newFragment) return null;
1707
+ if (oldFragment.kind !== newFragment.kind || oldFragment.blockId !== newFragment.blockId) return null;
1708
+ const startDelta = readPositionDelta(oldFragment.pmStart, newFragment.pmStart);
1709
+ if (startDelta !== null) {
1710
+ if (delta !== null && delta !== startDelta) return null;
1711
+ delta = startDelta;
1712
+ }
1713
+ const endDelta = readPositionDelta(oldFragment.pmEnd, newFragment.pmEnd);
1714
+ if (endDelta !== null) {
1715
+ if (delta !== null && delta !== endDelta) return null;
1716
+ delta = endDelta;
1717
+ }
1718
+ }
1719
+ return delta;
1720
+ }
1721
+ function readPositionDelta(previous, next) {
1722
+ if (previous === void 0 && next === void 0) return null;
1723
+ if (previous === void 0 || next === void 0) return null;
1724
+ return next - previous;
1725
+ }
1726
+ function shiftNumericDatasetValue(element, key, delta) {
1727
+ const value = element.dataset[key];
1728
+ if (value === void 0) return;
1729
+ const numeric = Number(value);
1730
+ if (!Number.isFinite(numeric)) return;
1731
+ element.dataset[key] = String(numeric + delta);
1732
+ }
1733
+ function syncPageShellFingerprints(shell, data, options) {
1734
+ const pageState = shell.parentElement?.__pageRenderState?.pageStates[data.index];
1735
+ if (!pageState || pageState.element !== shell) return;
1736
+ pageState.fingerprint = computePageFingerprint(data.page, options.blockLookup);
1737
+ pageState.renderFingerprint = computePageRenderFingerprint(data.page, options.blockLookup);
1738
+ }
1739
+ /**
1740
+ * Find the page shell whose layout fragments cover (or are nearest
1741
+ * before) a given ProseMirror position. Returns null if the
1742
+ * container has no virtualization state — callers should fall back
1743
+ * to the cheaper run-level DOM query in that case.
1744
+ *
1745
+ * Uses the layout-side Page records (always present even when a
1746
+ * page's content hasn't rendered yet under virtualization), so the
1747
+ * caller can scroll to the correct page shell and let the
1748
+ * IntersectionObserver populate it on demand. This avoids the
1749
+ * "many clicks to arrive" failure mode where a per-run DOM query
1750
+ * only finds runs in the currently-rendered buffer and steps the
1751
+ * viewport one buffer at a time.
1752
+ */
1753
+ function findPageShellForPmPos(container, pmPos) {
1754
+ const dataMap = container.__pageRenderState?.pageDataMap;
1755
+ if (!dataMap || dataMap.size === 0) return null;
1756
+ let bestStartShell = null;
1757
+ let bestStart = Number.NEGATIVE_INFINITY;
1758
+ for (const [shell, entry] of dataMap) {
1759
+ let pageStart = Number.POSITIVE_INFINITY;
1760
+ let pageEnd = Number.NEGATIVE_INFINITY;
1761
+ for (const fragment of entry.page.fragments) {
1762
+ if (fragment.pmStart !== void 0 && fragment.pmStart < pageStart) pageStart = fragment.pmStart;
1763
+ if (fragment.pmEnd !== void 0 && fragment.pmEnd > pageEnd) pageEnd = fragment.pmEnd;
1764
+ }
1765
+ if (pageStart === Number.POSITIVE_INFINITY) continue;
1766
+ if (pageStart <= pmPos && pmPos <= pageEnd) return {
1767
+ element: shell,
1768
+ isExact: true
1769
+ };
1770
+ if (pageStart <= pmPos && pageStart > bestStart) {
1771
+ bestStart = pageStart;
1772
+ bestStartShell = shell;
1773
+ }
1774
+ }
1775
+ return bestStartShell ? {
1776
+ element: bestStartShell,
1777
+ isExact: false
1778
+ } : null;
1779
+ }
1780
+ /**
1781
+ * Clear a page shell's content (keep shell dimensions for scroll).
1782
+ */
1783
+ function depopulatePageShell(shell, pageDataMap) {
1784
+ const data = pageDataMap.get(shell);
1785
+ if (!data || !data.rendered) return;
1786
+ shell.innerHTML = "";
1787
+ data.rendered = false;
1788
+ const pageState = shell.parentElement?.__pageRenderState?.pageStates[data.index];
1789
+ if (pageState?.element === shell) {
1790
+ pageState.fingerprint = null;
1791
+ pageState.renderFingerprint = null;
1792
+ }
1793
+ }
1794
+ //#endregion
1795
+ export { PAGE_CLASS_NAMES, PAINTER_PAINTED_EVENT, applySectionHeaderFooterOptions, calculateFootnoteAreaRenderHeight, computePageFingerprint, emuToPixels, findPageShellForPmPos, getDefaultPageFontFamily, isFloatingImageRun, renderFloatingImagesLayer, renderFootnoteArea, renderPage, renderPages, resolveAnchoredImagePosition, resolveHeaderFooterFloatLeft };