@superdoc/mcp 1.4.0-next.7 → 1.4.0-next.9

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 +877 -244
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31330,10 +31330,10 @@ var init_host = __esm(() => {
31330
31330
  });
31331
31331
 
31332
31332
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31333
- var SDK_VERSION = "2.17.0-next.7";
31333
+ var SDK_VERSION = "2.17.0-next.9";
31334
31334
 
31335
31335
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31336
- import { chmodSync, existsSync } from "node:fs";
31336
+ import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
31337
31337
  import { createRequire as createRequire2 } from "node:module";
31338
31338
  import path from "node:path";
31339
31339
  import { fileURLToPath } from "node:url";
@@ -31387,7 +31387,15 @@ function ensureEmbeddedExecutable(binaryPath) {
31387
31387
  if (process.platform === "win32")
31388
31388
  return;
31389
31389
  try {
31390
- chmodSync(binaryPath, 493);
31390
+ accessSync(binaryPath, constants.X_OK);
31391
+ return;
31392
+ } catch {}
31393
+ let mode = 493;
31394
+ try {
31395
+ mode = statSync(binaryPath).mode & 4095 | 73;
31396
+ } catch {}
31397
+ try {
31398
+ chmodSync(binaryPath, mode);
31391
31399
  } catch {}
31392
31400
  }
31393
31401
  var require2, TARGET_TO_PACKAGE, TARGET_TO_DIR;
@@ -135271,7 +135279,28 @@ function control(xml, element) {
135271
135279
  const locks = children.filter((child) => is(child, "lock"));
135272
135280
  const deletable = locks.every((lock) => attr(lock, "val") === "unlocked" || attr(lock, "val") === "contentLocked");
135273
135281
  const supportedProperties = children.every((child) => child.tag.uri === W3 ? ["id", "tag", "alias", "text", "richText", "lock", "rPr", "placeholder", "showingPlcHdr", "temporary"].includes(child.tag.local) : child.tag.uri === "http://schemas.microsoft.com/office/word/2012/wordml" && child.tag.local === "appearance");
135274
- return { id, key: `sdt:${attr(key2, "val")}`, xml: fragment2(xml, element), deletable: deletable && supportedProperties };
135282
+ const contentXml = xml.slice(content[0].start, content[0].end);
135283
+ const contentOpenEnd = contentXml.indexOf(">") + 1;
135284
+ const contentCloseStart = contentXml.lastIndexOf("</");
135285
+ const contentRuns = contentCloseStart < contentOpenEnd ? "" : contentXml.slice(contentOpenEnd, contentCloseStart);
135286
+ const offset = content[0].start - element.start;
135287
+ const itemXml = fragment2(xml, element);
135288
+ const head = itemXml.slice(0, offset + contentOpenEnd);
135289
+ const tail = itemXml.slice(offset + Math.max(contentOpenEnd, contentCloseStart));
135290
+ const unlocked = locks.every((lock) => attr(lock, "val") === "unlocked");
135291
+ const editable = locks.every((lock) => attr(lock, "val") === "unlocked" || attr(lock, "val") === "sdtLocked");
135292
+ return {
135293
+ id,
135294
+ key: `sdt:${attr(key2, "val")}`,
135295
+ xml: itemXml,
135296
+ contentXml: contentRuns,
135297
+ head,
135298
+ tail,
135299
+ deletable: deletable && supportedProperties,
135300
+ insertable: unlocked && supportedProperties,
135301
+ editable: editable && supportedProperties,
135302
+ supportedProperties
135303
+ };
135275
135304
  }
135276
135305
  function inspectInlineControlRemoval(beforeXml, afterXml, namespaces = {}) {
135277
135306
  const before = elements(beforeXml, namespaces);
@@ -135358,6 +135387,137 @@ function bodyOperationsCoverInlineControlRemoval(base2, target, operations, matc
135358
135387
  }
135359
135388
  return removed.size === changes.length && changes.every((entry) => entry.baseId !== null && removed.has(entry.baseId));
135360
135389
  }
135390
+ function inspectInlineControlReplay(beforeXml, afterXml, namespaces = {}) {
135391
+ const before = elements(beforeXml, namespaces);
135392
+ const after = elements(afterXml, namespaces);
135393
+ if (!before || !after)
135394
+ return null;
135395
+ const xmlns = "http://www.w3.org/2000/xmlns/";
135396
+ const attributes = (root, allowed) => Object.values(root.tag.attributes).every((attribute) => attribute.uri === xmlns || allowed(attribute.uri, attribute.local));
135397
+ const runProperties = (root) => is(root, "rPr") && attributes(root, () => false) && root.children.every((child) => child.tag.uri === W3 && RUN_PROPERTIES.has(child.tag.local) && !child.children.length && attributes(child, (uri) => uri === W3));
135398
+ const simpleRun = (root) => safeRun(root) && attributes(root, (uri, local) => uri === W3 && ["rsidR", "rsidRPr", "rsidDel"].includes(local)) && root.children.filter((child) => is(child, "t")).length === 1 && root.children.every((child) => runProperties(child) || is(child, "t") && !child.tag.isSelfClosing && attributes(child, (uri, local) => uri === "http://www.w3.org/XML/1998/namespace" && local === "space"));
135399
+ const safeControlProperties = (root) => {
135400
+ if (!attributes(root, (uri, local) => uri === W3 && ["rsidR", "rsidRPr", "rsidDel"].includes(local)))
135401
+ return false;
135402
+ const properties = root.children.find((child) => is(child, "sdtPr"));
135403
+ const content = root.children.find((child) => is(child, "sdtContent"));
135404
+ if (!attributes(properties, () => false) || !attributes(content, () => false) || content.tag.isSelfClosing)
135405
+ return false;
135406
+ if (properties.children.filter((child) => is(child, "text") || is(child, "richText")).length > 1)
135407
+ return false;
135408
+ const seen = new Set;
135409
+ for (const child of properties.children) {
135410
+ if (seen.has(child.tag.name))
135411
+ return false;
135412
+ seen.add(child.tag.name);
135413
+ if (!attributes(child, (uri) => uri === W3 || uri === child.tag.uri))
135414
+ return false;
135415
+ if (is(child, "rPr")) {
135416
+ if (!runProperties(child))
135417
+ return false;
135418
+ } else if (is(child, "placeholder")) {
135419
+ if (child.children.some((item) => !is(item, "docPart") || item.children.length || !attributes(item, (uri) => uri === W3)))
135420
+ return false;
135421
+ } else if (child.children.length)
135422
+ return false;
135423
+ }
135424
+ return root.children.filter((child) => is(child, "sdtEndPr")).every((child) => attributes(child, () => false) && child.children.every(runProperties));
135425
+ };
135426
+ const inspect = (xml, roots) => {
135427
+ const result = [];
135428
+ for (const [index, root] of roots.entries()) {
135429
+ if (simpleRun(root))
135430
+ continue;
135431
+ const item = control(xml, root);
135432
+ if (!item || !item.supportedProperties || !safeControlProperties(root) || !root.children.find((child) => is(child, "sdtContent"))?.children.every(simpleRun) || result.some((other) => other.id === item.id || other.key === item.key))
135433
+ return null;
135434
+ result.push({ ...item, index });
135435
+ }
135436
+ return result;
135437
+ };
135438
+ const previous = inspect(beforeXml, before);
135439
+ const next = inspect(afterXml, after);
135440
+ if (!previous || !next || !previous.length && !next.length)
135441
+ return null;
135442
+ const normalized = (xml) => signature(`<scope ${Object.entries(namespaces).filter(([prefix]) => prefix && prefix !== "xml").map(([prefix, uri]) => `xmlns:${prefix}=${JSON.stringify(uri)}`).join(" ")}>${xml}</scope>`);
135443
+ const anchors = [];
135444
+ for (const old of previous) {
135445
+ const current = next.find((item) => item.id === old.id);
135446
+ if (!current || old.key !== current.key || normalized(old.head + old.tail) !== normalized(current.head + current.tail))
135447
+ return null;
135448
+ const changed = normalized(old.xml) !== normalized(current.xml);
135449
+ if (changed && !old.editable)
135450
+ return null;
135451
+ anchors.push({ beforeIndex: old.index, afterIndex: current.index, before: old, after: current, changed });
135452
+ }
135453
+ if (anchors.some((anchor, index) => index > 0 && anchor.afterIndex <= anchors[index - 1].afterIndex))
135454
+ return null;
135455
+ const inserted = next.filter((item) => !previous.some((old) => old.id === item.id));
135456
+ if (inserted.some((item) => !item.insertable))
135457
+ return null;
135458
+ return {
135459
+ anchors,
135460
+ inserted,
135461
+ updated: anchors.filter((anchor) => anchor.changed),
135462
+ beforeRoots: before.map((root) => fragment2(beforeXml, root)),
135463
+ afterRoots: after.map((root) => fragment2(afterXml, root))
135464
+ };
135465
+ }
135466
+ function bodyOperationsCoverInlineControlReplay(base2, target, operations, match) {
135467
+ const family = match.families.find((item) => item.family === "content-controls");
135468
+ const changes = family?.entityMatch?.entries.filter((entry) => entry.disposition !== "matched" || entry.changed || entry.moved);
135469
+ if (!changes?.length || family?.hasAmbiguity || changes.some((entry) => entry.disposition !== "inserted" && entry.disposition !== "matched" || entry.moved))
135470
+ return false;
135471
+ const counts = (snapshot2) => {
135472
+ const result = new Map;
135473
+ const visit = (root) => {
135474
+ if (is(root, "sdtPr"))
135475
+ for (const child of root.children.filter((item) => is(item, "id"))) {
135476
+ const id = numericIdentity(attr(child, "val"));
135477
+ if (id !== null)
135478
+ result.set(id, (result.get(id) ?? 0) + 1);
135479
+ }
135480
+ root.children.forEach(visit);
135481
+ };
135482
+ for (const entry of [...snapshot2.body, ...(snapshot2.stories ?? []).flatMap((story) => story.entries)]) {
135483
+ const roots = elements(entry.runXml ?? "", {}, true);
135484
+ if (!roots)
135485
+ return null;
135486
+ roots.forEach(visit);
135487
+ }
135488
+ return result;
135489
+ };
135490
+ const oldCounts = counts(base2), newCounts = counts(target);
135491
+ if (!oldCounts || !newCounts)
135492
+ return false;
135493
+ const covered = new Map;
135494
+ for (const operation of operations) {
135495
+ if (operation.kind !== "edit" && operation.kind !== "formatEdit")
135496
+ continue;
135497
+ const previous = base2.body.filter((entry) => entry.blockId === operation.blockId);
135498
+ const next = target.body.filter((entry) => entry.blockId === operation.blockId);
135499
+ if (previous.length !== 1 || next.length !== 1)
135500
+ continue;
135501
+ const before = previous[0], after = next[0];
135502
+ const proof = inspectInlineControlReplay(before.runXml ?? "", after.runXml ?? "");
135503
+ if (!proof)
135504
+ continue;
135505
+ if (!/^[0-9A-Fa-f]{8}$/.test(before.blockId) || (before.structuralScope ?? "body") !== "body" || (after.structuralScope ?? "body") !== "body" || before.trackedChangeAnnotationKeys?.length || before.structuralChangeAnnotationKeys?.length || after.trackedChangeAnnotationKeys?.length || after.structuralChangeAnnotationKeys?.length || operation.targetRunXml !== after.runXml)
135506
+ return false;
135507
+ for (const item of proof.inserted) {
135508
+ if (covered.has(item.key) || oldCounts.has(item.id) || newCounts.get(item.id) !== 1)
135509
+ return false;
135510
+ covered.set(item.key, "inserted");
135511
+ }
135512
+ for (const anchor of proof.updated) {
135513
+ const item = anchor.after;
135514
+ if (covered.has(item.key) || oldCounts.get(item.id) !== 1 || newCounts.get(item.id) !== 1)
135515
+ return false;
135516
+ covered.set(item.key, "matched");
135517
+ }
135518
+ }
135519
+ return covered.size === changes.length && changes.every((entry) => entry.targetId !== null && covered.get(entry.targetId) === entry.disposition);
135520
+ }
135361
135521
  var import_saxes3, W3 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", attr = (element, name) => Object.values(element.tag.attributes).find((attribute) => attribute.uri === W3 && attribute.local === name)?.value, is = (element, name) => element.tag.uri === W3 && element.tag.local === name, fragment2 = (xml, element) => xml.slice(element.start, element.end), signature = (xml) => canonicalizeXmlForSignature(xml), RUN_PROPERTIES;
135362
135522
  var init_inline_control_removal = __esm(() => {
135363
135523
  init_run_signature();
@@ -136233,7 +136393,7 @@ function parseXmlStartTag(rawTag) {
136233
136393
  return null;
136234
136394
  }
136235
136395
  function validateRunContents(xml, options) {
136236
- if (options.baseRunXml !== undefined && inspectInlineControlRemoval(options.baseRunXml, xml)) {
136396
+ if (options.baseRunXml !== undefined && (inspectInlineControlRemoval(options.baseRunXml, xml) || inspectInlineControlReplay(options.baseRunXml, xml))) {
136237
136397
  return { ok: true };
136238
136398
  }
136239
136399
  const baseHasNoteMarker = options.baseRunXml !== undefined && /<(?:[A-Za-z_][\w.-]*:)?(?:footnoteRef|endnoteRef)\b/.test(options.baseRunXml);
@@ -140064,7 +140224,7 @@ function planCompare(base2, target) {
140064
140224
  const trackedRevisionSetChanged = semanticAnalysis.familyDeltas.find((delta) => delta.family === "tracked-changes")?.detectedChange === true;
140065
140225
  const revisionReplay = deriveCompareBodyOperationsWithRevisionReplay(base2, target, matchResult);
140066
140226
  const bodyOperations = revisionReplay.operations;
140067
- if (bodyOperationsCoverInlineControlRemoval(base2, target, bodyOperations, matchResult)) {
140227
+ if (bodyOperationsCoverInlineControlRemoval(base2, target, bodyOperations, matchResult) || bodyOperationsCoverInlineControlReplay(base2, target, bodyOperations, matchResult)) {
140068
140228
  semanticAnalysis = markFamilySupported(semanticAnalysis, "content-controls");
140069
140229
  }
140070
140230
  const computedStoryOperations = buildStoryOperations(base2, target, semanticAnalysis);
@@ -164385,6 +164545,9 @@ function planDirectInlineEdit(paragraphBytes, startOffset, endOffset, newText, c
164385
164545
  ...enclosingSdts.length > 0 ? { requiresCollaborationSessionSync: true } : {}
164386
164546
  };
164387
164547
  }
164548
+ const sdtProtection = validateSelectedSdtProtection(model.pieces, startOffset, endOffset);
164549
+ if (sdtProtection)
164550
+ return { ok: false, reason: sdtProtection };
164388
164551
  const tocPlan = planTocEntryEdit(paragraphBytes, xml, model, leaves, startOffset, endOffset, newText, inlineContext, authoredTocEntry);
164389
164552
  if (tocPlan)
164390
164553
  return tocPlan;
@@ -164437,7 +164600,13 @@ function planDirectInlineEdits(paragraphBytes, edits, inheritedNamespaceBindings
164437
164600
  return { ok: false, reason: "invalid-range" };
164438
164601
  }
164439
164602
  }
164440
- const batchLeaves = parseParagraphInlineMap(TD22.decode(paragraphBytes), inheritedNamespaceBindings).leaves();
164603
+ const batchModel = parseParagraphInlineMap(TD22.decode(paragraphBytes), inheritedNamespaceBindings);
164604
+ for (const edit of ordered) {
164605
+ const blocked = validateSelectedSdtProtection(batchModel.pieces, edit.startOffset, edit.endOffset);
164606
+ if (blocked)
164607
+ return { ok: false, reason: blocked };
164608
+ }
164609
+ const batchLeaves = batchModel.leaves();
164441
164610
  if (batchLeaves.some((piece) => piece.kind === "noteReference" && !piece.deleted && ordered.some((edit) => edit.startOffset < piece.visibleEnd && edit.endOffset > piece.visibleStart))) {
164442
164611
  return { ok: false, reason: "unsupported-context" };
164443
164612
  }
@@ -165014,6 +165183,27 @@ function hasNonWordMarkerAtCollapsedMoveBoundary(pieces, at, coordinateSpace = "
165014
165183
  function firstNonFieldRangeStartMarker(markers) {
165015
165184
  return markers.find((piece) => piece.role === "range-start" && !isFieldMarker(piece.markerKind)) ?? null;
165016
165185
  }
165186
+ function validateSelectedSdtProtection(pieces, start, end) {
165187
+ if (start === end)
165188
+ return null;
165189
+ for (const piece of pieces) {
165190
+ if (piece.kind !== "container" && piece.kind !== "tracked")
165191
+ continue;
165192
+ if (piece.kind === "container" && piece.containerKind === "sdt" && rangeCrossesContainer(piece, start, end)) {
165193
+ const policy = classifySdtMutationPolicyInternal(piece, true);
165194
+ if (!policy.ok)
165195
+ return policy.reason;
165196
+ const contentOnly = containerContainsRange(piece, start, end);
165197
+ const wholeWrapper = start <= piece.visibleStart && piece.visibleEnd <= end;
165198
+ if (contentOnly && !policy.contentEditable || !contentOnly && !policy.wrapperDeletable || !contentOnly && !wholeWrapper && !policy.contentEditable)
165199
+ return "text-range-in-sdt";
165200
+ }
165201
+ const blocked = validateSelectedSdtProtection(piece.children, start, end);
165202
+ if (blocked)
165203
+ return blocked;
165204
+ }
165205
+ return null;
165206
+ }
165017
165207
  function resolveEditScope(pieces, start, end, collapsedInlineAffinity, collapsedOutsideContentControl = false) {
165018
165208
  let current = pieces;
165019
165209
  let descended = false;
@@ -165068,11 +165258,11 @@ function planCrossBoundarySdts(pieces, start, end) {
165068
165258
  const policy = classifySdtMutationPolicy(piece);
165069
165259
  if (!policy.ok)
165070
165260
  return policy;
165261
+ if (!policy.wrapperDeletable)
165262
+ return { ok: false, reason: "text-range-in-sdt" };
165071
165263
  requiresCollaborationSessionSync = true;
165072
165264
  const wholeWrapper = start <= piece.visibleStart && piece.visibleEnd <= end;
165073
165265
  if (wholeWrapper) {
165074
- if (!policy.wrapperDeletable)
165075
- return { ok: false, reason: "text-range-in-sdt" };
165076
165266
  const blocked = findBlockingSdtChild(piece.children);
165077
165267
  if (blocked)
165078
165268
  return { ok: false, reason: blocked };
@@ -192926,7 +193116,7 @@ function tryRangeReplacementAcrossTokens(input, allTokens, touched) {
192926
193116
  if (!firstSelected)
192927
193117
  return null;
192928
193118
  const touchedInsertions = touched.filter((entry) => entry.token.kind === "ins");
192929
- if (touchedInsertions.some(({ token }) => token.innerRuns && token.innerRuns.length > 1 || token.nestedDeletions && token.nestedDeletions.length > 0)) {
193119
+ if (touchedInsertions.some(({ token }) => token.innerRuns && token.innerRuns.length > 1 && (token !== firstSelected.token || token.commentedBoundary != null) || token.nestedDeletions && token.nestedDeletions.length > 0)) {
192930
193120
  return null;
192931
193121
  }
192932
193122
  const result = input.changeMode === "tracked" ? authorTrackedPureDelete(input, allTokens, touched) : authorDirectPureDelete(input, allTokens, touched);
@@ -193030,7 +193220,7 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193030
193220
  continue;
193031
193221
  }
193032
193222
  const head2 = token.text.slice(0, localStart2);
193033
- const removed2 = token.text.slice(localStart2, localEnd2);
193223
+ const removed = token.text.slice(localStart2, localEnd2);
193034
193224
  const tail2 = token.text.slice(localEnd2);
193035
193225
  const headXml = head2.length > 0 ? renderPlainRun(head2, token.runOpen, token.runClose, token.rPr) : "";
193036
193226
  const delXml = buildDelWrapperXml({
@@ -193039,7 +193229,7 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193039
193229
  author: currentAuthor,
193040
193230
  date: input.txTimestamp,
193041
193231
  rsidDel: input.rsid,
193042
- inner: { runOpen: token.runOpen, runClose: token.runClose, rPr: token.rPr, text: removed2 }
193232
+ inner: { runOpen: token.runOpen, runClose: token.runClose, rPr: token.rPr, text: removed }
193043
193233
  });
193044
193234
  const insertXml = !replacementInserted && input.newText.length > 0 ? buildInsWrapperXml({
193045
193235
  nsPrefix,
@@ -193072,7 +193262,6 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193072
193262
  continue;
193073
193263
  }
193074
193264
  const head = token.inner.text.slice(0, localStart);
193075
- const removed = token.inner.text.slice(localStart, localEnd);
193076
193265
  const tail = token.inner.text.slice(localEnd);
193077
193266
  const classification = token._classification;
193078
193267
  removedAnything = true;
@@ -193101,8 +193290,13 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193101
193290
  updatedRsids.push(rsid);
193102
193291
  continue;
193103
193292
  }
193104
- const nestedHead = renderPlainRun(head, token.inner.runOpen, token.inner.runClose, token.inner.rPr);
193105
- const nestedTail = renderPlainRun(tail, token.inner.runOpen, token.inner.runClose, token.inner.rPr);
193293
+ const runs = token.innerRuns ?? [token.inner];
193294
+ const headRuns = sliceWrappedRuns(runs, 0, localStart);
193295
+ const removedRuns = sliceWrappedRuns(runs, localStart, localEnd);
193296
+ const tailRuns = sliceWrappedRuns(runs, localEnd, token.inner.text.length);
193297
+ const nestedHead = buildInsInnerXmlFromRuns(headRuns);
193298
+ const nestedTail = buildInsInnerXmlFromRuns(tailRuns);
193299
+ const insertMeta = runMetaAtInsertionPoint(token, localStart, true);
193106
193300
  const childIns = !replacementInserted && input.newText.length > 0 && input.rangeStart >= token.visibleStart && input.rangeStart < token.visibleEnd && input.rangeEnd > token.visibleEnd ? buildInsWrapperXml({
193107
193301
  namespaceReferenceOpenTag: token.openTag,
193108
193302
  nsPrefix: token.nsPrefix,
@@ -193111,9 +193305,9 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193111
193305
  date: input.txTimestamp,
193112
193306
  rsidR: input.insRsid,
193113
193307
  inner: {
193114
- runOpen: token.inner.runOpen,
193115
- runClose: token.inner.runClose,
193116
- rPr: token.inner.rPr,
193308
+ runOpen: insertMeta.runOpen,
193309
+ runClose: insertMeta.runClose,
193310
+ rPr: rPrAtInsertionPoint(token, localStart, true),
193117
193311
  text: input.newText
193118
193312
  }
193119
193313
  }) : "";
@@ -193124,10 +193318,8 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193124
193318
  author: currentAuthor,
193125
193319
  date: input.txTimestamp,
193126
193320
  rsidDel: input.rsid,
193127
- inner: { runOpen: token.inner.runOpen, runClose: token.inner.runClose, rPr: token.inner.rPr, text: removed },
193128
- ...token.commentedBoundary ? {
193129
- innerXml: renderDelRun(removed, token.inner.runOpen, token.inner.runClose, token.inner.rPr) + token.commentedBoundary.endXml + token.commentedBoundary.referenceRunXml
193130
- } : {}
193321
+ inner: removedRuns[0],
193322
+ innerXml: buildDelInnerXmlFromRuns(removedRuns) + (token.commentedBoundary?.endXml ?? "") + (token.commentedBoundary?.referenceRunXml ?? "")
193131
193323
  });
193132
193324
  if (token.commentedBoundary) {
193133
193325
  if (!childIns || tail.length > 0)
@@ -193148,7 +193340,8 @@ function authorTrackedPureDelete(input, allTokens, touched, touchedBreaks = [])
193148
193340
  author: token.author,
193149
193341
  date: token.date,
193150
193342
  rsidR: token.rsidR,
193151
- inner: { ...token.inner, text: head }
193343
+ inner: headRuns[0],
193344
+ innerXml: nestedHead
193152
193345
  }) : "";
193153
193346
  const tailIns = buildInsWrapperXml({
193154
193347
  openTag: token.openTag,
@@ -193515,6 +193708,20 @@ function foldInsideOwnInsertion(input, allTokens, parent) {
193515
193708
  const rebuilt = rebuildParagraph(allTokens, parent, newInsXml);
193516
193709
  return rebuilt.ok ? markTextInsertionRefined(markExistingRevisionUpdated(rebuilt, input, parent), input, parent, false) : rebuilt;
193517
193710
  }
193711
+ function sliceWrappedRuns(runs, start, end) {
193712
+ const result = [];
193713
+ let offset = 0;
193714
+ for (const run of runs) {
193715
+ const runEnd = offset + run.text.length;
193716
+ if (start < runEnd && end > offset) {
193717
+ result.push({ ...run, text: run.text.slice(Math.max(0, start - offset), Math.min(run.text.length, end - offset)) });
193718
+ }
193719
+ offset = runEnd;
193720
+ if (offset >= end)
193721
+ break;
193722
+ }
193723
+ return result;
193724
+ }
193518
193725
  function flattenWrappedRuns(runs) {
193519
193726
  const out = [];
193520
193727
  for (const run of runs) {
@@ -193735,8 +193942,10 @@ function splitInsertionAroundChildChange(input, allTokens, parent) {
193735
193942
  detail: "overlap compiler: edit range straddles an existing nested tracked deletion."
193736
193943
  };
193737
193944
  }
193738
- const headOwnedNested = parent.nestedDeletions?.filter((n) => n.localOffset <= localStart) ?? [];
193739
- const tailOwnedNested = parent.nestedDeletions?.filter((n) => n.localOffset > localStart) ?? [];
193945
+ const precedesBoundaryDeletion = input.changeMode === "tracked" && input.newText.length > 0 && input.rangeStart === input.rangeEnd && (input.coordinateSpace ?? "visible") === "visible" && input.collapsedInlineAffinity === "upstream";
193946
+ const belongsToHead = (n) => n.localOffset < localStart || n.localOffset === localStart && !precedesBoundaryDeletion;
193947
+ const headOwnedNested = nestedDeletions.filter(belongsToHead);
193948
+ const tailOwnedNested = nestedDeletions.filter((n) => !belongsToHead(n));
193740
193949
  const flat = flattenWrappedRuns(parent.innerRuns ?? [parent.inner]);
193741
193950
  const headRuns = coalesceWrappedRuns(flat.slice(0, localStart));
193742
193951
  const removedRuns = coalesceWrappedRuns(flat.slice(localStart, localEnd));
@@ -193866,7 +194075,7 @@ function splitInsertionAroundChildChange(input, allTokens, parent) {
193866
194075
  ok: true,
193867
194076
  xml,
193868
194077
  emittedRsids,
193869
- ...removedText.length > 0 || tailParentWId !== parent.wId || liftComment ? { requiresCollaborationSessionSync: true } : {}
194078
+ ...removedText.length > 0 || tailParentWId !== parent.wId || liftComment || precedesBoundaryDeletion && tailOwnedNested.some((n) => n.localOffset === localStart) ? { requiresCollaborationSessionSync: true } : {}
193870
194079
  };
193871
194080
  }
193872
194081
  function insertAtForeignDeletion(input, allTokens, parent, sameUser, side = "after") {
@@ -198950,6 +199159,15 @@ function rewriteTrackedPartialSdtSelection(paragraphXml, startOffset, endOffset,
198950
199159
  const sdts = [...intersectingSdts].sort((left, right) => left.visibleStart - right.visibleStart);
198951
199160
  if (sdts.some((sdt, index) => index > 0 && sdt.visibleStart < sdts[index - 1].visibleEnd))
198952
199161
  return null;
199162
+ for (const sdt of sdts) {
199163
+ if (sdt.visibleStart <= startOffset && endOffset <= sdt.visibleEnd)
199164
+ continue;
199165
+ const policy = classifySdtMutationPolicy(sdt);
199166
+ if (!policy.ok)
199167
+ return policy;
199168
+ if (!policy.wrapperDeletable)
199169
+ return { ok: false, reason: "text-range-in-sdt" };
199170
+ }
198953
199171
  const segments = [];
198954
199172
  let cursor = startOffset;
198955
199173
  for (const sdt of sdts) {
@@ -203111,6 +203329,101 @@ var init_paragraph_property_history = __esm(() => {
203111
203329
  init_paragraph_property_namespaces();
203112
203330
  });
203113
203331
 
203332
+ // ../../../v2/editor-core/dist/document/transactions/tracked-paragraph-properties.js
203333
+ function readParagraphProperties(xml, namespaceBindings) {
203334
+ const prefix = [...namespaceBindings].find(([key2, uri]) => key2 && uri === NS_W)?.[0] ?? "w";
203335
+ const source = xml || `<${prefix}:pPr/>`;
203336
+ const parsed = collectXmlElementRanges(source, {
203337
+ fragment: true,
203338
+ additionalNamespaces: Object.fromEntries(namespaceBindings)
203339
+ });
203340
+ const ranges = parsed.ranges.sort((a, b) => a.start - b.start || b.end - a.end);
203341
+ const root = ranges[0];
203342
+ if (parsed.errors.length || !root || root.start !== 0 || root.end !== source.length || root.tag.namespaceUri !== NS_W || root.tag.localName !== "pPr")
203343
+ return null;
203344
+ if (ranges.some((range) => range.tag.namespaceUri === NS_W && ["ins", "del", "moveFrom", "moveTo", "pPrChange", "rPrChange", "sectPr"].includes(range.tag.localName)))
203345
+ return null;
203346
+ const children = [];
203347
+ let cursor = root.openEnd;
203348
+ for (const range of ranges.slice(1)) {
203349
+ if (range.start < cursor)
203350
+ continue;
203351
+ if (source.slice(cursor, range.start).trim())
203352
+ return null;
203353
+ children.push(range);
203354
+ cursor = range.end;
203355
+ }
203356
+ const marks = children.filter((child) => child.tag.namespaceUri === NS_W && child.tag.localName === "rPr");
203357
+ if (marks.length > 1)
203358
+ return null;
203359
+ const mark = marks[0];
203360
+ const baseChildren = children.filter((child) => child !== mark).map((child) => source.slice(child.start, child.end)).join("");
203361
+ return {
203362
+ source,
203363
+ root,
203364
+ mark,
203365
+ markXml: mark ? source.slice(mark.start, mark.end) : "",
203366
+ baseChildren
203367
+ };
203368
+ }
203369
+ function isSafeTrackedParagraphProperties(xml, namespaceBindings) {
203370
+ return readParagraphProperties(xml, namespaceBindings) !== null;
203371
+ }
203372
+ function prepareTrackedParagraphProperties(input) {
203373
+ const prefix = [...input.namespaceBindings].find(([key2, uri]) => key2 && uri === NS_W)?.[0] ?? "w";
203374
+ const before = readParagraphProperties(input.beforeXml, input.namespaceBindings);
203375
+ const after = readParagraphProperties(input.afterXml, input.namespaceBindings);
203376
+ if (!before || !after)
203377
+ return null;
203378
+ const wordIds = [];
203379
+ const markBindings = after.mark?.namespaceBindings ?? after.root.namespaceBindings;
203380
+ const wrapperBindings = (kind) => ({
203381
+ ...kind === "rPr" ? markBindings : after.root.namespaceBindings,
203382
+ [prefix]: NS_W
203383
+ });
203384
+ const wrapper = (kind, old) => {
203385
+ const id = input.stamp.revisionIds?.[wordIds.length] ?? input.stamp.revisionId + wordIds.length;
203386
+ if (input.stamp.revisionIds && wordIds.length >= input.stamp.revisionIds.length)
203387
+ return null;
203388
+ wordIds.push(String(id));
203389
+ const namespace = (kind === "rPr" ? markBindings : after.root.namespaceBindings)[prefix] === NS_W ? "" : ` xmlns:${prefix}="${NS_W}"`;
203390
+ return `<${prefix}:${kind}Change${namespace} ${prefix}:id="${id}" ${prefix}:author="${escapeXmlAttribute(input.stamp.author.name)}" ${prefix}:date="${escapeXmlAttribute(input.stamp.date)}">${old}</${prefix}:${kind}Change>`;
203391
+ };
203392
+ let mark = after.markXml;
203393
+ if (before.markXml !== after.markXml) {
203394
+ const oldMark = before.mark ? copyParagraphPropertyChild(before.source, before.mark, wrapperBindings("rPr")) : `<${prefix}:rPr/>`;
203395
+ const change = wrapper("rPr", oldMark);
203396
+ if (!change)
203397
+ return null;
203398
+ if (!after.mark || after.mark.tag.isSelfClosing) {
203399
+ const open = after.mark ? after.markXml.replace(/\/>$/, ">") : `<${prefix}:rPr>`;
203400
+ mark = open + change + `</${after.mark?.tag.name ?? `${prefix}:rPr`}>`;
203401
+ } else {
203402
+ const at = after.mark.closeStart - after.mark.start;
203403
+ mark = after.markXml.slice(0, at) + change + after.markXml.slice(at);
203404
+ }
203405
+ }
203406
+ let paragraphChange = "";
203407
+ if (before.baseChildren !== after.baseChildren) {
203408
+ const oldProperties = paragraphPropertyOpeningWithNamespaces(before.source, before.root, wrapperBindings("pPr")).replace(/\/>$/, ">") + before.baseChildren + `</${before.root.tag.name}>`;
203409
+ const change = wrapper("pPr", oldProperties);
203410
+ if (!change)
203411
+ return null;
203412
+ paragraphChange = change;
203413
+ }
203414
+ if (wordIds.length === 0)
203415
+ return { xml: input.afterXml, wordIds };
203416
+ return {
203417
+ xml: after.source.slice(0, after.root.openEnd).replace(/\/>$/, ">") + after.baseChildren + mark + paragraphChange + `</${after.root.tag.name}>`,
203418
+ wordIds
203419
+ };
203420
+ }
203421
+ var init_tracked_paragraph_properties = __esm(() => {
203422
+ init_xml_sax();
203423
+ init_xml_text();
203424
+ init_paragraph_property_namespaces();
203425
+ });
203426
+
203114
203427
  // ../../../v2/editor-core/dist/document/transactions/tracked-changes/review-decision-semantics.js
203115
203428
  function structuralDecisionBehavior(kind, decision) {
203116
203429
  if (kind === "paragraph-mark-deletion" && decision === "accept" || kind === "paragraph-mark-insertion" && decision === "reject" || kind === "section-break-deletion" && decision === "accept")
@@ -203680,7 +203993,7 @@ function mergeParagraphMarkedBoundary(lookupContext, xml, fragment3, namespaceBi
203680
203993
  return { ok: false, reason: "unsupported-context" };
203681
203994
  }
203682
203995
  const pendingInsertionTerminalDeletion = fragment3.structuralKind === "paragraph-mark-deletion" && isPendingFullParagraphInsertion(currentWithoutMarker, fragment3.tagPrefix);
203683
- const merged = fragment3.structuralKind === "paragraph-mark-insertion" ? mergeParagraphXmlKeepingFirstForDecision(currentWithoutMarker, next.xml) : pendingInsertionTerminalDeletion ? mergeParagraphXmlKeepingPendingInsertion(currentWithoutMarker, next.xml) : next.wrapper ? mergeParagraphXmlForDecisionWithWrappedSuccessor(currentWithoutMarker, next.xml, next.wrapper) : mergeParagraphXmlForDecision(currentWithoutMarker, next.xml);
203996
+ const merged = fragment3.structuralKind === "paragraph-mark-insertion" ? mergeParagraphXmlKeepingFirstForDecision(currentWithoutMarker, next.xml) : pendingInsertionTerminalDeletion ? mergeParagraphXmlKeepingPendingInsertion(currentWithoutMarker, next.xml, effectiveNamespaceBindings) : next.wrapper ? mergeParagraphXmlForDecisionWithWrappedSuccessor(currentWithoutMarker, next.xml, next.wrapper) : mergeParagraphXmlForDecision(currentWithoutMarker, next.xml);
203684
203997
  if (!merged)
203685
203998
  return { ok: false, reason: "invalid-input" };
203686
203999
  return {
@@ -203893,7 +204206,7 @@ function mergeParagraphXmlForDecisionWithWrappedSuccessor(firstXml, secondXml, w
203893
204206
  return null;
203894
204207
  return secondOpenMatch[0] + secondPPr + firstRuns + wrapper.openTag + secondRuns + wrapper.closeTag + secondCloseMatch[0];
203895
204208
  }
203896
- function mergeParagraphXmlKeepingPendingInsertion(firstXml, secondXml) {
204209
+ function mergeParagraphXmlKeepingPendingInsertion(firstXml, secondXml, namespaceBindings) {
203897
204210
  firstXml = expandEmptyParagraphForMerge(firstXml);
203898
204211
  secondXml = expandEmptyParagraphForMerge(secondXml);
203899
204212
  const firstOpenMatch = firstXml.match(/^<[\w.-]+:p\b[^>]*>/);
@@ -203906,9 +204219,14 @@ function mergeParagraphXmlKeepingPendingInsertion(firstXml, secondXml) {
203906
204219
  const secondInner = secondXml.slice(secondOpenMatch[0].length, secondXml.length - secondCloseMatch[0].length);
203907
204220
  const firstPPr = matchLeadingElement(firstInner, "pPr");
203908
204221
  const secondPPr = matchLeadingElement(secondInner, "pPr");
203909
- if (!firstPPr || secondPPr)
204222
+ const parsedSecond = collectXmlElementRanges(secondXml, {
204223
+ fragment: true,
204224
+ additionalNamespaces: xmlFragmentAdditionalNamespaces(secondXml, new Map(Object.entries(namespaceBindings)))
204225
+ });
204226
+ const secondRoot = parsedSecond.ranges.find((range) => range.start === 0 && range.end === secondXml.length);
204227
+ if (!firstPPr || parsedSecond.errors.length || !secondRoot || !isSafeTrackedParagraphProperties(secondPPr, new Map(Object.entries(secondRoot.namespaceBindings))))
203910
204228
  return null;
203911
- return firstOpenMatch[0] + firstPPr + firstInner.slice(firstPPr.length) + secondInner + firstCloseMatch[0];
204229
+ return firstOpenMatch[0] + firstPPr + firstInner.slice(firstPPr.length) + secondInner.slice(secondPPr.length) + firstCloseMatch[0];
203912
204230
  }
203913
204231
  function isPendingFullParagraphInsertion(paragraphXml, prefix) {
203914
204232
  const parsed = collectXmlElementRanges(paragraphXml, {
@@ -205043,6 +205361,7 @@ var init_decide_engine = __esm(() => {
205043
205361
  init_paragraph_mark_format_history();
205044
205362
  init_paragraph_property_history();
205045
205363
  init_paragraph_property_namespaces();
205364
+ init_tracked_paragraph_properties();
205046
205365
  init_structural_groups();
205047
205366
  init_paragraph_property_block();
205048
205367
  init_block_deletion_text();
@@ -213039,97 +213358,6 @@ var init_tracked_block_replacement = __esm(() => {
213039
213358
  init_tracked_table_replacement();
213040
213359
  });
213041
213360
 
213042
- // ../../../v2/editor-core/dist/document/transactions/tracked-paragraph-properties.js
213043
- function prepareTrackedParagraphProperties(input) {
213044
- const prefix = [...input.namespaceBindings].find(([key2, uri]) => key2 && uri === NS_W)?.[0] ?? "w";
213045
- const read = (xml) => {
213046
- const source = xml || `<${prefix}:pPr/>`;
213047
- const parsed = collectXmlElementRanges(source, {
213048
- fragment: true,
213049
- additionalNamespaces: Object.fromEntries(input.namespaceBindings)
213050
- });
213051
- const ranges = parsed.ranges.sort((a, b) => a.start - b.start || b.end - a.end);
213052
- const root = ranges[0];
213053
- if (parsed.errors.length || !root || root.start !== 0 || root.end !== source.length || root.tag.namespaceUri !== NS_W || root.tag.localName !== "pPr")
213054
- return null;
213055
- if (ranges.some((range) => range.tag.namespaceUri === NS_W && ["ins", "del", "moveFrom", "moveTo", "pPrChange", "rPrChange", "sectPr"].includes(range.tag.localName)))
213056
- return null;
213057
- const children = [];
213058
- let cursor = root.openEnd;
213059
- for (const range of ranges.slice(1)) {
213060
- if (range.start < cursor)
213061
- continue;
213062
- if (source.slice(cursor, range.start).trim())
213063
- return null;
213064
- children.push(range);
213065
- cursor = range.end;
213066
- }
213067
- const marks = children.filter((child) => child.tag.namespaceUri === NS_W && child.tag.localName === "rPr");
213068
- if (marks.length > 1)
213069
- return null;
213070
- const mark2 = marks[0];
213071
- const baseChildren = children.filter((child) => child !== mark2).map((child) => source.slice(child.start, child.end)).join("");
213072
- return {
213073
- source,
213074
- root,
213075
- mark: mark2,
213076
- markXml: mark2 ? source.slice(mark2.start, mark2.end) : "",
213077
- baseChildren
213078
- };
213079
- };
213080
- const before = read(input.beforeXml);
213081
- const after = read(input.afterXml);
213082
- if (!before || !after)
213083
- return null;
213084
- const wordIds = [];
213085
- const markBindings = after.mark?.namespaceBindings ?? after.root.namespaceBindings;
213086
- const wrapperBindings = (kind) => ({
213087
- ...kind === "rPr" ? markBindings : after.root.namespaceBindings,
213088
- [prefix]: NS_W
213089
- });
213090
- const wrapper = (kind, old) => {
213091
- const id = input.stamp.revisionIds?.[wordIds.length] ?? input.stamp.revisionId + wordIds.length;
213092
- if (input.stamp.revisionIds && wordIds.length >= input.stamp.revisionIds.length)
213093
- return null;
213094
- wordIds.push(String(id));
213095
- const namespace = (kind === "rPr" ? markBindings : after.root.namespaceBindings)[prefix] === NS_W ? "" : ` xmlns:${prefix}="${NS_W}"`;
213096
- return `<${prefix}:${kind}Change${namespace} ${prefix}:id="${id}" ${prefix}:author="${escapeXmlAttribute(input.stamp.author.name)}" ${prefix}:date="${escapeXmlAttribute(input.stamp.date)}">${old}</${prefix}:${kind}Change>`;
213097
- };
213098
- let mark = after.markXml;
213099
- if (before.markXml !== after.markXml) {
213100
- const oldMark = before.mark ? copyParagraphPropertyChild(before.source, before.mark, wrapperBindings("rPr")) : `<${prefix}:rPr/>`;
213101
- const change = wrapper("rPr", oldMark);
213102
- if (!change)
213103
- return null;
213104
- if (!after.mark || after.mark.tag.isSelfClosing) {
213105
- const open = after.mark ? after.markXml.replace(/\/>$/, ">") : `<${prefix}:rPr>`;
213106
- mark = open + change + `</${after.mark?.tag.name ?? `${prefix}:rPr`}>`;
213107
- } else {
213108
- const at = after.mark.closeStart - after.mark.start;
213109
- mark = after.markXml.slice(0, at) + change + after.markXml.slice(at);
213110
- }
213111
- }
213112
- let paragraphChange = "";
213113
- if (before.baseChildren !== after.baseChildren) {
213114
- const oldProperties = paragraphPropertyOpeningWithNamespaces(before.source, before.root, wrapperBindings("pPr")).replace(/\/>$/, ">") + before.baseChildren + `</${before.root.tag.name}>`;
213115
- const change = wrapper("pPr", oldProperties);
213116
- if (!change)
213117
- return null;
213118
- paragraphChange = change;
213119
- }
213120
- if (wordIds.length === 0)
213121
- return { xml: input.afterXml, wordIds };
213122
- return {
213123
- xml: after.source.slice(0, after.root.openEnd).replace(/\/>$/, ">") + after.baseChildren + mark + paragraphChange + `</${after.root.tag.name}>`,
213124
- wordIds
213125
- };
213126
- }
213127
- var init_tracked_paragraph_properties = __esm(() => {
213128
- init_xml_sax();
213129
- init_xml_text();
213130
- init_paragraph_property_namespaces();
213131
- });
213132
-
213133
213361
  // ../../../v2/editor-core/dist/document/transactions/tracked-terminal-paragraph-delete.js
213134
213362
  function prepareTrackedTerminalParagraphDeletion(input) {
213135
213363
  const read = (xml, namespaces) => {
@@ -213159,7 +213387,7 @@ function prepareTrackedTerminalParagraphDeletion(input) {
213159
213387
  if (!previous || !current)
213160
213388
  return null;
213161
213389
  const pendingInsertion = (() => {
213162
- if (!previous.properties || current.propertiesXml || !previous.runs.trim())
213390
+ if (!previous.properties || !previous.runs.trim())
213163
213391
  return false;
213164
213392
  const properties2 = collectXmlElementRanges(previous.propertiesXml, {
213165
213393
  fragment: true,
@@ -213186,6 +213414,8 @@ function prepareTrackedTerminalParagraphDeletion(input) {
213186
213414
  return parsedContent.errors.length === 0 && contentRanges.length > 0 && contentRoot?.start === 0 && contentRoot.end === content.length && contentRoot.tag.namespaceUri === NS_W && contentRoot.tag.localName === "ins";
213187
213415
  })();
213188
213416
  if (pendingInsertion) {
213417
+ if (!isSafeTrackedParagraphProperties(current.propertiesXml, new Map(Object.entries(current.root.namespaceBindings))))
213418
+ return null;
213189
213419
  const ids2 = input.stamp.revisionIds ?? [input.stamp.revisionId, input.stamp.revisionId + 1];
213190
213420
  if (ids2.length < 2)
213191
213421
  return null;
@@ -213209,7 +213439,7 @@ function prepareTrackedTerminalParagraphDeletion(input) {
213209
213439
  return null;
213210
213440
  return {
213211
213441
  previousXml: previous.opening + previousProperties + previous.runs + previous.closing,
213212
- currentXml: current.opening + deleted2.xml + current.closing,
213442
+ currentXml: current.opening + current.propertiesXml + deleted2.xml + current.closing,
213213
213443
  wordIds: [String(ids2[0]), ...deleted2.wordIds]
213214
213444
  };
213215
213445
  }
@@ -216115,7 +216345,10 @@ function runParagraphRangeCollapseCommit(input) {
216115
216345
  if (startOffsetMap.charToByte(op.on.startOffset) !== op.on.startByte || endOffsetMap.charToByte(op.on.endOffset) !== op.on.endByte) {
216116
216346
  return rejected8(input.txId, "base-revision-drift");
216117
216347
  }
216118
- const structuralFailure = validateRangeCollapseStructure(bytes, index.entries, start, end, changeMode, op.startObjectBoundary, op.endObjectBoundary, { allowSectionBoundary: changeMode === "direct" && op.replacementText === undefined && !deleteFullBlocks });
216348
+ const structuralFailure = validateRangeCollapseStructure(bytes, index.entries, start, end, changeMode, op.startObjectBoundary, op.endObjectBoundary, {
216349
+ allowSectionBoundary: changeMode === "direct" && op.replacementText === undefined && !deleteFullBlocks,
216350
+ inlineRange: { startOffset: op.on.startOffset, endOffset: op.on.endOffset, deleteFullBlocks: op.deleteFinalParagraphMark === true }
216351
+ });
216119
216352
  if (structuralFailure)
216120
216353
  return rejected8(input.txId, structuralFailure);
216121
216354
  let replacementBlockId;
@@ -216172,7 +216405,7 @@ function runParagraphRangeCollapseCommit(input) {
216172
216405
  op = expanded.op;
216173
216406
  start = expanded.start;
216174
216407
  end = expanded.end;
216175
- const expandedStructure = validateRangeCollapseStructure(bytes, index.entries, start, end, changeMode, undefined, undefined, { allowSectionBoundary: true });
216408
+ const expandedStructure = validateRangeCollapseStructure(bytes, index.entries, start, end, changeMode, undefined, undefined, { allowSectionBoundary: true, inlineRange: { startOffset: op.on.startOffset, endOffset: op.on.endOffset } });
216176
216409
  if (expandedStructure)
216177
216410
  return rejected8(input.txId, expandedStructure);
216178
216411
  rangeIntegrity = validateParagraphRangeIntegrity({
@@ -217922,6 +218155,11 @@ function validateRangeCollapseStructure(bytes, entries, start, end, changeMode,
217922
218155
  if (!options.structuralMap && directBodyRangeIsStructurallyPlain(bytes, entries, start, end, changeMode)) {
217923
218156
  return null;
217924
218157
  }
218158
+ if (options.inlineRange) {
218159
+ const failure2 = validateRangeInlineSdtProtection(bytes, entries, start, end, options.inlineRange);
218160
+ if (failure2)
218161
+ return failure2;
218162
+ }
217925
218163
  if (!options.structuralMap)
217926
218164
  recordSDTxPerf("rangeCollapseStructuralFullScans", 1);
217927
218165
  const map3 = options.structuralMap ?? buildStructuralBoundaryMap(bytes);
@@ -217993,6 +218231,46 @@ function validateRangeCollapseStructure(bytes, entries, start, end, changeMode,
217993
218231
  }
217994
218232
  return null;
217995
218233
  }
218234
+ function validateRangeInlineSdtProtection(bytes, entries, start, end, range) {
218235
+ for (const entry of entries) {
218236
+ if (entry.ordinal < start.ordinal || entry.ordinal > end.ordinal)
218237
+ continue;
218238
+ const xml = decodeByteRange(bytes, entry.byteStart, entry.byteEnd);
218239
+ if (!/<\s*(?:[\w.-]+:)?sdt\b/.test(xml))
218240
+ continue;
218241
+ const namespaces = namespaceBindingsAtPosition(bytes, entry.byteStart, matchParagraphOpenTag(xml) ?? "");
218242
+ const selectedStart = entry.blockId === start.blockId ? range.startOffset : 0;
218243
+ const selectedEnd = entry.blockId === end.blockId ? range.endOffset : entry.textLength;
218244
+ const wholeParagraph = range.deleteFullBlocks === true || entry.ordinal > start.ordinal && entry.ordinal < end.ordinal;
218245
+ const visit = (pieces) => {
218246
+ for (const piece of pieces) {
218247
+ if (piece.kind !== "container" && piece.kind !== "tracked")
218248
+ continue;
218249
+ if (piece.kind === "container" && piece.containerKind === "sdt") {
218250
+ const touched = wholeParagraph || (piece.visibleStart === piece.visibleEnd ? (entry.blockId !== start.blockId || selectedStart < piece.visibleStart) && piece.visibleEnd <= selectedEnd : selectedStart < piece.visibleEnd && piece.visibleStart < selectedEnd);
218251
+ if (!touched)
218252
+ continue;
218253
+ const policy = classifySdtMutationPolicy(piece);
218254
+ if (!policy.ok)
218255
+ return policy.reason;
218256
+ if (!policy.wrapperDeletable)
218257
+ return "text-range-in-sdt";
218258
+ const wholeWrapper = wholeParagraph || selectedStart <= piece.visibleStart && piece.visibleEnd <= selectedEnd;
218259
+ if (!wholeWrapper && !policy.contentEditable)
218260
+ return "text-range-in-sdt";
218261
+ }
218262
+ const failure3 = visit(piece.children);
218263
+ if (failure3)
218264
+ return failure3;
218265
+ }
218266
+ return null;
218267
+ };
218268
+ const failure2 = visit(parseParagraphInlineMap(xml, namespaces).pieces);
218269
+ if (failure2)
218270
+ return failure2;
218271
+ }
218272
+ return null;
218273
+ }
217996
218274
  function directBodyRangeIsStructurallyPlain(bytes, entries, start, end, changeMode) {
217997
218275
  if (!Number.isSafeInteger(start.ordinal) || !Number.isSafeInteger(end.ordinal) || start.ordinal < 0 || end.ordinal <= start.ordinal || end.ordinal >= entries.length || entries[start.ordinal]?.blockId !== start.blockId || entries[start.ordinal]?.byteStart !== start.byteStart || entries[start.ordinal]?.byteEnd !== start.byteEnd || entries[end.ordinal]?.blockId !== end.blockId || entries[end.ordinal]?.byteStart !== end.byteStart || entries[end.ordinal]?.byteEnd !== end.byteEnd || !Number.isSafeInteger(start.byteStart) || !Number.isSafeInteger(end.byteEnd) || start.byteStart < 0 || end.byteEnd <= start.byteStart || end.byteEnd > bytes.byteLength)
217998
218276
  return false;
@@ -224310,7 +224588,7 @@ function runBodyStep(input, storyId, noteId, step2, changeMode, options, pushHis
224310
224588
  if ((step2.kind === "edit" || step2.kind === "formatEdit") && step2.targetRunXml !== undefined) {
224311
224589
  const before = liveCompareBodyRunXml(state, storyId, step2.blockId);
224312
224590
  const partBytes = state.packageBytes.get(storyPartUriFromStoryId2(storyId));
224313
- if (before !== undefined && partBytes && inspectInlineControlRemoval(before, step2.targetRunXml, textboxNamespaceBindingsFromPartBytes(partBytes))) {
224591
+ if (before !== undefined && partBytes && (inspectInlineControlRemoval(before, step2.targetRunXml, textboxNamespaceBindingsFromPartBytes(partBytes)) || inspectInlineControlReplay(before, step2.targetRunXml, textboxNamespaceBindingsFromPartBytes(partBytes)))) {
224314
224592
  return runInlineControlRemovalCommit(input, storyId, step2, changeMode, options, pushHistory);
224315
224593
  }
224316
224594
  }
@@ -225071,6 +225349,134 @@ function retainedNoteMarkerRuns(oldRuns, targetRuns, storyId) {
225071
225349
  targetRuns: targetMarker.remainingRunXml
225072
225350
  };
225073
225351
  }
225352
+ function equivalentSimpleRunContent(before, after) {
225353
+ const previous = parseSimpleRunTokens(before), next = parseSimpleRunTokens(after);
225354
+ if (!previous || !next)
225355
+ return false;
225356
+ const spans = (tokens) => tokens.flatMap((token) => Array.from(token.text, (char) => `${canonicalizeXmlForSignature(token.openTag)}:${char}`));
225357
+ const old = spans(previous), target = spans(next);
225358
+ return old.length === target.length && old.every((value, index) => value === target[index]);
225359
+ }
225360
+ function inlineComparePieces(proof) {
225361
+ const pieces = [];
225362
+ const gap = (before, roots, rootOffset) => {
225363
+ const tokens = parseSimpleRunTokens(before);
225364
+ if (!tokens)
225365
+ return false;
225366
+ const oldText = tokens.map((token) => token.text).join("");
225367
+ const targets = roots.map((xml, index) => {
225368
+ const control2 = proof.inserted.find((item) => item.index === index + rootOffset);
225369
+ const text = projectCompareReplayCurrentText(control2?.contentXml ?? xml);
225370
+ return text === null ? null : { xml, control: control2, text };
225371
+ });
225372
+ if (targets.some((item) => item === null))
225373
+ return false;
225374
+ const nextText = targets.map((item) => item.text).join("");
225375
+ const operations = getWordChanges(oldText, nextText);
225376
+ const mapOffset = (offset) => {
225377
+ let oldCursor3 = 0, nextCursor3 = 0;
225378
+ for (const op of operations) {
225379
+ const start = op.type === "insert" ? op.insertAt : op.oldFrom;
225380
+ const equalEnd = nextCursor3 + start - oldCursor3;
225381
+ if (offset < equalEnd)
225382
+ return oldCursor3 + offset - nextCursor3;
225383
+ const oldEnd = op.type === "insert" ? start : op.oldTo;
225384
+ const nextEnd = equalEnd + (op.type === "delete" ? 0 : op.newText.length);
225385
+ if (offset < nextEnd)
225386
+ return start;
225387
+ oldCursor3 = oldEnd;
225388
+ nextCursor3 = nextEnd;
225389
+ }
225390
+ return oldCursor3 + offset - nextCursor3;
225391
+ };
225392
+ let oldCursor2 = 0, nextCursor2 = 0;
225393
+ let ordinaryTarget = "";
225394
+ const appendOrdinary = (end) => {
225395
+ pieces.push({
225396
+ beforeXml: renderCompareRunRange(tokens, oldCursor2, end, "passthrough"),
225397
+ afterXml: ordinaryTarget,
225398
+ ordinary: true
225399
+ });
225400
+ ordinaryTarget = "";
225401
+ oldCursor2 = end;
225402
+ };
225403
+ for (const target of targets) {
225404
+ if (!target)
225405
+ return false;
225406
+ if (!target.control) {
225407
+ ordinaryTarget += target.xml;
225408
+ nextCursor2 += target.text.length;
225409
+ continue;
225410
+ }
225411
+ const start = mapOffset(nextCursor2), end = mapOffset(nextCursor2 + target.text.length);
225412
+ if (start < oldCursor2 || end < start || end > oldText.length)
225413
+ return false;
225414
+ appendOrdinary(start);
225415
+ const selected = renderCompareRunRange(tokens, start, end, "passthrough");
225416
+ if (equivalentSimpleRunContent(selected, target.control.contentXml)) {
225417
+ pieces.push({ beforeXml: target.control.contentXml, afterXml: target.xml });
225418
+ } else {
225419
+ pieces.push({ beforeXml: selected, afterXml: "", ordinary: true });
225420
+ pieces.push({ beforeXml: "", afterXml: target.xml });
225421
+ }
225422
+ oldCursor2 = end;
225423
+ nextCursor2 += target.text.length;
225424
+ }
225425
+ appendOrdinary(oldText.length);
225426
+ return true;
225427
+ };
225428
+ let oldCursor = 0, nextCursor = 0;
225429
+ for (const anchor of proof.anchors) {
225430
+ if (!gap(proof.beforeRoots.slice(oldCursor, anchor.beforeIndex).join(""), proof.afterRoots.slice(nextCursor, anchor.afterIndex), nextCursor))
225431
+ return null;
225432
+ if (anchor.changed) {
225433
+ pieces.push({ beforeXml: anchor.before.xml, afterXml: anchor.after.xml });
225434
+ } else
225435
+ pieces.push({ beforeXml: anchor.before.xml, afterXml: anchor.before.xml });
225436
+ oldCursor = anchor.beforeIndex + 1;
225437
+ nextCursor = anchor.afterIndex + 1;
225438
+ }
225439
+ if (!gap(proof.beforeRoots.slice(oldCursor).join(""), proof.afterRoots.slice(nextCursor), nextCursor))
225440
+ return null;
225441
+ return pieces;
225442
+ }
225443
+ function inspectInlineControlCompareBodyReplay(bytes, startByte, endByte, targetRunXml) {
225444
+ const xml = TD60.decode(bytes);
225445
+ const start = TD60.decode(bytes.subarray(0, startByte)).length;
225446
+ const end = start + TD60.decode(bytes.subarray(startByte, endByte)).length;
225447
+ const parsed = collectXmlElementRanges(xml);
225448
+ if (parsed.errors.length)
225449
+ return null;
225450
+ const body = parsed.ranges.find((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "body");
225451
+ if (!body || !directXmlChildRanges(parsed.ranges, body).some((range) => range.start === start && range.end === end && range.tag.namespaceUri === NS_W && range.tag.localName === "p"))
225452
+ return null;
225453
+ const proof = inspectInlineControlReplay(extractCompareParagraphRunXml(xml.slice(start, end)), targetRunXml, textboxNamespaceBindingsFromPartBytes(bytes));
225454
+ if (!proof)
225455
+ return null;
225456
+ const counts = new Map;
225457
+ for (const range of parsed.ranges) {
225458
+ if (range.tag.namespaceUri !== NS_W || range.tag.localName !== "sdtPr")
225459
+ continue;
225460
+ for (const id of directXmlChildRanges(parsed.ranges, range).filter((child) => child.tag.namespaceUri === NS_W && child.tag.localName === "id")) {
225461
+ const raw = readXmlAttribute(id.tag, NS_W, "val")?.value;
225462
+ if (raw !== undefined && /^-?\d+$/.test(raw) && Number.isSafeInteger(Number(raw))) {
225463
+ const key2 = String(Number(raw));
225464
+ counts.set(key2, (counts.get(key2) ?? 0) + 1);
225465
+ }
225466
+ }
225467
+ }
225468
+ if (proof.anchors.some((anchor) => counts.get(anchor.before.id) !== 1) || proof.inserted.some((control2) => counts.has(control2.id)))
225469
+ return null;
225470
+ return proof;
225471
+ }
225472
+ function directlyOwnedBodyParagraph(bytes, startByte, endByte) {
225473
+ const xml = TD60.decode(bytes);
225474
+ const start = TD60.decode(bytes.subarray(0, startByte)).length;
225475
+ const end = start + TD60.decode(bytes.subarray(startByte, endByte)).length;
225476
+ const parsed = collectXmlElementRanges(xml);
225477
+ const body = parsed.ranges.find((range) => range.tag.namespaceUri === NS_W && range.tag.localName === "body");
225478
+ return !parsed.errors.length && !!body && directXmlChildRanges(parsed.ranges, body).some((range) => range.start === start && range.end === end && range.tag.namespaceUri === NS_W && range.tag.localName === "p");
225479
+ }
225074
225480
  function runInlineControlRemovalCommit(input, storyId, step2, changeMode, options, pushHistory) {
225075
225481
  const { state, txId } = input;
225076
225482
  const partUri = storyPartUriFromStoryId2(storyId);
@@ -225086,7 +225492,10 @@ function runInlineControlRemovalCommit(input, storyId, step2, changeMode, option
225086
225492
  const before = extractCompareParagraphRunXml(paragraph);
225087
225493
  const namespaces = textboxNamespaceBindingsFromPartBytes(bytes);
225088
225494
  const proof = inspectInlineControlRemoval(before, step2.targetRunXml, namespaces);
225089
- if (!proof || /<(?:[\w.-]+:)?\w+Change\b/.test(properties))
225495
+ const replay = inspectInlineControlCompareBodyReplay(bytes, entry.byteStart, entry.byteEnd, step2.targetRunXml);
225496
+ if (replay && !/^[0-9A-Fa-f]{8}$/.test(step2.blockId))
225497
+ return rejected14(txId, "unsupported-context");
225498
+ if (!proof && !replay || !directlyOwnedBodyParagraph(bytes, entry.byteStart, entry.byteEnd) || /<(?:[\w.-]+:)?\w+Change\b/.test(properties))
225090
225499
  return rejected14(txId, "unsupported-context");
225091
225500
  const targetProperties = step2.targetParagraphPropertiesXml === undefined ? properties : rewriteCanonicalWordprocessingPrefix(step2.targetParagraphPropertiesXml, wrapper.wordprocessingPrefix);
225092
225501
  if (!equivalentParagraphProperties(properties, targetProperties))
@@ -225099,7 +225508,9 @@ function runInlineControlRemovalCommit(input, storyId, step2, changeMode, option
225099
225508
  return rejected14(txId, "no-author-configured");
225100
225509
  const namespaceBindings = new Map(Object.entries(namespaces));
225101
225510
  namespaceBindings.set(wrapper.wordprocessingPrefix, W_NS4);
225102
- const pieces = [];
225511
+ const pieces = replay ? inlineComparePieces(replay) ?? [] : [];
225512
+ if (replay && !pieces.length)
225513
+ return rejected14(txId, "unsupported-context");
225103
225514
  const appendGap = (old, next) => {
225104
225515
  let head = 0;
225105
225516
  while (head < old.length && head < next.length && old[head] === next[head])
@@ -225116,7 +225527,7 @@ function runInlineControlRemovalCommit(input, storyId, step2, changeMode, option
225116
225527
  };
225117
225528
  let oldCursor = 0;
225118
225529
  let nextCursor = 0;
225119
- for (let index = 0;index < proof.afterRoots.length; index++) {
225530
+ for (let index = 0;proof && !replay && index < proof.afterRoots.length; index++) {
225120
225531
  const root = proof.afterRoots[index];
225121
225532
  if (!/<(?:[\w.-]+:)?sdt\b/.test(root))
225122
225533
  continue;
@@ -225128,12 +225539,33 @@ function runInlineControlRemovalCommit(input, storyId, step2, changeMode, option
225128
225539
  oldCursor = oldIndex + 1;
225129
225540
  nextCursor = index + 1;
225130
225541
  }
225131
- appendGap(proof.beforeRoots.slice(oldCursor), proof.afterRoots.slice(nextCursor));
225542
+ if (proof && !replay)
225543
+ appendGap(proof.beforeRoots.slice(oldCursor), proof.afterRoots.slice(nextCursor));
225132
225544
  const stamp = { revisionId: 0, author: serializedSessionAuthor(sourceAuthor), date: input.txTimestamp };
225133
225545
  const prepare = (revisionIds) => {
225134
225546
  let xml = "";
225135
225547
  const wordIds = [];
225136
225548
  for (const piece of pieces) {
225549
+ if (piece.beforeXml === piece.afterXml) {
225550
+ xml += piece.beforeXml;
225551
+ continue;
225552
+ }
225553
+ if (piece.ordinary && !/<(?:[\w.-]+:)?sdt\b/.test(piece.beforeXml + piece.afterXml)) {
225554
+ const result2 = renderWordLevelTrackedRunSegment(piece.beforeXml, piece.afterXml, () => {
225555
+ const delId = revisionIds?.[wordIds.length] ?? wordIds.length;
225556
+ wordIds.push(String(delId));
225557
+ const insId = revisionIds?.[wordIds.length] ?? wordIds.length;
225558
+ wordIds.push(String(insId));
225559
+ return {
225560
+ del: { rsid: delId.toString(16).padStart(8, "0"), wId: delId, author: stamp.author, date: stamp.date },
225561
+ ins: { rsid: delId.toString(16).padStart(8, "0"), wId: insId, author: stamp.author, date: stamp.date }
225562
+ };
225563
+ }, wrapper.wordprocessingPrefix);
225564
+ if (result2) {
225565
+ xml += result2.xml;
225566
+ continue;
225567
+ }
225568
+ }
225137
225569
  const result = prepareTrackedSdtXmlReplacement({
225138
225570
  beforeXml: piece.beforeXml,
225139
225571
  afterXml: piece.afterXml,
@@ -236491,7 +236923,7 @@ function resolveFragmentApplyTarget(state, op) {
236491
236923
  const index2 = paragraphIndexForPasteStory(state, target.storyId);
236492
236924
  if (!index2)
236493
236925
  return { ok: false, reason: "unsupported-context" };
236494
- const structuralFailure = validateRangeCollapseStructure(bytes, index2.entries, anchor.entry, anchor.entry, op.changeMode ?? "direct", undefined, undefined, { allowWholeParagraphReplacement: true });
236926
+ const structuralFailure = validateRangeCollapseStructure(bytes, index2.entries, anchor.entry, anchor.entry, op.changeMode ?? "direct", undefined, undefined, { allowWholeParagraphReplacement: true, inlineRange: { startOffset: 0, endOffset: anchor.entry.textLength, deleteFullBlocks: true } });
236495
236927
  if (structuralFailure)
236496
236928
  return { ok: false, reason: structuralFailure };
236497
236929
  const integrityFailure = validateFragmentRangeIntegrity({
@@ -236567,7 +236999,7 @@ function resolveFragmentApplyTarget(state, op) {
236567
236999
  const crossParagraph = startAnchor.ordinal !== endAnchor.ordinal;
236568
237000
  const replacesContent = crossParagraph || target.charOffset !== explicitEnd.charOffset;
236569
237001
  if (crossParagraph) {
236570
- const structuralFailure = validateRangeCollapseStructure(residentBytes, index.entries, startAnchor.entry, endAnchor.entry, op.changeMode ?? "direct", target.collapsedObjectBoundary, explicitEnd.objectBoundary, { allowTrackedSdtContent: true });
237002
+ const structuralFailure = validateRangeCollapseStructure(residentBytes, index.entries, startAnchor.entry, endAnchor.entry, op.changeMode ?? "direct", target.collapsedObjectBoundary, explicitEnd.objectBoundary, { allowTrackedSdtContent: true, inlineRange: { startOffset: target.charOffset, endOffset: explicitEnd.charOffset } });
236571
237003
  if (structuralFailure)
236572
237004
  return { ok: false, reason: structuralFailure };
236573
237005
  } else if (replacesContent && residentBytes) {
@@ -255950,6 +256382,7 @@ var init_sd_document_session_internal = __esm(() => {
255950
256382
  init_section_property_references();
255951
256383
  init_bibliography_style();
255952
256384
  init_bibliography_review_resources();
256385
+ init_compile_compare_apply();
255953
256386
  });
255954
256387
 
255955
256388
  // ../../../v2/document-api-v2-adapter/dist/address/story-identity.js
@@ -316552,9 +316985,9 @@ var init_codes = __esm(() => {
316552
316985
  });
316553
316986
 
316554
316987
  // ../../../v2/node_modules/.pnpm/micromark-util-symbol@2.0.1/node_modules/micromark-util-symbol/lib/constants.js
316555
- var constants;
316988
+ var constants2;
316556
316989
  var init_constants = __esm(() => {
316557
- constants = {
316990
+ constants2 = {
316558
316991
  attentionSideAfter: 2,
316559
316992
  attentionSideBefore: 1,
316560
316993
  atxHeadingOpeningFenceSizeMax: 6,
@@ -316828,7 +317261,7 @@ function splice(list, start, remove, items) {
316828
317261
  start = start > end ? end : start;
316829
317262
  }
316830
317263
  remove = remove > 0 ? remove : 0;
316831
- if (items.length < constants.v8MaxSafeChunkSize) {
317264
+ if (items.length < constants2.v8MaxSafeChunkSize) {
316832
317265
  parameters = Array.from(items);
316833
317266
  parameters.unshift(start, remove);
316834
317267
  list.splice(...parameters);
@@ -316836,11 +317269,11 @@ function splice(list, start, remove, items) {
316836
317269
  if (remove)
316837
317270
  list.splice(start, remove);
316838
317271
  while (chunkStart < items.length) {
316839
- parameters = items.slice(chunkStart, chunkStart + constants.v8MaxSafeChunkSize);
317272
+ parameters = items.slice(chunkStart, chunkStart + constants2.v8MaxSafeChunkSize);
316840
317273
  parameters.unshift(start, 0);
316841
317274
  list.splice(...parameters);
316842
- chunkStart += constants.v8MaxSafeChunkSize;
316843
- start += constants.v8MaxSafeChunkSize;
317275
+ chunkStart += constants2.v8MaxSafeChunkSize;
317276
+ start += constants2.v8MaxSafeChunkSize;
316844
317277
  }
316845
317278
  }
316846
317279
  }
@@ -316995,7 +317428,7 @@ function initializeContent(effects2) {
316995
317428
  }
316996
317429
  function lineStart(code) {
316997
317430
  const token = effects2.enter(types9.chunkText, {
316998
- contentType: constants.contentTypeText,
317431
+ contentType: constants2.contentTypeText,
316999
317432
  previous
317000
317433
  });
317001
317434
  if (previous) {
@@ -317123,7 +317556,7 @@ function initializeDocument(effects2) {
317123
317556
  childFlow = childFlow || self.parser.flow(self.now());
317124
317557
  effects2.enter(types9.chunkFlow, {
317125
317558
  _tokenizer: childFlow,
317126
- contentType: constants.contentTypeFlow,
317559
+ contentType: constants2.contentTypeFlow,
317127
317560
  previous: childToken
317128
317561
  });
317129
317562
  return flowContinue(code);
@@ -317208,7 +317641,7 @@ function initializeDocument(effects2) {
317208
317641
  }
317209
317642
  function tokenizeContainer(effects2, ok3, nok) {
317210
317643
  ok2(this.parser.constructs.disable.null, "expected `disable.null` to be populated");
317211
- return factorySpace(effects2, effects2.attempt(this.parser.constructs.document, ok3, nok), types9.linePrefix, this.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize);
317644
+ return factorySpace(effects2, effects2.attempt(this.parser.constructs.document, ok3, nok), types9.linePrefix, this.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize);
317212
317645
  }
317213
317646
  var document3, containerConstruct;
317214
317647
  var init_document2 = __esm(() => {
@@ -317224,10 +317657,10 @@ var init_document2 = __esm(() => {
317224
317657
  // ../../../v2/node_modules/.pnpm/micromark-util-classify-character@2.0.1/node_modules/micromark-util-classify-character/dev/index.js
317225
317658
  function classifyCharacter(code) {
317226
317659
  if (code === codes.eof || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {
317227
- return constants.characterGroupWhitespace;
317660
+ return constants2.characterGroupWhitespace;
317228
317661
  }
317229
317662
  if (unicodePunctuation(code)) {
317230
- return constants.characterGroupPunctuation;
317663
+ return constants2.characterGroupPunctuation;
317231
317664
  }
317232
317665
  }
317233
317666
  var init_dev6 = __esm(() => {
@@ -317360,8 +317793,8 @@ function tokenizeAttention(effects2, ok3) {
317360
317793
  const token = effects2.exit("attentionSequence");
317361
317794
  const after = classifyCharacter(code);
317362
317795
  ok2(attentionMarkers, "expected `attentionMarkers` to be populated");
317363
- const open = !after || after === constants.characterGroupPunctuation && before || attentionMarkers.includes(code);
317364
- const close = !before || before === constants.characterGroupPunctuation && after || attentionMarkers.includes(previous);
317796
+ const open = !after || after === constants2.characterGroupPunctuation && before || attentionMarkers.includes(code);
317797
+ const close = !before || before === constants2.characterGroupPunctuation && after || attentionMarkers.includes(previous);
317365
317798
  token._open = Boolean(marker === codes.asterisk ? open : open && (before || !close));
317366
317799
  token._close = Boolean(marker === codes.asterisk ? close : close && (after || !open));
317367
317800
  return ok3(code);
@@ -317421,7 +317854,7 @@ function tokenizeAutolink(effects2, ok3, nok) {
317421
317854
  size = 0;
317422
317855
  return urlInside;
317423
317856
  }
317424
- if ((code === codes.plusSign || code === codes.dash || code === codes.dot || asciiAlphanumeric(code)) && size++ < constants.autolinkSchemeSizeMax) {
317857
+ if ((code === codes.plusSign || code === codes.dash || code === codes.dot || asciiAlphanumeric(code)) && size++ < constants2.autolinkSchemeSizeMax) {
317425
317858
  effects2.consume(code);
317426
317859
  return schemeInsideOrEmailAtext;
317427
317860
  }
@@ -317474,7 +317907,7 @@ function tokenizeAutolink(effects2, ok3, nok) {
317474
317907
  return emailValue(code);
317475
317908
  }
317476
317909
  function emailValue(code) {
317477
- if ((code === codes.dash || asciiAlphanumeric(code)) && size++ < constants.autolinkDomainSizeMax) {
317910
+ if ((code === codes.dash || asciiAlphanumeric(code)) && size++ < constants2.autolinkDomainSizeMax) {
317478
317911
  const next = code === codes.dash ? emailValue : emailLabel;
317479
317912
  effects2.consume(code);
317480
317913
  return next;
@@ -317546,7 +317979,7 @@ function tokenizeBlockQuoteContinuation(effects2, ok3, nok) {
317546
317979
  function contStart(code) {
317547
317980
  if (markdownSpace(code)) {
317548
317981
  ok2(self.parser.constructs.disable.null, "expected `disable.null` to be populated");
317549
- return factorySpace(effects2, contBefore, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize)(code);
317982
+ return factorySpace(effects2, contBefore, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize)(code);
317550
317983
  }
317551
317984
  return contBefore(code);
317552
317985
  }
@@ -317627,7 +318060,7 @@ function tokenizeCharacterReference(effects2, ok3, nok) {
317627
318060
  return numeric;
317628
318061
  }
317629
318062
  effects2.enter(types9.characterReferenceValue);
317630
- max2 = constants.characterReferenceNamedSizeMax;
318063
+ max2 = constants2.characterReferenceNamedSizeMax;
317631
318064
  test = asciiAlphanumeric;
317632
318065
  return value2(code);
317633
318066
  }
@@ -317637,12 +318070,12 @@ function tokenizeCharacterReference(effects2, ok3, nok) {
317637
318070
  effects2.consume(code);
317638
318071
  effects2.exit(types9.characterReferenceMarkerHexadecimal);
317639
318072
  effects2.enter(types9.characterReferenceValue);
317640
- max2 = constants.characterReferenceHexadecimalSizeMax;
318073
+ max2 = constants2.characterReferenceHexadecimalSizeMax;
317641
318074
  test = asciiHexDigit;
317642
318075
  return value2;
317643
318076
  }
317644
318077
  effects2.enter(types9.characterReferenceValue);
317645
- max2 = constants.characterReferenceDecimalSizeMax;
318078
+ max2 = constants2.characterReferenceDecimalSizeMax;
317646
318079
  test = asciiDigit;
317647
318080
  return value2(code);
317648
318081
  }
@@ -317704,7 +318137,7 @@ function tokenizeCodeFenced(effects2, ok3, nok) {
317704
318137
  effects2.consume(code);
317705
318138
  return sequenceOpen;
317706
318139
  }
317707
- if (sizeOpen < constants.codeFencedSequenceSizeMin) {
318140
+ if (sizeOpen < constants2.codeFencedSequenceSizeMin) {
317708
318141
  return nok(code);
317709
318142
  }
317710
318143
  effects2.exit(types9.codeFencedFenceSequence);
@@ -317716,7 +318149,7 @@ function tokenizeCodeFenced(effects2, ok3, nok) {
317716
318149
  return self.interrupt ? ok3(code) : effects2.check(nonLazyContinuation, atNonLazyBreak, after)(code);
317717
318150
  }
317718
318151
  effects2.enter(types9.codeFencedFenceInfo);
317719
- effects2.enter(types9.chunkString, { contentType: constants.contentTypeString });
318152
+ effects2.enter(types9.chunkString, { contentType: constants2.contentTypeString });
317720
318153
  return info(code);
317721
318154
  }
317722
318155
  function info(code) {
@@ -317741,7 +318174,7 @@ function tokenizeCodeFenced(effects2, ok3, nok) {
317741
318174
  return infoBefore(code);
317742
318175
  }
317743
318176
  effects2.enter(types9.codeFencedFenceMeta);
317744
- effects2.enter(types9.chunkString, { contentType: constants.contentTypeString });
318177
+ effects2.enter(types9.chunkString, { contentType: constants2.contentTypeString });
317745
318178
  return meta3(code);
317746
318179
  }
317747
318180
  function meta3(code) {
@@ -317802,7 +318235,7 @@ function tokenizeCodeFenced(effects2, ok3, nok) {
317802
318235
  function start2(code) {
317803
318236
  ok2(self.parser.constructs.disable.null, "expected `disable.null` to be populated");
317804
318237
  effects3.enter(types9.codeFencedFence);
317805
- return markdownSpace(code) ? factorySpace(effects3, beforeSequenceClose, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize)(code) : beforeSequenceClose(code);
318238
+ return markdownSpace(code) ? factorySpace(effects3, beforeSequenceClose, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize)(code) : beforeSequenceClose(code);
317806
318239
  }
317807
318240
  function beforeSequenceClose(code) {
317808
318241
  if (code === marker) {
@@ -317873,11 +318306,11 @@ function tokenizeCodeIndented(effects2, ok3, nok) {
317873
318306
  function start(code) {
317874
318307
  ok2(markdownSpace(code));
317875
318308
  effects2.enter(types9.codeIndented);
317876
- return factorySpace(effects2, afterPrefix, types9.linePrefix, constants.tabSize + 1)(code);
318309
+ return factorySpace(effects2, afterPrefix, types9.linePrefix, constants2.tabSize + 1)(code);
317877
318310
  }
317878
318311
  function afterPrefix(code) {
317879
318312
  const tail = self.events[self.events.length - 1];
317880
- return tail && tail[1].type === types9.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants.tabSize ? atBreak(code) : nok(code);
318313
+ return tail && tail[1].type === types9.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants2.tabSize ? atBreak(code) : nok(code);
317881
318314
  }
317882
318315
  function atBreak(code) {
317883
318316
  if (code === codes.eof) {
@@ -317915,11 +318348,11 @@ function tokenizeFurtherStart(effects2, ok3, nok) {
317915
318348
  effects2.exit(types9.lineEnding);
317916
318349
  return furtherStart2;
317917
318350
  }
317918
- return factorySpace(effects2, afterPrefix, types9.linePrefix, constants.tabSize + 1)(code);
318351
+ return factorySpace(effects2, afterPrefix, types9.linePrefix, constants2.tabSize + 1)(code);
317919
318352
  }
317920
318353
  function afterPrefix(code) {
317921
318354
  const tail = self.events[self.events.length - 1];
317922
- return tail && tail[1].type === types9.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants.tabSize ? ok3(code) : markdownLineEnding(code) ? furtherStart2(code) : nok(code);
318355
+ return tail && tail[1].type === types9.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants2.tabSize ? ok3(code) : markdownLineEnding(code) ? furtherStart2(code) : nok(code);
317923
318356
  }
317924
318357
  }
317925
318358
  var codeIndented, furtherStart;
@@ -318131,12 +318564,12 @@ class SpliceBuffer {
318131
318564
  }
318132
318565
  function chunkedPush(list, right) {
318133
318566
  let chunkStart = 0;
318134
- if (right.length < constants.v8MaxSafeChunkSize) {
318567
+ if (right.length < constants2.v8MaxSafeChunkSize) {
318135
318568
  list.push(...right);
318136
318569
  } else {
318137
318570
  while (chunkStart < right.length) {
318138
- list.push(...right.slice(chunkStart, chunkStart + constants.v8MaxSafeChunkSize));
318139
- chunkStart += constants.v8MaxSafeChunkSize;
318571
+ list.push(...right.slice(chunkStart, chunkStart + constants2.v8MaxSafeChunkSize));
318572
+ chunkStart += constants2.v8MaxSafeChunkSize;
318140
318573
  }
318141
318574
  }
318142
318575
  }
@@ -318315,7 +318748,7 @@ function tokenizeContent(effects2, ok3) {
318315
318748
  ok2(code !== codes.eof && !markdownLineEnding(code), "expected no eof or eol");
318316
318749
  effects2.enter(types9.content);
318317
318750
  previous2 = effects2.enter(types9.chunkContent, {
318318
- contentType: constants.contentTypeContent
318751
+ contentType: constants2.contentTypeContent
318319
318752
  });
318320
318753
  return chunkInside(code);
318321
318754
  }
@@ -318340,7 +318773,7 @@ function tokenizeContent(effects2, ok3) {
318340
318773
  effects2.exit(types9.chunkContent);
318341
318774
  ok2(previous2, "expected previous token");
318342
318775
  previous2.next = effects2.enter(types9.chunkContent, {
318343
- contentType: constants.contentTypeContent,
318776
+ contentType: constants2.contentTypeContent,
318344
318777
  previous: previous2
318345
318778
  });
318346
318779
  previous2 = previous2.next;
@@ -318364,7 +318797,7 @@ function tokenizeContinuation(effects2, ok3, nok) {
318364
318797
  }
318365
318798
  ok2(self.parser.constructs.disable.null, "expected `disable.null` to be populated");
318366
318799
  const tail = self.events[self.events.length - 1];
318367
- if (!self.parser.constructs.disable.null.includes("codeIndented") && tail && tail[1].type === types9.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants.tabSize) {
318800
+ if (!self.parser.constructs.disable.null.includes("codeIndented") && tail && tail[1].type === types9.linePrefix && tail[2].sliceSerialize(tail[1], true).length >= constants2.tabSize) {
318368
318801
  return ok3(code);
318369
318802
  }
318370
318803
  return effects2.interrupt(self.parser.constructs.flow, nok, ok3)(code);
@@ -318401,7 +318834,7 @@ function factoryDestination(effects2, ok3, nok, type, literalType2, literalMarke
318401
318834
  effects2.enter(type);
318402
318835
  effects2.enter(rawType);
318403
318836
  effects2.enter(stringType2);
318404
- effects2.enter(types9.chunkString, { contentType: constants.contentTypeString });
318837
+ effects2.enter(types9.chunkString, { contentType: constants2.contentTypeString });
318405
318838
  return raw(code);
318406
318839
  }
318407
318840
  function enclosedBefore(code) {
@@ -318414,7 +318847,7 @@ function factoryDestination(effects2, ok3, nok, type, literalType2, literalMarke
318414
318847
  return ok3;
318415
318848
  }
318416
318849
  effects2.enter(stringType2);
318417
- effects2.enter(types9.chunkString, { contentType: constants.contentTypeString });
318850
+ effects2.enter(types9.chunkString, { contentType: constants2.contentTypeString });
318418
318851
  return enclosed(code);
318419
318852
  }
318420
318853
  function enclosed(code) {
@@ -318489,7 +318922,7 @@ function factoryLabel(effects2, ok3, nok, type, markerType, stringType2) {
318489
318922
  return atBreak;
318490
318923
  }
318491
318924
  function atBreak(code) {
318492
- if (size > constants.linkReferenceSizeMax || code === codes.eof || code === codes.leftSquareBracket || code === codes.rightSquareBracket && !seen || code === codes.caret && !size && "_hiddenFootnoteSupport" in self.parser.constructs) {
318925
+ if (size > constants2.linkReferenceSizeMax || code === codes.eof || code === codes.leftSquareBracket || code === codes.rightSquareBracket && !seen || code === codes.caret && !size && "_hiddenFootnoteSupport" in self.parser.constructs) {
318493
318926
  return nok(code);
318494
318927
  }
318495
318928
  if (code === codes.rightSquareBracket) {
@@ -318506,11 +318939,11 @@ function factoryLabel(effects2, ok3, nok, type, markerType, stringType2) {
318506
318939
  effects2.exit(types9.lineEnding);
318507
318940
  return atBreak;
318508
318941
  }
318509
- effects2.enter(types9.chunkString, { contentType: constants.contentTypeString });
318942
+ effects2.enter(types9.chunkString, { contentType: constants2.contentTypeString });
318510
318943
  return labelInside(code);
318511
318944
  }
318512
318945
  function labelInside(code) {
318513
- if (code === codes.eof || code === codes.leftSquareBracket || code === codes.rightSquareBracket || markdownLineEnding(code) || size++ > constants.linkReferenceSizeMax) {
318946
+ if (code === codes.eof || code === codes.leftSquareBracket || code === codes.rightSquareBracket || markdownLineEnding(code) || size++ > constants2.linkReferenceSizeMax) {
318514
318947
  effects2.exit(types9.chunkString);
318515
318948
  return atBreak(code);
318516
318949
  }
@@ -318574,7 +319007,7 @@ function factoryTitle(effects2, ok3, nok, type, markerType, stringType2) {
318574
319007
  effects2.exit(types9.lineEnding);
318575
319008
  return factorySpace(effects2, atBreak, types9.linePrefix);
318576
319009
  }
318577
- effects2.enter(types9.chunkString, { contentType: constants.contentTypeString });
319010
+ effects2.enter(types9.chunkString, { contentType: constants2.contentTypeString });
318578
319011
  return inside(code);
318579
319012
  }
318580
319013
  function inside(code) {
@@ -318750,7 +319183,7 @@ function resolveHeadingAtx(events, context) {
318750
319183
  type: types9.chunkText,
318751
319184
  start: events[contentStart][1].start,
318752
319185
  end: events[contentEnd][1].end,
318753
- contentType: constants.contentTypeText
319186
+ contentType: constants2.contentTypeText
318754
319187
  };
318755
319188
  splice(events, contentStart, contentEnd - contentStart + 1, [
318756
319189
  ["enter", content3, context],
@@ -318774,7 +319207,7 @@ function tokenizeHeadingAtx(effects2, ok3, nok) {
318774
319207
  return sequenceOpen(code);
318775
319208
  }
318776
319209
  function sequenceOpen(code) {
318777
- if (code === codes.numberSign && size++ < constants.atxHeadingOpeningFenceSizeMax) {
319210
+ if (code === codes.numberSign && size++ < constants2.atxHeadingOpeningFenceSizeMax) {
318778
319211
  effects2.consume(code);
318779
319212
  return sequenceOpen;
318780
319213
  }
@@ -318945,7 +319378,7 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
318945
319378
  }
318946
319379
  if (code === codes.questionMark) {
318947
319380
  effects2.consume(code);
318948
- marker = constants.htmlInstruction;
319381
+ marker = constants2.htmlInstruction;
318949
319382
  return self.interrupt ? ok3 : continuationDeclarationInside;
318950
319383
  }
318951
319384
  if (asciiAlpha(code)) {
@@ -318959,18 +319392,18 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
318959
319392
  function declarationOpen(code) {
318960
319393
  if (code === codes.dash) {
318961
319394
  effects2.consume(code);
318962
- marker = constants.htmlComment;
319395
+ marker = constants2.htmlComment;
318963
319396
  return commentOpenInside;
318964
319397
  }
318965
319398
  if (code === codes.leftSquareBracket) {
318966
319399
  effects2.consume(code);
318967
- marker = constants.htmlCdata;
319400
+ marker = constants2.htmlCdata;
318968
319401
  index = 0;
318969
319402
  return cdataOpenInside;
318970
319403
  }
318971
319404
  if (asciiAlpha(code)) {
318972
319405
  effects2.consume(code);
318973
- marker = constants.htmlDeclaration;
319406
+ marker = constants2.htmlDeclaration;
318974
319407
  return self.interrupt ? ok3 : continuationDeclarationInside;
318975
319408
  }
318976
319409
  return nok(code);
@@ -318983,7 +319416,7 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
318983
319416
  return nok(code);
318984
319417
  }
318985
319418
  function cdataOpenInside(code) {
318986
- const value2 = constants.cdataOpeningString;
319419
+ const value2 = constants2.cdataOpeningString;
318987
319420
  if (code === value2.charCodeAt(index++)) {
318988
319421
  effects2.consume(code);
318989
319422
  if (index === value2.length) {
@@ -319007,18 +319440,18 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
319007
319440
  const slash = code === codes.slash;
319008
319441
  const name = buffer.toLowerCase();
319009
319442
  if (!slash && !closingTag && htmlRawNames.includes(name)) {
319010
- marker = constants.htmlRaw;
319443
+ marker = constants2.htmlRaw;
319011
319444
  return self.interrupt ? ok3(code) : continuation(code);
319012
319445
  }
319013
319446
  if (htmlBlockNames.includes(buffer.toLowerCase())) {
319014
- marker = constants.htmlBasic;
319447
+ marker = constants2.htmlBasic;
319015
319448
  if (slash) {
319016
319449
  effects2.consume(code);
319017
319450
  return basicSelfClosing;
319018
319451
  }
319019
319452
  return self.interrupt ? ok3(code) : continuation(code);
319020
319453
  }
319021
- marker = constants.htmlComplete;
319454
+ marker = constants2.htmlComplete;
319022
319455
  return self.interrupt && !self.parser.lazy[self.now().line] ? nok(code) : closingTag ? completeClosingTagAfter(code) : completeAttributeNameBefore(code);
319023
319456
  }
319024
319457
  if (code === codes.dash || asciiAlphanumeric(code)) {
@@ -319133,27 +319566,27 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
319133
319566
  return nok(code);
319134
319567
  }
319135
319568
  function continuation(code) {
319136
- if (code === codes.dash && marker === constants.htmlComment) {
319569
+ if (code === codes.dash && marker === constants2.htmlComment) {
319137
319570
  effects2.consume(code);
319138
319571
  return continuationCommentInside;
319139
319572
  }
319140
- if (code === codes.lessThan && marker === constants.htmlRaw) {
319573
+ if (code === codes.lessThan && marker === constants2.htmlRaw) {
319141
319574
  effects2.consume(code);
319142
319575
  return continuationRawTagOpen;
319143
319576
  }
319144
- if (code === codes.greaterThan && marker === constants.htmlDeclaration) {
319577
+ if (code === codes.greaterThan && marker === constants2.htmlDeclaration) {
319145
319578
  effects2.consume(code);
319146
319579
  return continuationClose;
319147
319580
  }
319148
- if (code === codes.questionMark && marker === constants.htmlInstruction) {
319581
+ if (code === codes.questionMark && marker === constants2.htmlInstruction) {
319149
319582
  effects2.consume(code);
319150
319583
  return continuationDeclarationInside;
319151
319584
  }
319152
- if (code === codes.rightSquareBracket && marker === constants.htmlCdata) {
319585
+ if (code === codes.rightSquareBracket && marker === constants2.htmlCdata) {
319153
319586
  effects2.consume(code);
319154
319587
  return continuationCdataInside;
319155
319588
  }
319156
- if (markdownLineEnding(code) && (marker === constants.htmlBasic || marker === constants.htmlComplete)) {
319589
+ if (markdownLineEnding(code) && (marker === constants2.htmlBasic || marker === constants2.htmlComplete)) {
319157
319590
  effects2.exit(types9.htmlFlowData);
319158
319591
  return effects2.check(blankLineBefore, continuationAfter, continuationStart)(code);
319159
319592
  }
@@ -319205,7 +319638,7 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
319205
319638
  }
319206
319639
  return continuation(code);
319207
319640
  }
319208
- if (asciiAlpha(code) && buffer.length < constants.htmlRawSizeMax) {
319641
+ if (asciiAlpha(code) && buffer.length < constants2.htmlRawSizeMax) {
319209
319642
  ok2(code !== null);
319210
319643
  effects2.consume(code);
319211
319644
  buffer += String.fromCharCode(code);
@@ -319225,7 +319658,7 @@ function tokenizeHtmlFlow(effects2, ok3, nok) {
319225
319658
  effects2.consume(code);
319226
319659
  return continuationClose;
319227
319660
  }
319228
- if (code === codes.dash && marker === constants.htmlComment) {
319661
+ if (code === codes.dash && marker === constants2.htmlComment) {
319229
319662
  effects2.consume(code);
319230
319663
  return continuationDeclarationInside;
319231
319664
  }
@@ -319372,7 +319805,7 @@ function tokenizeHtmlText(effects2, ok3, nok) {
319372
319805
  return code === codes.greaterThan ? end(code) : code === codes.dash ? commentClose(code) : comment(code);
319373
319806
  }
319374
319807
  function cdataOpenInside(code) {
319375
- const value2 = constants.cdataOpeningString;
319808
+ const value2 = constants2.cdataOpeningString;
319376
319809
  if (code === value2.charCodeAt(index++)) {
319377
319810
  effects2.consume(code);
319378
319811
  return index === value2.length ? cdata : cdataOpenInside;
@@ -319588,7 +320021,7 @@ function tokenizeHtmlText(effects2, ok3, nok) {
319588
320021
  }
319589
320022
  function lineEndingAfter(code) {
319590
320023
  ok2(self.parser.constructs.disable.null, "expected `disable.null` to be populated");
319591
- return markdownSpace(code) ? factorySpace(effects2, lineEndingAfterPrefix, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize)(code) : lineEndingAfterPrefix(code);
320024
+ return markdownSpace(code) ? factorySpace(effects2, lineEndingAfterPrefix, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize)(code) : lineEndingAfterPrefix(code);
319592
320025
  }
319593
320026
  function lineEndingAfterPrefix(code) {
319594
320027
  effects2.enter(types9.htmlTextData);
@@ -319751,7 +320184,7 @@ function tokenizeResource(effects2, ok3, nok) {
319751
320184
  if (code === codes.rightParenthesis) {
319752
320185
  return resourceEnd(code);
319753
320186
  }
319754
- return factoryDestination(effects2, resourceDestinationAfter, resourceDestinationMissing, types9.resourceDestination, types9.resourceDestinationLiteral, types9.resourceDestinationLiteralMarker, types9.resourceDestinationRaw, types9.resourceDestinationString, constants.linkResourceDestinationBalanceMax)(code);
320187
+ return factoryDestination(effects2, resourceDestinationAfter, resourceDestinationMissing, types9.resourceDestination, types9.resourceDestinationLiteral, types9.resourceDestinationLiteralMarker, types9.resourceDestinationRaw, types9.resourceDestinationString, constants2.linkResourceDestinationBalanceMax)(code);
319755
320188
  }
319756
320189
  function resourceDestinationAfter(code) {
319757
320190
  return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects2, resourceBetween)(code) : resourceEnd(code);
@@ -319942,7 +320375,7 @@ function tokenizeThematicBreak(effects2, ok3, nok) {
319942
320375
  effects2.enter(types9.thematicBreakSequence);
319943
320376
  return sequence(code);
319944
320377
  }
319945
- if (size >= constants.thematicBreakMarkerCountMin && (code === codes.eof || markdownLineEnding(code))) {
320378
+ if (size >= constants2.thematicBreakMarkerCountMin && (code === codes.eof || markdownLineEnding(code))) {
319946
320379
  effects2.exit(types9.thematicBreak);
319947
320380
  return ok3(code);
319948
320381
  }
@@ -319999,7 +320432,7 @@ function tokenizeListStart(effects2, ok3, nok) {
319999
320432
  }
320000
320433
  function inside(code) {
320001
320434
  ok2(self.containerState, "expected state");
320002
- if (asciiDigit(code) && ++size < constants.listItemValueSizeMax) {
320435
+ if (asciiDigit(code) && ++size < constants2.listItemValueSizeMax) {
320003
320436
  effects2.consume(code);
320004
320437
  return inside;
320005
320438
  }
@@ -320066,7 +320499,7 @@ function tokenizeListContinuation(effects2, ok3, nok) {
320066
320499
  self.containerState._closeFlow = true;
320067
320500
  self.interrupt = undefined;
320068
320501
  ok2(self.parser.constructs.disable.null, "expected `disable.null` to be populated");
320069
- return factorySpace(effects2, effects2.attempt(list, ok3, nok), types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize)(code);
320502
+ return factorySpace(effects2, effects2.attempt(list, ok3, nok), types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize)(code);
320070
320503
  }
320071
320504
  }
320072
320505
  function tokenizeIndent(effects2, ok3, nok) {
@@ -320088,7 +320521,7 @@ function tokenizeListEnd(effects2) {
320088
320521
  function tokenizeListItemPrefixWhitespace(effects2, ok3, nok) {
320089
320522
  const self = this;
320090
320523
  ok2(self.parser.constructs.disable.null, "expected `disable.null` to be populated");
320091
- return factorySpace(effects2, afterPrefix, types9.listItemPrefixWhitespace, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize + 1);
320524
+ return factorySpace(effects2, afterPrefix, types9.listItemPrefixWhitespace, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize + 1);
320092
320525
  function afterPrefix(code) {
320093
320526
  const tail = self.events[self.events.length - 1];
320094
320527
  return !markdownSpace(code) && tail && tail[1].type === types9.listItemPrefixWhitespace ? ok3(code) : nok(code);
@@ -320386,7 +320819,7 @@ function resolveAllLineSuffixes(events, context) {
320386
320819
  }
320387
320820
  if (size) {
320388
320821
  const token = {
320389
- type: eventIndex === events.length || tabs2 || size < constants.hardBreakPrefixSizeMin ? types9.lineSuffix : types9.hardBreakTrailing,
320822
+ type: eventIndex === events.length || tabs2 || size < constants2.hardBreakPrefixSizeMin ? types9.lineSuffix : types9.hardBreakTrailing,
320390
320823
  start: {
320391
320824
  _bufferIndex: index ? bufferIndex : data.start._bufferIndex + bufferIndex,
320392
320825
  _index: data.start._index + index,
@@ -321642,7 +322075,7 @@ function preprocess2() {
321642
322075
  break;
321643
322076
  }
321644
322077
  case codes.ht: {
321645
- next = Math.ceil(column / constants.tabSize) * constants.tabSize;
322078
+ next = Math.ceil(column / constants2.tabSize) * constants2.tabSize;
321646
322079
  chunks.push(codes.horizontalTab);
321647
322080
  while (column++ < next)
321648
322081
  chunks.push(codes.virtualSpace);
@@ -321696,7 +322129,7 @@ function decode4($0, $1, $2) {
321696
322129
  if (head === codes.numberSign) {
321697
322130
  const head2 = $2.charCodeAt(1);
321698
322131
  const hex3 = head2 === codes.lowercaseX || head2 === codes.uppercaseX;
321699
- return decodeNumericCharacterReference($2.slice(hex3 ? 2 : 1), hex3 ? constants.numericBaseHexadecimal : constants.numericBaseDecimal);
322132
+ return decodeNumericCharacterReference($2.slice(hex3 ? 2 : 1), hex3 ? constants2.numericBaseHexadecimal : constants2.numericBaseDecimal);
321700
322133
  }
321701
322134
  return decodeNamedCharacterReference($2) || $0;
321702
322135
  }
@@ -322043,7 +322476,7 @@ function compiler(options) {
322043
322476
  const ancestor = this.stack[this.stack.length - 2];
322044
322477
  ok2(ancestor, "expected nodes on stack");
322045
322478
  ok2(ancestor.type === "list", "expected list on stack");
322046
- ancestor.start = Number.parseInt(this.sliceSerialize(token), constants.numericBaseDecimal);
322479
+ ancestor.start = Number.parseInt(this.sliceSerialize(token), constants2.numericBaseDecimal);
322047
322480
  this.data.expectingFirstListItemValue = undefined;
322048
322481
  }
322049
322482
  }
@@ -322284,7 +322717,7 @@ function compiler(options) {
322284
322717
  const type = this.data.characterReferenceType;
322285
322718
  let value2;
322286
322719
  if (type) {
322287
- value2 = decodeNumericCharacterReference(data2, type === types9.characterReferenceMarkerNumeric ? constants.numericBaseDecimal : constants.numericBaseHexadecimal);
322720
+ value2 = decodeNumericCharacterReference(data2, type === types9.characterReferenceMarkerNumeric ? constants2.numericBaseDecimal : constants2.numericBaseHexadecimal);
322288
322721
  this.data.characterReferenceType = undefined;
322289
322722
  } else {
322290
322723
  const result = decodeNamedCharacterReference(data2);
@@ -323584,7 +324017,7 @@ function tokenizeGfmFootnoteCall(effects2, ok4, nok) {
323584
324017
  return callData;
323585
324018
  }
323586
324019
  function callData(code2) {
323587
- if (size > constants.linkReferenceSizeMax || code2 === codes.rightSquareBracket && !data || code2 === codes.eof || code2 === codes.leftSquareBracket || markdownLineEndingOrSpace(code2)) {
324020
+ if (size > constants2.linkReferenceSizeMax || code2 === codes.rightSquareBracket && !data || code2 === codes.eof || code2 === codes.leftSquareBracket || markdownLineEndingOrSpace(code2)) {
323588
324021
  return nok(code2);
323589
324022
  }
323590
324023
  if (code2 === codes.rightSquareBracket) {
@@ -323643,7 +324076,7 @@ function tokenizeDefinitionStart(effects2, ok4, nok) {
323643
324076
  return nok(code2);
323644
324077
  }
323645
324078
  function labelInside(code2) {
323646
- if (size > constants.linkReferenceSizeMax || code2 === codes.rightSquareBracket && !data || code2 === codes.eof || code2 === codes.leftSquareBracket || markdownLineEndingOrSpace(code2)) {
324079
+ if (size > constants2.linkReferenceSizeMax || code2 === codes.rightSquareBracket && !data || code2 === codes.eof || code2 === codes.leftSquareBracket || markdownLineEndingOrSpace(code2)) {
323647
324080
  return nok(code2);
323648
324081
  }
323649
324082
  if (code2 === codes.rightSquareBracket) {
@@ -323695,10 +324128,10 @@ function gfmFootnoteDefinitionEnd(effects2) {
323695
324128
  }
323696
324129
  function tokenizeIndent2(effects2, ok4, nok) {
323697
324130
  const self = this;
323698
- return factorySpace(effects2, afterPrefix, "gfmFootnoteDefinitionIndent", constants.tabSize + 1);
324131
+ return factorySpace(effects2, afterPrefix, "gfmFootnoteDefinitionIndent", constants2.tabSize + 1);
323699
324132
  function afterPrefix(code2) {
323700
324133
  const tail = self.events[self.events.length - 1];
323701
- return tail && tail[1].type === "gfmFootnoteDefinitionIndent" && tail[2].sliceSerialize(tail[1], true).length === constants.tabSize ? ok4(code2) : nok(code2);
324134
+ return tail && tail[1].type === "gfmFootnoteDefinitionIndent" && tail[2].sliceSerialize(tail[1], true).length === constants2.tabSize ? ok4(code2) : nok(code2);
323702
324135
  }
323703
324136
  }
323704
324137
  var indent;
@@ -323810,8 +324243,8 @@ function gfmStrikethrough(options) {
323810
324243
  return nok(code2);
323811
324244
  const token = effects2.exit("strikethroughSequenceTemporary");
323812
324245
  const after = classifyCharacter(code2);
323813
- token._open = !after || after === constants.attentionSideAfter && Boolean(before);
323814
- token._close = !before || before === constants.attentionSideAfter && Boolean(after);
324246
+ token._open = !after || after === constants2.attentionSideAfter && Boolean(before);
324247
+ token._close = !before || before === constants2.attentionSideAfter && Boolean(after);
323815
324248
  return ok4(code2);
323816
324249
  }
323817
324250
  }
@@ -324010,7 +324443,7 @@ function tokenizeTable(effects2, ok4, nok) {
324010
324443
  seen = false;
324011
324444
  if (markdownSpace(code2)) {
324012
324445
  ok2(self.parser.constructs.disable.null, "expected `disabled.null`");
324013
- return factorySpace(effects2, headDelimiterBefore, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants.tabSize)(code2);
324446
+ return factorySpace(effects2, headDelimiterBefore, types9.linePrefix, self.parser.constructs.disable.null.includes("codeIndented") ? undefined : constants2.tabSize)(code2);
324014
324447
  }
324015
324448
  return headDelimiterBefore(code2);
324016
324449
  }
@@ -324261,7 +324694,7 @@ function flushCell(map3, context, range, rowKind, rowEnd, previousCell) {
324261
324694
  const end = context.events[range[3]];
324262
324695
  start[1].end = Object.assign({}, end[1].end);
324263
324696
  start[1].type = types9.chunkText;
324264
- start[1].contentType = constants.contentTypeText;
324697
+ start[1].contentType = constants2.contentTypeText;
324265
324698
  if (range[3] > range[2] + 1) {
324266
324699
  const a = range[2] + 1;
324267
324700
  const b = range[3] - range[2] - 1;
@@ -388597,7 +389030,7 @@ function serializeSelectionRange(context, target, includeHtml, options) {
388597
389030
  };
388598
389031
  const tableCellPath = boundaryMap.byBlockId(entry.blockId)?.tableCellPath ?? [];
388599
389032
  const blockSdtPath = boundaryMap.byBlockId(entry.blockId)?.blockSdtPath ?? [];
388600
- const properties = readParagraphProperties(paragraphXml);
389033
+ const properties = readParagraphProperties2(paragraphXml);
388601
389034
  const selectedInlineControl = options?.wholeParagraphs !== true && startEntry.ordinal === endEntry.ordinal && map3.pieces.some((piece) => piece.kind === "container" && piece.containerKind === "sdt" && piece.visibleStart === from && piece.visibleEnd === to);
388602
389035
  const fullyCovered = !selectedInlineControl && from === 0 && to === map3.visibleLength && (options?.wholeParagraphs === true || startEntry.ordinal !== endEntry.ordinal || properties.styleRef !== undefined || properties.numbering !== undefined || hasParagraphProperties(paragraphXml));
388603
389036
  const styleModel = copyStyleModel ?? (copyStyleModel = compileCopyStyleModel(context));
@@ -389630,7 +390063,7 @@ function capturePPrXml(paragraphXml, notes) {
389630
390063
  return null;
389631
390064
  return pPr;
389632
390065
  }
389633
- function readParagraphProperties(paragraphXml) {
390066
+ function readParagraphProperties2(paragraphXml) {
389634
390067
  const pPr = /<w:pPr\b(?:[^>]*\/>|[^>]*>[\s\S]*?<\/w:pPr\s*>)/.exec(paragraphXml)?.[0] ?? "";
389635
390068
  const styleRef = /<w:pStyle\b[^>]*w:val="([^"]+)"/.exec(pPr)?.[1];
389636
390069
  const numPr = /<w:numPr\b[\s\S]*?<\/w:numPr>/.exec(pPr)?.[0];
@@ -429198,6 +429631,7 @@ function emissionContext(owner, xml) {
429198
429631
  return cached2.context;
429199
429632
  }
429200
429633
  function materializeProjection(input) {
429634
+ const readStorySnapshot = input.readStorySnapshot ?? snapshotStoryShard;
429201
429635
  const previousById = new Map;
429202
429636
  const previousByPartUri = new Map;
429203
429637
  if (input.previousRecord) {
@@ -429290,6 +429724,7 @@ function materializeProjection(input) {
429290
429724
  let fullStoryRebuilds = 0;
429291
429725
  const storyHandles = input.shardRegistry.listStories();
429292
429726
  const stories = [];
429727
+ const contentControlTopologies = new Map;
429293
429728
  const sourceBootstrapDigests = new Map;
429294
429729
  for (const handle of storyHandles) {
429295
429730
  const readTarget = shardReadTarget(handle);
@@ -429307,7 +429742,7 @@ function materializeProjection(input) {
429307
429742
  }
429308
429743
  const namespaces = previous3 ? emissionContext(previous3, previous3.xml) : bootstrap?.sourceXml ? emissionContext(bootstrap, bootstrap.sourceXml) : new XmlEmissionContext("");
429309
429744
  const sourceNamespaces = bootstrap?.sourceXml ? emissionContext(bootstrap, bootstrap.sourceXml) : namespaces;
429310
- let useBootstrapSourceXml = !previous3 && (bootstrap?.sourceStoryDigest ? canonicalDigest(snapshotStoryShard(readTarget)) === bootstrap.sourceStoryDigest : !explicitDirtyStoryShardIds.has(handle.shardId)) && typeof bootstrap?.sourceXml === "string" && bootstrap.sourceXml.length > 0;
429745
+ let useBootstrapSourceXml = !previous3 && (bootstrap?.sourceStoryDigest ? canonicalDigest(readStorySnapshot(readTarget)) === bootstrap.sourceStoryDigest : !explicitDirtyStoryShardIds.has(handle.shardId)) && typeof bootstrap?.sourceXml === "string" && bootstrap.sourceXml.length > 0;
429311
429746
  const syntheticAtoms = buildSyntheticCommentAtomsForStory({
429312
429747
  storyDoc: readTarget,
429313
429748
  storyShardId: handle.shardId,
@@ -429315,7 +429750,7 @@ function materializeProjection(input) {
429315
429750
  });
429316
429751
  if (syntheticAtoms.size > 0)
429317
429752
  useBootstrapSourceXml = false;
429318
- if (previous3 && sourceBootstrapDigest && bootstrap?.sourceStoryDigest && previous3.xml === bootstrap.sourceXml && syntheticAtoms.size === 0 && canonicalDigest(snapshotStoryShard(readTarget)) === bootstrap.sourceStoryDigest) {
429753
+ if (previous3 && sourceBootstrapDigest && bootstrap?.sourceStoryDigest && previous3.xml === bootstrap.sourceXml && syntheticAtoms.size === 0 && canonicalDigest(readStorySnapshot(readTarget)) === bootstrap.sourceStoryDigest) {
429319
429754
  stories.push(previous3);
429320
429755
  continue;
429321
429756
  }
@@ -429327,12 +429762,30 @@ function materializeProjection(input) {
429327
429762
  const tableReplacements = readTableStructuralReplacements(readTarget);
429328
429763
  const previousBlockIndex = previous3 ? blockDigestIndex(previous3.blockDigests) : null;
429329
429764
  const insertedBlockHint = previousBlockIndex && [...dirtyStoryBlocks.get(handle.shardId) ?? []].some((blockId) => !previousBlockIndex.has(blockId));
429330
- const structuralSnapshot = previous3 && (wholeStoryDirtyShardIds.has(handle.shardId) || insertedBlockHint) ? snapshotStoryShard(readTarget) : null;
429765
+ const structuralSnapshot = previous3 && (wholeStoryDirtyShardIds.has(handle.shardId) || insertedBlockHint) ? readStorySnapshot(readTarget) : null;
429331
429766
  const overlaidTableIds = structuralSnapshot ? new Set(tableReplacements.map((table) => table.tableNodeId)) : null;
429332
429767
  const restoredTableBoundary = structuralSnapshot && previousBlockIndex ? structuralSnapshot.blocks.some((block) => block.structuralRefs.tableNodeId != null && !previousBlockIndex.has(block.blockId) && !overlaidTableIds.has(block.structuralRefs.tableNodeId)) : false;
429333
429768
  const removedTableBoundary = structuralSnapshot && previous3 ? hasRemovedTableBoundary(previous3, structuralSnapshot.blocks, new Set(tableReplacements.filter((table) => table.deltaKind === "table.rewrite" && table.xml === "").flatMap((table) => table.affectedBlockIds))) : false;
429334
- if (hasContentControlGroups(resolveStoryShardScope(readTarget)) || restoredTableBoundary || removedTableBoundary) {
429335
- const snapshot4 = structuralSnapshot ?? snapshotStoryShard(readTarget);
429769
+ const controlledSnapshot = hasContentControlGroups(resolveStoryShardScope(readTarget)) ? structuralSnapshot ?? readStorySnapshot(readTarget) : null;
429770
+ let controlledTextOnly = false;
429771
+ if (controlledSnapshot) {
429772
+ const envelope = storyEnvelope(controlledSnapshot.meta.storyKind, bootstrap);
429773
+ const prior = previous3 ? CONTENT_CONTROL_TOPOLOGIES.get(previous3) : undefined;
429774
+ const stable = prior && prior.prefix === envelope.prefix && prior.suffix === envelope.suffix && prior.sourceXml === bootstrap?.sourceXml && prior.trailingXml === controlledSnapshot.meta.trailingXml && prior.blocks.length === controlledSnapshot.blocks.length && controlledSnapshot.blocks.every((block, index2) => {
429775
+ const old = prior.blocks[index2];
429776
+ return block.blockId === old.blockId && block.leadingXml === old.leadingXml && block.trailingXml === old.trailingXml && block.splitFromBlockId === old.splitFromBlockId;
429777
+ });
429778
+ controlledTextOnly = !!stable && !fullPackageRebuild && !insertedBlockHint && !wholeStoryDirtyShardIds.has(handle.shardId) && tableReplacements.length === 0 && input.dirty.length > 0 && input.dirty.every((dirty) => dirty.kind === PROJECTION_DIRTY_KIND.storyText && dirty.shardId === handle.shardId && !!dirty.blockId);
429779
+ contentControlTopologies.set(partUriHint, stable ? prior : {
429780
+ prefix: envelope.prefix,
429781
+ suffix: envelope.suffix,
429782
+ sourceXml: bootstrap?.sourceXml,
429783
+ trailingXml: controlledSnapshot.meta.trailingXml,
429784
+ blocks: controlledSnapshot.blocks.map(({ blockId, leadingXml, trailingXml, splitFromBlockId }) => ({ blockId, leadingXml, trailingXml, splitFromBlockId }))
429785
+ });
429786
+ }
429787
+ if (controlledSnapshot && !controlledTextOnly || restoredTableBoundary || removedTableBoundary) {
429788
+ const snapshot4 = controlledSnapshot ?? structuralSnapshot ?? readStorySnapshot(readTarget);
429336
429789
  const placements2 = projectedNamespaceContexts(snapshot4, bootstrap, sourceNamespaces);
429337
429790
  const blocks = snapshot4.blocks.map((block) => ({
429338
429791
  blockId: block.blockId,
@@ -429346,6 +429799,7 @@ function materializeProjection(input) {
429346
429799
  const composed = composeStoryProjection(snapshot4.meta.storyKind, blocks, bootstrap, snapshot4.meta.trailingXml);
429347
429800
  const base3 = { ...composed, partUri: partUriHint, storyId: storyIdHint, storyKind: snapshot4.meta.storyKind };
429348
429801
  const projected = composeTableStructuralProjection({
429802
+ readStorySnapshot,
429349
429803
  handle,
429350
429804
  previous: base3,
429351
429805
  bootstrap,
@@ -429380,7 +429834,7 @@ function materializeProjection(input) {
429380
429834
  blockHints.add(blockId);
429381
429835
  }
429382
429836
  if (blockHints && blockHints.size > 0 && previous3) {
429383
- const currentSnapshot = structuralSnapshot ?? snapshotStoryShard(readTarget);
429837
+ const currentSnapshot = structuralSnapshot ?? readStorySnapshot(readTarget);
429384
429838
  let placements2;
429385
429839
  const currentBlockIds = currentSnapshot.blocks.map((block) => block.blockId);
429386
429840
  if (wholeStoryDirtyShardIds.has(handle.shardId)) {
@@ -429520,6 +429974,7 @@ function materializeProjection(input) {
429520
429974
  };
429521
429975
  })();
429522
429976
  const projectedWithTables = composeTableStructuralProjection({
429977
+ readStorySnapshot,
429523
429978
  handle,
429524
429979
  previous: blockPatchedStory,
429525
429980
  bootstrap,
@@ -429535,6 +429990,7 @@ function materializeProjection(input) {
429535
429990
  storiesRebuilt += 1;
429536
429991
  } else if (tableReplacements.length > 0) {
429537
429992
  const projectedWithTables = composeTableStructuralProjection({
429993
+ readStorySnapshot,
429538
429994
  handle,
429539
429995
  previous: previous3,
429540
429996
  bootstrap,
@@ -429555,6 +430011,7 @@ function materializeProjection(input) {
429555
430011
  }
429556
430012
  }
429557
430013
  const tableStructuralProjection = composeTableStructuralProjection({
430014
+ readStorySnapshot,
429558
430015
  handle,
429559
430016
  previous: previous3,
429560
430017
  bootstrap,
@@ -429570,7 +430027,7 @@ function materializeProjection(input) {
429570
430027
  storiesRebuilt += 1;
429571
430028
  continue;
429572
430029
  }
429573
- const snapshot3 = snapshotStoryShard(readTarget);
430030
+ const snapshot3 = readStorySnapshot(readTarget);
429574
430031
  const placements = projectedNamespaceContexts(snapshot3, bootstrap, sourceNamespaces);
429575
430032
  const partUri = snapshot3.meta.sourcePartUri || `/word/story-${snapshot3.meta.storyId}.xml`;
429576
430033
  const blockDigests = [];
@@ -429628,6 +430085,11 @@ function materializeProjection(input) {
429628
430085
  stories[index2] = { ...story, sourceBootstrapDigest: digest6 };
429629
430086
  }
429630
430087
  stories.sort((a, b) => a.partUri < b.partUri ? -1 : a.partUri > b.partUri ? 1 : 0);
430088
+ for (const story of stories) {
430089
+ const topology = contentControlTopologies.get(story.partUri);
430090
+ if (topology)
430091
+ CONTENT_CONTROL_TOPOLOGIES.set(story, topology);
430092
+ }
429631
430093
  let relationships = input.previousRecord?.relationships ? [...input.previousRecord.relationships] : [];
429632
430094
  let parts = input.previousRecord?.parts ? [...input.previousRecord.parts] : [];
429633
430095
  let contentTypes = input.previousRecord?.contentTypes ?? { defaults: [], overrides: [] };
@@ -429662,17 +430124,21 @@ function materializeProjection(input) {
429662
430124
  safety,
429663
430125
  digest: ""
429664
430126
  };
430127
+ let projectionDigest;
429665
430128
  const withDigest = {
429666
430129
  ...record3,
429667
- digest: canonicalDigest({
429668
- stories: canonicalStoryDigestInputs(record3.stories),
429669
- parts: record3.parts,
429670
- relationships: record3.relationships,
429671
- contentTypes: record3.contentTypes,
429672
- media: record3.media,
429673
- safety: record3.safety,
429674
- snapshotToken: record3.snapshotToken.digest
429675
- })
430130
+ get digest() {
430131
+ projectionDigest ?? (projectionDigest = canonicalDigest({
430132
+ stories: canonicalStoryDigestInputs(record3.stories),
430133
+ parts: record3.parts,
430134
+ relationships: record3.relationships,
430135
+ contentTypes: record3.contentTypes,
430136
+ media: record3.media,
430137
+ safety: record3.safety,
430138
+ snapshotToken: record3.snapshotToken.digest
430139
+ }));
430140
+ return projectionDigest;
430141
+ }
429676
430142
  };
429677
430143
  return { record: withDigest, storiesRebuilt, fullStoryRebuilds, fullPackageRebuild };
429678
430144
  }
@@ -429790,6 +430256,12 @@ function blockProjection(block, extraAtoms = []) {
429790
430256
  }
429791
430257
  function projectedNamespaceContexts(snapshot3, bootstrap, source) {
429792
430258
  const envelope = storyEnvelope(snapshot3.meta.storyKind, bootstrap);
430259
+ const cached2 = PROJECTED_NAMESPACE_CONTEXTS.get(source);
430260
+ if (cached2 && cached2.prefix === envelope.prefix && cached2.suffix === envelope.suffix && cached2.trailingXml === snapshot3.meta.trailingXml && cached2.blocks.length === snapshot3.blocks.length && snapshot3.blocks.every((block, index2) => {
430261
+ const prior = cached2.blocks[index2];
430262
+ return block.blockId === prior.blockId && block.leadingXml === prior.leadingXml && block.trailingXml === prior.trailingXml && block.splitFromBlockId === prior.splitFromBlockId;
430263
+ }))
430264
+ return cached2.contexts;
429793
430265
  let wrappers = envelope.prefix;
429794
430266
  const positions = new Map;
429795
430267
  const blocksById = new Map(snapshot3.blocks.map((block) => [block.blockId, block]));
@@ -429799,9 +430271,6 @@ function projectedNamespaceContexts(snapshot3, bootstrap, source) {
429799
430271
  wrappers += `<projection-slot id="${xmlEscape(block.blockId)}" source="${xmlEscape(block.splitFromBlockId ?? "")}"/>${block.trailingXml ?? ""}`;
429800
430272
  }
429801
430273
  wrappers += snapshot3.meta.trailingXml + envelope.suffix;
429802
- const cached2 = PROJECTED_NAMESPACE_CONTEXTS.get(source);
429803
- if (cached2?.wrappers === wrappers)
429804
- return cached2.contexts;
429805
430274
  const placement3 = new XmlEmissionContext(wrappers);
429806
430275
  const contexts = new Map(snapshot3.blocks.map((block) => {
429807
430276
  const inherited = placement3.at(positions.get(block.blockId));
@@ -429815,7 +430284,13 @@ function projectedNamespaceContexts(snapshot3, bootstrap, source) {
429815
430284
  }
429816
430285
  return [block.blockId, { inherited, source: sourceBindings ?? inherited }];
429817
430286
  }));
429818
- PROJECTED_NAMESPACE_CONTEXTS.set(source, { wrappers, contexts });
430287
+ PROJECTED_NAMESPACE_CONTEXTS.set(source, {
430288
+ prefix: envelope.prefix,
430289
+ suffix: envelope.suffix,
430290
+ trailingXml: snapshot3.meta.trailingXml,
430291
+ blocks: snapshot3.blocks.map(({ blockId, leadingXml, trailingXml, splitFromBlockId }) => ({ blockId, leadingXml, trailingXml, splitFromBlockId })),
430292
+ contexts
430293
+ });
429819
430294
  return contexts;
429820
430295
  }
429821
430296
  function hasRemovedTableBoundary(previous3, blocks, overlayDeletedBlockIds) {
@@ -429875,6 +430350,8 @@ function replaceProjectedTrailingXml(story, trailingXml, bootstrap) {
429875
430350
  if (start === null)
429876
430351
  throw new Error(`Story ${story.storyId} has no resolved trailing XML boundary.`);
429877
430352
  const suffix = trailingXml + envelope.suffix;
430353
+ if (story.xml.slice(start) === suffix)
430354
+ return story;
429878
430355
  const xml = story.xml.slice(0, start) + suffix;
429879
430356
  return { ...story, xml, byteLength: UTF8_ENCODER3.encode(xml).length };
429880
430357
  }
@@ -430450,9 +430927,12 @@ function removeRedundantSplitSeparators(projection, redundantBlockIds) {
430450
430927
  };
430451
430928
  }
430452
430929
  function composeTableStructuralProjection(input) {
430453
- const snapshotBlocks = snapshotStoryShard(shardReadTarget(input.handle)).blocks;
430930
+ const replacements = input.tableReplacements ?? readTableStructuralReplacements(shardReadTarget(input.handle));
430931
+ if (replacements.length === 0)
430932
+ return null;
430933
+ const snapshotBlocks = (input.readStorySnapshot ?? snapshotStoryShard)(shardReadTarget(input.handle)).blocks;
430454
430934
  const liveBlockIds = new Set(snapshotBlocks.map((block) => block.blockId));
430455
- const rawTableReplacements = (input.tableReplacements ?? readTableStructuralReplacements(shardReadTarget(input.handle))).map((replacement) => {
430935
+ const rawTableReplacements = replacements.map((replacement) => {
430456
430936
  if (!replacement.creationPlacement && !replacement.relocation && !replacement.rowReordered && replacement.splitChildren.length === 0)
430457
430937
  return replacement;
430458
430938
  const liveTableBlockIds = snapshotBlocks.filter((block) => block.structuralRefs.tableNodeId === replacement.tableNodeId).map((block) => block.blockId);
@@ -432913,7 +433393,7 @@ function canonicalStoryDigestInputs(stories) {
432913
433393
  tableStructuralOverlays: [...story.tableStructuralOverlays ?? []].sort((left, right) => left.tableNodeId < right.tableNodeId ? -1 : left.tableNodeId > right.tableNodeId ? 1 : 0)
432914
433394
  }));
432915
433395
  }
432916
- var WORD_ML_NS2 = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"', WORD_ML_2010_NS = 'xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"', STORY_ROOT_NS, TEXT_DECODER7, STORY_BLOCK_INDEX_CACHE, SYNTHETIC_PARAGRAPH_BLOCK_ID_PREFIX4 = "__sd:paragraph:", UTF8_ENCODER3, SOURCE_XML_BYTE_ALIGNED_CACHE, XML_EMISSION_CONTEXTS, PROJECTED_NAMESPACE_CONTEXTS, PARAGRAPH_PROPERTY_ORDER, RUN_PROPERTY_CONTENT_LOCAL_NAMES;
433396
+ var WORD_ML_NS2 = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"', WORD_ML_2010_NS = 'xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"', STORY_ROOT_NS, TEXT_DECODER7, STORY_BLOCK_INDEX_CACHE, SYNTHETIC_PARAGRAPH_BLOCK_ID_PREFIX4 = "__sd:paragraph:", UTF8_ENCODER3, SOURCE_XML_BYTE_ALIGNED_CACHE, XML_EMISSION_CONTEXTS, CONTENT_CONTROL_TOPOLOGIES, PROJECTED_NAMESPACE_CONTEXTS, PARAGRAPH_PROPERTY_ORDER, RUN_PROPERTY_CONTENT_LOCAL_NAMES;
432917
433397
  var init_materialize = __esm(() => {
432918
433398
  init_package_part();
432919
433399
  init_anchors();
@@ -432939,6 +433419,7 @@ var init_materialize = __esm(() => {
432939
433419
  UTF8_ENCODER3 = new TextEncoder;
432940
433420
  SOURCE_XML_BYTE_ALIGNED_CACHE = new WeakMap;
432941
433421
  XML_EMISSION_CONTEXTS = new WeakMap;
433422
+ CONTENT_CONTROL_TOPOLOGIES = new WeakMap;
432942
433423
  PROJECTED_NAMESPACE_CONTEXTS = new WeakMap;
432943
433424
  PARAGRAPH_PROPERTY_ORDER = new Map([
432944
433425
  "pStyle",
@@ -433272,8 +433753,143 @@ var init_freshness = __esm(() => {
433272
433753
  }
433273
433754
  });
433274
433755
 
433756
+ // ../../../v2/collaboration-v2/dist/projection/story-snapshot-reader.js
433757
+ function createProjectionStorySnapshotReader() {
433758
+ const stories = new Map;
433759
+ function drop(state) {
433760
+ state.dispose();
433761
+ stories.delete(state.scope.blocks);
433762
+ }
433763
+ function create10(scope) {
433764
+ const invalidate = () => {
433765
+ state.snapshot = null;
433766
+ };
433767
+ const onBlocks = (events) => {
433768
+ for (const event of events) {
433769
+ if (event.target === scope.blocks) {
433770
+ invalidate();
433771
+ continue;
433772
+ }
433773
+ let owner = event.target;
433774
+ while (owner && owner.parent !== scope.blocks) {
433775
+ owner = owner.parent;
433776
+ }
433777
+ if (owner instanceof YMap)
433778
+ state.dirty.add(owner);
433779
+ else
433780
+ invalidate();
433781
+ }
433782
+ };
433783
+ const onMeta = (events) => {
433784
+ if (events.some((event) => [...event.keysChanged ?? []].some((key2) => key2.startsWith("contentControlGroup:"))))
433785
+ invalidate();
433786
+ };
433787
+ const onDestroy = () => drop(state);
433788
+ const state = {
433789
+ scope,
433790
+ snapshot: null,
433791
+ indices: new Map,
433792
+ boundaries: new Map,
433793
+ dirty: new Set,
433794
+ dispose() {
433795
+ scope.blocks.unobserveDeep(onBlocks);
433796
+ scope.order.unobserveDeep(invalidate);
433797
+ scope.meta.unobserveDeep(onMeta);
433798
+ scope.doc.off("destroy", onDestroy);
433799
+ }
433800
+ };
433801
+ scope.blocks.observeDeep(onBlocks);
433802
+ scope.order.observeDeep(invalidate);
433803
+ scope.meta.observeDeep(onMeta);
433804
+ scope.doc.on("destroy", onDestroy);
433805
+ return state;
433806
+ }
433807
+ function read2(target) {
433808
+ const scope = resolveStoryShardScope(target);
433809
+ if (scope.meta.get(STORY_META_KEY.storyKind) !== STORY_KIND.main)
433810
+ return snapshotStoryShard(target);
433811
+ if (scope.doc._transaction || scope.doc._transactionCleanups.length > 0)
433812
+ return snapshotStoryShard(target);
433813
+ let state = stories.get(scope.blocks);
433814
+ if (state && (state.scope.meta !== scope.meta || state.scope.order !== scope.order || state.scope.tables !== scope.tables || state.scope.doc !== scope.doc)) {
433815
+ drop(state);
433816
+ state = undefined;
433817
+ }
433818
+ if (!state) {
433819
+ state = create10(scope);
433820
+ stories.set(scope.blocks, state);
433821
+ }
433822
+ if (state.snapshot && state.dirty.size) {
433823
+ const blocks = [...state.snapshot.blocks];
433824
+ for (const carrier of state.dirty) {
433825
+ const index2 = state.indices.get(carrier);
433826
+ const previous3 = index2 === undefined ? undefined : blocks[index2];
433827
+ if (!previous3 || carrier.get(BLOCK_KEY.blockId) !== previous3.blockId || carrier.get(BLOCK_KEY.mergedIntoBlockId)) {
433828
+ state.snapshot = null;
433829
+ break;
433830
+ }
433831
+ const block = snapshotBlock(carrier);
433832
+ const boundary = state.boundaries.get(carrier);
433833
+ blocks[index2] = boundary.suffix === undefined && !boundary.prefix ? block : {
433834
+ ...block,
433835
+ leadingXml: block.leadingXml + boundary.prefix,
433836
+ trailingXml: boundary.suffix
433837
+ };
433838
+ }
433839
+ if (state.snapshot)
433840
+ state.snapshot = { meta: readMeta(scope), blocks };
433841
+ }
433842
+ state.dirty.clear();
433843
+ if (!state.snapshot) {
433844
+ state.indices.clear();
433845
+ state.boundaries.clear();
433846
+ const snapshot3 = snapshotStoryShard(scope);
433847
+ if (snapshot3.blocks.length !== scope.blocks.length || snapshot3.blocks.some((block) => block.mergedIntoBlockId || block.mergedTailBlockIds.length)) {
433848
+ return snapshot3;
433849
+ }
433850
+ const indices = new Map;
433851
+ for (const [index2, block] of snapshot3.blocks.entries()) {
433852
+ const carrier = findBlockById(scope, block.blockId);
433853
+ if (!carrier || indices.has(carrier))
433854
+ return snapshot3;
433855
+ const leading = String(carrier.get(BLOCK_KEY.leadingXml) ?? "");
433856
+ if (!block.leadingXml.startsWith(leading))
433857
+ return snapshot3;
433858
+ state.boundaries.set(carrier, {
433859
+ prefix: block.leadingXml.slice(leading.length),
433860
+ suffix: block.trailingXml
433861
+ });
433862
+ indices.set(carrier, index2);
433863
+ }
433864
+ state.indices = indices;
433865
+ state.snapshot = snapshot3;
433866
+ }
433867
+ return { meta: readMeta(scope), blocks: state.snapshot.blocks };
433868
+ }
433869
+ return {
433870
+ read: read2,
433871
+ retain(targets) {
433872
+ const live = new Set(targets.map((target) => resolveStoryShardScope(target).blocks));
433873
+ for (const state of stories.values())
433874
+ if (!live.has(state.scope.blocks))
433875
+ drop(state);
433876
+ },
433877
+ dispose() {
433878
+ for (const state of stories.values())
433879
+ drop(state);
433880
+ }
433881
+ };
433882
+ }
433883
+ var init_story_snapshot_reader = __esm(() => {
433884
+ init_yjs();
433885
+ init_constants4();
433886
+ init_read_view();
433887
+ init_scope3();
433888
+ });
433889
+
433275
433890
  // ../../../v2/collaboration-v2/dist/projection/runtime.js
433276
433891
  function createCollabV2ProjectionRuntime(options) {
433892
+ const storySnapshots = createProjectionStorySnapshotReader();
433277
433893
  let freshness = PROJECTION_FRESHNESS.dirty;
433278
433894
  let blockingReason = null;
433279
433895
  let lastCleanSnapshot = null;
@@ -433335,12 +433951,14 @@ function createCollabV2ProjectionRuntime(options) {
433335
433951
  function materialize(snapshotToken) {
433336
433952
  const currentImport = getPackagePartsMap(options.rootDoc);
433337
433953
  const replaced = currentImport !== projectedImport;
433954
+ storySnapshots.retain(options.shardRegistry.listStories().map(shardReadTarget));
433338
433955
  const output = materializeProjection({
433339
433956
  snapshotToken,
433340
433957
  rootDoc: options.rootDoc,
433341
433958
  shardRegistry: options.shardRegistry,
433342
433959
  dirty: pendingDirty,
433343
- previousRecord: replaced ? null : lastCleanRecord
433960
+ previousRecord: replaced ? null : lastCleanRecord,
433961
+ readStorySnapshot: storySnapshots.read
433344
433962
  });
433345
433963
  projectedImport = currentImport;
433346
433964
  if (output.fullPackageRebuild)
@@ -433594,6 +434212,7 @@ function createCollabV2ProjectionRuntime(options) {
433594
434212
  hasCollabMutation = true;
433595
434213
  },
433596
434214
  reset() {
434215
+ storySnapshots.dispose();
433597
434216
  pendingDirty = [];
433598
434217
  diagnostics = [];
433599
434218
  freshness = PROJECTION_FRESHNESS.dirty;
@@ -433621,6 +434240,7 @@ function createCollabV2ProjectionRuntime(options) {
433621
434240
  return freshness === PROJECTION_FRESHNESS.clean && pendingDirty.length === 0;
433622
434241
  },
433623
434242
  dispose() {
434243
+ storySnapshots.dispose();
433624
434244
  disposed = true;
433625
434245
  freshness = PROJECTION_FRESHNESS.invalid;
433626
434246
  blockingReason = PROJECTION_BLOCKING_REASON.disposed;
@@ -433679,6 +434299,7 @@ var init_runtime5 = __esm(() => {
433679
434299
  init_checkpoint();
433680
434300
  init_reducer();
433681
434301
  init_schema3();
434302
+ init_story_snapshot_reader();
433682
434303
  DEFAULT_BYTES_ENCODER = {
433683
434304
  encode: encodeProjectionAsBytes
433684
434305
  };
@@ -437065,8 +437686,8 @@ function applyPreflightedTrackedTextDecisionsToStory(input) {
437065
437686
  tx.meta.set(ACTOR_ATTRIBUTION_META_KEY, input.actorType);
437066
437687
  scope.meta.set(STORY_META_KEY.lastEditActorType, input.actorType);
437067
437688
  const { decision, doc: doc2, removedCommentCarrierIds, resolved, work } = input.plan;
437068
- for (const { target, span, block } of work) {
437069
- removeTrackedTextCarriers(block, span, decision === "reject" && target.carrierKind === "field-insertion");
437689
+ for (const { span, block } of work) {
437690
+ removeTrackedTextCarriers(block, span, decision === "reject" && span.trackedKind === "ins");
437070
437691
  removeCommentCarriersByIds(block, removedCommentCarrierIds);
437071
437692
  }
437072
437693
  const sorted = [...work].sort((left, right) => {
@@ -437083,12 +437704,12 @@ function applyPreflightedTrackedTextDecisionsToStory(input) {
437083
437704
  if (span.trackedKind === "ins" && decision === "reject") {
437084
437705
  const length3 = span.endOffset - span.startOffset;
437085
437706
  if (length3 > 0) {
437086
- deleteText2({
437087
- doc: doc2,
437088
- blockId: span.blockId,
437707
+ deleteTextAtResolvedTarget({
437708
+ target: resolveStoryTextMutationTarget(doc2, span.blockId),
437089
437709
  offset: span.startOffset,
437090
437710
  length: length3,
437091
- origin: STORY_SURFACE_BACKEND_ORIGIN
437711
+ origin: STORY_SURFACE_BACKEND_ORIGIN,
437712
+ preserveZeroLengthAtStart: true
437092
437713
  });
437093
437714
  }
437094
437715
  }
@@ -437456,8 +438077,19 @@ function validateCompareApplySessionSync(prepared, extension2, options) {
437456
438077
  if (!extension2.storyLocal || prepared.resolvedTargets.stories.length !== 1 || String(prepared.resolvedTargets.stories[0]) !== storyId || ownership.length !== 1 || String(ownership[0]?.storyId) !== storyId || prepared.resolvedTargets.partUris.length !== 1 || String(prepared.resolvedTargets.partUris[0]) !== String(ownership[0]?.partUri)) {
437457
438078
  return { ok: false, message: "compareApply collaboration requires one owned story part" };
437458
438079
  }
437459
- if (source.bodySteps.length === 0 || source.bodySteps.some((step3) => step3.kind !== "edit") || source.storyGroups?.length || source.storyPackageOperations?.length || source.commentSteps?.length || source.packageRewrites?.length || source.relationshipBackedBodyRewrites?.length || source.headerFooterLifecycle || source.headerFooterSlotSteps?.length || source.tableTopologySteps?.length || source.tableBlockSteps?.length || source.tablePropertySteps?.length || source.sectionReplaySteps?.length || source.referenceReplaySteps?.length) {
437460
- return { ok: false, message: "compareApply collaboration supports paragraph text edits only" };
438080
+ if (source.bodySteps.length === 0 || source.bodySteps.some((step3) => {
438081
+ if (step3.kind === "edit")
438082
+ return false;
438083
+ if (step3.kind !== "formatEdit" || step3.targetRunXml === undefined)
438084
+ return true;
438085
+ if (extension2.historyReplay)
438086
+ return false;
438087
+ const bytes = getSDDocumentSessionInternalPartBytes(options.session, String(ownership[0].partUri));
438088
+ const entry = getSDDocumentSessionInternalStoryParagraphIndex(options.session, source.storyId)?.byParaId(step3.blockId);
438089
+ const proof = bytes && entry && inspectInlineControlCompareBodyReplay(bytes, entry.byteStart, entry.byteEnd, step3.targetRunXml);
438090
+ return !proof || proof.inserted.length === 0;
438091
+ }) || source.storyGroups?.length || source.storyPackageOperations?.length || source.commentSteps?.length || source.packageRewrites?.length || source.relationshipBackedBodyRewrites?.length || source.headerFooterLifecycle || source.headerFooterSlotSteps?.length || source.tableTopologySteps?.length || source.tableBlockSteps?.length || source.tablePropertySteps?.length || source.sectionReplaySteps?.length || source.referenceReplaySteps?.length) {
438092
+ return { ok: false, message: "compareApply collaboration supports paragraph text edits and proved inline control wrapping only" };
437461
438093
  }
437462
438094
  const targetBlockIds2 = [...new Set(source.bodySteps.map((step3) => step3.blockId))];
437463
438095
  if (targetBlockIds2.length !== extension2.targetBlockIds.length || targetBlockIds2.some((blockId) => !extension2.targetBlockIds.includes(blockId))) {
@@ -438769,6 +439401,7 @@ function atomOverlapsRange(atomOffset, atomLength, rangeStart, rangeEnd) {
438769
439401
  var STORY_SURFACE_TRACE, TRACKED_CHANGE_DECISIONS_LEDGER_KEY = "trackedChangeDecisions", CLEARED_RUN_ATTRIBUTES;
438770
439402
  var init_story_surface_execution_backend = __esm(() => {
438771
439403
  init_yjs();
439404
+ init_sd_document_session_internal();
438772
439405
  init_scope3();
438773
439406
  init_content_control_groups();
438774
439407
  init_story_surface_session_sync();
@@ -439528,7 +440161,7 @@ function createCollabV2SessionProjectionController(options) {
439528
440161
  };
439529
440162
  }
439530
440163
  const forceStoryBytes = input.forceStoryBytes === true || sessionStoryAlignment === "room-realignment-required" && (remoteProjectionPending || deferredSessionAuthoritativeRemotePending);
439531
- if (!packageReplaced && !input.forceApply && !forceStoryBytes && lastAppliedRecord?.digest === record3.digest) {
440164
+ if (!packageReplaced && !input.forceApply && !forceStoryBytes && lastAppliedRecord === record3) {
439532
440165
  return { ok: true };
439533
440166
  }
439534
440167
  const tBuild = projectionTraceNow();