@beyondwork/docx-react-component 1.0.128 → 1.0.129

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 (98) hide show
  1. package/dist/api/public-types.cjs +215 -61
  2. package/dist/api/public-types.d.cts +2 -2
  3. package/dist/api/public-types.d.ts +2 -2
  4. package/dist/api/public-types.js +2 -2
  5. package/dist/api/v3.cjs +896 -71
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +8 -8
  9. package/dist/{canonical-document-CXCFCbAz.d.cts → canonical-document-BMtONpgf.d.cts} +6 -0
  10. package/dist/{canonical-document-CXCFCbAz.d.ts → canonical-document-BMtONpgf.d.ts} +6 -0
  11. package/dist/{chunk-KV435YXO.js → chunk-5DSHUYSY.js} +1 -1
  12. package/dist/{chunk-TQDQU2E3.js → chunk-63FYIGCT.js} +2 -2
  13. package/dist/{chunk-ZDOAUP3V.js → chunk-DDN2AIGE.js} +1 -1
  14. package/dist/{chunk-6F5QW44A.js → chunk-DJU2W4E4.js} +2 -2
  15. package/dist/{chunk-4EENH4FG.js → chunk-EZKJXIPH.js} +1 -1
  16. package/dist/{chunk-CXSYRB37.js → chunk-HUIHBBAQ.js} +166 -49
  17. package/dist/{chunk-ESJ2MES5.js → chunk-JJGVE5J7.js} +1 -1
  18. package/dist/{chunk-LZVBNDGU.js → chunk-LJH64PV3.js} +3 -3
  19. package/dist/{chunk-MWSBGJQO.js → chunk-OTQIW2TC.js} +2 -2
  20. package/dist/{chunk-2QL5DAKF.js → chunk-PGKUJZXV.js} +3 -3
  21. package/dist/{chunk-6EROGFUF.js → chunk-PRAZBHNF.js} +441 -128
  22. package/dist/{chunk-4YJVRIUB.js → chunk-Q3QYGKFE.js} +51 -8
  23. package/dist/{chunk-YHZHPXDB.js → chunk-RMRTQGW3.js} +50 -13
  24. package/dist/{chunk-XRACP43Q.js → chunk-SKPTKQHF.js} +351 -13
  25. package/dist/{chunk-D5HYZQTG.js → chunk-VNLDQJ47.js} +1 -1
  26. package/dist/{chunk-BYSRJ4FE.js → chunk-W34X3KBR.js} +1 -1
  27. package/dist/{chunk-V6XVZFFH.js → chunk-XMHSGPLN.js} +2 -2
  28. package/dist/{chunk-LCYYR57Q.js → chunk-XQCAMKIQ.js} +421 -6
  29. package/dist/{chunk-YD2JE54B.js → chunk-YZDZ4FGR.js} +1 -1
  30. package/dist/compare.d.cts +1 -1
  31. package/dist/compare.d.ts +1 -1
  32. package/dist/core/commands/formatting-commands.d.cts +2 -2
  33. package/dist/core/commands/formatting-commands.d.ts +2 -2
  34. package/dist/core/commands/image-commands.cjs +166 -49
  35. package/dist/core/commands/image-commands.d.cts +2 -2
  36. package/dist/core/commands/image-commands.d.ts +2 -2
  37. package/dist/core/commands/image-commands.js +4 -4
  38. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  39. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  40. package/dist/core/commands/style-commands.d.cts +2 -2
  41. package/dist/core/commands/style-commands.d.ts +2 -2
  42. package/dist/core/commands/table-structure-commands.cjs +166 -49
  43. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  44. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  45. package/dist/core/commands/table-structure-commands.js +3 -3
  46. package/dist/core/commands/text-commands.cjs +166 -49
  47. package/dist/core/commands/text-commands.d.cts +2 -2
  48. package/dist/core/commands/text-commands.d.ts +2 -2
  49. package/dist/core/commands/text-commands.js +4 -4
  50. package/dist/core/selection/mapping.d.cts +2 -2
  51. package/dist/core/selection/mapping.d.ts +2 -2
  52. package/dist/core/state/editor-state.d.cts +2 -2
  53. package/dist/core/state/editor-state.d.ts +2 -2
  54. package/dist/index.cjs +1486 -211
  55. package/dist/index.d.cts +5 -5
  56. package/dist/index.d.ts +5 -5
  57. package/dist/index.js +46 -22
  58. package/dist/io/docx-session.cjs +51 -8
  59. package/dist/io/docx-session.d.cts +4 -4
  60. package/dist/io/docx-session.d.ts +4 -4
  61. package/dist/io/docx-session.js +3 -3
  62. package/dist/legal.d.cts +1 -1
  63. package/dist/legal.d.ts +1 -1
  64. package/dist/legal.js +2 -2
  65. package/dist/{loader-19ct2Be0.d.ts → loader-4qsw4eIU.d.ts} +3 -3
  66. package/dist/{loader-CoXQ2wGd.d.cts → loader-B8TKhmQi.d.cts} +3 -3
  67. package/dist/{public-types-B-CskQen.d.cts → public-types-B5CRoR6f.d.cts} +128 -1
  68. package/dist/{public-types-7KZsNGE2.d.ts → public-types-p9b8rfy8.d.ts} +128 -1
  69. package/dist/public-types.cjs +215 -61
  70. package/dist/public-types.d.cts +2 -2
  71. package/dist/public-types.d.ts +2 -2
  72. package/dist/public-types.js +2 -2
  73. package/dist/runtime/collab.d.cts +3 -3
  74. package/dist/runtime/collab.d.ts +3 -3
  75. package/dist/runtime/document-runtime.cjs +980 -185
  76. package/dist/runtime/document-runtime.d.cts +2 -2
  77. package/dist/runtime/document-runtime.d.ts +2 -2
  78. package/dist/runtime/document-runtime.js +13 -13
  79. package/dist/{session-B5015J4v.d.cts → session-BnGIjaex.d.cts} +3 -3
  80. package/dist/{session-C2i8-d6v.d.ts → session-vEYKf-w3.d.ts} +3 -3
  81. package/dist/session.cjs +51 -8
  82. package/dist/session.d.cts +5 -5
  83. package/dist/session.d.ts +5 -5
  84. package/dist/session.js +4 -4
  85. package/dist/tailwind.cjs +215 -61
  86. package/dist/tailwind.d.cts +2 -2
  87. package/dist/tailwind.d.ts +2 -2
  88. package/dist/tailwind.js +5 -5
  89. package/dist/{types-DNhN0WeN.d.cts → types-BLuvZ6cQ.d.cts} +2 -2
  90. package/dist/{types-yvrQuGX9.d.ts → types-Dutlyj0T.d.ts} +2 -2
  91. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  92. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  93. package/dist/ui-tailwind/editor-surface/search-plugin.js +3 -3
  94. package/dist/ui-tailwind.cjs +215 -61
  95. package/dist/ui-tailwind.d.cts +3 -3
  96. package/dist/ui-tailwind.d.ts +3 -3
  97. package/dist/ui-tailwind.js +5 -5
  98. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -10120,12 +10120,13 @@ function getLevelStartAt(level, levelDefinitions) {
10120
10120
  return levelDefinitions.get(level)?.startAt ?? DEFAULT_NUMBERING_START_AT;
10121
10121
  }
10122
10122
  function getNumberingFormatPosture(format, value) {
10123
- if (!isSupportedNumberingFormat(format)) {
10123
+ const registryEntry = getNumberingFormatRegistryEntry(format);
10124
+ if (!registryEntry || registryEntry.renderSupport === "approximated") {
10124
10125
  return {
10125
10126
  status: "approximated",
10126
10127
  requestedFormat: format,
10127
10128
  renderedFormat: "decimal",
10128
- reason: "unsupported-numbering-format-decimal-fallback"
10129
+ reason: registryEntry?.fallbackReason ?? "unsupported-numbering-format-decimal-fallback"
10129
10130
  };
10130
10131
  }
10131
10132
  if (value !== void 0 && ((format === "upperRoman" || format === "lowerRoman") && (value <= 0 || value >= 4e3) || (format === "cardinalText" || format === "ordinalText") && (!Number.isInteger(value) || value < 1 || value > 999) || (format === "upperLetter" || format === "lowerLetter" || format === "chicago") && value < 1)) {
@@ -10156,56 +10157,148 @@ function renderLevelText(text, counters, levelDefinitions) {
10156
10157
  });
10157
10158
  return rendered.trim().length > 0 ? rendered : null;
10158
10159
  }
10159
- var SUPPORTED_NUMBERING_FORMATS = /* @__PURE__ */ new Set([
10160
- "decimal",
10161
- "decimalZero",
10162
- "upperLetter",
10163
- "lowerLetter",
10164
- "upperRoman",
10165
- "lowerRoman",
10166
- "hex",
10167
- "ordinal",
10168
- "cardinalText",
10169
- "ordinalText",
10170
- "chicago",
10171
- "bullet",
10172
- "none"
10173
- ]);
10174
10160
  function isSupportedNumberingFormat(format) {
10175
- return SUPPORTED_NUMBERING_FORMATS.has(format);
10161
+ return getNumberingFormatRegistryEntry(format)?.renderSupport === "supported";
10162
+ }
10163
+ function getNumberingFormatRegistryEntry(format) {
10164
+ return NUMBERING_FORMAT_REGISTRY.get(format);
10176
10165
  }
10177
10166
  function formatCounter(value, format) {
10178
- switch (format) {
10179
- case "decimal":
10180
- return String(value);
10181
- case "decimalZero":
10182
- return String(value).padStart(2, "0");
10183
- case "upperLetter":
10184
- return toAlphabetic2(value).toUpperCase();
10185
- case "lowerLetter":
10186
- return toAlphabetic2(value).toLowerCase();
10187
- case "upperRoman":
10188
- return toRoman2(value).toUpperCase();
10189
- case "lowerRoman":
10190
- return toRoman2(value).toLowerCase();
10191
- case "hex":
10192
- return value >= 0 ? value.toString(16).toUpperCase() : String(value);
10193
- case "ordinal":
10194
- return toOrdinal2(value);
10195
- case "cardinalText":
10196
- return toCardinalText2(value);
10197
- case "ordinalText":
10198
- return toOrdinalText2(value);
10199
- case "chicago":
10200
- return toChicago2(value);
10201
- case "bullet":
10202
- return "";
10203
- case "none":
10204
- return "";
10205
- default:
10206
- return String(value);
10207
- }
10167
+ return getNumberingFormatRegistryEntry(format)?.render(value) ?? String(value);
10208
10168
  }
10169
+ var exactNumberingFormatEntries = [
10170
+ {
10171
+ format: "decimal",
10172
+ renderSupport: "supported",
10173
+ renderedFormat: "decimal",
10174
+ supportsMutation: true,
10175
+ render: (value) => String(value)
10176
+ },
10177
+ {
10178
+ format: "decimalZero",
10179
+ renderSupport: "supported",
10180
+ renderedFormat: "decimalZero",
10181
+ supportsMutation: true,
10182
+ render: (value) => String(value).padStart(2, "0")
10183
+ },
10184
+ {
10185
+ format: "upperLetter",
10186
+ renderSupport: "supported",
10187
+ renderedFormat: "upperLetter",
10188
+ supportsMutation: true,
10189
+ render: (value) => toAlphabetic2(value).toUpperCase()
10190
+ },
10191
+ {
10192
+ format: "lowerLetter",
10193
+ renderSupport: "supported",
10194
+ renderedFormat: "lowerLetter",
10195
+ supportsMutation: true,
10196
+ render: (value) => toAlphabetic2(value).toLowerCase()
10197
+ },
10198
+ {
10199
+ format: "upperRoman",
10200
+ renderSupport: "supported",
10201
+ renderedFormat: "upperRoman",
10202
+ supportsMutation: true,
10203
+ render: (value) => toRoman2(value).toUpperCase()
10204
+ },
10205
+ {
10206
+ format: "lowerRoman",
10207
+ renderSupport: "supported",
10208
+ renderedFormat: "lowerRoman",
10209
+ supportsMutation: true,
10210
+ render: (value) => toRoman2(value).toLowerCase()
10211
+ },
10212
+ {
10213
+ format: "hex",
10214
+ renderSupport: "supported",
10215
+ renderedFormat: "hex",
10216
+ supportsMutation: true,
10217
+ render: (value) => value >= 0 ? value.toString(16).toUpperCase() : String(value)
10218
+ },
10219
+ {
10220
+ format: "ordinal",
10221
+ renderSupport: "supported",
10222
+ renderedFormat: "ordinal",
10223
+ supportsMutation: true,
10224
+ render: toOrdinal2
10225
+ },
10226
+ {
10227
+ format: "cardinalText",
10228
+ renderSupport: "supported",
10229
+ renderedFormat: "cardinalText",
10230
+ supportsMutation: true,
10231
+ render: toCardinalText2
10232
+ },
10233
+ {
10234
+ format: "ordinalText",
10235
+ renderSupport: "supported",
10236
+ renderedFormat: "ordinalText",
10237
+ supportsMutation: true,
10238
+ render: toOrdinalText2
10239
+ },
10240
+ {
10241
+ format: "chicago",
10242
+ renderSupport: "supported",
10243
+ renderedFormat: "chicago",
10244
+ supportsMutation: true,
10245
+ render: toChicago2
10246
+ },
10247
+ {
10248
+ format: "bullet",
10249
+ renderSupport: "supported",
10250
+ renderedFormat: "bullet",
10251
+ supportsMutation: true,
10252
+ render: () => ""
10253
+ },
10254
+ {
10255
+ format: "none",
10256
+ renderSupport: "supported",
10257
+ renderedFormat: "none",
10258
+ supportsMutation: true,
10259
+ render: () => ""
10260
+ }
10261
+ ];
10262
+ var approximatedDecimalFormats = [
10263
+ "decimalEnclosedCircle",
10264
+ "decimalEnclosedFullstop",
10265
+ "decimalEnclosedParen",
10266
+ "decimalFullWidth",
10267
+ "decimalHalfWidth",
10268
+ "aiueo",
10269
+ "iroha",
10270
+ "ganada",
10271
+ "chosung",
10272
+ "russianLower",
10273
+ "russianUpper",
10274
+ "hebrew1",
10275
+ "hebrew2",
10276
+ "arabicAlpha",
10277
+ "arabicAbjad",
10278
+ "thaiLetters",
10279
+ "thaiNumbers",
10280
+ "hindiLetters",
10281
+ "hindiNumbers",
10282
+ "ideographDigital",
10283
+ "ideographTraditional",
10284
+ "chineseCounting",
10285
+ "japaneseCounting",
10286
+ "japaneseLegal"
10287
+ ];
10288
+ var approximatedNumberingFormatEntries = approximatedDecimalFormats.map((format) => ({
10289
+ format,
10290
+ renderSupport: "approximated",
10291
+ renderedFormat: "decimal",
10292
+ supportsMutation: false,
10293
+ fallbackReason: "unsupported-numbering-format-decimal-fallback",
10294
+ render: (value) => String(value)
10295
+ }));
10296
+ var NUMBERING_FORMAT_REGISTRY = new Map(
10297
+ [...exactNumberingFormatEntries, ...approximatedNumberingFormatEntries].map((entry) => [
10298
+ entry.format,
10299
+ entry
10300
+ ])
10301
+ );
10209
10302
  function toOrdinal2(value) {
10210
10303
  if (value <= 0) return String(value);
10211
10304
  const lastTwo = value % 100;
@@ -10859,12 +10952,36 @@ var DEFAULT_HYPERLINK_COLOR_HEX = "0563C1";
10859
10952
  function resolveHyperlinkRunFormatting(input, catalog, resolver) {
10860
10953
  const augmentedInput = input.characterStyleId === void 0 ? { ...input, characterStyleId: HYPERLINK_CHARACTER_STYLE_ID } : input;
10861
10954
  const cascade = resolveEffectiveRunFormatting(augmentedInput, catalog);
10862
- const resolvedColor = resolveHyperlinkColorHex(cascade, resolver);
10955
+ const resolvedColor = resolveHyperlinkColorHex(
10956
+ stripInheritedColorHexForImplicitHyperlink(input, catalog, cascade),
10957
+ resolver
10958
+ );
10863
10959
  if (resolvedColor && resolvedColor !== cascade.colorHex) {
10864
10960
  return { ...cascade, colorHex: resolvedColor };
10865
10961
  }
10866
10962
  return cascade;
10867
10963
  }
10964
+ function hasDirectNonAutoColor(input) {
10965
+ return Boolean(input.direct?.colorHex && input.direct.colorHex !== "auto");
10966
+ }
10967
+ function characterStyleDeclaresColorHex(styleId, catalog) {
10968
+ if (!catalog) return false;
10969
+ const chain = resolveCharacterStyleChain(styleId, catalog);
10970
+ return chain.some((chainStyleId) => {
10971
+ const colorHex = catalog.characters[chainStyleId]?.runProperties?.colorHex;
10972
+ return Boolean(colorHex && colorHex !== "auto");
10973
+ });
10974
+ }
10975
+ function stripInheritedColorHexForImplicitHyperlink(originalInput, catalog, cascade) {
10976
+ if (originalInput.characterStyleId !== void 0 || hasDirectNonAutoColor(originalInput) || !cascade.colorHex || cascade.colorHex === "auto" || characterStyleDeclaresColorHex(HYPERLINK_CHARACTER_STYLE_ID, catalog)) {
10977
+ return cascade;
10978
+ }
10979
+ const inheritedCascade = resolveEffectiveRunFormatting(originalInput, catalog);
10980
+ if (inheritedCascade.colorHex !== cascade.colorHex) {
10981
+ return cascade;
10982
+ }
10983
+ return { ...cascade, colorHex: void 0 };
10984
+ }
10868
10985
  function resolveHyperlinkColorHex(cascade, resolver) {
10869
10986
  if (cascade.colorHex && cascade.colorHex !== "auto") {
10870
10987
  return cascade.colorHex;
@@ -16572,6 +16689,14 @@ function paginateSectionBlocksWithSplits(section, blocks, layout, footnotes, mea
16572
16689
  pushPage(block.from);
16573
16690
  continue;
16574
16691
  }
16692
+ if (isStandalonePageBreakParagraph(block)) {
16693
+ if (columnHeight > 0) {
16694
+ pushPage(nextBoundary);
16695
+ } else {
16696
+ pageStart = Math.max(pageStart, Math.min(nextBoundary, section.end));
16697
+ }
16698
+ break;
16699
+ }
16575
16700
  const effectiveNoteHeight = estimateFootnoteReservation(
16576
16701
  block,
16577
16702
  footnotes,
@@ -16746,6 +16871,21 @@ function hasPageBreak(block) {
16746
16871
  }
16747
16872
  return nestedBlocks(block).some(hasPageBreak);
16748
16873
  }
16874
+ function isStandalonePageBreakParagraph(block) {
16875
+ if (block.kind !== "paragraph") return false;
16876
+ let sawPageBreak = false;
16877
+ for (const segment of block.segments) {
16878
+ if (segment.kind === "opaque_inline" && segment.label === "Page break") {
16879
+ sawPageBreak = true;
16880
+ continue;
16881
+ }
16882
+ if (segment.kind === "text" && segment.text.trim().length === 0) {
16883
+ continue;
16884
+ }
16885
+ return false;
16886
+ }
16887
+ return sawPageBreak;
16888
+ }
16749
16889
  function nestedBlocks(block) {
16750
16890
  if (block.kind === "sdt_block") {
16751
16891
  return block.children;
@@ -18230,6 +18370,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
18230
18370
  for (let blockIndex = 0; blockIndex < surface.blocks.length; blockIndex += 1) {
18231
18371
  const block = surface.blocks[blockIndex];
18232
18372
  const blockPath = `main/block[${blockIndex}]`;
18373
+ if (isStandalonePageBreakParagraph2(block)) {
18374
+ continue;
18375
+ }
18233
18376
  if (block.kind === "table") {
18234
18377
  const tableSliceList = splits?.tablesByBlockId.get(block.blockId);
18235
18378
  if (tableSliceList && tableSliceList.length > 1) {
@@ -18315,6 +18458,23 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
18315
18458
  }
18316
18459
  return byPage;
18317
18460
  }
18461
+ function isStandalonePageBreakParagraph2(block) {
18462
+ if (block.kind !== "paragraph") {
18463
+ return false;
18464
+ }
18465
+ let sawPageBreak = false;
18466
+ for (const segment of block.segments) {
18467
+ if (segment.kind === "opaque_inline" && segment.label === "Page break") {
18468
+ sawPageBreak = true;
18469
+ continue;
18470
+ }
18471
+ if (segment.kind === "text" && segment.text.trim().length === 0) {
18472
+ continue;
18473
+ }
18474
+ return false;
18475
+ }
18476
+ return sawPageBreak;
18477
+ }
18318
18478
  function projectLineBoxesForPageFragments(pages, fragmentsByPageIndex, fragmentMeasurementsByPageIndex, surface) {
18319
18479
  const byPage = /* @__PURE__ */ new Map();
18320
18480
  const blocksById = surface ? new Map(surface.blocks.map((block) => [block.blockId, block])) : /* @__PURE__ */ new Map();
@@ -18827,13 +18987,11 @@ function buildBookmarkRanges(targets) {
18827
18987
  }
18828
18988
  var EMPTY_NUMBERING_INPUT_INDEX = {
18829
18989
  byNumberingKey: /* @__PURE__ */ new Map(),
18830
- byBlockPath: /* @__PURE__ */ new Map(),
18831
- byParagraphIndex: /* @__PURE__ */ new Map()
18990
+ byBlockPath: /* @__PURE__ */ new Map()
18832
18991
  };
18833
18992
  function buildNumberingInputIndex(numberingInputs) {
18834
18993
  const byNumberingKey = /* @__PURE__ */ new Map();
18835
18994
  const byBlockPath = /* @__PURE__ */ new Map();
18836
- const byParagraph = /* @__PURE__ */ new Map();
18837
18995
  for (const input of numberingInputs) {
18838
18996
  if (!byNumberingKey.has(input.numberingKey)) {
18839
18997
  byNumberingKey.set(input.numberingKey, input);
@@ -18841,11 +18999,8 @@ function buildNumberingInputIndex(numberingInputs) {
18841
18999
  if (!byBlockPath.has(input.blockPath)) {
18842
19000
  byBlockPath.set(input.blockPath, input);
18843
19001
  }
18844
- if (!byParagraph.has(input.paragraphIndex)) {
18845
- byParagraph.set(input.paragraphIndex, input);
18846
- }
18847
19002
  }
18848
- return { byNumberingKey, byBlockPath, byParagraphIndex: byParagraph };
19003
+ return { byNumberingKey, byBlockPath };
18849
19004
  }
18850
19005
  function collectBookmarkRangeLayoutFacts(fragmentId, blockPath, bookmarkRanges) {
18851
19006
  if (!blockPath || !bookmarkRanges || bookmarkRanges.length === 0) return [];
@@ -18965,8 +19120,7 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingIndex, n
18965
19120
  const canonical = lookupNumberingInput(
18966
19121
  numberingIndex,
18967
19122
  numberingKey,
18968
- context.path,
18969
- paragraphIndex
19123
+ context.path
18970
19124
  );
18971
19125
  const target = findNumberingTarget(numberingTargets, context.path);
18972
19126
  const numberingLayoutId = numberingKey ?? [
@@ -19006,7 +19160,7 @@ function findNumberingTarget(numberingTargets, blockPath) {
19006
19160
  if (blockPath === void 0) return void 0;
19007
19161
  return numberingTargets.find((target) => target.blockPath === blockPath);
19008
19162
  }
19009
- function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraphIndex) {
19163
+ function lookupNumberingInput(numberingIndex, numberingKey, blockPath) {
19010
19164
  if (!numberingIndex) return void 0;
19011
19165
  if (numberingKey !== void 0) {
19012
19166
  const byKey = numberingIndex.byNumberingKey.get(numberingKey);
@@ -19016,7 +19170,7 @@ function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraph
19016
19170
  const byPath = numberingIndex.byBlockPath.get(blockPath);
19017
19171
  if (byPath !== void 0) return byPath;
19018
19172
  }
19019
- return paragraphIndex !== void 0 ? numberingIndex.byParagraphIndex.get(paragraphIndex) : void 0;
19173
+ return void 0;
19020
19174
  }
19021
19175
  function collectNumberingUnavailableReasons(numbering, canonical) {
19022
19176
  const reasons = [];
@@ -19435,7 +19589,7 @@ async function createCanvasProvider(fontLoader) {
19435
19589
  }
19436
19590
 
19437
19591
  // src/runtime/layout/layout-engine-version.ts
19438
- var LAYOUT_ENGINE_VERSION = 88;
19592
+ var LAYOUT_ENGINE_VERSION = 89;
19439
19593
  var LAYCACHE_SCHEMA_VERSION = 12;
19440
19594
 
19441
19595
  // src/runtime/layout/layout-engine-instance.ts
@@ -22000,6 +22154,133 @@ function clamp(value, min, max) {
22000
22154
  return Math.min(max, Math.max(min, value));
22001
22155
  }
22002
22156
 
22157
+ // src/io/ooxml/numbering-catalog-mutation.ts
22158
+ function cloneNumberingCatalog(catalog) {
22159
+ return structuredClone(catalog);
22160
+ }
22161
+ function getListKind(catalog, numberingInstanceId) {
22162
+ const instance = catalog.instances[numberingInstanceId];
22163
+ const definition = instance ? catalog.abstractDefinitions[instance.abstractNumberingId] : void 0;
22164
+ const levelZero = definition?.levels.find((level) => level.level === 0);
22165
+ if (!levelZero) return void 0;
22166
+ return levelZero.format === "bullet" ? "bulleted" : "numbered";
22167
+ }
22168
+ function ensureDefaultListInstance(catalog, kind) {
22169
+ const existing = Object.values(catalog.instances).find(
22170
+ (instance) => getListKind(catalog, instance.numberingInstanceId) === kind
22171
+ );
22172
+ if (existing) return existing.numberingInstanceId;
22173
+ const abstractNumberingId = allocateAbstractDefinition(catalog, {
22174
+ levels: defaultLevels(kind),
22175
+ multiLevelType: "hybridMultilevel"
22176
+ });
22177
+ return allocateNumberingInstance(catalog, abstractNumberingId);
22178
+ }
22179
+ function allocateNumberingInstance(catalog, abstractNumberingId, overrides = []) {
22180
+ const numberingInstanceId = nextCanonicalNumericId(
22181
+ "num:",
22182
+ Object.keys(catalog.instances)
22183
+ );
22184
+ catalog.instances[numberingInstanceId] = {
22185
+ numberingInstanceId,
22186
+ abstractNumberingId,
22187
+ overrides: cloneOverrides(overrides)
22188
+ };
22189
+ return numberingInstanceId;
22190
+ }
22191
+ function allocateAbstractDefinition(catalog, input) {
22192
+ const abstractNumberingId = input.abstractNumberingId && !catalog.abstractDefinitions[input.abstractNumberingId] ? input.abstractNumberingId : nextCanonicalNumericId("abstract-num:", Object.keys(catalog.abstractDefinitions));
22193
+ catalog.abstractDefinitions[abstractNumberingId] = {
22194
+ abstractNumberingId,
22195
+ levels: structuredClone(input.levels),
22196
+ ...input.nsid ? { nsid: input.nsid } : { nsid: freshLongHex(catalog, abstractNumberingId, "nsid") },
22197
+ ...input.multiLevelType ? { multiLevelType: input.multiLevelType } : {},
22198
+ ...input.tplc ? { tplc: input.tplc } : { tplc: freshLongHex(catalog, abstractNumberingId, "tmpl") },
22199
+ ...input.styleLink ? { styleLink: input.styleLink } : {},
22200
+ ...input.numStyleLink ? { numStyleLink: input.numStyleLink } : {}
22201
+ };
22202
+ return abstractNumberingId;
22203
+ }
22204
+ function setStartOverride(catalog, numberingInstanceId, level, startAt) {
22205
+ const instance = catalog.instances[numberingInstanceId];
22206
+ if (!instance) return;
22207
+ catalog.instances[numberingInstanceId] = {
22208
+ ...instance,
22209
+ overrides: mergeOverride(instance.overrides, { level, startAt })
22210
+ };
22211
+ }
22212
+ function mergeOverride(overrides, nextOverride) {
22213
+ return [
22214
+ ...overrides.filter((override) => override.level !== nextOverride.level),
22215
+ structuredClone(nextOverride)
22216
+ ].sort((left, right) => left.level - right.level);
22217
+ }
22218
+ function cloneOverrides(overrides) {
22219
+ return overrides.map((override) => structuredClone(override));
22220
+ }
22221
+ function defaultLevels(kind) {
22222
+ if (kind === "bulleted") {
22223
+ return [
22224
+ { level: 0, format: "bullet", text: "\u2022" },
22225
+ { level: 1, format: "bullet", text: "o" },
22226
+ { level: 2, format: "bullet", text: "\u25A0" },
22227
+ { level: 3, format: "bullet", text: "\u2022" },
22228
+ { level: 4, format: "bullet", text: "o" },
22229
+ { level: 5, format: "bullet", text: "\u25A0" },
22230
+ { level: 6, format: "bullet", text: "\u2022" },
22231
+ { level: 7, format: "bullet", text: "o" },
22232
+ { level: 8, format: "bullet", text: "\u25A0" }
22233
+ ];
22234
+ }
22235
+ return [
22236
+ { level: 0, format: "decimal", text: "%1." },
22237
+ { level: 1, format: "decimal", text: "%1.%2." },
22238
+ { level: 2, format: "lowerLetter", text: "(%3)" },
22239
+ { level: 3, format: "lowerRoman", text: "(%4)" },
22240
+ { level: 4, format: "decimal", text: "%5." },
22241
+ { level: 5, format: "lowerLetter", text: "(%6)" },
22242
+ { level: 6, format: "lowerRoman", text: "(%7)" },
22243
+ { level: 7, format: "decimal", text: "%8." },
22244
+ { level: 8, format: "lowerLetter", text: "(%9)" }
22245
+ ];
22246
+ }
22247
+ function nextCanonicalNumericId(prefix, ids) {
22248
+ return `${prefix}${nextNumericString(ids.map((id) => stripPrefix(id, prefix)))}`;
22249
+ }
22250
+ function nextNumericString(ids) {
22251
+ const used = new Set(ids);
22252
+ let next = 1;
22253
+ for (const id of ids) {
22254
+ const parsed = Number.parseInt(id, 10);
22255
+ if (Number.isFinite(parsed) && parsed >= next) next = parsed + 1;
22256
+ }
22257
+ while (used.has(String(next))) next += 1;
22258
+ return String(next);
22259
+ }
22260
+ function stripPrefix(value, prefix) {
22261
+ return value.startsWith(prefix) ? value.slice(prefix.length) : value;
22262
+ }
22263
+ function freshLongHex(catalog, abstractNumberingId, salt) {
22264
+ const existing = new Set(
22265
+ Object.values(catalog.abstractDefinitions).map((definition) => salt === "nsid" ? definition.nsid : definition.tplc).filter((value) => Boolean(value))
22266
+ );
22267
+ let attempt = 0;
22268
+ while (attempt < 1e3) {
22269
+ const candidate = hashLongHex(`${salt}:${abstractNumberingId}:${attempt}`);
22270
+ if (!existing.has(candidate)) return candidate;
22271
+ attempt += 1;
22272
+ }
22273
+ return hashLongHex(`${salt}:${abstractNumberingId}:${Date.now()}`);
22274
+ }
22275
+ function hashLongHex(input) {
22276
+ let hash = 2166136261;
22277
+ for (let index = 0; index < input.length; index += 1) {
22278
+ hash ^= input.charCodeAt(index);
22279
+ hash = Math.imul(hash, 16777619) >>> 0;
22280
+ }
22281
+ return hash.toString(16).toUpperCase().padStart(8, "0").slice(-8);
22282
+ }
22283
+
22003
22284
  // src/core/commands/list-commands.ts
22004
22285
  function toggleNumberedList(document2, paragraphIndexes, context, options = {}) {
22005
22286
  return toggleListKind(document2, paragraphIndexes, "numbered", context, options);
@@ -22151,7 +22432,7 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1, optio
22151
22432
  affectedParagraphIndexes: []
22152
22433
  };
22153
22434
  }
22154
- const catalog = ensureNumberingCatalog(working.numbering);
22435
+ const catalog = cloneNumberingCatalog(working.numbering);
22155
22436
  const existingInstance = catalog.instances[target.numbering.numberingInstanceId];
22156
22437
  if (!existingInstance) {
22157
22438
  return {
@@ -22159,15 +22440,12 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1, optio
22159
22440
  affectedParagraphIndexes: []
22160
22441
  };
22161
22442
  }
22162
- const numberingInstanceId = createNumberingInstanceId(catalog);
22163
- catalog.instances[numberingInstanceId] = {
22164
- numberingInstanceId,
22165
- abstractNumberingId: existingInstance.abstractNumberingId,
22166
- overrides: mergeOverride(existingInstance.overrides, {
22167
- level: target.numbering.level,
22168
- startAt
22169
- })
22170
- };
22443
+ const numberingInstanceId = allocateNumberingInstance(
22444
+ catalog,
22445
+ existingInstance.abstractNumberingId,
22446
+ existingInstance.overrides
22447
+ );
22448
+ setStartOverride(catalog, numberingInstanceId, target.numbering.level, startAt);
22171
22449
  const affectedParagraphIndexes = [];
22172
22450
  for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
22173
22451
  const paragraph = paragraphs[index];
@@ -22221,7 +22499,7 @@ function continueNumbering(document2, paragraphIndex, context, options = {}) {
22221
22499
  affectedParagraphIndexes: []
22222
22500
  };
22223
22501
  }
22224
- const catalog = ensureNumberingCatalog(working.numbering);
22502
+ const catalog = cloneNumberingCatalog(working.numbering);
22225
22503
  const currentInstanceId = target.numbering.numberingInstanceId;
22226
22504
  const currentKind = getListKind(catalog, currentInstanceId);
22227
22505
  if (!currentKind) {
@@ -22288,7 +22566,7 @@ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
22288
22566
  affectedParagraphIndexes: []
22289
22567
  };
22290
22568
  }
22291
- const catalog = ensureNumberingCatalog(working.numbering);
22569
+ const catalog = cloneNumberingCatalog(working.numbering);
22292
22570
  const allAlreadyKind = normalizedIndexes.every((index) => {
22293
22571
  const paragraph = paragraphs[index];
22294
22572
  return paragraph.numbering ? getListKind(catalog, paragraph.numbering.numberingInstanceId) === kind : false;
@@ -22303,7 +22581,7 @@ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
22303
22581
  affectedParagraphIndexes: normalizedIndexes
22304
22582
  };
22305
22583
  }
22306
- const numberingInstanceId = findAdjacentCompatibleInstance(paragraphs, catalog, normalizedIndexes[0], kind) ?? ensureDefaultInstance(catalog, kind);
22584
+ const numberingInstanceId = findAdjacentCompatibleInstance(paragraphs, catalog, normalizedIndexes[0], kind) ?? ensureDefaultListInstance(catalog, kind);
22307
22585
  for (const index of normalizedIndexes) {
22308
22586
  const paragraph = paragraphs[index];
22309
22587
  paragraph.numbering = {
@@ -22468,23 +22746,6 @@ function sortJson(value) {
22468
22746
  }
22469
22747
  return value;
22470
22748
  }
22471
- function ensureDefaultInstance(catalog, kind) {
22472
- const existing = Object.values(catalog.instances).find(
22473
- (instance) => getListKind(catalog, instance.numberingInstanceId) === kind
22474
- );
22475
- if (existing) {
22476
- return existing.numberingInstanceId;
22477
- }
22478
- const abstractNumberingId = createAbstractNumberingId(catalog);
22479
- catalog.abstractDefinitions[abstractNumberingId] = kind === "bulleted" ? createDefaultBulletedDefinition(abstractNumberingId) : createDefaultNumberedDefinition(abstractNumberingId);
22480
- const numberingInstanceId = createNumberingInstanceId(catalog);
22481
- catalog.instances[numberingInstanceId] = {
22482
- numberingInstanceId,
22483
- abstractNumberingId,
22484
- overrides: []
22485
- };
22486
- return numberingInstanceId;
22487
- }
22488
22749
  function findAdjacentCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
22489
22750
  const previous = paragraphs[fromIndex - 1];
22490
22751
  if (previous?.numbering) {
@@ -22507,69 +22768,6 @@ function findPreviousCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
22507
22768
  }
22508
22769
  return void 0;
22509
22770
  }
22510
- function getListKind(catalog, numberingInstanceId) {
22511
- const instance = catalog.instances[numberingInstanceId];
22512
- const definition = instance ? catalog.abstractDefinitions[instance.abstractNumberingId] : void 0;
22513
- const levelZero = definition?.levels.find((level) => level.level === 0);
22514
- if (!levelZero) {
22515
- return void 0;
22516
- }
22517
- return levelZero.format === "bullet" ? "bulleted" : "numbered";
22518
- }
22519
- function mergeOverride(overrides, nextOverride) {
22520
- const filtered = overrides.filter((override) => override.level !== nextOverride.level);
22521
- filtered.push(nextOverride);
22522
- return filtered.sort((left, right) => left.level - right.level);
22523
- }
22524
- function createDefaultNumberedDefinition(abstractNumberingId) {
22525
- return {
22526
- abstractNumberingId,
22527
- levels: [
22528
- { level: 0, format: "decimal", text: "%1." },
22529
- { level: 1, format: "decimal", text: "%1.%2." },
22530
- { level: 2, format: "lowerLetter", text: "(%3)" },
22531
- { level: 3, format: "lowerRoman", text: "(%4)" },
22532
- { level: 4, format: "decimal", text: "%5." },
22533
- { level: 5, format: "lowerLetter", text: "(%6)" },
22534
- { level: 6, format: "lowerRoman", text: "(%7)" },
22535
- { level: 7, format: "decimal", text: "%8." },
22536
- { level: 8, format: "lowerLetter", text: "(%9)" }
22537
- ]
22538
- };
22539
- }
22540
- function createDefaultBulletedDefinition(abstractNumberingId) {
22541
- return {
22542
- abstractNumberingId,
22543
- levels: [
22544
- { level: 0, format: "bullet", text: "\u2022" },
22545
- { level: 1, format: "bullet", text: "o" },
22546
- { level: 2, format: "bullet", text: "\u25A0" },
22547
- { level: 3, format: "bullet", text: "\u2022" },
22548
- { level: 4, format: "bullet", text: "o" },
22549
- { level: 5, format: "bullet", text: "\u25A0" },
22550
- { level: 6, format: "bullet", text: "\u2022" },
22551
- { level: 7, format: "bullet", text: "o" },
22552
- { level: 8, format: "bullet", text: "\u25A0" }
22553
- ]
22554
- };
22555
- }
22556
- function createAbstractNumberingId(catalog) {
22557
- let index = 1;
22558
- while (catalog.abstractDefinitions[`abstract-num:generated-${index}`]) {
22559
- index += 1;
22560
- }
22561
- return `abstract-num:generated-${index}`;
22562
- }
22563
- function createNumberingInstanceId(catalog) {
22564
- let index = 1;
22565
- while (catalog.instances[`num:generated-${index}`]) {
22566
- index += 1;
22567
- }
22568
- return `num:generated-${index}`;
22569
- }
22570
- function ensureNumberingCatalog(value) {
22571
- return structuredClone(value);
22572
- }
22573
22771
  function cloneEnvelope(document2, timestamp) {
22574
22772
  return {
22575
22773
  ...structuredClone(document2),
@@ -33916,7 +34114,7 @@ function applyFragmentInsert(document2, selection, fragment, context) {
33916
34114
  );
33917
34115
  workingDocument = collapseResult.document;
33918
34116
  workingSelection = collapseResult.selection;
33919
- if (context.textTarget?.kind === "table-paragraph") {
34117
+ if (context.textTarget?.kind === "table-paragraph" || context.textTarget?.kind === "text-leaf") {
33920
34118
  workingContext = {
33921
34119
  ...context,
33922
34120
  textTarget: {
@@ -33938,11 +34136,11 @@ function applyFragmentInsert(document2, selection, fragment, context) {
33938
34136
  selection
33939
34137
  };
33940
34138
  }
33941
- const targetedTablePath = workingContext.textTarget?.kind === "table-paragraph" ? workingContext.textTarget.blockPath : void 0;
33942
- if (targetedTablePath) {
34139
+ const targetedBlockPath = workingContext.textTarget?.kind === "table-paragraph" || workingContext.textTarget?.kind === "text-leaf" ? workingContext.textTarget.blockPath : void 0;
34140
+ if (targetedBlockPath) {
33943
34141
  const targeted = insertFragmentBlocksAfterPath(
33944
34142
  splitResult.document,
33945
- targetedTablePath,
34143
+ targetedBlockPath,
33946
34144
  fragment.blocks
33947
34145
  );
33948
34146
  if (targeted) {
@@ -43194,7 +43392,7 @@ function emptyCompatibilityReport() {
43194
43392
  }
43195
43393
 
43196
43394
  // src/runtime/debug/runtime-debug-facet.ts
43197
- function createRuntimeDebugFacet(getRuntime, bus) {
43395
+ function createRuntimeDebugFacet(getRuntime, bus, options = {}) {
43198
43396
  return {
43199
43397
  bus,
43200
43398
  getSnapshot(query) {
@@ -43212,7 +43410,318 @@ function createRuntimeDebugFacet(getRuntime, bus) {
43212
43410
  },
43213
43411
  getChannels() {
43214
43412
  return bus.getChannels();
43413
+ },
43414
+ getHotEditTraces() {
43415
+ return options.getHotEditTraces?.() ?? [];
43416
+ }
43417
+ };
43418
+ }
43419
+
43420
+ // src/runtime/hot-edit/hot-edit-trace.ts
43421
+ var HOT_EDIT_TRACE_LIMIT = 64;
43422
+ var HotEditTraceRecorder = class {
43423
+ traces = [];
43424
+ sequence = 0;
43425
+ begin(input) {
43426
+ this.sequence += 1;
43427
+ return {
43428
+ sequence: this.sequence,
43429
+ commandType: input.commandType,
43430
+ startedAtUtc: input.nowUtc,
43431
+ startedAtMs: nowMs(),
43432
+ startCounters: input.counters.snapshot()
43433
+ };
43434
+ }
43435
+ complete(pending, input) {
43436
+ const endCounters = input.counters.snapshot();
43437
+ const refreshAllCount = counterDelta(pending.startCounters, endCounters, "refresh.all");
43438
+ const patchHitCount = counterDelta(pending.startCounters, endCounters, "surface.localText.patchHit");
43439
+ const patchBudgetFallbackCount = counterDelta(
43440
+ pending.startCounters,
43441
+ endCounters,
43442
+ "surface.localText.patchBudgetFallback"
43443
+ );
43444
+ const boundedEditableTargetBuildCount = counterDelta(
43445
+ pending.startCounters,
43446
+ endCounters,
43447
+ "runtime.editableTargets.boundedBuilds"
43448
+ );
43449
+ const tier = refineTier(input.tier, {
43450
+ refreshAllCount,
43451
+ patchHitCount,
43452
+ patchBudgetFallbackCount,
43453
+ boundedEditableTargetBuildCount
43454
+ });
43455
+ const trace = {
43456
+ sequence: pending.sequence,
43457
+ startedAtUtc: pending.startedAtUtc,
43458
+ commandType: pending.commandType,
43459
+ tier,
43460
+ patchMissReason: input.patchMissReason,
43461
+ totalDurationUs: Math.max(0, Math.round((nowMs() - pending.startedAtMs) * 1e3)),
43462
+ refreshAllCount,
43463
+ patchHitCount,
43464
+ patchBudgetFallbackCount,
43465
+ boundedEditableTargetBuildCount
43466
+ };
43467
+ this.traces.push(trace);
43468
+ if (this.traces.length > HOT_EDIT_TRACE_LIMIT) {
43469
+ this.traces.splice(0, this.traces.length - HOT_EDIT_TRACE_LIMIT);
43470
+ }
43471
+ input.counters.increment(`hotEdit.tier.${trace.tier}`);
43472
+ if (trace.patchMissReason !== "none") {
43473
+ input.counters.increment(`hotEdit.patchMiss.${trace.patchMissReason}`);
43474
+ }
43475
+ return trace;
43476
+ }
43477
+ getTraces() {
43478
+ return Object.freeze([...this.traces]);
43479
+ }
43480
+ clear() {
43481
+ this.traces.splice(0, this.traces.length);
43482
+ }
43483
+ };
43484
+ function refineTier(requested, counters) {
43485
+ if (requested === "blocked") return requested;
43486
+ if (counters.refreshAllCount > 0) return "full-refresh";
43487
+ if (counters.patchBudgetFallbackCount > 0 || counters.boundedEditableTargetBuildCount > 0) {
43488
+ return "bounded-projection";
43489
+ }
43490
+ if (counters.patchHitCount > 0) return "patch";
43491
+ return requested;
43492
+ }
43493
+ function counterDelta(start, end, key) {
43494
+ return (end[key] ?? 0) - (start[key] ?? 0);
43495
+ }
43496
+ function nowMs() {
43497
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
43498
+ }
43499
+
43500
+ // src/runtime/hot-edit/surface-local-patcher.ts
43501
+ function patchSurfaceTextSegment(surface, patch) {
43502
+ const delta = patch.insertedText.length - Math.max(0, patch.to - patch.from);
43503
+ let patched = false;
43504
+ const blocks = surface.blocks.map((block) => {
43505
+ const result = patchBlock(block, patch, delta);
43506
+ if (result.patched) patched = true;
43507
+ return result.block;
43508
+ });
43509
+ if (!patched) {
43510
+ return { status: "miss", reason: "segment-not-found" };
43511
+ }
43512
+ return {
43513
+ status: "patched",
43514
+ surface: {
43515
+ ...surface,
43516
+ storySize: surface.storySize + delta,
43517
+ plainText: surface.plainText.slice(0, patch.from) + patch.insertedText + surface.plainText.slice(patch.to),
43518
+ blocks
43519
+ }
43520
+ };
43521
+ }
43522
+ function patchBlock(block, patch, delta) {
43523
+ if (patch.to < block.from) return { block, patched: false };
43524
+ if (patch.from > block.to) {
43525
+ return { block: shiftBlock(block, delta), patched: false };
43526
+ }
43527
+ switch (block.kind) {
43528
+ case "paragraph":
43529
+ return patchParagraph(block, patch, delta);
43530
+ case "sdt_block": {
43531
+ let patched = false;
43532
+ const children = block.children.map((child) => {
43533
+ const result = patchBlock(child, patch, delta);
43534
+ patched ||= result.patched;
43535
+ return result.block;
43536
+ });
43537
+ return {
43538
+ block: patched ? { ...block, to: block.to + delta, children } : block,
43539
+ patched
43540
+ };
43541
+ }
43542
+ case "table": {
43543
+ let patched = false;
43544
+ const rows = block.rows.map((row2) => ({
43545
+ ...row2,
43546
+ cells: row2.cells.map((cell) => ({
43547
+ ...cell,
43548
+ content: cell.content.map((child) => {
43549
+ const result = patchBlock(child, patch, delta);
43550
+ patched ||= result.patched;
43551
+ return result.block;
43552
+ })
43553
+ }))
43554
+ }));
43555
+ return {
43556
+ block: patched ? { ...block, to: block.to + delta, rows } : block,
43557
+ patched
43558
+ };
43559
+ }
43560
+ case "opaque_block":
43561
+ return { block, patched: false };
43562
+ }
43563
+ }
43564
+ function patchParagraph(block, patch, delta) {
43565
+ if (patch.from < block.from || patch.to > block.to) {
43566
+ return { block, patched: false };
43567
+ }
43568
+ const segmentIndex = block.segments.findIndex(
43569
+ (segment2) => segment2.kind === "text" && patch.from >= segment2.from && patch.to <= segment2.to
43570
+ );
43571
+ if (segmentIndex < 0) return { block, patched: false };
43572
+ const segment = block.segments[segmentIndex];
43573
+ if (segment.kind !== "text") return { block, patched: false };
43574
+ const localFrom = patch.from - segment.from;
43575
+ const localTo = patch.to - segment.from;
43576
+ const segments = block.segments.map((candidate, index) => {
43577
+ if (index < segmentIndex) return candidate;
43578
+ if (index === segmentIndex) {
43579
+ return {
43580
+ ...segment,
43581
+ text: segment.text.slice(0, localFrom) + patch.insertedText + segment.text.slice(localTo),
43582
+ to: segment.to + delta
43583
+ };
43584
+ }
43585
+ return shiftInlineSegment(candidate, delta);
43586
+ });
43587
+ return {
43588
+ block: {
43589
+ ...block,
43590
+ to: block.to + delta,
43591
+ segments
43592
+ },
43593
+ patched: true
43594
+ };
43595
+ }
43596
+ function shiftBlock(block, delta) {
43597
+ if (delta === 0) return block;
43598
+ switch (block.kind) {
43599
+ case "paragraph":
43600
+ return {
43601
+ ...block,
43602
+ from: block.from + delta,
43603
+ to: block.to + delta,
43604
+ segments: block.segments.map((segment) => shiftInlineSegment(segment, delta))
43605
+ };
43606
+ case "sdt_block":
43607
+ return {
43608
+ ...block,
43609
+ from: block.from + delta,
43610
+ to: block.to + delta,
43611
+ children: block.children.map((child) => shiftBlock(child, delta))
43612
+ };
43613
+ case "table":
43614
+ return {
43615
+ ...block,
43616
+ from: block.from + delta,
43617
+ to: block.to + delta,
43618
+ rows: block.rows.map((row2) => ({
43619
+ ...row2,
43620
+ cells: row2.cells.map((cell) => ({
43621
+ ...cell,
43622
+ content: cell.content.map((child) => shiftBlock(child, delta))
43623
+ }))
43624
+ }))
43625
+ };
43626
+ case "opaque_block":
43627
+ return {
43628
+ ...block,
43629
+ from: block.from + delta,
43630
+ to: block.to + delta
43631
+ };
43632
+ }
43633
+ }
43634
+ function shiftInlineSegment(segment, delta) {
43635
+ if (delta === 0) return segment;
43636
+ return {
43637
+ ...segment,
43638
+ from: segment.from + delta,
43639
+ to: segment.to + delta
43640
+ };
43641
+ }
43642
+
43643
+ // src/runtime/hot-edit/hot-edit-profiler.ts
43644
+ var HEAVY_REVIEW_ITEM_THRESHOLD = 24;
43645
+ var DENSE_BLOCK_NODE_THRESHOLD = 256;
43646
+ function deriveHotEditDocumentProfile(document2) {
43647
+ const blocks = document2.content.children ?? [];
43648
+ let tableBlockCount = 0;
43649
+ let maxNestedSurfaceNodesPerBlock = 0;
43650
+ for (const block of blocks) {
43651
+ if (block.type === "table") tableBlockCount += 1;
43652
+ maxNestedSurfaceNodesPerBlock = Math.max(
43653
+ maxNestedSurfaceNodesPerBlock,
43654
+ countBlockNodes(block)
43655
+ );
43656
+ }
43657
+ const commentCount = Object.keys(document2.review.comments ?? {}).length;
43658
+ const revisionCount = Object.keys(document2.review.revisions ?? {}).length;
43659
+ const secondaryStoryBlockCount = countSecondaryStoryBlocks(document2);
43660
+ return {
43661
+ blockCount: blocks.length,
43662
+ tableBlockCount,
43663
+ maxNestedSurfaceNodesPerBlock,
43664
+ commentCount,
43665
+ revisionCount,
43666
+ secondaryStoryBlockCount,
43667
+ hasHeavyReview: commentCount + revisionCount >= HEAVY_REVIEW_ITEM_THRESHOLD,
43668
+ hasDenseTables: tableBlockCount > 0 && maxNestedSurfaceNodesPerBlock > DENSE_BLOCK_NODE_THRESHOLD
43669
+ };
43670
+ }
43671
+ function countBlockNodes(block) {
43672
+ const value = block;
43673
+ let total = 1;
43674
+ if (Array.isArray(value.children)) {
43675
+ total += value.children.length;
43676
+ for (const child of value.children) {
43677
+ if (isBlockLike(child)) total += countBlockNodes(child);
43678
+ }
43679
+ }
43680
+ if (Array.isArray(value.rows)) {
43681
+ for (const row2 of value.rows) {
43682
+ total += 1;
43683
+ for (const cell of row2.cells ?? []) {
43684
+ total += 1;
43685
+ for (const child of cell.children ?? []) {
43686
+ total += countBlockNodes(child);
43687
+ }
43688
+ }
43215
43689
  }
43690
+ }
43691
+ return total;
43692
+ }
43693
+ function isBlockLike(value) {
43694
+ return Boolean(value && typeof value === "object" && "type" in value);
43695
+ }
43696
+ function countSecondaryStoryBlocks(document2) {
43697
+ const subParts = document2.subParts;
43698
+ if (!subParts) return 0;
43699
+ let count = 0;
43700
+ for (const value of Object.values(subParts)) {
43701
+ count += countBlocksInUnknownStory(value);
43702
+ }
43703
+ return count;
43704
+ }
43705
+ function countBlocksInUnknownStory(value) {
43706
+ if (!value || typeof value !== "object") return 0;
43707
+ const candidate = value;
43708
+ if (Array.isArray(candidate.children)) return candidate.children.length;
43709
+ if (Array.isArray(candidate.content?.children)) return candidate.content.children.length;
43710
+ return Object.values(value).reduce((total, entry) => total + countBlocksInUnknownStory(entry), 0);
43711
+ }
43712
+
43713
+ // src/runtime/hot-edit/hot-edit-policy.ts
43714
+ var DEFAULT_MAX_SHIFTED_SURFACE_NODES = 5e3;
43715
+ var DEFAULT_MAX_SHIFTED_NODES_PER_BLOCK = 256;
43716
+ var DEFAULT_SELECTION_CORRIDOR_BLOCK_RADIUS = 8;
43717
+ var HEAVY_DOCUMENT_SELECTION_CORRIDOR_BLOCK_RADIUS = 12;
43718
+ function resolveHotEditPolicy(profile) {
43719
+ const complexGeometry = profile.hasDenseTables || profile.secondaryStoryBlockCount > 0;
43720
+ return {
43721
+ maxShiftedSurfaceNodes: DEFAULT_MAX_SHIFTED_SURFACE_NODES,
43722
+ maxShiftedNodesPerBlock: DEFAULT_MAX_SHIFTED_NODES_PER_BLOCK,
43723
+ selectionCorridorBlockRadius: complexGeometry ? HEAVY_DOCUMENT_SELECTION_CORRIDOR_BLOCK_RADIUS : DEFAULT_SELECTION_CORRIDOR_BLOCK_RADIUS,
43724
+ preferBoundedProjectionForDenseTails: profile.hasDenseTables
43216
43725
  };
43217
43726
  }
43218
43727
 
@@ -46755,6 +47264,12 @@ function resolveScopeRange(entry, handle, positionMap) {
46755
47264
  if (inlineRange) return inlineRange;
46756
47265
  return positionMap.blocks.get(entry.blockIndex) ?? null;
46757
47266
  }
47267
+ case "image": {
47268
+ const key = `${entry.blockIndex}:${entry.inlineIndex}`;
47269
+ const inlineRange = positionMap.inlines.get(key);
47270
+ if (inlineRange) return inlineRange;
47271
+ return positionMap.blocks.get(entry.blockIndex) ?? null;
47272
+ }
46758
47273
  case "comment-thread":
46759
47274
  return anchorToRange(entry.thread.anchor);
46760
47275
  case "revision":
@@ -46893,6 +47408,11 @@ function deriveReplaceability(kind, provenance) {
46893
47408
  level: "preserve-only",
46894
47409
  reason: "field-result-is-computed-preserve-only"
46895
47410
  };
47411
+ case "image":
47412
+ return {
47413
+ level: "preserve-only",
47414
+ reason: "image-object-command-required"
47415
+ };
46896
47416
  case "comment-thread":
46897
47417
  return {
46898
47418
  level: "preserve-only",
@@ -47597,6 +48117,55 @@ function compileHeadingScope(entry, options = {}) {
47597
48117
  };
47598
48118
  }
47599
48119
 
48120
+ // src/runtime/scopes/scope-kinds/image.ts
48121
+ function imageAltText(image) {
48122
+ if (image.type === "image") return image.altText ?? "";
48123
+ return image.anchor.docPr?.descr ?? image.anchor.docPr?.name ?? "";
48124
+ }
48125
+ function imageMediaId(image) {
48126
+ if (image.type === "image") return image.mediaId;
48127
+ return image.content.type === "picture" ? image.content.mediaId : void 0;
48128
+ }
48129
+ function imageDisplay(image) {
48130
+ if (image.type === "image") return image.display;
48131
+ return image.anchor.display;
48132
+ }
48133
+ function imageSourceKind(image) {
48134
+ return image.type === "image" ? "legacy-image" : "drawing-picture";
48135
+ }
48136
+ function compileImageScope(entry) {
48137
+ const { handle, image } = entry;
48138
+ const altText = imageAltText(image);
48139
+ const mediaId = imageMediaId(image);
48140
+ const display = imageDisplay(image);
48141
+ const sourceKind = imageSourceKind(image);
48142
+ return {
48143
+ handle,
48144
+ kind: "image",
48145
+ classifications: entry.classifications,
48146
+ content: {
48147
+ text: altText,
48148
+ excerpt: buildExcerpt(altText),
48149
+ authority: "structural-summary"
48150
+ },
48151
+ formatting: {},
48152
+ layout: display ? { flowKind: display } : {},
48153
+ geometry: {},
48154
+ workflow: { scopeIds: [], effectiveMode: "edit" },
48155
+ replaceability: deriveReplaceability("image", handle.provenance),
48156
+ audit: {
48157
+ source: "runtime",
48158
+ derivedFrom: [
48159
+ "canonical",
48160
+ `image-source:${sourceKind}`,
48161
+ ...mediaId ? [`media-id:${mediaId}`] : []
48162
+ ],
48163
+ confidence: "medium"
48164
+ },
48165
+ partial: true
48166
+ };
48167
+ }
48168
+
47600
48169
  // src/runtime/scopes/scope-kinds/list-item.ts
47601
48170
  function compileListItemScope(entry, options = {}) {
47602
48171
  const { handle, paragraph } = entry;
@@ -48185,6 +48754,8 @@ function compileScope(entry, optionsOrCatalog) {
48185
48754
  });
48186
48755
  case "field":
48187
48756
  return compileFieldScope(entry);
48757
+ case "image":
48758
+ return compileImageScope(entry);
48188
48759
  case "comment-thread":
48189
48760
  return compileCommentThreadScope(entry);
48190
48761
  case "revision":
@@ -48373,6 +48944,44 @@ function enumerateFieldsInParagraph(paragraph, blockIndex, documentId, parentSco
48373
48944
  }
48374
48945
  return out;
48375
48946
  }
48947
+ function isImageInline(child) {
48948
+ return child.type === "image" || child.type === "drawing_frame" && child.content.type === "picture";
48949
+ }
48950
+ function enumerateImagesInParagraph(paragraph, blockIndex, documentId, parentScopeId) {
48951
+ const out = [];
48952
+ for (let i = 0; i < paragraph.children.length; i += 1) {
48953
+ const child = paragraph.children[i];
48954
+ if (!isImageInline(child)) continue;
48955
+ const semanticPath = [
48956
+ "body",
48957
+ "paragraph",
48958
+ String(blockIndex),
48959
+ "image",
48960
+ String(i)
48961
+ ];
48962
+ const scopeId = `image:${blockIndex}:${i}`;
48963
+ const handle = {
48964
+ scopeId,
48965
+ documentId,
48966
+ storyTarget: MAIN_STORY2,
48967
+ semanticPath,
48968
+ parentScopeId,
48969
+ stableRef: { kind: "semantic-path", value: semanticPath.join("/") },
48970
+ provenance: "derived",
48971
+ rangePrecision: "canonical"
48972
+ };
48973
+ out.push({
48974
+ kind: "image",
48975
+ handle,
48976
+ image: child,
48977
+ paragraph,
48978
+ blockIndex,
48979
+ inlineIndex: i,
48980
+ classifications: Object.freeze([])
48981
+ });
48982
+ }
48983
+ return out;
48984
+ }
48376
48985
  function enumerateCommentThreads(document2, documentId) {
48377
48986
  const review = document2.review;
48378
48987
  const comments = review?.comments;
@@ -48503,6 +49112,8 @@ function enumerateScopes(document2, inputs = {}) {
48503
49112
  });
48504
49113
  const fields = enumerateFieldsInParagraph(block, index, documentId, scopeId);
48505
49114
  for (const field of fields) results.push(field);
49115
+ const images = enumerateImagesInParagraph(block, index, documentId, scopeId);
49116
+ for (const image of images) results.push(image);
48506
49117
  continue;
48507
49118
  }
48508
49119
  if (block.type === "table") {
@@ -48892,6 +49503,15 @@ var LIST_TEXT_TARGET_KINDS = /* @__PURE__ */ new Set([
48892
49503
  "sdt-paragraph-text",
48893
49504
  "secondary-story-paragraph-text"
48894
49505
  ]);
49506
+ var OBJECT_COMMAND_INTENTS = /* @__PURE__ */ new Set([
49507
+ "image-layout",
49508
+ "image-frame",
49509
+ "chart-edit",
49510
+ "custom-xml-update",
49511
+ "embedded-content-update",
49512
+ "opaque-content-preserve",
49513
+ "object-edit"
49514
+ ]);
48895
49515
  function freezeList(values) {
48896
49516
  return Object.freeze([...values]);
48897
49517
  }
@@ -49436,6 +50056,35 @@ function listStructureCapability(scope, context) {
49436
50056
  ]
49437
50057
  );
49438
50058
  }
50059
+ function objectEditCapability(context) {
50060
+ const objectTargets = (context?.editableTargets?.entries ?? []).filter(
50061
+ (entry) => entry.kind === "object-anchor" || entry.kind === "custom-xml-content" || entry.kind === "opaque-content" || entry.commandFamily === "object" || entry.commandFamily === "preserve-only-refusal" || entry.runtimeCommand.intents.some((intent) => OBJECT_COMMAND_INTENTS.has(intent))
50062
+ );
50063
+ const supportedTargets = objectTargets.filter(
50064
+ (entry) => entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.some((intent) => OBJECT_COMMAND_INTENTS.has(intent))
50065
+ );
50066
+ if (supportedTargets.length > 0) {
50067
+ return supportedCommand(
50068
+ "compile-supported:object-edit:editable-target",
50069
+ supportedTargets
50070
+ );
50071
+ }
50072
+ if (objectTargets.length > 0) {
50073
+ const blockers = commandTargetBlockers(objectTargets);
50074
+ return blocked(
50075
+ "compile-blocked:object-edit:target-ref-blocked",
50076
+ blockers.length > 0 ? blockers : ["compile-blocked:object-edit:target-ref-blocked"]
50077
+ );
50078
+ }
50079
+ return unsupported(
50080
+ "compile-unsupported:object-edit:no-target-family",
50081
+ [
50082
+ "compile-unsupported:object-edit:no-target-family",
50083
+ "capability:object-edit:l02-object-target-required",
50084
+ "capability:object-edit:l07-command-support-required"
50085
+ ]
50086
+ );
50087
+ }
49439
50088
  function deriveScopeCapabilities(scope, context = {}) {
49440
50089
  return {
49441
50090
  canReplaceText: replaceTextCapability(scope, context),
@@ -49452,7 +50101,8 @@ function deriveScopeCapabilities(scope, context = {}) {
49452
50101
  canEditTableStructure: tableStructureCapability(scope, context),
49453
50102
  canUseTableContinuationEvidence: tableContinuationEvidenceCapability(scope, context),
49454
50103
  canEditListText: listTextCapability(scope, context),
49455
- canEditListStructure: listStructureCapability(scope, context)
50104
+ canEditListStructure: listStructureCapability(scope, context),
50105
+ canEditObject: objectEditCapability(context)
49456
50106
  };
49457
50107
  }
49458
50108
 
@@ -49724,6 +50374,11 @@ function tokensForScope(entry) {
49724
50374
  { kind: "row", index: entry.rowIndex },
49725
50375
  { kind: "cell", index: entry.cellIndex }
49726
50376
  ]);
50377
+ case "image":
50378
+ return Object.freeze([
50379
+ { kind: "block", index: entry.blockIndex },
50380
+ { kind: "inline", index: entry.inlineIndex }
50381
+ ]);
49727
50382
  default:
49728
50383
  return null;
49729
50384
  }
@@ -50471,6 +51126,64 @@ function deriveScopeEditableTargetEvidence(document2, scope, entry, options = {}
50471
51126
  };
50472
51127
  }
50473
51128
 
51129
+ // src/runtime/scopes/object-evidence.ts
51130
+ var OBJECT_INTENTS = /* @__PURE__ */ new Set([
51131
+ "image-layout",
51132
+ "image-frame",
51133
+ "chart-edit",
51134
+ "custom-xml-update",
51135
+ "embedded-content-update",
51136
+ "opaque-content-preserve",
51137
+ "object-edit",
51138
+ "preserve-only-refusal"
51139
+ ]);
51140
+ function unique2(values) {
51141
+ return Object.freeze([...new Set(values.filter((value) => value.length > 0))]);
51142
+ }
51143
+ function isObjectTarget(entry) {
51144
+ return entry.object !== void 0 || entry.kind === "object-anchor" || entry.kind === "custom-xml-content" || entry.kind === "opaque-content" || entry.commandFamily === "object" || entry.runtimeCommand.intents.some((intent) => OBJECT_INTENTS.has(intent));
51145
+ }
51146
+ function blockersFor(entry) {
51147
+ return unique2([
51148
+ ...entry.posture.blockers,
51149
+ ...entry.runtimeCommand.blockers ?? [],
51150
+ ...entry.runtimeTextCommand.blockers ?? [],
51151
+ ...(entry.workflowBlockers ?? []).flatMap((blocker2) => [
51152
+ blocker2.blocker,
51153
+ blocker2.refusalId
51154
+ ]),
51155
+ entry.runtimeCommand.status === "blocked" ? entry.runtimeCommand.reason : ""
51156
+ ]);
51157
+ }
51158
+ function projectEntry2(entry) {
51159
+ const blockers = blockersFor(entry);
51160
+ return {
51161
+ targetKey: entry.targetKey,
51162
+ kind: entry.kind,
51163
+ ...entry.object?.objectKind ? { objectKind: entry.object.objectKind } : {},
51164
+ relation: entry.relation,
51165
+ commandFamily: entry.commandFamily,
51166
+ editability: entry.editability,
51167
+ ...entry.sourceRef ? { sourceRef: entry.sourceRef } : {},
51168
+ ...entry.object ? { object: entry.object } : {},
51169
+ runtimeCommand: entry.runtimeCommand,
51170
+ blockers,
51171
+ ...entry.posture.preserveOnly ? { preserveOnly: true } : {}
51172
+ };
51173
+ }
51174
+ function deriveScopeObjectEvidence(editableTargets) {
51175
+ const entries = Object.freeze(
51176
+ [...editableTargets?.entries ?? []].filter(isObjectTarget).map(projectEntry2).sort((left, right) => left.targetKey.localeCompare(right.targetKey))
51177
+ );
51178
+ const blockers = unique2(entries.flatMap((entry) => [...entry.blockers]));
51179
+ return {
51180
+ status: entries.length > 0 ? "present" : "none",
51181
+ count: entries.length,
51182
+ blockers,
51183
+ entries
51184
+ };
51185
+ }
51186
+
50474
51187
  // src/runtime/scopes/table-evidence.ts
50475
51188
  function isTableFamilyEntry(entry) {
50476
51189
  return entry?.kind === "table" || entry?.kind === "table-row" || entry?.kind === "table-cell";
@@ -51040,7 +51753,7 @@ function deriveScopeGeometryEvidence(scopeId, provider, context) {
51040
51753
  function freezeList2(values) {
51041
51754
  return values ? Object.freeze([...values]) : void 0;
51042
51755
  }
51043
- function unique2(values) {
51756
+ function unique3(values) {
51044
51757
  return Object.freeze([...new Set(values)]);
51045
51758
  }
51046
51759
  function parseTableFamilyScopeId2(scopeId) {
@@ -51070,7 +51783,7 @@ function candidateTableBlockIds(blockIndex, mapped) {
51070
51783
  const mappedId = mapped?.get(blockIndex);
51071
51784
  if (mappedId) ids.push(mappedId);
51072
51785
  ids.push(`table-${blockIndex}`, `table:${blockIndex}`, `block-${blockIndex}`);
51073
- return unique2(ids);
51786
+ return unique3(ids);
51074
51787
  }
51075
51788
  function rowInFragment(fragment, rowIndex) {
51076
51789
  const range = fragment.tableRowRange;
@@ -51107,19 +51820,19 @@ function projectTableFramePage(fragment) {
51107
51820
  ...fragment.tableRowRange ? { rowRange: { ...fragment.tableRowRange } } : {},
51108
51821
  ...fragment.continuation?.continuesFromPreviousPage !== void 0 ? { continuesFromPreviousPage: fragment.continuation.continuesFromPreviousPage } : {},
51109
51822
  ...fragment.continuation?.continuesToNextPage !== void 0 ? { continuesToNextPage: fragment.continuation.continuesToNextPage } : {},
51110
- ...repeated ? { repeatedHeaderRowIndexes: unique2(repeated) } : {},
51823
+ ...repeated ? { repeatedHeaderRowIndexes: unique3(repeated) } : {},
51111
51824
  ...splitRowCarry ? { splitRowCarry: Object.freeze(splitRowCarry.map((item) => ({ ...item }))) } : {},
51112
51825
  ...carry ? { verticalMergeCarry: Object.freeze(carry.map((item) => ({ ...item }))) } : {}
51113
51826
  };
51114
51827
  }
51115
51828
  function projectTableFrame(blockId, parsed, fragments) {
51116
- const pageIds = unique2(fragments.map((fragment) => fragment.pageId));
51117
- const pageSliceIds = unique2(fragments.map((fragment) => fragment.fragmentId));
51118
- const layoutObjectIds = unique2(
51829
+ const pageIds = unique3(fragments.map((fragment) => fragment.pageId));
51830
+ const pageSliceIds = unique3(fragments.map((fragment) => fragment.fragmentId));
51831
+ const layoutObjectIds = unique3(
51119
51832
  fragments.map((fragment) => fragment.layoutObject?.objectId).filter((objectId) => typeof objectId === "string" && objectId.length > 0)
51120
51833
  );
51121
51834
  const rowRangesByPage = Object.freeze(fragments.map(projectTableFramePage));
51122
- const repeatedHeaderRowIndexes = unique2(
51835
+ const repeatedHeaderRowIndexes = unique3(
51123
51836
  fragments.flatMap((fragment) => fragment.continuation?.repeatedHeaderRowIndexes ?? [])
51124
51837
  );
51125
51838
  const verticalMergeCarry = Object.freeze(
@@ -51144,7 +51857,7 @@ function projectTableFrame(blockId, parsed, fragments) {
51144
51857
  };
51145
51858
  }
51146
51859
  function continuationFromTableFrame(fragments) {
51147
- const pageIds = unique2(fragments.map((fragment) => fragment.pageId));
51860
+ const pageIds = unique3(fragments.map((fragment) => fragment.pageId));
51148
51861
  return {
51149
51862
  ...pageIds.length > 0 ? { pageIds } : {},
51150
51863
  pageCount: pageIds.length,
@@ -51442,6 +52155,7 @@ function composeEvidence(inputs) {
51442
52155
  ...editableTargets ? { editableTargets } : {},
51443
52156
  layout
51444
52157
  });
52158
+ const objects = deriveScopeObjectEvidence(editableTargets);
51445
52159
  return {
51446
52160
  formattingSummary: formattingSummaryOf(scope),
51447
52161
  reviewItemIds,
@@ -51452,6 +52166,7 @@ function composeEvidence(inputs) {
51452
52166
  ...adjacentGeometry ? { adjacentGeometry } : {},
51453
52167
  visualization: deriveScopeVisualization(scope),
51454
52168
  ...editableTargets ? { editableTargets } : {},
52169
+ objects,
51455
52170
  ...table ? { table } : {},
51456
52171
  contentControls,
51457
52172
  capabilities,
@@ -58679,7 +59394,7 @@ function shouldYield(scheduler, lastYieldAt) {
58679
59394
  const deadline = scheduler.frameDeadlineMs ?? DEFAULT_FRAME_DEADLINE_MS;
58680
59395
  return now3 - lastYieldAt >= deadline;
58681
59396
  }
58682
- function nowMs() {
59397
+ function nowMs2() {
58683
59398
  return typeof performance !== "undefined" ? performance.now() : Date.now();
58684
59399
  }
58685
59400
  function createLoadScheduler(options = {}) {
@@ -59690,7 +60405,7 @@ function parseNumberingXml(xml, context) {
59690
60405
  abstractDefinitions[abstractNumberingId] = {
59691
60406
  abstractNumberingId,
59692
60407
  ...context?.partPath !== void 0 ? { sourceRef: createNumberingSourceRef(context.partPath, "abstractNum", rawId, childXmlPath) } : {},
59693
- levels: readLevels(child),
60408
+ levels: readLevels(child, context, childXmlPath, rawId),
59694
60409
  ...nsid ? { nsid } : {},
59695
60410
  ...multiLevelType ? { multiLevelType } : {},
59696
60411
  ...tplc ? { tplc } : {},
@@ -59711,7 +60426,7 @@ function parseNumberingXml(xml, context) {
59711
60426
  numberingInstanceId,
59712
60427
  ...context?.partPath !== void 0 ? { sourceRef: createNumberingSourceRef(context.partPath, "num", rawId, childXmlPath) } : {},
59713
60428
  abstractNumberingId: toCanonicalAbstractNumberingId(rawAbstractId),
59714
- overrides: readOverrides(child)
60429
+ overrides: readOverrides(child, context, childXmlPath, rawId)
59715
60430
  };
59716
60431
  break;
59717
60432
  }
@@ -59732,6 +60447,16 @@ function createNumberingSourceRef(partPath, element, rawId, xmlPath) {
59732
60447
  ...xmlPath !== void 0 ? { xmlPath } : {}
59733
60448
  };
59734
60449
  }
60450
+ function createNumberingChildSourceRef(partPath, element, sourceIdSuffix, xmlPath) {
60451
+ if (partPath === void 0) return void 0;
60452
+ return {
60453
+ sourceId: `part:${partPath}#${sourceIdSuffix}`,
60454
+ partPath,
60455
+ storyKind: "numbering",
60456
+ element,
60457
+ ...xmlPath !== void 0 ? { xmlPath } : {}
60458
+ };
60459
+ }
59735
60460
  function readNumPicBullet(node, numPicBulletId, context, xmlPath) {
59736
60461
  let widthEmu;
59737
60462
  let heightEmu;
@@ -59808,18 +60533,29 @@ function toCanonicalAbstractNumberingId(value) {
59808
60533
  function toCanonicalNumberingInstanceId(value) {
59809
60534
  return value.startsWith("num:") ? value : `num:${value}`;
59810
60535
  }
59811
- function readLevels(abstractNode) {
60536
+ function readLevels(abstractNode, context, abstractXmlPath, rawAbstractId) {
59812
60537
  const levels = [];
60538
+ let levelOrdinal = 0;
59813
60539
  for (const child of abstractNode.children) {
59814
60540
  if (child.type !== "element" || localName(child.name) !== "lvl") {
59815
60541
  continue;
59816
60542
  }
60543
+ levelOrdinal += 1;
59817
60544
  const rawLevel = readStringAttr(child, "w:ilvl");
59818
60545
  const level = rawLevel === void 0 ? void 0 : parseInteger(rawLevel);
59819
60546
  if (level === void 0) {
59820
60547
  continue;
59821
60548
  }
59822
- const definition = readLevelDefinition(child, level);
60549
+ const definition = readLevelDefinition(
60550
+ child,
60551
+ level,
60552
+ createNumberingChildSourceRef(
60553
+ context?.partPath,
60554
+ "lvl",
60555
+ `abstractNum:${rawAbstractId}:lvl:${level}`,
60556
+ `${abstractXmlPath}/lvl[${levelOrdinal}]`
60557
+ )
60558
+ );
59823
60559
  if (!definition) {
59824
60560
  continue;
59825
60561
  }
@@ -59827,12 +60563,14 @@ function readLevels(abstractNode) {
59827
60563
  }
59828
60564
  return levels.sort((left, right) => left.level - right.level);
59829
60565
  }
59830
- function readOverrides(numNode) {
60566
+ function readOverrides(numNode, context, numXmlPath, rawNumId) {
59831
60567
  const overrides = [];
60568
+ let overrideOrdinal = 0;
59832
60569
  for (const child of numNode.children) {
59833
60570
  if (child.type !== "element" || localName(child.name) !== "lvlOverride") {
59834
60571
  continue;
59835
60572
  }
60573
+ overrideOrdinal += 1;
59836
60574
  const rawLevel = readStringAttr(child, "w:ilvl");
59837
60575
  const level = rawLevel === void 0 ? void 0 : parseInteger(rawLevel);
59838
60576
  if (level === void 0) {
@@ -59842,8 +60580,26 @@ function readOverrides(numNode) {
59842
60580
  const rawStart = startOverrideNode ? readStringAttr(startOverrideNode, "w:val") : void 0;
59843
60581
  const startAt = rawStart === void 0 ? void 0 : parseInteger(rawStart);
59844
60582
  const levelDefinitionNode = findChildElementOptional(child, "lvl");
59845
- const levelDefinition = levelDefinitionNode ? readLevelOverrideDefinition(levelDefinitionNode, level) : void 0;
60583
+ const overrideXmlPath = `${numXmlPath}/lvlOverride[${overrideOrdinal}]`;
60584
+ const levelDefinition = levelDefinitionNode ? readLevelOverrideDefinition(
60585
+ levelDefinitionNode,
60586
+ level,
60587
+ createNumberingChildSourceRef(
60588
+ context?.partPath,
60589
+ "lvl",
60590
+ `num:${rawNumId}:lvlOverride:${level}:lvl`,
60591
+ `${overrideXmlPath}/lvl[1]`
60592
+ )
60593
+ ) : void 0;
59846
60594
  overrides.push({
60595
+ ...context?.partPath !== void 0 ? {
60596
+ sourceRef: createNumberingChildSourceRef(
60597
+ context.partPath,
60598
+ "lvlOverride",
60599
+ `num:${rawNumId}:lvlOverride:${level}`,
60600
+ overrideXmlPath
60601
+ )
60602
+ } : {},
59847
60603
  level,
59848
60604
  ...startAt !== void 0 ? { startAt } : {},
59849
60605
  ...levelDefinition ? { levelDefinition } : {}
@@ -59851,7 +60607,7 @@ function readOverrides(numNode) {
59851
60607
  }
59852
60608
  return overrides.sort((left, right) => left.level - right.level);
59853
60609
  }
59854
- function readLevelDefinition(levelNode, fallbackLevel) {
60610
+ function readLevelDefinition(levelNode, fallbackLevel, sourceRef) {
59855
60611
  const rawLevel = readStringAttr(levelNode, "w:ilvl");
59856
60612
  const level = rawLevel === void 0 ? fallbackLevel : parseInteger(rawLevel);
59857
60613
  if (level === void 0) {
@@ -59881,6 +60637,7 @@ function readLevelDefinition(levelNode, fallbackLevel) {
59881
60637
  const lvlPicBulletNode = findChildElementOptional(levelNode, "lvlPicBulletId");
59882
60638
  const picBulletId = lvlPicBulletNode ? readStringAttr(lvlPicBulletNode, "w:val") : void 0;
59883
60639
  return {
60640
+ ...sourceRef ? { sourceRef } : {},
59884
60641
  level,
59885
60642
  format,
59886
60643
  text,
@@ -59894,7 +60651,7 @@ function readLevelDefinition(levelNode, fallbackLevel) {
59894
60651
  ...picBulletId !== void 0 ? { picBulletId } : {}
59895
60652
  };
59896
60653
  }
59897
- function readLevelOverrideDefinition(levelNode, fallbackLevel) {
60654
+ function readLevelOverrideDefinition(levelNode, fallbackLevel, sourceRef) {
59898
60655
  const rawLevel = readStringAttr(levelNode, "w:ilvl");
59899
60656
  const level = rawLevel === void 0 ? fallbackLevel : parseInteger(rawLevel);
59900
60657
  if (level === void 0) {
@@ -59928,6 +60685,7 @@ function readLevelOverrideDefinition(levelNode, fallbackLevel) {
59928
60685
  return void 0;
59929
60686
  }
59930
60687
  return {
60688
+ ...sourceRef ? { sourceRef } : {},
59931
60689
  level,
59932
60690
  ...startAt !== void 0 ? { startAt } : {},
59933
60691
  ...format !== void 0 ? { format } : {},
@@ -66121,7 +66879,7 @@ async function normalizeParsedTextDocumentAsync(document2, packagePartName = "/w
66121
66879
  };
66122
66880
  const children = [];
66123
66881
  let previousParagraph = false;
66124
- let lastYieldAt = nowMs();
66882
+ let lastYieldAt = nowMs2();
66125
66883
  for (let i = 0; i < document2.blocks.length; i += 1) {
66126
66884
  const block = document2.blocks[i];
66127
66885
  const normalizedBlocks = normalizeBlocks(block, state, packagePartName);
@@ -66134,7 +66892,7 @@ async function normalizeParsedTextDocumentAsync(document2, packagePartName = "/w
66134
66892
  }
66135
66893
  if (i > 0 && i % NORMALIZE_YIELD_STRIDE === 0 && shouldYield(scheduler, lastYieldAt)) {
66136
66894
  await scheduler.yield();
66137
- lastYieldAt = nowMs();
66895
+ lastYieldAt = nowMs2();
66138
66896
  }
66139
66897
  }
66140
66898
  const content = { type: "doc", children };
@@ -67505,8 +68263,6 @@ function sortJson2(value) {
67505
68263
 
67506
68264
  // src/runtime/document-runtime.ts
67507
68265
  var CANONICAL_BLOCK_REFS_SYMBOL2 = /* @__PURE__ */ Symbol.for("wre.canonical-block-refs");
67508
- var LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES = 5e3;
67509
- var LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK = 256;
67510
68266
  function getLocalTextPatchMetadata(mapping) {
67511
68267
  const metadata = mapping.metadata?.localTextPatch;
67512
68268
  if (!metadata || typeof metadata !== "object") {
@@ -67613,6 +68369,17 @@ function createDocumentRuntime(options) {
67613
68369
  const loadScheduler = options.loadScheduler ?? createLoadScheduler({ backendOverride: "sync" });
67614
68370
  let effectiveMarkupModeProvider;
67615
68371
  const perfCounters = new PerfCounters();
68372
+ const hotEditTraces = new HotEditTraceRecorder();
68373
+ let cachedHotEditPolicy = null;
68374
+ function getHotEditPolicy() {
68375
+ if (cachedHotEditPolicy?.document === state.document) {
68376
+ return cachedHotEditPolicy.policy;
68377
+ }
68378
+ const profile = deriveHotEditDocumentProfile(state.document);
68379
+ const policy = resolveHotEditPolicy(profile);
68380
+ cachedHotEditPolicy = { document: state.document, profile, policy };
68381
+ return policy;
68382
+ }
67616
68383
  let analyticsEmitScheduled = false;
67617
68384
  let analyticsEmitScheduleMode = "none";
67618
68385
  let deferNextContextAnalyticsEmit = false;
@@ -67684,7 +68451,6 @@ function createDocumentRuntime(options) {
67684
68451
  let viewportBlockRanges = null;
67685
68452
  let viewportRangesKey = serializeViewportRanges(viewportBlockRanges);
67686
68453
  let viewportBlocksPerPageEstimate = null;
67687
- const EDITING_CORRIDOR_BLOCK_RADIUS = 8;
67688
68454
  const getRuntimeForLayoutFacet = () => {
67689
68455
  if (!runtimeRef) {
67690
68456
  throw new Error("Document runtime viewport methods are not initialized");
@@ -68018,8 +68784,8 @@ function createDocumentRuntime(options) {
68018
68784
  return viewportBlockRanges;
68019
68785
  }
68020
68786
  const corridor = {
68021
- start: Math.max(0, caretBlockIndex - EDITING_CORRIDOR_BLOCK_RADIUS),
68022
- end: Math.min(previousSurface.blocks.length, caretBlockIndex + EDITING_CORRIDOR_BLOCK_RADIUS + 1)
68787
+ start: Math.max(0, caretBlockIndex - getHotEditPolicy().selectionCorridorBlockRadius),
68788
+ end: Math.min(previousSurface.blocks.length, caretBlockIndex + getHotEditPolicy().selectionCorridorBlockRadius + 1)
68023
68789
  };
68024
68790
  return normalizeViewportRanges([...viewportBlockRanges ?? [], corridor]);
68025
68791
  }
@@ -68100,8 +68866,12 @@ function createDocumentRuntime(options) {
68100
68866
  (block2) => block2.kind === "paragraph" && editFrom >= block2.from && editTo <= block2.to
68101
68867
  );
68102
68868
  if (blockIndex < 0) {
68103
- perfCounters.increment("surface.localText.patchMiss");
68104
- return null;
68869
+ return tryPatchNestedLocalTextSurface(
68870
+ previousSurface,
68871
+ editFrom,
68872
+ editTo,
68873
+ patch.insertedText
68874
+ );
68105
68875
  }
68106
68876
  const block = previousSurface.blocks[blockIndex];
68107
68877
  if (block.kind !== "paragraph") {
@@ -68176,6 +68946,34 @@ function createDocumentRuntime(options) {
68176
68946
  perfCounters.increment("surface.localText.total.us", Math.round((performance.now() - tTotal0) * 1e3));
68177
68947
  }
68178
68948
  }
68949
+ function tryPatchNestedLocalTextSurface(previousSurface, editFrom, editTo, insertedText) {
68950
+ const shiftBudget = estimateLocalTextPatchShiftBudget(previousSurface.blocks, 0);
68951
+ perfCounters.increment("surface.localText.shiftedBlocks", shiftBudget.shiftedBlocks);
68952
+ perfCounters.increment("surface.localText.shiftedNodes", shiftBudget.shiftedNodes);
68953
+ if (!shiftBudget.withinBudget) {
68954
+ perfCounters.increment("surface.localText.patchBudgetFallback");
68955
+ return null;
68956
+ }
68957
+ const patched = patchSurfaceTextSegment(previousSurface, {
68958
+ from: editFrom,
68959
+ to: editTo,
68960
+ insertedText
68961
+ });
68962
+ if (patched.status !== "patched") {
68963
+ perfCounters.increment("surface.localText.patchMiss");
68964
+ return null;
68965
+ }
68966
+ const refs = getSurfaceCanonicalBlockRefs(previousSurface);
68967
+ if (refs) {
68968
+ const nextRefs = state.document.content.children.map(
68969
+ (block, index) => block ?? refs[index] ?? null
68970
+ );
68971
+ attachSurfaceCanonicalBlockRefs(patched.surface, nextRefs);
68972
+ }
68973
+ perfCounters.increment("surface.localText.patchHit");
68974
+ perfCounters.increment("surface.localText.patchDelta", insertedText.length - (editTo - editFrom));
68975
+ return patched.surface;
68976
+ }
68179
68977
  function shiftSurfaceInlineSegment(segment, delta) {
68180
68978
  if (delta === 0) return segment;
68181
68979
  return {
@@ -68223,25 +69021,26 @@ function createDocumentRuntime(options) {
68223
69021
  }
68224
69022
  }
68225
69023
  function estimateLocalTextPatchShiftBudget(blocks, startIndex) {
69024
+ const policy = getHotEditPolicy();
68226
69025
  const shiftedBlocks = Math.max(0, blocks.length - startIndex);
68227
69026
  let shiftedNodes = 0;
68228
69027
  for (let index = startIndex; index < blocks.length; index += 1) {
68229
69028
  const shiftedBlockNodes = countSurfaceShiftNodesUpTo(
68230
69029
  blocks[index],
68231
69030
  Math.min(
68232
- LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK,
68233
- LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES - shiftedNodes
69031
+ policy.maxShiftedNodesPerBlock,
69032
+ policy.maxShiftedSurfaceNodes - shiftedNodes
68234
69033
  ) + 1
68235
69034
  );
68236
69035
  shiftedNodes += shiftedBlockNodes;
68237
- if (shiftedBlockNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK) {
69036
+ if (shiftedBlockNodes > policy.maxShiftedNodesPerBlock) {
68238
69037
  return {
68239
69038
  shiftedBlocks,
68240
69039
  shiftedNodes,
68241
69040
  withinBudget: false
68242
69041
  };
68243
69042
  }
68244
- if (shiftedNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES) {
69043
+ if (shiftedNodes > policy.maxShiftedSurfaceNodes) {
68245
69044
  return {
68246
69045
  shiftedBlocks,
68247
69046
  shiftedNodes,
@@ -69205,7 +70004,9 @@ function createDocumentRuntime(options) {
69205
70004
  });
69206
70005
  const r5ScratchReplayState = { ...state };
69207
70006
  const r5ScratchReplaySnapshot = { ...cachedRenderSnapshot };
69208
- const debugFacet = createRuntimeDebugFacet(() => runtime, telemetryBus);
70007
+ const debugFacet = createRuntimeDebugFacet(() => runtime, telemetryBus, {
70008
+ getHotEditTraces: () => hotEditTraces.getTraces()
70009
+ });
69209
70010
  function prepareTableStructureCommandForExecution(command, document2, storyTarget) {
69210
70011
  const resolution = resolveEditableTableStructureTarget({
69211
70012
  document: document2,
@@ -69302,13 +70103,12 @@ function createDocumentRuntime(options) {
69302
70103
  if (!command.editableTarget) {
69303
70104
  return { kind: "accepted", selection };
69304
70105
  }
69305
- const preserveCallerSelection = command.editableTarget.listAddress?.operationScope === "list-text";
69306
70106
  const resolution = resolveEditableTextTarget({
69307
70107
  document: document2,
69308
70108
  surface,
69309
70109
  target: command.editableTarget,
69310
70110
  activeStoryKey: canonicalEditableTargetStoryKey(storyTarget),
69311
- ...preserveCallerSelection ? { selection } : {},
70111
+ selection,
69312
70112
  editableTargetCache: editableTargetBlockCache
69313
70113
  });
69314
70114
  if (resolution.kind === "rejected") {
@@ -69326,7 +70126,7 @@ function createDocumentRuntime(options) {
69326
70126
  }
69327
70127
  return {
69328
70128
  kind: "accepted",
69329
- selection: preserveCallerSelection ? selection : createSelectionSnapshot(resolution.range.from, resolution.range.to),
70129
+ selection,
69330
70130
  ...resolution.textTarget ? { textTarget: resolution.textTarget } : {}
69331
70131
  };
69332
70132
  }
@@ -70502,12 +71302,23 @@ function createDocumentRuntime(options) {
70502
71302
  return actionDepth > 0;
70503
71303
  },
70504
71304
  applyActiveStoryTextCommand(command) {
71305
+ const pendingHotEditTrace = hotEditTraces.begin({
71306
+ commandType: command.type,
71307
+ nowUtc: clock(),
71308
+ counters: perfCounters
71309
+ });
70505
71310
  try {
70506
- return applyTextCommandInActiveStory(command);
71311
+ const ack = applyTextCommandInActiveStory(command);
71312
+ hotEditTraces.complete(pendingHotEditTrace, {
71313
+ tier: classifyHotEditTier(ack),
71314
+ patchMissReason: classifyHotEditPatchMissReason(ack),
71315
+ counters: perfCounters
71316
+ });
71317
+ return ack;
70507
71318
  } catch (error) {
70508
71319
  const runtimeError = toRuntimeError(error);
70509
71320
  emitError(runtimeError);
70510
- return {
71321
+ const ack = {
70511
71322
  kind: "rejected",
70512
71323
  refreshClass: "blocked",
70513
71324
  opId: command.origin?.opId,
@@ -70519,6 +71330,12 @@ function createDocumentRuntime(options) {
70519
71330
  }
70520
71331
  ]
70521
71332
  };
71333
+ hotEditTraces.complete(pendingHotEditTrace, {
71334
+ tier: "blocked",
71335
+ patchMissReason: "participant-blocked",
71336
+ counters: perfCounters
71337
+ });
71338
+ return ack;
70522
71339
  }
70523
71340
  },
70524
71341
  addComment(params) {
@@ -72294,6 +73111,27 @@ function createDocumentRuntime(options) {
72294
73111
  newRevisionToken: state.revisionToken
72295
73112
  }));
72296
73113
  }
73114
+ function classifyHotEditTier(ack) {
73115
+ if (ack.kind === "rejected" || ack.refreshClass === "blocked") {
73116
+ return "blocked";
73117
+ }
73118
+ if (ack.refreshClass === "full-projection" || ack.kind === "structural-divergence") {
73119
+ return "full-refresh";
73120
+ }
73121
+ if (ack.refreshClass === "local-text-equivalent" || ack.refreshClass === "selection-only" || ack.refreshClass === "surface-only") {
73122
+ return "patch";
73123
+ }
73124
+ return "full-refresh";
73125
+ }
73126
+ function classifyHotEditPatchMissReason(ack) {
73127
+ if (ack.kind === "rejected" || ack.refreshClass === "blocked") {
73128
+ return "participant-blocked";
73129
+ }
73130
+ if (ack.refreshClass === "full-projection" || ack.kind === "structural-divergence") {
73131
+ return "effect-disqualified";
73132
+ }
73133
+ return "none";
73134
+ }
72297
73135
  function classifyAck(params) {
72298
73136
  const { opId, priorState, transaction, newRevisionToken } = params;
72299
73137
  const meta = transaction.mapping.metadata ?? {};
@@ -91398,6 +92236,9 @@ function createLoadingDebugFacet() {
91398
92236
  },
91399
92237
  getChannels() {
91400
92238
  return bus.getChannels();
92239
+ },
92240
+ getHotEditTraces() {
92241
+ return [];
91401
92242
  }
91402
92243
  };
91403
92244
  }
@@ -116085,6 +116926,16 @@ function resolveSelectionEditableTarget(anchorTarget, headTarget) {
116085
116926
  if (!anchorTarget || !headTarget) return void 0;
116086
116927
  return anchorTarget.targetKey === headTarget.targetKey ? anchorTarget : void 0;
116087
116928
  }
116929
+ function resolveCurrentEditableTarget(state, positionMap) {
116930
+ if (!positionMap) return void 0;
116931
+ if (state.selection instanceof import_prosemirror_state2.NodeSelection) {
116932
+ return positionMap.pmToRuntimeWithContext(state.selection.from).editableTarget;
116933
+ }
116934
+ const { anchor, head } = state.selection;
116935
+ const anchorContext = positionMap.pmToRuntimeWithContext(anchor);
116936
+ const headContext = positionMap.pmToRuntimeWithContext(head);
116937
+ return resolveSelectionEditableTarget(anchorContext.editableTarget, headContext.editableTarget);
116938
+ }
116088
116939
  function createCommandBridgePlugins(callbacks, options) {
116089
116940
  let isComposing = false;
116090
116941
  let pendingCompositionText = null;
@@ -116263,11 +117114,13 @@ function createCommandBridgePlugins(callbacks, options) {
116263
117114
  if (isComposing) return true;
116264
117115
  const dragEvent = event;
116265
117116
  resolveDropSelectionFromCoordinates(_view, dragEvent);
116266
- if (!isPmEditTargetEditable(_view.state, callbacks.getPositionMap())) {
117117
+ const positionMap = callbacks.getPositionMap();
117118
+ if (!isPmEditTargetEditable(_view.state, positionMap)) {
116267
117119
  callbacks.onBlockedInput?.("drop", NON_EDITABLE_INPUT_MESSAGE);
116268
117120
  dragSourceRange = null;
116269
117121
  return true;
116270
117122
  }
117123
+ const editableTarget = resolveCurrentEditableTarget(_view.state, positionMap);
116271
117124
  const dt = dragEvent.dataTransfer;
116272
117125
  if (!dt) {
116273
117126
  callbacks.onBlockedInput?.("drop", "Drop data was not available.");
@@ -116284,6 +117137,7 @@ function createCommandBridgePlugins(callbacks, options) {
116284
117137
  callbacks.onDropFragment({
116285
117138
  fragment: parsed.fragment,
116286
117139
  effect,
117140
+ ...editableTarget ? { editableTarget } : {},
116287
117141
  ...sourceRange ? { sourceRange } : {}
116288
117142
  });
116289
117143
  dragSourceRange = null;
@@ -116414,7 +117268,7 @@ var import_prosemirror_view3 = require("prosemirror-view");
116414
117268
 
116415
117269
  // src/ui-tailwind/editor-surface/pm-decorations.ts
116416
117270
  var import_prosemirror_view2 = require("prosemirror-view");
116417
- function nowMs2() {
117271
+ function nowMs3() {
116418
117272
  return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
116419
117273
  }
116420
117274
  function sanitizeRevisionAuthorColor(raw) {
@@ -116688,7 +117542,7 @@ function buildDecorations(doc, positionMap, commentModel, revisionModel, markupD
116688
117542
  const activeScopeIds = new Set(activeWorkflowScopeIds ?? []);
116689
117543
  const effectiveWorkflowScopes = workflowScopes ?? [];
116690
117544
  const lockedPmRanges = collectLockedPmRanges(workflowLockedZones, activeStory, positionMap);
116691
- const commentsStartMs = nowMs2();
117545
+ const commentsStartMs = nowMs3();
116692
117546
  let commentCount = 0;
116693
117547
  if (commentModel) {
116694
117548
  for (const thread of commentModel.threads) {
@@ -116712,11 +117566,11 @@ function buildDecorations(doc, positionMap, commentModel, revisionModel, markupD
116712
117566
  }
116713
117567
  }
116714
117568
  }
116715
- recordPerfSample("pm.decorations.comments", nowMs2() - commentsStartMs);
117569
+ recordPerfSample("pm.decorations.comments", nowMs3() - commentsStartMs);
116716
117570
  if (commentCount > 0) {
116717
117571
  incrementInvalidationCounter("pm.decorations.comments.count", commentCount);
116718
117572
  }
116719
- const revisionsStartMs = nowMs2();
117573
+ const revisionsStartMs = nowMs3();
116720
117574
  let revisionCount = 0;
116721
117575
  if (revisionModel) {
116722
117576
  for (const rev of revisionModel.revisions) {
@@ -116825,11 +117679,11 @@ function buildDecorations(doc, positionMap, commentModel, revisionModel, markupD
116825
117679
  revisionCount += 1;
116826
117680
  }
116827
117681
  }
116828
- recordPerfSample("pm.decorations.revisions", nowMs2() - revisionsStartMs);
117682
+ recordPerfSample("pm.decorations.revisions", nowMs3() - revisionsStartMs);
116829
117683
  if (revisionCount > 0) {
116830
117684
  incrementInvalidationCounter("pm.decorations.revisions.count", revisionCount);
116831
117685
  }
116832
- const workflowStartMs = nowMs2();
117686
+ const workflowStartMs = nowMs3();
116833
117687
  const workflowDecorationsBefore = decorations.length;
116834
117688
  if (effectiveWorkflowScopes.length > 0) {
116835
117689
  for (const scope of effectiveWorkflowScopes) {
@@ -116947,7 +117801,7 @@ function buildDecorations(doc, positionMap, commentModel, revisionModel, markupD
116947
117801
  }, railRangeCache);
116948
117802
  }
116949
117803
  }
116950
- recordPerfSample("pm.decorations.workflow", nowMs2() - workflowStartMs);
117804
+ recordPerfSample("pm.decorations.workflow", nowMs3() - workflowStartMs);
116951
117805
  const workflowDecorationCount = decorations.length - workflowDecorationsBefore;
116952
117806
  if (workflowDecorationCount > 0) {
116953
117807
  incrementInvalidationCounter(
@@ -117024,11 +117878,11 @@ function applyRuntimeDecorationInputs(view, inputs) {
117024
117878
  const tr = view.state.tr.setMeta(runtimeDecorationPluginKey, {
117025
117879
  inputs
117026
117880
  });
117027
- const startedAt = nowMs3();
117881
+ const startedAt = nowMs4();
117028
117882
  view.dispatch(tr);
117029
- recordPerfSample("pm.decorations.apply", nowMs3() - startedAt);
117883
+ recordPerfSample("pm.decorations.apply", nowMs4() - startedAt);
117030
117884
  }
117031
- function nowMs3() {
117885
+ function nowMs4() {
117032
117886
  return typeof performance !== "undefined" ? performance.now() : Date.now();
117033
117887
  }
117034
117888
 
@@ -122818,6 +123672,7 @@ var LAYER_DEBUG_PANES = [
122818
123672
  snippets: [
122819
123673
  { label: "Selection context", expression: "ref?.getRuntimeContextAnalytics?.()" },
122820
123674
  { label: "Document context", expression: "ref?.getRuntimeContextAnalytics?.({ scopeKind: 'document' })" },
123675
+ { label: "Hot edit trace", expression: "runtime?.debug?.getHotEditTraces?.().at(-1)" },
122821
123676
  { label: "View state", expression: "ref?.getViewState?.()" }
122822
123677
  ],
122823
123678
  routed: [
@@ -122874,6 +123729,7 @@ var LAYER_DEBUG_PANES = [
122874
123729
  snippets: [
122875
123730
  { label: "Navigation", expression: "ref?.getDocumentNavigationSnapshot?.()" },
122876
123731
  { label: "Review surface", expression: "({ comments: ref?.getCommentSidebarSnapshot?.(), changes: ref?.getTrackedChangesSnapshot?.() })" },
123732
+ { label: "Hot edit traces", expression: "runtime?.debug?.getHotEditTraces?.()" },
122877
123733
  { label: "Compatibility", expression: "ref?.getCompatibilityReport?.()" }
122878
123734
  ],
122879
123735
  routed: [
@@ -124299,6 +125155,10 @@ function extractNLHaystack(entry) {
124299
125155
  }
124300
125156
  return out.slice(0, 200).toLowerCase();
124301
125157
  }
125158
+ case "image": {
125159
+ const text = entry.image.type === "image" ? entry.image.altText ?? "" : entry.image.anchor.docPr?.descr ?? entry.image.anchor.docPr?.name ?? "";
125160
+ return text.slice(0, 200).toLowerCase();
125161
+ }
124302
125162
  case "table":
124303
125163
  case "table-row":
124304
125164
  case "table-cell":
@@ -126134,6 +126994,391 @@ function createViewportFamily2(runtime) {
126134
126994
  };
126135
126995
  }
126136
126996
 
126997
+ // src/api/v3/runtime/lists.ts
126998
+ var SUPPORTED_COMMANDS = [
126999
+ "toggle-numbered",
127000
+ "toggle-bulleted",
127001
+ "indent",
127002
+ "outdent",
127003
+ "restart-numbering",
127004
+ "continue-numbering"
127005
+ ];
127006
+ var UNSUPPORTED_COMMANDS = [
127007
+ "create",
127008
+ "attach",
127009
+ "detach",
127010
+ "join",
127011
+ "separate",
127012
+ "split",
127013
+ "set-value",
127014
+ "apply-template",
127015
+ "capture-template",
127016
+ "apply-preset",
127017
+ "set-level-numbering",
127018
+ "set-level-bullet",
127019
+ "set-level-picture-bullet",
127020
+ "set-level-alignment",
127021
+ "set-level-indents",
127022
+ "set-level-trailing-character",
127023
+ "set-level-marker-font",
127024
+ "set-level-text",
127025
+ "set-level-start",
127026
+ "set-level-layout",
127027
+ "convert-to-text",
127028
+ "paste-fragment",
127029
+ "drop-fragment"
127030
+ ];
127031
+ var applyCommandMetadata = {
127032
+ name: "runtime.lists.applyCommand",
127033
+ status: "live-with-adapter",
127034
+ sourceLayer: "runtime-core",
127035
+ liveEvidence: {
127036
+ runnerTest: "test/api/v3/runtime/lists.test.ts",
127037
+ commit: "refactor-07-runtime-lists-namespace"
127038
+ },
127039
+ uxIntent: {
127040
+ uiVisible: true,
127041
+ expectsUxResponse: "surface-refresh",
127042
+ expectedDelta: "list structure changes through the L07 list command surface"
127043
+ },
127044
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "scope", auditCategory: "list-command" },
127045
+ stateClass: "A-canonical",
127046
+ persistsTo: "canonical",
127047
+ broadcastsVia: "crdt",
127048
+ rwdReference: "\xA7Runtime API \xA7 runtime.lists.applyCommand. Dispatches only proven L07 list commands through opaque list targets; future commands return owner-routed blockers until command/export/readback support lands."
127049
+ };
127050
+ function createListsFamily(runtime) {
127051
+ return {
127052
+ list(input = {}) {
127053
+ const document2 = runtime.getCanonicalDocument();
127054
+ const rows = currentListTargets(document2).filter((entry) => input.storyKey === void 0 || entry.target.storyKey === input.storyKey).map((entry) => toReadback(document2, entry.target, entry.paragraph));
127055
+ return input.limit === void 0 ? rows : rows.slice(0, Math.max(0, input.limit));
127056
+ },
127057
+ get(input) {
127058
+ const resolved = resolveCurrentListTarget(runtime.getCanonicalDocument(), input);
127059
+ return resolved.kind === "resolved" ? toReadback(runtime.getCanonicalDocument(), resolved.target, resolved.paragraph) : null;
127060
+ },
127061
+ previewCommand(input) {
127062
+ return previewListCommand(runtime.getCanonicalDocument(), input);
127063
+ },
127064
+ applyCommand(input) {
127065
+ const preview = previewListCommand(runtime.getCanonicalDocument(), input);
127066
+ if (!preview.supported || !preview.target) {
127067
+ return {
127068
+ applied: false,
127069
+ command: input.command,
127070
+ before: preview.target,
127071
+ blockers: preview.blockers
127072
+ };
127073
+ }
127074
+ const resolved = resolveCurrentListTarget(runtime.getCanonicalDocument(), {
127075
+ addressKey: preview.target.addressKey
127076
+ });
127077
+ if (resolved.kind !== "resolved") {
127078
+ return {
127079
+ applied: false,
127080
+ command: input.command,
127081
+ before: preview.target,
127082
+ blockers: [resolved.blocker]
127083
+ };
127084
+ }
127085
+ const command = editorCommandForListCommand(
127086
+ input.command,
127087
+ resolved.target,
127088
+ runtime.now(),
127089
+ input.startAt
127090
+ );
127091
+ if (!command) {
127092
+ return {
127093
+ applied: false,
127094
+ command: input.command,
127095
+ before: preview.target,
127096
+ blockers: [
127097
+ unsupportedCommandBlocker(input.command, {
127098
+ targetKey: preview.target.targetKey,
127099
+ addressKey: preview.target.addressKey
127100
+ })
127101
+ ]
127102
+ };
127103
+ }
127104
+ const beforeDocument = runtime.getCanonicalDocument();
127105
+ runtime.dispatch(command);
127106
+ const afterDocument = runtime.getCanonicalDocument();
127107
+ const after = resolveCurrentListTarget(afterDocument, { targetKey: preview.target.targetKey });
127108
+ emitUxResponse(runtime, {
127109
+ apiFn: applyCommandMetadata.name,
127110
+ intent: applyCommandMetadata.uxIntent.expectedDelta ?? "",
127111
+ mockOrLive: "live",
127112
+ uiVisible: true,
127113
+ expectedDelta: applyCommandMetadata.uxIntent.expectedDelta
127114
+ });
127115
+ return {
127116
+ applied: beforeDocument !== afterDocument,
127117
+ command: input.command,
127118
+ before: preview.target,
127119
+ ...after.kind === "resolved" ? { after: toReadback(afterDocument, after.target, after.paragraph) } : {},
127120
+ blockers: []
127121
+ };
127122
+ }
127123
+ };
127124
+ }
127125
+ function previewListCommand(document2, input) {
127126
+ const resolved = resolveCurrentListTarget(document2, input);
127127
+ if (resolved.kind !== "resolved") {
127128
+ return {
127129
+ command: input.command,
127130
+ supported: false,
127131
+ affectedTargets: [],
127132
+ blockers: [resolved.blocker]
127133
+ };
127134
+ }
127135
+ const target = toReadback(document2, resolved.target, resolved.paragraph);
127136
+ const targetRef = { targetKey: target.targetKey, addressKey: target.addressKey };
127137
+ if (!SUPPORTED_COMMANDS.includes(input.command)) {
127138
+ return {
127139
+ command: input.command,
127140
+ supported: false,
127141
+ target,
127142
+ affectedTargets: [target],
127143
+ blockers: [unsupportedCommandBlocker(input.command, targetRef)]
127144
+ };
127145
+ }
127146
+ const canContinuePrevious = canContinuePreviousSequence(document2, resolved.paragraphIndex);
127147
+ const canJoin = canJoinPreviousSequence(document2, resolved.paragraphIndex);
127148
+ const blockers = [];
127149
+ if (input.command === "continue-numbering" && !canContinuePrevious) {
127150
+ blockers.push({
127151
+ code: "list-continue-target-missing",
127152
+ ownerLayer: "L07",
127153
+ message: "No previous compatible list sequence is available for continue-numbering.",
127154
+ ...targetRef
127155
+ });
127156
+ }
127157
+ return {
127158
+ command: input.command,
127159
+ supported: blockers.length === 0,
127160
+ target,
127161
+ affectedTargets: [target],
127162
+ blockers,
127163
+ canJoin,
127164
+ canContinuePrevious
127165
+ };
127166
+ }
127167
+ function editorCommandForListCommand(command, editableTarget, timestamp, startAt) {
127168
+ const origin = { source: "api", timestamp };
127169
+ switch (command) {
127170
+ case "toggle-numbered":
127171
+ return { type: "list.toggle", kind: "numbered", editableTargets: [editableTarget], origin };
127172
+ case "toggle-bulleted":
127173
+ return { type: "list.toggle", kind: "bulleted", editableTargets: [editableTarget], origin };
127174
+ case "indent":
127175
+ return { type: "list.indent", editableTargets: [editableTarget], origin };
127176
+ case "outdent":
127177
+ return { type: "list.outdent", editableTargets: [editableTarget], origin };
127178
+ case "restart-numbering":
127179
+ return {
127180
+ type: "list.restart-numbering",
127181
+ editableTarget,
127182
+ ...startAt !== void 0 ? { startAt } : {},
127183
+ origin
127184
+ };
127185
+ case "continue-numbering":
127186
+ return { type: "list.continue-numbering", editableTarget, origin };
127187
+ default:
127188
+ return void 0;
127189
+ }
127190
+ }
127191
+ function resolveCurrentListTarget(document2, input) {
127192
+ if (input.editableTarget) {
127193
+ const shapeIssues = validateEditableTargetRef(input.editableTarget);
127194
+ if (shapeIssues.length > 0) {
127195
+ return {
127196
+ kind: "blocked",
127197
+ blocker: {
127198
+ code: "list-target-malformed",
127199
+ ownerLayer: "L07",
127200
+ message: `List target is malformed: ${shapeIssues[0]?.path ?? "$"}.`,
127201
+ targetKey: input.editableTarget.targetKey,
127202
+ addressKey: input.editableTarget.listAddress?.addressKey
127203
+ }
127204
+ };
127205
+ }
127206
+ }
127207
+ const requestedTargetKey = input.editableTarget?.targetKey ?? input.targetKey;
127208
+ const requestedAddressKey = input.editableTarget?.listAddress?.addressKey ?? input.addressKey;
127209
+ if (!requestedTargetKey && !requestedAddressKey) {
127210
+ return {
127211
+ kind: "blocked",
127212
+ blocker: {
127213
+ code: "list-target-required",
127214
+ ownerLayer: "L07",
127215
+ message: "runtime.lists requires a targetKey, addressKey, or editableTarget."
127216
+ }
127217
+ };
127218
+ }
127219
+ const currentTargets = currentListTargets(document2);
127220
+ const resolved = currentTargets.find(
127221
+ ({ target }) => requestedTargetKey !== void 0 && target.targetKey === requestedTargetKey || requestedAddressKey !== void 0 && target.listAddress?.addressKey === requestedAddressKey
127222
+ );
127223
+ if (!resolved) {
127224
+ return {
127225
+ kind: "blocked",
127226
+ blocker: {
127227
+ code: "list-target-not-found",
127228
+ ownerLayer: "L07",
127229
+ message: "List target no longer resolves in the current canonical document.",
127230
+ ...requestedTargetKey !== void 0 ? { targetKey: requestedTargetKey } : {},
127231
+ ...requestedAddressKey !== void 0 ? { addressKey: requestedAddressKey } : {}
127232
+ }
127233
+ };
127234
+ }
127235
+ if (input.editableTarget && !sameTargetStaleHash(input.editableTarget, resolved.target)) {
127236
+ return {
127237
+ kind: "blocked",
127238
+ blocker: {
127239
+ code: "list-target-stale",
127240
+ ownerLayer: "L07",
127241
+ message: "List target resolved by identity but stale discriminators changed.",
127242
+ targetKey: input.editableTarget.targetKey,
127243
+ addressKey: input.editableTarget.listAddress?.addressKey
127244
+ }
127245
+ };
127246
+ }
127247
+ if (resolved.target.editability !== "editable" || resolved.target.posture.blockers.length > 0) {
127248
+ return {
127249
+ kind: "blocked",
127250
+ blocker: {
127251
+ code: "list-target-non-editable",
127252
+ ownerLayer: "L07",
127253
+ message: resolved.target.posture.blockers.length > 0 ? `List target is not editable: ${resolved.target.posture.blockers.join(", ")}.` : "List target is not editable.",
127254
+ targetKey: resolved.target.targetKey,
127255
+ addressKey: resolved.target.listAddress?.addressKey
127256
+ }
127257
+ };
127258
+ }
127259
+ return { kind: "resolved", ...resolved };
127260
+ }
127261
+ function currentListTargets(document2) {
127262
+ const paragraphs = collectParagraphEntries(document2.content.children, "main");
127263
+ const targets = collectEditableTargetRefs(document2).filter(isListTextTarget);
127264
+ const byBlockPath = /* @__PURE__ */ new Map();
127265
+ for (const target of targets) byBlockPath.set(target.blockPath, target);
127266
+ const out = [];
127267
+ for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex += 1) {
127268
+ const entry = paragraphs[paragraphIndex];
127269
+ if (!entry?.paragraph.numbering) continue;
127270
+ const target = byBlockPath.get(entry.blockPath);
127271
+ if (!target) continue;
127272
+ out.push({ target, paragraph: entry.paragraph, paragraphIndex });
127273
+ }
127274
+ return out;
127275
+ }
127276
+ function collectParagraphEntries(blocks, basePath) {
127277
+ const out = [];
127278
+ collectParagraphEntriesInto(blocks, basePath, out);
127279
+ return out;
127280
+ }
127281
+ function collectParagraphEntriesInto(blocks, basePath, out) {
127282
+ for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
127283
+ const block = blocks[blockIndex];
127284
+ if (!block) continue;
127285
+ const blockPath = `${basePath}/block[${blockIndex}]`;
127286
+ switch (block.type) {
127287
+ case "paragraph":
127288
+ out.push({ paragraph: block, blockPath });
127289
+ break;
127290
+ case "table":
127291
+ for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
127292
+ const row2 = block.rows[rowIndex];
127293
+ if (!row2) continue;
127294
+ for (let cellIndex = 0; cellIndex < row2.cells.length; cellIndex += 1) {
127295
+ const cell = row2.cells[cellIndex];
127296
+ if (!cell) continue;
127297
+ collectParagraphEntriesInto(
127298
+ cell.children,
127299
+ `${blockPath}/row[${rowIndex}]/cell[${cellIndex}]`,
127300
+ out
127301
+ );
127302
+ }
127303
+ }
127304
+ break;
127305
+ case "sdt":
127306
+ collectParagraphEntriesInto(block.children, blockPath, out);
127307
+ break;
127308
+ case "custom_xml":
127309
+ break;
127310
+ default:
127311
+ break;
127312
+ }
127313
+ }
127314
+ }
127315
+ function isListTextTarget(target) {
127316
+ return target.commandFamily === "text-leaf" && target.listAddress?.operationScope === "list-text" && target.listAddress.addressKind === "list-item-text";
127317
+ }
127318
+ function sameTargetStaleHash(left, right) {
127319
+ return left.targetKey === right.targetKey && left.listAddress?.addressKey === right.listAddress?.addressKey && left.listAddress?.resolver?.staleHash === right.listAddress?.resolver?.staleHash && left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength && left.staleCheck.inlineCount === right.staleCheck.inlineCount;
127320
+ }
127321
+ function toReadback(document2, target, paragraph) {
127322
+ const numbering = paragraph.numbering;
127323
+ const instance = document2.numbering.instances[numbering.numberingInstanceId];
127324
+ const listKind = instance ? getListKind(document2.numbering, numbering.numberingInstanceId) : void 0;
127325
+ return {
127326
+ targetKey: target.targetKey,
127327
+ actionHandle: `list-action:${target.listAddress.addressKey}`,
127328
+ kind: target.kind,
127329
+ storyKey: target.storyKey,
127330
+ blockPath: target.blockPath,
127331
+ leafPath: target.leafPath,
127332
+ addressKey: target.listAddress.addressKey,
127333
+ numberingInstanceId: numbering.numberingInstanceId,
127334
+ ...instance?.abstractNumberingId ? { abstractNumberingId: instance.abstractNumberingId } : {},
127335
+ level: numbering.level,
127336
+ ...listKind ? { listKind } : {},
127337
+ editability: target.editability,
127338
+ blockers: target.posture.blockers,
127339
+ supportedCommands: SUPPORTED_COMMANDS,
127340
+ unsupportedCommands: UNSUPPORTED_COMMANDS,
127341
+ staleDiscriminators: {
127342
+ paragraphTextHash: target.staleCheck.paragraphTextHash,
127343
+ paragraphTextLength: target.staleCheck.paragraphTextLength,
127344
+ inlineCount: target.staleCheck.inlineCount,
127345
+ listAddressStaleHash: target.listAddress?.resolver?.staleHash
127346
+ }
127347
+ };
127348
+ }
127349
+ function canContinuePreviousSequence(document2, paragraphIndex) {
127350
+ const paragraphs = collectParagraphEntries(document2.content.children, "main");
127351
+ const current = paragraphs[paragraphIndex]?.paragraph;
127352
+ if (!current?.numbering) return false;
127353
+ const currentKind = getListKind(document2.numbering, current.numbering.numberingInstanceId);
127354
+ if (!currentKind) return false;
127355
+ for (let index = paragraphIndex - 1; index >= 0; index -= 1) {
127356
+ const previous = paragraphs[index]?.paragraph;
127357
+ if (!previous?.numbering) continue;
127358
+ const previousKind = getListKind(document2.numbering, previous.numbering.numberingInstanceId);
127359
+ return previousKind === currentKind && previous.numbering.numberingInstanceId !== current.numbering.numberingInstanceId;
127360
+ }
127361
+ return false;
127362
+ }
127363
+ function canJoinPreviousSequence(document2, paragraphIndex) {
127364
+ const paragraphs = collectParagraphEntries(document2.content.children, "main");
127365
+ const current = paragraphs[paragraphIndex]?.paragraph;
127366
+ const previous = paragraphs[paragraphIndex - 1]?.paragraph;
127367
+ if (!current?.numbering || !previous?.numbering) return false;
127368
+ const currentKind = getListKind(document2.numbering, current.numbering.numberingInstanceId);
127369
+ const previousKind = getListKind(document2.numbering, previous.numbering.numberingInstanceId);
127370
+ return Boolean(currentKind) && currentKind === previousKind && current.numbering.numberingInstanceId !== previous.numbering.numberingInstanceId;
127371
+ }
127372
+ function unsupportedCommandBlocker(command, target) {
127373
+ return {
127374
+ code: "list-command-unsupported",
127375
+ ownerLayer: "L07",
127376
+ message: `runtime.lists.${command} is reserved but not implemented by the L07 command surface yet.`,
127377
+ ...target.targetKey !== void 0 ? { targetKey: target.targetKey } : {},
127378
+ ...target.addressKey !== void 0 ? { addressKey: target.addressKey } : {}
127379
+ };
127380
+ }
127381
+
126137
127382
  // src/api/v3/ai/_pe2-evidence.ts
126138
127383
  function copyCoverage(coverage) {
126139
127384
  return {
@@ -127861,6 +129106,17 @@ function createTableActionFamily(runtime) {
127861
129106
  operationScope: target.table?.operationScope
127862
129107
  });
127863
129108
  }
129109
+ if (fragmentContent && fragmentContent.blocks.length === 0) {
129110
+ return blockedResult(input, proposalId, {
129111
+ code: `table-action-structured-fragment-empty:${input.operation.kind}`,
129112
+ category: "unsupported-operation",
129113
+ message: "Structured table text actions require a canonical document fragment with at least one block.",
129114
+ nextStep: 'Retry with operation.content.kind="structured" and a CanonicalDocumentFragment whose blocks array contains the paragraph or table content to paste/drop.',
129115
+ actionHandle: input.actionHandle,
129116
+ operation: input.operation.kind,
129117
+ operationScope: target.table?.operationScope
129118
+ });
129119
+ }
127864
129120
  const resolution2 = resolveEditableTextTarget({
127865
129121
  document: runtime.getCanonicalDocument(),
127866
129122
  surface: runtime.getRenderSnapshot().surface?.blocks ?? [],
@@ -127883,6 +129139,7 @@ function createTableActionFamily(runtime) {
127883
129139
  runtime.dispatch({
127884
129140
  type: "fragment.insert",
127885
129141
  fragment: fragmentContent,
129142
+ selection: createSelectionSnapshot(resolution2.range.to, resolution2.range.to),
127886
129143
  editableTarget: target,
127887
129144
  origin: { source: "api", timestamp: nowUtc }
127888
129145
  });
@@ -127895,6 +129152,17 @@ function createTableActionFamily(runtime) {
127895
129152
  });
127896
129153
  }
127897
129154
  const changed2 = runtime.getCanonicalDocument() !== before2;
129155
+ if (!changed2) {
129156
+ return blockedResult(input, proposalId, {
129157
+ code: `table-action-noop:${input.operation.kind}:${input.actionHandle}`,
129158
+ category: "runtime-noop",
129159
+ message: "The runtime accepted the table text target but the operation produced no document change.",
129160
+ nextStep: "Refresh the table action list and verify the target is still editable, the payload is non-empty when required, and structured fragments are dispatched through a command-safe table text action.",
129161
+ actionHandle: input.actionHandle,
129162
+ operation: input.operation.kind,
129163
+ operationScope: target.table?.operationScope
129164
+ });
129165
+ }
127898
129166
  const afterReadback = tableTextReadback(readEditableTargetText(runtime.getCanonicalDocument(), target));
127899
129167
  return {
127900
129168
  proposalId,
@@ -130997,7 +132265,8 @@ function createApiV3(handle, opts) {
130997
132265
  chart: createChartFamily(handle),
130998
132266
  search: createSearchFamily(handle),
130999
132267
  table: createTableFamily(handle),
131000
- viewport: createViewportFamily2(handle)
132268
+ viewport: createViewportFamily2(handle),
132269
+ lists: createListsFamily(handle)
131001
132270
  };
131002
132271
  const ui = opts?.ui ? createUiApi(handle, opts.ui) : void 0;
131003
132272
  const api = ui ? { runtime, ai, ui } : { runtime, ai };
@@ -133363,6 +134632,7 @@ var WordReviewEditor = (0, import_react71.forwardRef)(
133363
134632
  // auto-bracketing in insertFragment + our explicit startAction around
133364
134633
  // the delete, so the undo history sees a single atomic action.
133365
134634
  onDropFragment: (meta) => {
134635
+ const dropEditableTarget = meta.editableTarget ?? activeRuntime.getRenderSnapshot().selection.editableTarget;
133366
134636
  if (meta.effect === "move" && meta.sourceRange) {
133367
134637
  activeRuntime.startAction("drag-move");
133368
134638
  try {
@@ -133372,16 +134642,21 @@ var WordReviewEditor = (0, import_react71.forwardRef)(
133372
134642
  to: meta.sourceRange.to,
133373
134643
  assoc: { start: -1, end: 1 }
133374
134644
  });
133375
- activeRuntime.insertFragment(meta.fragment);
134645
+ const currentEditableTarget = activeRuntime.getRenderSnapshot().selection.editableTarget;
134646
+ const editableTarget = currentEditableTarget?.targetKey === dropEditableTarget?.targetKey ? currentEditableTarget : dropEditableTarget;
134647
+ activeRuntime.insertFragment(
134648
+ meta.fragment,
134649
+ void 0,
134650
+ editableTarget ? { editableTarget } : void 0
134651
+ );
133376
134652
  } finally {
133377
134653
  activeRuntime.endAction();
133378
134654
  }
133379
134655
  } else {
133380
- const editableTarget = activeRuntime.getRenderSnapshot().selection.editableTarget;
133381
134656
  activeRuntime.insertFragment(
133382
134657
  meta.fragment,
133383
134658
  void 0,
133384
- editableTarget ? { editableTarget } : void 0
134659
+ dropEditableTarget ? { editableTarget: dropEditableTarget } : void 0
133385
134660
  );
133386
134661
  }
133387
134662
  },