@superdoc/mcp 1.6.1-next.1 → 1.6.1-next.2

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 (2) hide show
  1. package/dist/index.js +1018 -356
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31600,7 +31600,7 @@ var init_host = __esm(() => {
31600
31600
  });
31601
31601
 
31602
31602
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31603
- var SDK_VERSION = "2.19.1-next.1";
31603
+ var SDK_VERSION = "2.19.1-next.2";
31604
31604
 
31605
31605
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31606
31606
  import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
@@ -127288,7 +127288,8 @@ function buildStructuralBoundaryMap(bytes) {
127288
127288
  sdtOrdinal: sdtCounter,
127289
127289
  wrapperLocked: lockPolicy.wrapperLocked,
127290
127290
  contentLocked: lockPolicy.contentLocked,
127291
- contentEditable: !lockPolicy.contentLocked && isSdtContentEditable(sdtXml)
127291
+ contentEditable: !lockPolicy.contentLocked && isSdtContentEditable(sdtXml),
127292
+ textAtomic: isTextAtomicBlockSdt(sdtXml)
127292
127293
  });
127293
127294
  sdtCounter += 1;
127294
127295
  } else if (tag.local === "customXml") {
@@ -127311,6 +127312,7 @@ function recordParagraph2(input) {
127311
127312
  const blockCustomXmlPath = [];
127312
127313
  let hasLockedBlockSdt = false;
127313
127314
  let hasNonEditableBlockSdtContent = false;
127315
+ let hasTextAtomicBlockSdt = false;
127314
127316
  let hasContentLockedBlockSdt = false;
127315
127317
  let lastTable = -1;
127316
127318
  let lastRow = -1;
@@ -127330,6 +127332,7 @@ function recordParagraph2(input) {
127330
127332
  blockSdtPath.push(frame.sdtOrdinal);
127331
127333
  hasLockedBlockSdt || (hasLockedBlockSdt = frame.wrapperLocked);
127332
127334
  hasNonEditableBlockSdtContent || (hasNonEditableBlockSdtContent = !frame.contentEditable);
127335
+ hasTextAtomicBlockSdt || (hasTextAtomicBlockSdt = frame.textAtomic);
127333
127336
  hasContentLockedBlockSdt || (hasContentLockedBlockSdt = frame.contentLocked);
127334
127337
  } else if (frame.kind === "customXml") {
127335
127338
  blockCustomXmlPath.push(frame.customXmlOrdinal);
@@ -127342,6 +127345,7 @@ function recordParagraph2(input) {
127342
127345
  blockSdtPath,
127343
127346
  hasLockedBlockSdt,
127344
127347
  hasNonEditableBlockSdtContent,
127348
+ hasTextAtomicBlockSdt,
127345
127349
  hasContentLockedBlockSdt,
127346
127350
  blockCustomXmlPath,
127347
127351
  sectionIndex: input.sectionIndex,
@@ -127351,6 +127355,13 @@ function recordParagraph2(input) {
127351
127355
  carriesSectionBreak: carriesSectionBreak(input.paragraphXml)
127352
127356
  };
127353
127357
  }
127358
+ function isTextAtomicBlockSdt(sdtXml) {
127359
+ const contentMatch = /<(?:[\w.-]+:)?sdtContent\b/iu.exec(sdtXml);
127360
+ if (!contentMatch)
127361
+ return false;
127362
+ const properties = sdtXml.slice(0, contentMatch.index);
127363
+ return /<(?:[\w.-]+:)?(?:checkbox|dropDownList)\b/iu.test(properties);
127364
+ }
127354
127365
  function blockSdtLockPolicy(sdtXml) {
127355
127366
  const properties = /<(?:[\w.-]+:)?sdtPr\b[^>]*>([\s\S]*?)<\/(?:[\w.-]+:)?sdtPr\s*>/.exec(sdtXml)?.[1];
127356
127367
  if (!properties)
@@ -165856,7 +165867,7 @@ function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, c
165856
165867
  if (tocPlan)
165857
165868
  return tocPlan;
165858
165869
  if (startOffset === endOffset) {
165859
- const beside = planCollapsedInsertBesideContainer(paragraphBytes, xml, model.pieces, startOffset, newText);
165870
+ const beside = planCollapsedInsertBesideContainer(paragraphBytes, xml, model.pieces, startOffset, newText, collapsedInlineAffinity);
165860
165871
  if (beside)
165861
165872
  return beside;
165862
165873
  }
@@ -166330,19 +166341,22 @@ function planCollapsedInsert(paragraphBytes, xml, pieces, leaves, at, newText, t
166330
166341
  runPropertiesXml: carrier?.runProperties ?? paragraphMarkRPr
166331
166342
  };
166332
166343
  }
166333
- function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, newText) {
166344
+ function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, newText, collapsedInlineAffinity) {
166334
166345
  if (newText.length === 0)
166335
166346
  return null;
166336
166347
  for (const piece of pieces) {
166337
166348
  if (piece.kind !== "container")
166338
166349
  continue;
166339
- if (piece.containerKind !== "hyperlink" && piece.containerKind !== "fldSimple")
166350
+ if (piece.containerKind !== "hyperlink" && piece.containerKind !== "fldSimple" && piece.containerKind !== "sdt")
166340
166351
  continue;
166341
166352
  if (piece.visibleEnd <= piece.visibleStart)
166342
166353
  continue;
166343
166354
  const atLeading = piece.visibleStart === at && !hasVisibleSiblingEndingAt(pieces, at);
166344
166355
  const atTrailing = piece.visibleEnd === at && !hasVisibleSiblingStartingAt(pieces, at);
166345
- if (!atLeading && !atTrailing)
166356
+ const isSdt = piece.containerKind === "sdt";
166357
+ const leading = isSdt ? piece.visibleStart === at && collapsedInlineAffinity === "upstream" : atLeading;
166358
+ const trailing = isSdt ? piece.visibleEnd === at && collapsedInlineAffinity === "downstream" : atTrailing;
166359
+ if (!leading && !trailing)
166346
166360
  continue;
166347
166361
  const blocked = findBlockingPiece(pieces, at, at);
166348
166362
  if (blocked)
@@ -166354,7 +166368,7 @@ function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, new
166354
166368
  const freshRunQnames = paragraphRunQnames(xml);
166355
166369
  if (!freshRunQnames)
166356
166370
  return { ok: false, reason: "invalid-range" };
166357
- const insertByte = atLeading ? Math.min(piece.byteStart, ...leadingRangeStarts.map((marker) => marker.runByteStart ?? marker.byteStart)) : Math.max(piece.byteEnd, ...trailingRangeEnds.map((marker) => marker.runByteEnd ?? marker.byteEnd));
166371
+ const insertByte = leading ? Math.min(piece.byteStart, ...leadingRangeStarts.map((marker) => marker.runByteStart ?? marker.byteStart)) : Math.max(piece.byteEnd, ...trailingRangeEnds.map((marker) => marker.runByteEnd ?? marker.byteEnd));
166358
166372
  const op = {
166359
166373
  start: insertByte,
166360
166374
  end: insertByte,
@@ -166363,7 +166377,8 @@ function planCollapsedInsertBesideContainer(paragraphBytes, xml, pieces, at, new
166363
166377
  return {
166364
166378
  ok: true,
166365
166379
  bytes: spliceBytes(paragraphBytes, [op]),
166366
- runPropertiesXml: paragraphMarkRPr
166380
+ runPropertiesXml: paragraphMarkRPr,
166381
+ ...isSdt ? { requiresCollaborationSessionSync: true } : {}
166367
166382
  };
166368
166383
  }
166369
166384
  return null;
@@ -171992,6 +172007,7 @@ function isTerminalDeletionOfPendingFullParagraphInsertion(fragment3, entries) {
171992
172007
  }
171993
172008
  function collectTextCandidates(lookupContext, partXml, entries, storyId) {
171994
172009
  const out = [];
172010
+ const bookmarkGroups = collectBookmarkRevisionGroups(entries.filter((entry) => entry.type === "insertion").flatMap((entry) => entry.fragments), partXml);
171995
172011
  for (const entry of entries) {
171996
172012
  if (entry.type !== "insertion" || entry.subtype !== "text-insertion")
171997
172013
  continue;
@@ -172003,6 +172019,8 @@ function collectTextCandidates(lookupContext, partXml, entries, storyId) {
172003
172019
  continue;
172004
172020
  if (entry.fragments.length === 0)
172005
172021
  continue;
172022
+ if (entry.fragments.every((fragment3) => bookmarkGroups.has(fragment3)))
172023
+ continue;
172006
172024
  if (!entry.fragments.every((fragment3) => fragment3.kind === "ins"))
172007
172025
  continue;
172008
172026
  let paragraphStart = null;
@@ -173852,6 +173870,7 @@ var init_review_groups = __esm(() => {
173852
173870
  init_structural_groups();
173853
173871
  init_numbering_catalog();
173854
173872
  init_field_paragraph_deletion_groups();
173873
+ init_bookmark_revision_groups();
173855
173874
  init_field_paragraph_range_deletion_groups();
173856
173875
  init_image_paragraph_deletion_groups();
173857
173876
  });
@@ -194696,7 +194715,7 @@ var init_created_text_span_proof = __esm(() => {
194696
194715
  });
194697
194716
 
194698
194717
  // ../../../v2/editor-core/dist/document/transactions/content-locked-block-sdt.js
194699
- function isParagraphInsideContentLockedBlockSdt(state, address2) {
194718
+ function isParagraphInsideNonEditableBlockSdt(state, address2) {
194700
194719
  const index = address2.storyId === state.mainStoryId ? getMainParagraphIndexFromState(state) : getStoryParagraphIndexFromState(state, address2.storyId);
194701
194720
  const entry = index?.byParaId(address2.blockId);
194702
194721
  if (!entry || entry.directBodyChildOrdinal != null || entry.containingBodyChildOrdinal == null) {
@@ -194711,7 +194730,7 @@ function isParagraphInsideContentLockedBlockSdt(state, address2) {
194711
194730
  return false;
194712
194731
  const map3 = buildStructuralBoundaryMap(scanBytes);
194713
194732
  const context = map3.byBlockId(entry.blockId) ?? map3.contexts[entry.ordinal - (chunk?.scanParagraphStartOrdinal ?? 0)] ?? null;
194714
- return context?.hasContentLockedBlockSdt === true;
194733
+ return context?.hasContentLockedBlockSdt === true || context?.hasTextAtomicBlockSdt === true;
194715
194734
  }
194716
194735
  function provesNoSdtCarrier(bytes) {
194717
194736
  if (bytes.length === 0 || bytes.includes(0))
@@ -198895,7 +198914,7 @@ function runEditTextCommit(input) {
198895
198914
  return rejected2(txId, "unsupported-context");
198896
198915
  return rejected2(txId, classifyCrossBlockEditText(bytes, op));
198897
198916
  }
198898
- if (isParagraphInsideContentLockedBlockSdt(state, {
198917
+ if (isParagraphInsideNonEditableBlockSdt(state, {
198899
198918
  storyId: op.on.storyId,
198900
198919
  partUri: op.on.partUri,
198901
198920
  blockId: op.on.startBlockId
@@ -198959,7 +198978,10 @@ function runDirectEditTextBatchCommit(input, edits) {
198959
198978
  for (const [blockId, blockEdits] of byBlock) {
198960
198979
  let blockUsedOverlapCompiler = false;
198961
198980
  const paragraph = index.byParaId(blockId);
198962
- if (!paragraph || index.duplicateParaIds.has(blockId) || paragraph.partUri !== partUri || paragraph.partRevision !== first.on.partRevision || paragraph.storyRevision !== first.on.storyRevision || isParagraphInsideContentLockedBlockSdt(state, { storyId, partUri, blockId })) {
198981
+ if (isParagraphInsideNonEditableBlockSdt(state, { storyId, partUri, blockId })) {
198982
+ return rejected2(txId, "text-range-in-sdt");
198983
+ }
198984
+ if (!paragraph || index.duplicateParaIds.has(blockId) || paragraph.partUri !== partUri || paragraph.partRevision !== first.on.partRevision || paragraph.storyRevision !== first.on.storyRevision) {
198963
198985
  return rejected2(txId, "patch-precondition-failed");
198964
198986
  }
198965
198987
  for (const edit of blockEdits) {
@@ -199378,7 +199400,10 @@ function runTrackedEditTextBatchCommit(input, edits) {
199378
199400
  let requiresCollaborationSessionSync = false;
199379
199401
  for (const [blockId, blockEdits] of byBlock) {
199380
199402
  const paragraph = index.byParaId(blockId);
199381
- if (!paragraph || index.duplicateParaIds.has(blockId) || paragraph.partUri !== partUri || paragraph.partRevision !== first.on.partRevision || paragraph.storyRevision !== first.on.storyRevision || isParagraphInsideContentLockedBlockSdt(state, { storyId, partUri, blockId })) {
199403
+ if (isParagraphInsideNonEditableBlockSdt(state, { storyId, partUri, blockId })) {
199404
+ return rejected2(txId, "text-range-in-sdt");
199405
+ }
199406
+ if (!paragraph || index.duplicateParaIds.has(blockId) || paragraph.partUri !== partUri || paragraph.partRevision !== first.on.partRevision || paragraph.storyRevision !== first.on.storyRevision) {
199382
199407
  return rejected2(txId, "patch-precondition-failed");
199383
199408
  }
199384
199409
  for (const edit of blockEdits) {
@@ -199774,7 +199799,7 @@ function runInsertInlineControlCommit(input) {
199774
199799
  if (op.on.startByte < 0 || op.on.endByte > bytes.length || op.on.startByte > op.on.endByte) {
199775
199800
  return rejected2(txId, "invalid-range");
199776
199801
  }
199777
- if (isParagraphInsideContentLockedBlockSdt(state, {
199802
+ if (isParagraphInsideNonEditableBlockSdt(state, {
199778
199803
  storyId: op.on.storyId,
199779
199804
  partUri: op.on.partUri,
199780
199805
  blockId: op.on.startBlockId
@@ -217912,6 +217937,45 @@ function collectFieldChar(fieldChars, { tag, start, end }) {
217912
217937
  locked: lock === "true" || lock === "1" || lock === "on"
217913
217938
  });
217914
217939
  }
217940
+ function createFieldTokenCollector(fieldChars, instructionTokens) {
217941
+ const instructionContexts = [];
217942
+ return {
217943
+ onOpenTag({ tag, start, end, namespaceBindings }) {
217944
+ const parent = instructionContexts.at(-1);
217945
+ const inWordRun = parent?.inWordRun ?? false;
217946
+ const isWord = tag.namespaceUri === NS_W || tag.namespaceUri === NS_WSTRICT;
217947
+ const isMce = tag.namespaceUri === NS_MC;
217948
+ const isRunProxy = isMce && (tag.localName === "AlternateContent" || tag.localName === "Choice" || tag.localName === "Fallback");
217949
+ const context = {
217950
+ inWordRun: isWord && tag.localName === "r" || isRunProxy && inWordRun,
217951
+ deleted: (parent?.deleted ?? false) || isWord && (tag.localName === "del" || tag.localName === "moveFrom"),
217952
+ effective: parent?.effective ?? true,
217953
+ choiceSelected: isMce && tag.localName === "AlternateContent" ? false : undefined
217954
+ };
217955
+ if (isMce && parent?.choiceSelected != null) {
217956
+ if (tag.localName === "Choice") {
217957
+ const requires = readXmlAttribute(tag, "", "Requires")?.value.trim().split(/\s+/).filter(Boolean) ?? [];
217958
+ const selected = !parent.choiceSelected && requires.length > 0 && requires.every((prefix) => UNDERSTOOD_FIELD_INSTRUCTION_NAMESPACES.has(namespaceBindings[prefix] ?? ""));
217959
+ context.effective && (context.effective = selected);
217960
+ if (selected)
217961
+ parent.choiceSelected = true;
217962
+ } else if (tag.localName === "Fallback") {
217963
+ context.effective && (context.effective = !parent.choiceSelected);
217964
+ }
217965
+ }
217966
+ instructionContexts.push(context);
217967
+ if (!isWord)
217968
+ return;
217969
+ if (tag.localName === "tab" && inWordRun && !context.deleted && context.effective) {
217970
+ instructionTokens.push({ start, text: "\t", inlineTab: true });
217971
+ }
217972
+ collectFieldChar(fieldChars, { tag, start, end, namespaceBindings });
217973
+ },
217974
+ onCloseTag() {
217975
+ instructionContexts.pop();
217976
+ }
217977
+ };
217978
+ }
217915
217979
  function buildFieldCatalogFromXml(input, xml, utf8Offsets) {
217916
217980
  let paragraphScan = input.sharedParagraphScan ?? null;
217917
217981
  const ownerResolution = {
@@ -217976,12 +218040,29 @@ function buildFieldCatalogFromXml(input, xml, utf8Offsets) {
217976
218040
  }
217977
218041
  const discovered = [];
217978
218042
  const fieldChars = input.preparedFieldChars ?? discovered;
218043
+ const instructionTokens = [...input.preparedInstructionTokens ?? []];
217979
218044
  if (input.preparedFieldChars === undefined && /<(?:[\w.-]+:)?fldChar\b/.test(xml)) {
217980
- walkXmlElements(xml, { onOpenTag: (event) => collectFieldChar(discovered, event) });
218045
+ walkXmlElements(xml, createFieldTokenCollector(discovered, instructionTokens));
218046
+ }
218047
+ if (fieldChars.length > 0) {
218048
+ const instrTextRe = /<[\w.-]+:instrText\b[^>]*>([\s\S]*?)<\/[\w.-]+:instrText>/g;
218049
+ for (let match = instrTextRe.exec(xml);match; match = instrTextRe.exec(xml)) {
218050
+ instructionTokens.push({ start: match.index, text: decodeXmlText(match[1]) });
218051
+ }
218052
+ instructionTokens.sort((left, right) => left.start - right.start);
217981
218053
  }
217982
- const instrTextRe = /<([\w.-]+):instrText\b[^>]*>([\s\S]*?)<\/[\w.-]+:instrText>/g;
218054
+ let instructionIndex = 0;
217983
218055
  const stack = [];
217984
218056
  for (const marker of fieldChars) {
218057
+ while (instructionIndex < instructionTokens.length && instructionTokens[instructionIndex].start < marker.start) {
218058
+ const token = instructionTokens[instructionIndex++];
218059
+ if (token.inlineTab && stack.at(-1)?.separateAt != null)
218060
+ continue;
218061
+ for (const frame of stack) {
218062
+ if (frame.separateAt == null)
218063
+ frame.instructionFragments.push(token.text);
218064
+ }
218065
+ }
217985
218066
  const charType = marker.type;
217986
218067
  const matchStart = marker.start;
217987
218068
  const matchEnd = marker.end;
@@ -218016,16 +218097,7 @@ function buildFieldCatalogFromXml(input, xml, utf8Offsets) {
218016
218097
  const fieldEnd = endEnclosingRunEnd;
218017
218098
  const resultStart = frame.resultStartOffset ?? fieldEnd;
218018
218099
  const resultEnd = Math.max(resultStart, enclosingRunStart(xml, matchStart));
218019
- const instrSpanStart = frame.beginOffset;
218020
- const instrSpanEnd = frame.separateAt ?? matchStart;
218021
- const instrSlice = xml.slice(instrSpanStart, instrSpanEnd);
218022
- const instrTextParts = [];
218023
- let instrM;
218024
- const instrLocal = new RegExp(instrTextRe.source, "g");
218025
- while ((instrM = instrLocal.exec(instrSlice)) != null) {
218026
- instrTextParts.push(decodeXmlText(instrM[2] ?? ""));
218027
- }
218028
- const instructionText = instrTextParts.join("").trim();
218100
+ const instructionText = frame.instructionFragments.join("").trim();
218029
218101
  const resultText = frame.separateAt != null ? extractText(xml.slice(resultStart, resultEnd)) : "";
218030
218102
  const paraId = enclosingParaId(frame.beginOffset);
218031
218103
  const byteStart = byteOffsetAt3(utf8Offsets, fieldStart);
@@ -218539,12 +218611,13 @@ async function buildFieldCatalogForStoryCooperatively(input) {
218539
218611
  }
218540
218612
  }
218541
218613
  const preparedFieldChars = [];
218614
+ const preparedInstructionTokens = [];
218542
218615
  if (/<(?:[\w.-]+:)?fldChar\b/.test(decoded.xml)) {
218543
218616
  let aborted2 = false;
218544
218617
  let yieldFailed = false;
218545
218618
  let yieldError;
218546
218619
  await walkXmlElementsCooperatively(decoded.xml, {
218547
- onOpenTag: (event) => collectFieldChar(preparedFieldChars, event),
218620
+ ...createFieldTokenCollector(preparedFieldChars, preparedInstructionTokens),
218548
218621
  yieldPoint: async () => {
218549
218622
  let current;
218550
218623
  try {
@@ -218576,6 +218649,7 @@ async function buildFieldCatalogForStoryCooperatively(input) {
218576
218649
  storyId: input.storyId,
218577
218650
  partUri: input.partUri,
218578
218651
  preparedFieldChars,
218652
+ preparedInstructionTokens,
218579
218653
  ...paragraphOwnerResolver ? { paragraphOwnerResolver } : { sharedParagraphScan }
218580
218654
  }, decoded.xml, utf8Offsets);
218581
218655
  catalog.ownerResolution.packedRejectionReason = ownerDiagnostics.rejectionReason;
@@ -218606,7 +218680,7 @@ function listFieldCatalogsForState(state) {
218606
218680
  }
218607
218681
  return out;
218608
218682
  }
218609
- var TD53, UTF8_OFFSET_CHECKPOINT_STRIDE = 256, FIELD_CANDIDATE_BYTES, FIELD_CANDIDATE_SEARCHES, STATE_CACHE2, STATE_IN_FLIGHT, DECODED_PART_IN_FLIGHT;
218683
+ var TD53, UTF8_OFFSET_CHECKPOINT_STRIDE = 256, UNDERSTOOD_FIELD_INSTRUCTION_NAMESPACES, FIELD_CANDIDATE_BYTES, FIELD_CANDIDATE_SEARCHES, STATE_CACHE2, STATE_IN_FLIGHT, DECODED_PART_IN_FLIGHT;
218610
218684
  var init_field_catalog = __esm(() => {
218611
218685
  init_sd_document_state();
218612
218686
  init_xml_text();
@@ -218615,6 +218689,7 @@ var init_field_catalog = __esm(() => {
218615
218689
  init_part_wml_scan_cache();
218616
218690
  init_field_paragraph_owner();
218617
218691
  TD53 = new TextDecoder;
218692
+ UNDERSTOOD_FIELD_INSTRUCTION_NAMESPACES = new Set([NS_W, NS_WSTRICT, NS_W14]);
218618
218693
  FIELD_CANDIDATE_BYTES = [["fldSimple", 3], ["fldChar", 3], ["instrText", 7]];
218619
218694
  FIELD_CANDIDATE_SEARCHES = FIELD_CANDIDATE_BYTES.map(([token, anchorOffset]) => ({
218620
218695
  token: new TextEncoder().encode(token),
@@ -224191,11 +224266,11 @@ function runTrackedTextMoveCommit(input) {
224191
224266
  if (source.value.entry.storyId !== input.state.mainStoryId) {
224192
224267
  return rejected10(input.txId, "tracked-text-move-cross-story");
224193
224268
  }
224194
- if (isParagraphInsideContentLockedBlockSdt(input.state, {
224269
+ if (isParagraphInsideNonEditableBlockSdt(input.state, {
224195
224270
  storyId: source.value.entry.storyId,
224196
224271
  partUri: source.value.entry.partUri,
224197
224272
  blockId: source.value.entry.blockId
224198
- }) || isParagraphInsideContentLockedBlockSdt(input.state, {
224273
+ }) || isParagraphInsideNonEditableBlockSdt(input.state, {
224199
224274
  storyId: destination.entry.storyId,
224200
224275
  partUri: destination.entry.partUri,
224201
224276
  blockId: destination.entry.blockId
@@ -290292,6 +290367,107 @@ var init_section_xml = __esm(() => {
290292
290367
  SECTPR_CHILD_RANK = new Map(SECTPR_CHILD_ORDER.map((name, index) => [name, index]));
290293
290368
  });
290294
290369
 
290370
+ // ../../../v2/document-api-v2-adapter/dist/formatting/paragraph-property-order.js
290371
+ function setParagraphPropertyChild(children2, localName2, xml) {
290372
+ const parsed = parseSingleElement(xml);
290373
+ const existingIndex = children2.findIndex((child) => child.localName === localName2);
290374
+ if (existingIndex >= 0) {
290375
+ const next = [...children2];
290376
+ next[existingIndex] = parsed;
290377
+ return next;
290378
+ }
290379
+ const targetRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(localName2);
290380
+ if (targetRank == null)
290381
+ throw new Error(`Unknown paragraph property child: ${localName2}`);
290382
+ let insertionIndex = 0;
290383
+ for (const [index, child] of children2.entries()) {
290384
+ const childRank = paragraphPropertyRankRange(child);
290385
+ if (!childRank)
290386
+ continue;
290387
+ if (childRank.minimum > targetRank) {
290388
+ return [...children2.slice(0, index), parsed, ...children2.slice(index)];
290389
+ }
290390
+ if (childRank.maximum >= targetRank) {
290391
+ throw new ParagraphPropertyMutationUnavailableError(`Cannot safely insert w:${localName2} within mc:AlternateContent paragraph properties`);
290392
+ }
290393
+ insertionIndex = index + 1;
290394
+ }
290395
+ return [...children2.slice(0, insertionIndex), parsed, ...children2.slice(insertionIndex)];
290396
+ }
290397
+ function paragraphPropertyRankRange(child) {
290398
+ const directRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(child.localName);
290399
+ if (directRank != null)
290400
+ return { minimum: directRank, maximum: directRank };
290401
+ if (child.localName !== "AlternateContent")
290402
+ return null;
290403
+ const alternateContent = parseContainerXml(child.xml, "AlternateContent");
290404
+ if (!alternateContent)
290405
+ return null;
290406
+ const ranks = parseTopLevelChildren(alternateContent.inner).flatMap((branch) => {
290407
+ if (branch.localName !== "Choice" && branch.localName !== "Fallback")
290408
+ return [];
290409
+ const branchContainer = parseContainerXml(branch.xml, branch.localName);
290410
+ if (!branchContainer)
290411
+ return [];
290412
+ return parseTopLevelChildren(branchContainer.inner).flatMap((candidate2) => {
290413
+ const range = paragraphPropertyRankRange(candidate2);
290414
+ return range ? [range.minimum, range.maximum] : [];
290415
+ });
290416
+ });
290417
+ if (ranks.length === 0)
290418
+ return null;
290419
+ return { minimum: Math.min(...ranks), maximum: Math.max(...ranks) };
290420
+ }
290421
+ var PARAGRAPH_PROPERTY_CHILD_ORDER, PARAGRAPH_PROPERTY_CHILD_RANK, ParagraphPropertyMutationUnavailableError;
290422
+ var init_paragraph_property_order = __esm(() => {
290423
+ init_common();
290424
+ PARAGRAPH_PROPERTY_CHILD_ORDER = [
290425
+ "pStyle",
290426
+ "keepNext",
290427
+ "keepLines",
290428
+ "pageBreakBefore",
290429
+ "framePr",
290430
+ "widowControl",
290431
+ "numPr",
290432
+ "suppressLineNumbers",
290433
+ "pBdr",
290434
+ "shd",
290435
+ "tabs",
290436
+ "suppressAutoHyphens",
290437
+ "kinsoku",
290438
+ "wordWrap",
290439
+ "overflowPunct",
290440
+ "topLinePunct",
290441
+ "autoSpaceDE",
290442
+ "autoSpaceDN",
290443
+ "bidi",
290444
+ "adjustRightInd",
290445
+ "snapToGrid",
290446
+ "spacing",
290447
+ "ind",
290448
+ "contextualSpacing",
290449
+ "mirrorIndents",
290450
+ "suppressOverlap",
290451
+ "jc",
290452
+ "textDirection",
290453
+ "textAlignment",
290454
+ "textboxTightWrap",
290455
+ "outlineLvl",
290456
+ "divId",
290457
+ "cnfStyle",
290458
+ "rPr",
290459
+ "sectPr",
290460
+ "pPrChange"
290461
+ ];
290462
+ PARAGRAPH_PROPERTY_CHILD_RANK = new Map(PARAGRAPH_PROPERTY_CHILD_ORDER.map((name, index) => [name, index]));
290463
+ ParagraphPropertyMutationUnavailableError = class ParagraphPropertyMutationUnavailableError extends Error {
290464
+ constructor(message) {
290465
+ super(message);
290466
+ this.name = "ParagraphPropertyMutationUnavailableError";
290467
+ }
290468
+ };
290469
+ });
290470
+
290295
290471
  // ../../../v2/document-api-v2-adapter/dist/references/date-time-field.js
290296
290472
  function readDateTimePictureSwitch(instruction) {
290297
290473
  return /\\@\s+"([^"]*)"/u.exec(instruction)?.[1] ?? null;
@@ -292099,17 +292275,18 @@ function buildTocFieldBodyXml(context, instruction, options) {
292099
292275
  return buildComplexFieldXml(instruction, buildTocFieldResultXml(context, instruction, options));
292100
292276
  }
292101
292277
  function buildTocFieldResultXml(context, instruction, options) {
292102
- if (shouldUseV1EmptyTocSourceSet(instruction)) {
292103
- return buildTextRunXml("No table of contents entries found.");
292104
- }
292105
- const entries = buildTocEntries(context, instruction, options?.currentField, options?.preservedTocPages, options?.tocBookmarkNames);
292278
+ return buildTocFieldResult(context, instruction, options).xml;
292279
+ }
292280
+ function buildTocFieldResult(context, instruction, options) {
292281
+ const emptyText = shouldUseV1EmptyTocSourceSet(instruction) ? "No table of contents entries found." : "";
292282
+ const entries = emptyText ? [] : buildTocEntries(context, instruction, options?.currentField, options?.preservedTocPages, options?.tocBookmarkNames);
292106
292283
  if (options?.currentField) {
292107
- return buildTocResultXmlPreservingParagraphs(context, instruction, entries, options.currentField);
292284
+ return buildTocResultXmlPreservingParagraphs(context, instruction, entries, options.currentField, emptyText);
292108
292285
  }
292109
- return buildTocResultRunsXml(instruction, entries);
292286
+ return { xml: emptyText ? buildTextRunXml(emptyText) : buildTocResultRunsXml(instruction, entries) };
292110
292287
  }
292111
292288
  function buildTocFieldXml(context, instruction, options) {
292112
- const contentXml = options?.currentField && options.preserveParagraphs ? buildTocFieldBodyXml(context, instruction, options) : buildNewTocFieldContentXml(context, instruction, options?.seedParagraph, options?.currentField, options?.preservedTocPages, options?.reservedParaIds, options?.tocBookmarkNames);
292289
+ const contentXml = options?.currentField && options.preserveParagraphs ? buildTocFieldBodyXml(context, instruction, options) : buildNewTocFieldContentXml(context, instruction, options?.seedParagraph, options?.currentField, options?.preservedTocPages, options?.reservedParaIds, options?.tocBookmarkNames, options?.insertionByteStart);
292113
292290
  if (options?.bare)
292114
292291
  return contentXml;
292115
292292
  return "<w:sdt>" + "<w:sdtPr>" + "<w:docPartObj>" + '<w:docPartGallery w:val="Table of Contents"/>' + "<w:docPartUnique/>" + "</w:docPartObj>" + "</w:sdtPr>" + "<w:sdtContent>" + contentXml + "</w:sdtContent>" + "</w:sdt>";
@@ -292496,28 +292673,8 @@ function prepareTocSdtReplacement(context, entry, instruction, tocBookmarkNames)
292496
292673
  afterXml: buildNewTocFieldContentXml(context, instruction, paragraph2, entry, preservedTocPages, reservedParaIds, tocBookmarkNames)
292497
292674
  };
292498
292675
  }
292499
- function replaceTocSdtXml(context, entry, instruction, txIdPrefix) {
292500
- const prepared = prepareTocSdtReplacement(context, entry, instruction);
292501
- if (!prepared.ok)
292502
- return prepared;
292503
- const nextBytes = spliceBytes3(prepared.bytes, prepared.byteStart, prepared.byteEnd, encodeXml(prepared.afterXml));
292504
- return commitKernelStorySurfacePatch({
292505
- context,
292506
- txIdPrefix,
292507
- perPart: { [entry.partUri]: replaceWholePartEntry(prepared.bytes, nextBytes) },
292508
- storyIds: [entry.storyId],
292509
- signalLanesToRebuild: ["paragraphIndex", "headings", "noteAnchorRefs"]
292510
- });
292511
- }
292512
292676
  function replaceTocXml(context, entry, instruction, txIdPrefix) {
292513
- const sdtReplacement = replaceTocSdtXml(context, entry, instruction, txIdPrefix);
292514
- if (sdtReplacement.ok || sdtReplacement.message !== "Unable to locate the containing TOC content control.") {
292515
- return sdtReplacement;
292516
- }
292517
- return replaceBareTocFieldXml(context, entry, instruction, txIdPrefix);
292518
- }
292519
- function replaceBareTocFieldXml(context, entry, instruction, txIdPrefix) {
292520
- const prepared = prepareBareTocFieldReplacement(context, entry, instruction);
292677
+ const prepared = prepareTocReplacement(context, entry, instruction);
292521
292678
  if (!prepared.ok)
292522
292679
  return prepared;
292523
292680
  const nextBytes = spliceBytes3(prepared.bytes, prepared.byteStart, prepared.byteEnd, encodeXml(prepared.afterXml));
@@ -292529,6 +292686,10 @@ function replaceBareTocFieldXml(context, entry, instruction, txIdPrefix) {
292529
292686
  signalLanesToRebuild: ["paragraphIndex", "headings", "noteAnchorRefs"]
292530
292687
  });
292531
292688
  }
292689
+ function prepareTocReplacement(context, entry, instruction, tocBookmarkNames) {
292690
+ const sdt = prepareTocSdtReplacement(context, entry, instruction, tocBookmarkNames);
292691
+ return !sdt.ok && sdt.message === "Unable to locate the containing TOC content control." ? prepareBareTocFieldReplacement(context, entry, instruction, tocBookmarkNames) : sdt;
292692
+ }
292532
292693
  function prepareBareTocReplacement(context, entry, instruction, tocBookmarkNames) {
292533
292694
  const prepared = prepareBareTocFieldReplacement(context, entry, instruction, tocBookmarkNames);
292534
292695
  if (!prepared.ok)
@@ -292568,18 +292729,112 @@ function prepareBareTocFieldReplacement(context, entry, instruction, tocBookmark
292568
292729
  }
292569
292730
  const xml = TD83.decode(bytes);
292570
292731
  const preservedTocPages = readPreservedTocPagesFromPartXml(xml);
292571
- const nextFieldXml = shouldUseV1EmptyTocSourceSet(instruction) ? buildComplexFieldXml(instruction, buildTextRunXml("No table of contents entries found.")) : buildTocFieldBodyXml(context, instruction, { currentField: entry, preservedTocPages, tocBookmarkNames });
292732
+ const result = buildTocFieldResult(context, instruction, { currentField: entry, preservedTocPages, tocBookmarkNames });
292733
+ const nextFieldXml = buildComplexFieldXml(instruction, result.xml);
292734
+ const fieldStartChar = TD83.decode(bytes.subarray(0, entry.descriptor.byteStart)).length;
292735
+ const fieldEndChar = TD83.decode(bytes.subarray(0, entry.descriptor.byteEnd)).length;
292736
+ const paragraphStart = findEnclosingParagraphStart(xml, fieldStartChar, 0);
292737
+ const paragraphOpenEnd = paragraphStart >= 0 ? findXmlTagEnd4(xml, paragraphStart + 1) : -1;
292738
+ const paragraphCloseStart = xml.indexOf("</w:p>", fieldStartChar);
292739
+ const paragraphPropertiesStart = paragraphOpenEnd >= 0 ? skipXmlWhitespace(xml, paragraphOpenEnd) : -1;
292740
+ const paragraphProperties = paragraphOpenEnd >= 0 ? matchLeadingElement(xml.slice(paragraphPropertiesStart, fieldStartChar), "pPr") : "";
292741
+ const ownsFirstParagraph = entry.descriptor.complete && paragraphOpenEnd >= 0 && paragraphCloseStart >= fieldStartChar && readTocParagraphLevel(paragraphProperties) != null && xml.slice(paragraphPropertiesStart + paragraphProperties.length, fieldStartChar).trim() === "" && (fieldEndChar >= paragraphCloseStart || xml.slice(fieldEndChar, paragraphCloseStart).trim() === "");
292742
+ const replaceParagraphProperties = ownsFirstParagraph && result.firstParagraphProperties != null;
292743
+ const byteStart = replaceParagraphProperties ? encodeXml(xml.slice(0, paragraphOpenEnd)).length : entry.descriptor.byteStart;
292744
+ const nextParagraphProperties = replaceParagraphProperties ? preserveTocOwnerProperties(result.firstParagraphProperties, paragraphProperties) : "";
292745
+ const afterXml = nextParagraphProperties + nextFieldXml;
292746
+ const nextXml = TD83.decode(spliceBytes3(bytes, byteStart, entry.descriptor.byteEnd, encodeXml(afterXml)));
292747
+ if (collectXmlElementRanges(nextXml).errors.length > 0) {
292748
+ return {
292749
+ ok: false,
292750
+ code: "CAPABILITY_UNAVAILABLE",
292751
+ message: "The bare TOC replacement crosses unsupported XML boundaries."
292752
+ };
292753
+ }
292572
292754
  return {
292573
292755
  ok: true,
292574
292756
  bytes,
292575
- byteStart: entry.descriptor.byteStart,
292757
+ byteStart,
292576
292758
  byteEnd: entry.descriptor.byteEnd,
292577
- beforeXml: TD83.decode(bytes.subarray(entry.descriptor.byteStart, entry.descriptor.byteEnd)),
292578
- afterXml: nextFieldXml
292759
+ beforeXml: TD83.decode(bytes.subarray(byteStart, entry.descriptor.byteEnd)),
292760
+ afterXml
292579
292761
  };
292580
292762
  }
292763
+ function findDirectChild(xml, localName2) {
292764
+ return scanDirectElementChildren(xml).find((child) => xmlLocalName(child.qname) === localName2);
292765
+ }
292766
+ function removeTocOwnerPropertiesFromTemplate(xml) {
292767
+ const properties = matchLeadingElement(xml, "pPr") || findDirectChild(xml, "pPr")?.xml;
292768
+ if (!properties)
292769
+ return xml;
292770
+ for (const child of scanDirectElementChildren(properties)) {
292771
+ if (["rPr", "sectPr", "pPrChange"].includes(xmlLocalName(child.qname))) {
292772
+ xml = xml.replace(child.xml, "");
292773
+ }
292774
+ }
292775
+ return xml;
292776
+ }
292777
+ function preserveTocOwnerProperties(template, ownerProperties) {
292778
+ const properties = removeTocOwnerPropertiesFromTemplate(template);
292779
+ const retained = ["rPr", "sectPr", "pPrChange"].map((name) => {
292780
+ const child = findDirectChild(ownerProperties, name);
292781
+ return child ? inheritRunNamespaceDeclarations(child.xml, ownerProperties, ownerProperties.indexOf(child.xml), ownerProperties.slice(0, findXmlTagEnd4(ownerProperties, 1))) : "";
292782
+ }).join("");
292783
+ const insertAt = properties.lastIndexOf("</");
292784
+ return properties.slice(0, insertAt) + retained + properties.slice(insertAt);
292785
+ }
292786
+ function removeTocSectionBoundaryFromTemplate(xml) {
292787
+ const properties = matchLeadingElement(xml, "pPr") || findDirectChild(xml, "pPr")?.xml;
292788
+ if (!properties)
292789
+ return xml;
292790
+ const section = findDirectChild(properties, "sectPr");
292791
+ return section ? xml.replace(section.xml, "") : xml;
292792
+ }
292793
+ function readTocContinuationSectionPlacement(paragraphs, entryCount) {
292794
+ const byEntryIndex = new Map;
292795
+ const carriers = [];
292796
+ for (const [index, paragraph2] of paragraphs.entries()) {
292797
+ if (index === 0)
292798
+ continue;
292799
+ const properties = findDirectChild(paragraph2, "pPr");
292800
+ if (!properties || !findDirectChild(properties.xml, "sectPr"))
292801
+ continue;
292802
+ if (index === paragraphs.length - 1) {
292803
+ const lastEntryIndex = entryCount - 1;
292804
+ if (readTocParagraphTemplateText(paragraph2) && lastEntryIndex > 0 && !byEntryIndex.has(lastEntryIndex) && carriers.length === 0) {
292805
+ byEntryIndex.set(lastEntryIndex, paragraph2);
292806
+ } else {
292807
+ carriers.push(paragraph2);
292808
+ }
292809
+ } else if (index < entryCount) {
292810
+ byEntryIndex.set(index, paragraph2);
292811
+ } else {
292812
+ carriers.push(paragraph2);
292813
+ }
292814
+ }
292815
+ return { byEntryIndex, carriers };
292816
+ }
292817
+ function buildTocSectionOwnerParagraphOpen(template, owner) {
292818
+ const openEnd = findXmlTagEnd4(template, 1);
292819
+ const properties = inheritRunNamespaceDeclarations(template.slice(openEnd) || "<w:pPr></w:pPr>", template, openEnd, template.slice(0, openEnd));
292820
+ const ownerProperties = findDirectChild(owner, "pPr").xml;
292821
+ const retainedProperties = inheritRunNamespaceDeclarations(ownerProperties, owner, owner.indexOf(ownerProperties), readParagraphOpenTag(owner));
292822
+ return readParagraphOpenTag(owner) + preserveTocOwnerProperties(properties, retainedProperties);
292823
+ }
292824
+ function preserveTocContinuationSectionOpen(template, index, sectionOwners, usedParaIds) {
292825
+ const owner = sectionOwners.get(index);
292826
+ const open2 = removeTocSectionBoundaryFromTemplate(template);
292827
+ if (!owner)
292828
+ return open2 === template ? open2 : removeTocOwnerPropertiesFromTemplate(template);
292829
+ for (const id of collectParaIdsInXml(readParagraphOpenTag(owner)))
292830
+ usedParaIds.delete(id);
292831
+ return buildTocSectionOwnerParagraphOpen(open2, owner);
292832
+ }
292833
+ function buildTocSectionCarrierXml(owner) {
292834
+ return buildTocSectionOwnerParagraphOpen("<w:p><w:pPr></w:pPr>", owner) + "</w:p>";
292835
+ }
292581
292836
  function shouldUseV1EmptyTocSourceSet(instruction) {
292582
- return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) && parseQuotedSwitch(instruction, "f") == null && parseNumericSwitchRange(instruction, "l") == null;
292837
+ return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) && !parseTocTcSourceSelection(instruction).enabled;
292583
292838
  }
292584
292839
  function findLastSdtStart(xmlPrefix2) {
292585
292840
  let start = -1;
@@ -292873,6 +293128,104 @@ function resolveBookmarkSpanInParagraph(context, entry) {
292873
293128
  text: map3.visibleText().slice(startOffset, endOffset)
292874
293129
  };
292875
293130
  }
293131
+ function buildParagraphBookmarkMarkers(paragraph2, insertion, id) {
293132
+ const namespace = insertion.fieldSource || paragraph2.namespaceBindings?.w !== WORDPROCESSINGML_NAMESPACE5 ? ` xmlns:w="${WORDPROCESSINGML_NAMESPACE5}"` : "";
293133
+ return {
293134
+ startXml: `<w:bookmarkStart${namespace} w:id="${xmlEscapeAttr(String(id))}" w:name="${xmlEscapeAttr(insertion.name)}"${insertion.tableColumn ? ` w:colFirst="${insertion.tableColumn.colFirst}" w:colLast="${insertion.tableColumn.colLast}"` : ""}/>`,
293135
+ endXml: `<w:bookmarkEnd${namespace} w:id="${xmlEscapeAttr(String(id))}"/>`
293136
+ };
293137
+ }
293138
+ function readBookmarkInsertionNamespaceBindings(paragraph2, insertion) {
293139
+ if (!insertion.fieldSource)
293140
+ return new Map(Object.entries(paragraph2.namespaceBindings ?? {}));
293141
+ const relativeByte = insertion.fieldSource.byteStart - paragraph2.byteStart;
293142
+ const charStart = TD83.decode(encodeXml(paragraph2.rawXml).subarray(0, relativeByte)).length;
293143
+ const parsed = collectXmlElementRanges(paragraph2.rawXml, {
293144
+ fragment: true,
293145
+ additionalNamespaces: paragraph2.namespaceBindings
293146
+ });
293147
+ const parent = parsed.ranges.filter((range) => !range.tag.isSelfClosing && range.openEnd <= charStart && range.closeStart > charStart).sort((left, right) => right.start - left.start)[0];
293148
+ return parsed.errors.length || !parent ? null : new Map(Object.entries(parent.namespaceBindings));
293149
+ }
293150
+ function canPlaceBookmarkAtFieldSource(paragraph2, fieldSource) {
293151
+ return prepareBookmarkParagraphGroups([paragraph2], [{
293152
+ blockId: paragraph2.blockId,
293153
+ name: "_TocPlacement",
293154
+ fieldSource,
293155
+ startXml: `<w:bookmarkStart xmlns:w="${WORDPROCESSINGML_NAMESPACE5}" w:id="0" w:name="_TocPlacement"/>`,
293156
+ endXml: `<w:bookmarkEnd xmlns:w="${WORDPROCESSINGML_NAMESPACE5}" w:id="0"/>`
293157
+ }]) != null;
293158
+ }
293159
+ function prepareBookmarkParagraphGroups(paragraphs, insertions) {
293160
+ const paragraphsById = new Map;
293161
+ for (const paragraph2 of paragraphs) {
293162
+ paragraphsById.set(paragraph2.blockId, paragraphsById.has(paragraph2.blockId) ? null : paragraph2);
293163
+ }
293164
+ const groups = new Map;
293165
+ for (const insertion of insertions) {
293166
+ if (!paragraphsById.get(insertion.blockId))
293167
+ return null;
293168
+ const group = groups.get(insertion.blockId) ?? [];
293169
+ group.push(insertion);
293170
+ groups.set(insertion.blockId, group);
293171
+ }
293172
+ const result = [];
293173
+ for (const [blockId, group] of groups) {
293174
+ const paragraph2 = paragraphsById.get(blockId);
293175
+ const generic = group.filter((insertion) => !insertion.fieldSource);
293176
+ if (generic.length > 1)
293177
+ return null;
293178
+ const parsed = collectXmlElementRanges(paragraph2.rawXml, {
293179
+ fragment: true,
293180
+ additionalNamespaces: paragraph2.namespaceBindings
293181
+ });
293182
+ const root = parsed.ranges.find((range) => range.start === 0 && range.end === paragraph2.rawXml.length);
293183
+ if (parsed.errors.length || !root || root.tag.localName !== "p" || root.tag.namespaceUri !== WORDPROCESSINGML_NAMESPACE5)
293184
+ return null;
293185
+ const fields = group.filter((insertion) => insertion.fieldSource).sort((left, right) => right.fieldSource.byteStart - left.fieldSource.byteStart);
293186
+ const original = encodeXml(paragraph2.rawXml);
293187
+ let next = original;
293188
+ let previousStart = paragraph2.byteEnd;
293189
+ const keys = new Set;
293190
+ for (const insertion of fields) {
293191
+ const source = insertion.fieldSource;
293192
+ if (keys.has(source.key) || !Number.isInteger(source.byteStart) || !Number.isInteger(source.byteEnd) || source.byteStart < paragraph2.byteStart || source.byteEnd > previousStart || source.byteEnd <= source.byteStart)
293193
+ return null;
293194
+ keys.add(source.key);
293195
+ const start = source.byteStart - paragraph2.byteStart;
293196
+ const end = source.byteEnd - paragraph2.byteStart;
293197
+ const startChar = TD83.decode(original.subarray(0, start)).length;
293198
+ const endChar = TD83.decode(original.subarray(0, end)).length;
293199
+ if (encodeXml(paragraph2.rawXml.slice(0, startChar)).length !== start || encodeXml(paragraph2.rawXml.slice(0, endChar)).length !== end)
293200
+ return null;
293201
+ const first = parsed.ranges.find((range) => range.start === startChar && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && (range.tag.localName === "r" || range.tag.localName === "fldSimple"));
293202
+ const last = parsed.ranges.find((range) => range.end === endChar && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && range.tag.localName === first?.tag.localName);
293203
+ const parent = (range) => parsed.ranges.filter((candidate2) => candidate2.start < range.start && candidate2.end > range.end).sort((a, b) => b.start - a.start)[0];
293204
+ if (!first || !last || first.start < root.openEnd || last.end > root.closeStart || parent(first)?.start !== parent(last)?.start || first.tag.localName === "fldSimple" && first !== last)
293205
+ return null;
293206
+ if (first.tag.localName === "r") {
293207
+ const hasMarker = (run, kind) => parsed.ranges.some((range) => range.start >= run.start && range.end <= run.end && range.tag.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && range.tag.localName === "fldChar" && range.tag.attributes.some((attribute) => attribute.namespaceUri === WORDPROCESSINGML_NAMESPACE5 && attribute.localName === "fldCharType" && attribute.value === kind));
293208
+ if (!hasMarker(first, "begin") || !hasMarker(last, "end"))
293209
+ return null;
293210
+ }
293211
+ next = spliceBytes3(next, end, end, encodeXml(insertion.endXml));
293212
+ next = spliceBytes3(next, start, start, encodeXml(insertion.startXml));
293213
+ previousStart = source.byteStart;
293214
+ }
293215
+ let xml = TD83.decode(next);
293216
+ if (generic[0]) {
293217
+ const withStart = injectParagraphPrefix(xml, generic[0].startXml);
293218
+ const withEnd = withStart && injectParagraphSuffix(withStart, generic[0].endXml);
293219
+ if (!withEnd)
293220
+ return null;
293221
+ xml = withEnd;
293222
+ }
293223
+ if (collectXmlElementRanges(xml, { fragment: true, additionalNamespaces: paragraph2.namespaceBindings }).errors.length)
293224
+ return null;
293225
+ result.push({ paragraph: paragraph2, xml });
293226
+ }
293227
+ return result;
293228
+ }
292876
293229
  function insertBookmarksIntoParagraphs(context, insertions, txIdPrefix) {
292877
293230
  if (insertions.length === 0) {
292878
293231
  return {
@@ -292881,59 +293234,46 @@ function insertBookmarksIntoParagraphs(context, insertions, txIdPrefix) {
292881
293234
  message: "At least one bookmark insertion is required."
292882
293235
  };
292883
293236
  }
292884
- const paragraphsByBlockId = new Map;
292885
- for (const paragraph2 of readBodyParagraphs(context)) {
292886
- paragraphsByBlockId.set(paragraph2.blockId, paragraphsByBlockId.has(paragraph2.blockId) ? null : paragraph2);
293237
+ const paragraphs = readBodyParagraphs(context);
293238
+ const paragraphGroups = new Map;
293239
+ for (const paragraph2 of paragraphs) {
293240
+ const group = paragraphGroups.get(paragraph2.blockId) ?? [];
293241
+ group.push(paragraph2);
293242
+ paragraphGroups.set(paragraph2.blockId, group);
292887
293243
  }
292888
293244
  const existingNames = new Set(readBookmarkEntries(context).map((entry) => entry.name));
292889
- const requestedBlockIds = new Set;
292890
293245
  const requestedNames = new Set;
292891
- const replacementsByPart = new Map;
292892
- const storyIds = new Set;
292893
293246
  const bookmarkIds = [];
292894
293247
  let nextBookmarkId = nextBookmarkNumericId(context);
293248
+ const markers = [];
292895
293249
  for (const insertion of insertions) {
292896
- if (requestedBlockIds.has(insertion.blockId)) {
292897
- return {
292898
- ok: false,
292899
- code: "INVALID_TARGET",
292900
- message: `Paragraph "${insertion.blockId}" was requested more than once.`
292901
- };
292902
- }
292903
293250
  if (existingNames.has(insertion.name) || requestedNames.has(insertion.name)) {
292904
- return {
292905
- ok: false,
292906
- code: "INVALID_TARGET",
292907
- message: `Bookmark name "${insertion.name}" already exists.`
292908
- };
293251
+ return { ok: false, code: "INVALID_TARGET", message: `Bookmark name "${insertion.name}" already exists.` };
292909
293252
  }
292910
- const paragraph2 = paragraphsByBlockId.get(insertion.blockId);
292911
- if (!paragraph2) {
293253
+ const targets = paragraphGroups.get(insertion.blockId);
293254
+ if (targets?.length !== 1)
292912
293255
  return {
292913
293256
  ok: false,
292914
293257
  code: "TARGET_NOT_FOUND",
292915
293258
  message: `Paragraph "${insertion.blockId}" was not found or is ambiguous.`
292916
293259
  };
292917
- }
292918
293260
  const bookmarkId = String(nextBookmarkId++);
292919
- const startFragment = `<w:bookmarkStart w:id="${xmlEscapeAttr(bookmarkId)}" w:name="${xmlEscapeAttr(insertion.name)}"${insertion.tableColumn ? ` w:colFirst="${insertion.tableColumn.colFirst}" w:colLast="${insertion.tableColumn.colLast}"` : ""}/>`;
292920
- const endFragment = `<w:bookmarkEnd w:id="${xmlEscapeAttr(bookmarkId)}"/>`;
292921
- const withStart = injectParagraphPrefix(paragraph2.rawXml, startFragment);
292922
- const withEnd = withStart ? injectParagraphSuffix(withStart, endFragment) : null;
292923
- if (!withEnd) {
292924
- return {
292925
- ok: false,
292926
- code: "INTERNAL_ERROR",
292927
- message: `Unable to inject bookmark markup into paragraph "${insertion.blockId}".`
292928
- };
292929
- }
293261
+ markers.push({ ...insertion, ...buildParagraphBookmarkMarkers(targets[0], insertion, bookmarkId) });
293262
+ bookmarkIds.push(bookmarkId);
293263
+ requestedNames.add(insertion.name);
293264
+ }
293265
+ const prepared = prepareBookmarkParagraphGroups(paragraphs, markers);
293266
+ if (!prepared)
293267
+ return { ok: false, code: "INVALID_TARGET", message: "Bookmark targets have unavailable or unsupported paragraph or field boundaries." };
293268
+ const replacementsByPart = new Map;
293269
+ const storyIds = new Set;
293270
+ const requestedBlockIds = new Set;
293271
+ for (const { paragraph: paragraph2, xml } of prepared) {
292930
293272
  const replacements = replacementsByPart.get(paragraph2.partUri) ?? [];
292931
- replacements.push({ paragraph: paragraph2, bytes: encodeXml(withEnd) });
293273
+ replacements.push({ paragraph: paragraph2, bytes: encodeXml(xml) });
292932
293274
  replacementsByPart.set(paragraph2.partUri, replacements);
292933
293275
  storyIds.add(paragraph2.storyId);
292934
- bookmarkIds.push(bookmarkId);
292935
- requestedBlockIds.add(insertion.blockId);
292936
- requestedNames.add(insertion.name);
293276
+ requestedBlockIds.add(paragraph2.blockId);
292937
293277
  }
292938
293278
  const perPart = {};
292939
293279
  for (const [partUri, replacements] of replacementsByPart) {
@@ -293390,6 +293730,34 @@ function parseQuotedSwitch(instruction, flag) {
293390
293730
  const re = new RegExp(`\\\\${escapeRegExp15(flag)}\\s+"([^"]*)"`);
293391
293731
  return re.exec(instruction)?.[1];
293392
293732
  }
293733
+ function parseTocFieldIdentifier(instruction) {
293734
+ return parseTocTcSourceSelection(instruction).identifier;
293735
+ }
293736
+ function parseTocTcSourceSelection(instruction) {
293737
+ const tokens = instruction.match(/"[^"]*"|[^\s"]+/g) ?? [];
293738
+ const fieldIndex = tokens.findIndex((token) => token.toLowerCase() === "\\f");
293739
+ const levelIndex = tokens.findIndex((token) => token.toLowerCase() === "\\l");
293740
+ const argument = (index) => {
293741
+ const value2 = index < 0 ? undefined : tokens[index + 1];
293742
+ if (value2 == null || value2.startsWith("\\"))
293743
+ return;
293744
+ return value2.startsWith('"') ? value2.slice(1, -1) : value2;
293745
+ };
293746
+ const identifier = argument(fieldIndex);
293747
+ const levelArgument = argument(levelIndex);
293748
+ const range = /^(\d+)-(\d+)$/.exec(levelArgument ?? "");
293749
+ return {
293750
+ enabled: fieldIndex >= 0 || levelIndex >= 0,
293751
+ hasFieldSwitch: fieldIndex >= 0,
293752
+ hasLevelSwitch: levelIndex >= 0,
293753
+ ...identifier != null ? { identifier } : {},
293754
+ ...levelArgument != null ? { levelArgument } : {},
293755
+ ...range ? { levels: { from: Number(range[1]), to: Number(range[2]) } } : {}
293756
+ };
293757
+ }
293758
+ function matchesTocTcSourceSelection(selection, entry) {
293759
+ return selection.enabled && entry.text.length > 0 && (selection.identifier == null || (entry.tableIdentifier ?? "C") === selection.identifier) && (selection.levels == null || entry.level >= selection.levels.from && entry.level <= selection.levels.to);
293760
+ }
293393
293761
  function parseNumericSwitchRange(instruction, flag) {
293394
293762
  const re = new RegExp(`\\\\${escapeRegExp15(flag)}\\s+"?(\\d+)-(\\d+)"?`);
293395
293763
  const match = re.exec(instruction);
@@ -293771,16 +294139,26 @@ function buildTocResultRunsXml(instruction, entries) {
293771
294139
  return chunks.join("");
293772
294140
  }).join("");
293773
294141
  }
293774
- function buildTocResultXmlPreservingParagraphs(context, instruction, entries, currentField) {
293775
- if (entries.length === 0)
293776
- return buildTextRunXml("");
294142
+ function buildTocResultXmlPreservingParagraphs(context, instruction, sourceEntries, currentField, emptyText = "") {
293777
294143
  const sourceParagraphs = readCurrentTocParagraphXmls(context, currentField, true);
293778
- const paragraphTemplates = buildTocParagraphTemplatesFromParagraphXml(sourceParagraphs.join(""));
294144
+ const sectionPlacement = readTocContinuationSectionPlacement(sourceParagraphs, sourceEntries.length);
294145
+ const sectionOwners = sectionPlacement.byEntryIndex;
294146
+ if (sourceEntries.length === 0) {
294147
+ const carriers = sectionPlacement.carriers.map(buildTocSectionCarrierXml);
294148
+ return { xml: buildTextRunXml(emptyText) + (carriers.length ? `</w:p>${carriers.join("").slice(0, -6)}` : "") };
294149
+ }
294150
+ const paragraphTemplates = buildTocParagraphTemplatesFromParagraphXml([
294151
+ removeTocOwnerPropertiesFromTemplate(sourceParagraphs[0] ?? ""),
294152
+ ...sourceParagraphs.slice(1)
294153
+ ].join(""));
293779
294154
  const entryRunPropertiesTemplates = readTocEntryRunPropertiesTemplates(context, currentField);
293780
- const entryRunProperties = resolveTocEntryRunProperties(entries, entryRunPropertiesTemplates);
294155
+ const entryRunProperties = resolveTocEntryRunProperties(sourceEntries, entryRunPropertiesTemplates);
294156
+ const entryParagraphOpens = resolveTocEntryParagraphOpens(sourceEntries, entryRunProperties, entryRunPropertiesTemplates, sourceParagraphs[0]);
294157
+ const entries = sourceEntries.map((entry, index) => applyCachedTcEntrySeparator(entry, entryRunProperties[index]));
294158
+ const withPageTab = createTocPageTabFallback(context, instruction, currentField.descriptor.byteStart);
293781
294159
  const documentParaIds = collectDocumentParaIds(context);
293782
294160
  const reusableParaIds = collectParaIdsInXml(sourceParagraphs.slice(1).join(""));
293783
- for (const id of collectParaIdsInXml(sourceParagraphs[0] ?? ""))
294161
+ for (const id of collectParaIdsInXml((sourceParagraphs[0] ?? "") + [...sectionOwners.values(), ...sectionPlacement.carriers].join("")))
293784
294162
  reusableParaIds.delete(id);
293785
294163
  const usedParaIds = new Set(documentParaIds);
293786
294164
  const nextParaId = createUniqueParaIdAllocator(documentParaIds);
@@ -293797,31 +294175,47 @@ function buildTocResultXmlPreservingParagraphs(context, instruction, entries, cu
293797
294175
  }
293798
294176
  let xml = buildTocEntryRunsXml(instruction, entries[0], entryRunProperties[0]);
293799
294177
  for (const [index, entry] of entries.slice(1).entries()) {
293800
- const retained = remainingTemplates.get(`${normalizeTocLevel(entry.level)}:${normalizeTocEntryText(entry.text)}`)?.pop();
294178
+ const retained = entryParagraphOpens[index + 1] ?? remainingTemplates.get(`${normalizeTocLevel(entry.level)}:${normalizeTocEntryText(entry.cachedParagraphText ?? entry.text)}`)?.pop();
293801
294179
  if (retained) {
293802
294180
  for (const id of collectParaIdsInXml(retained)) {
293803
294181
  if (reusableParaIds.delete(id))
293804
294182
  usedParaIds.delete(id);
293805
294183
  }
293806
294184
  }
293807
- xml += `</w:p>${dedupeParagraphOpenParaId(retained ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), usedParaIds, nextParaId)}` + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index + 1]);
294185
+ xml += `</w:p>${dedupeParagraphOpenParaId(preserveTocContinuationSectionOpen(withPageTab(retained ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), entry), index + 1, sectionOwners, usedParaIds), usedParaIds, nextParaId)}` + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index + 1]);
293808
294186
  }
293809
- return xml;
294187
+ for (const owner of sectionPlacement.carriers) {
294188
+ xml += `</w:p>${buildTocSectionCarrierXml(owner).slice(0, -6)}`;
294189
+ }
294190
+ const firstParagraphOpen = removeTocSectionBoundaryFromTemplate(withPageTab(entryParagraphOpens[0] ?? buildTocContinuationParagraphOpen(entries[0], paragraphTemplates), entries[0]));
294191
+ const firstParagraphOpenEnd = findXmlTagEnd4(firstParagraphOpen, 1);
294192
+ return {
294193
+ xml,
294194
+ firstParagraphProperties: inheritRunNamespaceDeclarations(firstParagraphOpen.slice(firstParagraphOpenEnd), firstParagraphOpen, firstParagraphOpenEnd, firstParagraphOpen.slice(0, firstParagraphOpenEnd))
294195
+ };
293810
294196
  }
293811
- function buildNewTocFieldContentXml(context, instruction, seedParagraph, currentField, preservedTocPages, reservedParaIds, tocBookmarkNames) {
294197
+ function buildNewTocFieldContentXml(context, instruction, seedParagraph, currentField, preservedTocPages, reservedParaIds, tocBookmarkNames, insertionByteStart) {
293812
294198
  const useEmptyPlaceholder = shouldUseV1EmptyTocSourceSet(instruction);
293813
294199
  const paragraphs = readBodyParagraphs(context, { includeListState: false });
293814
- const entries = useEmptyPlaceholder ? [] : buildTocEntries(context, instruction, currentField, preservedTocPages, tocBookmarkNames, paragraphs);
293815
- const paragraphTemplates = readDocumentTocParagraphTemplates(paragraphs);
294200
+ const sourceEntries = useEmptyPlaceholder ? [] : buildTocEntries(context, instruction, currentField, preservedTocPages, tocBookmarkNames, paragraphs);
294201
+ const paragraphTemplates = readDocumentTocParagraphTemplates(paragraphs, currentField?.blockId);
293816
294202
  const entryRunPropertiesTemplates = readTocEntryRunPropertiesTemplates(context, currentField);
293817
- const entryRunProperties = resolveTocEntryRunProperties(entries, entryRunPropertiesTemplates);
294203
+ const entryRunProperties = resolveTocEntryRunProperties(sourceEntries, entryRunPropertiesTemplates);
294204
+ const entryParagraphOpens = resolveTocEntryParagraphOpens(sourceEntries, entryRunProperties, entryRunPropertiesTemplates, seedParagraph?.rawXml);
294205
+ const entries = sourceEntries.map((entry, index) => applyCachedTcEntrySeparator(entry, entryRunProperties[index]));
294206
+ const withPageTab = createTocPageTabFallback(context, instruction, currentField?.descriptor.byteStart ?? insertionByteStart ?? seedParagraph?.byteStart ?? 0);
294207
+ const sectionPlacement = readTocContinuationSectionPlacement(currentField ? readCurrentTocParagraphXmls(context, currentField, true) : [], entries.length);
294208
+ const sectionOwners = sectionPlacement.byEntryIndex;
294209
+ const carriers = sectionPlacement.carriers.map(buildTocSectionCarrierXml);
293818
294210
  if (entries.length === 0) {
293819
- return buildGeneratedTocParagraphOpen(1, seedParagraph, paragraphTemplates) + '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' + buildTextRunXml(useEmptyPlaceholder ? "No table of contents entries found." : "") + '<w:r><w:fldChar w:fldCharType="end" /></w:r>' + "</w:p>";
294211
+ return buildGeneratedTocParagraphOpen(1, seedParagraph, paragraphTemplates, undefined, currentField != null) + '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' + buildTextRunXml(useEmptyPlaceholder ? "No table of contents entries found." : "") + (carriers.length ? `</w:p>${carriers.join("").slice(0, -6)}` : "") + '<w:r><w:fldChar w:fldCharType="end" /></w:r>' + "</w:p>";
293820
294212
  }
293821
294213
  const documentParaIds = collectDocumentParaIds(context);
293822
294214
  const usedParaIds = new Set(reservedParaIds ?? []);
294215
+ for (const id of collectParaIdsInXml([...sectionOwners.values(), ...sectionPlacement.carriers].join("")))
294216
+ usedParaIds.add(id);
293823
294217
  const nextParaId = createUniqueParaIdAllocator(documentParaIds);
293824
- return entries.map((entry, index) => `${dedupeParagraphOpenParaId(index === 0 ? buildGeneratedTocParagraphOpen(entry.level, seedParagraph, paragraphTemplates, entry.text) : buildTocContinuationParagraphOpen(entry, paragraphTemplates), usedParaIds, nextParaId)}` + (index === 0 ? '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' : "") + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index]) + (index === entries.length - 1 ? '<w:r><w:fldChar w:fldCharType="end" /></w:r>' : "") + "</w:p>").join("");
294218
+ return entries.map((entry, index) => `${dedupeParagraphOpenParaId(withPageTab(index === 0 ? buildGeneratedTocParagraphOpen(entry.level, seedParagraph, paragraphTemplates, entry.cachedParagraphText ?? entry.text, currentField != null, entryParagraphOpens[index]) : currentField ? preserveTocContinuationSectionOpen(entryParagraphOpens[index] ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), index, sectionOwners, usedParaIds) : entryParagraphOpens[index] ?? buildTocContinuationParagraphOpen(entry, paragraphTemplates), entry), usedParaIds, nextParaId)}` + (index === 0 ? '<w:r><w:fldChar w:fldCharType="begin" /></w:r>' + buildInstructionRunXml(instruction) + '<w:r><w:fldChar w:fldCharType="separate" /></w:r>' : "") + buildTocEntryRunsXml(instruction, entry, entryRunProperties[index]) + (index === entries.length - 1 ? (carriers.length ? `</w:p>${carriers.join("").slice(0, -6)}` : "") + '<w:r><w:fldChar w:fldCharType="end" /></w:r>' : "") + "</w:p>").join("");
293825
294219
  }
293826
294220
  function collectDocumentParaIds(context) {
293827
294221
  const existing = new Set;
@@ -293889,7 +294283,8 @@ function buildTocEntryRunsXml(instruction, entry, entryRunProperties) {
293889
294283
  function buildTocEntries(context, instruction, currentField, preservedTocPages, tocBookmarkNames, paragraphs = readBodyParagraphs(context, { includeListState: false })) {
293890
294284
  const pages = estimateDocumentPages(context);
293891
294285
  const numberingMarkers = buildBodyParagraphNumberReferenceMap(context, paragraphs);
293892
- const tocBookmarks = buildBodyTocBookmarkMap(context);
294286
+ const bodyBookmarks = readBookmarkEntries(context);
294287
+ const tocBookmarks = buildBodyTocBookmarkMap(bodyBookmarks);
293893
294288
  if (tocBookmarkNames)
293894
294289
  for (const [key2, name] of tocBookmarkNames)
293895
294290
  tocBookmarks.set(key2, name);
@@ -293911,6 +294306,7 @@ function buildTocEntries(context, instruction, currentField, preservedTocPages,
293911
294306
  const bookmarkKey = bookmarkName ? normalizeTocBookmarkKey(bookmarkName) : undefined;
293912
294307
  const preservedPage = (bookmarkKey ? preservedPagesByBookmark.get(bookmarkKey) : undefined) ?? readPreservedTocPageByText(preservedPages, text);
293913
294308
  return {
294309
+ sourceByteStart: paragraph2.byteStart,
293914
294310
  text,
293915
294311
  page: preservedPage ?? String(pages.displayPageByBlockId.get(paragraph2.blockId) ?? 1),
293916
294312
  level: derivedLevel,
@@ -293922,17 +294318,30 @@ function buildTocEntries(context, instruction, currentField, preservedTocPages,
293922
294318
  ...bookmarkName ? { bookmarkName } : {}
293923
294319
  };
293924
294320
  }).filter((entry) => entry != null).filter((entry) => entry.text.length > 0);
293925
- const tcIdentifier = parseQuotedSwitch(instruction, "f");
293926
- const tcLevels = parseNumericSwitchRange(instruction, "l");
293927
- const tcEntries = listCanonicalFieldEntries(context).filter((entry) => instructionKeyword(entry.descriptor.instructionText) === "TC").map((entry) => ({ entry, parsed: parseTocEntryInstruction(entry.descriptor.instructionText) })).filter(({ parsed }) => (tcIdentifier == null || parsed.tableIdentifier === tcIdentifier) && (tcLevels == null || parsed.level >= tcLevels.from && parsed.level <= tcLevels.to)).map(({ entry, parsed }) => {
293928
- const preservedPage = readPreservedTocPageByText(preservedPages, parsed.text);
294321
+ const tcSelection = parseTocTcSourceSelection(instruction);
294322
+ const bodyParagraphs = new Map(paragraphs.map((paragraph2) => [`${paragraph2.storyId}:${paragraph2.blockId}`, paragraph2]));
294323
+ const tcFields = listCanonicalFieldEntries(context).filter((entry) => instructionKeyword(entry.descriptor.instructionText) === "TC").filter((entry) => bodyParagraphs.has(`${entry.storyId}:${entry.blockId}`));
294324
+ const tcBookmarkNames = resolveTocTcBookmarkNames(bodyBookmarks, paragraphs, tcFields);
294325
+ const tcEntries = tcFields.map((entry) => ({ entry, parsed: parseTocEntryInstruction(entry.descriptor.instructionText) })).filter(({ parsed }) => matchesTocTcSourceSelection(tcSelection, parsed)).map(({ entry, parsed }) => {
294326
+ const text = parsed.text;
294327
+ const separatorIndex = text.indexOf("\t");
294328
+ const marker = separatorIndex > 0 ? text.slice(0, separatorIndex) : undefined;
294329
+ const title = separatorIndex > 0 ? text.slice(separatorIndex + 1) : undefined;
294330
+ const fieldKey = tocTcFieldSourceKey(entry);
294331
+ const bookmarkName = tocBookmarkNames?.get(fieldKey) ?? tcBookmarkNames.get(fieldKey);
294332
+ const bookmarkKey = bookmarkName ? normalizeTocBookmarkKey(bookmarkName) : undefined;
294333
+ const preservedPage = (bookmarkKey ? preservedPagesByBookmark.get(bookmarkKey) : undefined) ?? readPreservedTocPageByText(preservedPages, text);
293929
294334
  return {
293930
- text: parsed.text,
294335
+ sourceByteStart: entry.descriptor.byteStart,
294336
+ text,
293931
294337
  page: preservedPage ?? String(pages.displayPageByBlockId.get(entry.blockId) ?? 1),
293932
- level: parsed.level
294338
+ level: parsed.level,
294339
+ isTcEntry: true,
294340
+ ...marker && title ? { marker, title, markerSeparator: "tab" } : {},
294341
+ ...bookmarkName ? { bookmarkName } : {}
293933
294342
  };
293934
- }).filter((entry) => entry.text.length > 0);
293935
- return [...headings, ...tcEntries];
294343
+ });
294344
+ return [...headings, ...tcEntries].sort((left, right) => left.sourceByteStart - right.sourceByteStart).map(({ sourceByteStart: _sourceByteStart, ...entry }) => entry);
293936
294345
  }
293937
294346
  function parseTocCustomStyles(instruction) {
293938
294347
  const raw = parseQuotedSwitch(instruction, "t");
@@ -293952,18 +294361,19 @@ function parseTocCustomStyles(instruction) {
293952
294361
  function normalizeStyleId(value2) {
293953
294362
  return value2.replace(/\s+/g, "").trim().toLowerCase();
293954
294363
  }
293955
- function readDocumentTocParagraphTemplates(paragraphs) {
294364
+ function readDocumentTocParagraphTemplates(paragraphs, ownerBlockId) {
293956
294365
  const templates = emptyTocParagraphTemplates();
293957
294366
  for (const paragraph2 of paragraphs) {
293958
294367
  const level = readTocParagraphLevel(paragraph2.rawXml);
293959
294368
  if (level == null)
293960
294369
  continue;
293961
- const open2 = buildTocParagraphTemplateOpen(paragraph2.rawXml);
294370
+ const open2 = buildTocParagraphTemplateOpen(paragraph2.blockId === ownerBlockId ? removeTocOwnerPropertiesFromTemplate(paragraph2.rawXml) : paragraph2.rawXml);
293962
294371
  if (!templates.byLevel.has(level))
293963
294372
  templates.byLevel.set(level, open2);
293964
294373
  const entryText = readTocParagraphTemplateText(paragraph2.rawXml);
293965
- if (entryText && !templates.byText.has(entryText))
293966
- templates.byText.set(entryText, open2);
294374
+ const key2 = `${level}:${entryText}`;
294375
+ if (entryText && !templates.byLevelAndText.has(key2))
294376
+ templates.byLevelAndText.set(key2, open2);
293967
294377
  }
293968
294378
  return templates;
293969
294379
  }
@@ -293971,7 +294381,8 @@ function readTocEntryRunPropertiesTemplates(context, currentField) {
293971
294381
  const templates = {
293972
294382
  byBookmark: new Map,
293973
294383
  byText: new Map,
293974
- byLevel: new Map
294384
+ byLevel: new Map,
294385
+ paragraphByRunTemplate: new Map
293975
294386
  };
293976
294387
  if (!currentField)
293977
294388
  return templates;
@@ -293986,12 +294397,18 @@ function readTocEntryRunPropertiesTemplates(context, currentField) {
293986
294397
  const { runProperties } = visibleEntry;
293987
294398
  if (runProperties.length === 0)
293988
294399
  continue;
294400
+ templates.paragraphByRunTemplate.set(runProperties, {
294401
+ level,
294402
+ open: buildTocParagraphTemplateOpen(paragraphXml)
294403
+ });
293989
294404
  const hyperlinkXml = findFirstElement(paragraphXml, "hyperlink")?.xml ?? "";
293990
294405
  const hyperlinkBookmark = readXmlAttributeByLocalName(hyperlinkXml, "anchor");
293991
294406
  const bookmark = hyperlinkBookmark ? decodeXmlEntities2(hyperlinkBookmark) : readTocPageReferenceBookmarkName(paragraphXml);
293992
294407
  const bookmarkKey = bookmark ? normalizeTocBookmarkKey(bookmark) : "";
293993
- if (bookmarkKey && !templates.byBookmark.has(bookmarkKey)) {
293994
- templates.byBookmark.set(bookmarkKey, runProperties);
294408
+ if (bookmarkKey) {
294409
+ const byBookmark = templates.byBookmark.get(bookmarkKey) ?? [];
294410
+ byBookmark.push(runProperties);
294411
+ templates.byBookmark.set(bookmarkKey, byBookmark);
293995
294412
  }
293996
294413
  const entryText = readTocParagraphTemplateText(visibleEntry);
293997
294414
  if (entryText) {
@@ -294255,24 +294672,54 @@ function hasEnabledWebHidden(xml) {
294255
294672
  }
294256
294673
  function resolveTocEntryRunProperties(entries, templates) {
294257
294674
  const usedTemplates = new Set;
294675
+ const bookmarkEntryCounts = new Map;
294676
+ for (const entry of entries) {
294677
+ if (!entry.bookmarkName)
294678
+ continue;
294679
+ const key2 = normalizeTocBookmarkKey(entry.bookmarkName);
294680
+ bookmarkEntryCounts.set(key2, (bookmarkEntryCounts.get(key2) ?? 0) + 1);
294681
+ }
294258
294682
  const byTextQueues = new Map([...templates.byText].map(([text, matches]) => [text, [...matches]]));
294259
- const takeByText = (text) => {
294683
+ const takeByText = (text, accept) => {
294260
294684
  const queue = byTextQueues.get(text);
294261
- while (queue?.length) {
294262
- const candidate2 = queue.shift();
294263
- if (candidate2 && !usedTemplates.has(candidate2))
294264
- return candidate2;
294265
- }
294266
- return;
294685
+ const index = queue?.findIndex((candidate2) => !usedTemplates.has(candidate2) && (!accept || accept(candidate2))) ?? -1;
294686
+ return index >= 0 ? queue?.splice(index, 1)[0] : undefined;
294267
294687
  };
294268
294688
  const resolved = entries.map((entry) => {
294269
294689
  const bookmarkKey = entry.bookmarkName ? normalizeTocBookmarkKey(entry.bookmarkName) : "";
294270
- const byBookmark = bookmarkKey ? templates.byBookmark.get(bookmarkKey) : undefined;
294271
- const byText = byBookmark ? undefined : takeByText(normalizeTocEntryText(entry.text));
294272
- const match = byBookmark ?? byText;
294273
- if (match)
294274
- usedTemplates.add(match);
294275
- return match;
294690
+ const bookmarkTemplates = bookmarkKey ? templates.byBookmark.get(bookmarkKey) : undefined;
294691
+ const byBookmark = bookmarkEntryCounts.get(bookmarkKey) === 1 && bookmarkTemplates?.length === 1 ? bookmarkTemplates[0] : undefined;
294692
+ if (byBookmark)
294693
+ usedTemplates.add(byBookmark);
294694
+ return byBookmark;
294695
+ });
294696
+ entries.forEach((entry, index) => {
294697
+ if (resolved[index] || !entry.isTcEntry)
294698
+ return;
294699
+ const levelTemplates = templates.byLevel.get(normalizeTocLevel(entry.level));
294700
+ const byText = takeByText(normalizeTocEntryText(entry.text), (template) => levelTemplates?.includes(template) === true && !template.some((run) => run.separator === "tab"));
294701
+ if (!byText)
294702
+ return;
294703
+ resolved[index] = byText;
294704
+ usedTemplates.add(byText);
294705
+ });
294706
+ entries.forEach((entry, index) => {
294707
+ if (resolved[index] || !entry.isTcEntry)
294708
+ return;
294709
+ const cachedSeparatorTemplate = templates.byLevel.get(normalizeTocLevel(entry.level))?.find((template) => !usedTemplates.has(template) && applyCachedTcEntrySeparator(entry, template) !== entry);
294710
+ if (!cachedSeparatorTemplate)
294711
+ return;
294712
+ resolved[index] = cachedSeparatorTemplate;
294713
+ usedTemplates.add(cachedSeparatorTemplate);
294714
+ });
294715
+ entries.forEach((entry, index) => {
294716
+ if (resolved[index])
294717
+ return;
294718
+ const byText = takeByText(normalizeTocEntryText(entry.text));
294719
+ if (!byText)
294720
+ return;
294721
+ resolved[index] = byText;
294722
+ usedTemplates.add(byText);
294276
294723
  });
294277
294724
  for (const level of new Set(entries.map((entry) => normalizeTocLevel(entry.level)))) {
294278
294725
  const entryIndexes = entries.map((entry, index) => normalizeTocLevel(entry.level) === level ? index : -1).filter((index) => index >= 0);
@@ -294308,6 +294755,49 @@ function resolveTocEntryRunProperties(entries, templates) {
294308
294755
  }
294309
294756
  return resolved;
294310
294757
  }
294758
+ function resolveTocEntryParagraphOpens(entries, runTemplates, templates, ownerParagraphXml) {
294759
+ const ownerOpen = ownerParagraphXml ? buildTocParagraphTemplateOpen(ownerParagraphXml) : undefined;
294760
+ return entries.map((entry, index) => {
294761
+ const runs = runTemplates[index];
294762
+ const paired = runs && templates.paragraphByRunTemplate.get(runs);
294763
+ if (!paired || paired.level !== normalizeTocLevel(entry.level))
294764
+ return;
294765
+ return paired.open === ownerOpen ? removeTocOwnerPropertiesFromTemplate(paired.open) : paired.open;
294766
+ });
294767
+ }
294768
+ function applyCachedTcEntrySeparator(entry, template) {
294769
+ if (!entry.isTcEntry || !template || entry.text.includes("\t"))
294770
+ return entry;
294771
+ const separatorIndex = template.findIndex((run) => run.separator === "tab");
294772
+ if (separatorIndex <= 0 || template.slice(separatorIndex + 1).some((run) => run.separator === "tab"))
294773
+ return entry;
294774
+ const cachedLabel = template.map((run) => run.separator === "tab" ? "\t" : run.text).join("");
294775
+ const compactLabel = normalizeCompactTocEntryText(cachedLabel).replace(/\.$/, "");
294776
+ if (compactLabel !== normalizeCompactTocEntryText(entry.text).replace(/\.$/, ""))
294777
+ return entry;
294778
+ const marker = normalizeTocEntryText(template.slice(0, separatorIndex).map((run) => run.text).join(""));
294779
+ const compactMarker = normalizeCompactTocEntryText(marker);
294780
+ if (!compactMarker || !normalizeCompactTocEntryText(entry.text).startsWith(compactMarker))
294781
+ return entry;
294782
+ let markerEnd = 0;
294783
+ let remainingMarkerLength = compactMarker.length;
294784
+ while (markerEnd < entry.text.length && remainingMarkerLength > 0) {
294785
+ if (!/\s/.test(entry.text[markerEnd]))
294786
+ remainingMarkerLength -= 1;
294787
+ markerEnd += 1;
294788
+ }
294789
+ const title = entry.text.slice(markerEnd).trim();
294790
+ if (!title)
294791
+ return entry;
294792
+ return {
294793
+ ...entry,
294794
+ text: joinMarkerAndText(marker, title),
294795
+ marker,
294796
+ title,
294797
+ markerSeparator: "tab",
294798
+ cachedParagraphText: cachedLabel
294799
+ };
294800
+ }
294311
294801
  function readUnanimousTocTextTemplate(matchingTemplates) {
294312
294802
  const template = matchingTemplates?.[0];
294313
294803
  if (!template)
@@ -294340,16 +294830,61 @@ function readUniformTocLevelRunProperties(siblingTemplates) {
294340
294830
  return uniformRunProperties;
294341
294831
  }
294342
294832
  function buildTocContinuationParagraphOpen(entry, templates) {
294343
- return resolveTocParagraphOpen(entry.level, templates, entry.text);
294833
+ return resolveTocParagraphOpen(entry.level, templates, entry.cachedParagraphText ?? entry.text);
294834
+ }
294835
+ function createTocPageTabFallback(context, instruction, fieldByteStart) {
294836
+ if (/\\n\b/.test(instruction) || parseQuotedSwitch(instruction, "p") != null)
294837
+ return (paragraphOpen) => paragraphOpen;
294838
+ let model;
294839
+ let position;
294840
+ return (paragraphOpen, entry) => {
294841
+ if (entry.markerSeparator === "tab" || entry.text.includes("\t"))
294842
+ return paragraphOpen;
294843
+ const properties = findDirectChild(paragraphOpen + "</w:p>", "pPr");
294844
+ if (!properties || findDirectChild(properties.xml, "tabs") || findDirectChild(properties.xml, "AlternateContent"))
294845
+ return paragraphOpen;
294846
+ model ?? (model = compileWordStyleModel({
294847
+ stylesXml: readStyleDefinitionsPartBytes(context),
294848
+ settingsXml: readPartBytes2(context, "/word/settings.xml"),
294849
+ numberingXml: readPartBytes2(context, "/word/numbering.xml")
294850
+ }));
294851
+ const style = findDirectChild(properties.xml, "pStyle");
294852
+ const styleId = style ? readXmlAttributeByLocalName(style.xml, "val") : undefined;
294853
+ if (model.resolveParagraph({ inlineProps: { styleId } }).tabStops?.length)
294854
+ return paragraphOpen;
294855
+ const container = parseContainerXml(properties.xml.replace(/\/>$/, `></${properties.qname}>`), "pPr");
294856
+ if (!container)
294857
+ return paragraphOpen;
294858
+ if (position == null) {
294859
+ const sections = readLiveSectionSignals(context);
294860
+ const section = sections.find((candidate2) => fieldByteStart < candidate2.sectPr.rawXmlByteEnd) ?? sections.at(-1);
294861
+ const setup = section?.pageSetup;
294862
+ const width = (setup?.pageSize.widthTwips ?? 12240) - (setup?.margins.leftTwips ?? 1440) - (setup?.margins.rightTwips ?? 1440) - (setup?.margins.gutterTwips ?? 0);
294863
+ const count = Math.max(1, section?.columns?.count ?? 1);
294864
+ const columnWidth = section?.columns?.columns[0]?.widthTwips ?? (width - (count - 1) * (section?.columns?.spaceTwips ?? 720)) / count;
294865
+ position = Math.max(0, Math.floor(columnWidth) - 10);
294866
+ }
294867
+ const prefix = container.prefix;
294868
+ const tabs2 = `<${prefix}:tabs><${prefix}:tab ${prefix}:val="right" ${prefix}:leader="dot" ${prefix}:pos="${position}"/></${prefix}:tabs>`;
294869
+ const children2 = setParagraphPropertyChild(parseTopLevelChildrenPreservingTrivia(container.inner), "tabs", tabs2);
294870
+ return paragraphOpen.replace(properties.xml, () => container.open + serializeTopLevelChildren(children2) + container.close);
294871
+ };
294344
294872
  }
294345
- function buildGeneratedTocParagraphOpen(level, seedParagraph, templates, entryText) {
294346
- const template = resolveTocParagraphTemplate(level, templates, entryText);
294347
- if (template)
294873
+ function buildGeneratedTocParagraphOpen(level, seedParagraph, templates, entryText, retainOwner = false, pairedTemplate) {
294874
+ const template = pairedTemplate ?? resolveTocParagraphTemplate(level, templates, entryText);
294875
+ if (template && !(retainOwner && seedParagraph))
294348
294876
  return template;
294349
294877
  const normalizedLevel = normalizeTocLevel(level);
294350
294878
  if (!seedParagraph)
294351
294879
  return `<w:p><w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
294352
- return `${readParagraphOpenTag(seedParagraph.rawXml)}<w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
294880
+ const ownerOpenTag = readParagraphOpenTag(seedParagraph.rawXml);
294881
+ if (!retainOwner)
294882
+ return `${ownerOpenTag}<w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
294883
+ const templateOpenEnd = template ? findXmlTagEnd4(template, 1) : -1;
294884
+ const properties = template ? inheritRunNamespaceDeclarations(template.slice(templateOpenEnd), template, templateOpenEnd, template.slice(0, templateOpenEnd)) : `<w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
294885
+ const ownerPropertiesStart = skipXmlWhitespace(seedParagraph.rawXml, ownerOpenTag.length);
294886
+ const ownerProperties = matchLeadingElement(seedParagraph.rawXml.slice(ownerPropertiesStart), "pPr");
294887
+ return ownerOpenTag + preserveTocOwnerProperties(properties, ownerProperties);
294353
294888
  }
294354
294889
  function readParagraphOpenTag(paragraphXml) {
294355
294890
  const match = /^<w:p\b([^>]*?)(?:\/>|>)/s.exec(paragraphXml);
@@ -294360,6 +294895,9 @@ function normalizeTocLevel(level) {
294360
294895
  }
294361
294896
  function buildTocEntryTextRuns(entry, runProperties, includeHyperlinks) {
294362
294897
  const buildLabelRun = (text, template) => {
294898
+ if (entry.isTcEntry && text.includes("\t")) {
294899
+ return text.split("\t").map((part, index) => (index > 0 ? "<w:r><w:tab/></w:r>" : "") + (part ? buildLabelRun(part, template) : "")).join("");
294900
+ }
294363
294901
  const sanitized = template ? sanitizeTocLabelRunProperties(template.runProperties, includeHyperlinks) : "";
294364
294902
  if (!sanitized)
294365
294903
  return buildTextRunXml(text);
@@ -294388,7 +294926,7 @@ function buildTocEntryTextRuns(entry, runProperties, includeHyperlinks) {
294388
294926
  }
294389
294927
  const cachedFirstRunText = runProperties?.[0]?.text;
294390
294928
  const matchesCompleteMarkerBoundary = cachedFirstRunText === entry.marker || entry.markerSeparator === "space" && cachedFirstRunText?.startsWith(`${entry.marker} `);
294391
- if (markerSeparatorIndex < 0 && matchesCompleteMarkerBoundary) {
294929
+ if (markerSeparatorIndex < 0 && entry.markerSeparator !== "tab" && matchesCompleteMarkerBoundary) {
294392
294930
  return buildLabelRuns(entry.text, runProperties);
294393
294931
  }
294394
294932
  if (markerSeparatorIndex < 0 && entry.markerSeparator === "space" && runProperties?.[0]) {
@@ -294408,8 +294946,28 @@ function buildTocEntryTextRuns(entry, runProperties, includeHyperlinks) {
294408
294946
  }
294409
294947
  }
294410
294948
  }
294411
- const markerTemplates = markerSeparatorIndex >= 0 ? runProperties?.slice(0, markerSeparatorIndex) : runProperties?.slice(0, 1);
294412
- const titleTemplates = markerSeparatorIndex >= 0 ? runProperties?.slice(markerSeparatorIndex + 1) : runProperties && runProperties.length > 1 ? runProperties.slice(1) : runProperties;
294949
+ let markerTemplates = markerSeparatorIndex >= 0 ? runProperties?.slice(0, markerSeparatorIndex) : runProperties?.slice(0, 1);
294950
+ let titleTemplates = markerSeparatorIndex >= 0 ? runProperties?.slice(markerSeparatorIndex + 1) : runProperties && runProperties.length > 1 ? runProperties.slice(1) : runProperties;
294951
+ if (markerSeparatorIndex < 0 && entry.markerSeparator === "tab" && runProperties) {
294952
+ const cachedLabel = runProperties.map((template) => template.text).join("");
294953
+ const markerEnd = entry.marker.length;
294954
+ const titleStart = markerEnd + /^\s*/.exec(cachedLabel.slice(markerEnd))[0].length;
294955
+ if (cachedLabel.startsWith(entry.marker) && cachedLabel.slice(titleStart) === entry.title) {
294956
+ markerTemplates = [];
294957
+ titleTemplates = [];
294958
+ let offset = 0;
294959
+ for (const template of runProperties) {
294960
+ const end = offset + template.text.length;
294961
+ if (offset < markerEnd) {
294962
+ markerTemplates.push({ ...template, text: template.text.slice(0, markerEnd - offset) });
294963
+ }
294964
+ if (end > titleStart) {
294965
+ titleTemplates.push({ ...template, text: template.text.slice(Math.max(0, titleStart - offset)) });
294966
+ }
294967
+ offset = end;
294968
+ }
294969
+ }
294970
+ }
294413
294971
  const markerRuns = buildLabelRuns(entry.marker, markerTemplates);
294414
294972
  if (entry.markerSeparator === "tab") {
294415
294973
  return [...markerRuns, "<w:r><w:tab/></w:r>", ...buildLabelRuns(entry.title, titleTemplates)];
@@ -294426,9 +294984,42 @@ function sanitizeTocLabelRunProperties(runPropertiesXml, includeHyperlinks) {
294426
294984
  return runPropertiesXml;
294427
294985
  return runPropertiesXml.replace(/<(?:[\w.-]+:)?rStyle\b(?=[^>]*\b(?:[\w.-]+:)?val=(["'])Hyperlink\1)[^>]*(?:\/>|>\s*<\/(?:[\w.-]+:)?rStyle\s*>)/gi, "");
294428
294986
  }
294429
- function buildBodyTocBookmarkMap(context) {
294987
+ function tocTcFieldSourceKey(field) {
294988
+ return `tc:${field.storyId}:${field.stableFieldId}`;
294989
+ }
294990
+ function resolveTocTcBookmarkNames(bookmarks, paragraphs, fields) {
294991
+ if (fields.length === 0)
294992
+ return new Map;
294993
+ const sourceKeys = new Set(fields.map((field) => `${field.storyId}:${field.blockId}`));
294994
+ const sourceParagraphs = paragraphs.filter((paragraph2) => sourceKeys.has(`${paragraph2.storyId}:${paragraph2.blockId}`));
294995
+ const paragraphBookmarks = buildBodyTocBookmarkMap(bookmarks);
294996
+ const paragraphsByKey = new Map(sourceParagraphs.map((paragraph2) => [`${paragraph2.storyId}:${paragraph2.blockId}`, paragraph2]));
294997
+ const ranges = buildBodyTocBookmarkRangeMap(bookmarks, sourceParagraphs);
294998
+ const siblings = new Map;
294999
+ for (const field of fields) {
295000
+ const key2 = `${field.storyId}:${field.blockId}`;
295001
+ const group = siblings.get(key2) ?? [];
295002
+ group.push(field);
295003
+ siblings.set(key2, group);
295004
+ }
295005
+ const names = new Map;
295006
+ for (const field of fields) {
295007
+ const paragraphKey = `${field.storyId}:${field.blockId}`;
295008
+ const bookmarkRanges = ranges.get(paragraphKey);
295009
+ const paragraphBookmark = paragraphBookmarks.get(paragraphKey);
295010
+ const fallbackRange = bookmarkRanges?.find((bookmark) => bookmark.name === paragraphBookmark);
295011
+ const belongsToSibling = fallbackRange && siblings.get(paragraphKey)?.some((sibling) => sibling.stableFieldId !== field.stableFieldId && (fallbackRange.start >= sibling.descriptor.byteStart && fallbackRange.end <= sibling.descriptor.byteEnd || fallbackRange.start <= sibling.descriptor.byteStart && fallbackRange.end >= sibling.descriptor.byteEnd));
295012
+ const paragraph2 = paragraphsByKey.get(paragraphKey);
295013
+ const coversCrossParagraphStart = paragraph2 && fallbackRange && field.descriptor.byteEnd > paragraph2.byteEnd && fallbackRange.start <= field.descriptor.byteStart && fallbackRange.end > field.descriptor.byteStart;
295014
+ const name = bookmarkRanges?.find((bookmark) => bookmark.start >= field.descriptor.byteStart && bookmark.end <= field.descriptor.byteEnd)?.name ?? bookmarkRanges?.find((bookmark) => bookmark.start <= field.descriptor.byteStart && bookmark.end >= field.descriptor.byteEnd)?.name ?? (belongsToSibling && !coversCrossParagraphStart ? undefined : paragraphBookmark);
295015
+ if (name)
295016
+ names.set(tocTcFieldSourceKey(field), name);
295017
+ }
295018
+ return names;
295019
+ }
295020
+ function buildBodyTocBookmarkMap(entries) {
294430
295021
  const bookmarks = new Map;
294431
- for (const entry of readBookmarkEntries(context)) {
295022
+ for (const entry of entries) {
294432
295023
  if (!entry.name.startsWith("_Toc"))
294433
295024
  continue;
294434
295025
  const key2 = `${entry.storyId}:${entry.blockId}`;
@@ -294437,6 +295028,43 @@ function buildBodyTocBookmarkMap(context) {
294437
295028
  }
294438
295029
  return bookmarks;
294439
295030
  }
295031
+ function buildBodyTocBookmarkRangeMap(bookmarks, paragraphs) {
295032
+ if (paragraphs.length === 0)
295033
+ return new Map;
295034
+ const paragraphsByKey = new Map(paragraphs.map((paragraph2) => [`${paragraph2.storyId}:${paragraph2.blockId}`, paragraph2]));
295035
+ const scans = new Map;
295036
+ const ranges = new Map;
295037
+ for (const bookmark of bookmarks) {
295038
+ if (!bookmark.name.startsWith("_Toc"))
295039
+ continue;
295040
+ const key2 = `${bookmark.storyId}:${bookmark.blockId}`;
295041
+ const paragraph2 = paragraphsByKey.get(key2);
295042
+ if (!paragraph2)
295043
+ continue;
295044
+ if (!scans.has(key2))
295045
+ scans.set(key2, readBookmarkMarkerSpans(paragraph2.rawXml, paragraph2.namespaceBindings));
295046
+ const scan = scans.get(key2);
295047
+ if (!scan || scan.invalidBookmarkIds.has(bookmark.bookmarkId))
295048
+ continue;
295049
+ const endMarker = scan.markers.find((marker) => marker.kind === "end" && marker.bookmarkId === bookmark.bookmarkId);
295050
+ if (!endMarker)
295051
+ continue;
295052
+ const range = {
295053
+ name: bookmark.name,
295054
+ start: bookmark.markerByteStart,
295055
+ end: paragraph2.byteStart + encodeXml(paragraph2.rawXml.slice(0, endMarker.start)).length
295056
+ };
295057
+ if (range.end < range.start)
295058
+ continue;
295059
+ const paragraphRanges = ranges.get(key2) ?? [];
295060
+ paragraphRanges.push(range);
295061
+ ranges.set(key2, paragraphRanges);
295062
+ }
295063
+ for (const paragraphRanges of ranges.values()) {
295064
+ paragraphRanges.sort((left, right) => left.end - left.start - (right.end - right.start));
295065
+ }
295066
+ return ranges;
295067
+ }
294440
295068
  function buildTocPageReferenceRunsXml(bookmarkName, page, separator) {
294441
295069
  return buildTocPageSeparatorRunsXml(separator) + buildWebHiddenFieldCharRunXml("begin") + buildWebHiddenInstructionRunXml(` PAGEREF ${bookmarkName} \\h `) + buildWebHiddenEmptyRunXml() + buildWebHiddenFieldCharRunXml("separate") + buildWebHiddenTextRunXml(page) + buildWebHiddenFieldCharRunXml("end");
294442
295070
  }
@@ -294466,7 +295094,7 @@ function buildWebHiddenEmptyRunXml() {
294466
295094
  function emptyTocParagraphTemplates() {
294467
295095
  return {
294468
295096
  byLevel: new Map,
294469
- byText: new Map
295097
+ byLevelAndText: new Map
294470
295098
  };
294471
295099
  }
294472
295100
  function buildTocParagraphTemplatesFromParagraphXml(xml) {
@@ -294480,18 +295108,20 @@ function buildTocParagraphTemplatesFromParagraphXml(xml) {
294480
295108
  if (!templates.byLevel.has(level))
294481
295109
  templates.byLevel.set(level, open2);
294482
295110
  const entryText = readTocParagraphTemplateText(paragraphXml);
294483
- if (entryText && !templates.byText.has(entryText))
294484
- templates.byText.set(entryText, open2);
295111
+ const key2 = `${level}:${entryText}`;
295112
+ if (entryText && !templates.byLevelAndText.has(key2))
295113
+ templates.byLevelAndText.set(key2, open2);
294485
295114
  }
294486
295115
  return templates;
294487
295116
  }
294488
295117
  function buildTocParagraphTemplateOpen(paragraphXml) {
294489
295118
  const openTag = /^<w:p\b[^>]*>/s.exec(paragraphXml)?.[0] ?? "";
294490
- const pPrXml = openTag ? matchLeadingElement(paragraphXml.slice(openTag.length), "pPr") : "";
295119
+ const pPrXml = openTag ? matchLeadingElement(paragraphXml.slice(skipXmlWhitespace(paragraphXml, openTag.length)), "pPr") : "";
294491
295120
  return `${readParagraphOpenTag(paragraphXml)}${pPrXml}`;
294492
295121
  }
294493
295122
  function readTocParagraphLevel(paragraphXml) {
294494
- const paragraphStyle = findFirstElement(paragraphXml, "pStyle");
295123
+ const propertiesXml = matchLeadingElement(paragraphXml, "pPr") || findDirectChild(paragraphXml, "pPr")?.xml;
295124
+ const paragraphStyle = propertiesXml ? findDirectChild(propertiesXml, "pStyle") : undefined;
294495
295125
  const style = paragraphStyle ? /^TOC(\d+)$/.exec(readXmlAttributeByLocalName(paragraphStyle.xml, "val") ?? "")?.[1] : undefined;
294496
295126
  if (!style)
294497
295127
  return null;
@@ -294514,13 +295144,14 @@ function resolveTocParagraphOpen(level, templates, entryText) {
294514
295144
  return `<w:p><w:pPr><w:pStyle w:val="TOC${normalizedLevel}"/></w:pPr>`;
294515
295145
  }
294516
295146
  function resolveTocParagraphTemplate(level, templates, entryText) {
295147
+ const normalizedLevel = normalizeTocLevel(level);
294517
295148
  const normalizedText = entryText ? normalizeTocEntryText(entryText) : "";
294518
295149
  if (normalizedText.length > 0) {
294519
- const byText = templates.byText.get(normalizedText);
294520
- if (byText)
294521
- return byText;
295150
+ const byLevelAndText = templates.byLevelAndText.get(`${normalizedLevel}:${normalizedText}`);
295151
+ if (byLevelAndText)
295152
+ return byLevelAndText;
294522
295153
  }
294523
- return templates.byLevel.get(normalizeTocLevel(level));
295154
+ return templates.byLevel.get(normalizedLevel);
294524
295155
  }
294525
295156
  function readPreservedTocPagesByText(context, currentField, paragraphs = readBodyParagraphs(context, { includeListState: false })) {
294526
295157
  const preserved = new Map;
@@ -295210,7 +295841,7 @@ function joinMarkerAndText(marker, text) {
295210
295841
  return text.length > 0 ? `${marker} ${text}` : marker;
295211
295842
  }
295212
295843
  function parseTocEntryInstruction(instruction) {
295213
- const tableIdentifier = parseQuotedSwitch(instruction, "f") ?? parseQuotedSwitch(instruction, "t");
295844
+ const tableIdentifier = parseTocFieldIdentifier(instruction) ?? parseQuotedSwitch(instruction, "t");
295214
295845
  return {
295215
295846
  text: parseFirstQuotedValue(instruction) ?? "",
295216
295847
  level: Number(parseNumericSwitchValue(instruction, "l") ?? "1"),
@@ -295319,6 +295950,10 @@ var init_runtime2 = __esm(() => {
295319
295950
  init_registry3();
295320
295951
  init_stories();
295321
295952
  init_section_xml();
295953
+ init_src6();
295954
+ init_part();
295955
+ init_common();
295956
+ init_paragraph_property_order();
295322
295957
  init_scalar_evaluation();
295323
295958
  init_bookmark_insertion();
295324
295959
  init_xml();
@@ -340500,10 +341135,18 @@ class V2ContentControlsAdapter {
340500
341135
  if (controlPlacement(part.xml, control2) !== control2.info.kind) {
340501
341136
  throw operationError("CAPABILITY_UNAVAILABLE", "Row and cell controls are not supported adjacent insertion targets.");
340502
341137
  }
340503
- let fragment4 = buildAdjacentContent(input.content ?? "", control2.info.kind, createParaIdAllocator(this.context));
341138
+ const allocator = createParaIdAllocator(this.context);
341139
+ let createdBlockId = null;
341140
+ const captureParaId = () => {
341141
+ const id = allocator();
341142
+ if (createdBlockId == null)
341143
+ createdBlockId = id;
341144
+ return id;
341145
+ };
341146
+ let fragment4 = buildAdjacentContent(input.content ?? "", control2.info.kind, captureParaId);
340504
341147
  let commitOptions = {
340505
341148
  partUri: part.partUri,
340506
- storySurface: { family: "storyBlocks", contentControlRewrite: true, targetBlockIds: [] },
341149
+ storySurface: { family: "storyBlocks", contentControlRewrite: true, changeMode: "direct", targetBlockIds: [] },
340507
341150
  preserveRenderCommit: true
340508
341151
  };
340509
341152
  if (options?.changeMode === "tracked") {
@@ -340529,7 +341172,7 @@ class V2ContentControlsAdapter {
340529
341172
  return this.validateDryRun(input, options, control2.target);
340530
341173
  const index2 = placement3 === "before" ? control2.start : control2.end;
340531
341174
  const nextXml = `${part.xml.slice(0, index2)}${fragment4}${part.xml.slice(index2)}`;
340532
- return this.commitDocument(nextXml, `content-control-insert-${placement3}`, input, options, control2.target, commitOptions);
341175
+ return this.commitDocument(nextXml, `content-control-insert-${placement3}`, input, options, control2.target, { ...commitOptions, ...createdBlockId != null ? { createdBlockId } : {} });
340533
341176
  }
340534
341177
  mutatePr(input, options, transform2) {
340535
341178
  return this.mutateControl(input.target, input, options, (control2) => {
@@ -340920,6 +341563,7 @@ class V2ContentControlsAdapter {
340920
341563
  if (!documentProtectionAllowsXmlRewrite(this.context, partUri, before, nextXml)) {
340921
341564
  return { success: false, failure: { code: "PERMISSION_DENIED", message: DOCUMENT_PROTECTION_MESSAGE } };
340922
341565
  }
341566
+ let remappedCreatedBlockId = commitOptions.createdBlockId;
340923
341567
  if (commitOptions.storySurface?.contentControlRewrite && this.context.isCollaborativeSession()) {
340924
341568
  const existingIds = new Set(this.load().parts.flatMap((part) => Array.from(part.xml.matchAll(/\bw14:paraId="([^"]+)"/g), (match) => match[1])));
340925
341569
  const newIds = [...new Set(Array.from(nextXml.matchAll(/\bw14:paraId="([^"]+)"/g), (match) => match[1]))].filter((id) => !existingIds.has(id));
@@ -340929,6 +341573,9 @@ class V2ContentControlsAdapter {
340929
341573
  return { success: false, failure: { code: "PRECONDITION_FAILED", message: "Could not reserve content-control paragraph identities." } };
340930
341574
  const remap = new Map(newIds.map((id, index2) => [id, allocated[index2]]));
340931
341575
  nextXml = nextXml.replace(/\bw14:paraId="([^"]+)"/g, (attribute, id) => remap.has(id) ? `w14:paraId="${remap.get(id)}"` : attribute);
341576
+ if (remappedCreatedBlockId != null) {
341577
+ remappedCreatedBlockId = remap.get(remappedCreatedBlockId) ?? remappedCreatedBlockId;
341578
+ }
340932
341579
  }
340933
341580
  }
340934
341581
  const committed = commitWholePartUpdates(this.context, prefix, { [partUri]: encodeXml(nextXml) }, {
@@ -340953,7 +341600,8 @@ class V2ContentControlsAdapter {
340953
341600
  contentControl: target,
340954
341601
  ...commitOptions.updatedRef ? { updatedRef: commitOptions.updatedRef } : {},
340955
341602
  affectedStories: [...commitOptions.affectedStories ?? [target.story ?? { kind: "story", storyType: "body" }]],
340956
- ...trackedChangeRefs && trackedChangeRefs.length > 0 ? { trackedChangeRefs } : {}
341603
+ ...trackedChangeRefs && trackedChangeRefs.length > 0 ? { trackedChangeRefs } : {},
341604
+ ...remappedCreatedBlockId != null ? { createdBlockId: remappedCreatedBlockId } : {}
340957
341605
  };
340958
341606
  if (commitOptions.preserveRenderCommit) {
340959
341607
  const renderCommit = getSDRenderCommitEnvelope(committed);
@@ -343099,10 +343747,12 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
343099
343747
  }));
343100
343748
  if (missing2.some((bookmark) => !bookmark.paragraph))
343101
343749
  return unavailable4("A TOC heading target is unavailable.");
343102
- const names = new Map(missing2.map((bookmark) => [
343103
- `${bookmark.paragraph.storyId}:${bookmark.blockId}`,
343104
- bookmark.name
343105
- ]));
343750
+ const names = new Map;
343751
+ for (const bookmark of missing2) {
343752
+ names.set(bookmark.fieldSource?.key ?? `${bookmark.paragraph.storyId}:${bookmark.blockId}`, bookmark.name);
343753
+ for (const key2 of bookmark.fieldSourceKeys ?? [])
343754
+ names.set(key2, bookmark.name);
343755
+ }
343106
343756
  const sdt = prepareTocSdtReplacement(context, entry, instruction, names);
343107
343757
  const rendered = !sdt.ok && sdt.message === "Unable to locate the containing TOC content control." ? prepareBareTocReplacement(context, entry, instruction, names) : sdt;
343108
343758
  if (!rendered.ok)
@@ -343141,16 +343791,18 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
343141
343791
  ];
343142
343792
  let count = content3.wordIds.length;
343143
343793
  let bookmarkId = nextBookmarkNumericId(context);
343794
+ const bookmarkMarkers = [];
343144
343795
  for (const bookmark of missing2) {
343145
343796
  const paragraph4 = bookmark.paragraph;
343146
- const markers = [
343147
- `<w:bookmarkStart w:id="${bookmarkId}" w:name="${xmlEscapeAttr(bookmark.name)}"/>`,
343148
- `<w:bookmarkEnd w:id="${bookmarkId++}"/>`
343149
- ].map((xml2) => {
343797
+ const markerBindings = readBookmarkInsertionNamespaceBindings(paragraph4, bookmark);
343798
+ if (!markerBindings)
343799
+ return null;
343800
+ const fragments = buildParagraphBookmarkMarkers(paragraph4, bookmark, bookmarkId++);
343801
+ const markers = [fragments.startXml, fragments.endXml].map((xml) => {
343150
343802
  const marker = prepareTrackedInlineXmlReplacement({
343151
343803
  beforeXml: "",
343152
- afterXml: xml2,
343153
- namespaceBindings: new Map(Object.entries(paragraph4.namespaceBindings ?? {})),
343804
+ afterXml: xml,
343805
+ namespaceBindings: markerBindings,
343154
343806
  stamp: {
343155
343807
  ...stamp,
343156
343808
  revisionId: revisionIds?.[count] ?? count,
@@ -343163,10 +343815,12 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
343163
343815
  });
343164
343816
  if (!markers[0] || !markers[1])
343165
343817
  return null;
343166
- const start = injectParagraphPrefix(paragraph4.rawXml, markers[0].xml);
343167
- const xml = start && injectParagraphSuffix(start, markers[1].xml);
343168
- if (!xml)
343169
- return null;
343818
+ bookmarkMarkers.push({ ...bookmark, startXml: markers[0].xml, endXml: markers[1].xml });
343819
+ }
343820
+ const grouped = prepareBookmarkParagraphGroups(paragraphs, bookmarkMarkers);
343821
+ if (!grouped)
343822
+ return null;
343823
+ for (const { paragraph: paragraph4, xml } of grouped) {
343170
343824
  edits.push({
343171
343825
  partUri: paragraph4.partUri,
343172
343826
  storyId: paragraph4.storyId,
@@ -343202,6 +343856,8 @@ function regenerateTrackedToc(context, entry, instruction, dryRun) {
343202
343856
  return unavailable4("This TOC rebuild requires unsupported existing field, paragraph, or heading boundaries.");
343203
343857
  if (dryRun)
343204
343858
  return { ok: true };
343859
+ if (context.isCollaborativeSession())
343860
+ return { ok: false, code: "INVALID_CONTEXT", message: "toc-regenerate-tracked: unsupported-context" };
343205
343861
  const ids = reserveTrackedReferenceRevisionIds(context, preview.count, false);
343206
343862
  if (!ids)
343207
343863
  return unavailable4("The TOC rebuild could not reserve its complete revision identity batch.");
@@ -344461,9 +345117,11 @@ class V2TocAdapter {
344461
345117
  }
344462
345118
  if (options?.dryRun)
344463
345119
  return success3(input.target.nodeId);
345120
+ if (this.context.isCollaborativeSession())
345121
+ return failure6("INVALID_CONTEXT", "toc-configure: unsupported-context");
344464
345122
  let refreshed = entry;
344465
345123
  if (!usesV1EmptyTocSourceSet(nextInstruction)) {
344466
- const seeded = seedMissingTocBookmarks(this.context, nextInstruction);
345124
+ const seeded = seedMissingTocBookmarks(this.context, nextInstruction, entry.field);
344467
345125
  if (!seeded.ok)
344468
345126
  return failure6(seeded.code, seeded.message);
344469
345127
  const seededEntry = findTocBlock(this.context, input.target.nodeId);
@@ -344495,9 +345153,11 @@ class V2TocAdapter {
344495
345153
  }
344496
345154
  if (options?.dryRun)
344497
345155
  return success3(input.target.nodeId);
345156
+ if (this.context.isCollaborativeSession())
345157
+ return failure6("INVALID_CONTEXT", "toc-update: unsupported-context");
344498
345158
  let refreshed = entry;
344499
345159
  if (!usesV1EmptyTocSourceSet(entry.field.descriptor.instructionText)) {
344500
- const seeded = seedMissingTocBookmarks(this.context, entry.field.descriptor.instructionText);
345160
+ const seeded = seedMissingTocBookmarks(this.context, entry.field.descriptor.instructionText, entry.field);
344501
345161
  if (!seeded.ok)
344502
345162
  return failure6(seeded.code, seeded.message);
344503
345163
  const seededEntry = findTocBlock(this.context, input.target.nodeId);
@@ -344679,6 +345339,9 @@ function listTocBlocks(context) {
344679
345339
  function findTocBlock(context, nodeId) {
344680
345340
  return listTocBlocks(context).find((entry) => entry.field.blockId === nodeId) ?? null;
344681
345341
  }
345342
+ function guardTocBookmarkInsertion(context, instruction, operation) {
345343
+ return guardTocContentMutation(context, null, instruction, operation);
345344
+ }
344682
345345
  function guardTocContentMutation(context, field, instruction, operation) {
344683
345346
  const unavailable4 = () => ({ code: "CAPABILITY_UNAVAILABLE", message: `${operation}: the TOC source is unavailable.` });
344684
345347
  const decoder7 = new TextDecoder;
@@ -344698,15 +345361,28 @@ function guardTocContentMutation(context, field, instruction, operation) {
344698
345361
  });
344699
345362
  return true;
344700
345363
  };
344701
- if (!add(field.partUri, field.descriptor.byteStart, field.descriptor.byteEnd))
345364
+ if (field && !add(field.partUri, field.descriptor.byteStart, field.descriptor.byteEnd))
344702
345365
  return unavailable4();
344703
345366
  const missing2 = planMissingTocBookmarks(context, instruction);
344704
345367
  if (missing2.length) {
344705
345368
  const paragraphs = new Map(readBodyParagraphs(context, { includeListState: false }).map((paragraph4) => [paragraph4.blockId, paragraph4]));
345369
+ const aliasedFields = missing2.some((bookmark) => bookmark.fieldSourceKeys?.length) ? new Map(listCanonicalFieldEntries(context).map((source) => [tocTcFieldSourceKey(source), source])) : null;
344706
345370
  for (const bookmark of missing2) {
344707
345371
  const paragraph4 = paragraphs.get(bookmark.blockId);
344708
- if (!paragraph4 || !add(paragraph4.partUri, paragraph4.byteStart, paragraph4.byteStart + 1))
345372
+ if (!paragraph4)
344709
345373
  return unavailable4();
345374
+ const start = bookmark.fieldSource?.byteStart ?? paragraph4.byteStart;
345375
+ const end = bookmark.fieldSource?.byteEnd ?? paragraph4.byteStart;
345376
+ if (!add(paragraph4.partUri, start, start + 1) || bookmark.fieldSource && !add(paragraph4.partUri, end - 1, end))
345377
+ return unavailable4();
345378
+ for (const key2 of bookmark.fieldSourceKeys ?? []) {
345379
+ const source = aliasedFields?.get(key2);
345380
+ if (!source?.descriptor.complete)
345381
+ continue;
345382
+ const fieldSource = { key: key2, byteStart: source.descriptor.byteStart, byteEnd: source.descriptor.byteEnd };
345383
+ if (canPlaceBookmarkAtFieldSource(paragraph4, fieldSource) && (!add(source.partUri, fieldSource.byteStart, fieldSource.byteStart + 1) || !add(source.partUri, fieldSource.byteEnd - 1, fieldSource.byteEnd)))
345384
+ return unavailable4();
345385
+ }
344710
345386
  }
344711
345387
  }
344712
345388
  for (const part of parts.values()) {
@@ -344714,6 +345390,20 @@ function guardTocContentMutation(context, field, instruction, operation) {
344714
345390
  if (locked)
344715
345391
  return locked;
344716
345392
  }
345393
+ if (missing2.length) {
345394
+ const paragraphs = readBodyParagraphs(context, { includeListState: false });
345395
+ const byId = new Map(paragraphs.map((paragraph4) => [paragraph4.blockId, paragraph4]));
345396
+ let id = nextBookmarkNumericId(context);
345397
+ const markers = missing2.map((bookmark) => ({
345398
+ ...bookmark,
345399
+ ...buildParagraphBookmarkMarkers(byId.get(bookmark.blockId), bookmark, id++)
345400
+ }));
345401
+ if (!prepareBookmarkParagraphGroups(paragraphs, markers))
345402
+ return {
345403
+ code: "CAPABILITY_UNAVAILABLE",
345404
+ message: `${operation}: TOC bookmark targets have unsupported paragraph or field boundaries.`
345405
+ };
345406
+ }
344717
345407
  return null;
344718
345408
  }
344719
345409
  function paragraphOverlapsSpan(entry, span) {
@@ -344797,10 +345487,11 @@ function projectTocInlineDomain(entry) {
344797
345487
  };
344798
345488
  }
344799
345489
  function projectTocSourceConfig(instruction) {
345490
+ const tcSelection = parseTocTcSourceSelection(instruction);
344800
345491
  return {
344801
345492
  ...parseNumericSwitchRange(instruction, "o") ? { outlineLevels: parseNumericSwitchRange(instruction, "o") } : {},
344802
- ...parseQuotedSwitch(instruction, "f") ? { tcFieldIdentifier: parseQuotedSwitch(instruction, "f") } : {},
344803
- ...parseNumericSwitchRange(instruction, "l") ? { tcFieldLevels: parseNumericSwitchRange(instruction, "l") } : {},
345493
+ ...tcSelection.identifier ? { tcFieldIdentifier: tcSelection.identifier } : {},
345494
+ ...tcSelection.levels ? { tcFieldLevels: tcSelection.levels } : {},
344804
345495
  ...instruction.includes("\\u") ? { useAppliedOutlineLevel: true } : {}
344805
345496
  };
344806
345497
  }
@@ -344828,23 +345519,22 @@ function countGeneratedTocEntries(context, instruction, sourceConfig) {
344828
345519
  const outline = sourceConfig.outlineLevels ?? { from: 1, to: 3 };
344829
345520
  const customStyles = parseTocCustomStyles2(parseQuotedSwitch(instruction, "t") ?? "");
344830
345521
  const includeOutlineEntries = customStyles.length === 0 || sourceConfig.outlineLevels != null;
344831
- const headings = readBodyParagraphs(context, { includeListState: false }).filter((paragraph4) => {
345522
+ const paragraphs = readBodyParagraphs(context, { includeListState: false });
345523
+ const bodyParagraphs = new Set(paragraphs.map((paragraph4) => `${paragraph4.storyId}:${paragraph4.blockId}`));
345524
+ const headings = paragraphs.filter((paragraph4) => {
344832
345525
  const matchesCustomStyle = paragraph4.styleId != null && customStyles.some((entry) => normalizeStyleId2(entry.styleName) === normalizeStyleId2(paragraph4.styleId ?? ""));
344833
345526
  const matchesOutline = includeOutlineEntries && paragraph4.headingLevel >= outline.from && paragraph4.headingLevel <= outline.to;
344834
345527
  return matchesCustomStyle || matchesOutline;
344835
345528
  }).length;
344836
- const tcEntries = listTocInlineEntries(context).filter((entry) => {
345529
+ const tcSelection = parseTocTcSourceSelection(instruction);
345530
+ const tcEntries = listTocInlineEntries(context).filter((entry) => bodyParagraphs.has(`${entry.field.storyId}:${entry.field.blockId}`)).filter((entry) => {
344837
345531
  const parsed = parseTocEntryInstruction(entry.field.descriptor.instructionText);
344838
- if (sourceConfig.tcFieldIdentifier && parsed.tableIdentifier !== sourceConfig.tcFieldIdentifier)
344839
- return false;
344840
- if (sourceConfig.tcFieldLevels && (parsed.level < sourceConfig.tcFieldLevels.from || parsed.level > sourceConfig.tcFieldLevels.to))
344841
- return false;
344842
- return true;
345532
+ return matchesTocTcSourceSelection(tcSelection, parsed);
344843
345533
  }).length;
344844
345534
  return headings + tcEntries;
344845
345535
  }
344846
345536
  function usesV1EmptyTocSourceSet(instruction) {
344847
- return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) && parseQuotedSwitch(instruction, "f") == null && parseNumericSwitchRange(instruction, "l") == null;
345537
+ return parseQuotedSwitch(instruction, "t") != null && parseNumericSwitchRange(instruction, "o") == null && !/\\u\b/i.test(instruction) && !parseTocTcSourceSelection(instruction).enabled;
344848
345538
  }
344849
345539
  function countMaterializedTocResultParagraphs(context, field) {
344850
345540
  if (field.descriptor.resultText.length === 0)
@@ -344867,6 +345557,7 @@ function isTocResultParagraph(rawXml) {
344867
345557
  return /<[\w.-]+:pStyle\b[^>]*\b(?:[\w.-]+:)?val="TOC[1-9]"/.test(rawXml);
344868
345558
  }
344869
345559
  function applyTocPatch(instruction, patch) {
345560
+ const tcSelection = parseTocTcSourceSelection(instruction);
344870
345561
  const nextParts = ["TOC"];
344871
345562
  const outlineLevels = patch.outlineLevels ?? parseNumericSwitchRange(instruction, "o");
344872
345563
  if (outlineLevels)
@@ -344883,12 +345574,17 @@ function applyTocPatch(instruction, patch) {
344883
345574
  nextParts.push(`\\p "${separator}"`);
344884
345575
  if ((patch.useAppliedOutlineLevel ?? instruction.includes("\\u")) === true)
344885
345576
  nextParts.push("\\u");
344886
- const tcIdentifier = patch.tcFieldIdentifier ?? parseQuotedSwitch(instruction, "f");
345577
+ const tcIdentifier = patch.tcFieldIdentifier ?? tcSelection.identifier;
344887
345578
  if (tcIdentifier != null)
344888
345579
  nextParts.push(`\\f "${tcIdentifier}"`);
344889
- const tcLevels = patch.tcFieldLevels ?? parseNumericSwitchRange(instruction, "l");
345580
+ else if (tcSelection.hasFieldSwitch)
345581
+ nextParts.push("\\f");
345582
+ const tcLevels = patch.tcFieldLevels ?? tcSelection.levels;
344890
345583
  if (tcLevels)
344891
345584
  nextParts.push(`\\l "${tcLevels.from}-${tcLevels.to}"`);
345585
+ else if (tcSelection.hasLevelSwitch) {
345586
+ nextParts.push(tcSelection.levelArgument == null ? "\\l" : `\\l "${tcSelection.levelArgument}"`);
345587
+ }
344892
345588
  return [...nextParts, ...readPreservedTocSwitchFragments(instruction)].join(" ");
344893
345589
  }
344894
345590
  function serializeTocEntryInstruction(text4, level, tableIdentifier, omitPageNumber) {
@@ -344986,9 +345682,19 @@ function parseTocCustomStyles2(value2) {
344986
345682
  function normalizeStyleId2(value2) {
344987
345683
  return value2.replace(/\s+/g, "").trim().toLowerCase();
344988
345684
  }
344989
- function seedMissingTocBookmarks(context, instruction) {
345685
+ function seedMissingTocBookmarks(context, instruction, field) {
344990
345686
  const insertions = planMissingTocBookmarks(context, instruction);
344991
345687
  if (insertions.length > 0) {
345688
+ const paragraphs = new Map(readBodyParagraphs(context, { includeListState: false }).map((paragraph4) => [paragraph4.blockId, paragraph4]));
345689
+ const names = new Map;
345690
+ for (const bookmark of insertions) {
345691
+ names.set(bookmark.fieldSource?.key ?? `${paragraphs.get(bookmark.blockId).storyId}:${bookmark.blockId}`, bookmark.name);
345692
+ for (const key2 of bookmark.fieldSourceKeys ?? [])
345693
+ names.set(key2, bookmark.name);
345694
+ }
345695
+ const prepared = prepareTocReplacement(context, field, instruction, names);
345696
+ if (!prepared.ok)
345697
+ return prepared;
344992
345698
  const committed = insertBookmarksIntoParagraphs(context, insertions, "toc-bookmark-seed");
344993
345699
  if (!committed.ok)
344994
345700
  return committed;
@@ -344998,44 +345704,91 @@ function seedMissingTocBookmarks(context, instruction) {
344998
345704
  function planMissingTocBookmarks(context, instruction) {
344999
345705
  if (usesV1EmptyTocSourceSet(instruction))
345000
345706
  return [];
345001
- const existing = new Map;
345002
- const existingNames = new Set;
345003
- for (const bookmark of readBookmarkEntries(context)) {
345004
- existingNames.add(bookmark.name);
345005
- if (!bookmark.name.startsWith("_Toc"))
345006
- continue;
345007
- const key2 = `${bookmark.storyId}:${bookmark.blockId}`;
345008
- if (!existing.has(key2))
345009
- existing.set(key2, bookmark.name);
345010
- }
345707
+ const bookmarks = readBookmarkEntries(context);
345708
+ const existingNames = new Set(bookmarks.map((bookmark) => bookmark.name));
345709
+ const existingParagraphs = new Set(bookmarks.filter((bookmark) => bookmark.name.startsWith("_Toc")).map((bookmark) => `${bookmark.storyId}:${bookmark.blockId}`));
345710
+ const paragraphs = readBodyParagraphs(context, { includeListState: false });
345711
+ const bodyKeys = new Set(paragraphs.map((paragraph4) => `${paragraph4.storyId}:${paragraph4.blockId}`));
345712
+ const canonicalFields = listCanonicalFieldEntries(context);
345713
+ const tcFields = canonicalFields.filter((field) => instructionKeyword(field.descriptor.instructionText) === "TC" && bodyKeys.has(`${field.storyId}:${field.blockId}`));
345714
+ const incompleteFields = canonicalFields.filter((field) => !field.descriptor.complete);
345715
+ const tcBookmarkNames = resolveTocTcBookmarkNames(bookmarks, paragraphs, tcFields);
345011
345716
  let nextOrdinal = nextTocBookmarkOrdinal(existingNames);
345012
345717
  const insertions = [];
345013
- for (const paragraph4 of listIncludedTocParagraphs(context, instruction)) {
345014
- const key2 = `${paragraph4.storyId}:${paragraph4.blockId}`;
345015
- if (existing.has(key2))
345016
- continue;
345017
- let name = buildTocBookmarkName(nextOrdinal);
345018
- while (existingNames.has(name)) {
345019
- nextOrdinal += 1;
345020
- name = buildTocBookmarkName(nextOrdinal);
345021
- }
345022
- insertions.push({ blockId: paragraph4.blockId, name });
345023
- existing.set(key2, name);
345718
+ const genericByParagraph = new Map;
345719
+ const paragraphsByKey = new Map(paragraphs.map((paragraph4) => [`${paragraph4.storyId}:${paragraph4.blockId}`, paragraph4]));
345720
+ const allocateName = () => {
345721
+ let name = buildTocBookmarkName(nextOrdinal++);
345722
+ while (existingNames.has(name))
345723
+ name = buildTocBookmarkName(nextOrdinal++);
345024
345724
  existingNames.add(name);
345025
- nextOrdinal += 1;
345026
- }
345027
- return insertions;
345028
- }
345029
- function listIncludedTocParagraphs(context, instruction) {
345725
+ return name;
345726
+ };
345030
345727
  const customStyles = parseTocCustomStyles2(parseQuotedSwitch(instruction, "t") ?? "");
345031
345728
  const explicitOutlineRange = parseNumericSwitchRange(instruction, "o");
345032
345729
  const outlineRange = explicitOutlineRange ?? { from: 1, to: 3 };
345033
345730
  const includeOutlineEntries = customStyles.length === 0 || explicitOutlineRange != null;
345034
- return readBodyParagraphs(context, { includeListState: false }).filter((paragraph4) => {
345731
+ for (const paragraph4 of paragraphs) {
345035
345732
  const matchesCustomStyle = paragraph4.styleId != null && customStyles.some((entry) => normalizeStyleId2(entry.styleName) === normalizeStyleId2(paragraph4.styleId ?? ""));
345036
345733
  const matchesOutline = includeOutlineEntries && paragraph4.headingLevel >= outlineRange.from && paragraph4.headingLevel <= outlineRange.to;
345037
- return matchesCustomStyle || matchesOutline;
345038
- });
345734
+ if ((matchesCustomStyle || matchesOutline) && !existingParagraphs.has(`${paragraph4.storyId}:${paragraph4.blockId}`)) {
345735
+ const insertion = { blockId: paragraph4.blockId, name: allocateName() };
345736
+ insertions.push(insertion);
345737
+ genericByParagraph.set(`${paragraph4.storyId}:${paragraph4.blockId}`, insertion);
345738
+ }
345739
+ }
345740
+ const selection = parseTocTcSourceSelection(instruction);
345741
+ const missingFields = tcFields.filter((field) => matchesTocTcSourceSelection(selection, parseTocEntryInstruction(field.descriptor.instructionText)) && !tcBookmarkNames.has(tocTcFieldSourceKey(field))).map((field) => {
345742
+ const key2 = tocTcFieldSourceKey(field);
345743
+ const fieldSource = { key: key2, byteStart: field.descriptor.byteStart, byteEnd: field.descriptor.byteEnd };
345744
+ const paragraphKey = `${field.storyId}:${field.blockId}`;
345745
+ const paragraph4 = paragraphsByKey.get(paragraphKey);
345746
+ const bytes = readPartBytes2(context, field.partUri);
345747
+ const validCanonicalField = Boolean(field.descriptor.complete && Number.isInteger(fieldSource.byteStart) && Number.isInteger(fieldSource.byteEnd) && fieldSource.byteStart >= paragraph4.byteStart && fieldSource.byteEnd > fieldSource.byteStart && bytes && fieldSource.byteEnd <= bytes.length);
345748
+ return { field, key: key2, fieldSource, paragraphKey, paragraph: paragraph4, validCanonicalField };
345749
+ });
345750
+ const fieldsByParagraph = new Map;
345751
+ for (const source of missingFields) {
345752
+ const group = fieldsByParagraph.get(source.paragraphKey) ?? [];
345753
+ group.push(source);
345754
+ fieldsByParagraph.set(source.paragraphKey, group);
345755
+ }
345756
+ const collidingKeys = new Set;
345757
+ for (const group of fieldsByParagraph.values()) {
345758
+ group.sort((left, right) => left.fieldSource.byteStart - right.fieldSource.byteStart);
345759
+ let component = [];
345760
+ let componentEnd = -1;
345761
+ const finishComponent = () => {
345762
+ if (component.length > 1 && component.every((source) => source.validCanonicalField) && !incompleteFields.some((field) => field.storyId === component[0].field.storyId && field.blockId === component[0].field.blockId && field.descriptor.byteStart >= component[0].fieldSource.byteStart && field.descriptor.byteStart < componentEnd)) {
345763
+ for (const source of component)
345764
+ collidingKeys.add(source.key);
345765
+ }
345766
+ };
345767
+ for (const source of group) {
345768
+ if (source.fieldSource.byteStart >= componentEnd) {
345769
+ finishComponent();
345770
+ component = [];
345771
+ componentEnd = -1;
345772
+ }
345773
+ component.push(source);
345774
+ componentEnd = Math.max(componentEnd, source.fieldSource.byteEnd);
345775
+ }
345776
+ finishComponent();
345777
+ }
345778
+ for (const { field, key: key2, fieldSource, paragraphKey, paragraph: paragraph4, validCanonicalField } of missingFields) {
345779
+ if (validCanonicalField && (collidingKeys.has(key2) || !canPlaceBookmarkAtFieldSource(paragraph4, fieldSource))) {
345780
+ let generic = genericByParagraph.get(paragraphKey);
345781
+ if (!generic) {
345782
+ generic = { blockId: field.blockId, name: allocateName() };
345783
+ genericByParagraph.set(paragraphKey, generic);
345784
+ insertions.push(generic);
345785
+ }
345786
+ (generic.fieldSourceKeys ?? (generic.fieldSourceKeys = [])).push(key2);
345787
+ } else {
345788
+ insertions.push({ blockId: field.blockId, name: allocateName(), fieldSource });
345789
+ }
345790
+ }
345791
+ return insertions;
345039
345792
  }
345040
345793
  function nextTocBookmarkOrdinal(existingNames) {
345041
345794
  let largest = 0;
@@ -345134,14 +345887,17 @@ function insertTrackedToc(context, input) {
345134
345887
  }));
345135
345888
  if (missing2.some((bookmark) => !bookmark.paragraph))
345136
345889
  return unavailable4("A TOC heading target is unavailable.");
345137
- const names = new Map(missing2.map((bookmark) => [
345138
- `${bookmark.paragraph.storyId}:${bookmark.blockId}`,
345139
- bookmark.name
345140
- ]));
345890
+ const names = new Map;
345891
+ for (const bookmark of missing2) {
345892
+ names.set(bookmark.fieldSource?.key ?? `${bookmark.paragraph.storyId}:${bookmark.blockId}`, bookmark.name);
345893
+ for (const key2 of bookmark.fieldSourceKeys ?? [])
345894
+ names.set(key2, bookmark.name);
345895
+ }
345141
345896
  let tocXml = buildTocFieldXml(context, input.instruction, {
345142
345897
  bare: true,
345143
345898
  tocBookmarkNames: names,
345144
- reservedParaIds: occupied
345899
+ reservedParaIds: occupied,
345900
+ insertionByteStart: insertByte
345145
345901
  });
345146
345902
  tocXml = tocXml.replace(/<w:p\b[^>]*>/g, (open2) => /\sxmlns:w14\s*=/.test(open2) ? open2 : open2.replace("<w:p", '<w:p xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"'));
345147
345903
  const tocRanges = collectXmlElementRanges(tocXml, {
@@ -345153,17 +345909,8 @@ function insertTrackedToc(context, input) {
345153
345909
  const tocParagraphs = tocRanges.ranges.filter((range) => range.tag.namespaceUri === bindings.get("w") && range.tag.localName === "p");
345154
345910
  if (!tocParagraphs.length)
345155
345911
  return unavailable4("The generated TOC has no paragraphs.");
345156
- const coordinated = context.isCollaborativeSession() && !input.dryRun ? context.allocateCollaborativeStoryParaIds({
345157
- count: tocParagraphs.length,
345158
- inUse: [...occupied]
345159
- }) : null;
345160
- if (context.isCollaborativeSession() && !input.dryRun && (coordinated?.length !== tocParagraphs.length || new Set(coordinated.map((id) => id.toUpperCase())).size !== coordinated.length || coordinated.some((id) => !/^[0-9a-f]{8}$/i.test(id) || occupied.has(id.toUpperCase())))) {
345161
- return unavailable4("TOC insertion could not reserve its complete paragraph identity batch.");
345162
- }
345163
345912
  let nextParagraphId = 184549376;
345164
- const paragraphIds = tocParagraphs.map((_paragraph, index2) => {
345165
- if (coordinated)
345166
- return coordinated[index2];
345913
+ const paragraphIds = tocParagraphs.map(() => {
345167
345914
  let id;
345168
345915
  do {
345169
345916
  id = (++nextParagraphId).toString(16).toUpperCase().padStart(8, "0");
@@ -345188,6 +345935,12 @@ function insertTrackedToc(context, input) {
345188
345935
  const preview = prepareTrackedTocInsertion({ xml: tocXml, namespaceBindings: bindings, stamp });
345189
345936
  if (!preview)
345190
345937
  return unavailable4("The generated TOC content cannot be represented by supported run revisions.");
345938
+ if (context.isCollaborativeSession() && !input.dryRun)
345939
+ return {
345940
+ ok: false,
345941
+ code: "INVALID_CONTEXT",
345942
+ message: "create-table-of-contents-tracked: unsupported-context"
345943
+ };
345191
345944
  const ids = reserveTrackedReferenceRevisionIds(context, preview.wordIds.length + missing2.length * 2, input.dryRun);
345192
345945
  if (!ids)
345193
345946
  return unavailable4("TOC insertion could not reserve its complete revision identity batch.");
@@ -345204,24 +345957,29 @@ function insertTrackedToc(context, input) {
345204
345957
  const storyIds = new Set([input.storyId]);
345205
345958
  let idIndex = preview.wordIds.length;
345206
345959
  let bookmarkId = nextBookmarkNumericId(context);
345960
+ const bookmarkMarkers = [];
345207
345961
  for (const bookmark of missing2) {
345208
345962
  const paragraph4 = bookmark.paragraph;
345209
- const startXml = `<w:bookmarkStart w:id="${bookmarkId}" w:name="${xmlEscapeAttr(bookmark.name)}"/>`;
345210
- const endXml = `<w:bookmarkEnd w:id="${bookmarkId++}"/>`;
345963
+ const markerBindings = readBookmarkInsertionNamespaceBindings(paragraph4, bookmark);
345964
+ if (!markerBindings)
345965
+ return unavailable4("TOC bookmark namespace context is unavailable.");
345966
+ const { startXml, endXml } = buildParagraphBookmarkMarkers(paragraph4, bookmark, bookmarkId++);
345211
345967
  const markers = [startXml, endXml].map((xml) => prepareTrackedInlineXmlReplacement({
345212
345968
  beforeXml: "",
345213
345969
  afterXml: xml,
345214
- namespaceBindings: new Map(Object.entries(paragraph4.namespaceBindings ?? {})),
345970
+ namespaceBindings: markerBindings,
345215
345971
  stamp: { ...stamp, revisionId: ids[idIndex], revisionIds: [ids[idIndex++]] }
345216
345972
  }));
345217
345973
  if (!markers[0] || !markers[1])
345218
345974
  return unavailable4("TOC bookmark markers cannot be revision marked.");
345219
- const withStart = injectParagraphPrefix(paragraph4.rawXml, markers[0].xml);
345220
- const withEnd = withStart && injectParagraphSuffix(withStart, markers[1].xml);
345221
- if (!withEnd)
345222
- return unavailable4("TOC bookmark markers could not be placed.");
345975
+ bookmarkMarkers.push({ ...bookmark, startXml: markers[0].xml, endXml: markers[1].xml });
345976
+ }
345977
+ const grouped = prepareBookmarkParagraphGroups(paragraphs, bookmarkMarkers);
345978
+ if (!grouped)
345979
+ return unavailable4("TOC bookmark markers could not be placed.");
345980
+ for (const { paragraph: paragraph4, xml } of grouped) {
345223
345981
  const perPart2 = edits.get(paragraph4.partUri) ?? [];
345224
- perPart2.push({ start: paragraph4.byteStart, end: paragraph4.byteEnd, bytes: encodeXml(withEnd) });
345982
+ perPart2.push({ start: paragraph4.byteStart, end: paragraph4.byteEnd, bytes: encodeXml(xml) });
345225
345983
  edits.set(paragraph4.partUri, perPart2);
345226
345984
  storyIds.add(paragraph4.storyId);
345227
345985
  }
@@ -346189,10 +346947,14 @@ class V2CreateAdapter {
346189
346947
  return { success: true, section, ...trackedChangeRefs.length ? { trackedChangeRefs } : {} };
346190
346948
  }
346191
346949
  tableOfContents(input, options) {
346950
+ const guard = beginCanonicalMutation(this.context, options, "create.tableOfContents");
346951
+ if (guard)
346952
+ return createFailure(guard.code, guard.message);
346953
+ const instruction = buildEffectiveTocInstruction(input.instruction, input.config);
346954
+ const locked = guardTocBookmarkInsertion(this.context, instruction, "create.tableOfContents");
346955
+ if (locked)
346956
+ return createFailure(locked.code, locked.message);
346192
346957
  if (options?.changeMode === "tracked") {
346193
- const guard = beginCanonicalMutation(this.context, options, "create.tableOfContents");
346194
- if (guard)
346195
- return createFailure(guard.code, guard.message);
346196
346958
  const paragraphInput = { at: input.at, text: "" };
346197
346959
  const story = resolveStoryTarget(this.context, effectiveStoryLocator(paragraphInput));
346198
346960
  if ("failure" in story)
@@ -346212,7 +346974,7 @@ class V2CreateAdapter {
346212
346974
  ...site,
346213
346975
  storyId: anchor.storyId,
346214
346976
  documentBoundary: input.at?.kind === "documentStart" || input.at?.kind === "documentEnd" ? input.at.kind : undefined,
346215
- instruction: buildEffectiveTocInstruction(input.instruction, input.config),
346977
+ instruction,
346216
346978
  dryRun: options.dryRun
346217
346979
  });
346218
346980
  if (!inserted.ok)
@@ -346225,6 +346987,8 @@ class V2CreateAdapter {
346225
346987
  toc: { kind: "block", nodeType: "tableOfContents", nodeId: "(dry-run)" }
346226
346988
  };
346227
346989
  }
346990
+ if (this.context.isCollaborativeSession())
346991
+ return createFailure("INVALID_CONTEXT", "create-table-of-contents: unsupported-context");
346228
346992
  const created = this.paragraph({ at: input.at, text: "" }, options);
346229
346993
  if (!created.success) {
346230
346994
  return {
@@ -346233,7 +346997,6 @@ class V2CreateAdapter {
346233
346997
  };
346234
346998
  }
346235
346999
  const nodeId = created.paragraph.nodeId;
346236
- const instruction = buildEffectiveTocInstruction(input.instruction, input.config);
346237
347000
  const committed = prependTocFieldToGeneratedParagraph(this.context, nodeId, instruction, "create-table-of-contents", undefined, input.at?.kind === "documentStart" || input.at?.kind === "documentEnd" ? input.at.kind : undefined);
346238
347001
  if (!committed.ok)
346239
347002
  return createFailure(committed.code, committed.message);
@@ -346964,107 +347727,6 @@ var init_adapter14 = __esm(() => {
346964
347727
  VALUED_TOC_SWITCHES = new Set(["\\o", "\\n", "\\p", "\\f", "\\l"]);
346965
347728
  });
346966
347729
 
346967
- // ../../../v2/document-api-v2-adapter/dist/formatting/paragraph-property-order.js
346968
- function setParagraphPropertyChild(children2, localName2, xml) {
346969
- const parsed = parseSingleElement(xml);
346970
- const existingIndex = children2.findIndex((child) => child.localName === localName2);
346971
- if (existingIndex >= 0) {
346972
- const next = [...children2];
346973
- next[existingIndex] = parsed;
346974
- return next;
346975
- }
346976
- const targetRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(localName2);
346977
- if (targetRank == null)
346978
- throw new Error(`Unknown paragraph property child: ${localName2}`);
346979
- let insertionIndex = 0;
346980
- for (const [index2, child] of children2.entries()) {
346981
- const childRank = paragraphPropertyRankRange(child);
346982
- if (!childRank)
346983
- continue;
346984
- if (childRank.minimum > targetRank) {
346985
- return [...children2.slice(0, index2), parsed, ...children2.slice(index2)];
346986
- }
346987
- if (childRank.maximum >= targetRank) {
346988
- throw new ParagraphPropertyMutationUnavailableError(`Cannot safely insert w:${localName2} within mc:AlternateContent paragraph properties`);
346989
- }
346990
- insertionIndex = index2 + 1;
346991
- }
346992
- return [...children2.slice(0, insertionIndex), parsed, ...children2.slice(insertionIndex)];
346993
- }
346994
- function paragraphPropertyRankRange(child) {
346995
- const directRank = PARAGRAPH_PROPERTY_CHILD_RANK.get(child.localName);
346996
- if (directRank != null)
346997
- return { minimum: directRank, maximum: directRank };
346998
- if (child.localName !== "AlternateContent")
346999
- return null;
347000
- const alternateContent = parseContainerXml(child.xml, "AlternateContent");
347001
- if (!alternateContent)
347002
- return null;
347003
- const ranks = parseTopLevelChildren(alternateContent.inner).flatMap((branch) => {
347004
- if (branch.localName !== "Choice" && branch.localName !== "Fallback")
347005
- return [];
347006
- const branchContainer = parseContainerXml(branch.xml, branch.localName);
347007
- if (!branchContainer)
347008
- return [];
347009
- return parseTopLevelChildren(branchContainer.inner).flatMap((candidate2) => {
347010
- const range = paragraphPropertyRankRange(candidate2);
347011
- return range ? [range.minimum, range.maximum] : [];
347012
- });
347013
- });
347014
- if (ranks.length === 0)
347015
- return null;
347016
- return { minimum: Math.min(...ranks), maximum: Math.max(...ranks) };
347017
- }
347018
- var PARAGRAPH_PROPERTY_CHILD_ORDER, PARAGRAPH_PROPERTY_CHILD_RANK, ParagraphPropertyMutationUnavailableError;
347019
- var init_paragraph_property_order = __esm(() => {
347020
- init_common();
347021
- PARAGRAPH_PROPERTY_CHILD_ORDER = [
347022
- "pStyle",
347023
- "keepNext",
347024
- "keepLines",
347025
- "pageBreakBefore",
347026
- "framePr",
347027
- "widowControl",
347028
- "numPr",
347029
- "suppressLineNumbers",
347030
- "pBdr",
347031
- "shd",
347032
- "tabs",
347033
- "suppressAutoHyphens",
347034
- "kinsoku",
347035
- "wordWrap",
347036
- "overflowPunct",
347037
- "topLinePunct",
347038
- "autoSpaceDE",
347039
- "autoSpaceDN",
347040
- "bidi",
347041
- "adjustRightInd",
347042
- "snapToGrid",
347043
- "spacing",
347044
- "ind",
347045
- "contextualSpacing",
347046
- "mirrorIndents",
347047
- "suppressOverlap",
347048
- "jc",
347049
- "textDirection",
347050
- "textAlignment",
347051
- "textboxTightWrap",
347052
- "outlineLvl",
347053
- "divId",
347054
- "cnfStyle",
347055
- "rPr",
347056
- "sectPr",
347057
- "pPrChange"
347058
- ];
347059
- PARAGRAPH_PROPERTY_CHILD_RANK = new Map(PARAGRAPH_PROPERTY_CHILD_ORDER.map((name, index2) => [name, index2]));
347060
- ParagraphPropertyMutationUnavailableError = class ParagraphPropertyMutationUnavailableError extends Error {
347061
- constructor(message) {
347062
- super(message);
347063
- this.name = "ParagraphPropertyMutationUnavailableError";
347064
- }
347065
- };
347066
- });
347067
-
347068
347730
  // ../../../v2/document-api-v2-adapter/dist/formatting/paragraph.js
347069
347731
  function classifyParagraphNodeType(input) {
347070
347732
  if (input.headingLevel > 0)