@beyondwork/docx-react-component 1.0.120 → 1.0.122

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 (116) hide show
  1. package/README.md +1 -0
  2. package/dist/api/public-types.cjs +1713 -55
  3. package/dist/api/public-types.d.cts +2 -2
  4. package/dist/api/public-types.d.ts +2 -2
  5. package/dist/api/public-types.js +6 -6
  6. package/dist/api/v3.cjs +4958 -406
  7. package/dist/api/v3.d.cts +3 -3
  8. package/dist/api/v3.d.ts +3 -3
  9. package/dist/api/v3.js +14 -14
  10. package/dist/{canonical-document-fNawStsc.d.cts → canonical-document-ByIqTd4s.d.cts} +9 -1
  11. package/dist/{canonical-document-fNawStsc.d.ts → canonical-document-ByIqTd4s.d.ts} +9 -1
  12. package/dist/{chunk-5RNMPLXU.js → chunk-37SEJQ3G.js} +4 -4
  13. package/dist/{chunk-FXGQM2JB.js → chunk-3OFSP2IX.js} +11 -5
  14. package/dist/{chunk-U5BSQXF4.js → chunk-3OHVK2D6.js} +70 -12
  15. package/dist/{chunk-AUQDC5BD.js → chunk-3TUQCHYT.js} +101 -2
  16. package/dist/{chunk-SJSMYEMU.js → chunk-B4YHWFE3.js} +3 -3
  17. package/dist/{chunk-XC56YLIS.js → chunk-C2LWJ4CZ.js} +4 -0
  18. package/dist/{chunk-VDIUVT46.js → chunk-CX42VC67.js} +1 -1
  19. package/dist/{chunk-KCHEAX4Z.js → chunk-EMDH4IQN.js} +148 -70
  20. package/dist/{chunk-TMQGWF7R.js → chunk-G3B2OBCZ.js} +352 -17
  21. package/dist/{chunk-VCL5MJMZ.js → chunk-GON2DNTE.js} +149 -28
  22. package/dist/{chunk-WVZX4NYG.js → chunk-GZW2ERUO.js} +601 -47
  23. package/dist/{chunk-WDNEPRFW.js → chunk-ICX54W4U.js} +1 -1
  24. package/dist/{chunk-FIGWJ43K.js → chunk-IT2DK3A7.js} +1883 -90
  25. package/dist/{chunk-2ZWFQ74R.js → chunk-OBCP6VTG.js} +1 -1
  26. package/dist/{chunk-FLNQY74K.js → chunk-OYGMRRR7.js} +1 -1
  27. package/dist/{chunk-MPYYBRVN.js → chunk-PCXTMEGY.js} +782 -124
  28. package/dist/{chunk-4JNUMMM7.js → chunk-PGGPPZ65.js} +17 -2
  29. package/dist/{chunk-KHZNNBTN.js → chunk-QFU7ZOAD.js} +43 -39
  30. package/dist/{chunk-4ZNQFWFM.js → chunk-QIO6V46H.js} +84 -4
  31. package/dist/{chunk-IQ2VJEF6.js → chunk-QNGJRZ2D.js} +1 -1
  32. package/dist/{chunk-BM5NSDII.js → chunk-S4ANOS2M.js} +2 -2
  33. package/dist/{chunk-AQA7OZ2R.js → chunk-TFSXOIAI.js} +959 -43
  34. package/dist/{chunk-NQZUGMLW.js → chunk-TMU7JMXX.js} +184 -32
  35. package/dist/{chunk-KD5K5XIA.js → chunk-UHQOUTAX.js} +568 -88
  36. package/dist/{chunk-327AIUXL.js → chunk-UWDWGQH5.js} +11 -4
  37. package/dist/{chunk-BBB4GSDB.js → chunk-XVFENXLK.js} +2 -2
  38. package/dist/{chunk-MUEN2WOG.js → chunk-ZKSDVHGH.js} +6 -3
  39. package/dist/compare.cjs +17 -2
  40. package/dist/compare.d.cts +1 -1
  41. package/dist/compare.d.ts +1 -1
  42. package/dist/compare.js +3 -3
  43. package/dist/core/commands/formatting-commands.d.cts +2 -2
  44. package/dist/core/commands/formatting-commands.d.ts +2 -2
  45. package/dist/core/commands/image-commands.cjs +814 -45
  46. package/dist/core/commands/image-commands.d.cts +2 -2
  47. package/dist/core/commands/image-commands.d.ts +2 -2
  48. package/dist/core/commands/image-commands.js +8 -8
  49. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  50. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  51. package/dist/core/commands/style-commands.d.cts +2 -2
  52. package/dist/core/commands/style-commands.d.ts +2 -2
  53. package/dist/core/commands/table-structure-commands.cjs +750 -42
  54. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  55. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  56. package/dist/core/commands/table-structure-commands.js +6 -6
  57. package/dist/core/commands/text-commands.cjs +910 -57
  58. package/dist/core/commands/text-commands.d.cts +2 -2
  59. package/dist/core/commands/text-commands.d.ts +2 -2
  60. package/dist/core/commands/text-commands.js +8 -8
  61. package/dist/core/selection/mapping.d.cts +2 -2
  62. package/dist/core/selection/mapping.d.ts +2 -2
  63. package/dist/core/state/editor-state.cjs +17 -2
  64. package/dist/core/state/editor-state.d.cts +2 -2
  65. package/dist/core/state/editor-state.d.ts +2 -2
  66. package/dist/core/state/editor-state.js +2 -2
  67. package/dist/index.cjs +6203 -625
  68. package/dist/index.d.cts +5 -5
  69. package/dist/index.d.ts +5 -5
  70. package/dist/index.js +299 -67
  71. package/dist/io/docx-session.cjs +354 -102
  72. package/dist/io/docx-session.d.cts +4 -4
  73. package/dist/io/docx-session.d.ts +4 -4
  74. package/dist/io/docx-session.js +5 -5
  75. package/dist/legal.cjs +183 -31
  76. package/dist/legal.d.cts +1 -1
  77. package/dist/legal.d.ts +1 -1
  78. package/dist/legal.js +3 -3
  79. package/dist/{loader-CaohrhNl.d.ts → loader-BF8ju_LK.d.ts} +22 -4
  80. package/dist/{loader-BpCyGnZl.d.cts → loader-g54WRvj1.d.cts} +22 -4
  81. package/dist/{public-types-Dpch9JG0.d.cts → public-types-D_y4Ptcj.d.cts} +747 -21
  82. package/dist/{public-types-C948HNVF.d.ts → public-types-Dl1jiWjk.d.ts} +747 -21
  83. package/dist/public-types.cjs +1713 -55
  84. package/dist/public-types.d.cts +2 -2
  85. package/dist/public-types.d.ts +2 -2
  86. package/dist/public-types.js +6 -6
  87. package/dist/runtime/collab.cjs +4 -0
  88. package/dist/runtime/collab.d.cts +3 -3
  89. package/dist/runtime/collab.d.ts +3 -3
  90. package/dist/runtime/collab.js +2 -2
  91. package/dist/runtime/document-runtime.cjs +3699 -507
  92. package/dist/runtime/document-runtime.d.cts +2 -2
  93. package/dist/runtime/document-runtime.d.ts +2 -2
  94. package/dist/runtime/document-runtime.js +18 -18
  95. package/dist/{session-Dqg17V3s.d.ts → session-C1EPAkcI.d.ts} +3 -3
  96. package/dist/{session-BlXE5zxz.d.cts → session-D15QOO0Q.d.cts} +3 -3
  97. package/dist/session.cjs +951 -104
  98. package/dist/session.d.cts +5 -5
  99. package/dist/session.d.ts +5 -5
  100. package/dist/session.js +10 -8
  101. package/dist/tailwind.cjs +1752 -91
  102. package/dist/tailwind.d.cts +2 -2
  103. package/dist/tailwind.d.ts +2 -2
  104. package/dist/tailwind.js +10 -10
  105. package/dist/{types-C9vZVpKy.d.cts → types-BoSRp2Vg.d.cts} +2 -2
  106. package/dist/{types-B1tlF1bq.d.ts → types-DEvRwq9C.d.ts} +2 -2
  107. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  108. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  109. package/dist/ui-tailwind/editor-surface/search-plugin.js +7 -7
  110. package/dist/ui-tailwind/theme/editor-theme.css +5 -5
  111. package/dist/ui-tailwind.cjs +1752 -91
  112. package/dist/ui-tailwind.d.cts +8 -8
  113. package/dist/ui-tailwind.d.ts +8 -8
  114. package/dist/ui-tailwind.js +10 -10
  115. package/package.json +17 -5
  116. package/dist/ui-tailwind/theme/tokens.css +0 -382
@@ -1185,7 +1185,7 @@ function parseTextStory(content) {
1185
1185
  function countLogicalPositions(units) {
1186
1186
  let size = 0;
1187
1187
  for (const unit of units) {
1188
- if (unit.kind !== "scope_marker") size += 1;
1188
+ size += unitLogicalSize(unit);
1189
1189
  }
1190
1190
  return size;
1191
1191
  }
@@ -1245,7 +1245,29 @@ function flattenInlineNodes(nodes, hyperlinkHref) {
1245
1245
  });
1246
1246
  break;
1247
1247
  case "hyperlink":
1248
- units.push(...flattenInlineNodes(node.children, node.href));
1248
+ units.push({
1249
+ kind: "protected_inline",
1250
+ node: structuredClone(node),
1251
+ logicalSize: inlineLogicalLength(node),
1252
+ reason: "hyperlink"
1253
+ });
1254
+ break;
1255
+ case "field":
1256
+ units.push({
1257
+ kind: "protected_inline",
1258
+ node: structuredClone(node),
1259
+ logicalSize: inlineLogicalLength(node),
1260
+ reason: "field"
1261
+ });
1262
+ break;
1263
+ case "bookmark_start":
1264
+ case "bookmark_end":
1265
+ units.push({
1266
+ kind: "protected_inline",
1267
+ node: structuredClone(node),
1268
+ logicalSize: 0,
1269
+ reason: "bookmark"
1270
+ });
1249
1271
  break;
1250
1272
  case "image":
1251
1273
  units.push({
@@ -1279,6 +1301,32 @@ function flattenInlineNodes(nodes, hyperlinkHref) {
1279
1301
  }
1280
1302
  return units;
1281
1303
  }
1304
+ function unitLogicalSize(unit) {
1305
+ switch (unit.kind) {
1306
+ case "scope_marker":
1307
+ return 0;
1308
+ case "protected_inline":
1309
+ return unit.logicalSize;
1310
+ default:
1311
+ return 1;
1312
+ }
1313
+ }
1314
+ function inlineLogicalLength(node) {
1315
+ switch (node.type) {
1316
+ case "text":
1317
+ return Array.from(node.text).length;
1318
+ case "hyperlink":
1319
+ case "field":
1320
+ return node.children.reduce((total, child) => total + inlineLogicalLength(child), 0);
1321
+ case "bookmark_start":
1322
+ case "bookmark_end":
1323
+ case "scope_marker_start":
1324
+ case "scope_marker_end":
1325
+ return 0;
1326
+ default:
1327
+ return 1;
1328
+ }
1329
+ }
1282
1330
  function extractParagraphProperties(paragraph) {
1283
1331
  return {
1284
1332
  ...paragraph.styleId ? { styleId: paragraph.styleId } : {},
@@ -2473,7 +2521,19 @@ function createHeaderFooterStoryKey(input) {
2473
2521
  function createNoteStoryKey(kind, noteId) {
2474
2522
  return `${kind}:${noteId}`;
2475
2523
  }
2476
- function collectEditableTargetRefs(doc) {
2524
+ function collectCanonicalLayoutInputs(doc) {
2525
+ const blockContexts = collectStoryBlockContexts(doc);
2526
+ return {
2527
+ stories: collectCanonicalStoryIdentities(doc),
2528
+ fieldRegions: collectCanonicalFieldRegionIdentities(doc),
2529
+ numbering: collectCanonicalNumberingLayoutInputs(doc, blockContexts),
2530
+ tables: collectCanonicalTableLayoutInputs(blockContexts),
2531
+ anchors: collectCanonicalAnchorLayoutInputs(doc, blockContexts),
2532
+ scopes: collectCanonicalScopeLayoutInputs(blockContexts),
2533
+ editableTargets: collectEditableTargetRefs(doc)
2534
+ };
2535
+ }
2536
+ function collectEditableTargetRefs(doc, cache) {
2477
2537
  const targets = [];
2478
2538
  for (const context of collectStoryBlockContexts(doc)) {
2479
2539
  collectEditableTargetsInBlocks(
@@ -2485,17 +2545,53 @@ function collectEditableTargetRefs(doc) {
2485
2545
  insideTextBox: false,
2486
2546
  tableDepth: 0
2487
2547
  },
2488
- targets
2548
+ targets,
2549
+ cache
2489
2550
  );
2490
2551
  }
2552
+ collectFieldRegionRefreshTargets(doc, targets);
2553
+ collectBookmarkContentRangeTargets(doc, targets);
2491
2554
  collectReviewEditableTargets(doc, targets);
2492
2555
  return targets;
2493
2556
  }
2494
- function collectEditableTargetsInBlocks(blocks, context, targets) {
2557
+ function buildBlockCacheSignature(context, blockIndex) {
2558
+ const cc = context.contentControl;
2559
+ const tt = context.tableTarget;
2560
+ const owner = tt?.editableOwnersByChildIndex?.get(blockIndex);
2561
+ return [
2562
+ context.storyKey,
2563
+ context.insideSdt ? "1" : "0",
2564
+ context.insideTextBox ? "1" : "0",
2565
+ String(context.tableDepth),
2566
+ cc?.sdtId ?? "",
2567
+ cc?.tag ?? "",
2568
+ cc?.alias ?? "",
2569
+ cc?.sdtType ?? "",
2570
+ cc?.lock ?? "",
2571
+ tt?.tablePath ?? "",
2572
+ tt?.tableDepth ?? "",
2573
+ tt?.rowIndex ?? "",
2574
+ tt?.cellIndex ?? "",
2575
+ tt?.gridColumnStart ?? "",
2576
+ tt?.cell?.verticalMerge ?? "",
2577
+ tt?.cell?.gridSpan ?? "",
2578
+ owner?.targetKey ?? ""
2579
+ ].join("|");
2580
+ }
2581
+ function collectEditableTargetsInBlocks(blocks, context, targets, cache) {
2495
2582
  for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
2496
2583
  const block = blocks[blockIndex];
2497
2584
  if (!block) continue;
2498
2585
  const blockPath = `${context.basePath}/block[${blockIndex}]`;
2586
+ const signature = cache !== void 0 ? buildBlockCacheSignature(context, blockIndex) : "";
2587
+ if (cache !== void 0) {
2588
+ const cached = cache.get(block);
2589
+ if (cached !== void 0 && cached.blockPath === blockPath && cached.signature === signature) {
2590
+ for (const target of cached.targets) targets.push(target);
2591
+ continue;
2592
+ }
2593
+ }
2594
+ const blockStart = targets.length;
2499
2595
  if (block.type === "paragraph") {
2500
2596
  const targetKind = editableParagraphTargetKind(context);
2501
2597
  if (targetKind !== null) {
@@ -2507,14 +2603,13 @@ function collectEditableTargetsInBlocks(blocks, context, targets) {
2507
2603
  blockPath,
2508
2604
  editableParagraphTargetPosture(targetKind),
2509
2605
  context.contentControl,
2510
- context.tableTarget
2606
+ context.tableTarget,
2607
+ context.tableTarget?.editableOwnersByChildIndex?.get(blockIndex)
2511
2608
  )
2512
2609
  );
2513
2610
  }
2514
2611
  collectEditableTargetsInInlines(block.children ?? [], `${blockPath}/inline`, context, targets);
2515
- continue;
2516
- }
2517
- if (block.type === "sdt") {
2612
+ } else if (block.type === "sdt") {
2518
2613
  const contentControl = contentControlIdentityForSdt(block, context.contentControl);
2519
2614
  collectEditableTargetsInBlocks(
2520
2615
  block.children,
@@ -2524,11 +2619,10 @@ function collectEditableTargetsInBlocks(blocks, context, targets) {
2524
2619
  insideSdt: true,
2525
2620
  contentControl
2526
2621
  },
2527
- targets
2622
+ targets,
2623
+ cache
2528
2624
  );
2529
- continue;
2530
- }
2531
- if (block.type === "custom_xml") {
2625
+ } else if (block.type === "custom_xml") {
2532
2626
  targets.push(createCustomXmlEditableTarget(block, context.storyKey, blockPath));
2533
2627
  collectEditableTargetsInBlocks(
2534
2628
  block.children,
@@ -2536,25 +2630,29 @@ function collectEditableTargetsInBlocks(blocks, context, targets) {
2536
2630
  ...context,
2537
2631
  basePath: blockPath
2538
2632
  },
2539
- targets
2633
+ targets,
2634
+ cache
2540
2635
  );
2541
- continue;
2542
- }
2543
- if (block.type === "opaque_block") {
2636
+ } else if (block.type === "opaque_block") {
2544
2637
  targets.push(createOpaqueBlockEditableTarget(block, context.storyKey, blockPath));
2545
- continue;
2546
- }
2547
- if (block.type === "alt_chunk") {
2638
+ } else if (block.type === "alt_chunk") {
2548
2639
  targets.push(createAltChunkEditableTarget(block.relationshipId, context.storyKey, blockPath));
2549
- continue;
2550
- }
2551
- if (block.type === "table") {
2552
- collectEditableTargetsInTable(block, blockPath, context, targets);
2640
+ } else if (block.type === "table") {
2641
+ collectEditableTargetsInTable(block, blockPath, context, targets, cache);
2642
+ }
2643
+ if (cache !== void 0) {
2644
+ const blockTargets = targets.slice(blockStart);
2645
+ cache.set(block, {
2646
+ blockPath,
2647
+ signature,
2648
+ targets: blockTargets
2649
+ });
2553
2650
  }
2554
2651
  }
2555
2652
  }
2556
- function collectEditableTargetsInTable(table, tablePath, context, targets) {
2653
+ function collectEditableTargetsInTable(table, tablePath, context, targets, cache) {
2557
2654
  const tableDepth = context.tableDepth + 1;
2655
+ const verticalMergeOwners = [];
2558
2656
  targets.push(createTableStructureTarget({
2559
2657
  scope: "table",
2560
2658
  kind: "table-structure-table",
@@ -2593,6 +2691,10 @@ function collectEditableTargetsInTable(table, tablePath, context, targets) {
2593
2691
  const cell = row.cells[cellIndex];
2594
2692
  if (!cell) continue;
2595
2693
  const gridSpan = cell.gridSpan ?? 1;
2694
+ const continuationOwner = cell.verticalMerge === "continue" ? findVerticalMergeOwner(verticalMergeOwners, gridColumnStart, gridSpan) : null;
2695
+ if (cell.verticalMerge !== "continue") {
2696
+ clearVerticalMergeOwners(verticalMergeOwners, gridColumnStart, gridSpan);
2697
+ }
2596
2698
  targets.push(createTableStructureTarget({
2597
2699
  scope: "cell",
2598
2700
  kind: "table-structure-cell",
@@ -2635,15 +2737,136 @@ function collectEditableTargetsInTable(table, tablePath, context, targets) {
2635
2737
  row,
2636
2738
  cellIndex,
2637
2739
  cell,
2638
- gridColumnStart
2740
+ gridColumnStart,
2741
+ ...continuationOwner ? {
2742
+ editableOwnersByChildIndex: continuationOwnerTargetsByChildIndex(
2743
+ continuationOwner,
2744
+ cell.children.length
2745
+ )
2746
+ } : {}
2639
2747
  }
2640
2748
  },
2641
- targets
2749
+ targets,
2750
+ cache
2642
2751
  );
2752
+ if (cell.verticalMerge === "restart") {
2753
+ verticalMergeOwners.push(createVerticalMergeOwnerState({
2754
+ context,
2755
+ table,
2756
+ tablePath,
2757
+ tableDepth,
2758
+ rowIndex,
2759
+ row,
2760
+ cellIndex,
2761
+ cell,
2762
+ gridColumnStart,
2763
+ gridSpan
2764
+ }));
2765
+ }
2643
2766
  gridColumnStart += gridSpan;
2644
2767
  }
2645
2768
  }
2646
2769
  }
2770
+ function findVerticalMergeOwner(owners, gridColumnStart, gridSpan) {
2771
+ return owners.find(
2772
+ (owner) => owner.gridColumnStart === gridColumnStart && owner.gridSpan === gridSpan
2773
+ ) ?? null;
2774
+ }
2775
+ function clearVerticalMergeOwners(owners, gridColumnStart, gridSpan) {
2776
+ const gridColumnEnd = gridColumnStart + gridSpan;
2777
+ for (let index = owners.length - 1; index >= 0; index -= 1) {
2778
+ const owner = owners[index];
2779
+ if (!owner) continue;
2780
+ const ownerEnd = owner.gridColumnStart + owner.gridSpan;
2781
+ if (gridColumnStart < ownerEnd && owner.gridColumnStart < gridColumnEnd) {
2782
+ owners.splice(index, 1);
2783
+ }
2784
+ }
2785
+ }
2786
+ function continuationOwnerTargetsByChildIndex(owner, childCount) {
2787
+ if (!owner.fallbackOwnerTarget) return void 0;
2788
+ const targets = /* @__PURE__ */ new Map();
2789
+ for (let childIndex = 0; childIndex < childCount; childIndex += 1) {
2790
+ targets.set(
2791
+ childIndex,
2792
+ owner.ownerTargetsByChildIndex.get(childIndex) ?? owner.fallbackOwnerTarget
2793
+ );
2794
+ }
2795
+ return targets;
2796
+ }
2797
+ function createVerticalMergeOwnerState(input) {
2798
+ const ownerTargetsByChildIndex = /* @__PURE__ */ new Map();
2799
+ for (let childIndex = 0; childIndex < input.cell.children.length; childIndex += 1) {
2800
+ const owner = createVerticalMergeEditableOwner({ ...input, childIndex });
2801
+ if (owner) ownerTargetsByChildIndex.set(childIndex, owner);
2802
+ }
2803
+ return {
2804
+ gridColumnStart: input.gridColumnStart,
2805
+ gridSpan: input.gridSpan,
2806
+ ownerTargetsByChildIndex,
2807
+ ...ownerTargetsByChildIndex.size > 0 ? { fallbackOwnerTarget: ownerTargetsByChildIndex.values().next().value } : {}
2808
+ };
2809
+ }
2810
+ function createVerticalMergeEditableOwner(input) {
2811
+ const child = input.cell.children[input.childIndex];
2812
+ if (child?.type !== "paragraph") return null;
2813
+ const ownerTableTarget = {
2814
+ table: input.table,
2815
+ tablePath: input.tablePath,
2816
+ tableDepth: input.tableDepth,
2817
+ rowIndex: input.rowIndex,
2818
+ row: input.row,
2819
+ cellIndex: input.cellIndex,
2820
+ cell: input.cell,
2821
+ gridColumnStart: input.gridColumnStart
2822
+ };
2823
+ const kind = editableParagraphTargetKind({
2824
+ ...input.context,
2825
+ basePath: `${input.tablePath}/row[${input.rowIndex}]/cell[${input.cellIndex}]`,
2826
+ tableDepth: input.tableDepth,
2827
+ tableTarget: ownerTableTarget
2828
+ });
2829
+ if (!kind) return null;
2830
+ const blockPath = `${input.tablePath}/row[${input.rowIndex}]/cell[${input.cellIndex}]/block[${input.childIndex}]`;
2831
+ const paragraphTextHash = hashText(collectParagraphText(child));
2832
+ const table = createTableIdentity({
2833
+ scope: "text",
2834
+ context: {
2835
+ storyKey: input.context.storyKey,
2836
+ insideSdt: input.context.contentControl !== void 0
2837
+ },
2838
+ ...ownerTableTarget
2839
+ });
2840
+ return {
2841
+ targetKey: `${input.context.storyKey}:${blockPath}:text`,
2842
+ kind,
2843
+ storyKey: input.context.storyKey,
2844
+ blockPath,
2845
+ leafPath: `${blockPath}/inline`,
2846
+ commandFamily: "text-leaf",
2847
+ reason: "vertical-merge-restart-cell",
2848
+ canonicalAddress: ownerRoutingFromAddress(
2849
+ createTableTargetCanonicalAddress(
2850
+ table,
2851
+ "paragraph",
2852
+ paragraphTextHash,
2853
+ { rangeBoundary: { boundaryKind: "cell-fragment" } }
2854
+ )
2855
+ ),
2856
+ table: {
2857
+ tableKey: table.tableKey,
2858
+ tablePath: table.tablePath,
2859
+ ...table.sourceRef !== void 0 ? { sourceRef: table.sourceRef } : {},
2860
+ ...table.rowSourceRef !== void 0 ? { rowSourceRef: table.rowSourceRef } : {},
2861
+ ...table.cellSourceRef !== void 0 ? { cellSourceRef: table.cellSourceRef } : {},
2862
+ ...table.rowIndex !== void 0 ? { rowIndex: table.rowIndex } : {},
2863
+ ...table.cellIndex !== void 0 ? { cellIndex: table.cellIndex } : {},
2864
+ ...table.gridColumnStart !== void 0 ? { gridColumnStart: table.gridColumnStart } : {},
2865
+ ...table.gridSpan !== void 0 ? { gridSpan: table.gridSpan } : {},
2866
+ ...table.verticalMerge !== void 0 ? { verticalMerge: table.verticalMerge } : {}
2867
+ }
2868
+ };
2869
+ }
2647
2870
  function computeTableStructureColumnCount(table) {
2648
2871
  let columnCount = table.gridColumns.length;
2649
2872
  for (const row of table.rows) {
@@ -2663,6 +2886,7 @@ function createTableStructureTarget(input) {
2663
2886
  const columnPath = input.columnIndex !== void 0 ? `${input.tablePath}/column[${input.columnIndex}]` : void 0;
2664
2887
  const blockPath = cellPath ?? rowPath ?? columnPath ?? input.tablePath;
2665
2888
  const tableIdentity = createTableIdentity(input);
2889
+ const targetHash = hashTableStructureTarget(input);
2666
2890
  return {
2667
2891
  targetKey: `${tableKey}:structure:${tableIdentity.operationScope}${tableTargetSuffix(tableIdentity)}`,
2668
2892
  kind: input.kind,
@@ -2674,8 +2898,14 @@ function createTableStructureTarget(input) {
2674
2898
  ...input.table.sourceRef !== void 0 ? { sourceRef: input.table.sourceRef } : {},
2675
2899
  ...input.context.contentControl !== void 0 ? { contentControl: input.context.contentControl } : {},
2676
2900
  table: tableIdentity,
2901
+ canonicalAddress: createTableTargetCanonicalAddress(
2902
+ tableIdentity,
2903
+ tableStructureBlockType(input.scope),
2904
+ targetHash,
2905
+ { rangeBoundary: { boundaryKind: "table-grid" } }
2906
+ ),
2677
2907
  staleCheck: {
2678
- targetHash: hashTableStructureTarget(input),
2908
+ targetHash,
2679
2909
  childCount: input.scope === "table" ? input.table.rows.length : input.scope === "row" ? input.row?.cells.length ?? 0 : input.scope === "cell" || input.scope === "span" ? input.cell?.children.length ?? 0 : computeTableStructureColumnCount(input.table),
2680
2910
  blockType: tableStructureBlockType(input.scope),
2681
2911
  ...input.table.sourceRef !== void 0 ? { sourceRef: input.table.sourceRef } : {}
@@ -2686,10 +2916,15 @@ function createTableStructureTarget(input) {
2686
2916
  function createTableIdentity(input) {
2687
2917
  const tableKey = `${input.context.storyKey}:${input.tablePath}`;
2688
2918
  const columnCount = computeTableStructureColumnCount(input.table);
2919
+ const rowRange = tableFragmentRowRange(input).rowRange;
2920
+ const columnRange = tableFragmentColumnRange(input, columnCount).columnRange;
2689
2921
  const base = {
2690
2922
  operationScope: input.scope,
2691
2923
  tableKey,
2692
2924
  tablePath: input.tablePath,
2925
+ ...input.table.sourceRef !== void 0 ? { sourceRef: input.table.sourceRef } : {},
2926
+ ...input.row?.sourceRef !== void 0 ? { rowSourceRef: input.row.sourceRef } : {},
2927
+ ...input.cell?.sourceRef !== void 0 ? { cellSourceRef: input.cell.sourceRef } : {},
2693
2928
  ...tablePathIndexes(input.tablePath),
2694
2929
  tableDepth: input.tableDepth,
2695
2930
  ...input.tableDepth >= 2 ? { nestedTable: true } : {},
@@ -2697,7 +2932,10 @@ function createTableIdentity(input) {
2697
2932
  ...input.context.storyKey !== MAIN_STORY_KEY ? { secondaryStory: true } : {},
2698
2933
  rowCount: input.table.rows.length,
2699
2934
  columnCount,
2700
- fragment: createTableFragmentIdentity(input, tableKey, columnCount)
2935
+ fragment: createTableFragmentIdentity(input, tableKey, columnCount),
2936
+ ...input.cell !== void 0 ? {
2937
+ cellFragment: createTableCellFragmentIdentity(input, tableKey, rowRange, columnRange)
2938
+ } : {}
2701
2939
  };
2702
2940
  return {
2703
2941
  ...base,
@@ -2711,6 +2949,25 @@ function createTableIdentity(input) {
2711
2949
  ...input.cell !== void 0 ? { blockCount: input.cell.children.length } : {}
2712
2950
  };
2713
2951
  }
2952
+ function createTableCellFragmentIdentity(input, tableKey, rowRange, columnRange) {
2953
+ const text = (input.cell?.children ?? []).map(blockTextForTargetHash).join("");
2954
+ return {
2955
+ fragmentKey: hashText(JSON.stringify({
2956
+ tableKey,
2957
+ rowIndex: input.rowIndex ?? null,
2958
+ cellIndex: input.cellIndex ?? null,
2959
+ gridColumnStart: input.gridColumnStart ?? null,
2960
+ gridSpan: input.cell?.gridSpan ?? 1,
2961
+ verticalMerge: input.cell?.verticalMerge ?? null,
2962
+ sourceId: input.cell?.sourceRef?.sourceId ?? null
2963
+ })),
2964
+ textHash: hashText(text),
2965
+ blockCount: input.cell?.children.length ?? 0,
2966
+ ...rowRange !== void 0 ? { rowRange } : {},
2967
+ ...columnRange !== void 0 ? { columnRange } : {},
2968
+ ...sourceJoinHashForRefs(input.table.sourceRef, input.row?.sourceRef, input.cell?.sourceRef)
2969
+ };
2970
+ }
2714
2971
  function tablePathIndexes(tablePath) {
2715
2972
  const blockIndexes = [...tablePath.matchAll(/\/block\[(\d+)\]/gu)].map((match) => Number(match[1]));
2716
2973
  const storyBlockIndex = blockIndexes[0];
@@ -2876,13 +3133,39 @@ function collectEditableTargetsInInlines(inlines, basePath, context, targets) {
2876
3133
  }
2877
3134
  }
2878
3135
  }
2879
- function createParagraphEditableTarget(paragraph, kind, storyKey, blockPath, targetPosture = { editability: "editable", posture: { blockers: [] } }, contentControl, tableTarget) {
3136
+ function createParagraphEditableTarget(paragraph, kind, storyKey, blockPath, targetPosture = { editability: "editable", posture: { blockers: [] } }, contentControl, tableTarget, editableOwner) {
2880
3137
  const paragraphText = collectParagraphText(paragraph);
3138
+ const paragraphTextHash = hashText(paragraphText);
2881
3139
  const sourceRef = paragraph.sourceRef;
2882
3140
  const lockedContentControl = contentControlLocksContent(contentControl);
2883
- const posture = lockedContentControl ? mergeTargetPosture(targetPosture.posture, ["locked-content-control"], {
3141
+ const syntheticLayoutCell = tableTarget?.cell?.verticalMerge === "continue";
3142
+ const tableIdentity = tableTarget !== void 0 ? createTableIdentity({
3143
+ scope: "text",
3144
+ context: { storyKey, insideSdt: contentControl !== void 0 },
3145
+ ...tableTarget
3146
+ }) : void 0;
3147
+ const listAddress = tableIdentity === void 0 && paragraph.numbering !== void 0 ? createCanonicalAddress({
3148
+ addressKind: "list-item-text",
3149
+ storyKey,
3150
+ staleCheckKind: "paragraph",
3151
+ operationScope: "list-text",
3152
+ sourceRefs: [sourceRef],
3153
+ staleHash: paragraphTextHash,
3154
+ rangeBoundary: { boundaryKind: "list-item-text" },
3155
+ discriminator: {
3156
+ blockPath,
3157
+ numberingInstanceId: paragraph.numbering.numberingInstanceId,
3158
+ level: paragraph.numbering.level,
3159
+ sourceId: sourceRef?.sourceId ?? null,
3160
+ paraId: paragraph.wordExtensionIds?.paraId ?? null,
3161
+ textId: paragraph.wordExtensionIds?.textId ?? null
3162
+ }
3163
+ }) : void 0;
3164
+ const tableAwarePosture = syntheticLayoutCell ? mergeTargetPosture(targetPosture.posture, ["synthetic-layout-cell"]) : targetPosture.posture;
3165
+ const posture = lockedContentControl ? mergeTargetPosture(tableAwarePosture, ["locked-content-control"], {
2884
3166
  lockedContentControl: true
2885
- }) : targetPosture.posture;
3167
+ }) : tableAwarePosture;
3168
+ const editability = lockedContentControl || syntheticLayoutCell ? "non-editable" : targetPosture.editability;
2886
3169
  return {
2887
3170
  targetKey: `${storyKey}:${blockPath}:text`,
2888
3171
  kind,
@@ -2890,12 +3173,24 @@ function createParagraphEditableTarget(paragraph, kind, storyKey, blockPath, tar
2890
3173
  blockPath,
2891
3174
  leafPath: `${blockPath}/inline`,
2892
3175
  commandFamily: "text-leaf",
2893
- editability: lockedContentControl ? "non-editable" : targetPosture.editability,
3176
+ editability,
2894
3177
  ...sourceRef !== void 0 ? { sourceRef } : {},
2895
3178
  ...contentControl !== void 0 ? { contentControl } : {},
2896
- ...tableTarget !== void 0 ? { table: createTableIdentity({ scope: "text", context: { storyKey, insideSdt: contentControl !== void 0 }, ...tableTarget }) } : {},
3179
+ ...tableIdentity !== void 0 ? { table: tableIdentity } : {},
3180
+ ...editableOwner !== void 0 ? { editableOwner } : {},
3181
+ ...tableIdentity !== void 0 ? {
3182
+ canonicalAddress: createTableTargetCanonicalAddress(
3183
+ tableIdentity,
3184
+ "paragraph",
3185
+ paragraphTextHash,
3186
+ {
3187
+ rangeBoundary: { boundaryKind: "cell-fragment" },
3188
+ owner: editableOwner?.canonicalAddress
3189
+ }
3190
+ )
3191
+ } : listAddress !== void 0 ? { canonicalAddress: listAddress } : {},
2897
3192
  staleCheck: {
2898
- paragraphTextHash: hashText(paragraphText),
3193
+ paragraphTextHash,
2899
3194
  paragraphTextLength: Array.from(paragraphText).length,
2900
3195
  inlineCount: paragraph.children?.length ?? 0,
2901
3196
  blockType: "paragraph",
@@ -2926,12 +3221,27 @@ function collectInlineTarget(inline, storyKey, inlinePath, targets) {
2926
3221
  return;
2927
3222
  case "hyperlink":
2928
3223
  targets.push(createHyperlinkEditableTarget(inline, storyKey, inlinePath));
3224
+ targets.push(createHyperlinkDestinationEditableTarget(inline, storyKey, inlinePath));
2929
3225
  return;
2930
3226
  case "bookmark_start":
2931
- targets.push(createBookmarkEditableTarget(inline.bookmarkId, inline.name, storyKey, inlinePath, "start"));
3227
+ targets.push(createBookmarkEditableTarget(
3228
+ inline.bookmarkId,
3229
+ inline.name,
3230
+ storyKey,
3231
+ inlinePath,
3232
+ "start",
3233
+ inline.sourceRef
3234
+ ));
2932
3235
  return;
2933
3236
  case "bookmark_end":
2934
- targets.push(createBookmarkEditableTarget(inline.bookmarkId, void 0, storyKey, inlinePath, "end"));
3237
+ targets.push(createBookmarkEditableTarget(
3238
+ inline.bookmarkId,
3239
+ void 0,
3240
+ storyKey,
3241
+ inlinePath,
3242
+ "end",
3243
+ inline.sourceRef
3244
+ ));
2935
3245
  return;
2936
3246
  case "image":
2937
3247
  targets.push(createImageEditableTarget(inline, storyKey, inlinePath));
@@ -2955,6 +3265,7 @@ function collectInlineTarget(inline, storyKey, inlinePath, targets) {
2955
3265
  function createFieldEditableTarget(field, storyKey, inlinePath) {
2956
3266
  const resultText = field.children.map(inlineTextForTargetHash).join("");
2957
3267
  const sourceRef = field.sourceRef;
3268
+ const targetHash = hashText(`${field.instruction}\0${resultText}`);
2958
3269
  const preserveOnly = field.refreshStatus === "preserve-only" || field.fieldFamily === "UNKNOWN";
2959
3270
  const blockers = preserveOnly ? ["field-generated-text", "preserve-only"] : ["field-generated-text", "unmodeled-target"];
2960
3271
  return {
@@ -2974,9 +3285,28 @@ function createFieldEditableTarget(field, storyKey, inlinePath) {
2974
3285
  ...field.locked !== void 0 ? { locked: field.locked } : {},
2975
3286
  ...field.dirty !== void 0 ? { dirty: field.dirty } : {}
2976
3287
  },
3288
+ canonicalAddress: createCanonicalAddress({
3289
+ addressKind: "field-result",
3290
+ storyKey,
3291
+ staleCheckKind: "field",
3292
+ operationScope: "field-refresh",
3293
+ sourceRefs: [sourceRef],
3294
+ staleHash: targetHash,
3295
+ rangeBoundary: {
3296
+ boundaryKind: "field-result",
3297
+ from: 0,
3298
+ to: Array.from(resultText).length
3299
+ },
3300
+ discriminator: {
3301
+ canonicalFieldId: field.canonicalFieldId ?? null,
3302
+ fieldFamily: field.fieldFamily ?? null,
3303
+ fieldTarget: field.fieldTarget ?? null,
3304
+ sourceId: sourceRef?.sourceId ?? null
3305
+ }
3306
+ }),
2977
3307
  staleCheck: {
2978
3308
  blockType: "field",
2979
- targetHash: hashText(`${field.instruction}\0${resultText}`),
3309
+ targetHash,
2980
3310
  targetTextLength: Array.from(resultText).length,
2981
3311
  childCount: field.children.length,
2982
3312
  ...sourceRef !== void 0 ? { sourceRef } : {}
@@ -2990,6 +3320,7 @@ function createFieldEditableTarget(field, storyKey, inlinePath) {
2990
3320
  function createHyperlinkEditableTarget(hyperlink, storyKey, inlinePath) {
2991
3321
  const text = hyperlink.children.map(inlineTextForTargetHash).join("");
2992
3322
  const sourceRef = hyperlink.sourceRef ?? hyperlink.fieldCarrier?.sourceRef;
3323
+ const targetHash = hashText(`${hyperlink.href}\0${text}`);
2993
3324
  return {
2994
3325
  targetKey: `${storyKey}:${inlinePath}:hyperlink`,
2995
3326
  kind: "hyperlink-text",
@@ -3000,9 +3331,25 @@ function createHyperlinkEditableTarget(hyperlink, storyKey, inlinePath) {
3000
3331
  editability: "editable",
3001
3332
  ...sourceRef !== void 0 ? { sourceRef } : {},
3002
3333
  link: { href: hyperlink.href },
3334
+ canonicalAddress: createCanonicalAddress({
3335
+ addressKind: "hyperlink-display-text",
3336
+ storyKey,
3337
+ staleCheckKind: "hyperlink",
3338
+ sourceRefs: [sourceRef],
3339
+ staleHash: targetHash,
3340
+ rangeBoundary: {
3341
+ boundaryKind: "hyperlink-display",
3342
+ from: 0,
3343
+ to: Array.from(text).length
3344
+ },
3345
+ discriminator: {
3346
+ href: hyperlink.href,
3347
+ sourceId: sourceRef?.sourceId ?? null
3348
+ }
3349
+ }),
3003
3350
  staleCheck: {
3004
3351
  blockType: "hyperlink",
3005
- targetHash: hashText(`${hyperlink.href}\0${text}`),
3352
+ targetHash,
3006
3353
  targetTextLength: Array.from(text).length,
3007
3354
  childCount: hyperlink.children.length,
3008
3355
  ...sourceRef !== void 0 ? { sourceRef } : {}
@@ -3010,7 +3357,52 @@ function createHyperlinkEditableTarget(hyperlink, storyKey, inlinePath) {
3010
3357
  posture: { blockers: [] }
3011
3358
  };
3012
3359
  }
3013
- function createBookmarkEditableTarget(bookmarkId, bookmarkName, storyKey, inlinePath, edge) {
3360
+ function createHyperlinkDestinationEditableTarget(hyperlink, storyKey, inlinePath) {
3361
+ const sourceRef = hyperlink.sourceRef ?? hyperlink.fieldCarrier?.sourceRef;
3362
+ const destinationKind = hyperlink.href.startsWith("#") ? "internal-anchor" : "external";
3363
+ const targetHash = hashText(`destination\0${hyperlink.href}`);
3364
+ return {
3365
+ targetKey: `${storyKey}:${inlinePath}:hyperlink-destination`,
3366
+ kind: "hyperlink-destination",
3367
+ storyKey,
3368
+ blockPath: inlinePath,
3369
+ leafPath: `${inlinePath}/destination`,
3370
+ commandFamily: "link-bookmark",
3371
+ editability: "non-editable",
3372
+ ...sourceRef !== void 0 ? { sourceRef } : {},
3373
+ link: {
3374
+ href: hyperlink.href,
3375
+ destinationKind
3376
+ },
3377
+ canonicalAddress: createCanonicalAddress({
3378
+ addressKind: "hyperlink-destination",
3379
+ storyKey,
3380
+ staleCheckKind: "hyperlink",
3381
+ operationScope: "link-destination",
3382
+ sourceRefs: [sourceRef],
3383
+ staleHash: targetHash,
3384
+ rangeBoundary: {
3385
+ boundaryKind: "hyperlink-destination",
3386
+ ...sourceRef !== void 0 ? { startSourceJoinHash: sourceJoinHash([sourceRef]) } : {},
3387
+ ...sourceRef !== void 0 ? { endSourceJoinHash: sourceJoinHash([sourceRef]) } : {}
3388
+ },
3389
+ discriminator: {
3390
+ href: hyperlink.href,
3391
+ destinationKind,
3392
+ sourceId: sourceRef?.sourceId ?? null
3393
+ }
3394
+ }),
3395
+ staleCheck: {
3396
+ blockType: "hyperlink",
3397
+ targetHash,
3398
+ childCount: hyperlink.children.length,
3399
+ ...sourceRef !== void 0 ? { sourceRef } : {}
3400
+ },
3401
+ posture: { blockers: ["unmodeled-target"] }
3402
+ };
3403
+ }
3404
+ function createBookmarkEditableTarget(bookmarkId, bookmarkName, storyKey, inlinePath, edge, sourceRef) {
3405
+ const targetHash = hashText(`${edge}\0${bookmarkId}\0${bookmarkName ?? ""}`);
3014
3406
  return {
3015
3407
  targetKey: `${storyKey}:${inlinePath}:bookmark:${edge}:${bookmarkId}`,
3016
3408
  kind: "bookmark-anchor",
@@ -3019,14 +3411,34 @@ function createBookmarkEditableTarget(bookmarkId, bookmarkName, storyKey, inline
3019
3411
  leafPath: inlinePath,
3020
3412
  commandFamily: "link-bookmark",
3021
3413
  editability: "non-editable",
3414
+ ...sourceRef !== void 0 ? { sourceRef } : {},
3022
3415
  link: {
3023
3416
  bookmarkId,
3024
3417
  ...bookmarkName !== void 0 ? { bookmarkName } : {}
3025
3418
  },
3419
+ canonicalAddress: createCanonicalAddress({
3420
+ addressKind: "bookmark-anchor",
3421
+ storyKey,
3422
+ staleCheckKind: "bookmark",
3423
+ sourceRefs: [sourceRef],
3424
+ staleHash: targetHash,
3425
+ rangeBoundary: {
3426
+ boundaryKind: "bookmark-anchor",
3427
+ ...sourceRef !== void 0 ? { startSourceJoinHash: sourceJoinHash([sourceRef]) } : {},
3428
+ ...sourceRef !== void 0 ? { endSourceJoinHash: sourceJoinHash([sourceRef]) } : {}
3429
+ },
3430
+ discriminator: {
3431
+ bookmarkId,
3432
+ bookmarkName: bookmarkName ?? null,
3433
+ edge,
3434
+ sourceId: sourceRef?.sourceId ?? null
3435
+ }
3436
+ }),
3026
3437
  staleCheck: {
3027
3438
  blockType: "bookmark",
3028
- targetHash: hashText(`${edge}\0${bookmarkId}\0${bookmarkName ?? ""}`),
3029
- childCount: 0
3439
+ targetHash,
3440
+ childCount: 0,
3441
+ ...sourceRef !== void 0 ? { sourceRef } : {}
3030
3442
  },
3031
3443
  posture: { blockers: ["unmodeled-target"] }
3032
3444
  };
@@ -3074,6 +3486,7 @@ function createObjectEditableTarget(inline, storyKey, inlinePath) {
3074
3486
  storyKey,
3075
3487
  inlinePath,
3076
3488
  objectKind: "ole",
3489
+ sourceRef: inline.sourceRef,
3077
3490
  targetHash: `${inline.id}\0${inline.relationshipId}`,
3078
3491
  object: {
3079
3492
  objectKind: "ole",
@@ -3195,6 +3608,167 @@ function createOpaqueEditableTarget(input) {
3195
3608
  }
3196
3609
  };
3197
3610
  }
3611
+ function collectFieldRegionRefreshTargets(doc, targets) {
3612
+ for (const region of collectCanonicalFieldRegionIdentities(doc)) {
3613
+ targets.push(createFieldRegionRefreshEditableTarget(region));
3614
+ }
3615
+ }
3616
+ function createFieldRegionRefreshEditableTarget(region) {
3617
+ const isToc = region.kind === "toc-region" || region.fieldFamily === "TOC";
3618
+ const sourceRef = region.sourceRef;
3619
+ const targetHash = hashText(JSON.stringify({
3620
+ regionId: region.regionId,
3621
+ canonicalFieldId: region.canonicalFieldId,
3622
+ fieldFamily: region.fieldFamily,
3623
+ refreshStatus: region.refreshStatus,
3624
+ tocId: region.tocId ?? null,
3625
+ resultRange: region.resultRange ?? null,
3626
+ status: region.status ?? null
3627
+ }));
3628
+ return {
3629
+ targetKey: `${region.storyKey}:field-region:${region.regionId}:refresh`,
3630
+ kind: isToc ? "toc-region-refresh" : "field-region-refresh",
3631
+ storyKey: region.storyKey,
3632
+ blockPath: `${region.storyKey}/field-region[${region.regionId}]`,
3633
+ leafPath: `${region.storyKey}/field-region[${region.regionId}]/refresh`,
3634
+ commandFamily: "field",
3635
+ editability: "non-editable",
3636
+ ...sourceRef !== void 0 ? { sourceRef } : {},
3637
+ field: {
3638
+ canonicalFieldId: region.canonicalFieldId,
3639
+ regionId: region.regionId,
3640
+ fieldFamily: region.fieldFamily,
3641
+ refreshStatus: region.refreshStatus,
3642
+ ...region.sourcePath !== void 0 ? { sourcePath: region.sourcePath } : {},
3643
+ ...region.tocId !== void 0 ? { tocId: region.tocId } : {},
3644
+ ...region.resultRange !== void 0 ? {
3645
+ resultRangeFromParagraphIndex: region.resultRange.fromParagraphIndex,
3646
+ resultRangeToParagraphIndex: region.resultRange.toParagraphIndex
3647
+ } : {},
3648
+ ...region.status !== void 0 ? { status: region.status } : {},
3649
+ ...region.cachedEntryCount !== void 0 ? { cachedEntryCount: region.cachedEntryCount } : {},
3650
+ ...region.generatedEntryCount !== void 0 ? { generatedEntryCount: region.generatedEntryCount } : {}
3651
+ },
3652
+ canonicalAddress: createCanonicalAddress({
3653
+ addressKind: isToc ? "toc-region-refresh" : "field-region-refresh",
3654
+ storyKey: region.storyKey,
3655
+ staleCheckKind: "field",
3656
+ operationScope: isToc ? "toc-refresh" : "field-refresh",
3657
+ sourceRefs: [sourceRef],
3658
+ staleHash: targetHash,
3659
+ rangeBoundary: {
3660
+ boundaryKind: "field-region",
3661
+ ...region.resultRange !== void 0 ? {
3662
+ from: region.resultRange.fromParagraphIndex,
3663
+ to: region.resultRange.toParagraphIndex
3664
+ } : { from: region.paragraphIndex, to: region.paragraphIndex }
3665
+ },
3666
+ discriminator: {
3667
+ regionId: region.regionId,
3668
+ canonicalFieldId: region.canonicalFieldId,
3669
+ fieldIndex: region.fieldIndex,
3670
+ fieldFamily: region.fieldFamily,
3671
+ tocId: region.tocId ?? null
3672
+ }
3673
+ }),
3674
+ staleCheck: {
3675
+ blockType: "field",
3676
+ targetHash,
3677
+ childCount: region.cachedEntryCount ?? 0,
3678
+ ...sourceRef !== void 0 ? { sourceRef } : {}
3679
+ },
3680
+ posture: {
3681
+ blockers: ["field-generated-text", "unmodeled-target"]
3682
+ }
3683
+ };
3684
+ }
3685
+ function collectBookmarkContentRangeTargets(doc, targets) {
3686
+ const candidates = /* @__PURE__ */ new Map();
3687
+ for (const context of collectStoryBlockContexts(doc)) {
3688
+ walkBlocks(context.blocks, context.storyKey, context.basePath, {
3689
+ inline(inline, _blockPath, inlinePath) {
3690
+ if (inline.type !== "bookmark_start" && inline.type !== "bookmark_end") return;
3691
+ const key = `${context.storyKey}:${inline.bookmarkId}`;
3692
+ const previous = candidates.get(key);
3693
+ if (inline.type === "bookmark_start") {
3694
+ candidates.set(key, {
3695
+ ...previous ?? { storyKey: context.storyKey, bookmarkId: inline.bookmarkId },
3696
+ bookmarkName: inline.name,
3697
+ startPath: inlinePath,
3698
+ startSourceRef: inline.sourceRef
3699
+ });
3700
+ return;
3701
+ }
3702
+ candidates.set(key, {
3703
+ ...previous ?? { storyKey: context.storyKey, bookmarkId: inline.bookmarkId },
3704
+ endPath: inlinePath,
3705
+ endSourceRef: inline.sourceRef
3706
+ });
3707
+ }
3708
+ });
3709
+ }
3710
+ for (const candidate of candidates.values()) {
3711
+ if (candidate.startPath === void 0 || candidate.endPath === void 0) continue;
3712
+ targets.push(createBookmarkContentRangeEditableTarget({
3713
+ ...candidate,
3714
+ startPath: candidate.startPath,
3715
+ endPath: candidate.endPath
3716
+ }));
3717
+ }
3718
+ }
3719
+ function createBookmarkContentRangeEditableTarget(candidate) {
3720
+ const startSourceJoinHash = sourceJoinHash([candidate.startSourceRef]);
3721
+ const endSourceJoinHash = sourceJoinHash([candidate.endSourceRef]);
3722
+ const rangeKey = hashText(JSON.stringify({
3723
+ storyKey: candidate.storyKey,
3724
+ bookmarkId: candidate.bookmarkId,
3725
+ bookmarkName: candidate.bookmarkName ?? null,
3726
+ startSourceId: candidate.startSourceRef?.sourceId ?? null,
3727
+ endSourceId: candidate.endSourceRef?.sourceId ?? null
3728
+ }));
3729
+ const targetHash = hashText(`range\0${candidate.bookmarkId}\0${candidate.bookmarkName ?? ""}\0${candidate.startPath}\0${candidate.endPath}`);
3730
+ return {
3731
+ targetKey: `${candidate.storyKey}:bookmark:${candidate.bookmarkId}:content-range`,
3732
+ kind: "bookmark-content-range",
3733
+ storyKey: candidate.storyKey,
3734
+ blockPath: `${candidate.storyKey}/bookmark[${candidate.bookmarkId}]`,
3735
+ leafPath: `${candidate.storyKey}/bookmark[${candidate.bookmarkId}]/content-range`,
3736
+ commandFamily: "link-bookmark",
3737
+ editability: "non-editable",
3738
+ ...candidate.startSourceRef !== void 0 ? { sourceRef: candidate.startSourceRef } : {},
3739
+ link: {
3740
+ bookmarkId: candidate.bookmarkId,
3741
+ ...candidate.bookmarkName !== void 0 ? { bookmarkName: candidate.bookmarkName } : {},
3742
+ rangeKey
3743
+ },
3744
+ canonicalAddress: createCanonicalAddress({
3745
+ addressKind: "bookmark-content-range",
3746
+ storyKey: candidate.storyKey,
3747
+ staleCheckKind: "bookmark",
3748
+ operationScope: "bookmark-range",
3749
+ sourceRefs: [candidate.startSourceRef, candidate.endSourceRef],
3750
+ staleHash: targetHash,
3751
+ rangeBoundary: {
3752
+ boundaryKind: "bookmark-content",
3753
+ ...startSourceJoinHash !== void 0 ? { startSourceJoinHash } : {},
3754
+ ...endSourceJoinHash !== void 0 ? { endSourceJoinHash } : {}
3755
+ },
3756
+ discriminator: {
3757
+ bookmarkId: candidate.bookmarkId,
3758
+ bookmarkName: candidate.bookmarkName ?? null,
3759
+ startSourceId: candidate.startSourceRef?.sourceId ?? null,
3760
+ endSourceId: candidate.endSourceRef?.sourceId ?? null
3761
+ }
3762
+ }),
3763
+ staleCheck: {
3764
+ blockType: "bookmark",
3765
+ targetHash,
3766
+ childCount: 2,
3767
+ ...candidate.startSourceRef !== void 0 ? { sourceRef: candidate.startSourceRef } : {}
3768
+ },
3769
+ posture: { blockers: ["unmodeled-target"] }
3770
+ };
3771
+ }
3198
3772
  function inlineObjectKind(inline) {
3199
3773
  switch (inline.type) {
3200
3774
  case "chart_preview":
@@ -3317,6 +3891,16 @@ function collectParagraphText(paragraph) {
3317
3891
  }
3318
3892
  return text;
3319
3893
  }
3894
+ function blockTextForTargetHash(block) {
3895
+ if (block.type === "paragraph") return collectParagraphText(block);
3896
+ if (block.type === "sdt" || block.type === "custom_xml") {
3897
+ return block.children.map(blockTextForTargetHash).join("");
3898
+ }
3899
+ if (block.type === "table") {
3900
+ return block.rows.flatMap((row) => row.cells).flatMap((cell) => cell.children).map(blockTextForTargetHash).join("");
3901
+ }
3902
+ return "";
3903
+ }
3320
3904
  function inlineTextForTargetHash(inline) {
3321
3905
  if (inline.type === "text") return inline.text;
3322
3906
  if (inline.type === "symbol") return inline.char;
@@ -3332,6 +3916,225 @@ function inlineTextForTargetHash(inline) {
3332
3916
  }
3333
3917
  return "";
3334
3918
  }
3919
+ function createTableTargetCanonicalAddress(table, staleCheckKind, staleHash, resolver = {}) {
3920
+ return createCanonicalAddress({
3921
+ addressKind: "table-target",
3922
+ storyKey: tableStoryKey(table),
3923
+ staleCheckKind,
3924
+ operationScope: table.operationScope,
3925
+ rowRange: table.fragment?.rowRange,
3926
+ columnRange: table.fragment?.columnRange,
3927
+ sourceRefs: [table.sourceRef, table.rowSourceRef, table.cellSourceRef],
3928
+ staleHash,
3929
+ ...resolver,
3930
+ discriminator: {
3931
+ operationScope: table.operationScope,
3932
+ tableDepth: table.tableDepth,
3933
+ rowIndex: table.rowIndex ?? null,
3934
+ columnIndex: table.columnIndex ?? null,
3935
+ cellIndex: table.cellIndex ?? null,
3936
+ gridColumnStart: table.gridColumnStart ?? null,
3937
+ gridSpan: table.gridSpan ?? null,
3938
+ verticalMerge: table.verticalMerge ?? null,
3939
+ sourceId: table.sourceRef?.sourceId ?? null,
3940
+ rowSourceId: table.rowSourceRef?.sourceId ?? null,
3941
+ cellSourceId: table.cellSourceRef?.sourceId ?? null
3942
+ },
3943
+ secondaryStory: table.secondaryStory,
3944
+ nestedTable: table.nestedTable,
3945
+ insideSdt: table.insideSdt
3946
+ });
3947
+ }
3948
+ function tableStoryKey(table) {
3949
+ const suffix = `:${table.tablePath}`;
3950
+ return table.tableKey.endsWith(suffix) ? table.tableKey.slice(0, -suffix.length) : MAIN_STORY_KEY;
3951
+ }
3952
+ function createCanonicalAddress(input) {
3953
+ const sourceHash = sourceJoinHash(input.sourceRefs ?? []);
3954
+ const payload = {
3955
+ addressKind: input.addressKind,
3956
+ storyKey: input.storyKey,
3957
+ operationScope: input.operationScope ?? null,
3958
+ rowRange: input.rowRange ?? null,
3959
+ columnRange: input.columnRange ?? null,
3960
+ sourceHash: sourceHash ?? null,
3961
+ discriminator: input.discriminator
3962
+ };
3963
+ return {
3964
+ addressKey: `editable-address:${hashText(JSON.stringify(payload))}`,
3965
+ addressKind: input.addressKind,
3966
+ storyKey: input.storyKey,
3967
+ staleCheckKind: input.staleCheckKind,
3968
+ ...input.operationScope !== void 0 ? { operationScope: input.operationScope } : {},
3969
+ ...input.rowRange !== void 0 ? { rowRange: input.rowRange } : {},
3970
+ ...input.columnRange !== void 0 ? { columnRange: input.columnRange } : {},
3971
+ ...sourceHash !== void 0 ? { sourceJoinHash: sourceHash } : {},
3972
+ ...input.secondaryStory === true ? { secondaryStory: true } : {},
3973
+ ...input.nestedTable === true ? { nestedTable: true } : {},
3974
+ ...input.insideSdt === true ? { insideSdt: true } : {},
3975
+ resolver: {
3976
+ staleHash: input.staleHash,
3977
+ ...sourceHash !== void 0 ? { sourceJoinHash: sourceHash } : {},
3978
+ ...input.rowRange !== void 0 ? { rowRange: input.rowRange } : {},
3979
+ ...input.columnRange !== void 0 ? { columnRange: input.columnRange } : {},
3980
+ ...input.rangeBoundary !== void 0 ? { rangeBoundary: input.rangeBoundary } : {},
3981
+ ...input.owner !== void 0 ? { owner: input.owner } : {}
3982
+ }
3983
+ };
3984
+ }
3985
+ function ownerRoutingFromAddress(address) {
3986
+ return {
3987
+ addressKey: address.addressKey,
3988
+ addressKind: address.addressKind,
3989
+ storyKey: address.storyKey,
3990
+ ...address.operationScope !== void 0 ? { operationScope: address.operationScope } : {},
3991
+ ...address.sourceJoinHash !== void 0 ? { sourceJoinHash: address.sourceJoinHash } : {},
3992
+ staleHash: address.resolver?.staleHash ?? "",
3993
+ ...address.rowRange !== void 0 ? { rowRange: address.rowRange } : {},
3994
+ ...address.columnRange !== void 0 ? { columnRange: address.columnRange } : {}
3995
+ };
3996
+ }
3997
+ function sourceJoinHashForRefs(...refs) {
3998
+ const sourceHash = sourceJoinHash(refs);
3999
+ return sourceHash === void 0 ? {} : { sourceJoinHash: sourceHash };
4000
+ }
4001
+ function sourceJoinHash(refs) {
4002
+ const sourceIds = refs.map((ref) => ref?.sourceId).filter((sourceId) => sourceId !== void 0);
4003
+ if (sourceIds.length === 0) return void 0;
4004
+ return hashText(sourceIds.join("\0"));
4005
+ }
4006
+ function collectCanonicalStoryIdentities(doc) {
4007
+ const stories = [
4008
+ {
4009
+ storyKey: MAIN_STORY_KEY,
4010
+ kind: "main",
4011
+ blockCount: doc.content.children.length
4012
+ }
4013
+ ];
4014
+ const sectionCount = countSections(doc);
4015
+ for (const header of doc.subParts?.headers ?? []) {
4016
+ const bindings = collectHeaderFooterBindings(
4017
+ doc,
4018
+ "header",
4019
+ header.relationshipId,
4020
+ header.variant,
4021
+ header.sectionIndex,
4022
+ sectionCount
4023
+ );
4024
+ stories.push({
4025
+ storyKey: createHeaderFooterStoryKey({
4026
+ kind: "header",
4027
+ relationshipId: header.relationshipId,
4028
+ variant: header.variant,
4029
+ ...header.sectionIndex !== void 0 ? { sectionIndex: header.sectionIndex } : {}
4030
+ }),
4031
+ kind: "header",
4032
+ blockCount: header.blocks.length,
4033
+ variant: header.variant,
4034
+ relationshipId: header.relationshipId,
4035
+ partPath: header.partPath,
4036
+ ...header.sectionIndex !== void 0 ? { sectionIndex: header.sectionIndex } : {},
4037
+ boundSectionIndexes: bindings.boundSectionIndexes,
4038
+ explicitSectionIndexes: bindings.explicitSectionIndexes,
4039
+ inheritedSectionIndexes: bindings.inheritedSectionIndexes
4040
+ });
4041
+ }
4042
+ for (const footer of doc.subParts?.footers ?? []) {
4043
+ const bindings = collectHeaderFooterBindings(
4044
+ doc,
4045
+ "footer",
4046
+ footer.relationshipId,
4047
+ footer.variant,
4048
+ footer.sectionIndex,
4049
+ sectionCount
4050
+ );
4051
+ stories.push({
4052
+ storyKey: createHeaderFooterStoryKey({
4053
+ kind: "footer",
4054
+ relationshipId: footer.relationshipId,
4055
+ variant: footer.variant,
4056
+ ...footer.sectionIndex !== void 0 ? { sectionIndex: footer.sectionIndex } : {}
4057
+ }),
4058
+ kind: "footer",
4059
+ blockCount: footer.blocks.length,
4060
+ variant: footer.variant,
4061
+ relationshipId: footer.relationshipId,
4062
+ partPath: footer.partPath,
4063
+ ...footer.sectionIndex !== void 0 ? { sectionIndex: footer.sectionIndex } : {},
4064
+ boundSectionIndexes: bindings.boundSectionIndexes,
4065
+ explicitSectionIndexes: bindings.explicitSectionIndexes,
4066
+ inheritedSectionIndexes: bindings.inheritedSectionIndexes
4067
+ });
4068
+ }
4069
+ const notes = doc.subParts?.footnoteCollection;
4070
+ if (notes) {
4071
+ for (const note of Object.values(notes.footnotes)) {
4072
+ stories.push({
4073
+ storyKey: createNoteStoryKey("footnote", note.noteId),
4074
+ kind: "footnote",
4075
+ noteId: note.noteId,
4076
+ blockCount: note.blocks.length
4077
+ });
4078
+ }
4079
+ for (const note of Object.values(notes.endnotes)) {
4080
+ stories.push({
4081
+ storyKey: createNoteStoryKey("endnote", note.noteId),
4082
+ kind: "endnote",
4083
+ noteId: note.noteId,
4084
+ blockCount: note.blocks.length
4085
+ });
4086
+ }
4087
+ }
4088
+ return stories;
4089
+ }
4090
+ function collectCanonicalNumberingLayoutInputs(doc, contexts = collectStoryBlockContexts(doc)) {
4091
+ const inputs = [];
4092
+ for (const context of contexts) {
4093
+ walkBlocks(context.blocks, context.storyKey, context.basePath, {
4094
+ paragraph(paragraph, blockPath) {
4095
+ const styleNumbering = paragraph.numbering === void 0 && paragraph.styleId !== void 0 ? resolveParagraphStyleNumbering(doc, paragraph.styleId) : void 0;
4096
+ const numbering = paragraph.numbering ?? styleNumbering;
4097
+ if (numbering === void 0) {
4098
+ return;
4099
+ }
4100
+ const instance = doc.numbering.instances[numbering.numberingInstanceId];
4101
+ const abstractDefinition = instance?.abstractNumberingId === void 0 ? void 0 : doc.numbering.abstractDefinitions[instance.abstractNumberingId];
4102
+ inputs.push({
4103
+ numberingKey: `${context.storyKey}:${blockPath}:numbering`,
4104
+ storyKey: context.storyKey,
4105
+ blockPath,
4106
+ paragraphIndex: blockIndexFromPath(blockPath),
4107
+ ...paragraph.sourceRef !== void 0 ? { sourceRef: paragraph.sourceRef } : {},
4108
+ ...paragraph.numbering?.sourceRef !== void 0 ? { numberingSourceRef: paragraph.numbering.sourceRef } : {},
4109
+ numberingOrigin: paragraph.numbering === void 0 ? "paragraph-style" : "paragraph",
4110
+ ...paragraph.numbering === void 0 && paragraph.styleId !== void 0 ? { paragraphStyleId: paragraph.styleId } : {},
4111
+ numberingInstanceId: numbering.numberingInstanceId,
4112
+ ...instance?.sourceRef !== void 0 ? { numberingInstanceSourceRef: instance.sourceRef } : {},
4113
+ ...instance?.abstractNumberingId !== void 0 ? { abstractNumberingId: instance.abstractNumberingId } : {},
4114
+ ...abstractDefinition?.sourceRef !== void 0 ? { abstractNumberingSourceRef: abstractDefinition.sourceRef } : {},
4115
+ level: numbering.level ?? 0
4116
+ });
4117
+ }
4118
+ });
4119
+ }
4120
+ return inputs;
4121
+ }
4122
+ function resolveParagraphStyleNumbering(doc, styleId) {
4123
+ const visited = /* @__PURE__ */ new Set();
4124
+ let currentStyleId = styleId;
4125
+ while (currentStyleId !== void 0 && !visited.has(currentStyleId)) {
4126
+ visited.add(currentStyleId);
4127
+ const style = doc.styles.paragraphs[currentStyleId];
4128
+ if (style === void 0) {
4129
+ return void 0;
4130
+ }
4131
+ if (style.numbering !== void 0) {
4132
+ return style.numbering;
4133
+ }
4134
+ currentStyleId = style.basedOn;
4135
+ }
4136
+ return void 0;
4137
+ }
3335
4138
  function collectCanonicalFieldRegionIdentities(doc) {
3336
4139
  const registry = doc.fieldRegistry;
3337
4140
  const byFieldIndex = new Map(
@@ -3457,6 +4260,42 @@ function blockIndexFromPath(blockPath) {
3457
4260
  const last = matches.at(-1);
3458
4261
  return last ? Number.parseInt(last[1], 10) : 0;
3459
4262
  }
4263
+ function collectCanonicalTableLayoutInputs(contexts) {
4264
+ const tables = [];
4265
+ for (const context of contexts) {
4266
+ walkBlocks(context.blocks, context.storyKey, context.basePath, {
4267
+ table(table, blockPath) {
4268
+ tables.push(projectTableLayoutInput(table, context.storyKey, blockPath));
4269
+ }
4270
+ });
4271
+ }
4272
+ return tables;
4273
+ }
4274
+ function collectCanonicalAnchorLayoutInputs(doc, contexts = collectStoryBlockContexts(doc)) {
4275
+ const anchors = [];
4276
+ for (const context of contexts) {
4277
+ walkBlocks(context.blocks, context.storyKey, context.basePath, {
4278
+ inline(inline, blockPath, inlinePath) {
4279
+ const anchor = projectAnchorLayoutInput(
4280
+ doc,
4281
+ inline,
4282
+ context.storyKey,
4283
+ blockPath,
4284
+ inlinePath
4285
+ );
4286
+ if (anchor) anchors.push(anchor);
4287
+ }
4288
+ });
4289
+ }
4290
+ return anchors;
4291
+ }
4292
+ function collectCanonicalScopeLayoutInputs(contexts) {
4293
+ const scopes = [];
4294
+ for (const context of contexts) {
4295
+ scopes.push(...collectScopeLayoutInputsForStory(context));
4296
+ }
4297
+ return scopes.sort((left, right) => left.scopeKey.localeCompare(right.scopeKey));
4298
+ }
3460
4299
  function collectStoryBlockContexts(doc) {
3461
4300
  const contexts = [
3462
4301
  { storyKey: MAIN_STORY_KEY, blocks: doc.content.children, basePath: "main" }
@@ -3529,7 +4368,7 @@ function walkBlocks(blocks, storyKey, basePath, visitor) {
3529
4368
  }
3530
4369
  if (block.type === "paragraph") {
3531
4370
  visitor.paragraph?.(block, blockPath);
3532
- walkInlines(block.children, storyKey, blockPath, `${blockPath}/inline`, visitor);
4371
+ walkInlines(block.children ?? [], storyKey, blockPath, `${blockPath}/inline`, visitor);
3533
4372
  continue;
3534
4373
  }
3535
4374
  if (block.type === "sdt" || block.type === "custom_xml") {
@@ -3556,6 +4395,393 @@ function walkInlines(inlines, storyKey, blockPath, basePath, visitor) {
3556
4395
  }
3557
4396
  }
3558
4397
  }
4398
+ function projectTableLayoutInput(table, storyKey, blockPath) {
4399
+ const tableKey = `${storyKey}:${blockPath}`;
4400
+ const rows = table.rows.map(
4401
+ (row, rowIndex) => projectTableRowLayoutInput(row, tableKey, rowIndex)
4402
+ );
4403
+ return {
4404
+ tableKey,
4405
+ storyKey,
4406
+ blockPath,
4407
+ ...table.sourceRef !== void 0 ? { sourceRef: table.sourceRef } : {},
4408
+ ...table.styleId !== void 0 ? { styleId: table.styleId } : {},
4409
+ rowCount: table.rows.length,
4410
+ columnCount: table.gridColumns.length,
4411
+ gridColumns: [...table.gridColumns],
4412
+ ...table.width !== void 0 ? { width: table.width } : {},
4413
+ ...table.alignment !== void 0 ? { alignment: table.alignment } : {},
4414
+ ...table.borders !== void 0 ? { borders: table.borders } : {},
4415
+ ...table.cellMargins !== void 0 ? { cellMargins: table.cellMargins } : {},
4416
+ ...table.tblLook !== void 0 ? { tblLook: table.tblLook } : {},
4417
+ ...table.indent !== void 0 ? { indent: table.indent } : {},
4418
+ ...table.layoutMode !== void 0 ? { layoutMode: table.layoutMode } : {},
4419
+ ...table.cellSpacing !== void 0 ? { cellSpacing: table.cellSpacing } : {},
4420
+ ...table.bidiVisual !== void 0 ? { bidiVisual: table.bidiVisual } : {},
4421
+ ...table.floating !== void 0 ? { floating: table.floating } : {},
4422
+ rows
4423
+ };
4424
+ }
4425
+ function projectTableRowLayoutInput(row, tableKey, rowIndex) {
4426
+ const rowKey = `${tableKey}:row[${rowIndex}]`;
4427
+ let gridColumn = row.gridBefore ?? 0;
4428
+ const cells = row.cells.map((cell, cellIndex) => {
4429
+ const input = projectTableCellLayoutInput(cell, rowKey, rowIndex, cellIndex, gridColumn);
4430
+ gridColumn += input.gridSpan;
4431
+ return input;
4432
+ });
4433
+ return {
4434
+ rowKey,
4435
+ ...row.sourceRef !== void 0 ? { sourceRef: row.sourceRef } : {},
4436
+ rowIndex,
4437
+ cellCount: row.cells.length,
4438
+ ...row.gridBefore !== void 0 ? { gridBefore: row.gridBefore } : {},
4439
+ ...row.widthBefore !== void 0 ? { widthBefore: row.widthBefore } : {},
4440
+ ...row.gridAfter !== void 0 ? { gridAfter: row.gridAfter } : {},
4441
+ ...row.widthAfter !== void 0 ? { widthAfter: row.widthAfter } : {},
4442
+ ...row.height !== void 0 ? { height: row.height } : {},
4443
+ ...row.heightRule !== void 0 ? { heightRule: row.heightRule } : {},
4444
+ ...row.isHeader !== void 0 ? { isHeader: row.isHeader } : {},
4445
+ ...row.cantSplit !== void 0 ? { cantSplit: row.cantSplit } : {},
4446
+ ...row.horizontalAlignment !== void 0 ? { horizontalAlignment: row.horizontalAlignment } : {},
4447
+ ...row.cnfStyle !== void 0 ? { cnfStyle: row.cnfStyle } : {},
4448
+ cells
4449
+ };
4450
+ }
4451
+ function projectTableCellLayoutInput(cell, rowKey, rowIndex, cellIndex, gridColumnStart) {
4452
+ const gridSpan = cell.gridSpan ?? 1;
4453
+ return {
4454
+ cellKey: `${rowKey}:cell[${cellIndex}]`,
4455
+ ...cell.sourceRef !== void 0 ? { sourceRef: cell.sourceRef } : {},
4456
+ rowIndex,
4457
+ cellIndex,
4458
+ gridColumnStart,
4459
+ gridSpan,
4460
+ ...cell.verticalMerge !== void 0 ? { verticalMerge: cell.verticalMerge } : {},
4461
+ ...cell.width !== void 0 ? { width: cell.width } : {},
4462
+ ...cell.borders !== void 0 ? { borders: cell.borders } : {},
4463
+ ...cell.shading !== void 0 ? { shading: cell.shading } : {},
4464
+ ...cell.verticalAlign !== void 0 ? { verticalAlign: cell.verticalAlign } : {},
4465
+ ...cell.textDirection !== void 0 ? { textDirection: cell.textDirection } : {},
4466
+ ...cell.noWrap !== void 0 ? { noWrap: cell.noWrap } : {},
4467
+ ...cell.fitText !== void 0 ? { fitText: cell.fitText } : {},
4468
+ ...cell.margins !== void 0 ? { margins: cell.margins } : {},
4469
+ ...cell.cnfStyle !== void 0 ? { cnfStyle: cell.cnfStyle } : {},
4470
+ blockCount: cell.children.length
4471
+ };
4472
+ }
4473
+ function projectAnchorLayoutInput(doc, inline, storyKey, blockPath, inlinePath) {
4474
+ if (inline.type === "drawing_frame") {
4475
+ return projectDrawingFrameAnchor(inline, storyKey, blockPath, inlinePath);
4476
+ }
4477
+ if (inline.type === "image") {
4478
+ return projectLegacyImageAnchor(doc, inline, storyKey, blockPath, inlinePath);
4479
+ }
4480
+ return null;
4481
+ }
4482
+ function projectDrawingFrameAnchor(node, storyKey, blockPath, inlinePath) {
4483
+ const anchor = node.anchor;
4484
+ const content = node.content;
4485
+ const shapeBlocks = content.type === "shape" ? content.txbxBlocks : void 0;
4486
+ const objectKind = drawingContentKind(content);
4487
+ const sourceRef = node.sourceRef ?? drawingContentSourceRef(content);
4488
+ const objectKey = `${storyKey}:${inlinePath}`;
4489
+ const textBoxBody = projectTextBoxBodyLayoutInput(content, objectKey, sourceRef, `${inlinePath}/txbx`);
4490
+ return {
4491
+ objectKey,
4492
+ storyKey,
4493
+ blockPath,
4494
+ inlinePath,
4495
+ ...sourceRef !== void 0 ? { sourceRef } : {},
4496
+ objectKind,
4497
+ editPosture: drawingEditPosture(node),
4498
+ display: anchor.display,
4499
+ extent: anchor.extent,
4500
+ wrapMode: anchor.wrapMode,
4501
+ ...anchor.wrapPolygon !== void 0 ? { wrapPolygonPointCount: anchor.wrapPolygon.length } : {},
4502
+ ...anchor.positionH !== void 0 ? { positionH: anchor.positionH } : {},
4503
+ ...anchor.positionV !== void 0 ? { positionV: anchor.positionV } : {},
4504
+ ...anchor.distMargins !== void 0 ? { distMargins: anchor.distMargins } : {},
4505
+ ...anchor.relativeHeight !== void 0 ? { relativeHeight: anchor.relativeHeight } : {},
4506
+ ...anchor.behindDoc !== void 0 ? { zOrder: anchor.behindDoc ? "behind-document" : "in-front-of-text" } : {},
4507
+ ...anchor.layoutInCell !== void 0 ? { layoutInCell: anchor.layoutInCell } : {},
4508
+ ...anchor.allowOverlap !== void 0 ? { allowOverlap: anchor.allowOverlap } : {},
4509
+ ...anchor.simplePos !== void 0 ? { simplePos: anchor.simplePos } : {},
4510
+ ...anchor.docPr?.id !== void 0 ? { docPrId: anchor.docPr.id } : {},
4511
+ ...anchor.docPr?.name !== void 0 ? { docPrName: anchor.docPr.name } : {},
4512
+ ...anchor.docPr?.descr !== void 0 ? { docPrDescription: anchor.docPr.descr } : {},
4513
+ ...anchor.docPr?.hidden !== void 0 ? { hidden: anchor.docPr.hidden } : {},
4514
+ ...anchor.frameLocks !== void 0 ? { frameLocks: anchor.frameLocks } : {},
4515
+ ...content.type === "picture" && content.mediaId !== void 0 ? { mediaId: content.mediaId } : {},
4516
+ ...content.type === "picture" && content.packagePartName !== void 0 ? { packagePartName: content.packagePartName } : {},
4517
+ ...content.type === "picture" ? { relationshipId: content.blipRef } : {},
4518
+ ...content.type === "picture" && content.isLinked !== void 0 ? { isLinked: content.isLinked } : {},
4519
+ ...shapeBlocks !== void 0 ? { hasTextBoxBlocks: true } : {},
4520
+ ...shapeBlocks !== void 0 ? { textBoxBlockCount: shapeBlocks.length } : {},
4521
+ ...textBoxBody !== void 0 ? { textBoxBody } : {},
4522
+ rawXmlPreserved: content.type !== "picture" || content.rawXml !== void 0
4523
+ };
4524
+ }
4525
+ function projectTextBoxBodyLayoutInput(content, objectKey, sourceRef, basePath) {
4526
+ if (content.type !== "shape") return void 0;
4527
+ if (!content.isTextBox && content.txbxContentXml === void 0 && content.txbxBlocks === void 0) {
4528
+ return void 0;
4529
+ }
4530
+ const bodyKey = `${objectKey}:txbx`;
4531
+ const blockCount = content.txbxBlocks?.length ?? 0;
4532
+ if (content.txbxBlocks === void 0) {
4533
+ return {
4534
+ bodyKey,
4535
+ ...sourceRef !== void 0 ? { sourceRef } : {},
4536
+ status: content.txbxContentXml !== void 0 ? "preserve-only" : "unavailable",
4537
+ unavailableReason: "txbx-blocks-unavailable",
4538
+ ...content.textBoxBody !== void 0 ? { bodyProperties: content.textBoxBody } : {},
4539
+ blockCount,
4540
+ paragraphCount: 0,
4541
+ unsupportedBlockCount: 0,
4542
+ paragraphs: []
4543
+ };
4544
+ }
4545
+ const paragraphs = content.txbxBlocks.flatMap(
4546
+ (block, index) => block.type === "paragraph" ? [projectTextBoxParagraphLayoutInput(block, bodyKey, `${basePath}/block[${index}]`, index)] : []
4547
+ );
4548
+ const unsupportedBlockCount = content.txbxBlocks.length - paragraphs.length;
4549
+ const unavailableReason = content.txbxBlocks.length === 0 ? "empty-body" : paragraphs.length === 0 ? "unsupported-content" : void 0;
4550
+ return {
4551
+ bodyKey,
4552
+ ...sourceRef !== void 0 ? { sourceRef } : {},
4553
+ status: unavailableReason === void 0 ? "modeled" : "unavailable",
4554
+ ...unavailableReason !== void 0 ? { unavailableReason } : {},
4555
+ ...content.textBoxBody !== void 0 ? { bodyProperties: content.textBoxBody } : {},
4556
+ blockCount,
4557
+ paragraphCount: paragraphs.length,
4558
+ unsupportedBlockCount,
4559
+ paragraphs
4560
+ };
4561
+ }
4562
+ function projectTextBoxParagraphLayoutInput(paragraph, bodyKey, blockPath, blockIndex) {
4563
+ const runs = paragraph.children.map(
4564
+ (inline, inlineIndex) => projectTextBoxRunLayoutInput(inline, `${bodyKey}:block[${blockIndex}]`, inlineIndex)
4565
+ );
4566
+ const text = runs.map((run) => run.text ?? "").join("");
4567
+ return {
4568
+ paragraphKey: `${bodyKey}:block[${blockIndex}]`,
4569
+ blockPath,
4570
+ blockIndex,
4571
+ ...paragraph.sourceRef !== void 0 ? { sourceRef: paragraph.sourceRef } : {},
4572
+ ...paragraph.styleId !== void 0 ? { styleId: paragraph.styleId } : {},
4573
+ ...paragraph.alignment !== void 0 ? { alignment: paragraph.alignment } : {},
4574
+ ...paragraph.borders !== void 0 ? { borders: paragraph.borders } : {},
4575
+ text,
4576
+ textLength: Array.from(text).length,
4577
+ runCount: runs.length,
4578
+ runs
4579
+ };
4580
+ }
4581
+ function projectTextBoxRunLayoutInput(inline, paragraphKey, inlineIndex) {
4582
+ const runKey = `${paragraphKey}:inline[${inlineIndex}]`;
4583
+ if (inline.type === "text") {
4584
+ return {
4585
+ runKey,
4586
+ inlineIndex,
4587
+ kind: "text",
4588
+ text: inline.text,
4589
+ textLength: Array.from(inline.text).length,
4590
+ ...inline.marks !== void 0 ? { marks: inline.marks } : {}
4591
+ };
4592
+ }
4593
+ if (inline.type === "tab") {
4594
+ return { runKey, inlineIndex, kind: "tab", text: " ", textLength: 1 };
4595
+ }
4596
+ if (inline.type === "hard_break") {
4597
+ return { runKey, inlineIndex, kind: "hard-break", text: "\n", textLength: 1 };
4598
+ }
4599
+ if (inline.type === "symbol") {
4600
+ return {
4601
+ runKey,
4602
+ inlineIndex,
4603
+ kind: "symbol",
4604
+ text: inline.char,
4605
+ textLength: Array.from(inline.char).length
4606
+ };
4607
+ }
4608
+ return { runKey, inlineIndex, kind: "unsupported" };
4609
+ }
4610
+ function projectLegacyImageAnchor(doc, node, storyKey, blockPath, inlinePath) {
4611
+ const media = doc.media.items[node.mediaId];
4612
+ return {
4613
+ objectKey: `${storyKey}:${inlinePath}`,
4614
+ storyKey,
4615
+ blockPath,
4616
+ inlinePath,
4617
+ objectKind: "legacy-image",
4618
+ editPosture: "editable",
4619
+ ...node.display !== void 0 ? { display: node.display } : {},
4620
+ ...media?.widthEmu !== void 0 && media.heightEmu !== void 0 ? { extent: { widthEmu: media.widthEmu, heightEmu: media.heightEmu } } : {},
4621
+ ...node.floating?.wrap !== void 0 ? { wrapMode: node.floating.wrap } : {},
4622
+ ...node.floating?.horizontalPosition !== void 0 ? { positionH: normalizeFloatingAxis(node.floating.horizontalPosition) } : {},
4623
+ ...node.floating?.verticalPosition !== void 0 ? { positionV: normalizeFloatingAxis(node.floating.verticalPosition) } : {},
4624
+ ...node.floating?.behindDoc !== void 0 ? { zOrder: node.floating.behindDoc ? "behind-document" : "in-front-of-text" } : {},
4625
+ ...node.floating?.layoutInCell !== void 0 ? { layoutInCell: node.floating.layoutInCell } : {},
4626
+ ...node.floating?.allowOverlap !== void 0 ? { allowOverlap: node.floating.allowOverlap } : {},
4627
+ mediaId: node.mediaId,
4628
+ ...node.sourceRef !== void 0 ? { sourceRef: node.sourceRef } : {},
4629
+ ...media?.packagePartName !== void 0 ? { packagePartName: media.packagePartName } : {},
4630
+ ...media?.relationshipId !== void 0 ? { relationshipId: media.relationshipId } : {},
4631
+ ...node.placementXml !== void 0 ? { rawXmlPreserved: true } : {}
4632
+ };
4633
+ }
4634
+ function preserveOnlySourceRef(sourceId) {
4635
+ return sourceId === void 0 ? void 0 : { sourceId };
4636
+ }
4637
+ function drawingContentSourceRef(content) {
4638
+ if ("preserveOnlyObject" in content) {
4639
+ return preserveOnlySourceRef(content.preserveOnlyObject?.sourceId);
4640
+ }
4641
+ return void 0;
4642
+ }
4643
+ function normalizeFloatingAxis(axis) {
4644
+ return {
4645
+ relativeFrom: axis?.relativeFrom ?? "",
4646
+ ...axis?.align !== void 0 ? { align: axis.align } : {},
4647
+ ...axis?.offset !== void 0 ? { offset: axis.offset } : {}
4648
+ };
4649
+ }
4650
+ function drawingContentKind(content) {
4651
+ if (content.type === "picture") return "picture";
4652
+ if (content.type === "shape") {
4653
+ return content.isTextBox || content.txbxBlocks || content.txbxContentXml ? "textbox" : "shape";
4654
+ }
4655
+ if (content.type === "chart_preview") return "chart";
4656
+ if (content.type === "smartart_preview") return "smartart";
4657
+ return "opaque";
4658
+ }
4659
+ function drawingEditPosture(node) {
4660
+ if (node.content.type === "picture" && !node.content.isLinked) return "editable";
4661
+ if (node.content.type === "opaque") return "preserve-only";
4662
+ return "read-only-preview";
4663
+ }
4664
+ function collectScopeLayoutInputsForStory(context) {
4665
+ const occurrences = [];
4666
+ walkBlocks(context.blocks, context.storyKey, context.basePath, {
4667
+ inline(inline, blockPath, inlinePath) {
4668
+ if (inline.type !== "scope_marker_start" && inline.type !== "scope_marker_end") {
4669
+ return;
4670
+ }
4671
+ occurrences.push({
4672
+ scopeId: inline.scopeId,
4673
+ markerType: inline.type === "scope_marker_start" ? "start" : "end",
4674
+ markerIndex: occurrences.length,
4675
+ blockPath,
4676
+ inlinePath
4677
+ });
4678
+ }
4679
+ });
4680
+ const open = /* @__PURE__ */ new Map();
4681
+ const scopes = [];
4682
+ for (const marker of occurrences) {
4683
+ if (marker.markerType === "start") {
4684
+ const stack2 = open.get(marker.scopeId) ?? [];
4685
+ stack2.push(marker);
4686
+ open.set(marker.scopeId, stack2);
4687
+ continue;
4688
+ }
4689
+ const stack = open.get(marker.scopeId);
4690
+ const opener = stack?.pop();
4691
+ if (stack && stack.length === 0) {
4692
+ open.delete(marker.scopeId);
4693
+ }
4694
+ if (opener) {
4695
+ scopes.push(createScopeLayoutInput(context.storyKey, "paired", opener, marker));
4696
+ continue;
4697
+ }
4698
+ scopes.push(createScopeLayoutInput(context.storyKey, "end-only", void 0, marker));
4699
+ }
4700
+ for (const stack of open.values()) {
4701
+ for (const opener of stack) {
4702
+ scopes.push(createScopeLayoutInput(context.storyKey, "start-only", opener, void 0));
4703
+ }
4704
+ }
4705
+ return scopes.sort(
4706
+ (left, right) => (left.start?.markerIndex ?? left.end?.markerIndex ?? Number.MAX_SAFE_INTEGER) - (right.start?.markerIndex ?? right.end?.markerIndex ?? Number.MAX_SAFE_INTEGER) || left.scopeId.localeCompare(right.scopeId)
4707
+ );
4708
+ }
4709
+ function createScopeLayoutInput(storyKey, status, start, end) {
4710
+ const scopeId = start?.scopeId ?? end?.scopeId ?? "";
4711
+ const keyIndex = start?.markerIndex ?? end?.markerIndex ?? 0;
4712
+ return {
4713
+ scopeKey: `${storyKey}:scope:${scopeId}:${keyIndex}`,
4714
+ scopeId,
4715
+ storyKey,
4716
+ status,
4717
+ source: "canonical-marker",
4718
+ ...start !== void 0 ? { start: createScopeMarkerReference(storyKey, start) } : {},
4719
+ ...end !== void 0 ? { end: createScopeMarkerReference(storyKey, end) } : {}
4720
+ };
4721
+ }
4722
+ function createScopeMarkerReference(storyKey, marker) {
4723
+ return {
4724
+ markerKey: `${storyKey}:scope-marker:${marker.scopeId}:${marker.markerIndex}`,
4725
+ blockPath: marker.blockPath,
4726
+ inlinePath: marker.inlinePath,
4727
+ markerIndex: marker.markerIndex
4728
+ };
4729
+ }
4730
+ function countSections(doc) {
4731
+ let explicitBreaks = 0;
4732
+ for (const block of doc.content.children) {
4733
+ if (block.type === "section_break") explicitBreaks += 1;
4734
+ }
4735
+ return explicitBreaks + 1;
4736
+ }
4737
+ function collectHeaderFooterBindings(doc, kind, relationshipId, variant, fallbackSectionIndex, sectionCount) {
4738
+ const bound = /* @__PURE__ */ new Set();
4739
+ const explicit = /* @__PURE__ */ new Set();
4740
+ const inherited = /* @__PURE__ */ new Set();
4741
+ const effectiveByVariant = /* @__PURE__ */ new Map();
4742
+ const sectionProperties = collectSectionProperties(doc);
4743
+ for (let sectionIndex = 0; sectionIndex < sectionCount; sectionIndex += 1) {
4744
+ const properties = sectionProperties[sectionIndex];
4745
+ const refs = getHeaderFooterReferences(properties, kind);
4746
+ const hasRequestedVariant = refs.some((ref) => ref.variant === variant);
4747
+ if (!hasRequestedVariant && effectiveByVariant.get(variant) === relationshipId) {
4748
+ inherited.add(sectionIndex);
4749
+ bound.add(sectionIndex);
4750
+ }
4751
+ if (refs.some(
4752
+ (ref) => ref.relationshipId === relationshipId && ref.variant === variant
4753
+ )) {
4754
+ explicit.add(sectionIndex);
4755
+ bound.add(sectionIndex);
4756
+ }
4757
+ for (const ref of refs) {
4758
+ effectiveByVariant.set(ref.variant, ref.relationshipId);
4759
+ }
4760
+ }
4761
+ if (fallbackSectionIndex !== void 0) {
4762
+ bound.add(fallbackSectionIndex);
4763
+ } else if (bound.size === 0) {
4764
+ for (let sectionIndex = 0; sectionIndex < sectionCount; sectionIndex += 1) {
4765
+ bound.add(sectionIndex);
4766
+ }
4767
+ }
4768
+ return {
4769
+ boundSectionIndexes: sortIndexes(bound),
4770
+ explicitSectionIndexes: sortIndexes(explicit),
4771
+ inheritedSectionIndexes: sortIndexes(inherited)
4772
+ };
4773
+ }
4774
+ function collectSectionProperties(doc) {
4775
+ const sectionProperties = doc.content.children.filter((block) => block.type === "section_break").map((block) => block.sectionProperties);
4776
+ sectionProperties.push(doc.subParts?.finalSectionProperties);
4777
+ return sectionProperties;
4778
+ }
4779
+ function getHeaderFooterReferences(properties, kind) {
4780
+ return (kind === "header" ? properties?.headerReferences : properties?.footerReferences) ?? [];
4781
+ }
4782
+ function sortIndexes(indexes) {
4783
+ return [...indexes].sort((left, right) => left - right);
4784
+ }
3559
4785
 
3560
4786
  // src/preservation/store.ts
3561
4787
  var BLOCKED_IMPORT_FEATURE_KEYS = /* @__PURE__ */ new Set([
@@ -5979,7 +7205,7 @@ function createEditorSurfaceSnapshot(document2, _selection, activeStory = { kind
5979
7205
  ...options.getEffectiveMarkupMode ? { getEffectiveMarkupMode: options.getEffectiveMarkupMode } : {},
5980
7206
  ...options.authorColorPalette ? { authorColorPalette: options.authorColorPalette } : {}
5981
7207
  });
5982
- const editableTargetsByBlockPath = indexEditableTargetsByBlockPath(document2);
7208
+ const editableTargetsByBlockPath = options.editableTargetsByBlockPath ?? indexEditableTargetsByBlockPath(document2);
5983
7209
  const activeStoryBlockPathBase = getActiveStoryBlockPathBase(document2, activeStory);
5984
7210
  chartModelStore.beginBuildPass(document2);
5985
7211
  const unsupportedNumberingFormatsSeen = options.emitFormattingTelemetry ? /* @__PURE__ */ new Set() : null;
@@ -6260,6 +7486,7 @@ function createTableBlock(tableIndex, table, document2, cursor, counters, format
6260
7486
  from: cursor,
6261
7487
  to: innerCursor,
6262
7488
  styleId: table.styleId,
7489
+ ...table.sourceRef !== void 0 ? { sourceRef: table.sourceRef } : {},
6263
7490
  gridColumns: table.gridColumns,
6264
7491
  rows: []
6265
7492
  },
@@ -6329,6 +7556,7 @@ function createTableBlock(tableIndex, table, document2, cursor, counters, format
6329
7556
  resolvedTable.table?.cellMargins
6330
7557
  );
6331
7558
  cells.push({
7559
+ ...cell.sourceRef !== void 0 ? { sourceRef: cell.sourceRef } : {},
6332
7560
  gridSpan: cell.gridSpan ?? 1,
6333
7561
  verticalMerge: cell.verticalMerge ?? null,
6334
7562
  colspan: cell.gridSpan ?? 1,
@@ -6352,6 +7580,7 @@ function createTableBlock(tableIndex, table, document2, cursor, counters, format
6352
7580
  }
6353
7581
  const headerLike = row.isHeader === true || resolvedRow?.style.isHeader === true;
6354
7582
  rows.push({
7583
+ ...row.sourceRef !== void 0 ? { sourceRef: row.sourceRef } : {},
6355
7584
  cells,
6356
7585
  ...row.gridBefore !== void 0 ? { gridBefore: row.gridBefore } : {},
6357
7586
  ...row.gridAfter !== void 0 ? { gridAfter: row.gridAfter } : {},
@@ -6382,6 +7611,7 @@ function createTableBlock(tableIndex, table, document2, cursor, counters, format
6382
7611
  from: cursor,
6383
7612
  to: innerCursor,
6384
7613
  styleId: table.styleId,
7614
+ ...table.sourceRef !== void 0 ? { sourceRef: table.sourceRef } : {},
6385
7615
  gridColumns: table.gridColumns,
6386
7616
  ...gridColumnsRelative ? { gridColumnsRelative } : {},
6387
7617
  ...resolvedTable.table?.alignment ? { alignment: resolvedTable.table.alignment } : {},
@@ -6926,6 +8156,7 @@ function appendInlineSegments(paragraph, node, document2, start, promoteSecondar
6926
8156
  const anchor = surfaceAnchorFromGeometry(node.anchor);
6927
8157
  const txbxTextSegment = c.isTextBox ? extractTxbxFirstTextSegment(c.txbxBlocks) : void 0;
6928
8158
  const txbxText = txbxTextSegment?.text ?? (c.isTextBox ? c.text : void 0);
8159
+ const txbxBody = c.isTextBox ? surfaceTextBoxBodyFromShape(c, node.sourceRef) : void 0;
6929
8160
  const surfaceFill = c.fill;
6930
8161
  paragraph.segments.push({
6931
8162
  segmentId: `${paragraph.blockId}-segment-${paragraph.segments.length}`,
@@ -6942,6 +8173,7 @@ function appendInlineSegments(paragraph, node, document2, start, promoteSecondar
6942
8173
  ...c.textBoxBody ? { textBoxBody: c.textBoxBody } : {},
6943
8174
  ...c.preserveOnlyObject ? { preserveOnlyObject: surfacePreserveOnlyObject(c.preserveOnlyObject) } : {},
6944
8175
  ...txbxText ? { txbxText } : {},
8176
+ ...txbxBody ? { txbxBody } : {},
6945
8177
  ...txbxTextSegment?.marks && txbxTextSegment.marks.length > 0 ? { txbxMarks: txbxTextSegment.marks } : {},
6946
8178
  ...txbxTextSegment?.markAttrs ? { txbxMarkAttrs: txbxTextSegment.markAttrs } : {}
6947
8179
  });
@@ -7354,6 +8586,97 @@ function extractTxbxFirstTextSegment(blocks) {
7354
8586
  }
7355
8587
  return void 0;
7356
8588
  }
8589
+ function surfaceTextBoxBodyFromShape(shape, sourceRef) {
8590
+ if (!shape.isTextBox && shape.txbxContentXml === void 0 && shape.txbxBlocks === void 0) {
8591
+ return void 0;
8592
+ }
8593
+ if (shape.txbxBlocks === void 0) {
8594
+ return {
8595
+ ...sourceRef !== void 0 ? { sourceRef } : {},
8596
+ status: shape.txbxContentXml !== void 0 ? "preserve-only" : "unavailable",
8597
+ unavailableReason: "txbx-blocks-unavailable",
8598
+ ...shape.textBoxBody !== void 0 ? { bodyProperties: shape.textBoxBody } : {},
8599
+ blockCount: 0,
8600
+ paragraphCount: 0,
8601
+ unsupportedBlockCount: 0,
8602
+ paragraphs: []
8603
+ };
8604
+ }
8605
+ const paragraphs = shape.txbxBlocks.flatMap((block, blockIndex) => {
8606
+ if (block.type !== "paragraph") return [];
8607
+ const children = block.children;
8608
+ const legacyRuns = block.runs;
8609
+ const runs = children !== void 0 ? children.map(
8610
+ (inline, inlineIndex) => surfaceTextBoxRunFromInline(inline, inlineIndex)
8611
+ ) : legacyRuns?.map(
8612
+ (run, inlineIndex) => surfaceTextBoxRunFromLegacyRun(run, inlineIndex)
8613
+ ) ?? [];
8614
+ const text = runs.map((run) => run.text ?? "").join("");
8615
+ return [{
8616
+ ...block.sourceRef !== void 0 ? { sourceRef: block.sourceRef } : {},
8617
+ blockIndex,
8618
+ text,
8619
+ textLength: Array.from(text).length,
8620
+ ...block.borders !== void 0 ? { borders: block.borders } : {},
8621
+ runs
8622
+ }];
8623
+ });
8624
+ const unsupportedBlockCount = shape.txbxBlocks.length - paragraphs.length;
8625
+ const unavailableReason = shape.txbxBlocks.length === 0 ? "empty-body" : paragraphs.length === 0 ? "unsupported-content" : void 0;
8626
+ return {
8627
+ ...sourceRef !== void 0 ? { sourceRef } : {},
8628
+ status: unavailableReason === void 0 ? "modeled" : "unavailable",
8629
+ ...unavailableReason !== void 0 ? { unavailableReason } : {},
8630
+ ...shape.textBoxBody !== void 0 ? { bodyProperties: shape.textBoxBody } : {},
8631
+ blockCount: shape.txbxBlocks.length,
8632
+ paragraphCount: paragraphs.length,
8633
+ unsupportedBlockCount,
8634
+ paragraphs
8635
+ };
8636
+ }
8637
+ function surfaceTextBoxRunFromLegacyRun(run, inlineIndex) {
8638
+ const text = run.text ?? "";
8639
+ const cloned = run.marks ? cloneMarks2(run.marks) : void 0;
8640
+ return {
8641
+ inlineIndex,
8642
+ kind: "text",
8643
+ text,
8644
+ textLength: Array.from(text).length,
8645
+ ...cloned?.marks && cloned.marks.length > 0 ? { marks: cloned.marks } : {},
8646
+ ...cloned?.markAttrs ? { markAttrs: cloned.markAttrs } : {}
8647
+ };
8648
+ }
8649
+ function surfaceTextBoxRunFromInline(inline, inlineIndex) {
8650
+ if (inline.type === "text") {
8651
+ const cloned = inline.marks ? cloneMarks2(inline.marks) : void 0;
8652
+ return {
8653
+ inlineIndex,
8654
+ kind: "text",
8655
+ text: inline.text,
8656
+ textLength: Array.from(inline.text).length,
8657
+ ...cloned?.marks && cloned.marks.length > 0 ? { marks: cloned.marks } : {},
8658
+ ...cloned?.markAttrs ? { markAttrs: cloned.markAttrs } : {}
8659
+ };
8660
+ }
8661
+ if (inline.type === "tab") {
8662
+ return { inlineIndex, kind: "tab", text: " ", textLength: 1 };
8663
+ }
8664
+ if (inline.type === "hard_break") {
8665
+ return { inlineIndex, kind: "hard-break", text: "\n", textLength: 1 };
8666
+ }
8667
+ if (inline.type === "symbol") {
8668
+ const cloned = inline.marks ? cloneMarks2(inline.marks) : void 0;
8669
+ return {
8670
+ inlineIndex,
8671
+ kind: "symbol",
8672
+ text: inline.char,
8673
+ textLength: Array.from(inline.char).length,
8674
+ ...cloned?.marks && cloned.marks.length > 0 ? { marks: cloned.marks } : {},
8675
+ ...cloned?.markAttrs ? { markAttrs: cloned.markAttrs } : {}
8676
+ };
8677
+ }
8678
+ return { inlineIndex, kind: "unsupported" };
8679
+ }
7357
8680
  function appendComplexPreviewSegment(paragraph, node, start, label, detail, extras = {}) {
7358
8681
  const preserveOnlyObject = node.preserveOnlyObject ? surfacePreserveOnlyObject(node.preserveOnlyObject) : void 0;
7359
8682
  paragraph.segments.push({
@@ -10485,6 +11808,7 @@ var PAGE_INSTANCE_FIELD_FAMILIES = /* @__PURE__ */ new Set([
10485
11808
  "NUMPAGES",
10486
11809
  "SECTIONPAGES"
10487
11810
  ]);
11811
+ var MAX_PAGE_LOCAL_STORY_PREVIEW_CHARS = 140;
10488
11812
  var EMUS_PER_TWIP = 635;
10489
11813
  function buildPageGraph(inputOrPages, sectionsArg, storiesArg) {
10490
11814
  const input = Array.isArray(inputOrPages) ? {
@@ -10797,6 +12121,8 @@ function buildPageLocalStoryInstance(frameId, pageId, pageIndex, sectionIndex, d
10797
12121
  layout,
10798
12122
  pageFieldCounts
10799
12123
  }) : [];
12124
+ const previewParts = source ? collectPageLocalStoryPreviewParts(source.blocks, storyKey) : [];
12125
+ const previewText = renderPageLocalStoryPreviewText(previewParts, resolvedFields);
10800
12126
  const objectLedger = source ? collectStoryAnchoredObjects(source.blocks, {
10801
12127
  frameId,
10802
12128
  storyKey,
@@ -10811,6 +12137,7 @@ function buildPageLocalStoryInstance(frameId, pageId, pageIndex, sectionIndex, d
10811
12137
  relationshipId: target.relationshipId,
10812
12138
  sectionPart,
10813
12139
  measuredFrameHeightTwips,
12140
+ previewText,
10814
12141
  resolvedFields,
10815
12142
  anchoredObjects: objectLedger.objects
10816
12143
  });
@@ -10824,6 +12151,8 @@ function buildPageLocalStoryInstance(frameId, pageId, pageIndex, sectionIndex, d
10824
12151
  relationshipId: target.relationshipId,
10825
12152
  ...target.sectionIndex === void 0 ? {} : { sectionIndex: target.sectionIndex },
10826
12153
  resolvedFields,
12154
+ previewText,
12155
+ previewParts,
10827
12156
  anchoredObjects: objectLedger.objects,
10828
12157
  measuredFrameHeightTwips,
10829
12158
  signature
@@ -10839,6 +12168,7 @@ function buildPageLocalStorySignature(input) {
10839
12168
  input.relationshipId,
10840
12169
  input.sectionPart,
10841
12170
  input.measuredFrameHeightTwips,
12171
+ input.previewText,
10842
12172
  ...input.resolvedFields.map(
10843
12173
  (field) => [field.fieldId, field.family, field.displayText].join(":")
10844
12174
  ),
@@ -10929,6 +12259,74 @@ function collectResolvedStoryFields(blocks, context) {
10929
12259
  for (const block of blocks) visitBlock(block);
10930
12260
  return fields;
10931
12261
  }
12262
+ function collectPageLocalStoryPreviewParts(blocks, storyKey) {
12263
+ const parts = [];
12264
+ let pageFieldOrdinal = 0;
12265
+ const visitBlock = (block) => {
12266
+ switch (block.type) {
12267
+ case "paragraph":
12268
+ for (const child of block.children) visitInline(child);
12269
+ parts.push({ kind: "text", text: " " });
12270
+ break;
12271
+ case "table":
12272
+ for (const row of block.rows) {
12273
+ for (const cell of row.cells) {
12274
+ for (const childBlock of cell.children) visitBlock(childBlock);
12275
+ }
12276
+ }
12277
+ break;
12278
+ case "sdt":
12279
+ for (const child of block.children) visitBlock(child);
12280
+ break;
12281
+ default:
12282
+ break;
12283
+ }
12284
+ };
12285
+ const visitInline = (inline) => {
12286
+ switch (inline.type) {
12287
+ case "text":
12288
+ parts.push({ kind: "text", text: inline.text });
12289
+ break;
12290
+ case "tab":
12291
+ case "hard_break":
12292
+ parts.push({ kind: "text", text: " " });
12293
+ break;
12294
+ case "field": {
12295
+ const family = inline.fieldFamily ?? classifyFieldInstructionLocal2(inline.instruction);
12296
+ const fallbackText = flattenInline2(inline.children);
12297
+ if (PAGE_INSTANCE_FIELD_FAMILIES.has(family)) {
12298
+ parts.push({
12299
+ kind: "field",
12300
+ fieldId: `${storyKey}:field-${pageFieldOrdinal}:${family}`,
12301
+ fallbackText
12302
+ });
12303
+ pageFieldOrdinal += 1;
12304
+ } else {
12305
+ parts.push({ kind: "text", text: fallbackText });
12306
+ }
12307
+ break;
12308
+ }
12309
+ case "hyperlink":
12310
+ for (const child of inline.children) visitInline(child);
12311
+ break;
12312
+ default:
12313
+ break;
12314
+ }
12315
+ };
12316
+ for (const block of blocks) visitBlock(block);
12317
+ return parts;
12318
+ }
12319
+ function renderPageLocalStoryPreviewText(parts, resolvedFields) {
12320
+ const fieldsById = new Map(resolvedFields.map((field) => [field.fieldId, field]));
12321
+ const text = parts.map(
12322
+ (part) => part.kind === "field" ? fieldsById.get(part.fieldId)?.displayText ?? part.fallbackText : part.text
12323
+ ).join("").replace(/\s+/g, " ").trim();
12324
+ return truncatePageLocalStoryPreview(text);
12325
+ }
12326
+ function truncatePageLocalStoryPreview(text) {
12327
+ if (text.length <= MAX_PAGE_LOCAL_STORY_PREVIEW_CHARS) return text;
12328
+ return `${text.slice(0, MAX_PAGE_LOCAL_STORY_PREVIEW_CHARS - 1).trimEnd()}\u2026`;
12329
+ }
10932
12330
  function collectStoryAnchoredObjects(blocks, context) {
10933
12331
  const objects = [];
10934
12332
  const divergences = [];
@@ -11329,6 +12727,7 @@ function freezeRuntimePageGraph(graph) {
11329
12727
  for (const page of graph.pages) {
11330
12728
  freezePageNode(page);
11331
12729
  }
12730
+ for (const fragment of graph.fragments) freezeBlockFragment(fragment);
11332
12731
  Object.freeze(graph.pages);
11333
12732
  Object.freeze(graph.fragments);
11334
12733
  Object.freeze(graph.anchors);
@@ -11343,6 +12742,64 @@ function freezePageNode(page) {
11343
12742
  Object.freeze(page.noteAllocations);
11344
12743
  Object.freeze(page);
11345
12744
  }
12745
+ function freezeBlockFragment(fragment) {
12746
+ if (fragment.layoutObject) {
12747
+ Object.freeze(fragment.layoutObject.measuredExtentTwips);
12748
+ if (fragment.layoutObject.fieldFamilies) Object.freeze(fragment.layoutObject.fieldFamilies);
12749
+ if (fragment.layoutObject.fieldRegions) {
12750
+ for (const region of fragment.layoutObject.fieldRegions) {
12751
+ if (region.resultRange) Object.freeze(region.resultRange);
12752
+ if (region.sourceRef) Object.freeze(region.sourceRef);
12753
+ if (region.fieldEvidence?.sourceRef) Object.freeze(region.fieldEvidence.sourceRef);
12754
+ if (region.fieldEvidence) Object.freeze(region.fieldEvidence);
12755
+ Object.freeze(region);
12756
+ }
12757
+ Object.freeze(fragment.layoutObject.fieldRegions);
12758
+ }
12759
+ if (fragment.layoutObject.bookmarkRanges) {
12760
+ for (const range of fragment.layoutObject.bookmarkRanges) {
12761
+ if (range.sourceRef) Object.freeze(range.sourceRef);
12762
+ if (range.startSourceRef) Object.freeze(range.startSourceRef);
12763
+ if (range.endSourceRef) Object.freeze(range.endSourceRef);
12764
+ Object.freeze(range);
12765
+ }
12766
+ Object.freeze(fragment.layoutObject.bookmarkRanges);
12767
+ }
12768
+ if (fragment.layoutObject.hyperlinks) {
12769
+ for (const hyperlink of fragment.layoutObject.hyperlinks) {
12770
+ if (hyperlink.sourceRef) Object.freeze(hyperlink.sourceRef);
12771
+ Object.freeze(hyperlink);
12772
+ }
12773
+ Object.freeze(fragment.layoutObject.hyperlinks);
12774
+ }
12775
+ if (fragment.layoutObject.numbering) freezeNumberingLayoutFacts(fragment.layoutObject.numbering);
12776
+ if (fragment.layoutObject.numberingRows) {
12777
+ for (const numbering of fragment.layoutObject.numberingRows) {
12778
+ freezeNumberingLayoutFacts(numbering);
12779
+ }
12780
+ Object.freeze(fragment.layoutObject.numberingRows);
12781
+ }
12782
+ Object.freeze(fragment.layoutObject);
12783
+ }
12784
+ if (fragment.paragraphLineRange) Object.freeze(fragment.paragraphLineRange);
12785
+ if (fragment.tableRowRange) Object.freeze(fragment.tableRowRange);
12786
+ if (fragment.continuation) Object.freeze(fragment.continuation);
12787
+ Object.freeze(fragment);
12788
+ }
12789
+ function freezeNumberingLayoutFacts(numbering) {
12790
+ if (!numbering) return;
12791
+ if (numbering.sourceRef) Object.freeze(numbering.sourceRef);
12792
+ if (numbering.numberingSourceRef) Object.freeze(numbering.numberingSourceRef);
12793
+ if (numbering.numberingInstanceSourceRef) Object.freeze(numbering.numberingInstanceSourceRef);
12794
+ if (numbering.abstractNumberingSourceRef) Object.freeze(numbering.abstractNumberingSourceRef);
12795
+ if (numbering.markerLane) Object.freeze(numbering.markerLane);
12796
+ if (numbering.textColumn) Object.freeze(numbering.textColumn);
12797
+ if (numbering.tabStops) {
12798
+ for (const tab of numbering.tabStops) Object.freeze(tab);
12799
+ Object.freeze(numbering.tabStops);
12800
+ }
12801
+ Object.freeze(numbering);
12802
+ }
11346
12803
  function freezePageRegions(regions) {
11347
12804
  freezePageRegion(regions.body);
11348
12805
  if (regions.header) freezePageRegion(regions.header);
@@ -11365,6 +12822,12 @@ function freezePageRegion(region) {
11365
12822
  function freezePageFrame(frame) {
11366
12823
  Object.freeze(frame.physicalBoundsTwips);
11367
12824
  Object.freeze(frame.divergenceIds);
12825
+ for (const story of frame.pageLocalStories) {
12826
+ Object.freeze(story.resolvedFields);
12827
+ Object.freeze(story.previewParts);
12828
+ Object.freeze(story.anchoredObjects);
12829
+ Object.freeze(story);
12830
+ }
11368
12831
  Object.freeze(frame.pageLocalStories);
11369
12832
  Object.freeze(frame);
11370
12833
  }
@@ -11398,16 +12861,22 @@ function normalizePageLocalStoryFieldsForPages(pages) {
11398
12861
  return { ...field, displayText };
11399
12862
  });
11400
12863
  if (!storyChanged) return story;
12864
+ const previewText = renderPageLocalStoryPreviewText(
12865
+ story.previewParts,
12866
+ resolvedFields
12867
+ );
11401
12868
  const sectionPart = story.sectionIndex === void 0 ? "section-unknown" : `section-${story.sectionIndex}`;
11402
12869
  return {
11403
12870
  ...story,
11404
12871
  resolvedFields,
12872
+ previewText,
11405
12873
  signature: buildPageLocalStorySignature({
11406
12874
  kind: story.kind,
11407
12875
  variant: story.variant,
11408
12876
  relationshipId: story.relationshipId,
11409
12877
  sectionPart,
11410
12878
  measuredFrameHeightTwips: story.measuredFrameHeightTwips,
12879
+ previewText,
11411
12880
  resolvedFields,
11412
12881
  anchoredObjects: story.anchoredObjects
11413
12882
  })
@@ -11514,10 +12983,13 @@ function collectSplitRowCarryForPage(ranges, pageRangeIndex) {
11514
12983
  }
11515
12984
 
11516
12985
  // src/runtime/layout/project-block-fragments.ts
11517
- function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlockIdByPageIndex, fragmentMeasurementsByPageIndex, fieldRegions = []) {
12986
+ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlockIdByPageIndex, fragmentMeasurementsByPageIndex, fieldRegions = [], editableTargets = [], numberingInputs = []) {
11518
12987
  const byPage = /* @__PURE__ */ new Map();
11519
12988
  const perPageCounter = /* @__PURE__ */ new Map();
11520
12989
  const fieldRegionsByParagraphIndex = buildFieldRegionsByParagraphIndex(fieldRegions);
12990
+ const generatedTargets = buildGeneratedTargets(editableTargets);
12991
+ const bookmarkRanges = buildBookmarkRanges(editableTargets);
12992
+ const numberingByParagraphIndex = buildNumberingByParagraphIndex(numberingInputs);
11521
12993
  const pushFragment = (pageIndex, fragment) => {
11522
12994
  const existing = byPage.get(pageIndex);
11523
12995
  if (existing) {
@@ -11552,6 +13024,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
11552
13024
  });
11553
13025
  },
11554
13026
  fieldRegionsByParagraphIndex,
13027
+ generatedTargets,
13028
+ bookmarkRanges,
13029
+ numberingByParagraphIndex,
11555
13030
  blockPath
11556
13031
  );
11557
13032
  continue;
@@ -11571,6 +13046,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
11571
13046
  });
11572
13047
  },
11573
13048
  fieldRegionsByParagraphIndex,
13049
+ generatedTargets,
13050
+ bookmarkRanges,
13051
+ numberingByParagraphIndex,
11574
13052
  blockPath
11575
13053
  );
11576
13054
  continue;
@@ -11601,6 +13079,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
11601
13079
  widthTwips,
11602
13080
  paginationRole: "whole",
11603
13081
  fieldRegionsByParagraphIndex,
13082
+ generatedTargets,
13083
+ bookmarkRanges,
13084
+ numberingByParagraphIndex,
11604
13085
  blockPath
11605
13086
  }),
11606
13087
  ...columnIndex !== void 0 ? { columnIndex } : {}
@@ -11747,7 +13228,7 @@ function buildRunAnchorsForLine(input) {
11747
13228
  }
11748
13229
  return anchors;
11749
13230
  }
11750
- function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
13231
+ function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], bookmarkRanges = [], numberingByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
11751
13232
  for (let i = 0; i < slices.length; i += 1) {
11752
13233
  const slice = slices[i];
11753
13234
  const heightTwips = slice.heightTwips ?? estimateSliceHeightFromLines(slice.lineRange);
@@ -11771,6 +13252,9 @@ function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex =
11771
13252
  widthTwips: slice.widthTwips,
11772
13253
  paginationRole: slice.lineRange.from > 0 ? "continuation" : "slice",
11773
13254
  fieldRegionsByParagraphIndex,
13255
+ generatedTargets,
13256
+ bookmarkRanges,
13257
+ numberingByParagraphIndex,
11774
13258
  blockPath
11775
13259
  })
11776
13260
  };
@@ -11791,7 +13275,7 @@ function estimateSliceHeightFromLines(lineRange) {
11791
13275
  const lines = Math.max(0, lineRange.to - lineRange.from);
11792
13276
  return lines * 240;
11793
13277
  }
11794
- function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
13278
+ function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], bookmarkRanges = [], numberingByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
11795
13279
  for (let i = 0; i < slices.length; i += 1) {
11796
13280
  const slice = slices[i];
11797
13281
  const heightTwips = slice.heightTwips ?? estimateSliceHeightFromRows(slice.rowRange);
@@ -11814,6 +13298,9 @@ function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /*
11814
13298
  heightTwips,
11815
13299
  paginationRole: slice.rowRange.from > 0 ? "continuation" : "slice",
11816
13300
  fieldRegionsByParagraphIndex,
13301
+ generatedTargets,
13302
+ bookmarkRanges,
13303
+ numberingByParagraphIndex,
11817
13304
  blockPath
11818
13305
  }),
11819
13306
  ...slice.columnIndex !== void 0 ? { columnIndex: slice.columnIndex } : {}
@@ -11884,13 +13371,27 @@ function estimateSliceHeightFromRows(rowRange) {
11884
13371
  function buildFragmentLayoutObject(input) {
11885
13372
  const fieldFamilies = collectFieldFamilies(input.block);
11886
13373
  const kind = resolveFragmentLayoutObjectKind(input.block, fieldFamilies);
11887
- const numberingRows = collectNumberingLayoutFactsForBlock(input.block, input.blockPath);
13374
+ const numberingRows = collectNumberingLayoutFactsForBlock(
13375
+ input.block,
13376
+ input.blockPath,
13377
+ input.numberingByParagraphIndex
13378
+ );
11888
13379
  const numbering = input.block.kind === "paragraph" ? numberingRows[0] : void 0;
11889
13380
  const fieldRegions = collectFieldRegionLayoutFacts(
11890
13381
  input.block,
11891
13382
  input.fragmentId,
11892
13383
  input.fieldRegionsByParagraphIndex
11893
13384
  );
13385
+ const bookmarkRanges = collectBookmarkRangeLayoutFacts(
13386
+ input.fragmentId,
13387
+ input.blockPath,
13388
+ input.bookmarkRanges
13389
+ );
13390
+ const hyperlinks = collectHyperlinkLayoutFacts(
13391
+ input.fragmentId,
13392
+ input.blockPath,
13393
+ input.generatedTargets
13394
+ );
11894
13395
  return {
11895
13396
  objectId: `${kind}:${input.fragmentId}`,
11896
13397
  kind,
@@ -11902,6 +13403,8 @@ function buildFragmentLayoutObject(input) {
11902
13403
  },
11903
13404
  ...fieldFamilies.length > 0 ? { fieldFamilies } : {},
11904
13405
  ...fieldRegions.length > 0 ? { fieldRegions } : {},
13406
+ ...bookmarkRanges.length > 0 ? { bookmarkRanges } : {},
13407
+ ...hyperlinks.length > 0 ? { hyperlinks } : {},
11905
13408
  ...numbering ? { numbering } : {},
11906
13409
  ...numberingRows.length > 0 ? { numberingRows } : {}
11907
13410
  };
@@ -12016,6 +13519,18 @@ function toRuntimeFieldRegionLayoutFacts(region, fieldRegionId) {
12016
13519
  paragraphIndex: region.paragraphIndex,
12017
13520
  fieldFamily: region.fieldFamily,
12018
13521
  refreshStatus: region.refreshStatus,
13522
+ ...region.tocId !== void 0 ? { tocId: region.tocId } : {},
13523
+ ...region.sourcePath !== void 0 ? { sourcePath: region.sourcePath } : {},
13524
+ ...region.parentKind !== void 0 ? { parentKind: region.parentKind } : {},
13525
+ ...region.resultRange !== void 0 ? {
13526
+ resultRange: {
13527
+ fromParagraphIndex: region.resultRange.fromParagraphIndex,
13528
+ toParagraphIndex: region.resultRange.toParagraphIndex
13529
+ }
13530
+ } : {},
13531
+ ...region.status !== void 0 ? { status: region.status } : {},
13532
+ ...region.cachedEntryCount !== void 0 ? { cachedEntryCount: region.cachedEntryCount } : {},
13533
+ ...region.generatedEntryCount !== void 0 ? { generatedEntryCount: region.generatedEntryCount } : {},
12019
13534
  ...region.sourceRef !== void 0 ? { sourceRef: { ...region.sourceRef } } : {},
12020
13535
  ...region.fieldEvidence !== void 0 ? {
12021
13536
  fieldEvidence: {
@@ -12025,6 +13540,134 @@ function toRuntimeFieldRegionLayoutFacts(region, fieldRegionId) {
12025
13540
  } : {}
12026
13541
  };
12027
13542
  }
13543
+ function buildGeneratedTargets(targets) {
13544
+ return targets.filter(
13545
+ (target) => target.kind === "field-result-text" || target.kind === "hyperlink-text" || target.kind === "hyperlink-destination" || target.kind === "bookmark-anchor" || target.kind === "bookmark-content-range"
13546
+ );
13547
+ }
13548
+ function buildBookmarkRanges(targets) {
13549
+ const anchors = /* @__PURE__ */ new Map();
13550
+ const contentRanges = /* @__PURE__ */ new Map();
13551
+ for (const target of targets) {
13552
+ const bookmarkId = target.link?.bookmarkId;
13553
+ if (!bookmarkId) continue;
13554
+ const key = `${target.storyKey}:${bookmarkId}`;
13555
+ if (target.kind === "bookmark-content-range") {
13556
+ contentRanges.set(key, target);
13557
+ continue;
13558
+ }
13559
+ if (target.kind !== "bookmark-anchor") continue;
13560
+ const entry = anchors.get(key) ?? {};
13561
+ if (target.targetKey.includes(":bookmark:start:")) entry.start = target;
13562
+ else if (target.targetKey.includes(":bookmark:end:")) entry.end = target;
13563
+ anchors.set(key, entry);
13564
+ }
13565
+ const ranges = [];
13566
+ for (const [key, pair] of anchors) {
13567
+ if (!pair.start || !pair.end) continue;
13568
+ const startBlockPath = topLevelBlockPath(pair.start.blockPath);
13569
+ const endBlockPath = topLevelBlockPath(pair.end.blockPath);
13570
+ const startBlockIndex = parseTopLevelBlockIndex(startBlockPath);
13571
+ const endBlockIndex = parseTopLevelBlockIndex(endBlockPath);
13572
+ if (startBlockPath === void 0 || endBlockPath === void 0 || startBlockIndex === void 0 || endBlockIndex === void 0) {
13573
+ continue;
13574
+ }
13575
+ const contentRange = contentRanges.get(key);
13576
+ ranges.push({
13577
+ bookmarkId: pair.start.link?.bookmarkId ?? pair.end.link?.bookmarkId ?? key,
13578
+ ...pair.start.link?.bookmarkName !== void 0 ? { bookmarkName: pair.start.link.bookmarkName } : {},
13579
+ storyKey: pair.start.storyKey,
13580
+ ...contentRange?.link?.rangeKey !== void 0 ? { rangeKey: contentRange.link.rangeKey } : {},
13581
+ ...contentRange?.targetKey !== void 0 ? { contentRangeTargetKey: contentRange.targetKey } : {},
13582
+ startTargetKey: pair.start.targetKey,
13583
+ endTargetKey: pair.end.targetKey,
13584
+ startBlockPath,
13585
+ endBlockPath,
13586
+ startBlockIndex,
13587
+ endBlockIndex,
13588
+ ...cloneRuntimeSourceRef(contentRange?.sourceRef ?? pair.start.sourceRef) !== void 0 ? { sourceRef: cloneRuntimeSourceRef(contentRange?.sourceRef ?? pair.start.sourceRef) } : {},
13589
+ ...cloneRuntimeSourceRef(pair.start.sourceRef) !== void 0 ? { startSourceRef: cloneRuntimeSourceRef(pair.start.sourceRef) } : {},
13590
+ ...cloneRuntimeSourceRef(pair.end.sourceRef) !== void 0 ? { endSourceRef: cloneRuntimeSourceRef(pair.end.sourceRef) } : {}
13591
+ });
13592
+ }
13593
+ return ranges;
13594
+ }
13595
+ function buildNumberingByParagraphIndex(numberingInputs) {
13596
+ const byParagraph = /* @__PURE__ */ new Map();
13597
+ for (const input of numberingInputs) {
13598
+ if (!byParagraph.has(input.paragraphIndex)) {
13599
+ byParagraph.set(input.paragraphIndex, input);
13600
+ }
13601
+ }
13602
+ return byParagraph;
13603
+ }
13604
+ function collectBookmarkRangeLayoutFacts(fragmentId, blockPath, bookmarkRanges) {
13605
+ if (!blockPath || !bookmarkRanges || bookmarkRanges.length === 0) return [];
13606
+ const blockIndex = parseTopLevelBlockIndex(blockPath);
13607
+ if (blockIndex === void 0) return [];
13608
+ const facts = [];
13609
+ for (const range of bookmarkRanges) {
13610
+ const from = Math.min(range.startBlockIndex, range.endBlockIndex);
13611
+ const to = Math.max(range.startBlockIndex, range.endBlockIndex);
13612
+ if (blockIndex < from || blockIndex > to) continue;
13613
+ const startsHere = blockIndex === range.startBlockIndex;
13614
+ const endsHere = blockIndex === range.endBlockIndex;
13615
+ facts.push({
13616
+ bookmarkRangeId: `bookmark-range:${range.storyKey}:${range.bookmarkId}:${fragmentId}`,
13617
+ bookmarkId: range.bookmarkId,
13618
+ ...range.bookmarkName !== void 0 ? { bookmarkName: range.bookmarkName } : {},
13619
+ storyKey: range.storyKey,
13620
+ rangeRole: startsHere && endsHere ? "whole" : startsHere ? "start" : endsHere ? "end" : "inside",
13621
+ startBlockPath: range.startBlockPath,
13622
+ endBlockPath: range.endBlockPath,
13623
+ ...range.rangeKey !== void 0 ? { rangeKey: range.rangeKey } : {},
13624
+ ...range.contentRangeTargetKey !== void 0 ? { contentRangeTargetKey: range.contentRangeTargetKey } : {},
13625
+ ...range.startTargetKey !== void 0 ? { startTargetKey: range.startTargetKey } : {},
13626
+ ...range.endTargetKey !== void 0 ? { endTargetKey: range.endTargetKey } : {},
13627
+ ...range.sourceRef !== void 0 ? { sourceRef: { ...range.sourceRef } } : {},
13628
+ ...range.startSourceRef !== void 0 ? { startSourceRef: { ...range.startSourceRef } } : {},
13629
+ ...range.endSourceRef !== void 0 ? { endSourceRef: { ...range.endSourceRef } } : {}
13630
+ });
13631
+ }
13632
+ return facts;
13633
+ }
13634
+ function collectHyperlinkLayoutFacts(fragmentId, blockPath, targets) {
13635
+ if (!blockPath || !targets || targets.length === 0) return [];
13636
+ const facts = [];
13637
+ for (const target of targets) {
13638
+ if (target.kind !== "hyperlink-text" && target.kind !== "hyperlink-destination") continue;
13639
+ if (!pathParticipatesInBlock(target.blockPath, blockPath)) continue;
13640
+ const href = target.link?.href;
13641
+ facts.push({
13642
+ hyperlinkLayoutId: `hyperlink:${target.targetKey}:${fragmentId}`,
13643
+ targetKey: target.targetKey,
13644
+ storyKey: target.storyKey,
13645
+ blockPath: target.blockPath,
13646
+ leafPath: target.leafPath,
13647
+ role: target.kind === "hyperlink-text" ? "display-text" : "destination",
13648
+ ...href !== void 0 ? { href } : {},
13649
+ ...target.link?.destinationKind !== void 0 ? { destinationKind: target.link.destinationKind } : href?.startsWith("#") ? { destinationKind: "internal-anchor" } : href !== void 0 ? { destinationKind: "external" } : {},
13650
+ ...target.link?.bookmarkName !== void 0 ? { targetBookmarkName: target.link.bookmarkName } : href?.startsWith("#") && href.length > 1 ? { targetBookmarkName: href.slice(1) } : {},
13651
+ ...cloneRuntimeSourceRef(target.sourceRef) !== void 0 ? { sourceRef: cloneRuntimeSourceRef(target.sourceRef) } : {}
13652
+ });
13653
+ }
13654
+ return facts;
13655
+ }
13656
+ function pathParticipatesInBlock(targetPath, blockPath) {
13657
+ return targetPath === blockPath || targetPath.startsWith(`${blockPath}/`);
13658
+ }
13659
+ function topLevelBlockPath(path) {
13660
+ const match = /^(main\/block\[\d+\])(?:\/|$)/u.exec(path);
13661
+ return match?.[1];
13662
+ }
13663
+ function parseTopLevelBlockIndex(path) {
13664
+ if (!path) return void 0;
13665
+ const match = /^main\/block\[(\d+)\]$/u.exec(path);
13666
+ return match ? Number(match[1]) : void 0;
13667
+ }
13668
+ function cloneRuntimeSourceRef(sourceRef) {
13669
+ return sourceRef !== void 0 ? { ...sourceRef } : void 0;
13670
+ }
12028
13671
  function collectNumberingLayoutFacts(block) {
12029
13672
  if (block.kind !== "paragraph") return void 0;
12030
13673
  if (!block.numbering && !block.resolvedNumbering && block.numberingPrefix === void 0) {
@@ -12064,13 +13707,14 @@ function collectNumberingLayoutFacts(block) {
12064
13707
  } : {}
12065
13708
  };
12066
13709
  }
12067
- function collectNumberingLayoutFactsForBlock(block, blockPath) {
13710
+ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagraphIndex) {
12068
13711
  const rows = [];
12069
13712
  const seen = /* @__PURE__ */ new Set();
12070
13713
  visitParagraphBlocks(block, (paragraph, context) => {
12071
13714
  const numbering = collectNumberingLayoutFacts(paragraph);
12072
13715
  if (!numbering) return;
12073
13716
  const paragraphIndex = parseParagraphBlockIndex(paragraph.blockId);
13717
+ const canonical = paragraphIndex !== void 0 ? numberingByParagraphIndex?.get(paragraphIndex) : void 0;
12074
13718
  const numberingKey = context.path !== void 0 ? `main:${context.path}:numbering` : void 0;
12075
13719
  const numberingLayoutId = numberingKey ?? [
12076
13720
  "numbering",
@@ -12083,9 +13727,17 @@ function collectNumberingLayoutFactsForBlock(block, blockPath) {
12083
13727
  rows.push({
12084
13728
  numberingLayoutId,
12085
13729
  ...numberingKey !== void 0 ? { numberingKey } : {},
12086
- ...context.path !== void 0 ? { sourceBlockPath: context.path } : {},
13730
+ ...canonical?.storyKey !== void 0 ? { storyKey: canonical.storyKey } : {},
13731
+ ...canonical?.blockPath !== void 0 ? { sourceBlockPath: canonical.blockPath } : context.path !== void 0 ? { sourceBlockPath: context.path } : {},
12087
13732
  sourceBlockId: paragraph.blockId,
12088
13733
  ...paragraphIndex !== void 0 ? { paragraphIndex } : {},
13734
+ ...canonical?.sourceRef !== void 0 ? { sourceRef: { ...canonical.sourceRef } } : {},
13735
+ ...canonical?.numberingSourceRef !== void 0 ? { numberingSourceRef: { ...canonical.numberingSourceRef } } : {},
13736
+ ...canonical?.numberingOrigin !== void 0 ? { numberingOrigin: canonical.numberingOrigin } : {},
13737
+ ...canonical?.paragraphStyleId !== void 0 ? { paragraphStyleId: canonical.paragraphStyleId } : {},
13738
+ ...canonical?.numberingInstanceSourceRef !== void 0 ? { numberingInstanceSourceRef: { ...canonical.numberingInstanceSourceRef } } : {},
13739
+ ...canonical?.abstractNumberingId !== void 0 ? { abstractNumberingId: canonical.abstractNumberingId } : {},
13740
+ ...canonical?.abstractNumberingSourceRef !== void 0 ? { abstractNumberingSourceRef: { ...canonical.abstractNumberingSourceRef } } : {},
12089
13741
  ...numbering
12090
13742
  });
12091
13743
  }, blockPath);
@@ -12467,7 +14119,7 @@ function createEmpiricalProvider() {
12467
14119
  }
12468
14120
 
12469
14121
  // src/runtime/layout/layout-engine-version.ts
12470
- var LAYOUT_ENGINE_VERSION = 96;
14122
+ var LAYOUT_ENGINE_VERSION = 87;
12471
14123
 
12472
14124
  // src/runtime/layout/layout-engine-instance.ts
12473
14125
  var FULL_VIEWPORT_WINDOW_KEY = "full";
@@ -12774,7 +14426,8 @@ function createLayoutEngine(options = {}) {
12774
14426
  MAIN_STORY_TARGET
12775
14427
  );
12776
14428
  const sections = buildResolvedSections(document2);
12777
- const fieldRegions = collectCanonicalFieldRegionIdentities(document2);
14429
+ const layoutInputs = collectCanonicalLayoutInputs(document2);
14430
+ const fieldRegions = layoutInputs.fieldRegions;
12778
14431
  const pageStack = buildPageStackWithSplits(
12779
14432
  document2,
12780
14433
  sections,
@@ -12790,7 +14443,9 @@ function createLayoutEngine(options = {}) {
12790
14443
  pageStack.splits,
12791
14444
  pageStack.columnByBlockIdByPageIndex,
12792
14445
  pageStack.fragmentMeasurementsByPageIndex,
12793
- fieldRegions
14446
+ fieldRegions,
14447
+ layoutInputs.editableTargets,
14448
+ layoutInputs.numbering
12794
14449
  );
12795
14450
  const lineBoxesByPageIndex = projectLineBoxesForPageFragments(
12796
14451
  pages,
@@ -12914,14 +14569,17 @@ function createLayoutEngine(options = {}) {
12914
14569
  const freshSnapshotsToRebuild = freshSnapshots.slice(0, convergenceIndex);
12915
14570
  const convergedTailStart = convergenceIndex < freshSnapshots.length ? firstDirty + convergenceIndex : void 0;
12916
14571
  const freshStories = resolvePageStories(freshSnapshotsToRebuild);
12917
- const fieldRegions = collectCanonicalFieldRegionIdentities(document2);
14572
+ const layoutInputs = collectCanonicalLayoutInputs(document2);
14573
+ const fieldRegions = layoutInputs.fieldRegions;
12918
14574
  const freshBodyFragmentsByPageIndex = projectSurfaceBlocksToPageFragments(
12919
14575
  mainSurface,
12920
14576
  freshSnapshotsToRebuild,
12921
14577
  freshResult.splits,
12922
14578
  freshResult.columnByBlockIdByPageIndex,
12923
14579
  freshResult.fragmentMeasurementsByPageIndex,
12924
- fieldRegions
14580
+ fieldRegions,
14581
+ layoutInputs.editableTargets,
14582
+ layoutInputs.numbering
12925
14583
  );
12926
14584
  const freshLineBoxesByPageIndex = projectLineBoxesForPageFragments(
12927
14585
  freshSnapshotsToRebuild,