@a3s-lab/office 0.12.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +112 -7
  2. package/dist/0~1403.js +20 -12
  3. package/dist/0~2805.js +241 -241
  4. package/dist/0~4980.js +1 -1
  5. package/dist/0~5050.js +1 -20
  6. package/dist/0~5093.js +547 -547
  7. package/dist/0~6090.js +63 -4
  8. package/dist/0~7048.js +31 -29
  9. package/dist/0~document-editor.js +694 -90
  10. package/dist/0~pdf-viewer.js +41 -10
  11. package/dist/0~presentation-editor.js +8 -6
  12. package/dist/0~spreadsheet-editor.js +11892 -9682
  13. package/dist/0~work-document-import-worker-client.js +237 -0
  14. package/dist/0~work-docx-export.js +1 -1
  15. package/dist/0~work-docx-import.js +1 -1
  16. package/dist/0~work-docx-large-document-import.js +559 -0
  17. package/dist/0~work-office-diagnostics.js +46 -32
  18. package/dist/4104.js +5070 -3112
  19. package/dist/432.js +51 -7
  20. package/dist/4476.js +201 -7
  21. package/dist/5184.js +24 -2
  22. package/dist/{8928.js → 6282.js} +2338 -93
  23. package/dist/8715.js +895 -888
  24. package/dist/9356.js +3 -1
  25. package/dist/core.js +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -9
  28. package/dist/internal/features/work/editors/document-external-content.d.ts +1 -1
  29. package/dist/internal/features/work/editors/office-menu-keyboard.d.ts +1 -0
  30. package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +3 -1
  31. package/dist/internal/features/work/editors/presentation-slide-thumbnail.d.ts +3 -2
  32. package/dist/internal/features/work/editors/presentation-thumbnail-rail.d.ts +2 -1
  33. package/dist/internal/features/work/editors/presentation-workspace.d.ts +2 -1
  34. package/dist/internal/features/work/editors/spreadsheet-border-ribbon.d.ts +5 -0
  35. package/dist/internal/features/work/editors/spreadsheet-calculation-projection.d.ts +10 -0
  36. package/dist/internal/features/work/editors/spreadsheet-cell-border-command.d.ts +3 -0
  37. package/dist/internal/features/work/editors/spreadsheet-cell-border-per-cell.d.ts +5 -0
  38. package/dist/internal/features/work/editors/spreadsheet-cell-border.d.ts +28 -0
  39. package/dist/internal/features/work/editors/spreadsheet-cell-fill-command.d.ts +3 -0
  40. package/dist/internal/features/work/editors/spreadsheet-cell-fill.d.ts +12 -0
  41. package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +14 -0
  42. package/dist/internal/features/work/editors/spreadsheet-cell-style-command.d.ts +3 -0
  43. package/dist/internal/features/work/editors/spreadsheet-cell-style-ribbon.d.ts +9 -0
  44. package/dist/internal/features/work/editors/spreadsheet-cell-style.d.ts +41 -0
  45. package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +293 -0
  46. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +10 -4
  47. package/dist/internal/features/work/editors/spreadsheet-editor-ribbon.d.ts +3 -1
  48. package/dist/internal/features/work/editors/spreadsheet-editor-support.d.ts +8 -2
  49. package/dist/internal/features/work/editors/spreadsheet-home-format-ribbon.d.ts +10 -0
  50. package/dist/internal/features/work/editors/spreadsheet-in-place-workbook-sync.d.ts +10 -0
  51. package/dist/internal/features/work/editors/spreadsheet-number-format.d.ts +15 -3
  52. package/dist/internal/features/work/editors/spreadsheet-operation-projection.d.ts +14 -0
  53. package/dist/internal/features/work/editors/spreadsheet-structure-selection.d.ts +7 -0
  54. package/dist/internal/features/work/editors/use-document-pagination.d.ts +5 -0
  55. package/dist/internal/features/work/editors/use-presentation-design-commands.d.ts +2 -1
  56. package/dist/internal/features/work/editors/use-spreadsheet-workbook-sync.d.ts +2 -1
  57. package/dist/internal/features/work/spreadsheet-history-value.d.ts +1 -0
  58. package/dist/internal/features/work/spreadsheet-sparse.d.ts +6 -1
  59. package/dist/internal/features/work/work-document-chunk-geometry.d.ts +28 -0
  60. package/dist/internal/features/work/work-document-chunk-node.d.ts +23 -0
  61. package/dist/internal/features/work/work-document-extensions.d.ts +1 -0
  62. package/dist/internal/features/work/work-document-html-fingerprint.d.ts +15 -0
  63. package/dist/internal/features/work/work-document-import-worker-client.d.ts +13 -0
  64. package/dist/internal/features/work/work-document-import-worker-protocol.d.ts +36 -0
  65. package/dist/internal/features/work/work-document-import.worker.d.ts +1 -0
  66. package/dist/internal/features/work/work-document-incremental-layout.d.ts +1 -1
  67. package/dist/internal/features/work/work-document-integrity-index.d.ts +14 -0
  68. package/dist/internal/features/work/work-document-lazy-block.d.ts +3 -0
  69. package/dist/internal/features/work/work-document-lazy-html.d.ts +21 -0
  70. package/dist/internal/features/work/work-document-lazy-model.d.ts +29 -0
  71. package/dist/internal/features/work/work-document-lazy-pagination-measurement.d.ts +3 -0
  72. package/dist/internal/features/work/work-document-lazy-preview.d.ts +21 -0
  73. package/dist/internal/features/work/work-document-lazy-update.d.ts +14 -0
  74. package/dist/internal/features/work/work-document-model.d.ts +18 -2
  75. package/dist/internal/features/work/work-document-page-surface-registry.d.ts +16 -0
  76. package/dist/internal/features/work/work-document-pagination-dom.d.ts +1 -0
  77. package/dist/internal/features/work/work-document-pagination-types.d.ts +1 -0
  78. package/dist/internal/features/work/work-document-pagination.d.ts +1 -1
  79. package/dist/internal/features/work/work-document-text-statistics.d.ts +25 -0
  80. package/dist/internal/features/work/work-document-windowing.d.ts +23 -0
  81. package/dist/internal/features/work/work-docx-large-document-import.d.ts +35 -0
  82. package/dist/internal/features/work/work-docx-large-document-parser.d.ts +29 -0
  83. package/dist/internal/features/work/work-file-import.d.ts +5 -0
  84. package/dist/internal/features/work/work-file-io.d.ts +3 -3
  85. package/dist/internal/features/work/work-file-kind.d.ts +5 -0
  86. package/dist/internal/features/work/work-office-diagnostics.d.ts +10 -1
  87. package/dist/internal/features/work/work-ooxml-package.d.ts +8 -0
  88. package/dist/internal/features/work/work-presentation-layouts.d.ts +7 -1
  89. package/dist/internal/features/work/work-repository.d.ts +1 -0
  90. package/dist/internal/features/work/work-spreadsheet-compatibility-summary.d.ts +10 -0
  91. package/dist/internal/features/work/work-spreadsheet-file-export.d.ts +2 -0
  92. package/dist/internal/features/work/work-spreadsheet-file-import.d.ts +3 -0
  93. package/dist/internal/features/work/work-spreadsheet-import-diagnostics.d.ts +2 -0
  94. package/dist/internal/features/work/work-spreadsheet-import-worker-client.d.ts +6 -0
  95. package/dist/internal/features/work/work-spreadsheet-import-worker-protocol.d.ts +32 -0
  96. package/dist/internal/features/work/work-spreadsheet-import.worker.d.ts +1 -0
  97. package/dist/internal/features/work/work-spreadsheet-matrix-profile.d.ts +64 -0
  98. package/dist/internal/features/work/work-spreadsheet-package-scan-worker-client.d.ts +6 -0
  99. package/dist/internal/features/work/work-spreadsheet-package-scan-worker-protocol.d.ts +49 -0
  100. package/dist/internal/features/work/work-spreadsheet-package-scan.worker.d.ts +1 -0
  101. package/dist/internal/features/work/work-xlsx-cell-borders.d.ts +25 -0
  102. package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +21 -0
  103. package/dist/internal/features/work/work-xlsx-cell-style-xml.d.ts +17 -0
  104. package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +13 -0
  105. package/dist/internal/features/work/work-xlsx-colors.d.ts +6 -0
  106. package/dist/internal/features/work/work-xlsx-formula-diagnostics.d.ts +3 -1
  107. package/dist/internal/features/work/work-xlsx-formulas.d.ts +2 -1
  108. package/dist/internal/features/work/work-xlsx-interop.d.ts +8 -5
  109. package/dist/internal/features/work/work-xlsx-pivot-diagnostics.d.ts +2 -1
  110. package/dist/internal/features/work/work-xlsx-plain-fast-path.d.ts +54 -0
  111. package/dist/internal/features/work/work-xlsx-style-gate.d.ts +1 -0
  112. package/dist/internal/features/work/work-xlsx-worksheet-scan.d.ts +13 -0
  113. package/dist/internal/features/work/work-xlsx-worksheet.d.ts +12 -0
  114. package/dist/office-kernel.wasm +0 -0
  115. package/dist/office-kernel.worker.js +31 -29
  116. package/dist/react.d.ts +7 -1
  117. package/dist/styles.css +557 -3
  118. package/dist/work-document-import.worker.js +558 -0
  119. package/dist/work-spreadsheet-import.worker.js +24745 -0
  120. package/dist/work-spreadsheet-import.worker.js.LICENSE.txt +3 -0
  121. package/dist/work-spreadsheet-package-scan.worker.js +4161 -0
  122. package/dist/work-spreadsheet-package-scan.worker.js.LICENSE.txt +11 -0
  123. package/docs/latest/en/browser-editor-architecture.md +351 -15
  124. package/package.json +23 -3
package/dist/0~6090.js CHANGED
@@ -1235,11 +1235,15 @@ const OFFICE_MENU_NAVIGATION_KEYS = [
1235
1235
  'Home',
1236
1236
  'End'
1237
1237
  ];
1238
+ const OFFICE_GRID_MENU_NAVIGATION_KEYS = [
1239
+ ...OFFICE_MENU_NAVIGATION_KEYS,
1240
+ 'ArrowLeft',
1241
+ 'ArrowRight'
1242
+ ];
1243
+ const OFFICE_MENU_BUTTON_SELECTOR = 'button[role="menuitem"]:not(:disabled), button[role="menuitemradio"]:not(:disabled), button[role="menuitemcheckbox"]:not(:disabled)';
1238
1244
  function moveOfficeMenuFocus(event) {
1239
1245
  if (!OFFICE_MENU_NAVIGATION_KEYS.includes(event.key)) return false;
1240
- const buttons = [
1241
- ...event.currentTarget.querySelectorAll('button[role="menuitem"]:not(:disabled), button[role="menuitemradio"]:not(:disabled), button[role="menuitemcheckbox"]:not(:disabled)')
1242
- ];
1246
+ const buttons = officeMenuButtons(event.currentTarget);
1243
1247
  if (!buttons.length) return false;
1244
1248
  event.preventDefault();
1245
1249
  const current = buttons.indexOf(document.activeElement);
@@ -1247,6 +1251,61 @@ function moveOfficeMenuFocus(event) {
1247
1251
  buttons[next]?.focus();
1248
1252
  return true;
1249
1253
  }
1254
+ function moveOfficeGridMenuFocus(event, columns) {
1255
+ if (!OFFICE_GRID_MENU_NAVIGATION_KEYS.includes(event.key)) return false;
1256
+ const buttons = officeMenuButtons(event.currentTarget);
1257
+ if (!buttons.length) return false;
1258
+ event.preventDefault();
1259
+ const currentButton = document.activeElement;
1260
+ const current = Math.max(0, buttons.indexOf(currentButton));
1261
+ if ('Home' === event.key || 'End' === event.key) {
1262
+ buttons['Home' === event.key ? 0 : buttons.length - 1]?.focus();
1263
+ return true;
1264
+ }
1265
+ if ('ArrowLeft' === event.key || 'ArrowRight' === event.key) {
1266
+ const delta = 'ArrowRight' === event.key ? 1 : -1;
1267
+ buttons[(current + delta + buttons.length) % buttons.length]?.focus();
1268
+ return true;
1269
+ }
1270
+ const groups = [
1271
+ ...event.currentTarget.querySelectorAll('[data-office-menu-grid]')
1272
+ ];
1273
+ const groupIndex = groups.findIndex((group)=>group.contains(currentButton));
1274
+ if (groupIndex < 0) {
1275
+ const delta = 'ArrowDown' === event.key ? columns : -columns;
1276
+ buttons[(current + delta + buttons.length) % buttons.length]?.focus();
1277
+ return true;
1278
+ }
1279
+ const groupButtons = officeMenuButtons(groups[groupIndex]);
1280
+ const localIndex = Math.max(0, groupButtons.indexOf(currentButton));
1281
+ const column = localIndex % columns;
1282
+ if ('ArrowDown' === event.key) {
1283
+ const nextRow = localIndex - column + columns;
1284
+ if (nextRow < groupButtons.length) {
1285
+ groupButtons[Math.min(nextRow + column, groupButtons.length - 1)]?.focus();
1286
+ return true;
1287
+ }
1288
+ const nextGroup = groups[(groupIndex + 1) % groups.length];
1289
+ const nextButtons = officeMenuButtons(nextGroup);
1290
+ nextButtons[Math.min(column, nextButtons.length - 1)]?.focus();
1291
+ return true;
1292
+ }
1293
+ const previousRow = localIndex - column - columns;
1294
+ if (previousRow >= 0) {
1295
+ groupButtons[previousRow + column]?.focus();
1296
+ return true;
1297
+ }
1298
+ const previousGroup = groups[(groupIndex - 1 + groups.length) % groups.length];
1299
+ const previousButtons = officeMenuButtons(previousGroup);
1300
+ const previousRowStart = Math.floor((previousButtons.length - 1) / columns) * columns;
1301
+ previousButtons[Math.min(previousRowStart + column, previousButtons.length - 1)]?.focus();
1302
+ return true;
1303
+ }
1304
+ function officeMenuButtons(root) {
1305
+ return [
1306
+ ...root.querySelectorAll(OFFICE_MENU_BUTTON_SELECTOR)
1307
+ ];
1308
+ }
1250
1309
  function stepOfficeZoom(zoom, direction, { minimum = 50, maximum = 200, step = 10 } = {}) {
1251
1310
  const delta = 'in' === direction ? step : -step;
1252
1311
  return Math.min(maximum, Math.max(minimum, Math.round(zoom + delta)));
@@ -1280,4 +1339,4 @@ function useOfficeEditorWheelZoom({ enabled = true, scopeRef, onZoomIn, onZoomOu
1280
1339
  scopeRef
1281
1340
  ]);
1282
1341
  }
1283
- export { CommittedOfficeTextArea, CommittedOfficeTextField, MarkdownSourcePresenceLayer, OfficePresenceAvatar, OfficeTiptapPresenceLayer, Popover, WorkOfficeCollaborationParticipants, button_Button, icon_button_IconButton, matchesAriaKeyShortcuts, matchesOfficeEditorKeyboardShortcut, moveOfficeMenuFocus, officeOverlayPortalRoot, officePresenceColor, officePresenceColorStyle, office_text_field_OfficeFileInput, office_text_field_OfficeTextArea, office_text_field_OfficeTextField, stepOfficeZoom, useDialogFocusScope, useOfficeEditorWheelZoom, useOfficePublishPresenceLocation, useOfficeRemoteParticipants };
1342
+ export { CommittedOfficeTextArea, CommittedOfficeTextField, MarkdownSourcePresenceLayer, OfficePresenceAvatar, OfficeTiptapPresenceLayer, Popover, WorkOfficeCollaborationParticipants, button_Button, icon_button_IconButton, matchesAriaKeyShortcuts, matchesOfficeEditorKeyboardShortcut, moveOfficeGridMenuFocus, moveOfficeMenuFocus, officeOverlayPortalRoot, officePresenceColor, officePresenceColorStyle, office_text_field_OfficeFileInput, office_text_field_OfficeTextArea, office_text_field_OfficeTextField, stepOfficeZoom, useDialogFocusScope, useOfficeEditorWheelZoom, useOfficePublishPresenceLocation, useOfficeRemoteParticipants };
package/dist/0~7048.js CHANGED
@@ -667,8 +667,8 @@ function officeFontFamilyLabel(value) {
667
667
  function normalizeOfficeFontFamily(value) {
668
668
  return officeFontFamilyLabel(value).toLocaleLowerCase();
669
669
  }
670
- const MAX_LAYOUT_BLOCKS = 10000;
671
- const MAX_LAYOUT_PAGE_STYLES = MAX_LAYOUT_BLOCKS;
670
+ const MAX_LAYOUT_BLOCKS = 200000;
671
+ const MAX_LAYOUT_PAGE_STYLES = 10000;
672
672
  const MAX_LAYOUT_EXTENT = 1000000;
673
673
  const MAX_LAYOUT_PAGE_INDEX = 1000000;
674
674
  function layoutOfficeDocumentInJavaScript(request) {
@@ -688,10 +688,10 @@ function layoutOfficeDocumentInJavaScript(request) {
688
688
  ensurePageMetrics(pages, page);
689
689
  if (void 0 !== block.flowCount) {
690
690
  const end = index + block.flowCount;
691
- layoutFlow(request.blocks.slice(index, end), request.blocks.slice(end), pages, page, request.page, pageStyles, end < request.blocks.length);
691
+ layoutFlow(request.blocks, index, end, pages, page, request.page, pageStyles, end < request.blocks.length);
692
692
  index = end;
693
693
  } else {
694
- layoutSingleBlock(block, request.blocks.slice(index + 1), pages, page, request.page, pageStyles, index + 1 < request.blocks.length);
694
+ layoutSingleBlock(block, request.blocks, index + 1, pages, page, request.page, pageStyles, index + 1 < request.blocks.length);
695
695
  index += 1;
696
696
  }
697
697
  }
@@ -735,7 +735,7 @@ function validateLayoutRequest(request) {
735
735
  }
736
736
  validateFlowSequences(request.blocks);
737
737
  }
738
- function layoutSingleBlock(block, next, pages, page, defaultPage, pageStyles, hasMoreBlocks) {
738
+ function layoutSingleBlock(block, blocks, nextIndex, pages, page, defaultPage, pageStyles, hasMoreBlocks) {
739
739
  const availableHeight = pageBodyHeight(page);
740
740
  let current = pages.at(-1);
741
741
  let currentHasContent = current.placements.length > 0;
@@ -745,7 +745,7 @@ function layoutSingleBlock(block, next, pages, page, defaultPage, pageStyles, ha
745
745
  currentHasContent = false;
746
746
  }
747
747
  const remaining = Math.max(0, availableHeight - current.usedHeight);
748
- const nextHeight = nextBlockPreviewHeight(next, page, defaultPage, pageStyles);
748
+ const nextHeight = nextBlockPreviewHeight(blocks, nextIndex, page, defaultPage, pageStyles);
749
749
  const groupedHeight = block.height + (block.keepWithNext ? nextHeight : 0);
750
750
  const shouldAdvance = currentHasContent && (block.height > remaining || (block.keepTogether || block.keepWithNext) && groupedHeight <= availableHeight && groupedHeight > remaining);
751
751
  if (shouldAdvance) {
@@ -755,13 +755,13 @@ function layoutSingleBlock(block, next, pages, page, defaultPage, pageStyles, ha
755
755
  placeFragment(block, current, availableHeight);
756
756
  if (block.breakAfter && hasMoreBlocks) pages.push(emptyPage(nextPageIndex(pages), page));
757
757
  }
758
- function layoutFlow(blocks, next, pages, page, defaultPage, pageStyles, hasMoreBlocks) {
758
+ function layoutFlow(blocks, start, end, pages, page, defaultPage, pageStyles, hasMoreBlocks) {
759
759
  const availableHeight = pageBodyHeight(page);
760
- const first = blocks[0];
761
- const last = blocks.at(-1);
760
+ const first = blocks[start];
761
+ const last = blocks[end - 1];
762
762
  if (first.breakBefore && pages.at(-1)?.placements.length) pages.push(emptyPage(nextPageIndex(pages), page));
763
- const totalHeight = fragmentHeight(blocks, 0, blocks.length);
764
- const nextHeight = last.keepWithNext ? nextBlockPreviewHeight(next, page, defaultPage, pageStyles) : 0;
763
+ const totalHeight = fragmentHeight(blocks, start, end);
764
+ const nextHeight = last.keepWithNext ? nextBlockPreviewHeight(blocks, end, page, defaultPage, pageStyles) : 0;
765
765
  let current = pages.at(-1);
766
766
  const repeatHeaderCount = first.repeatHeaderCount ?? 0;
767
767
  const repeatHeaderHeight = first.repeatHeaderHeight ?? 0;
@@ -770,8 +770,8 @@ function layoutFlow(blocks, next, pages, page, defaultPage, pageStyles, hasMoreB
770
770
  current = emptyPage(nextPageIndex(pages), page);
771
771
  pages.push(current);
772
772
  }
773
- if (repeatHeaderCount > 0 && repeatHeaderCount < blocks.length) {
774
- const leadingHeight = fragmentHeight(blocks, 0, repeatHeaderCount + 1);
773
+ if (repeatHeaderCount > 0 && repeatHeaderCount < end - start) {
774
+ const leadingHeight = fragmentHeight(blocks, start, start + repeatHeaderCount + 1);
775
775
  const remainingHeight = Math.max(0, availableHeight - current.usedHeight);
776
776
  if (current.placements.length > 0 && leadingHeight <= availableHeight && leadingHeight > remainingHeight) {
777
777
  current = emptyPage(nextPageIndex(pages), page);
@@ -779,22 +779,23 @@ function layoutFlow(blocks, next, pages, page, defaultPage, pageStyles, hasMoreB
779
779
  }
780
780
  }
781
781
  const minimum = Math.max(1, first.minimumFragmentsPerPage ?? 1);
782
- let cursor = 0;
783
- while(cursor < blocks.length){
782
+ let cursor = start;
783
+ let remainingFlowHeight = totalHeight;
784
+ while(cursor < end){
784
785
  current = pages.at(-1);
785
- if (cursor >= repeatHeaderCount && cursor > 0 && repeatHeaderHeight > 0 && 0 === current.placements.length && 0 === current.usedHeight) current.usedHeight = repeatHeaderHeight;
786
+ if (cursor - start >= repeatHeaderCount && cursor > start && repeatHeaderHeight > 0 && 0 === current.placements.length && 0 === current.usedHeight) current.usedHeight = repeatHeaderHeight;
786
787
  const currentHasContent = current.placements.length > 0;
787
788
  const remainingHeight = Math.max(0, availableHeight - current.usedHeight);
788
- const remainingFragments = blocks.length - cursor;
789
- const remainingFlowHeight = fragmentHeight(blocks, cursor, blocks.length);
789
+ const remainingFragments = end - cursor;
790
790
  if (nextHeight > 0 && currentHasContent && remainingFlowHeight <= remainingHeight && remainingFlowHeight + nextHeight > remainingHeight && remainingFlowHeight + nextHeight <= availableHeight) {
791
791
  pages.push(emptyPage(nextPageIndex(pages), page));
792
792
  continue;
793
793
  }
794
- let fitting = fragmentsFitting(blocks, cursor, blocks.length, remainingHeight);
794
+ let fitting = fragmentsFitting(blocks, cursor, end, remainingHeight);
795
795
  if (fitting === remainingFragments) {
796
- placeFragments(blocks, cursor, blocks.length, current, availableHeight);
797
- cursor = blocks.length;
796
+ placeFragments(blocks, cursor, end, current, availableHeight);
797
+ cursor = end;
798
+ remainingFlowHeight = 0;
798
799
  continue;
799
800
  }
800
801
  if (0 === fitting) {
@@ -811,18 +812,19 @@ function layoutFlow(blocks, next, pages, page, defaultPage, pageStyles, hasMoreB
811
812
  continue;
812
813
  }
813
814
  fitting = Math.max(1, fitting);
815
+ remainingFlowHeight -= fragmentHeight(blocks, cursor, cursor + fitting);
814
816
  placeFragments(blocks, cursor, cursor + fitting, current, availableHeight);
815
817
  cursor += fitting;
816
- if (cursor < blocks.length) pages.push(emptyPage(nextPageIndex(pages), page));
818
+ if (cursor < end) pages.push(emptyPage(nextPageIndex(pages), page));
817
819
  }
818
820
  if (last.breakAfter && hasMoreBlocks) pages.push(emptyPage(nextPageIndex(pages), page));
819
821
  }
820
- function nextBlockPreviewHeight(blocks, currentPage, defaultPage, pageStyles) {
821
- const first = blocks[0];
822
+ function nextBlockPreviewHeight(blocks, start, currentPage, defaultPage, pageStyles) {
823
+ const first = blocks[start];
822
824
  if (!first || first.breakBefore) return 0;
823
825
  if (!pageMetricsEqual(currentPage, pageMetricsForBlock(first, defaultPage, pageStyles))) return 0;
824
826
  const count = Math.min(2, first.flowCount ?? 1);
825
- return fragmentHeight(blocks, 0, count);
827
+ return fragmentHeight(blocks, start, Math.min(blocks.length, start + count));
826
828
  }
827
829
  function fragmentsFitting(blocks, start, end, availableHeight) {
828
830
  let used = 0;
@@ -890,13 +892,13 @@ function validateFlowSequences(blocks) {
890
892
  const count = block.flowCount;
891
893
  const repeatHeaderCount = block.repeatHeaderCount;
892
894
  const repeatHeaderHeight = block.repeatHeaderHeight;
893
- const flow = blocks.slice(index, index + count);
894
- if (flow.length !== count) throw kernelError('office.kernel.flow_sequence_invalid', 'A layout flow must contain its declared number of fragments.');
895
- flow.forEach((fragment, flowIndex)=>{
895
+ if (index + count > blocks.length) throw kernelError('office.kernel.flow_sequence_invalid', 'A layout flow must contain its declared number of fragments.');
896
+ for(let flowIndex = 0; flowIndex < count; flowIndex += 1){
897
+ const fragment = blocks[index + flowIndex];
896
898
  if (fragment.flowId !== block.flowId || fragment.flowIndex !== flowIndex || fragment.flowCount !== count || fragment.minimumFragmentsPerPage !== block.minimumFragmentsPerPage || fragment.repeatHeaderCount !== repeatHeaderCount || fragment.repeatHeaderHeight !== repeatHeaderHeight || fragment.pageStyleId !== block.pageStyleId) throw kernelError('office.kernel.flow_sequence_invalid', 'Layout flow fragments must be consecutive and consistently indexed.');
897
899
  if (flowIndex > 0 && fragment.breakBefore) throw kernelError('office.kernel.flow_break_invalid', 'Only the first flow fragment may request breakBefore.');
898
900
  if (flowIndex + 1 < count && fragment.breakAfter) throw kernelError('office.kernel.flow_break_invalid', 'Only the last flow fragment may request breakAfter.');
899
- });
901
+ }
900
902
  index += count;
901
903
  }
902
904
  }