ooxml-core 1.9.0 → 1.11.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 (202) hide show
  1. package/dist/PptxHandler-DNZHAHUY.cjs +12 -0
  2. package/dist/PptxHandler-E44KDHMQ.mjs +3 -0
  3. package/dist/{PptxHandler-EX4WBIQQ.mjs → PptxHandler-NROFYT2N.mjs} +2 -2
  4. package/dist/automation/index.cjs +3236 -2258
  5. package/dist/automation/index.mjs +3236 -2258
  6. package/dist/{chunk-SWF7KVL5.cjs → chunk-2UVH6RHI.cjs} +1608 -1163
  7. package/dist/{chunk-M76PHYRR.mjs → chunk-7DSZI7S6.mjs} +1 -1
  8. package/dist/{chunk-AT66SA5M.cjs → chunk-7QZGRB3T.cjs} +28 -10
  9. package/dist/chunk-ANZ4Q6I3.cjs +21 -0
  10. package/dist/{chunk-CPKNMQLX.cjs → chunk-AWIDASUW.cjs} +25 -2
  11. package/dist/{chunk-SVQZXP3F.mjs → chunk-CBNKBVX5.mjs} +25 -2
  12. package/dist/{chunk-FIELY5PI.mjs → chunk-EC2W2MDY.mjs} +30 -2
  13. package/dist/chunk-EGTRL3QJ.mjs +19 -0
  14. package/dist/chunk-GXHKNSZX.mjs +9 -0
  15. package/dist/{chunk-OXHMZS7B.mjs → chunk-HCXUI5UC.mjs} +943 -273
  16. package/dist/chunk-HDQXPSHY.cjs +17 -0
  17. package/dist/chunk-KTYBFGEY.mjs +14 -0
  18. package/dist/chunk-QOO36KG4.cjs +42 -0
  19. package/dist/chunk-R2KZXD6U.mjs +39 -0
  20. package/dist/{chunk-IGOA57LE.mjs → chunk-U2DF3EGK.mjs} +1 -1
  21. package/dist/{chunk-OB277ZGE.mjs → chunk-UAY26XOI.mjs} +27 -9
  22. package/dist/{chunk-WSO4T2LJ.mjs → chunk-W5ARCUJB.mjs} +26 -3
  23. package/dist/chunk-XZPZHXV4.cjs +12 -0
  24. package/dist/{chunk-LCS3J3QI.mjs → chunk-YB5SRNFS.mjs} +717 -272
  25. package/dist/docx/layout/adapt-table.d.ts +2 -2
  26. package/dist/docx/layout/adapt-table.d.ts.map +1 -1
  27. package/dist/docx/layout/flow-table.d.ts.map +1 -1
  28. package/dist/docx/layout/index.cjs +554 -83
  29. package/dist/docx/layout/index.mjs +554 -84
  30. package/dist/docx/layout/nested-fragment-edges.d.ts +9 -0
  31. package/dist/docx/layout/nested-fragment-edges.d.ts.map +1 -0
  32. package/dist/docx/layout/nested-frame-profile.d.ts +9 -0
  33. package/dist/docx/layout/nested-frame-profile.d.ts.map +1 -0
  34. package/dist/docx/layout/page-cursor.d.ts +2 -0
  35. package/dist/docx/layout/page-cursor.d.ts.map +1 -1
  36. package/dist/docx/layout/result.d.ts +20 -0
  37. package/dist/docx/layout/result.d.ts.map +1 -1
  38. package/dist/docx/layout/table-border-layout.d.ts +16 -0
  39. package/dist/docx/layout/table-border-layout.d.ts.map +1 -0
  40. package/dist/docx/layout/table-cell-layout.d.ts +3 -2
  41. package/dist/docx/layout/table-cell-layout.d.ts.map +1 -1
  42. package/dist/docx/layout/table-content.d.ts +4 -0
  43. package/dist/docx/layout/table-content.d.ts.map +1 -0
  44. package/dist/docx/layout/table-footnotes.d.ts +5 -0
  45. package/dist/docx/layout/table-footnotes.d.ts.map +1 -1
  46. package/dist/docx/layout/table-frames.d.ts +4 -0
  47. package/dist/docx/layout/table-frames.d.ts.map +1 -0
  48. package/dist/docx/layout/table-layout.d.ts +8 -3
  49. package/dist/docx/layout/table-layout.d.ts.map +1 -1
  50. package/dist/docx/layout/table-note-completion.d.ts +5 -0
  51. package/dist/docx/layout/table-note-completion.d.ts.map +1 -0
  52. package/dist/docx/layout/table-note-stories.d.ts +6 -0
  53. package/dist/docx/layout/table-note-stories.d.ts.map +1 -0
  54. package/dist/pptx/automation/index.cjs +801 -296
  55. package/dist/pptx/automation/index.d.ts +5 -4
  56. package/dist/pptx/automation/index.d.ts.map +1 -1
  57. package/dist/pptx/automation/index.mjs +5 -5
  58. package/dist/pptx/chunks/{text-operations-BLodkuXE.d.ts → elements-DD3UGOMd.d.ts} +27 -3248
  59. package/dist/pptx/chunks/elements-DD3UGOMd.d.ts.map +1 -0
  60. package/dist/pptx/chunks/{index-B4cnSPNz.d.ts → index-BZrFyNtU.d.ts} +113 -5
  61. package/dist/pptx/chunks/index-BZrFyNtU.d.ts.map +1 -0
  62. package/dist/pptx/chunks/{index-BZh-IMkN.d.ts → index-DdX02BSm.d.ts} +19 -3
  63. package/dist/pptx/chunks/index-DdX02BSm.d.ts.map +1 -0
  64. package/dist/pptx/chunks/smart-art-ENMMEbmW.d.ts +1512 -0
  65. package/dist/pptx/chunks/smart-art-ENMMEbmW.d.ts.map +1 -0
  66. package/dist/pptx/chunks/text-D49FKllA.d.ts +1473 -0
  67. package/dist/pptx/chunks/text-D49FKllA.d.ts.map +1 -0
  68. package/dist/pptx/chunks/text-operations-CyMTMfID.d.ts +3261 -0
  69. package/dist/pptx/chunks/text-operations-CyMTMfID.d.ts.map +1 -0
  70. package/dist/pptx/cli/index.cjs +801 -296
  71. package/dist/pptx/cli/index.d.ts +1 -1
  72. package/dist/pptx/cli/index.mjs +4 -4
  73. package/dist/pptx/converter/index.cjs +1 -0
  74. package/dist/pptx/converter/index.d.ts +1 -1
  75. package/dist/pptx/converter/index.mjs +2 -2
  76. package/dist/pptx/editor/render/collaboration-live-patch-target.cjs +2 -2
  77. package/dist/pptx/editor/render/collaboration-live-patch-target.mjs +1 -1
  78. package/dist/pptx/editor/render/find-replace.cjs +19 -18
  79. package/dist/pptx/editor/render/find-replace.d.ts +2 -2
  80. package/dist/pptx/editor/render/find-replace.mjs +3 -2
  81. package/dist/pptx/editor/render/font-family-update.cjs +14 -0
  82. package/dist/pptx/editor/render/font-family-update.d.ts +17 -0
  83. package/dist/pptx/editor/render/font-family-update.d.ts.map +1 -0
  84. package/dist/pptx/editor/render/font-family-update.mjs +1 -0
  85. package/dist/pptx/editor/render/paragraph-geometry-overrides.cjs +14 -0
  86. package/dist/pptx/editor/render/paragraph-geometry-overrides.d.ts +17 -0
  87. package/dist/pptx/editor/render/paragraph-geometry-overrides.d.ts.map +1 -0
  88. package/dist/pptx/editor/render/paragraph-geometry-overrides.mjs +12 -0
  89. package/dist/pptx/editor/render/remap-text.cjs +2 -2
  90. package/dist/pptx/editor/render/remap-text.d.ts.map +1 -1
  91. package/dist/pptx/editor/render/remap-text.mjs +1 -1
  92. package/dist/pptx/editor/render/slide-operations.cjs +9 -8
  93. package/dist/pptx/editor/render/slide-operations.mjs +3 -2
  94. package/dist/pptx/editor/render/table-data-grid-ops.cjs +1 -1
  95. package/dist/pptx/editor/render/table-data-grid-ops.mjs +1 -1
  96. package/dist/pptx/editor/render/text-content-style.cjs +18 -0
  97. package/dist/pptx/editor/render/text-content-style.d.ts +9 -0
  98. package/dist/pptx/editor/render/text-content-style.d.ts.map +1 -0
  99. package/dist/pptx/editor/render/text-content-style.mjs +5 -0
  100. package/dist/pptx/editor/render/text-runs-style-patch.cjs +17 -0
  101. package/dist/pptx/editor/render/text-runs-style-patch.d.ts +7 -0
  102. package/dist/pptx/editor/render/text-runs-style-patch.d.ts.map +1 -0
  103. package/dist/pptx/editor/render/text-runs-style-patch.mjs +15 -0
  104. package/dist/pptx/editor/render/text-style-scope.cjs +173 -0
  105. package/dist/pptx/editor/render/text-style-scope.d.ts +76 -0
  106. package/dist/pptx/editor/render/text-style-scope.d.ts.map +1 -0
  107. package/dist/pptx/editor/render/text-style-scope.mjs +164 -0
  108. package/dist/pptx/editor/render/theme-editor-model.cjs +1 -1
  109. package/dist/pptx/editor/render/theme-editor-model.mjs +1 -1
  110. package/dist/pptx/editor/render/update-text-segment-style.cjs +11 -0
  111. package/dist/pptx/editor/render/update-text-segment-style.d.ts +14 -0
  112. package/dist/pptx/editor/render/update-text-segment-style.d.ts.map +1 -0
  113. package/dist/pptx/editor/render/update-text-segment-style.mjs +2 -0
  114. package/dist/pptx/index.cjs +1091 -296
  115. package/dist/pptx/index.d.ts +7 -5
  116. package/dist/pptx/index.mjs +5 -5
  117. package/dist/pptx/smartart-layouts/index.d.ts +1 -1
  118. package/dist/teams/index.cjs +590 -122
  119. package/dist/teams/index.mjs +590 -122
  120. package/dist/visio/date-cache.d.ts +3 -0
  121. package/dist/visio/date-cache.d.ts.map +1 -0
  122. package/dist/visio/edit-commands.d.ts +3 -3
  123. package/dist/visio/edit-commands.d.ts.map +1 -1
  124. package/dist/visio/edit-formatting-scope.d.ts.map +1 -1
  125. package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
  126. package/dist/visio/edit-text-field-commands.d.ts +15 -0
  127. package/dist/visio/edit-text-field-commands.d.ts.map +1 -1
  128. package/dist/visio/edit-text-field.d.ts +2 -2
  129. package/dist/visio/edit-text-field.d.ts.map +1 -1
  130. package/dist/visio/edit.d.ts +1 -1
  131. package/dist/visio/edit.d.ts.map +1 -1
  132. package/dist/visio/index.cjs +501 -220
  133. package/dist/visio/index.d.ts +1 -1
  134. package/dist/visio/index.d.ts.map +1 -1
  135. package/dist/visio/index.mjs +501 -220
  136. package/dist/visio/model.d.ts +6 -0
  137. package/dist/visio/model.d.ts.map +1 -1
  138. package/dist/visio/shape-metadata.d.ts.map +1 -1
  139. package/dist/visio/shapes.d.ts.map +1 -1
  140. package/dist/visio/style.d.ts +1 -1
  141. package/dist/visio/style.d.ts.map +1 -1
  142. package/dist/visio/text-field-display.d.ts +3 -0
  143. package/dist/visio/text-field-display.d.ts.map +1 -1
  144. package/dist/visio/text-field-editability.d.ts +6 -0
  145. package/dist/visio/text-field-editability.d.ts.map +1 -0
  146. package/dist/visio/text-field-fraction.d.ts +3 -0
  147. package/dist/visio/text-field-fraction.d.ts.map +1 -0
  148. package/dist/visio/text-field-independent.d.ts +4 -0
  149. package/dist/visio/text-field-independent.d.ts.map +1 -0
  150. package/dist/visio/text-field-numeric.d.ts +1 -1
  151. package/dist/visio/text-field-numeric.d.ts.map +1 -1
  152. package/dist/visio/text-field-source.d.ts +6 -0
  153. package/dist/visio/text-field-source.d.ts.map +1 -0
  154. package/dist/visio/text-field-system-date.d.ts +4 -0
  155. package/dist/visio/text-field-system-date.d.ts.map +1 -0
  156. package/dist/visio/text-fields.d.ts +1 -0
  157. package/dist/visio/text-fields.d.ts.map +1 -1
  158. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  159. package/dist/visio/ui/index.cjs +514 -221
  160. package/dist/visio/ui/index.mjs +514 -221
  161. package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
  162. package/dist/visio/ui/text-field-catalog.d.ts.map +1 -1
  163. package/dist/xlsx/edit/pivots.d.ts.map +1 -1
  164. package/dist/xlsx/index.cjs +1362 -659
  165. package/dist/xlsx/index.mjs +1361 -660
  166. package/dist/xlsx/load/index.cjs +1091 -430
  167. package/dist/xlsx/load/index.mjs +1091 -430
  168. package/dist/xlsx/model-pivots.d.ts +31 -2
  169. package/dist/xlsx/model-pivots.d.ts.map +1 -1
  170. package/dist/xlsx/pivot/admission.d.ts.map +1 -1
  171. package/dist/xlsx/pivot/aggregate.d.ts +3 -1
  172. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
  173. package/dist/xlsx/pivot/data.d.ts +2 -2
  174. package/dist/xlsx/pivot/data.d.ts.map +1 -1
  175. package/dist/xlsx/pivot/hierarchy-first.d.ts +21 -0
  176. package/dist/xlsx/pivot/hierarchy-first.d.ts.map +1 -0
  177. package/dist/xlsx/pivot/hierarchy.d.ts +2 -4
  178. package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -1
  179. package/dist/xlsx/pivot/index.d.ts +2 -0
  180. package/dist/xlsx/pivot/index.d.ts.map +1 -1
  181. package/dist/xlsx/pivot/measures.d.ts +13 -0
  182. package/dist/xlsx/pivot/measures.d.ts.map +1 -0
  183. package/dist/xlsx/pivot/page-filter-admission.d.ts +5 -0
  184. package/dist/xlsx/pivot/page-filter-admission.d.ts.map +1 -0
  185. package/dist/xlsx/pivot/page-filter.d.ts +11 -0
  186. package/dist/xlsx/pivot/page-filter.d.ts.map +1 -0
  187. package/dist/xlsx/pivot/read.d.ts.map +1 -1
  188. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
  189. package/dist/xlsx/pivot/values-axis.d.ts +12 -0
  190. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -0
  191. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
  192. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
  193. package/dist/xlsx/ui/index.cjs +640 -137
  194. package/dist/xlsx/ui/index.mjs +640 -137
  195. package/package.json +2 -2
  196. package/dist/PptxHandler-AT7FVG5Q.mjs +0 -2
  197. package/dist/PptxHandler-VFSCECPL.cjs +0 -11
  198. package/dist/pptx/chunks/index-B4cnSPNz.d.ts.map +0 -1
  199. package/dist/pptx/chunks/index-BZh-IMkN.d.ts.map +0 -1
  200. package/dist/pptx/chunks/smart-art-Q2kZQtHh.d.ts +0 -2970
  201. package/dist/pptx/chunks/smart-art-Q2kZQtHh.d.ts.map +0 -1
  202. package/dist/pptx/chunks/text-operations-BLodkuXE.d.ts.map +0 -1
@@ -4427,6 +4427,12 @@ function appendBreakMarker(tokens, runIndex, sourceStart, kind) {
4427
4427
  tokens.push({ kind: kind === "page" ? "pageBreak" : "columnBreak", runIndex, sourceStart });
4428
4428
  }
4429
4429
 
4430
+ // docx/layout/result.ts
4431
+ function cellVerticalOffset(geometry, rowHeightPx) {
4432
+ const free = Math.max(0, (geometry.alignmentHeightPx ?? rowHeightPx) - geometry.contentHeightPx);
4433
+ return geometry.verticalAlign === "center" ? free / 2 : geometry.verticalAlign === "bottom" ? free : 0;
4434
+ }
4435
+
4430
4436
  // docx/layout/page-fields.ts
4431
4437
  function fieldDisplayText(run, values) {
4432
4438
  if (!run.field || isFieldLocked(run)) return run.text;
@@ -4891,6 +4897,124 @@ function widowControlEnabled(value) {
4891
4897
  return value !== false;
4892
4898
  }
4893
4899
 
4900
+ // docx/layout/nested-frame-profile.ts
4901
+ 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;
4902
+ function nestedFrameProfile(table, tableWidthPx = table.widthPx) {
4903
+ const sides = table.rows.flatMap(
4904
+ (row) => row.cells.flatMap(
4905
+ (cell) => ["top", "right", "bottom", "left"].map((side) => cell.borders?.[side])
4906
+ )
4907
+ );
4908
+ if (sides.every((side) => !side)) return { leftPx: 0, rightPx: 0, bottomPx: 0 };
4909
+ if (!sides.every((side) => side?.style === "solid" && side.widthPx > 0)) return void 0;
4910
+ const first3 = table.rows[0], left = first3.cells[0].borders.left, right = first3.cells.at(-1).borders.right;
4911
+ for (const [index, row] of table.rows.entries()) {
4912
+ if (row.cells.length !== first3.cells.length || !equal(row.cells[0]?.borders?.left, left) || !equal(row.cells.at(-1)?.borders?.right, right))
4913
+ return void 0;
4914
+ for (const [column, cell] of row.cells.entries()) {
4915
+ const sourceWidth = cell.widthPx ?? (tableWidthPx === void 0 ? void 0 : tableWidthPx / row.cells.length);
4916
+ 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);
4917
+ if (paintWidth !== void 0 && paintWidth <= 0) return void 0;
4918
+ if (!equal(cell.borders?.top, row.cells[0]?.borders?.top) || !equal(cell.borders?.bottom, row.cells[0]?.borders?.bottom))
4919
+ return void 0;
4920
+ if (column && !equal(row.cells[column - 1]?.borders?.right, cell.borders?.left))
4921
+ return void 0;
4922
+ if (index) {
4923
+ const previous = table.rows[index - 1].cells[column];
4924
+ if (previous.xPx !== cell.xPx || previous.widthPx !== cell.widthPx || !equal(previous.borders?.bottom, cell.borders?.top))
4925
+ return void 0;
4926
+ }
4927
+ }
4928
+ }
4929
+ return {
4930
+ leftPx: left.widthPx,
4931
+ rightPx: right.widthPx,
4932
+ bottomPx: table.rows.at(-1).cells[0].borders.bottom.widthPx
4933
+ };
4934
+ }
4935
+
4936
+ // docx/layout/nested-fragment-edges.ts
4937
+ var plain = (paragraph) => !paragraph.keepLines && !paragraph.keepNext && !paragraph.pageBreakBefore && !paragraph.footnotes?.length && !paragraph.runs.some((run) => run.footnoteReferenceId !== void 0 || run.breakAfter);
4938
+ function nestedFragmentEdges(table) {
4939
+ if (table.widthPx === void 0 || !Number.isFinite(table.widthPx) || table.widthPx <= 0 || table.rows.length < 2 || !nestedFrameProfile(table, table.widthPx) || table.rows.some(
4940
+ (row) => row.heightPx !== void 0 || row.cantSplit || row.isHeader || row.cells.length !== 2 || row.cells.some(
4941
+ (cell) => cell.verticalAlign && cell.verticalAlign !== "top" || cell.blocks?.some((block) => block.kind !== "paragraph") || !(cell.blocks ?? cell.paragraphs).every(
4942
+ (block) => block.kind === "paragraph" && plain(block)
4943
+ )
4944
+ )
4945
+ ))
4946
+ return void 0;
4947
+ const top = table.rows[0].cells.map((cell) => cell.borders?.top);
4948
+ const bottom = table.rows.at(-1).cells.map((cell) => cell.borders?.bottom);
4949
+ return top.every(Boolean) && bottom.every(Boolean) ? { top, bottom } : void 0;
4950
+ }
4951
+ function reflowNestedFragments(row) {
4952
+ if (row.heightPx !== void 0 || row.cantSplit || row.isHeader || row.cells.length !== 2)
4953
+ return false;
4954
+ let tables = 0;
4955
+ for (const cell of row.cells) {
4956
+ if (cell.verticalAlign && cell.verticalAlign !== "top") return false;
4957
+ for (const [index, block] of (cell.blocks ?? cell.paragraphs).entries()) {
4958
+ if (block.kind === "paragraph") {
4959
+ if (!plain(block)) return false;
4960
+ } else {
4961
+ if (index !== 0 || !nestedFragmentEdges(block) || ++tables > 1) return false;
4962
+ }
4963
+ }
4964
+ }
4965
+ return tables === 1;
4966
+ }
4967
+
4968
+ // docx/layout/table-content.ts
4969
+ function cellContentBottom(boxes, paddingBottom = 0) {
4970
+ return Math.max(
4971
+ 0,
4972
+ ...boxes.map(
4973
+ (box) => box.yPx + box.heightPx + (box.tableFrameInsets?.bottom ?? 0) + paddingBottom
4974
+ )
4975
+ );
4976
+ }
4977
+
4978
+ // docx/layout/table-frames.ts
4979
+ function clipTableFrames(tables, start, end, inset = 0) {
4980
+ return tables.flatMap((table) => {
4981
+ const top = Math.max(start, table.yPx);
4982
+ const bottom = Math.min(end, table.yPx + table.heightPx);
4983
+ if (bottom <= top) return [];
4984
+ const rows = table.rows.flatMap((row) => {
4985
+ const rowTop = table.yPx + row.yPx;
4986
+ const a = Math.max(top, rowTop), b = Math.min(bottom, rowTop + row.heightPx);
4987
+ if (b <= a) return [];
4988
+ return [
4989
+ {
4990
+ ...row,
4991
+ yPx: a - top,
4992
+ heightPx: b - a,
4993
+ ...row.cellTables ? {
4994
+ cellTables: row.cellTables.map(
4995
+ (nested) => clipTableFrames(nested, a - rowTop, b - rowTop)
4996
+ )
4997
+ } : {}
4998
+ }
4999
+ ];
5000
+ });
5001
+ if (table.fragmentEdges && rows.length) {
5002
+ const edges = table.fragmentEdges;
5003
+ for (const [row, side] of [
5004
+ [rows[0], "top"],
5005
+ [rows.at(-1), "bottom"]
5006
+ ]) {
5007
+ if (row.geometry)
5008
+ row.geometry = row.geometry.map((cell, index) => ({
5009
+ ...cell,
5010
+ borders: { ...cell.borders, [side]: edges[side][index] }
5011
+ }));
5012
+ }
5013
+ }
5014
+ return [{ ...table, yPx: top - start + inset, heightPx: bottom - top, rows }];
5015
+ });
5016
+ }
5017
+
4894
5018
  // docx/layout/table-cell-layout.ts
4895
5019
  function cellParagraphs(cell) {
4896
5020
  const walk = (blocks) => blocks.flatMap(
@@ -4898,7 +5022,7 @@ function cellParagraphs(cell) {
4898
5022
  );
4899
5023
  return cell.blocks ? walk(cell.blocks) : cell.paragraphs;
4900
5024
  }
4901
- function stackCellBlocks(cell, width, measurer, note, top, starts) {
5025
+ function stackCellBlocks(cell, width, measurer, note, top, starts, physicalFragments = false) {
4902
5026
  if (!cell.blocks)
4903
5027
  return stackParagraphs(
4904
5028
  starts ? cell.paragraphs.filter((p) => starts.has(p.id)) : cell.paragraphs,
@@ -4910,6 +5034,7 @@ function stackCellBlocks(cell, width, measurer, note, top, starts) {
4910
5034
  );
4911
5035
  let y = top;
4912
5036
  const boxes = [];
5037
+ const tables = [];
4913
5038
  for (const block of cell.blocks) {
4914
5039
  if (block.kind === "paragraph") {
4915
5040
  if (starts && !starts.has(block.id)) continue;
@@ -4918,28 +5043,83 @@ function stackCellBlocks(cell, width, measurer, note, top, starts) {
4918
5043
  y = result.heightPx;
4919
5044
  continue;
4920
5045
  }
5046
+ const edges = physicalFragments ? nestedFragmentEdges(block) : void 0;
4921
5047
  const tableWidth = block.widthPx ?? width;
4922
- const x = block.alignment === "center" ? Math.max(0, (width - tableWidth) / 2) : block.alignment === "right" ? Math.max(0, width - tableWidth) : block.indentPx ?? 0;
5048
+ const profile = nestedFrameProfile(block, tableWidth);
5049
+ const reserveBorders = profile !== void 0;
5050
+ if (!reserveBorders)
5051
+ note(
5052
+ "Nested table border occupancy is approximate for missing edges, non-solid or conflicting shared borders and changing row grids."
5053
+ );
5054
+ const externalRight = profile ? (profile.leftPx + profile.rightPx) / 2 : 0;
5055
+ const paintedWidth = tableWidth + externalRight;
5056
+ const x = block.alignment === "center" ? Math.max(0, (width - paintedWidth) / 2) : block.alignment === "right" ? Math.max(0, width - paintedWidth) : block.indentPx ?? 0;
5057
+ const frame = {
5058
+ kind: "table",
5059
+ blockId: block.id,
5060
+ xPx: x,
5061
+ widthPx: paintedWidth,
5062
+ yPx: y,
5063
+ heightPx: 0,
5064
+ rows: [],
5065
+ ...edges ? { fragmentEdges: edges } : {}
5066
+ };
4923
5067
  for (const row of block.rows) {
4924
5068
  if (starts && !row.cells.some((nested) => cellParagraphs(nested).some((p) => starts.has(p.id))))
4925
5069
  continue;
4926
- const layout = layoutRow(row, tableWidth, measurer, note, void 0, starts);
5070
+ const visibleRow = edges && starts && !frame.rows.length ? {
5071
+ ...row,
5072
+ cells: row.cells.map((cell2, index) => ({
5073
+ ...cell2,
5074
+ borders: { ...cell2.borders, top: edges.top[index] }
5075
+ }))
5076
+ } : row;
5077
+ const layout = layoutRow(
5078
+ visibleRow,
5079
+ tableWidth,
5080
+ measurer,
5081
+ note,
5082
+ void 0,
5083
+ starts,
5084
+ reserveBorders,
5085
+ profile?.leftPx
5086
+ );
5087
+ frame.rows.push({
5088
+ yPx: y - frame.yPx,
5089
+ heightPx: layout.heightPx,
5090
+ repeated: false,
5091
+ cells: layout.cells,
5092
+ geometry: layout.geometry,
5093
+ ...layout.cellTables ? { cellTables: layout.cellTables } : {}
5094
+ });
4927
5095
  layout.cells.forEach((paragraphs, index) => {
4928
5096
  const geometry = layout.geometry[index];
4929
5097
  for (const paragraph of paragraphs)
4930
5098
  boxes.push({
4931
5099
  ...paragraph,
4932
- yPx: y + paragraph.yPx,
5100
+ yPx: y + paragraph.yPx + cellVerticalOffset(geometry, layout.heightPx),
4933
5101
  xPx: x + geometry.xPx + geometry.paddingLeftPx + (paragraph.xPx ?? 0),
4934
5102
  widthPx: paragraph.widthPx ?? Math.max(1, geometry.widthPx - geometry.paddingLeftPx - geometry.paddingRightPx),
4935
- readOnly: true
5103
+ readOnly: true,
5104
+ ...edges ? { tableFragmentBottomPx: edges.bottom[index].widthPx } : {},
5105
+ tableFrameInsets: {
5106
+ top: (paragraph.tableFrameInsets?.top ?? 0) + (reserveBorders ? geometry.borders?.top?.widthPx ?? 0 : 0),
5107
+ bottom: (paragraph.tableFrameInsets?.bottom ?? 0) + (reserveBorders ? geometry.borders?.bottom?.widthPx ?? 0 : 0)
5108
+ }
4936
5109
  });
4937
5110
  });
4938
5111
  y += layout.heightPx;
4939
5112
  }
5113
+ const bottomBorder = profile?.bottomPx ?? 0;
5114
+ if (frame.rows.length) {
5115
+ frame.rows.at(-1).heightPx += bottomBorder;
5116
+ y += bottomBorder;
5117
+ frame.heightPx = y - frame.yPx;
5118
+ tables.push(frame);
5119
+ }
4940
5120
  }
4941
5121
  boxes.sort((a, b) => a.yPx - b.yPx);
4942
- return { heightPx: y, boxes };
5122
+ return { heightPx: y, boxes, tables };
4943
5123
  }
4944
5124
 
4945
5125
  // docx/layout/table-layout.ts
@@ -4970,7 +5150,7 @@ function stackParagraphs(paragraphs, widthPx, measurer, note, topPx = 0, startTo
4970
5150
  }
4971
5151
  return { heightPx: y, boxes };
4972
5152
  }
4973
- function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens) {
5153
+ function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens, frameBorders = false, frameLeftBorderPx, physicalFragments = reflowNestedFragments(row)) {
4974
5154
  const count = row.cells.length || 1;
4975
5155
  let x = 0;
4976
5156
  const geometry = [];
@@ -4978,59 +5158,81 @@ function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens) {
4978
5158
  const continuation = remaining?.[geometry.length];
4979
5159
  const starts = continuation ? new Map(continuation.map((box) => [box.blockId, box.lines[0]?.firstToken ?? 0])) : startTokens;
4980
5160
  const widthPx = cell.widthPx ?? tableWidthPx / count;
4981
- const padding = cell.padding ?? { top: 0, right: 0, bottom: 0, left: 0 };
5161
+ const margins = cell.padding ?? { top: 0, right: 0, bottom: 0, left: 0 };
5162
+ const leftBorder = frameBorders ? cell.borders?.left?.widthPx ?? 0 : 0;
5163
+ const rightBorder = frameBorders ? cell.borders?.right?.widthPx ?? 0 : 0;
5164
+ const padding = frameBorders ? {
5165
+ top: margins.top + (cell.borders?.top?.widthPx ?? 0),
5166
+ bottom: margins.bottom,
5167
+ left: leftBorder / 2 + Math.max(margins.left, leftBorder / 2),
5168
+ right: Math.max(margins.right, rightBorder / 2) - rightBorder / 2
5169
+ } : margins;
5170
+ const externalRight = frameBorders && geometry.length === row.cells.length - 1 ? rightBorder : 0;
5171
+ const paintWidth = widthPx + (frameBorders ? (leftBorder - rightBorder) / 2 + externalRight : 0);
5172
+ const frameX = frameBorders ? ((frameLeftBorderPx ?? leftBorder) - leftBorder) / 2 : 0;
4982
5173
  const content2 = stackCellBlocks(
4983
5174
  cell,
4984
- Math.max(1, widthPx - padding.left - padding.right),
5175
+ Math.max(1, paintWidth - padding.left - padding.right - externalRight),
4985
5176
  measurer,
4986
5177
  note,
4987
5178
  padding.top,
4988
- starts
5179
+ starts,
5180
+ physicalFragments
4989
5181
  );
4990
5182
  const heightPx2 = content2.heightPx + padding.bottom;
4991
5183
  geometry.push({
4992
- xPx: cell.xPx ?? x,
4993
- widthPx,
5184
+ xPx: (cell.xPx ?? x) + frameX,
5185
+ widthPx: paintWidth,
5186
+ ...frameBorders ? { borderInsetsReserved: true } : {},
4994
5187
  paddingLeftPx: padding.left,
4995
- paddingRightPx: padding.right,
5188
+ paddingRightPx: padding.right + externalRight,
4996
5189
  contentHeightPx: heightPx2,
4997
5190
  ...cell.borders ? { borders: cell.borders } : {},
4998
5191
  ...cell.shading ? { shading: cell.shading } : {},
4999
5192
  ...cell.verticalAlign ? { verticalAlign: cell.verticalAlign } : {}
5000
5193
  });
5001
5194
  x = (cell.xPx ?? x) + widthPx;
5002
- return { heightPx: heightPx2, boxes: content2.boxes };
5195
+ return { heightPx: heightPx2, boxes: content2.boxes, tables: content2.tables ?? [] };
5003
5196
  });
5004
5197
  const content = Math.max(0, ...laidOut.map((cell) => cell.heightPx));
5005
5198
  const heightPx = row.heightPx === void 0 ? content : row.heightRule === "exact" ? row.heightPx : Math.max(content, row.heightPx);
5199
+ if (frameBorders) for (const cell of geometry) cell.alignmentHeightPx = heightPx;
5006
5200
  return {
5007
5201
  heightPx,
5008
5202
  cells: laidOut.map((cell) => cell.boxes),
5009
5203
  geometry,
5204
+ ...laidOut.some((cell) => cell.tables.length) ? { cellTables: laidOut.map((cell) => cell.tables) } : {},
5010
5205
  cellPadding: row.cells.map((cell) => ({
5011
5206
  top: cell.padding?.top ?? 0,
5012
5207
  bottom: cell.padding?.bottom ?? 0
5013
5208
  }))
5014
5209
  };
5015
5210
  }
5016
- function splitCellAtHeight(boxes, cutHeightPx) {
5211
+ function splitCellAtHeight(boxes, cutHeightPx, paragraphCuts) {
5017
5212
  const before = [];
5018
5213
  const after = [];
5019
5214
  let beforeHeightPx = 0;
5020
5215
  for (const box of boxes) {
5021
- if (box.yPx + box.heightPx <= cutHeightPx) {
5216
+ const cut = paragraphCuts?.get(box.blockId) ?? cutHeightPx;
5217
+ if (box.yPx + box.heightPx + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0) <= cut) {
5022
5218
  before.push(box);
5023
- beforeHeightPx = Math.max(beforeHeightPx, box.yPx + box.heightPx);
5219
+ beforeHeightPx = Math.max(
5220
+ beforeHeightPx,
5221
+ box.yPx + box.heightPx + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0)
5222
+ );
5024
5223
  continue;
5025
5224
  }
5026
5225
  const beforeLines = box.lines.filter(
5027
- (line2) => box.yPx + line2.yPx + line2.heightPx <= cutHeightPx
5226
+ (line2) => box.yPx + line2.yPx + line2.heightPx + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0) <= cut
5028
5227
  );
5029
5228
  const afterLines = box.lines.slice(beforeLines.length);
5030
5229
  if (beforeLines.length) {
5031
5230
  const bottom = beforeLines.at(-1).yPx + beforeLines.at(-1).heightPx;
5032
5231
  before.push({ ...box, heightPx: bottom, lines: beforeLines });
5033
- beforeHeightPx = Math.max(beforeHeightPx, box.yPx + bottom);
5232
+ beforeHeightPx = Math.max(
5233
+ beforeHeightPx,
5234
+ box.yPx + bottom + (box.tableFragmentBottomPx ?? box.tableFrameInsets?.bottom ?? 0)
5235
+ );
5034
5236
  }
5035
5237
  if (afterLines.length) {
5036
5238
  const shift = expectDefined(afterLines[0], "first line after split").yPx;
@@ -5042,43 +5244,81 @@ function splitCellAtHeight(boxes, cutHeightPx) {
5042
5244
  });
5043
5245
  }
5044
5246
  }
5045
- const afterOrigin = Math.min(...after.map((box) => box.yPx));
5247
+ const afterOrigin = Math.min(...after.map((box) => box.yPx - (box.tableFrameInsets?.top ?? 0)));
5046
5248
  for (const box of after) box.yPx -= afterOrigin;
5047
- return { before, after, beforeHeightPx };
5249
+ return { before, after, beforeHeightPx, ...after.length ? { afterOrigin } : {} };
5048
5250
  }
5049
- function splitRowAtHeight(row, cutHeightPx, cellCuts) {
5251
+ function splitRowAtHeight(row, cutHeightPx, cellCuts, paragraphCuts) {
5050
5252
  const splits = row.cells.map((cell, index) => {
5051
5253
  const padding = row.cellPadding?.[index] ?? { top: 0, bottom: 0 };
5052
- const split = splitCellAtHeight(cell, (cellCuts?.[index] ?? cutHeightPx) - padding.bottom);
5254
+ const cuts = paragraphCuts ? new Map(
5255
+ cell.flatMap((box) => {
5256
+ const cut = paragraphCuts.get(box.blockId);
5257
+ return cut === void 0 ? [] : [[box.blockId, cut - padding.bottom]];
5258
+ })
5259
+ ) : void 0;
5260
+ const split = splitCellAtHeight(
5261
+ cell,
5262
+ (cellCuts?.[index] ?? cutHeightPx) - padding.bottom,
5263
+ cuts
5264
+ );
5053
5265
  if (split.before.length) split.beforeHeightPx += padding.bottom;
5054
5266
  if (split.after.length)
5055
5267
  split.after = split.after.map((box) => ({ ...box, yPx: box.yPx + padding.top }));
5056
5268
  return split;
5057
5269
  });
5058
5270
  const anyAfter = splits.some((split) => split.after.length > 0);
5271
+ const beforeHeightPx = Math.max(0, ...splits.map((split) => split.beforeHeightPx));
5059
5272
  const before = {
5060
- heightPx: Math.max(0, ...splits.map((split) => split.beforeHeightPx)),
5273
+ heightPx: beforeHeightPx,
5061
5274
  cells: splits.map((split) => split.before),
5275
+ ...row.cellTables ? {
5276
+ cellTables: row.cellTables.map(
5277
+ (tables, index) => clipTableFrames(
5278
+ tables,
5279
+ 0,
5280
+ splits[index].beforeHeightPx - (row.cellPadding?.[index]?.bottom ?? 0)
5281
+ )
5282
+ )
5283
+ } : {},
5062
5284
  geometry: row.geometry.map((geometry, index) => ({
5063
5285
  ...geometry,
5064
- contentHeightPx: splits[index].beforeHeightPx
5286
+ contentHeightPx: splits[index].beforeHeightPx,
5287
+ ...row.borderBottomPx !== void 0 ? { alignmentHeightPx: beforeHeightPx } : {}
5065
5288
  })),
5066
- ...row.cellPadding ? { cellPadding: row.cellPadding } : {}
5289
+ ...row.cellPadding ? { cellPadding: row.cellPadding } : {},
5290
+ ...row.borderBottomPx !== void 0 ? { borderBottomPx: row.borderBottomPx } : {}
5067
5291
  };
5068
5292
  if (!anyAfter) return { before, after: null };
5293
+ const afterHeightPx = Math.max(
5294
+ 0,
5295
+ ...splits.map(
5296
+ (split, index) => cellContentBottom(split.after, row.cellPadding?.[index]?.bottom ?? 0)
5297
+ )
5298
+ );
5069
5299
  const after = {
5070
- heightPx: Math.max(
5071
- 0,
5072
- ...splits.map(
5073
- (split, index) => split.after.length ? split.after.at(-1).yPx + split.after.at(-1).heightPx + (row.cellPadding?.[index]?.bottom ?? 0) : 0
5074
- )
5075
- ),
5300
+ heightPx: afterHeightPx,
5076
5301
  cells: splits.map((split) => split.after),
5302
+ ...row.cellTables ? {
5303
+ cellTables: row.cellTables.map(
5304
+ (tables, index) => splits[index].after.length ? clipTableFrames(
5305
+ tables,
5306
+ splits[index].afterOrigin ?? 0,
5307
+ row.heightPx,
5308
+ row.cellPadding?.[index]?.top ?? 0
5309
+ ) : []
5310
+ )
5311
+ } : {},
5077
5312
  geometry: row.geometry.map((geometry, index) => ({
5078
5313
  ...geometry,
5079
- contentHeightPx: splits[index].after.length ? splits[index].after.at(-1).yPx + splits[index].after.at(-1).heightPx + (row.cellPadding?.[index]?.bottom ?? 0) : 0
5314
+ contentHeightPx: cellContentBottom(
5315
+ splits[index].after,
5316
+ row.cellPadding?.[index]?.bottom ?? 0
5317
+ ),
5318
+ ...row.borderBottomPx !== void 0 ? { alignmentHeightPx: afterHeightPx } : {}
5080
5319
  })),
5081
- ...row.cellPadding ? { cellPadding: row.cellPadding } : {}
5320
+ ...row.cellPadding ? { cellPadding: row.cellPadding } : {},
5321
+ ...row.borderBottomPx !== void 0 ? { borderBottomPx: row.borderBottomPx } : {}
5082
5322
  };
5083
5323
  return { before, after };
5084
5324
  }
@@ -5139,11 +5379,11 @@ function splitNote(note, budget) {
5139
5379
  // docx/layout/footnote-columns.ts
5140
5380
  function footnoteColumns(page, columns) {
5141
5381
  const width = page.widthPx - page.marginLeftPx - page.marginRightPx;
5142
- const equal = (width - columns.gapPx * (columns.count - 1)) / columns.count;
5382
+ const equal2 = (width - columns.gapPx * (columns.count - 1)) / columns.count;
5143
5383
  let x = 0;
5144
5384
  return Array.from({ length: columns.count }, (_, index) => {
5145
5385
  const own = columns.widths?.[index];
5146
- const column = { xPx: x, widthPx: Math.max(1, own?.widthPx ?? equal) };
5386
+ const column = { xPx: x, widthPx: Math.max(1, own?.widthPx ?? equal2) };
5147
5387
  x += column.widthPx + (own?.gapPx ?? columns.gapPx);
5148
5388
  return column;
5149
5389
  });
@@ -5551,6 +5791,10 @@ var PageCursor = class {
5551
5791
  this.page.heightPx - this.page.marginTopPx - this.geometry.marginBottomPx - this.columnTopPx
5552
5792
  );
5553
5793
  }
5794
+ /** Number of independently balanced note columns, distinct from legacy body-column notes. */
5795
+ get footnoteColumnCount() {
5796
+ return this.legacyFootnoteColumns ? 1 : this.noteColumns?.count ?? 1;
5797
+ }
5554
5798
  remainingHeightPx() {
5555
5799
  return this.columnHeightPx - (this.yPx - this.columnTopPx) - this.footnotes.reserved(this.page, this.noteColumnIndex) - this.pendingHeightPx();
5556
5800
  }
@@ -5795,20 +6039,133 @@ function placeParagraph(cursor, placement, note) {
5795
6039
  }
5796
6040
  }
5797
6041
 
6042
+ // docx/layout/table-note-stories.ts
6043
+ function independentNoteStories(cell) {
6044
+ const first3 = cell.blocks?.[0];
6045
+ if (first3?.kind !== "table" || first3.rows.length !== 1 || cell.verticalAlign && cell.verticalAlign !== "top")
6046
+ return void 0;
6047
+ if (cell.blocks.slice(1).some((block) => block.kind !== "paragraph" || block.footnotes?.length))
6048
+ return void 0;
6049
+ const row = first3.rows[0];
6050
+ if (row.heightPx !== void 0 || row.cantSplit || row.isHeader || !nestedFrameProfile(first3, first3.widthPx))
6051
+ return void 0;
6052
+ if (row.cells.some(
6053
+ (inner) => inner.blocks?.some((block) => block.kind === "table") || cellParagraphs(inner).some(
6054
+ (paragraph) => paragraph.keepLines || paragraph.keepNext || paragraph.pageBreakBefore
6055
+ ) || inner.verticalAlign && inner.verticalAlign !== "top"
6056
+ ))
6057
+ return void 0;
6058
+ if (!measuredNoteReferences(row.cells.flatMap(cellParagraphs))) return void 0;
6059
+ const groups = /* @__PURE__ */ new Map();
6060
+ row.cells.forEach((inner, index) => {
6061
+ for (const paragraph of cellParagraphs(inner)) groups.set(paragraph.id, first3.id + ":" + index);
6062
+ });
6063
+ return groups.size ? groups : void 0;
6064
+ }
6065
+ function measuredNoteReferences(paragraphs) {
6066
+ const markers = paragraphs.flatMap(
6067
+ (paragraph) => paragraph.runs.flatMap(
6068
+ (run) => run.footnoteReferenceId === void 0 ? [] : [run.footnoteReferenceId]
6069
+ )
6070
+ );
6071
+ const ids = new Set(markers);
6072
+ const unanchored = paragraphs.flatMap(
6073
+ (paragraph) => (paragraph.footnotes ?? []).filter(
6074
+ (note) => !paragraph.runs.some((run) => run.footnoteReferenceId === note.id)
6075
+ )
6076
+ ).length;
6077
+ return markers.length + unanchored <= 3 && ids.size === markers.length && !(markers.length + unanchored > 1 && unanchored);
6078
+ }
6079
+
6080
+ // docx/layout/table-border-layout.ts
6081
+ function layoutBorderedRow(row, width, measurer, note, profile, remaining, physicalFragments) {
6082
+ const reserved = profile !== void 0 && (profile.leftPx > 0 || profile.rightPx > 0 || profile.bottomPx > 0);
6083
+ const layout = layoutRow(
6084
+ row,
6085
+ width,
6086
+ measurer,
6087
+ note,
6088
+ remaining,
6089
+ void 0,
6090
+ reserved,
6091
+ profile?.leftPx,
6092
+ physicalFragments
6093
+ );
6094
+ if (!reserved) return layout;
6095
+ const bottom = Math.max(0, ...layout.geometry.map((cell) => cell.borders?.bottom?.widthPx ?? 0));
6096
+ return {
6097
+ ...layout,
6098
+ heightPx: layout.heightPx + bottom,
6099
+ borderBottomPx: bottom,
6100
+ cellPadding: row.cells.map((cell) => ({
6101
+ top: (cell.padding?.top ?? 0) + (cell.borders?.top?.widthPx ?? 0),
6102
+ bottom: (cell.padding?.bottom ?? 0) + (cell.borders?.bottom?.widthPx ?? 0)
6103
+ }))
6104
+ };
6105
+ }
6106
+ var TableFragmentBorders = class {
6107
+ bottom = 0;
6108
+ included = true;
6109
+ record(bottom) {
6110
+ this.bottom = bottom ?? 0;
6111
+ this.included = true;
6112
+ }
6113
+ remove(row) {
6114
+ if (!row || !this.included) return 0;
6115
+ row.heightPx -= this.bottom;
6116
+ this.included = false;
6117
+ return -this.bottom;
6118
+ }
6119
+ restore(row) {
6120
+ if (!row || this.included) return 0;
6121
+ row.heightPx += this.bottom;
6122
+ this.included = true;
6123
+ return this.bottom;
6124
+ }
6125
+ };
6126
+
6127
+ // docx/layout/table-note-completion.ts
6128
+ function completedNoteStoryMinimum(row, stories, pendingBlocks, available) {
6129
+ let minimum = 0;
6130
+ for (const [index, cell] of row.cells.entries()) {
6131
+ const groups = /* @__PURE__ */ new Map();
6132
+ for (const box of cell) {
6133
+ const group = stories.get(box.blockId);
6134
+ if (group !== void 0) {
6135
+ const boxes = groups.get(group) ?? [];
6136
+ boxes.push(box);
6137
+ groups.set(group, boxes);
6138
+ }
6139
+ }
6140
+ for (const boxes of groups.values()) {
6141
+ if (boxes.reduce((count, box) => count + box.lines.length, 0) !== 1 || boxes.some((box) => pendingBlocks.has(box.blockId)))
6142
+ continue;
6143
+ const bottom = cellContentBottom(boxes, row.cellPadding?.[index]?.bottom ?? 0);
6144
+ if (bottom <= available + 1e-6) minimum = Math.max(minimum, bottom);
6145
+ }
6146
+ }
6147
+ return minimum;
6148
+ }
6149
+
5798
6150
  // docx/layout/table-footnotes.ts
5799
- function prefix(row, cut, cellCuts) {
6151
+ function prefix(row, cut, cellCuts, paragraphCuts) {
5800
6152
  const cells = row.cells.map((cell, index) => {
5801
- const contentCut = (cellCuts?.[index] ?? cut) - (row.cellPadding?.[index]?.bottom ?? 0);
6153
+ const padding = row.cellPadding?.[index]?.bottom ?? 0;
5802
6154
  const boxes = [];
5803
6155
  for (const box of cell) {
5804
- if (box.yPx >= contentCut + 1e-6) break;
5805
- if (box.yPx + box.heightPx <= contentCut + 1e-6) {
6156
+ const contentCut = (paragraphCuts?.get(box.blockId) ?? cellCuts?.[index] ?? cut) - padding;
6157
+ if (box.yPx >= contentCut + 1e-6) {
6158
+ if (!paragraphCuts?.size) break;
6159
+ continue;
6160
+ }
6161
+ if (box.yPx + box.heightPx + (box.tableFrameInsets?.bottom ?? 0) <= contentCut + 1e-6) {
5806
6162
  boxes.push(box);
5807
6163
  continue;
5808
6164
  }
5809
6165
  const lines = [];
5810
6166
  for (const line2 of box.lines) {
5811
- if (box.yPx + line2.yPx + line2.heightPx > contentCut + 1e-6) break;
6167
+ if (box.yPx + line2.yPx + line2.heightPx + (box.tableFrameInsets?.bottom ?? 0) > contentCut + 1e-6)
6168
+ break;
5812
6169
  lines.push(line2);
5813
6170
  }
5814
6171
  if (lines.length)
@@ -5828,9 +6185,7 @@ function prefix(row, cut, cellCuts) {
5828
6185
  cells,
5829
6186
  heightPx: Math.max(
5830
6187
  0,
5831
- ...cells.flatMap(
5832
- (cell, index) => cell.map((box) => box.yPx + box.heightPx + (row.cellPadding?.[index]?.bottom ?? 0))
5833
- )
6188
+ ...cells.map((cell, index) => cellContentBottom(cell, row.cellPadding?.[index]?.bottom ?? 0))
5834
6189
  )
5835
6190
  };
5836
6191
  }
@@ -5840,16 +6195,23 @@ var TableFootnotes = class {
5840
6195
  this.table = table;
5841
6196
  this.height = height;
5842
6197
  this.resolve = resolve;
5843
- for (const row of table.rows)
5844
- for (const cell of row.cells)
6198
+ for (const row of table.rows) {
6199
+ const measured = measuredNoteReferences(row.cells.flatMap(cellParagraphs));
6200
+ for (const cell of row.cells) {
5845
6201
  for (const paragraph of cellParagraphs(cell))
5846
6202
  if (paragraph.footnotes?.length) this.paragraphs.set(paragraph.id, paragraph);
6203
+ for (const [id, group] of (measured ? independentNoteStories(cell) : void 0) ?? []) {
6204
+ this.stories.set(id, group);
6205
+ }
6206
+ }
6207
+ }
5847
6208
  }
5848
6209
  cursor;
5849
6210
  table;
5850
6211
  height;
5851
6212
  resolve;
5852
6213
  paragraphs = /* @__PURE__ */ new Map();
6214
+ stories = /* @__PURE__ */ new Map();
5853
6215
  placed = /* @__PURE__ */ new Set();
5854
6216
  fragment = /* @__PURE__ */ new Map();
5855
6217
  references(row) {
@@ -5871,14 +6233,30 @@ var TableFootnotes = class {
5871
6233
  ) ?? box.lines[0];
5872
6234
  const bottom = Math.min(
5873
6235
  row.heightPx,
5874
- box.yPx + (line2?.yPx ?? 0) + (line2?.heightPx ?? box.heightPx)
6236
+ box.yPx + (line2?.yPx ?? 0) + (line2?.heightPx ?? box.heightPx) + (box.tableFrameInsets?.bottom ?? 0)
5875
6237
  );
5876
6238
  const prior = refs.get(note.id);
5877
- if (!prior || bottom < prior.bottom) refs.set(note.id, { note, bottom });
6239
+ if (!prior || bottom < prior.bottom)
6240
+ refs.set(note.id, {
6241
+ note,
6242
+ bottom,
6243
+ blockId: box.blockId,
6244
+ before: box.yPx + (line2?.yPx ?? 0) + (box.tableFrameInsets?.bottom ?? 0)
6245
+ });
5878
6246
  }
5879
6247
  }
5880
6248
  return [...refs.values()];
5881
6249
  }
6250
+ /** A consumed marker no longer constrains its story. Deferred markers stop just before
6251
+ * their own line, allowing another pending story to use a different complete prefix. */
6252
+ storyCut(pending, boxes, padding, cut, space, included) {
6253
+ const ids = new Set(boxes.map((box) => box.blockId));
6254
+ const refs = pending.filter((ref) => ids.has(ref.blockId));
6255
+ let limit = refs.some((ref) => included.has(ref.note.id)) ? Math.min(cut, space) : space;
6256
+ for (const ref of refs)
6257
+ if (!included.has(ref.note.id)) limit = Math.min(limit, ref.before + padding);
6258
+ return limit;
6259
+ }
5882
6260
  hold(refs, minimumBody = 0) {
5883
6261
  const referenceBottom = Math.max(0, ...[...refs.values()].map((ref) => ref.bottom));
5884
6262
  const bodyHeight = Math.max(referenceBottom, minimumBody);
@@ -5889,17 +6267,20 @@ var TableFootnotes = class {
5889
6267
  this.cursor.usedColumnHeightPx + referenceBottom
5890
6268
  );
5891
6269
  }
5892
- holdCandidate(row) {
6270
+ holdCandidate(row, completionMinimum = 0) {
5893
6271
  const refs = new Map(this.fragment);
5894
6272
  for (const ref of this.references(row))
5895
6273
  if (!refs.has(ref.note.id))
5896
6274
  refs.set(ref.note.id, { ...ref, bottom: this.height() + ref.bottom });
5897
6275
  const referenceBottom = Math.max(0, ...[...refs.values()].map((ref) => ref.bottom));
5898
- const contentBottom = this.height() + Math.max(0, ...row.cells.flatMap((cell) => cell.map((box) => box.yPx + box.heightPx)));
6276
+ const contentBottom = this.height() + Math.max(0, ...row.cells.map((cell) => cellContentBottom(cell)));
5899
6277
  const paddingBottom = Math.max(0, ...(row.cellPadding ?? []).map((padding) => padding.bottom));
5900
6278
  this.hold(
5901
6279
  refs,
5902
- contentBottom <= referenceBottom + 1e-6 ? this.height() + row.heightPx : referenceBottom + paddingBottom
6280
+ Math.max(
6281
+ completionMinimum,
6282
+ contentBottom <= referenceBottom + 1e-6 ? this.height() + row.heightPx : referenceBottom + paddingBottom
6283
+ )
5903
6284
  );
5904
6285
  }
5905
6286
  /** Largest complete prefix that keeps each new marker with available note content. */
@@ -5912,29 +6293,76 @@ var TableFootnotes = class {
5912
6293
  return { layout: row, cut: row.heightPx };
5913
6294
  }
5914
6295
  if (!atomic) {
6296
+ const independent = row.cells.some(
6297
+ (cell) => cell.some((box) => this.stories.has(box.blockId))
6298
+ );
6299
+ const pending = independent ? this.references(row) : [];
6300
+ const completing = (this.cursor.footnoteColumnCount === 2 || this.cursor.footnoteColumnCount === 3) && pending.length === 1 && !this.stories.has(pending[0].blockId) ? completedNoteStoryMinimum(
6301
+ row,
6302
+ this.stories,
6303
+ new Set(pending.map((ref) => ref.blockId)),
6304
+ available
6305
+ ) : 0;
5915
6306
  const cuts = /* @__PURE__ */ new Set();
5916
6307
  for (const [index, cell] of row.cells.entries())
5917
6308
  for (const box of cell) {
5918
6309
  if (box.yPx > available + 1e-6) break;
5919
6310
  for (const line2 of box.lines) {
5920
- const bottom = box.yPx + line2.yPx + line2.heightPx + (row.cellPadding?.[index]?.bottom ?? 0);
6311
+ const bottom = box.yPx + line2.yPx + line2.heightPx + (box.tableFrameInsets?.bottom ?? 0) + (row.cellPadding?.[index]?.bottom ?? 0);
5921
6312
  if (bottom > available + 1e-6) break;
5922
6313
  if (bottom > 0) cuts.add(bottom);
5923
6314
  }
5924
6315
  }
5925
6316
  for (const cut of [...cuts].sort((a, b) => b - a)) {
5926
6317
  const candidate = prefix(row, cut);
5927
- this.holdCandidate(candidate);
6318
+ const included = new Set(this.references(candidate).map((ref) => ref.note.id));
6319
+ const completion = completing > 0 && included.has(pending[0]?.note.id ?? "") ? this.height() + completing : 0;
6320
+ this.holdCandidate(candidate, completion);
5928
6321
  if (candidate.heightPx <= this.cursor.remainingHeightPx() - this.height() + 1e-6) {
5929
6322
  const space = this.cursor.remainingHeightPx() - this.height();
5930
6323
  const cellCuts = row.cells.map(
5931
- (cell) => cell.some((box) => this.paragraphs.has(box.blockId)) ? cut : space
6324
+ (cell, index) => independent ? this.storyCut(
6325
+ pending,
6326
+ cell,
6327
+ row.cellPadding?.[index]?.bottom ?? 0,
6328
+ cut,
6329
+ space,
6330
+ included
6331
+ ) : cell.some((box) => this.paragraphs.has(box.blockId)) ? cut : space
5932
6332
  );
5933
- const expanded = prefix(row, cut, cellCuts);
5934
- this.holdCandidate(expanded);
6333
+ const paragraphCuts = /* @__PURE__ */ new Map();
6334
+ for (const [index, cell] of row.cells.entries()) {
6335
+ const groups = /* @__PURE__ */ new Map();
6336
+ for (const box of cell) {
6337
+ const group = this.stories.get(box.blockId);
6338
+ if (group !== void 0) {
6339
+ const boxes = groups.get(group) ?? [];
6340
+ boxes.push(box);
6341
+ groups.set(group, boxes);
6342
+ }
6343
+ }
6344
+ for (const boxes of groups.values()) {
6345
+ const limit = this.storyCut(
6346
+ pending,
6347
+ boxes,
6348
+ row.cellPadding?.[index]?.bottom ?? 0,
6349
+ cut,
6350
+ space,
6351
+ included
6352
+ );
6353
+ for (const box of boxes) paragraphCuts.set(box.blockId, limit);
6354
+ }
6355
+ }
6356
+ const expanded = prefix(row, cut, cellCuts, paragraphCuts);
6357
+ this.holdCandidate(expanded, completion);
5935
6358
  if (expanded.heightPx <= this.cursor.remainingHeightPx() - this.height() + 1e-6)
5936
- return { layout: expanded, cut, cellCuts };
5937
- this.holdCandidate(candidate);
6359
+ return {
6360
+ layout: expanded,
6361
+ cut,
6362
+ cellCuts,
6363
+ ...paragraphCuts.size ? { paragraphCuts } : {}
6364
+ };
6365
+ this.holdCandidate(candidate, completion);
5938
6366
  return { layout: candidate, cut };
5939
6367
  }
5940
6368
  }
@@ -5961,26 +6389,47 @@ var TableFootnotes = class {
5961
6389
  function placeTable(cursor, table, measurer, note, resolveFootnotes) {
5962
6390
  const firstBodyRow = table.rows.findIndex((row) => !row.isHeader);
5963
6391
  const headerRows = table.rows.slice(0, firstBodyRow < 0 ? table.rows.length : firstBodyRow);
6392
+ const nativeFragments = new Map(table.rows.map((row) => [row, reflowNestedFragments(row)]));
5964
6393
  const xPosition = () => {
5965
- const width = table.widthPx ?? cursor.columnWidthPx;
6394
+ const width = (table.widthPx ?? cursor.columnWidthPx) + (activeBorders ? (profile.leftPx + profile.rightPx) / 2 : 0);
5966
6395
  return table.alignment === "center" ? Math.max(0, (cursor.columnWidthPx - width) / 2) : table.alignment === "right" ? Math.max(0, cursor.columnWidthPx - width) : table.indentPx ?? 0;
5967
6396
  };
6397
+ const profile = nestedFrameProfile(table, table.widthPx ?? cursor.columnWidthPx);
6398
+ const activeBorders = profile !== void 0 && (profile.leftPx > 0 || profile.rightPx > 0 || profile.bottomPx > 0);
6399
+ if (!profile && table.rows.some((row) => row.cells.some((cell) => cell.borders)))
6400
+ note(
6401
+ "Ordinary table border occupancy remains approximate for missing edges, non-solid or conflicting shared borders and changing row grids."
6402
+ );
6403
+ const layoutRow2 = (row, width, m, n2, remaining, sourceRow = row) => layoutBorderedRow(
6404
+ row,
6405
+ activeBorders ? table.widthPx ?? width : width,
6406
+ m,
6407
+ n2,
6408
+ profile,
6409
+ remaining,
6410
+ nativeFragments.get(sourceRow) ?? false
6411
+ );
6412
+ const fragmentBorders = new TableFragmentBorders();
5968
6413
  let fragmentRows = [];
5969
6414
  let fragmentHeight = 0;
5970
6415
  const footnotes = resolveFootnotes ? new TableFootnotes(cursor, table, () => fragmentHeight, resolveFootnotes) : void 0;
5971
6416
  const toRowBox = (layout, repeated) => {
6417
+ fragmentHeight += fragmentBorders.remove(fragmentRows.at(-1));
5972
6418
  footnotes?.add(layout, repeated);
5973
6419
  const box = {
5974
6420
  yPx: fragmentHeight,
5975
6421
  heightPx: layout.heightPx,
5976
6422
  repeated,
5977
6423
  cells: layout.cells,
5978
- geometry: layout.geometry
6424
+ geometry: layout.geometry,
6425
+ ...layout.cellTables ? { cellTables: layout.cellTables } : {}
5979
6426
  };
5980
6427
  fragmentHeight += layout.heightPx;
6428
+ fragmentBorders.record(layout.borderBottomPx);
5981
6429
  return box;
5982
6430
  };
5983
6431
  function flushFragment() {
6432
+ fragmentHeight += fragmentBorders.restore(fragmentRows.at(-1));
5984
6433
  if (!fragmentRows.length) {
5985
6434
  footnotes?.holdFragment();
5986
6435
  return;
@@ -5988,6 +6437,9 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
5988
6437
  const box = {
5989
6438
  kind: "table",
5990
6439
  blockId: table.id,
6440
+ ...activeBorders ? {
6441
+ widthPx: (table.widthPx ?? cursor.columnWidthPx) + (profile.leftPx + profile.rightPx) / 2
6442
+ } : {},
5991
6443
  ...xPosition() ? { xPx: xPosition() } : {},
5992
6444
  yPx: 0,
5993
6445
  heightPx: fragmentHeight,
@@ -6006,15 +6458,16 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6006
6458
  }
6007
6459
  function addHeaders() {
6008
6460
  for (const header of headerRows)
6009
- fragmentRows.push(toRowBox(layoutRow(header, cursor.columnWidthPx, measurer, note), true));
6461
+ fragmentRows.push(toRowBox(layoutRow2(header, cursor.columnWidthPx, measurer, note), true));
6010
6462
  }
6011
6463
  function placeRow(row, initial, cantSplit) {
6012
6464
  let remainingRow = initial;
6013
6465
  while (remainingRow) {
6466
+ fragmentHeight += fragmentBorders.remove(fragmentRows.at(-1));
6014
6467
  const minimum = cantSplit ? Math.min(remainingRow.heightPx, cursor.columnHeightPx) : Math.min(
6015
6468
  ...remainingRow.cells.flatMap(
6016
- (cell) => cell.map(
6017
- (paragraph) => paragraph.yPx + (paragraph.lines[0]?.yPx ?? 0) + (paragraph.lines[0]?.heightPx ?? 0)
6469
+ (cell, index) => cell.map(
6470
+ (paragraph) => paragraph.yPx + (paragraph.lines[0]?.yPx ?? 0) + (paragraph.lines[0]?.heightPx ?? 0) + (remainingRow.borderBottomPx !== void 0 ? (remainingRow.cellPadding?.[index]?.bottom ?? 0) + (paragraph.tableFrameInsets?.bottom ?? 0) : 0)
6018
6471
  )
6019
6472
  )
6020
6473
  );
@@ -6022,12 +6475,13 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6022
6475
  const width = cursor.columnWidthPx;
6023
6476
  cursor.advancePastFootnotes(fragmentHeight + (Number.isFinite(minimum) ? minimum : 0));
6024
6477
  if (width !== cursor.columnWidthPx) {
6025
- remainingRow = layoutRow(
6478
+ remainingRow = layoutRow2(
6026
6479
  remainingRow === initial ? row : { ...row, heightPx: 0, heightRule: "atLeast" },
6027
6480
  cursor.columnWidthPx,
6028
6481
  measurer,
6029
6482
  note,
6030
- remainingRow.cells
6483
+ remainingRow.cells,
6484
+ row
6031
6485
  );
6032
6486
  if (fragmentRows.length) {
6033
6487
  fragmentRows = [];
@@ -6048,17 +6502,19 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6048
6502
  const { before: before2, after: after2 } = splitRowAtHeight(
6049
6503
  remainingRow,
6050
6504
  selected.cut + 1e-6,
6051
- selected.cellCuts?.map((cut) => cut + 1e-6)
6505
+ selected.cellCuts?.map((cut) => cut + 1e-6),
6506
+ selected.paragraphCuts ? new Map([...selected.paragraphCuts].map(([id, cut]) => [id, cut + 1e-6])) : void 0
6052
6507
  );
6053
6508
  fragmentRows.push(toRowBox(before2, false));
6054
6509
  const previousWidth2 = cursor.columnWidthPx;
6055
6510
  startNewFragment();
6056
- remainingRow = after2 && previousWidth2 !== cursor.columnWidthPx ? layoutRow(
6511
+ remainingRow = after2 && (selected.paragraphCuts || previousWidth2 !== cursor.columnWidthPx) ? layoutRow2(
6057
6512
  { ...row, heightPx: 0, heightRule: "atLeast" },
6058
6513
  cursor.columnWidthPx,
6059
6514
  measurer,
6060
6515
  note,
6061
- after2.cells
6516
+ after2.cells,
6517
+ row
6062
6518
  ) : after2;
6063
6519
  continue;
6064
6520
  }
@@ -6066,12 +6522,13 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6066
6522
  const previousWidth2 = cursor.columnWidthPx;
6067
6523
  startNewFragment();
6068
6524
  if (previousWidth2 !== cursor.columnWidthPx)
6069
- remainingRow = layoutRow(
6525
+ remainingRow = layoutRow2(
6070
6526
  remainingRow === initial ? row : { ...row, heightPx: 0, heightRule: "atLeast" },
6071
6527
  cursor.columnWidthPx,
6072
6528
  measurer,
6073
6529
  note,
6074
- remainingRow === initial ? void 0 : remainingRow.cells
6530
+ remainingRow === initial ? void 0 : remainingRow.cells,
6531
+ row
6075
6532
  );
6076
6533
  continue;
6077
6534
  }
@@ -6085,14 +6542,14 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6085
6542
  if (cantSplit) {
6086
6543
  if (fragmentRows.length || !cursor.atColumnTop) {
6087
6544
  startNewFragment();
6088
- remainingRow = layoutRow(row, cursor.columnWidthPx, measurer, note);
6545
+ remainingRow = layoutRow2(row, cursor.columnWidthPx, measurer, note);
6089
6546
  }
6090
6547
  const noteWidth = cursor.columnWidthPx;
6091
6548
  cursor.advancePastFootnotes(
6092
6549
  fragmentHeight + Math.min(remainingRow.heightPx, cursor.columnHeightPx)
6093
6550
  );
6094
6551
  if (noteWidth !== cursor.columnWidthPx) {
6095
- remainingRow = layoutRow(row, cursor.columnWidthPx, measurer, note);
6552
+ remainingRow = layoutRow2(row, cursor.columnWidthPx, measurer, note);
6096
6553
  if (fragmentRows.length) {
6097
6554
  fragmentRows = [];
6098
6555
  fragmentHeight = 0;
@@ -6118,17 +6575,30 @@ function placeTable(cursor, table, measurer, note, resolveFootnotes) {
6118
6575
  const previousWidth = cursor.columnWidthPx;
6119
6576
  if (before.cells.some((cell) => cell.length)) fragmentRows.push(toRowBox(before, false));
6120
6577
  startNewFragment();
6121
- remainingRow = after && previousWidth !== cursor.columnWidthPx ? layoutRow(
6578
+ remainingRow = after && (previousWidth !== cursor.columnWidthPx || nativeFragments.get(row)) ? layoutRow2(
6122
6579
  { ...row, heightPx: 0, heightRule: "atLeast" },
6123
6580
  cursor.columnWidthPx,
6124
6581
  measurer,
6125
6582
  note,
6126
- after.cells
6583
+ after.cells,
6584
+ row
6127
6585
  ) : after;
6128
6586
  }
6129
6587
  }
6130
6588
  for (const row of table.rows) {
6131
- const layout = layoutRow(row, cursor.columnWidthPx, measurer, note);
6589
+ const layout = layoutRow2(row, cursor.columnWidthPx, measurer, note);
6590
+ if (layout.heightPx > cursor.remainingHeightPx() && !nativeFragments.get(row) && row.cells.some(
6591
+ (cell) => cell.blocks?.some((block) => block.kind === "table" && block.rows.length > 1)
6592
+ ))
6593
+ note(
6594
+ "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."
6595
+ );
6596
+ if (activeBorders && layout.heightPx > cursor.remainingHeightPx() && row.cells.some(
6597
+ (cell) => (!measuredNoteReferences(row.cells.flatMap(cellParagraphs)) || !independentNoteStories(cell)) && cell.blocks?.some((block) => block.kind === "table") && cellParagraphs(cell).some((p) => p.footnotes?.length)
6598
+ ))
6599
+ note(
6600
+ "Independent inner-cell continuation around nested note references remains approximate when an enclosing bordered row splits."
6601
+ );
6132
6602
  placeRow(
6133
6603
  row,
6134
6604
  layout,
@@ -6386,9 +6856,9 @@ var SectionFlow = class {
6386
6856
  const page = this.cursor.page;
6387
6857
  const exclusions = this.exclusions?.get(page.index);
6388
6858
  if (!exclusions) return void 0;
6389
- const plain = this.paragraphLayout(index);
6859
+ const plain2 = this.paragraphLayout(index);
6390
6860
  const topPx = page.marginTopPx + this.cursor.y + spacingBeforePx;
6391
- const bottomPx = topPx + plain.contentHeightPx;
6861
+ const bottomPx = topPx + plain2.contentHeightPx;
6392
6862
  if (!exclusions.some((item) => item.yPx < bottomPx && item.yPx + item.heightPx > topPx))
6393
6863
  return void 0;
6394
6864
  return layoutParagraph(
@@ -6639,13 +7109,13 @@ function cssHex(value) {
6639
7109
  const hex = value?.replace(/^#/, "");
6640
7110
  return hex && /^[0-9a-f]{6}$/i.test(hex) ? `#${hex}` : void 0;
6641
7111
  }
6642
- function border(side, theme) {
7112
+ function border(side, theme, preserveSingleWidth = false) {
6643
7113
  if (!side?.style || side.style === "none" || side.style === "nil") return void 0;
6644
7114
  const style = side.style.startsWith("double") ? "double" : /dot/i.test(side.style) ? "dotted" : /dash/i.test(side.style) ? "dashed" : "solid";
6645
7115
  const themed = side.themeColor && theme ? resolveThemeColorReference({ token: side.themeColor }, theme) : void 0;
6646
7116
  const hex = cssHex(side.color);
6647
7117
  const widthPx = Math.max(
6648
- style === "double" ? 3 : 1,
7118
+ style === "double" ? 3 : preserveSingleWidth && style === "solid" ? 0 : 1,
6649
7119
  (side.sizeEighthPoints ?? 4) / 8 * 96 / 72
6650
7120
  );
6651
7121
  return { widthPx, style, color: themed ?? hex ?? "#000000" };
@@ -6658,7 +7128,7 @@ function rowLayout(props) {
6658
7128
  ...props.header ? { isHeader: true } : {}
6659
7129
  };
6660
7130
  }
6661
- function adaptTable(table, model, adaptParagraph) {
7131
+ function adaptTable(table, model, adaptParagraph, _nested = false) {
6662
7132
  const grid = table.grid?.map(twipsToPx2);
6663
7133
  const columnCount = grid?.length ?? Math.max(1, ...table.rows.map((row) => row.length));
6664
7134
  const gridWidth = (start, span) => grid ? grid.slice(start, start + span).reduce((sum, width) => sum + width, 0) : void 0;
@@ -6700,7 +7170,7 @@ function adaptTable(table, model, adaptParagraph) {
6700
7170
  );
6701
7171
  const borders = {};
6702
7172
  for (const side of ["top", "right", "bottom", "left"]) {
6703
- const resolved = border(visuals.borders?.[side], model.theme);
7173
+ const resolved = border(visuals.borders?.[side], model.theme, true);
6704
7174
  if (resolved) borders[side] = resolved;
6705
7175
  }
6706
7176
  if (cell.verticalMerge === "continue") delete borders.top;
@@ -6719,7 +7189,7 @@ function adaptTable(table, model, adaptParagraph) {
6719
7189
  paragraphs: cell.paragraphs.map(adaptParagraph),
6720
7190
  ...cell.sourceBlocks ? {
6721
7191
  blocks: cellSourceBlocks(cell).map(
6722
- (block) => block.type === "paragraph" ? adaptParagraph(block) : adaptTable(block, model, adaptParagraph)
7192
+ (block) => block.type === "paragraph" ? adaptParagraph(block) : adaptTable(block, model, adaptParagraph, true)
6723
7193
  )
6724
7194
  } : {},
6725
7195
  ...width !== void 0 ? { widthPx: width } : {},
@@ -7019,7 +7489,7 @@ function adaptDocumentModel(model, note = () => {
7019
7489
  reportOnce(VERTICAL_MERGE_NOTE);
7020
7490
  if (block.rows.some((row) => row.some((cell) => cell.nestedTables?.length)))
7021
7491
  reportOnce(
7022
- "Nested tables are projected as read-only cell paragraphs in Print Layout; their borders, shading, vertical merge and repeated header geometry are not rendered."
7492
+ "Nested tables are projected as read-only cell paragraphs in Print Layout; vertical merge and repeated header geometry are not rendered."
7023
7493
  );
7024
7494
  return adaptTable(block, model, adaptParagraph);
7025
7495
  }
@@ -7296,6 +7766,7 @@ exports.SINGLE_LINE_SPACING_UNITS = SINGLE_LINE_SPACING_UNITS;
7296
7766
  exports.adaptDocumentModel = adaptDocumentModel;
7297
7767
  exports.adjustForWidowOrphan = adjustForWidowOrphan;
7298
7768
  exports.appendBreakMarker = appendBreakMarker;
7769
+ exports.cellVerticalOffset = cellVerticalOffset;
7299
7770
  exports.createFakeMeasurer = createFakeMeasurer;
7300
7771
  exports.cssFontStack = cssFontStack;
7301
7772
  exports.fieldDisplayText = fieldDisplayText;