ooxml-core 1.10.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/PptxHandler-DNZHAHUY.cjs +12 -0
  2. package/dist/PptxHandler-E44KDHMQ.mjs +3 -0
  3. package/dist/{PptxHandler-ADEFY476.mjs → PptxHandler-NROFYT2N.mjs} +2 -2
  4. package/dist/automation/index.cjs +3504 -2888
  5. package/dist/automation/index.mjs +3504 -2888
  6. package/dist/{chunk-3N6XMMTT.cjs → chunk-2UVH6RHI.cjs} +1138 -996
  7. package/dist/{chunk-ZOUGMAZG.mjs → chunk-7DSZI7S6.mjs} +1 -1
  8. package/dist/{chunk-S6DOCMQC.cjs → chunk-7QZGRB3T.cjs} +0 -10
  9. package/dist/chunk-ANZ4Q6I3.cjs +21 -0
  10. package/dist/{chunk-5NVJN4E6.mjs → chunk-EC2W2MDY.mjs} +1 -1
  11. package/dist/chunk-EGTRL3QJ.mjs +19 -0
  12. package/dist/chunk-GXHKNSZX.mjs +9 -0
  13. package/dist/{chunk-CCHYFCPD.mjs → chunk-HCXUI5UC.mjs} +296 -103
  14. package/dist/chunk-HDQXPSHY.cjs +17 -0
  15. package/dist/chunk-KTYBFGEY.mjs +14 -0
  16. package/dist/chunk-QOO36KG4.cjs +42 -0
  17. package/dist/chunk-R2KZXD6U.mjs +39 -0
  18. package/dist/{chunk-A6P7G3UK.mjs → chunk-U2DF3EGK.mjs} +1 -1
  19. package/dist/{chunk-R6KSBNKX.mjs → chunk-UAY26XOI.mjs} +1 -9
  20. package/dist/{chunk-WUE5ZHU3.mjs → chunk-W5ARCUJB.mjs} +3 -3
  21. package/dist/chunk-XZPZHXV4.cjs +12 -0
  22. package/dist/{chunk-ZE53K7DH.mjs → chunk-YB5SRNFS.mjs} +244 -102
  23. package/dist/docx/embedded.cjs +1 -1
  24. package/dist/docx/embedded.mjs +1 -1
  25. package/dist/docx/index.cjs +1 -1
  26. package/dist/docx/index.mjs +1 -1
  27. package/dist/docx/layout/adapt-table.d.ts.map +1 -1
  28. package/dist/docx/layout/flow-table.d.ts.map +1 -1
  29. package/dist/docx/layout/index.cjs +266 -61
  30. package/dist/docx/layout/index.d.ts +1 -0
  31. package/dist/docx/layout/index.d.ts.map +1 -1
  32. package/dist/docx/layout/index.mjs +266 -62
  33. package/dist/docx/layout/input.d.ts +5 -0
  34. package/dist/docx/layout/input.d.ts.map +1 -1
  35. package/dist/docx/layout/layout-session.d.ts +10 -0
  36. package/dist/docx/layout/layout-session.d.ts.map +1 -0
  37. package/dist/docx/layout/nested-fragment-edges.d.ts +9 -0
  38. package/dist/docx/layout/nested-fragment-edges.d.ts.map +1 -0
  39. package/dist/docx/layout/paragraph-cache.d.ts +8 -0
  40. package/dist/docx/layout/paragraph-cache.d.ts.map +1 -0
  41. package/dist/docx/layout/paragraph-layout.d.ts.map +1 -1
  42. package/dist/docx/layout/paragraph-tokens.d.ts +1 -1
  43. package/dist/docx/layout/paragraph-tokens.d.ts.map +1 -1
  44. package/dist/docx/layout/result.d.ts +7 -0
  45. package/dist/docx/layout/result.d.ts.map +1 -1
  46. package/dist/docx/layout/table-border-layout.d.ts +1 -1
  47. package/dist/docx/layout/table-border-layout.d.ts.map +1 -1
  48. package/dist/docx/layout/table-cell-layout.d.ts +1 -1
  49. package/dist/docx/layout/table-cell-layout.d.ts.map +1 -1
  50. package/dist/docx/layout/table-frames.d.ts.map +1 -1
  51. package/dist/docx/layout/table-layout.d.ts +1 -1
  52. package/dist/docx/layout/table-layout.d.ts.map +1 -1
  53. package/dist/docx/layout/table-paragraph-keeps.d.ts +14 -0
  54. package/dist/docx/layout/table-paragraph-keeps.d.ts.map +1 -0
  55. package/dist/docx/load/index.cjs +1 -1
  56. package/dist/docx/load/index.mjs +1 -1
  57. package/dist/docx/ui/index.cjs +83 -6
  58. package/dist/docx/ui/index.mjs +83 -7
  59. package/dist/docx/ui/ribbon-action-ids.d.ts +1 -1
  60. package/dist/docx/ui/ribbon-action-ids.d.ts.map +1 -1
  61. package/dist/docx/ui/word-count.d.ts +3 -0
  62. package/dist/docx/ui/word-count.d.ts.map +1 -1
  63. package/dist/geometry/element-transform.d.ts +90 -0
  64. package/dist/geometry/element-transform.d.ts.map +1 -0
  65. package/dist/geometry/index.cjs +90 -0
  66. package/dist/geometry/index.d.ts +1 -0
  67. package/dist/geometry/index.d.ts.map +1 -1
  68. package/dist/geometry/index.mjs +83 -1
  69. package/dist/index.cjs +90 -0
  70. package/dist/index.mjs +90 -0
  71. package/dist/pptx/automation/index.cjs +266 -114
  72. package/dist/pptx/automation/index.d.ts +5 -4
  73. package/dist/pptx/automation/index.d.ts.map +1 -1
  74. package/dist/pptx/automation/index.mjs +5 -5
  75. package/dist/pptx/chunks/{text-operations-BqHmLaLA.d.ts → elements-DD3UGOMd.d.ts} +17 -3262
  76. package/dist/pptx/chunks/elements-DD3UGOMd.d.ts.map +1 -0
  77. package/dist/pptx/chunks/{index-DUCGeZh7.d.ts → index-BZrFyNtU.d.ts} +53 -5
  78. package/dist/pptx/chunks/index-BZrFyNtU.d.ts.map +1 -0
  79. package/dist/pptx/chunks/{index-Cuxtr76Y.d.ts → index-DdX02BSm.d.ts} +5 -3
  80. package/dist/pptx/chunks/index-DdX02BSm.d.ts.map +1 -0
  81. package/dist/pptx/chunks/smart-art-ENMMEbmW.d.ts +1512 -0
  82. package/dist/pptx/chunks/smart-art-ENMMEbmW.d.ts.map +1 -0
  83. package/dist/pptx/chunks/text-D49FKllA.d.ts +1473 -0
  84. package/dist/pptx/chunks/text-D49FKllA.d.ts.map +1 -0
  85. package/dist/pptx/chunks/text-operations-CyMTMfID.d.ts +3261 -0
  86. package/dist/pptx/chunks/text-operations-CyMTMfID.d.ts.map +1 -0
  87. package/dist/pptx/cli/index.cjs +266 -114
  88. package/dist/pptx/cli/index.d.ts +1 -1
  89. package/dist/pptx/cli/index.mjs +4 -4
  90. package/dist/pptx/converter/index.d.ts +1 -1
  91. package/dist/pptx/converter/index.mjs +2 -2
  92. package/dist/pptx/editor/render/find-replace.cjs +17 -16
  93. package/dist/pptx/editor/render/find-replace.d.ts +2 -2
  94. package/dist/pptx/editor/render/find-replace.mjs +2 -1
  95. package/dist/pptx/editor/render/font-family-update.cjs +14 -0
  96. package/dist/pptx/editor/render/font-family-update.d.ts +17 -0
  97. package/dist/pptx/editor/render/font-family-update.d.ts.map +1 -0
  98. package/dist/pptx/editor/render/font-family-update.mjs +1 -0
  99. package/dist/pptx/editor/render/paragraph-geometry-overrides.cjs +14 -0
  100. package/dist/pptx/editor/render/paragraph-geometry-overrides.d.ts +17 -0
  101. package/dist/pptx/editor/render/paragraph-geometry-overrides.d.ts.map +1 -0
  102. package/dist/pptx/editor/render/paragraph-geometry-overrides.mjs +12 -0
  103. package/dist/pptx/editor/render/slide-operations.cjs +9 -8
  104. package/dist/pptx/editor/render/slide-operations.mjs +3 -2
  105. package/dist/pptx/editor/render/table-data-grid-ops.cjs +1 -1
  106. package/dist/pptx/editor/render/table-data-grid-ops.mjs +1 -1
  107. package/dist/pptx/editor/render/text-content-style.cjs +18 -0
  108. package/dist/pptx/editor/render/text-content-style.d.ts +9 -0
  109. package/dist/pptx/editor/render/text-content-style.d.ts.map +1 -0
  110. package/dist/pptx/editor/render/text-content-style.mjs +5 -0
  111. package/dist/pptx/editor/render/text-runs-style-patch.cjs +17 -0
  112. package/dist/pptx/editor/render/text-runs-style-patch.d.ts +7 -0
  113. package/dist/pptx/editor/render/text-runs-style-patch.d.ts.map +1 -0
  114. package/dist/pptx/editor/render/text-runs-style-patch.mjs +15 -0
  115. package/dist/pptx/editor/render/text-style-scope.cjs +173 -0
  116. package/dist/pptx/editor/render/text-style-scope.d.ts +76 -0
  117. package/dist/pptx/editor/render/text-style-scope.d.ts.map +1 -0
  118. package/dist/pptx/editor/render/text-style-scope.mjs +164 -0
  119. package/dist/pptx/editor/render/theme-editor-model.cjs +1 -1
  120. package/dist/pptx/editor/render/theme-editor-model.mjs +1 -1
  121. package/dist/pptx/editor/render/update-text-segment-style.cjs +11 -0
  122. package/dist/pptx/editor/render/update-text-segment-style.d.ts +14 -0
  123. package/dist/pptx/editor/render/update-text-segment-style.d.ts.map +1 -0
  124. package/dist/pptx/editor/render/update-text-segment-style.mjs +2 -0
  125. package/dist/pptx/index.cjs +329 -114
  126. package/dist/pptx/index.d.ts +7 -5
  127. package/dist/pptx/index.mjs +5 -5
  128. package/dist/pptx/smartart-layouts/index.d.ts +1 -1
  129. package/dist/teams/index.cjs +112 -16
  130. package/dist/teams/index.mjs +112 -16
  131. package/dist/visio/edit-commands.d.ts +3 -3
  132. package/dist/visio/edit-commands.d.ts.map +1 -1
  133. package/dist/visio/edit-formatting-scope.d.ts.map +1 -1
  134. package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
  135. package/dist/visio/edit-text-field-commands.d.ts +15 -0
  136. package/dist/visio/edit-text-field-commands.d.ts.map +1 -1
  137. package/dist/visio/edit-text-field.d.ts +2 -2
  138. package/dist/visio/edit-text-field.d.ts.map +1 -1
  139. package/dist/visio/edit.d.ts +1 -1
  140. package/dist/visio/edit.d.ts.map +1 -1
  141. package/dist/visio/index.cjs +696 -249
  142. package/dist/visio/index.d.ts +2 -1
  143. package/dist/visio/index.d.ts.map +1 -1
  144. package/dist/visio/index.mjs +695 -250
  145. package/dist/visio/model.d.ts +18 -0
  146. package/dist/visio/model.d.ts.map +1 -1
  147. package/dist/visio/paper-sizes.d.ts +5 -0
  148. package/dist/visio/paper-sizes.d.ts.map +1 -1
  149. package/dist/visio/parser.d.ts.map +1 -1
  150. package/dist/visio/print-count.d.ts +20 -0
  151. package/dist/visio/print-count.d.ts.map +1 -0
  152. package/dist/visio/print-settings.d.ts +14 -0
  153. package/dist/visio/print-settings.d.ts.map +1 -0
  154. package/dist/visio/shapes.d.ts.map +1 -1
  155. package/dist/visio/style.d.ts +1 -1
  156. package/dist/visio/style.d.ts.map +1 -1
  157. package/dist/visio/text-field-display.d.ts +3 -0
  158. package/dist/visio/text-field-display.d.ts.map +1 -1
  159. package/dist/visio/text-field-editability.d.ts +6 -0
  160. package/dist/visio/text-field-editability.d.ts.map +1 -0
  161. package/dist/visio/text-field-independent.d.ts +4 -0
  162. package/dist/visio/text-field-independent.d.ts.map +1 -0
  163. package/dist/visio/text-field-source.d.ts +6 -0
  164. package/dist/visio/text-field-source.d.ts.map +1 -0
  165. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  166. package/dist/visio/ui/index.cjs +588 -215
  167. package/dist/visio/ui/index.mjs +588 -215
  168. package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
  169. package/dist/xlsx/edit/pivots.d.ts.map +1 -1
  170. package/dist/xlsx/index.cjs +773 -514
  171. package/dist/xlsx/index.mjs +772 -515
  172. package/dist/xlsx/load/index.cjs +541 -292
  173. package/dist/xlsx/load/index.mjs +541 -292
  174. package/dist/xlsx/model-pivots.d.ts +8 -0
  175. package/dist/xlsx/model-pivots.d.ts.map +1 -1
  176. package/dist/xlsx/pivot/admission.d.ts.map +1 -1
  177. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
  178. package/dist/xlsx/pivot/data.d.ts +2 -2
  179. package/dist/xlsx/pivot/data.d.ts.map +1 -1
  180. package/dist/xlsx/pivot/index.d.ts +2 -0
  181. package/dist/xlsx/pivot/index.d.ts.map +1 -1
  182. package/dist/xlsx/pivot/measures.d.ts +1 -1
  183. package/dist/xlsx/pivot/measures.d.ts.map +1 -1
  184. package/dist/xlsx/pivot/page-filter-admission.d.ts +5 -0
  185. package/dist/xlsx/pivot/page-filter-admission.d.ts.map +1 -0
  186. package/dist/xlsx/pivot/page-filter.d.ts +11 -0
  187. package/dist/xlsx/pivot/page-filter.d.ts.map +1 -0
  188. package/dist/xlsx/pivot/read.d.ts.map +1 -1
  189. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
  190. package/dist/xlsx/pivot/values-axis.d.ts +4 -1
  191. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -1
  192. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
  193. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
  194. package/dist/xlsx/ui/index.cjs +95 -12
  195. package/dist/xlsx/ui/index.mjs +95 -12
  196. package/dist/xlsx/ui/ribbon/parts.d.ts +1 -0
  197. package/dist/xlsx/ui/ribbon/parts.d.ts.map +1 -1
  198. package/package.json +2 -2
  199. package/dist/PptxHandler-5UURGJEV.mjs +0 -2
  200. package/dist/PptxHandler-U5XB2HUE.cjs +0 -11
  201. package/dist/pptx/chunks/index-Cuxtr76Y.d.ts.map +0 -1
  202. package/dist/pptx/chunks/index-DUCGeZh7.d.ts.map +0 -1
  203. package/dist/pptx/chunks/smart-art-D-sXa_Nb.d.ts +0 -2980
  204. package/dist/pptx/chunks/smart-art-D-sXa_Nb.d.ts.map +0 -1
  205. package/dist/pptx/chunks/text-operations-BqHmLaLA.d.ts.map +0 -1
@@ -8678,7 +8678,7 @@ function parseRowProperties(row) {
8678
8678
  const result = {};
8679
8679
  const height = first2(trPr, "trHeight");
8680
8680
  const heightTwips = dxa(getW(height, "val"));
8681
- if (heightTwips) {
8681
+ if (heightTwips !== void 0) {
8682
8682
  result.heightTwips = heightTwips;
8683
8683
  result.heightRule = getW(height, "hRule") === "exact" ? "exact" : "atLeast";
8684
8684
  }
@@ -11891,7 +11891,7 @@ function parseRowProperties(row) {
11891
11891
  const result = {};
11892
11892
  const height = first2(trPr, "trHeight");
11893
11893
  const heightTwips = dxa(getW(height, "val"));
11894
- if (heightTwips) {
11894
+ if (heightTwips !== void 0) {
11895
11895
  result.heightTwips = heightTwips;
11896
11896
  result.heightRule = getW(height, "hRule") === "exact" ? "exact" : "atLeast";
11897
11897
  }
@@ -11885,7 +11885,7 @@ function parseRowProperties(row) {
11885
11885
  const result = {};
11886
11886
  const height = first2(trPr, "trHeight");
11887
11887
  const heightTwips = dxa(getW(height, "val"));
11888
- if (heightTwips) {
11888
+ if (heightTwips !== void 0) {
11889
11889
  result.heightTwips = heightTwips;
11890
11890
  result.heightRule = getW(height, "hRule") === "exact" ? "exact" : "atLeast";
11891
11891
  }
@@ -1 +1 @@
1
- {"version":3,"file":"adapt-table.d.ts","sourceRoot":"","sources":["../../../docx/layout/adapt-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,eAAe,EAEpB,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EACX,YAAY,EAGZ,eAAe,EACf,WAAW,EAGX,MAAM,SAAS,CAAC;AAWjB,qFAAqF;AACrF,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED,wBAAgB,MAAM,CACrB,IAAI,EAAE,eAAe,GAAG,SAAS,EACjC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,mBAAmB,UAAQ,GACzB,YAAY,GAAG,SAAS,CAoB1B;AAgBD;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,aAAa,EACpB,cAAc,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,eAAe,EACzD,OAAO,UAAQ,GACb,WAAW,CAoFb"}
1
+ {"version":3,"file":"adapt-table.d.ts","sourceRoot":"","sources":["../../../docx/layout/adapt-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,eAAe,EAEpB,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EACX,YAAY,EAGZ,eAAe,EACf,WAAW,EAGX,MAAM,SAAS,CAAC;AAWjB,qFAAqF;AACrF,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED,wBAAgB,MAAM,CACrB,IAAI,EAAE,eAAe,GAAG,SAAS,EACjC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,mBAAmB,UAAQ,GACzB,YAAY,GAAG,SAAS,CAoB1B;AAiBD;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,aAAa,EACpB,cAAc,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,eAAe,EACzD,OAAO,UAAQ,GACb,WAAW,CAsFb"}
@@ -1 +1 @@
1
- {"version":3,"file":"flow-table.d.ts","sourceRoot":"","sources":["../../../docx/layout/flow-table.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,SAAS,CAAC;AAG3D;;;;;;GAMG;AACH,wBAAgB,UAAU,CACzB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EAC/B,gBAAgB,CAAC,EAAE,kBAAkB,GACnC,IAAI,CA8QN"}
1
+ {"version":3,"file":"flow-table.d.ts","sourceRoot":"","sources":["../../../docx/layout/flow-table.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,SAAS,CAAC;AAG3D;;;;;;GAMG;AACH,wBAAgB,UAAU,CACzB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EAC/B,gBAAgB,CAAC,EAAE,kBAAkB,GACnC,IAAI,CAwUN"}
@@ -4526,10 +4526,14 @@ function fontOf(run) {
4526
4526
  };
4527
4527
  }
4528
4528
  var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
4529
- function runTextWidth(text2, run, measurer) {
4529
+ function runTextWidth(text2, run, measurer, font = fontOf(run)) {
4530
+ let characters = 0;
4531
+ if (run.characterSpacingPx) {
4532
+ for (const _segment of graphemes2.segment(text2)) characters++;
4533
+ }
4530
4534
  return Math.max(
4531
4535
  0,
4532
- measurer.widthOf(text2, fontOf(run)) * (run.textScalePercent ?? 100) / 100 + [...graphemes2.segment(text2)].length * (run.characterSpacingPx ?? 0)
4536
+ measurer.widthOf(text2, font) * (run.textScalePercent ?? 100) / 100 + characters * (run.characterSpacingPx ?? 0)
4533
4537
  );
4534
4538
  }
4535
4539
  function resolveIndents(paragraph) {
@@ -4663,8 +4667,45 @@ function alignFragments(fragments, width, isLastLine, effectiveAlign) {
4663
4667
  return offset === 0 ? fragments : fragments.map((f) => ({ ...f, xPx: f.xPx + offset }));
4664
4668
  }
4665
4669
 
4670
+ // docx/layout/paragraph-cache.ts
4671
+ var sessions = /* @__PURE__ */ new WeakMap();
4672
+ function registerParagraphCache(measurer) {
4673
+ sessions.set(measurer, /* @__PURE__ */ new Map());
4674
+ }
4675
+ function cachedParagraphLayout(measurer, key, note, compute) {
4676
+ const cache = sessions.get(measurer);
4677
+ if (!cache) return compute(note);
4678
+ const { index, signature } = key();
4679
+ const cached = cache.get(index);
4680
+ if (cached?.signature === signature) {
4681
+ for (const warning of cached.warnings) note(warning);
4682
+ return structuredClone(cached.result);
4683
+ }
4684
+ const warnings = [];
4685
+ const result = compute((warning) => {
4686
+ warnings.push(warning);
4687
+ note(warning);
4688
+ });
4689
+ if (!cache.has(index) && cache.size >= 4e3) cache.delete(cache.keys().next().value);
4690
+ cache.set(index, { signature, result: structuredClone(result), warnings });
4691
+ return result;
4692
+ }
4693
+
4666
4694
  // docx/layout/paragraph-layout.ts
4667
4695
  function layoutParagraph(paragraph, contentWidthPx, measurer, note, lineBox, startToken = 0) {
4696
+ if (lineBox)
4697
+ return measureParagraph(paragraph, contentWidthPx, measurer, note, lineBox, startToken);
4698
+ return cachedParagraphLayout(
4699
+ measurer,
4700
+ () => ({
4701
+ index: JSON.stringify([paragraph.id, contentWidthPx, startToken]),
4702
+ signature: JSON.stringify(paragraph)
4703
+ }),
4704
+ note,
4705
+ (report) => measureParagraph(paragraph, contentWidthPx, measurer, report, void 0, startToken)
4706
+ );
4707
+ }
4708
+ function measureParagraph(paragraph, contentWidthPx, measurer, note, lineBox, startToken = 0) {
4668
4709
  const { leftPx, rightPx, firstLineExtraPx: initialIndent } = resolveIndents(paragraph);
4669
4710
  const firstLineExtraPx = startToken ? 0 : initialIndent;
4670
4711
  const bodyWidth = Math.max(1, contentWidthPx - leftPx - rightPx);
@@ -4721,7 +4762,8 @@ function layoutParagraph(paragraph, contentWidthPx, measurer, note, lineBox, sta
4721
4762
  const tokenWidth = (token) => token.kind === "word" || token.kind === "space" ? runTextWidth(
4722
4763
  token.text,
4723
4764
  expectDefined(paragraph.runs[token.runIndex], "token run"),
4724
- measurer
4765
+ measurer,
4766
+ fonts[token.runIndex]
4725
4767
  ) : token.kind === "object" ? paragraph.runs[token.runIndex]?.object?.widthPx ?? 0 : 0;
4726
4768
  const widths = tokens.map(tokenWidth);
4727
4769
  const ends = /* @__PURE__ */ new Set(["tab", "lineBreak", "pageBreak", "columnBreak"]);
@@ -4897,6 +4939,75 @@ function widowControlEnabled(value) {
4897
4939
  return value !== false;
4898
4940
  }
4899
4941
 
4942
+ // docx/layout/nested-frame-profile.ts
4943
+ var equal = (a, b) => a !== void 0 && b !== void 0 && a.style === b.style && a.color === b.color && Math.abs(a.widthPx - b.widthPx) < 1e-6;
4944
+ function nestedFrameProfile(table, tableWidthPx = table.widthPx) {
4945
+ const sides = table.rows.flatMap(
4946
+ (row) => row.cells.flatMap(
4947
+ (cell) => ["top", "right", "bottom", "left"].map((side) => cell.borders?.[side])
4948
+ )
4949
+ );
4950
+ if (sides.every((side) => !side)) return { leftPx: 0, rightPx: 0, bottomPx: 0 };
4951
+ if (!sides.every((side) => side?.style === "solid" && side.widthPx > 0)) return void 0;
4952
+ const first3 = table.rows[0], left = first3.cells[0].borders.left, right = first3.cells.at(-1).borders.right;
4953
+ for (const [index, row] of table.rows.entries()) {
4954
+ if (row.cells.length !== first3.cells.length || !equal(row.cells[0]?.borders?.left, left) || !equal(row.cells.at(-1)?.borders?.right, right))
4955
+ return void 0;
4956
+ for (const [column, cell] of row.cells.entries()) {
4957
+ const sourceWidth = cell.widthPx ?? (tableWidthPx === void 0 ? void 0 : tableWidthPx / row.cells.length);
4958
+ const paintWidth = sourceWidth === void 0 ? void 0 : sourceWidth + (cell.borders.left.widthPx - cell.borders.right.widthPx) / 2 + (column === row.cells.length - 1 ? cell.borders.right.widthPx : 0);
4959
+ if (paintWidth !== void 0 && paintWidth <= 0) return void 0;
4960
+ if (!equal(cell.borders?.top, row.cells[0]?.borders?.top) || !equal(cell.borders?.bottom, row.cells[0]?.borders?.bottom))
4961
+ return void 0;
4962
+ if (column && !equal(row.cells[column - 1]?.borders?.right, cell.borders?.left))
4963
+ return void 0;
4964
+ if (index) {
4965
+ const previous = table.rows[index - 1].cells[column];
4966
+ if (previous.xPx !== cell.xPx || previous.widthPx !== cell.widthPx || !equal(previous.borders?.bottom, cell.borders?.top))
4967
+ return void 0;
4968
+ }
4969
+ }
4970
+ }
4971
+ return {
4972
+ leftPx: left.widthPx,
4973
+ rightPx: right.widthPx,
4974
+ bottomPx: table.rows.at(-1).cells[0].borders.bottom.widthPx
4975
+ };
4976
+ }
4977
+
4978
+ // docx/layout/nested-fragment-edges.ts
4979
+ var plain = (paragraph) => !paragraph.keepLines && !paragraph.keepNext && !paragraph.pageBreakBefore && !paragraph.footnotes?.length && !paragraph.runs.some((run) => run.footnoteReferenceId !== void 0 || run.breakAfter);
4980
+ function nestedFragmentEdges(table) {
4981
+ if (table.widthPx === void 0 || !Number.isFinite(table.widthPx) || table.widthPx <= 0 || table.rows.length < 2 || !nestedFrameProfile(table, table.widthPx) || table.rows.some(
4982
+ (row) => row.heightPx !== void 0 || row.heightSpecified || row.cantSplit || row.isHeader || row.cells.length !== 2 || row.cells.some(
4983
+ (cell) => (cell.gridSpan ?? 1) !== 1 || cell.verticalMerge !== void 0 || cell.verticalAlign && cell.verticalAlign !== "top" || cell.blocks?.some((block) => block.kind !== "paragraph") || !(cell.blocks ?? cell.paragraphs).every(
4984
+ (block) => block.kind === "paragraph" && plain(block)
4985
+ )
4986
+ )
4987
+ ))
4988
+ return void 0;
4989
+ const top = table.rows[0].cells.map((cell) => cell.borders?.top);
4990
+ const bottom = table.rows.at(-1).cells.map((cell) => cell.borders?.bottom);
4991
+ return top.every(Boolean) && bottom.every(Boolean) ? { top, bottom } : void 0;
4992
+ }
4993
+ function reflowNestedFragments(row) {
4994
+ if (row.heightPx !== void 0 || row.heightSpecified || row.cantSplit || row.isHeader || row.cells.length !== 2)
4995
+ return false;
4996
+ let tables = 0;
4997
+ for (const cell of row.cells) {
4998
+ if ((cell.gridSpan ?? 1) !== 1 || cell.verticalMerge !== void 0) return false;
4999
+ if (cell.verticalAlign && cell.verticalAlign !== "top") return false;
5000
+ for (const [index, block] of (cell.blocks ?? cell.paragraphs).entries()) {
5001
+ if (block.kind === "paragraph") {
5002
+ if (!plain(block)) return false;
5003
+ } else {
5004
+ if (index !== 0 || !nestedFragmentEdges(block) || ++tables > 1) return false;
5005
+ }
5006
+ }
5007
+ }
5008
+ return tables === 1;
5009
+ }
5010
+
4900
5011
  // docx/layout/table-content.ts
4901
5012
  function cellContentBottom(boxes, paddingBottom = 0) {
4902
5013
  return Math.max(
@@ -4930,44 +5041,21 @@ function clipTableFrames(tables, start, end, inset = 0) {
4930
5041
  }
4931
5042
  ];
4932
5043
  });
4933
- return [{ ...table, yPx: top - start + inset, heightPx: bottom - top, rows }];
4934
- });
4935
- }
4936
-
4937
- // docx/layout/nested-frame-profile.ts
4938
- var equal = (a, b) => a !== void 0 && b !== void 0 && a.style === b.style && a.color === b.color && Math.abs(a.widthPx - b.widthPx) < 1e-6;
4939
- function nestedFrameProfile(table, tableWidthPx = table.widthPx) {
4940
- const sides = table.rows.flatMap(
4941
- (row) => row.cells.flatMap(
4942
- (cell) => ["top", "right", "bottom", "left"].map((side) => cell.borders?.[side])
4943
- )
4944
- );
4945
- if (sides.every((side) => !side)) return { leftPx: 0, rightPx: 0, bottomPx: 0 };
4946
- if (!sides.every((side) => side?.style === "solid" && side.widthPx > 0)) return void 0;
4947
- const first3 = table.rows[0], left = first3.cells[0].borders.left, right = first3.cells.at(-1).borders.right;
4948
- for (const [index, row] of table.rows.entries()) {
4949
- if (row.cells.length !== first3.cells.length || !equal(row.cells[0]?.borders?.left, left) || !equal(row.cells.at(-1)?.borders?.right, right))
4950
- return void 0;
4951
- for (const [column, cell] of row.cells.entries()) {
4952
- const sourceWidth = cell.widthPx ?? (tableWidthPx === void 0 ? void 0 : tableWidthPx / row.cells.length);
4953
- const paintWidth = sourceWidth === void 0 ? void 0 : sourceWidth + (cell.borders.left.widthPx - cell.borders.right.widthPx) / 2 + (column === row.cells.length - 1 ? cell.borders.right.widthPx : 0);
4954
- if (paintWidth !== void 0 && paintWidth <= 0) return void 0;
4955
- if (!equal(cell.borders?.top, row.cells[0]?.borders?.top) || !equal(cell.borders?.bottom, row.cells[0]?.borders?.bottom))
4956
- return void 0;
4957
- if (column && !equal(row.cells[column - 1]?.borders?.right, cell.borders?.left))
4958
- return void 0;
4959
- if (index) {
4960
- const previous = table.rows[index - 1].cells[column];
4961
- if (previous.xPx !== cell.xPx || previous.widthPx !== cell.widthPx || !equal(previous.borders?.bottom, cell.borders?.top))
4962
- return void 0;
5044
+ if (table.fragmentEdges && rows.length) {
5045
+ const edges = table.fragmentEdges;
5046
+ for (const [row, side] of [
5047
+ [rows[0], "top"],
5048
+ [rows.at(-1), "bottom"]
5049
+ ]) {
5050
+ if (row.geometry)
5051
+ row.geometry = row.geometry.map((cell, index) => ({
5052
+ ...cell,
5053
+ borders: { ...cell.borders, [side]: edges[side][index] }
5054
+ }));
4963
5055
  }
4964
5056
  }
4965
- }
4966
- return {
4967
- leftPx: left.widthPx,
4968
- rightPx: right.widthPx,
4969
- bottomPx: table.rows.at(-1).cells[0].borders.bottom.widthPx
4970
- };
5057
+ return [{ ...table, yPx: top - start + inset, heightPx: bottom - top, rows }];
5058
+ });
4971
5059
  }
4972
5060
 
4973
5061
  // docx/layout/table-cell-layout.ts
@@ -4977,7 +5065,7 @@ function cellParagraphs(cell) {
4977
5065
  );
4978
5066
  return cell.blocks ? walk(cell.blocks) : cell.paragraphs;
4979
5067
  }
4980
- function stackCellBlocks(cell, width, measurer, note, top, starts) {
5068
+ function stackCellBlocks(cell, width, measurer, note, top, starts, physicalFragments = false) {
4981
5069
  if (!cell.blocks)
4982
5070
  return stackParagraphs(
4983
5071
  starts ? cell.paragraphs.filter((p) => starts.has(p.id)) : cell.paragraphs,
@@ -4998,6 +5086,7 @@ function stackCellBlocks(cell, width, measurer, note, top, starts) {
4998
5086
  y = result.heightPx;
4999
5087
  continue;
5000
5088
  }
5089
+ const edges = physicalFragments ? nestedFragmentEdges(block) : void 0;
5001
5090
  const tableWidth = block.widthPx ?? width;
5002
5091
  const profile = nestedFrameProfile(block, tableWidth);
5003
5092
  const reserveBorders = profile !== void 0;
@@ -5015,13 +5104,21 @@ function stackCellBlocks(cell, width, measurer, note, top, starts) {
5015
5104
  widthPx: paintedWidth,
5016
5105
  yPx: y,
5017
5106
  heightPx: 0,
5018
- rows: []
5107
+ rows: [],
5108
+ ...edges ? { fragmentEdges: edges } : {}
5019
5109
  };
5020
5110
  for (const row of block.rows) {
5021
5111
  if (starts && !row.cells.some((nested) => cellParagraphs(nested).some((p) => starts.has(p.id))))
5022
5112
  continue;
5113
+ const visibleRow = edges && starts && !frame.rows.length ? {
5114
+ ...row,
5115
+ cells: row.cells.map((cell2, index) => ({
5116
+ ...cell2,
5117
+ borders: { ...cell2.borders, top: edges.top[index] }
5118
+ }))
5119
+ } : row;
5023
5120
  const layout = layoutRow(
5024
- row,
5121
+ visibleRow,
5025
5122
  tableWidth,
5026
5123
  measurer,
5027
5124
  note,
@@ -5047,6 +5144,7 @@ function stackCellBlocks(cell, width, measurer, note, top, starts) {
5047
5144
  xPx: x + geometry.xPx + geometry.paddingLeftPx + (paragraph.xPx ?? 0),
5048
5145
  widthPx: paragraph.widthPx ?? Math.max(1, geometry.widthPx - geometry.paddingLeftPx - geometry.paddingRightPx),
5049
5146
  readOnly: true,
5147
+ ...edges ? { tableFragmentBottomPx: edges.bottom[index].widthPx } : {},
5050
5148
  tableFrameInsets: {
5051
5149
  top: (paragraph.tableFrameInsets?.top ?? 0) + (reserveBorders ? geometry.borders?.top?.widthPx ?? 0 : 0),
5052
5150
  bottom: (paragraph.tableFrameInsets?.bottom ?? 0) + (reserveBorders ? geometry.borders?.bottom?.widthPx ?? 0 : 0)
@@ -5095,7 +5193,7 @@ function stackParagraphs(paragraphs, widthPx, measurer, note, topPx = 0, startTo
5095
5193
  }
5096
5194
  return { heightPx: y, boxes };
5097
5195
  }
5098
- function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens, frameBorders = false, frameLeftBorderPx) {
5196
+ function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens, frameBorders = false, frameLeftBorderPx, physicalFragments = reflowNestedFragments(row)) {
5099
5197
  const count = row.cells.length || 1;
5100
5198
  let x = 0;
5101
5199
  const geometry = [];
@@ -5121,7 +5219,8 @@ function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens, fr
5121
5219
  measurer,
5122
5220
  note,
5123
5221
  padding.top,
5124
- starts
5222
+ starts,
5223
+ physicalFragments
5125
5224
  );
5126
5225
  const heightPx2 = content2.heightPx + padding.bottom;
5127
5226
  geometry.push({
@@ -5158,16 +5257,16 @@ function splitCellAtHeight(boxes, cutHeightPx, paragraphCuts) {
5158
5257
  let beforeHeightPx = 0;
5159
5258
  for (const box of boxes) {
5160
5259
  const cut = paragraphCuts?.get(box.blockId) ?? cutHeightPx;
5161
- if (box.yPx + box.heightPx + (box.tableFrameInsets?.bottom ?? 0) <= cut) {
5260
+ if (box.yPx + box.heightPx + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0) <= cut) {
5162
5261
  before.push(box);
5163
5262
  beforeHeightPx = Math.max(
5164
5263
  beforeHeightPx,
5165
- box.yPx + box.heightPx + (box.tableFrameInsets?.bottom ?? 0)
5264
+ box.yPx + box.heightPx + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0)
5166
5265
  );
5167
5266
  continue;
5168
5267
  }
5169
5268
  const beforeLines = box.lines.filter(
5170
- (line2) => box.yPx + line2.yPx + line2.heightPx + (box.tableFrameInsets?.bottom ?? 0) <= cut
5269
+ (line2) => box.yPx + line2.yPx + line2.heightPx + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0) <= cut
5171
5270
  );
5172
5271
  const afterLines = box.lines.slice(beforeLines.length);
5173
5272
  if (beforeLines.length) {
@@ -5175,7 +5274,7 @@ function splitCellAtHeight(boxes, cutHeightPx, paragraphCuts) {
5175
5274
  before.push({ ...box, heightPx: bottom, lines: beforeLines });
5176
5275
  beforeHeightPx = Math.max(
5177
5276
  beforeHeightPx,
5178
- box.yPx + bottom + (box.tableFrameInsets?.bottom ?? 0)
5277
+ box.yPx + bottom + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0)
5179
5278
  );
5180
5279
  }
5181
5280
  if (afterLines.length) {
@@ -5983,6 +6082,55 @@ function placeParagraph(cursor, placement, note) {
5983
6082
  }
5984
6083
  }
5985
6084
 
6085
+ // docx/layout/table-paragraph-keeps.ts
6086
+ function tableParagraphKeeps(table) {
6087
+ const row = table.rows[0];
6088
+ if (table.rows.length !== 1 || !row || row.cells.length !== 2 || row.heightPx !== void 0 || row.heightSpecified || row.cantSplit || row.isHeader || table.widthPx === void 0 || !Number.isFinite(table.widthPx) || table.widthPx <= 0 || !nestedFrameProfile(table, table.widthPx) || row.cells.some(
6089
+ (cell) => !cell.borders?.top || (cell.gridSpan ?? 1) !== 1 || cell.verticalMerge !== void 0 || cell.verticalAlign && cell.verticalAlign !== "top" || cell.blocks?.some((block) => block.kind !== "paragraph")
6090
+ ))
6091
+ return void 0;
6092
+ const paragraphs = row.cells.flatMap(cellParagraphs);
6093
+ if (paragraphs.some(
6094
+ (p) => p.keepNext || p.pageBreakBefore || p.footnotes?.length || p.floats?.length || p.borders || p.shading || p.widowControl !== false || p.lineSpacingRule !== "exact" || p.lineSpacingTwips === void 0 || !Number.isFinite(p.lineSpacingTwips) || p.lineSpacingTwips <= 0 || (p.spacingBeforeTwips ?? 0) !== 0 || (p.spacingAfterTwips ?? 0) !== 0 || p.runs.some((run) => run.footnoteReferenceId !== void 0 || run.breakAfter || run.object)
6095
+ ))
6096
+ return void 0;
6097
+ const sources = new Map(paragraphs.map((p) => [p.id, p]));
6098
+ if (sources.size !== paragraphs.length || !paragraphs.some((p) => p.keepLines)) return void 0;
6099
+ return new TableParagraphKeeps(sources);
6100
+ }
6101
+ var TableParagraphKeeps = class {
6102
+ constructor(sources) {
6103
+ this.sources = sources;
6104
+ }
6105
+ sources;
6106
+ /** Before an ordinary row starts, a first kept paragraph can defer the entire row. */
6107
+ startupMinimum(row) {
6108
+ return Math.max(
6109
+ 0,
6110
+ ...row.cells.map((cell, index) => {
6111
+ const first3 = cell[0];
6112
+ return first3 && this.sources.get(first3.blockId)?.keepLines ? first3.yPx + first3.heightPx + (row.cellPadding?.[index]?.bottom ?? 0) : 0;
6113
+ })
6114
+ );
6115
+ }
6116
+ /** Defer an unstarted paragraph and its following cell content, leaving other cells independent. */
6117
+ cuts(row, available, fresh) {
6118
+ const cuts = /* @__PURE__ */ new Map();
6119
+ row.cells.forEach((cell, index) => {
6120
+ const padding = row.cellPadding?.[index] ?? { top: 0, bottom: 0 };
6121
+ let deferred = false;
6122
+ for (const [position, box] of cell.entries()) {
6123
+ const source = this.sources.get(box.blockId);
6124
+ const atFreshOrigin = fresh && position === 0 && Math.abs(box.yPx - padding.top) < 1e-6;
6125
+ if (!deferred && source?.keepLines && (box.lines[0]?.firstToken ?? 0) === 0 && box.yPx + box.heightPx + padding.bottom > available + 1e-6 && !atFreshOrigin)
6126
+ deferred = true;
6127
+ if (deferred) cuts.set(box.blockId, 0);
6128
+ }
6129
+ });
6130
+ return cuts.size ? cuts : void 0;
6131
+ }
6132
+ };
6133
+
5986
6134
  // docx/layout/table-note-stories.ts
5987
6135
  function independentNoteStories(cell) {
5988
6136
  const first3 = cell.blocks?.[0];
@@ -6022,7 +6170,7 @@ function measuredNoteReferences(paragraphs) {
6022
6170
  }
6023
6171
 
6024
6172
  // docx/layout/table-border-layout.ts
6025
- function layoutBorderedRow(row, width, measurer, note, profile, remaining) {
6173
+ function layoutBorderedRow(row, width, measurer, note, profile, remaining, physicalFragments) {
6026
6174
  const reserved = profile !== void 0 && (profile.leftPx > 0 || profile.rightPx > 0 || profile.bottomPx > 0);
6027
6175
  const layout = layoutRow(
6028
6176
  row,
@@ -6032,7 +6180,8 @@ function layoutBorderedRow(row, width, measurer, note, profile, remaining) {
6032
6180
  remaining,
6033
6181
  void 0,
6034
6182
  reserved,
6035
- profile?.leftPx
6183
+ profile?.leftPx,
6184
+ physicalFragments
6036
6185
  );
6037
6186
  if (!reserved) return layout;
6038
6187
  const bottom = Math.max(0, ...layout.geometry.map((cell) => cell.borders?.bottom?.widthPx ?? 0));
@@ -6332,6 +6481,12 @@ var TableFootnotes = class {
6332
6481
  function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6333
6482
  const firstBodyRow = table.rows.findIndex((row) => !row.isHeader);
6334
6483
  const headerRows = table.rows.slice(0, firstBodyRow < 0 ? table.rows.length : firstBodyRow);
6484
+ const nativeFragments = new Map(table.rows.map((row) => [row, reflowNestedFragments(row)]));
6485
+ const paragraphKeeps = tableParagraphKeeps(table);
6486
+ const hasParagraphKeeps = table.rows.some(
6487
+ (row) => row.cells.some((cell) => cellParagraphs(cell).some((paragraph) => paragraph.keepLines))
6488
+ );
6489
+ let keepWarning = false;
6335
6490
  const xPosition = () => {
6336
6491
  const width = (table.widthPx ?? cursor.columnWidthPx) + (activeBorders ? (profile.leftPx + profile.rightPx) / 2 : 0);
6337
6492
  return table.alignment === "center" ? Math.max(0, (cursor.columnWidthPx - width) / 2) : table.alignment === "right" ? Math.max(0, cursor.columnWidthPx - width) : table.indentPx ?? 0;
@@ -6342,13 +6497,14 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6342
6497
  note(
6343
6498
  "Ordinary table border occupancy remains approximate for missing edges, non-solid or conflicting shared borders and changing row grids."
6344
6499
  );
6345
- const layoutRow2 = (row, width, m, n2, remaining) => layoutBorderedRow(
6500
+ const layoutRow2 = (row, width, m, n2, remaining, sourceRow = row) => layoutBorderedRow(
6346
6501
  row,
6347
6502
  activeBorders ? table.widthPx ?? width : width,
6348
6503
  m,
6349
6504
  n2,
6350
6505
  profile,
6351
- remaining
6506
+ remaining,
6507
+ nativeFragments.get(sourceRow) ?? false
6352
6508
  );
6353
6509
  const fragmentBorders = new TableFragmentBorders();
6354
6510
  let fragmentRows = [];
@@ -6405,6 +6561,17 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6405
6561
  let remainingRow = initial;
6406
6562
  while (remainingRow) {
6407
6563
  fragmentHeight += fragmentBorders.remove(fragmentRows.at(-1));
6564
+ const keeps = paragraphKeeps && cursor.page.columns.length === 1 && cursor.column.startYPx === void 0 && Math.abs(cursor.remainingHeightPx() - (cursor.columnHeightPx - cursor.usedColumnHeightPx)) < 1e-6 ? paragraphKeeps : void 0;
6565
+ if (hasParagraphKeeps && !keeps && !keepWarning) {
6566
+ note(
6567
+ "Table-cell keep-lines pagination remains approximate outside the measured ordinary automatic two-cell, top-aligned, single-column, note-free row with direct exact-spaced paragraphs, zero paragraph spacing and widow control off."
6568
+ );
6569
+ keepWarning = true;
6570
+ }
6571
+ if (keeps && remainingRow === initial && !cursor.atColumnTop && keeps.startupMinimum(remainingRow) > cursor.remainingHeightPx() - fragmentHeight + 1e-6) {
6572
+ startNewFragment();
6573
+ continue;
6574
+ }
6408
6575
  const minimum = cantSplit ? Math.min(remainingRow.heightPx, cursor.columnHeightPx) : Math.min(
6409
6576
  ...remainingRow.cells.flatMap(
6410
6577
  (cell, index) => cell.map(
@@ -6421,7 +6588,8 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6421
6588
  cursor.columnWidthPx,
6422
6589
  measurer,
6423
6590
  note,
6424
- remainingRow.cells
6591
+ remainingRow.cells,
6592
+ row
6425
6593
  );
6426
6594
  if (fragmentRows.length) {
6427
6595
  fragmentRows = [];
@@ -6431,7 +6599,7 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6431
6599
  continue;
6432
6600
  }
6433
6601
  }
6434
- if (footnotes) {
6602
+ if (footnotes && !keeps) {
6435
6603
  const selected = footnotes.choose(remainingRow, cantSplit);
6436
6604
  if (selected) {
6437
6605
  if (selected.layout === remainingRow) {
@@ -6453,7 +6621,8 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6453
6621
  cursor.columnWidthPx,
6454
6622
  measurer,
6455
6623
  note,
6456
- after2.cells
6624
+ after2.cells,
6625
+ row
6457
6626
  ) : after2;
6458
6627
  continue;
6459
6628
  }
@@ -6466,7 +6635,8 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6466
6635
  cursor.columnWidthPx,
6467
6636
  measurer,
6468
6637
  note,
6469
- remainingRow === initial ? void 0 : remainingRow.cells
6638
+ remainingRow === initial ? void 0 : remainingRow.cells,
6639
+ row
6470
6640
  );
6471
6641
  continue;
6472
6642
  }
@@ -6501,7 +6671,17 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6501
6671
  remainingRow = null;
6502
6672
  continue;
6503
6673
  }
6504
- const { before, after } = splitRowAtHeight(remainingRow, Math.max(0, remaining));
6674
+ const paragraphCuts = keeps?.cuts(
6675
+ remainingRow,
6676
+ remaining,
6677
+ cursor.atColumnTop && fragmentRows.length === 0
6678
+ );
6679
+ const { before, after } = splitRowAtHeight(
6680
+ remainingRow,
6681
+ Math.max(0, remaining),
6682
+ void 0,
6683
+ paragraphCuts
6684
+ );
6505
6685
  if (!before.cells.some((cell) => cell.length) && cursor.atColumnTop && fragmentRows.every((row2) => row2.repeated)) {
6506
6686
  note(
6507
6687
  "A table row cannot fit a line in an empty page/column and was placed without splitting."
@@ -6513,17 +6693,24 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6513
6693
  const previousWidth = cursor.columnWidthPx;
6514
6694
  if (before.cells.some((cell) => cell.length)) fragmentRows.push(toRowBox(before, false));
6515
6695
  startNewFragment();
6516
- remainingRow = after && previousWidth !== cursor.columnWidthPx ? layoutRow2(
6696
+ remainingRow = after && (paragraphCuts || previousWidth !== cursor.columnWidthPx || nativeFragments.get(row)) ? layoutRow2(
6517
6697
  { ...row, heightPx: 0, heightRule: "atLeast" },
6518
6698
  cursor.columnWidthPx,
6519
6699
  measurer,
6520
6700
  note,
6521
- after.cells
6701
+ after.cells,
6702
+ row
6522
6703
  ) : after;
6523
6704
  }
6524
6705
  }
6525
6706
  for (const row of table.rows) {
6526
6707
  const layout = layoutRow2(row, cursor.columnWidthPx, measurer, note);
6708
+ if (layout.heightPx > cursor.remainingHeightPx() && !nativeFragments.get(row) && row.cells.some(
6709
+ (cell) => cell.blocks?.some((block) => block.kind === "table" && block.rows.length > 1)
6710
+ ))
6711
+ note(
6712
+ "Nested physical border edges at page cuts remain approximate outside automatic, top-aligned tables with two or more two-cell, note-free rows, direct paragraphs and complete shared borders."
6713
+ );
6527
6714
  if (activeBorders && layout.heightPx > cursor.remainingHeightPx() && row.cells.some(
6528
6715
  (cell) => (!measuredNoteReferences(row.cells.flatMap(cellParagraphs)) || !independentNoteStories(cell)) && cell.blocks?.some((block) => block.kind === "table") && cellParagraphs(cell).some((p) => p.footnotes?.length)
6529
6716
  ))
@@ -6787,9 +6974,9 @@ var SectionFlow = class {
6787
6974
  const page = this.cursor.page;
6788
6975
  const exclusions = this.exclusions?.get(page.index);
6789
6976
  if (!exclusions) return void 0;
6790
- const plain = this.paragraphLayout(index);
6977
+ const plain2 = this.paragraphLayout(index);
6791
6978
  const topPx = page.marginTopPx + this.cursor.y + spacingBeforePx;
6792
- const bottomPx = topPx + plain.contentHeightPx;
6979
+ const bottomPx = topPx + plain2.contentHeightPx;
6793
6980
  if (!exclusions.some((item) => item.yPx < bottomPx && item.yPx + item.heightPx > topPx))
6794
6981
  return void 0;
6795
6982
  return layoutParagraph(
@@ -7054,6 +7241,7 @@ function border(side, theme, preserveSingleWidth = false) {
7054
7241
  function rowLayout(props) {
7055
7242
  if (!props) return {};
7056
7243
  return {
7244
+ ...props.heightTwips !== void 0 ? { heightSpecified: true } : {},
7057
7245
  ...props.heightTwips ? { heightPx: twipsToPx2(props.heightTwips), heightRule: props.heightRule ?? "atLeast" } : {},
7058
7246
  ...props.cantSplit ? { cantSplit: true } : {},
7059
7247
  ...props.header ? { isHeader: true } : {}
@@ -7118,6 +7306,8 @@ function adaptTable(table, model, adaptParagraph, _nested = false) {
7118
7306
  const fill = cssHex(visuals.shadingFill);
7119
7307
  return {
7120
7308
  paragraphs: cell.paragraphs.map(adaptParagraph),
7309
+ ...cell.gridSpan !== void 0 ? { gridSpan: cell.gridSpan } : {},
7310
+ ...cell.verticalMerge ? { verticalMerge: cell.verticalMerge } : {},
7121
7311
  ...cell.sourceBlocks ? {
7122
7312
  blocks: cellSourceBlocks(cell).map(
7123
7313
  (block) => block.type === "paragraph" ? adaptParagraph(block) : adaptTable(block, model, adaptParagraph, true)
@@ -7687,6 +7877,20 @@ function cssFontStack(family) {
7687
7877
  );
7688
7878
  }
7689
7879
 
7880
+ // docx/layout/layout-session.ts
7881
+ function createLayoutSession(measurer) {
7882
+ const sessionMeasurer = {
7883
+ widthOf: (text2, font) => measurer.widthOf(text2, font),
7884
+ lineHeightOf: (font) => measurer.lineHeightOf(font),
7885
+ ...measurer.ascentOf ? { ascentOf: measurer.ascentOf.bind(measurer) } : {}
7886
+ };
7887
+ registerParagraphCache(sessionMeasurer);
7888
+ return {
7889
+ layoutDocument: (input) => layoutDocument(input, sessionMeasurer),
7890
+ layoutDocumentModel: (model, options = {}) => layoutDocumentModel(model, sessionMeasurer, options)
7891
+ };
7892
+ }
7893
+
7690
7894
  exports.DEFAULT_FONT_FAMILY = DEFAULT_FONT_FAMILY;
7691
7895
  exports.DEFAULT_FONT_SIZE_PT = DEFAULT_FONT_SIZE_PT;
7692
7896
  exports.DEFAULT_TAB_STOP_PX = DEFAULT_TAB_STOP_PX;
@@ -7699,6 +7903,7 @@ exports.adjustForWidowOrphan = adjustForWidowOrphan;
7699
7903
  exports.appendBreakMarker = appendBreakMarker;
7700
7904
  exports.cellVerticalOffset = cellVerticalOffset;
7701
7905
  exports.createFakeMeasurer = createFakeMeasurer;
7906
+ exports.createLayoutSession = createLayoutSession;
7702
7907
  exports.cssFontStack = cssFontStack;
7703
7908
  exports.fieldDisplayText = fieldDisplayText;
7704
7909
  exports.floatPosition = floatPosition;
@@ -19,4 +19,5 @@ export type { LayoutReviewOptions } from './review-display.js';
19
19
  export { floatPosition, positionFloats, FLOAT_WRAP_NOTE } from './floats.js';
20
20
  export { cssFontStack } from './fonts.js';
21
21
  export { placeTab, type TabPlacement } from './tab-stops.js';
22
+ export { createLayoutSession } from './layout-session.js';
22
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../docx/layout/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../docx/layout/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}