@beyondwork/docx-react-component 1.0.135 → 1.0.136

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 (62) hide show
  1. package/dist/api/public-types.d.cts +2 -2
  2. package/dist/api/public-types.d.ts +2 -2
  3. package/dist/api/v3.cjs +183 -39
  4. package/dist/api/v3.d.cts +3 -3
  5. package/dist/api/v3.d.ts +3 -3
  6. package/dist/api/v3.js +2 -2
  7. package/dist/{canonical-document-CfZIc-fC.d.cts → canonical-document-COmM7v11.d.cts} +1 -1
  8. package/dist/{canonical-document-CfZIc-fC.d.ts → canonical-document-COmM7v11.d.ts} +1 -1
  9. package/dist/{chunk-5CCYF333.js → chunk-HUWZ7AHE.js} +123 -0
  10. package/dist/{chunk-GIFXKIM5.js → chunk-JZZKTL7K.js} +620 -50
  11. package/dist/{chunk-EPFVMUKF.js → chunk-NX7W6T7L.js} +169 -37
  12. package/dist/compare.d.cts +1 -1
  13. package/dist/compare.d.ts +1 -1
  14. package/dist/core/commands/formatting-commands.d.cts +2 -2
  15. package/dist/core/commands/formatting-commands.d.ts +2 -2
  16. package/dist/core/commands/image-commands.d.cts +2 -2
  17. package/dist/core/commands/image-commands.d.ts +2 -2
  18. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  19. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  20. package/dist/core/commands/style-commands.d.cts +2 -2
  21. package/dist/core/commands/style-commands.d.ts +2 -2
  22. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  23. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  24. package/dist/core/commands/text-commands.d.cts +2 -2
  25. package/dist/core/commands/text-commands.d.ts +2 -2
  26. package/dist/core/selection/mapping.d.cts +2 -2
  27. package/dist/core/selection/mapping.d.ts +2 -2
  28. package/dist/core/state/editor-state.d.cts +2 -2
  29. package/dist/core/state/editor-state.d.ts +2 -2
  30. package/dist/index.cjs +1075 -154
  31. package/dist/index.d.cts +5 -5
  32. package/dist/index.d.ts +5 -5
  33. package/dist/index.js +123 -23
  34. package/dist/io/docx-session.d.cts +4 -4
  35. package/dist/io/docx-session.d.ts +4 -4
  36. package/dist/legal.d.cts +1 -1
  37. package/dist/legal.d.ts +1 -1
  38. package/dist/{loader-BQ7AB-0v.d.cts → loader-Cr35kVUi.d.cts} +3 -3
  39. package/dist/{loader-Cy6OYBfn.d.ts → loader-uGY6nDZP.d.ts} +3 -3
  40. package/dist/{public-types-D31xKNGc.d.cts → public-types-8kVIB5HW.d.ts} +16 -8
  41. package/dist/{public-types-DqYt8GdP.d.ts → public-types-CSSH2Whc.d.cts} +16 -8
  42. package/dist/public-types.d.cts +2 -2
  43. package/dist/public-types.d.ts +2 -2
  44. package/dist/runtime/collab.d.cts +3 -3
  45. package/dist/runtime/collab.d.ts +3 -3
  46. package/dist/runtime/document-runtime.cjs +737 -46
  47. package/dist/runtime/document-runtime.d.cts +2 -2
  48. package/dist/runtime/document-runtime.d.ts +2 -2
  49. package/dist/runtime/document-runtime.js +2 -2
  50. package/dist/{session-DA-F2fCw.d.cts → session-Beg8ihOi.d.cts} +3 -3
  51. package/dist/{session-DqL8H0oZ.d.ts → session-Dgp-2uYw.d.ts} +3 -3
  52. package/dist/session.d.cts +5 -5
  53. package/dist/session.d.ts +5 -5
  54. package/dist/tailwind.d.cts +2 -2
  55. package/dist/tailwind.d.ts +2 -2
  56. package/dist/{types-SllbCtGs.d.ts → types-Cin_abw3.d.ts} +2 -2
  57. package/dist/{types-B2y94n5t.d.cts → types-qsS39ZkQ.d.cts} +2 -2
  58. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  59. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  60. package/dist/ui-tailwind.d.cts +3 -3
  61. package/dist/ui-tailwind.d.ts +3 -3
  62. package/package.json +1 -1
@@ -19712,6 +19712,106 @@ function setStartOverride(catalog, numberingInstanceId, level, startAt) {
19712
19712
  overrides: mergeOverride(instance.overrides, { level, startAt })
19713
19713
  };
19714
19714
  }
19715
+ function mergeFragmentNumberingCatalog(target, fragment) {
19716
+ const catalog = cloneNumberingCatalog(target);
19717
+ const abstractIdMap = /* @__PURE__ */ new Map();
19718
+ const instanceIdMap = /* @__PURE__ */ new Map();
19719
+ const picBulletIdMap = /* @__PURE__ */ new Map();
19720
+ if (!fragment) {
19721
+ return { catalog, abstractIdMap, instanceIdMap, picBulletIdMap };
19722
+ }
19723
+ for (const [picBulletId, entry] of Object.entries(fragment.numPicBullets ?? {})) {
19724
+ const mappedId = mapPicBulletId(catalog, picBulletId, entry);
19725
+ picBulletIdMap.set(picBulletId, mappedId);
19726
+ }
19727
+ for (const [abstractId, definition] of Object.entries(fragment.abstractDefinitions)) {
19728
+ const mappedId = mapAbstractDefinition(catalog, definition, picBulletIdMap);
19729
+ abstractIdMap.set(abstractId, mappedId);
19730
+ }
19731
+ for (const [instanceId, instance] of Object.entries(fragment.instances)) {
19732
+ const mappedAbstractId = abstractIdMap.get(instance.abstractNumberingId) ?? instance.abstractNumberingId;
19733
+ const mappedId = mapNumberingInstance(
19734
+ catalog,
19735
+ instance,
19736
+ mappedAbstractId,
19737
+ picBulletIdMap
19738
+ );
19739
+ instanceIdMap.set(instanceId, mappedId);
19740
+ }
19741
+ return { catalog, abstractIdMap, instanceIdMap, picBulletIdMap };
19742
+ }
19743
+ function mapPicBulletId(catalog, picBulletId, entry) {
19744
+ const existing = catalog.numPicBullets?.[picBulletId];
19745
+ if (existing && existing.rawXml === entry.rawXml) return picBulletId;
19746
+ const mappedId = existing ? nextNumericString(Object.keys(catalog.numPicBullets ?? {})) : picBulletId;
19747
+ const numPicBullets = { ...catalog.numPicBullets ?? {} };
19748
+ numPicBullets[mappedId] = {
19749
+ ...stripSourceRef(structuredClone(entry)),
19750
+ numPicBulletId: mappedId
19751
+ };
19752
+ catalog.numPicBullets = numPicBullets;
19753
+ return mappedId;
19754
+ }
19755
+ function mapAbstractDefinition(catalog, definition, picBulletIdMap) {
19756
+ const existing = catalog.abstractDefinitions[definition.abstractNumberingId];
19757
+ if (existing && sameJson(comparableAbstract(existing), comparableAbstract(definition))) {
19758
+ return definition.abstractNumberingId;
19759
+ }
19760
+ const mappedId = existing ? nextCanonicalNumericId("abstract-num:", Object.keys(catalog.abstractDefinitions)) : definition.abstractNumberingId;
19761
+ catalog.abstractDefinitions[mappedId] = {
19762
+ ...stripSourceRef(structuredClone(definition)),
19763
+ abstractNumberingId: mappedId,
19764
+ nsid: freshLongHex(catalog, mappedId, "nsid"),
19765
+ tplc: freshLongHex(catalog, mappedId, "tmpl"),
19766
+ levels: definition.levels.map((level) => remapLevelPicBullet(level, picBulletIdMap))
19767
+ };
19768
+ return mappedId;
19769
+ }
19770
+ function mapNumberingInstance(catalog, instance, abstractNumberingId, picBulletIdMap) {
19771
+ const existing = catalog.instances[instance.numberingInstanceId];
19772
+ const candidate = {
19773
+ ...instance,
19774
+ abstractNumberingId,
19775
+ overrides: instance.overrides.map(
19776
+ (override) => remapOverridePicBullet(override, picBulletIdMap)
19777
+ )
19778
+ };
19779
+ if (existing && sameJson(comparableInstance(existing), comparableInstance(candidate))) {
19780
+ return instance.numberingInstanceId;
19781
+ }
19782
+ const mappedId = existing ? nextCanonicalNumericId("num:", Object.keys(catalog.instances)) : instance.numberingInstanceId;
19783
+ catalog.instances[mappedId] = {
19784
+ ...stripSourceRef(structuredClone(instance)),
19785
+ overrides: candidate.overrides.map((override) => stripOverrideSourceRefs(override)),
19786
+ numberingInstanceId: mappedId,
19787
+ abstractNumberingId
19788
+ };
19789
+ return mappedId;
19790
+ }
19791
+ function remapLevelPicBullet(level, picBulletIdMap) {
19792
+ const cloned = stripSourceRef(structuredClone(level));
19793
+ if (!level.picBulletId) return cloned;
19794
+ return {
19795
+ ...cloned,
19796
+ picBulletId: picBulletIdMap.get(level.picBulletId) ?? level.picBulletId
19797
+ };
19798
+ }
19799
+ function remapOverridePicBullet(override, picBulletIdMap) {
19800
+ const cloned = stripOverrideSourceRefs(structuredClone(override));
19801
+ if (!override.levelDefinition) return cloned;
19802
+ return {
19803
+ ...cloned,
19804
+ levelDefinition: remapLevelPicBullet(override.levelDefinition, picBulletIdMap)
19805
+ };
19806
+ }
19807
+ function stripOverrideSourceRefs(override) {
19808
+ const cloned = stripSourceRef(override);
19809
+ if (!override.levelDefinition) return cloned;
19810
+ return {
19811
+ ...cloned,
19812
+ levelDefinition: stripSourceRef(override.levelDefinition)
19813
+ };
19814
+ }
19715
19815
  function mergeOverride(overrides, nextOverride) {
19716
19816
  return [
19717
19817
  ...overrides.filter((override) => override.level !== nextOverride.level),
@@ -19783,6 +19883,28 @@ function hashLongHex(input) {
19783
19883
  }
19784
19884
  return hash.toString(16).toUpperCase().padStart(8, "0").slice(-8);
19785
19885
  }
19886
+ function stripSourceRef(value) {
19887
+ const { sourceRef: _sourceRef, ...rest } = value;
19888
+ return rest;
19889
+ }
19890
+ function comparableAbstract(definition) {
19891
+ return {
19892
+ ...stripSourceRef(definition),
19893
+ levels: definition.levels.map((level) => stripSourceRef(level))
19894
+ };
19895
+ }
19896
+ function comparableInstance(instance) {
19897
+ return {
19898
+ ...stripSourceRef(instance),
19899
+ overrides: instance.overrides.map((override) => ({
19900
+ ...stripSourceRef(override),
19901
+ ...override.levelDefinition ? { levelDefinition: stripSourceRef(override.levelDefinition) } : {}
19902
+ }))
19903
+ };
19904
+ }
19905
+ function sameJson(left, right) {
19906
+ return JSON.stringify(left) === JSON.stringify(right);
19907
+ }
19786
19908
 
19787
19909
  // src/core/commands/list-commands.ts
19788
19910
  function toggleNumberedList(document2, paragraphIndexes, context, options = {}) {
@@ -19821,7 +19943,7 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1, optio
19821
19943
  affectedParagraphIndexes: []
19822
19944
  };
19823
19945
  }
19824
- const target = paragraphs[resolvedParagraphIndex];
19946
+ const target = paragraphs[resolvedParagraphIndex]?.paragraph;
19825
19947
  if (!target?.numbering) {
19826
19948
  return {
19827
19949
  document: working,
@@ -19843,8 +19965,13 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1, optio
19843
19965
  );
19844
19966
  setStartOverride(catalog, numberingInstanceId, target.numbering.level, startAt);
19845
19967
  const affectedParagraphIndexes = [];
19968
+ const targetStoryKey = paragraphs[resolvedParagraphIndex]?.storyKey;
19846
19969
  for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
19847
- const paragraph = paragraphs[index];
19970
+ const entry = paragraphs[index];
19971
+ if (entry?.storyKey !== targetStoryKey) {
19972
+ break;
19973
+ }
19974
+ const paragraph = entry.paragraph;
19848
19975
  if (!paragraph?.numbering) {
19849
19976
  break;
19850
19977
  }
@@ -19888,7 +20015,7 @@ function continueNumbering(document2, paragraphIndex, context, options = {}) {
19888
20015
  affectedParagraphIndexes: []
19889
20016
  };
19890
20017
  }
19891
- const target = paragraphs[resolvedParagraphIndex];
20018
+ const target = paragraphs[resolvedParagraphIndex]?.paragraph;
19892
20019
  if (!target?.numbering) {
19893
20020
  return {
19894
20021
  document: working,
@@ -19917,8 +20044,13 @@ function continueNumbering(document2, paragraphIndex, context, options = {}) {
19917
20044
  };
19918
20045
  }
19919
20046
  const affectedParagraphIndexes = [];
20047
+ const targetStoryKey = paragraphs[resolvedParagraphIndex]?.storyKey;
19920
20048
  for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
19921
- const paragraph = paragraphs[index];
20049
+ const entry = paragraphs[index];
20050
+ if (entry?.storyKey !== targetStoryKey) {
20051
+ break;
20052
+ }
20053
+ const paragraph = entry.paragraph;
19922
20054
  if (!paragraph?.numbering) {
19923
20055
  break;
19924
20056
  }
@@ -19964,12 +20096,13 @@ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
19964
20096
  }
19965
20097
  const catalog = cloneNumberingCatalog(working.numbering);
19966
20098
  const allAlreadyKind = normalizedIndexes.every((index) => {
19967
- const paragraph = paragraphs[index];
19968
- return paragraph.numbering ? getListKind(catalog, paragraph.numbering.numberingInstanceId) === kind : false;
20099
+ const paragraph = paragraphs[index]?.paragraph;
20100
+ return paragraph?.numbering ? getListKind(catalog, paragraph.numbering.numberingInstanceId) === kind : false;
19969
20101
  });
19970
20102
  if (allAlreadyKind) {
19971
20103
  for (const index of normalizedIndexes) {
19972
- delete paragraphs[index].numbering;
20104
+ const paragraph = paragraphs[index]?.paragraph;
20105
+ if (paragraph) delete paragraph.numbering;
19973
20106
  }
19974
20107
  working.numbering = catalog;
19975
20108
  return {
@@ -19979,7 +20112,8 @@ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
19979
20112
  }
19980
20113
  const numberingInstanceId = findAdjacentCompatibleInstance(paragraphs, catalog, normalizedIndexes[0], kind) ?? ensureDefaultListInstance(catalog, kind);
19981
20114
  for (const index of normalizedIndexes) {
19982
- const paragraph = paragraphs[index];
20115
+ const paragraph = paragraphs[index]?.paragraph;
20116
+ if (!paragraph) continue;
19983
20117
  paragraph.numbering = {
19984
20118
  numberingInstanceId,
19985
20119
  level: clampLevel(paragraph.numbering?.level ?? 0)
@@ -20010,10 +20144,11 @@ function adjustListLevels(document2, paragraphIndexes, delta, context, options)
20010
20144
  };
20011
20145
  }
20012
20146
  const affectedParagraphIndexes = resolved.paragraphIndexes.filter(
20013
- (index) => Boolean(paragraphs[index]?.numbering)
20147
+ (index) => Boolean(paragraphs[index]?.paragraph.numbering)
20014
20148
  );
20015
20149
  for (const index of affectedParagraphIndexes) {
20016
- const paragraph = paragraphs[index];
20150
+ const paragraph = paragraphs[index]?.paragraph;
20151
+ if (!paragraph) continue;
20017
20152
  if (!paragraph.numbering) {
20018
20153
  continue;
20019
20154
  }
@@ -20033,17 +20168,21 @@ function normalizeListCommandTargets(options) {
20033
20168
  }
20034
20169
  function resolveListCommandParagraphIndexes(document2, paragraphs, paragraphIndexes, context, editableTargets) {
20035
20170
  if (editableTargets.length === 0) {
20036
- return { paragraphIndexes: normalizeParagraphIndexes(paragraphs, paragraphIndexes) };
20171
+ return {
20172
+ paragraphIndexes: normalizeParagraphIndexesForStory(
20173
+ paragraphs,
20174
+ paragraphIndexes,
20175
+ context.activeStoryKey
20176
+ )
20177
+ };
20037
20178
  }
20038
20179
  const currentTargets = collectEditableTargetRefs(document2, context.editableTargetCache);
20039
- const paragraphIndexByTargetKey = /* @__PURE__ */ new Map();
20040
- let paragraphIndex = 0;
20041
- for (const target of currentTargets) {
20042
- if (!isParagraphTextTarget(target)) continue;
20043
- if (!paragraphIndexByTargetKey.has(target.targetKey)) {
20044
- paragraphIndexByTargetKey.set(target.targetKey, paragraphIndex);
20045
- paragraphIndex += 1;
20046
- }
20180
+ const paragraphIndexByAddress = /* @__PURE__ */ new Map();
20181
+ for (let index = 0; index < paragraphs.length; index += 1) {
20182
+ const entry = paragraphs[index];
20183
+ if (!entry) continue;
20184
+ paragraphIndexByAddress.set(`${entry.storyKey}
20185
+ ${entry.blockPath}`, index);
20047
20186
  }
20048
20187
  const resolvedIndexes = [];
20049
20188
  for (const target of editableTargets) {
@@ -20068,7 +20207,8 @@ function resolveListCommandParagraphIndexes(document2, paragraphs, paragraphInde
20068
20207
  }
20069
20208
  };
20070
20209
  }
20071
- const currentIndex = paragraphIndexByTargetKey.get(current.targetKey);
20210
+ const currentIndex = paragraphIndexByAddress.get(`${current.storyKey}
20211
+ ${current.blockPath}`);
20072
20212
  if (currentIndex === void 0) {
20073
20213
  return {
20074
20214
  paragraphIndexes: [],
@@ -20143,18 +20283,28 @@ function sortJson(value) {
20143
20283
  return value;
20144
20284
  }
20145
20285
  function findAdjacentCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
20286
+ const current = paragraphs[fromIndex];
20146
20287
  const previous = paragraphs[fromIndex - 1];
20147
- if (previous?.numbering) {
20148
- const previousKind = getListKind(catalog, previous.numbering.numberingInstanceId);
20288
+ if (previous?.storyKey !== current?.storyKey) {
20289
+ return void 0;
20290
+ }
20291
+ const previousParagraph = previous?.paragraph;
20292
+ if (previousParagraph?.numbering) {
20293
+ const previousKind = getListKind(catalog, previousParagraph.numbering.numberingInstanceId);
20149
20294
  if (previousKind === kind) {
20150
- return previous.numbering.numberingInstanceId;
20295
+ return previousParagraph.numbering.numberingInstanceId;
20151
20296
  }
20152
20297
  }
20153
20298
  return void 0;
20154
20299
  }
20155
20300
  function findPreviousCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
20301
+ const storyKey2 = paragraphs[fromIndex]?.storyKey;
20156
20302
  for (let index = fromIndex - 1; index >= 0; index -= 1) {
20157
- const paragraph = paragraphs[index];
20303
+ const entry = paragraphs[index];
20304
+ if (entry?.storyKey !== storyKey2) {
20305
+ break;
20306
+ }
20307
+ const paragraph = entry.paragraph;
20158
20308
  if (!paragraph?.numbering) {
20159
20309
  continue;
20160
20310
  }
@@ -20173,7 +20323,14 @@ function cloneEnvelope(document2, timestamp) {
20173
20323
  function captureEditableParagraphs(document2) {
20174
20324
  if (isDocumentRoot(document2.content)) {
20175
20325
  const paragraphs = [];
20176
- collectEditableParagraphs(document2.content.children, paragraphs);
20326
+ for (const context of collectStoryBlockContexts(document2)) {
20327
+ collectEditableParagraphs(
20328
+ context.blocks,
20329
+ paragraphs,
20330
+ context.storyKey,
20331
+ context.basePath
20332
+ );
20333
+ }
20177
20334
  return paragraphs;
20178
20335
  }
20179
20336
  const fallback = {
@@ -20181,23 +20338,39 @@ function captureEditableParagraphs(document2) {
20181
20338
  children: [{ type: "paragraph", children: [] }]
20182
20339
  };
20183
20340
  document2.content = fallback;
20184
- return fallback.children;
20341
+ return [{
20342
+ paragraph: fallback.children[0],
20343
+ storyKey: "main",
20344
+ blockPath: "main/block[0]"
20345
+ }];
20185
20346
  }
20186
- function collectEditableParagraphs(blocks, output) {
20187
- for (const block of blocks) {
20347
+ function collectEditableParagraphs(blocks, output, storyKey2, basePath) {
20348
+ for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
20349
+ const block = blocks[blockIndex];
20350
+ if (!block) continue;
20351
+ const blockPath = `${basePath}/block[${blockIndex}]`;
20188
20352
  switch (block.type) {
20189
20353
  case "paragraph":
20190
- output.push(block);
20354
+ output.push({ paragraph: block, storyKey: storyKey2, blockPath });
20191
20355
  break;
20192
20356
  case "table":
20193
- for (const row2 of block.rows) {
20194
- for (const cell of row2.cells) {
20195
- collectEditableParagraphs(cell.children, output);
20357
+ for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
20358
+ const row2 = block.rows[rowIndex];
20359
+ if (!row2) continue;
20360
+ for (let cellIndex = 0; cellIndex < row2.cells.length; cellIndex += 1) {
20361
+ const cell = row2.cells[cellIndex];
20362
+ if (!cell) continue;
20363
+ collectEditableParagraphs(
20364
+ cell.children,
20365
+ output,
20366
+ storyKey2,
20367
+ `${blockPath}/row[${rowIndex}]/cell[${cellIndex}]`
20368
+ );
20196
20369
  }
20197
20370
  }
20198
20371
  break;
20199
20372
  case "sdt":
20200
- collectEditableParagraphs(block.children, output);
20373
+ collectEditableParagraphs(block.children, output, storyKey2, blockPath);
20201
20374
  break;
20202
20375
  case "custom_xml":
20203
20376
  break;
@@ -20209,6 +20382,18 @@ function collectEditableParagraphs(blocks, output) {
20209
20382
  function normalizeParagraphIndexes(paragraphs, paragraphIndexes) {
20210
20383
  return [...new Set(paragraphIndexes)].filter((index) => Number.isInteger(index) && index >= 0 && index < paragraphs.length).sort((left, right) => left - right);
20211
20384
  }
20385
+ function normalizeParagraphIndexesForStory(paragraphs, paragraphIndexes, storyKey2) {
20386
+ if (storyKey2 === void 0) {
20387
+ return normalizeParagraphIndexes(paragraphs, paragraphIndexes);
20388
+ }
20389
+ const storyParagraphIndexes = [];
20390
+ for (let index = 0; index < paragraphs.length; index += 1) {
20391
+ if (paragraphs[index]?.storyKey === storyKey2) {
20392
+ storyParagraphIndexes.push(index);
20393
+ }
20394
+ }
20395
+ return [...new Set(paragraphIndexes)].filter((index) => Number.isInteger(index) && index >= 0 && index < storyParagraphIndexes.length).map((index) => storyParagraphIndexes[index]).sort((left, right) => left - right);
20396
+ }
20212
20397
  function clampLevel(level) {
20213
20398
  return Math.max(0, Math.min(8, level));
20214
20399
  }
@@ -20890,8 +21075,9 @@ function applyFragmentInsert(document2, selection, fragment, context) {
20890
21075
  workingDocument = collapseResult.document;
20891
21076
  workingSelection = collapseResult.selection;
20892
21077
  if (context.textTarget?.kind === "table-paragraph" || context.textTarget?.kind === "text-leaf") {
21078
+ const { precomputedSurface: _precomputedSurface, ...contextWithoutPrecomputedSurface } = context;
20893
21079
  workingContext = {
20894
- ...context,
21080
+ ...contextWithoutPrecomputedSurface,
20895
21081
  textTarget: {
20896
21082
  ...context.textTarget,
20897
21083
  paragraphEnd: Math.max(
@@ -20903,7 +21089,11 @@ function applyFragmentInsert(document2, selection, fragment, context) {
20903
21089
  }
20904
21090
  }
20905
21091
  const splitResult = splitParagraph(workingDocument, workingSelection, workingContext);
20906
- const splitRoot = splitResult.document.content;
21092
+ const preparedFragment = prepareFragmentNumberingForInsertion(
21093
+ splitResult.document,
21094
+ fragment
21095
+ );
21096
+ const splitRoot = preparedFragment.document.content;
20907
21097
  if (!splitRoot || splitRoot.type !== "doc") {
20908
21098
  return {
20909
21099
  changed: false,
@@ -20914,9 +21104,9 @@ function applyFragmentInsert(document2, selection, fragment, context) {
20914
21104
  const targetedBlockPath = workingContext.textTarget?.kind === "table-paragraph" || workingContext.textTarget?.kind === "text-leaf" ? workingContext.textTarget.blockPath : void 0;
20915
21105
  if (targetedBlockPath) {
20916
21106
  const targeted = insertFragmentBlocksAfterPath(
20917
- splitResult.document,
21107
+ preparedFragment.document,
20918
21108
  targetedBlockPath,
20919
- fragment.blocks
21109
+ preparedFragment.blocks
20920
21110
  );
20921
21111
  if (targeted) {
20922
21112
  return {
@@ -20948,7 +21138,7 @@ function applyFragmentInsert(document2, selection, fragment, context) {
20948
21138
  const rightHalfIndex = scope.blockIndex + 1;
20949
21139
  const splicedChildren = [
20950
21140
  ...splitRoot.children.slice(0, rightHalfIndex),
20951
- ...fragment.blocks.map((block) => cloneBlock(block)),
21141
+ ...preparedFragment.blocks.map((block) => cloneBlock(block)),
20952
21142
  ...splitRoot.children.slice(rightHalfIndex)
20953
21143
  ];
20954
21144
  const nextRoot = {
@@ -20956,7 +21146,7 @@ function applyFragmentInsert(document2, selection, fragment, context) {
20956
21146
  children: splicedChildren
20957
21147
  };
20958
21148
  const nextDocument = {
20959
- ...splitResult.document,
21149
+ ...preparedFragment.document,
20960
21150
  updatedAt: context.timestamp,
20961
21151
  content: nextRoot
20962
21152
  };
@@ -20968,14 +21158,47 @@ function applyFragmentInsert(document2, selection, fragment, context) {
20968
21158
  mapping: createEmptyMapping()
20969
21159
  };
20970
21160
  }
20971
- function cloneBlock(block) {
20972
- if (block.type === "paragraph") {
20973
- return {
20974
- ...block,
20975
- children: block.children.map((child) => ({ ...child }))
21161
+ function prepareFragmentNumberingForInsertion(document2, fragment) {
21162
+ if (!fragment.numbering) {
21163
+ return { document: document2, blocks: fragment.blocks };
21164
+ }
21165
+ const merged = mergeFragmentNumberingCatalog(document2.numbering, fragment.numbering);
21166
+ return {
21167
+ document: {
21168
+ ...document2,
21169
+ numbering: merged.catalog
21170
+ },
21171
+ blocks: fragment.blocks.map((block) => cloneBlock(block, merged.instanceIdMap))
21172
+ };
21173
+ }
21174
+ function cloneBlock(block, numberingInstanceIdMap) {
21175
+ const cloned = structuredClone(block);
21176
+ remapNumberingReferences(cloned, numberingInstanceIdMap);
21177
+ return cloned;
21178
+ }
21179
+ function remapNumberingReferences(value, numberingInstanceIdMap) {
21180
+ if (!numberingInstanceIdMap?.size || !value || typeof value !== "object") {
21181
+ return;
21182
+ }
21183
+ if (Array.isArray(value)) {
21184
+ for (const entry of value) {
21185
+ remapNumberingReferences(entry, numberingInstanceIdMap);
21186
+ }
21187
+ return;
21188
+ }
21189
+ const record = value;
21190
+ if (record.numbering?.numberingInstanceId) {
21191
+ const mappedId = numberingInstanceIdMap.get(record.numbering.numberingInstanceId) ?? record.numbering.numberingInstanceId;
21192
+ record.numbering = {
21193
+ ...record.numbering,
21194
+ numberingInstanceId: mappedId
20976
21195
  };
20977
21196
  }
20978
- return JSON.parse(JSON.stringify(block));
21197
+ remapNumberingReferences(record.children, numberingInstanceIdMap);
21198
+ remapNumberingReferences(record.rows, numberingInstanceIdMap);
21199
+ remapNumberingReferences(record.cells, numberingInstanceIdMap);
21200
+ remapNumberingReferences(record.txbxBlocks, numberingInstanceIdMap);
21201
+ remapNumberingReferences(record.content, numberingInstanceIdMap);
20979
21202
  }
20980
21203
  function insertFragmentBlocksAfterPath(document2, blockPath, fragmentBlocks) {
20981
21204
  const tokens = parseCanonicalBlockPath2(blockPath);
@@ -49192,6 +49415,16 @@ function coerceIssueValue2(value) {
49192
49415
  function insertScopeMarkers(document2, params) {
49193
49416
  const { scopeId } = params;
49194
49417
  const root = document2.content;
49418
+ if (!Number.isFinite(params.from) || !Number.isFinite(params.to)) {
49419
+ const from = Number.isFinite(params.from) ? params.from : 0;
49420
+ const to = Number.isFinite(params.to) ? params.to : from;
49421
+ return {
49422
+ status: "non-finite-range",
49423
+ scopeId,
49424
+ from,
49425
+ to
49426
+ };
49427
+ }
49195
49428
  const normalizedFrom = Math.min(params.from, params.to);
49196
49429
  const normalizedTo = Math.max(params.from, params.to);
49197
49430
  if (!root || root.type !== "doc" || root.children.length === 0) {
@@ -49644,6 +49877,14 @@ function isRecord3(value) {
49644
49877
  }
49645
49878
 
49646
49879
  // src/runtime/workflow/coordinator.ts
49880
+ function createScopeMarkerMutationMapping() {
49881
+ return {
49882
+ steps: [],
49883
+ metadata: {
49884
+ layoutNeutralScopeMarkers: true
49885
+ }
49886
+ };
49887
+ }
49647
49888
  var MODE_RESTRICTIVENESS = {
49648
49889
  edit: 0,
49649
49890
  suggest: 1,
@@ -49951,6 +50192,60 @@ function createWorkflowCoordinator(deps) {
49951
50192
  activeStory: deps.getActiveStory()
49952
50193
  };
49953
50194
  }
50195
+ function createPlantFailureResult(input) {
50196
+ const { scopeId, anchor, assoc, plantResult } = input;
50197
+ return {
50198
+ scopeId: "",
50199
+ anchor: {
50200
+ kind: "range",
50201
+ from: anchor.from,
50202
+ to: anchor.to,
50203
+ assoc
50204
+ },
50205
+ plantStatus: {
50206
+ planted: false,
50207
+ reason: plantResult.status,
50208
+ ...plantResult.status === "non-paragraph-target" ? {
50209
+ blockIndex: plantResult.blockIndex,
50210
+ blockKind: plantResult.blockKind
50211
+ } : {},
50212
+ ...plantResult.status === "range-out-of-bounds" ? { storyLength: plantResult.storyLength } : {},
50213
+ requestedFrom: plantResult.from,
50214
+ requestedTo: plantResult.to
50215
+ }
50216
+ };
50217
+ }
50218
+ function buildWorkflowScope(input) {
50219
+ const { params, scopeId, publicAnchor } = input;
50220
+ return {
50221
+ scopeId,
50222
+ mode: params.mode ?? "comment",
50223
+ anchor: publicAnchor,
50224
+ ...params.storyTarget ? { storyTarget: params.storyTarget } : {},
50225
+ ...params.label ? { label: params.label } : {},
50226
+ ...params.visibility ? { visibility: params.visibility } : {},
50227
+ ...params.guardPolicy ? { guardPolicy: params.guardPolicy } : {},
50228
+ ...params.scopeMetadataFields && params.scopeMetadataFields.length > 0 ? { metadata: [...params.scopeMetadataFields] } : {}
50229
+ };
50230
+ }
50231
+ function buildWorkflowMetadataEntry(input) {
50232
+ const { params, scopeId, publicAnchor } = input;
50233
+ if (!params.persistence || params.persistence === "runtime-only") return null;
50234
+ const requestedMetadata = params.metadata ?? {};
50235
+ const entryPersistence = requestedMetadata.metadataPersistence ?? (params.persistence === "session" ? "external" : "internal");
50236
+ return {
50237
+ entryId: requestedMetadata.entryId ?? `scope-metadata-${scopeId}`,
50238
+ metadataId: requestedMetadata.metadataId ?? "workflow.scope",
50239
+ anchor: publicAnchor,
50240
+ ...params.storyTarget ? { storyTarget: params.storyTarget } : {},
50241
+ scopeId,
50242
+ ...requestedMetadata.workItemId ? { workItemId: requestedMetadata.workItemId } : {},
50243
+ ...requestedMetadata.value !== void 0 ? { value: requestedMetadata.value } : params.persistence === "document-metadata" && params.label ? { value: { label: params.label } } : {},
50244
+ metadataPersistence: entryPersistence,
50245
+ ...requestedMetadata.storageRef !== void 0 ? { storageRef: requestedMetadata.storageRef } : {},
50246
+ ...requestedMetadata.metadataVersion !== void 0 ? { metadataVersion: requestedMetadata.metadataVersion } : {}
50247
+ };
50248
+ }
49954
50249
  function addScope(params) {
49955
50250
  const state = deps.getState();
49956
50251
  const scopeId = params.scopeId ?? `scope-${clock().replace(/[^0-9]/gu, "")}-${Math.floor(Math.random() * 1e6)}`;
@@ -49993,6 +50288,7 @@ function createWorkflowCoordinator(deps) {
49993
50288
  deps.dispatch({
49994
50289
  type: "document.replace",
49995
50290
  document: nextDocument,
50291
+ mapping: createScopeMarkerMutationMapping(),
49996
50292
  origin: { source: "api", at: clock() }
49997
50293
  });
49998
50294
  const callerAssoc = params.anchor.kind === "range" ? params.anchor.assoc : { start: -1, end: 1 };
@@ -50049,6 +50345,84 @@ function createWorkflowCoordinator(deps) {
50049
50345
  }
50050
50346
  return { scopeId, anchor: publicAnchor };
50051
50347
  }
50348
+ function addScopes(paramsList) {
50349
+ if (paramsList.length === 0) return [];
50350
+ let nextDocument = deps.getDocument();
50351
+ let documentChanged = false;
50352
+ const results = [];
50353
+ const scopesToAdd = [];
50354
+ const metadataEntriesToAdd = [];
50355
+ const newScopeIds = /* @__PURE__ */ new Set();
50356
+ for (const params of paramsList) {
50357
+ const scopeId = params.scopeId ?? `scope-${clock().replace(/[^0-9]/gu, "")}-${Math.floor(Math.random() * 1e6)}`;
50358
+ const anchor = params.anchor.kind === "range" ? { from: params.anchor.from, to: params.anchor.to } : null;
50359
+ if (!anchor) {
50360
+ results.push({ scopeId, anchor: params.anchor });
50361
+ continue;
50362
+ }
50363
+ const callerAssoc = params.anchor.kind === "range" ? params.anchor.assoc : { start: -1, end: 1 };
50364
+ const plantResult = insertScopeMarkers(nextDocument, {
50365
+ scopeId,
50366
+ from: anchor.from,
50367
+ to: anchor.to
50368
+ });
50369
+ if (plantResult.status !== "planted") {
50370
+ results.push(
50371
+ createPlantFailureResult({
50372
+ scopeId,
50373
+ anchor,
50374
+ assoc: callerAssoc,
50375
+ plantResult
50376
+ })
50377
+ );
50378
+ continue;
50379
+ }
50380
+ nextDocument = plantResult.document;
50381
+ documentChanged = true;
50382
+ const publicAnchor = {
50383
+ kind: "range",
50384
+ from: plantResult.plantedRange.from,
50385
+ to: plantResult.plantedRange.to,
50386
+ assoc: callerAssoc
50387
+ };
50388
+ newScopeIds.add(scopeId);
50389
+ scopesToAdd.push(buildWorkflowScope({ params, scopeId, publicAnchor }));
50390
+ const entry = buildWorkflowMetadataEntry({ params, scopeId, publicAnchor });
50391
+ if (entry) metadataEntriesToAdd.push(entry);
50392
+ results.push({ scopeId, anchor: publicAnchor });
50393
+ }
50394
+ if (documentChanged) {
50395
+ deps.dispatch({
50396
+ type: "document.replace",
50397
+ document: nextDocument,
50398
+ mapping: createScopeMarkerMutationMapping(),
50399
+ origin: { source: "api", at: clock() }
50400
+ });
50401
+ }
50402
+ if (scopesToAdd.length > 0) {
50403
+ const currentOverlay = overlayStore.getOverlay() ?? {
50404
+ overlayVersion: "workflow-overlay/1",
50405
+ scopes: []
50406
+ };
50407
+ const existingScopes = currentOverlay.scopes.filter(
50408
+ (existing) => !newScopeIds.has(existing.scopeId)
50409
+ );
50410
+ deps.dispatch({
50411
+ type: "workflow.set-overlay",
50412
+ overlay: { ...currentOverlay, scopes: [...existingScopes, ...scopesToAdd] },
50413
+ origin: { source: "api", at: clock() }
50414
+ });
50415
+ }
50416
+ if (metadataEntriesToAdd.length > 0) {
50417
+ const priorEntries = overlayStore.getMetadataEntries();
50418
+ deps.dispatch({
50419
+ type: "workflow.set-metadata-entries",
50420
+ entries: [...priorEntries, ...metadataEntriesToAdd],
50421
+ origin: { source: "api", at: clock() }
50422
+ });
50423
+ }
50424
+ return results;
50425
+ }
50052
50426
  function removeScope(scopeId) {
50053
50427
  const overlay = overlayStore.getOverlay();
50054
50428
  if (overlay) {
@@ -50066,6 +50440,7 @@ function createWorkflowCoordinator(deps) {
50066
50440
  deps.dispatch({
50067
50441
  type: "document.replace",
50068
50442
  document: nextDocument,
50443
+ mapping: createScopeMarkerMutationMapping(),
50069
50444
  origin: { source: "api", at: clock() }
50070
50445
  });
50071
50446
  }
@@ -50459,6 +50834,7 @@ function createWorkflowCoordinator(deps) {
50459
50834
  }
50460
50835
  return {
50461
50836
  addScope,
50837
+ addScopes,
50462
50838
  removeScope,
50463
50839
  addInvisibleScope,
50464
50840
  setScopeVisibility,
@@ -58299,6 +58675,17 @@ function createDocumentRuntime(options) {
58299
58675
  };
58300
58676
  resolvedReplayTextTarget = prepared.textTarget;
58301
58677
  } else {
58678
+ const listBoundaryJoinCommand = createListItemBoundaryJoinReplayCommand({
58679
+ command,
58680
+ document: replayState.document,
58681
+ selection: replayState.selection,
58682
+ surface: replaySnapshot.surface?.blocks ?? [],
58683
+ storyTarget: replayStory,
58684
+ timestamp: context.timestamp
58685
+ });
58686
+ if (listBoundaryJoinCommand) {
58687
+ executableCommand = listBoundaryJoinCommand;
58688
+ }
58302
58689
  const selectedListItemDeleteCommand = createSelectedListItemDeleteReplayCommand({
58303
58690
  command,
58304
58691
  document: replayState.document,
@@ -58456,6 +58843,17 @@ function createDocumentRuntime(options) {
58456
58843
  };
58457
58844
  resolvedReplayTextTarget = prepared.textTarget;
58458
58845
  } else {
58846
+ const listBoundaryJoinCommand = createListItemBoundaryJoinReplayCommand({
58847
+ command,
58848
+ document: stateForCommand.document,
58849
+ selection: stateForCommand.selection,
58850
+ surface: snapshotForCommand.surface?.blocks ?? [],
58851
+ storyTarget: replayStory,
58852
+ timestamp: context.timestamp
58853
+ });
58854
+ if (listBoundaryJoinCommand) {
58855
+ executableCommand = listBoundaryJoinCommand;
58856
+ }
58459
58857
  const selectedListItemDeleteCommand = createSelectedListItemDeleteReplayCommand({
58460
58858
  command,
58461
58859
  document: stateForCommand.document,
@@ -59485,6 +59883,9 @@ function createDocumentRuntime(options) {
59485
59883
  addScope(params) {
59486
59884
  return workflowCoordinator.addScope(params);
59487
59885
  },
59886
+ addScopes(params) {
59887
+ return workflowCoordinator.addScopes(params);
59888
+ },
59488
59889
  getScope(scopeId) {
59489
59890
  return workflowCoordinator.getScope(scopeId);
59490
59891
  },
@@ -60468,6 +60869,9 @@ function createDocumentRuntime(options) {
60468
60869
  if (transaction.mapping.metadata?.scopeTagTouches) return false;
60469
60870
  return getLocalTextPatchMetadata(transaction.mapping) !== null;
60470
60871
  }
60872
+ function isLayoutNeutralScopeMarkerCommit(previous, next, transaction) {
60873
+ return transaction.markDirty && previous.document !== next.document && transaction.mapping.steps.length === 0 && transaction.mapping.metadata?.layoutNeutralScopeMarkers === true;
60874
+ }
60471
60875
  function applyTransactionToState(transaction, options2 = {}) {
60472
60876
  const effects = transaction.effects;
60473
60877
  const selectionUnchanged = transaction.nextState.selection === state.selection;
@@ -60496,6 +60900,11 @@ function createDocumentRuntime(options) {
60496
60900
  transaction,
60497
60901
  transaction.effects
60498
60902
  );
60903
+ const layoutNeutralScopeMarkerCommit = isLayoutNeutralScopeMarkerCommit(
60904
+ previous,
60905
+ state,
60906
+ transaction
60907
+ );
60499
60908
  perfCounters.increment("commit.refreshClassify.us", Math.round((performance.now() - tClassify0) * 1e3));
60500
60909
  const tOverlay0 = performance.now();
60501
60910
  const skipOverlaySync = useLocalTextCommitSnapshot && canSkipOverlaySyncForLocalText(transaction);
@@ -60544,9 +60953,12 @@ function createDocumentRuntime(options) {
60544
60953
  ...detachedWorkflowScopeWarnings.cleared
60545
60954
  ]
60546
60955
  };
60547
- if (!useLocalTextCommitSnapshot && transaction.markDirty && previous.document !== state.document) {
60956
+ if (!useLocalTextCommitSnapshot && !layoutNeutralScopeMarkerCommit && transaction.markDirty && previous.document !== state.document) {
60548
60957
  applyViewportRanges(getSelectionCorridorViewportRanges(cachedRenderSnapshot.surface));
60549
60958
  }
60959
+ if (layoutNeutralScopeMarkerCommit && viewportBlockRanges !== null) {
60960
+ getCachedFullSurface(state.document, activeStory);
60961
+ }
60550
60962
  const tValidation0 = performance.now();
60551
60963
  const patchSourceSurface = getReusableCachedFullSurface(previous.document, activeStory) ?? cachedRenderSnapshot.surface;
60552
60964
  const patchedFullLocalTextSurface = useLocalTextCommitSnapshot ? tryPatchLocalTextSurface(patchSourceSurface, transaction.mapping) : null;
@@ -60915,6 +61327,39 @@ function createDocumentRuntime(options) {
60915
61327
  const preSelection = selection;
60916
61328
  const preActiveStory = activeStory;
60917
61329
  const priorDocument = state.document;
61330
+ const listBoundaryJoin = createListItemBoundaryJoinReplacement({
61331
+ command: commandForDispatch,
61332
+ document: state.document,
61333
+ editableTarget,
61334
+ selection,
61335
+ storyTarget: activeStory,
61336
+ targetResolution,
61337
+ timestamp
61338
+ });
61339
+ if (listBoundaryJoin && context.documentMode !== "suggesting") {
61340
+ const replacementCommand = {
61341
+ type: "document.replace",
61342
+ document: listBoundaryJoin.document,
61343
+ selection: listBoundaryJoin.selection,
61344
+ mapping: listBoundaryJoin.mapping,
61345
+ protectionSelection: selection,
61346
+ origin: commandForDispatch.origin
61347
+ };
61348
+ const transaction = executeEditorCommand(baseState, replacementCommand, context);
61349
+ commit(transaction);
61350
+ options.onCommandApplied?.(commandForDispatch, transaction, context, {
61351
+ preSelection,
61352
+ activeStory: preActiveStory,
61353
+ priorDocument
61354
+ });
61355
+ return completeDispatch(classifyAck({
61356
+ command: commandForDispatch,
61357
+ opId,
61358
+ priorState: baseState,
61359
+ transaction,
61360
+ newRevisionToken: state.revisionToken
61361
+ }));
61362
+ }
60918
61363
  const selectedListItemDelete = createSelectedListItemDeleteReplacement({
60919
61364
  command: commandForDispatch,
60920
61365
  document: state.document,
@@ -63831,6 +64276,56 @@ function stripStoryTarget(selection) {
63831
64276
  function isTopLevelMainStoryBlockPath(blockPath) {
63832
64277
  return typeof blockPath === "string" && /^main\/block\[\d+\]$/u.test(blockPath);
63833
64278
  }
64279
+ function createListItemBoundaryJoinReplacement(input) {
64280
+ const { command, document: document2, editableTarget, selection, storyTarget, targetResolution, timestamp } = input;
64281
+ const direction = listItemBoundaryJoinDirection(command, selection, targetResolution);
64282
+ if (!direction || editableTarget?.listAddress?.operationScope !== "list-text" || targetResolution?.kind !== "accepted") {
64283
+ return null;
64284
+ }
64285
+ const storyBlocks = getStoryBlocks(document2, storyTarget);
64286
+ const replacement = joinNumberedParagraphAtStoryPath(
64287
+ storyBlocks,
64288
+ editableTarget.blockPath,
64289
+ storyTarget,
64290
+ direction
64291
+ );
64292
+ if (!replacement) {
64293
+ return null;
64294
+ }
64295
+ const nextDocument = replaceStoryBlocks({
64296
+ ...document2,
64297
+ updatedAt: timestamp
64298
+ }, storyTarget, replacement.blocks);
64299
+ const deletedFrom = direction === "backward" ? Math.max(0, selection.anchor - 1) : selection.anchor;
64300
+ const deletedTo = direction === "backward" ? selection.anchor : selection.anchor + 1;
64301
+ const nextAnchor = direction === "backward" ? deletedFrom : selection.anchor;
64302
+ return {
64303
+ document: nextDocument,
64304
+ selection: createSelectionSnapshot(nextAnchor, nextAnchor),
64305
+ mapping: {
64306
+ steps: [{
64307
+ from: deletedFrom,
64308
+ to: deletedTo,
64309
+ insertSize: 0
64310
+ }],
64311
+ metadata: {
64312
+ invalidatesStructures: true
64313
+ }
64314
+ }
64315
+ };
64316
+ }
64317
+ function listItemBoundaryJoinDirection(command, selection, targetResolution) {
64318
+ if (selection.isCollapsed !== true || targetResolution?.kind !== "accepted") {
64319
+ return null;
64320
+ }
64321
+ if (command.type === "text.delete-backward" && selection.anchor === targetResolution.range.from) {
64322
+ return "backward";
64323
+ }
64324
+ if (command.type === "text.delete-forward" && selection.anchor === targetResolution.range.to) {
64325
+ return "forward";
64326
+ }
64327
+ return null;
64328
+ }
63834
64329
  function createSelectedListItemDeleteReplacement(input) {
63835
64330
  const { command, document: document2, editableTarget, selection, storyTarget, targetResolution, timestamp } = input;
63836
64331
  if (command.type !== "text.delete-backward" && command.type !== "text.delete-forward") {
@@ -63878,6 +64373,152 @@ function removeNumberedParagraphAtStoryPath(blocks, blockPath, storyTarget) {
63878
64373
  if (!tokens) return null;
63879
64374
  return removeNumberedParagraphFromBlocks(blocks, tokens);
63880
64375
  }
64376
+ function joinNumberedParagraphAtStoryPath(blocks, blockPath, storyTarget, direction) {
64377
+ const tokens = parseStoryBlockPathTokens(blockPath, storyTarget);
64378
+ if (!tokens) return null;
64379
+ return joinNumberedParagraphFromBlocks(blocks, tokens, direction);
64380
+ }
64381
+ function joinNumberedParagraphFromBlocks(blocks, tokens, direction) {
64382
+ const [token, ...rest] = tokens;
64383
+ if (!token || token.kind !== "block") return null;
64384
+ const block = blocks[token.index];
64385
+ if (!block) return null;
64386
+ if (rest.length === 0) {
64387
+ return joinAdjacentNumberedParagraphs(blocks, token.index, direction);
64388
+ }
64389
+ const next = rest[0];
64390
+ if (block.type === "table" && next?.kind === "row") {
64391
+ const updatedTable = joinNumberedParagraphInTable(block, rest, direction);
64392
+ if (!updatedTable) return null;
64393
+ return {
64394
+ blocks: [
64395
+ ...blocks.slice(0, token.index),
64396
+ updatedTable,
64397
+ ...blocks.slice(token.index + 1)
64398
+ ]
64399
+ };
64400
+ }
64401
+ if ((block.type === "sdt" || block.type === "custom_xml") && next?.kind === "block") {
64402
+ const updatedChildren = joinNumberedParagraphFromBlocks(block.children, rest, direction);
64403
+ if (!updatedChildren) return null;
64404
+ return {
64405
+ blocks: [
64406
+ ...blocks.slice(0, token.index),
64407
+ { ...block, children: updatedChildren.blocks },
64408
+ ...blocks.slice(token.index + 1)
64409
+ ]
64410
+ };
64411
+ }
64412
+ if (block.type === "paragraph" && next?.kind === "inline") {
64413
+ const updatedParagraph = joinNumberedParagraphInTextBoxInline(block, rest, direction);
64414
+ if (!updatedParagraph) return null;
64415
+ return {
64416
+ blocks: [
64417
+ ...blocks.slice(0, token.index),
64418
+ updatedParagraph,
64419
+ ...blocks.slice(token.index + 1)
64420
+ ]
64421
+ };
64422
+ }
64423
+ return null;
64424
+ }
64425
+ function joinAdjacentNumberedParagraphs(blocks, targetIndex, direction) {
64426
+ const target = blocks[targetIndex];
64427
+ if (target?.type !== "paragraph" || !target.numbering) {
64428
+ return null;
64429
+ }
64430
+ if (direction === "backward") {
64431
+ const previousIndex = targetIndex - 1;
64432
+ const previous = blocks[previousIndex];
64433
+ if (previous?.type !== "paragraph" || !previous.numbering) {
64434
+ return null;
64435
+ }
64436
+ const merged2 = {
64437
+ ...previous,
64438
+ children: [...previous.children, ...target.children]
64439
+ };
64440
+ return {
64441
+ blocks: [
64442
+ ...blocks.slice(0, previousIndex),
64443
+ merged2,
64444
+ ...blocks.slice(targetIndex + 1)
64445
+ ]
64446
+ };
64447
+ }
64448
+ const nextIndex = targetIndex + 1;
64449
+ const next = blocks[nextIndex];
64450
+ if (next?.type !== "paragraph" || !next.numbering) {
64451
+ return null;
64452
+ }
64453
+ const merged = {
64454
+ ...target,
64455
+ children: [...target.children, ...next.children]
64456
+ };
64457
+ return {
64458
+ blocks: [
64459
+ ...blocks.slice(0, targetIndex),
64460
+ merged,
64461
+ ...blocks.slice(nextIndex + 1)
64462
+ ]
64463
+ };
64464
+ }
64465
+ function joinNumberedParagraphInTable(table, tokens, direction) {
64466
+ const [rowToken, cellToken, ...childTokens] = tokens;
64467
+ if (rowToken?.kind !== "row" || cellToken?.kind !== "cell" || childTokens[0]?.kind !== "block") {
64468
+ return null;
64469
+ }
64470
+ const row2 = table.rows[rowToken.index];
64471
+ const cell = row2?.cells[cellToken.index];
64472
+ if (!row2 || !cell) return null;
64473
+ const updatedChildren = joinNumberedParagraphFromBlocks(cell.children, childTokens, direction);
64474
+ if (!updatedChildren) return null;
64475
+ const nextCells = [
64476
+ ...row2.cells.slice(0, cellToken.index),
64477
+ { ...cell, children: updatedChildren.blocks },
64478
+ ...row2.cells.slice(cellToken.index + 1)
64479
+ ];
64480
+ const nextRows = [
64481
+ ...table.rows.slice(0, rowToken.index),
64482
+ { ...row2, cells: nextCells },
64483
+ ...table.rows.slice(rowToken.index + 1)
64484
+ ];
64485
+ return { ...table, rows: nextRows };
64486
+ }
64487
+ function joinNumberedParagraphInTextBoxInline(paragraph, tokens, direction) {
64488
+ const [inlineToken, textBoxToken, ...childTokens] = tokens;
64489
+ if (inlineToken?.kind !== "inline" || textBoxToken?.kind !== "txbx" || childTokens[0]?.kind !== "block") {
64490
+ return null;
64491
+ }
64492
+ const inline = paragraph.children[inlineToken.index];
64493
+ if (!inline) return null;
64494
+ const updatedInline = joinNumberedParagraphInInlineTextBox(inline, childTokens, direction);
64495
+ if (!updatedInline) return null;
64496
+ return {
64497
+ ...paragraph,
64498
+ children: [
64499
+ ...paragraph.children.slice(0, inlineToken.index),
64500
+ updatedInline,
64501
+ ...paragraph.children.slice(inlineToken.index + 1)
64502
+ ]
64503
+ };
64504
+ }
64505
+ function joinNumberedParagraphInInlineTextBox(inline, tokens, direction) {
64506
+ if (inline.type === "shape" && inline.txbxBlocks) {
64507
+ const updatedBlocks = joinNumberedParagraphFromBlocks(inline.txbxBlocks, tokens, direction);
64508
+ return updatedBlocks ? { ...inline, txbxBlocks: updatedBlocks.blocks } : null;
64509
+ }
64510
+ if (inline.type === "drawing_frame" && inline.content.type === "shape" && inline.content.txbxBlocks) {
64511
+ const updatedBlocks = joinNumberedParagraphFromBlocks(inline.content.txbxBlocks, tokens, direction);
64512
+ return updatedBlocks ? {
64513
+ ...inline,
64514
+ content: {
64515
+ ...inline.content,
64516
+ txbxBlocks: updatedBlocks.blocks
64517
+ }
64518
+ } : null;
64519
+ }
64520
+ return null;
64521
+ }
63881
64522
  function removeNumberedParagraphFromBlocks(blocks, tokens) {
63882
64523
  const [token, ...rest] = tokens;
63883
64524
  if (!token || token.kind !== "block") return null;
@@ -64040,6 +64681,56 @@ function createSelectedListItemDeleteReplayCommand(input) {
64040
64681
  origin: command.origin
64041
64682
  };
64042
64683
  }
64684
+ function createListItemBoundaryJoinReplayCommand(input) {
64685
+ const { command, document: document2, selection, surface, storyTarget, timestamp } = input;
64686
+ if (command.type !== "text.delete-backward" && command.type !== "text.delete-forward") {
64687
+ return null;
64688
+ }
64689
+ const editableTarget = command.editableTarget;
64690
+ if (!editableTarget) {
64691
+ return null;
64692
+ }
64693
+ const targetResolution = resolveEditableTextTarget({
64694
+ document: document2,
64695
+ selection,
64696
+ surface,
64697
+ target: editableTarget,
64698
+ activeStoryKey: canonicalEditableTargetStoryKey(storyTarget)
64699
+ });
64700
+ const resolvedEditableTarget = targetResolution.kind === "accepted" ? editableTarget : storyTarget.kind !== "main" && blockPathBelongsToStoryTarget(editableTarget.blockPath, storyTarget) ? resolveEditableCommandTarget({
64701
+ document: document2,
64702
+ target: editableTarget,
64703
+ activeStoryKey: canonicalEditableTargetStoryKey(storyTarget),
64704
+ commandFamilies: ["text-leaf"]
64705
+ }) : null;
64706
+ const selectedRange = {
64707
+ from: Math.min(selection.anchor, selection.head),
64708
+ to: Math.max(selection.anchor, selection.head)
64709
+ };
64710
+ const replacement = createListItemBoundaryJoinReplacement({
64711
+ command,
64712
+ document: document2,
64713
+ editableTarget: resolvedEditableTarget && resolvedEditableTarget.kind === "accepted" ? resolvedEditableTarget.target : editableTarget,
64714
+ selection,
64715
+ storyTarget,
64716
+ targetResolution: resolvedEditableTarget && resolvedEditableTarget.kind === "accepted" ? {
64717
+ kind: "accepted",
64718
+ range: selectedRange
64719
+ } : targetResolution,
64720
+ timestamp
64721
+ });
64722
+ if (!replacement) {
64723
+ return null;
64724
+ }
64725
+ return {
64726
+ type: "document.replace",
64727
+ document: replacement.document,
64728
+ selection: replacement.selection,
64729
+ mapping: replacement.mapping,
64730
+ protectionSelection: selection,
64731
+ origin: command.origin
64732
+ };
64733
+ }
64043
64734
  function parseStoryBlockPathTokens(blockPath, storyTarget) {
64044
64735
  if (!blockPath) {
64045
64736
  return null;