@superdoc-dev/cli 0.17.0-next.34 → 0.17.0-next.35

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 +2227 -922
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -6278,7 +6278,7 @@ More content with **bold** and *italic*.`
6278
6278
  },
6279
6279
  "footnotes.insert": {
6280
6280
  memberPath: "footnotes.insert",
6281
- description: `Insert a new footnote or endnote at a target location.${FOOTNOTE_STRUCTURED_BODY_V1_NOTE}`,
6281
+ description: `Insert a new footnote or endnote at a target location or the current selection.${FOOTNOTE_STRUCTURED_BODY_V1_NOTE}`,
6282
6282
  expectedResult: "Returns a FootnoteMutationResult indicating success with the footnote address or a failure.",
6283
6283
  requiresDocumentContext: true,
6284
6284
  metadata: mutationOperation({
@@ -14966,12 +14966,12 @@ var init_schemas = __esm(() => {
14966
14966
  "footnotes.insert": {
14967
14967
  input: {
14968
14968
  oneOf: [
14969
- objectSchema({ at: textTargetSchema, type: { enum: ["footnote", "endnote"] }, content: { type: "string" } }, ["at", "type", "content"]),
14969
+ objectSchema({ at: textTargetSchema, type: { enum: ["footnote", "endnote"] }, content: { type: "string" } }, ["type", "content"]),
14970
14970
  objectSchema({
14971
14971
  at: textTargetSchema,
14972
14972
  type: { enum: ["footnote", "endnote"] },
14973
14973
  body: { ...sdFragmentSchema, description: "Structured SDM/1 note body." }
14974
- }, ["at", "type", "body"])
14974
+ }, ["type", "body"])
14975
14975
  ]
14976
14976
  },
14977
14977
  ...footnoteMutation
@@ -69059,7 +69059,7 @@ var init_remark_gfm_BUJjZJLy_es = __esm(() => {
69059
69059
  emptyOptions2 = {};
69060
69060
  });
69061
69061
 
69062
- // ../../packages/superdoc/dist/chunks/SuperConverter-0i3YuAr2.es.js
69062
+ // ../../packages/superdoc/dist/chunks/SuperConverter-Bdmhv7BA.es.js
69063
69063
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
69064
69064
  const fieldValue = extension$1.config[field];
69065
69065
  if (typeof fieldValue === "function")
@@ -91872,7 +91872,7 @@ function isPartCacheStale(editor, partId) {
91872
91872
  function clearPartCacheStale(editor, partId) {
91873
91873
  stalePartIds.get(editor)?.delete(partId);
91874
91874
  }
91875
- function getConverter$9(editor) {
91875
+ function getConverter$10(editor) {
91876
91876
  return editor.converter;
91877
91877
  }
91878
91878
  function closeUndoGroup(editor) {
@@ -91990,7 +91990,7 @@ function rollback(editor, entries2) {
91990
91990
  }
91991
91991
  }
91992
91992
  function runPostCommitSideEffects(editor, outcomes, operations, source) {
91993
- const converter = getConverter$9(editor);
91993
+ const converter = getConverter$10(editor);
91994
91994
  if (converter) {
91995
91995
  converter.documentModified = true;
91996
91996
  if (!converter.documentGuid && typeof converter.promoteToGuid === "function")
@@ -92881,7 +92881,7 @@ function cloneListDefinitionWithLevelStyle(numbering, sourceNumId, ilvl, options
92881
92881
  newAbstractId
92882
92882
  };
92883
92883
  }
92884
- function getConverter$8(editor) {
92884
+ function getConverter$9(editor) {
92885
92885
  return editor.converter;
92886
92886
  }
92887
92887
  function syncNumberingToXmlTree(part, numbering) {
@@ -92932,7 +92932,7 @@ function rebuildNumberingIndexFromPart(converter, part) {
92932
92932
  function ensureTranslatedNumberingFresh(editor) {
92933
92933
  if (!isPartCacheStale(editor, NUMBERING_PART_ID))
92934
92934
  return;
92935
- const converter = getConverter$8(editor);
92935
+ const converter = getConverter$9(editor);
92936
92936
  if (!converter)
92937
92937
  return;
92938
92938
  try {
@@ -95644,7 +95644,7 @@ function subcontent(events, eventIndex) {
95644
95644
  }
95645
95645
  return gaps;
95646
95646
  }
95647
- function resolveContent(events) {
95647
+ function resolveContent$1(events) {
95648
95648
  subtokenize(events);
95649
95649
  return events;
95650
95650
  }
@@ -106233,14 +106233,14 @@ function textNodeToRun({ node: node3, positions, storyKey, defaultFont, defaultS
106233
106233
  function buildReferenceMarkerRun(displayText, params3) {
106234
106234
  const originalRun = buildOriginalReferenceRun(displayText, params3);
106235
106235
  if (hasExplicitBaselineShift(originalRun.baselineShift))
106236
- return copyReferencePmPositions(originalRun, params3);
106236
+ return withReferenceDataAttrs(copyReferencePmPositions(originalRun, params3), params3);
106237
106237
  const baseFontSize = resolveReferenceBaseFontSize(buildReferenceRunWithoutVerticalPositioning(displayText, params3), originalRun, params3.defaultSize);
106238
- return copyReferencePmPositions({
106238
+ return withReferenceDataAttrs(copyReferencePmPositions({
106239
106239
  ...originalRun,
106240
106240
  vertAlign: "superscript",
106241
106241
  baselineShift: undefined,
106242
106242
  fontSize: baseFontSize * SUBSCRIPT_SUPERSCRIPT_SCALE
106243
- }, params3);
106243
+ }, params3), params3);
106244
106244
  }
106245
106245
  function toUpperRoman(num) {
106246
106246
  if (num < 1 || num > 3999)
@@ -110704,11 +110704,11 @@ function toSectionPageNumbering(numbering) {
110704
110704
  function buildSectionId(index2) {
110705
110705
  return `section-${index2}`;
110706
110706
  }
110707
- function getConverter$7(editor) {
110707
+ function getConverter$8(editor) {
110708
110708
  return editor.converter;
110709
110709
  }
110710
110710
  function getBodySectPrFromEditor(editor) {
110711
- const converter = getConverter$7(editor);
110711
+ const converter = getConverter$8(editor);
110712
110712
  if (isSectPrElement(converter?.bodySectPr))
110713
110713
  return cloneXmlElement(converter.bodySectPr);
110714
110714
  const docAttrs = editor.state.doc.attrs ?? {};
@@ -110757,7 +110757,7 @@ function resolveAnalysisDoc(editor, paragraphs) {
110757
110757
  return buildAnalysisDocFromParagraphs(paragraphs);
110758
110758
  }
110759
110759
  function getSettingsRoot(editor) {
110760
- const settingsPart = getConverter$7(editor)?.convertedXml?.["word/settings.xml"];
110760
+ const settingsPart = getConverter$8(editor)?.convertedXml?.["word/settings.xml"];
110761
110761
  if (!settingsPart)
110762
110762
  return null;
110763
110763
  if (settingsPart.name === "w:settings")
@@ -110767,7 +110767,7 @@ function getSettingsRoot(editor) {
110767
110767
  return settingsPart.elements.find((entry) => entry.name === "w:settings") ?? null;
110768
110768
  }
110769
110769
  function readOddEvenHeadersFlag(editor) {
110770
- const converter = getConverter$7(editor);
110770
+ const converter = getConverter$8(editor);
110771
110771
  if (converter?.pageStyles?.alternateHeaders != null)
110772
110772
  return converter.pageStyles.alternateHeaders === true;
110773
110773
  const settingsRoot = getSettingsRoot(editor);
@@ -110953,11 +110953,11 @@ function readTargetSectPr(editor, projection) {
110953
110953
  return readParagraphSectPr(projection.target.node);
110954
110954
  return getBodySectPrFromEditor(editor);
110955
110955
  }
110956
- function getConverter$6(editor) {
110956
+ function getConverter$7(editor) {
110957
110957
  return editor.converter;
110958
110958
  }
110959
110959
  function takeSnapshot(editor, partIds) {
110960
- const converter = getConverter$6(editor);
110960
+ const converter = getConverter$7(editor);
110961
110961
  const partEntries = /* @__PURE__ */ new Map;
110962
110962
  if (converter?.convertedXml)
110963
110963
  for (const partId of partIds) {
@@ -110992,7 +110992,7 @@ function takeSnapshot(editor, partIds) {
110992
110992
  };
110993
110993
  }
110994
110994
  function restoreFromSnapshot(editor, snapshot2) {
110995
- const converter = getConverter$6(editor);
110995
+ const converter = getConverter$7(editor);
110996
110996
  if (!converter)
110997
110997
  return;
110998
110998
  if (converter.convertedXml)
@@ -111774,7 +111774,7 @@ function resolveEffectiveRef(sections, startSectionIndex, kind, variant) {
111774
111774
  resolvedVariant: resolved.matchedVariant
111775
111775
  };
111776
111776
  }
111777
- function getConverter$5(editor) {
111777
+ function getConverter$6(editor) {
111778
111778
  return editor.converter;
111779
111779
  }
111780
111780
  function setHeaderFooterRefMutation(sectPr, kind, variant, refId, converter, operationName, dryRun = false) {
@@ -111835,7 +111835,7 @@ function setLinkedToPreviousMutation(sectPr, projection, sections, kind, variant
111835
111835
  }
111836
111836
  };
111837
111837
  if (!dryRun && clearedRef) {
111838
- const converter$1 = getConverter$5(editor);
111838
+ const converter$1 = getConverter$6(editor);
111839
111839
  if (converter$1)
111840
111840
  reconcileVariantPointerOnClear(converter$1, kind, clearedRef);
111841
111841
  }
@@ -111872,12 +111872,12 @@ function setLinkedToPreviousMutation(sectPr, projection, sections, kind, variant
111872
111872
  };
111873
111873
  }
111874
111874
  setSectPrHeaderFooterRef(sectPr, kind, variant, explicitRefId);
111875
- const converter = getConverter$5(editor);
111875
+ const converter = getConverter$6(editor);
111876
111876
  if (converter)
111877
111877
  reconcileVariantPointerOnSet(converter, kind, variant, explicitRefId);
111878
111878
  }
111879
111879
  function createExplicitHeaderFooterReference(editor, input) {
111880
- if (!getConverter$5(editor))
111880
+ if (!getConverter$6(editor))
111881
111881
  return null;
111882
111882
  try {
111883
111883
  const { refId } = createHeaderFooterPart(editor, {
@@ -111915,7 +111915,7 @@ function reconcileVariantPointerOnClear(converter, kind, clearedRefId) {
111915
111915
  if (variantIds[key] === clearedRefId)
111916
111916
  variantIds[key] = null;
111917
111917
  }
111918
- function getConverter$4(editor) {
111918
+ function getConverter$5(editor) {
111919
111919
  return editor.converter;
111920
111920
  }
111921
111921
  function isHeaderPartId(partId) {
@@ -111950,7 +111950,7 @@ function ensureHeaderFooterDescriptor(partId, sectionId) {
111950
111950
  };
111951
111951
  },
111952
111952
  afterCommit(ctx) {
111953
- const converter = getConverter$4(ctx.editor);
111953
+ const converter = getConverter$5(ctx.editor);
111954
111954
  if (!converter)
111955
111955
  return;
111956
111956
  const resolvedSectionId = ctx.sectionId ?? sectionId;
@@ -111970,7 +111970,7 @@ function ensureHeaderFooterDescriptor(partId, sectionId) {
111970
111970
  refreshActiveSubEditors(converter, type, resolvedSectionId);
111971
111971
  },
111972
111972
  onDelete(ctx) {
111973
- const converter = getConverter$4(ctx.editor);
111973
+ const converter = getConverter$5(ctx.editor);
111974
111974
  if (!converter)
111975
111975
  return;
111976
111976
  const resolvedSectionId = ctx.sectionId ?? sectionId;
@@ -112020,7 +112020,7 @@ function registerHeaderFooterInvalidationHandler(partId) {
112020
112020
  } catch {}
112021
112021
  });
112022
112022
  }
112023
- function getConverter$3(editor) {
112023
+ function getConverter$4(editor) {
112024
112024
  return editor.converter;
112025
112025
  }
112026
112026
  function normalizeHeaderFooterPartPath(target = "") {
@@ -112033,7 +112033,7 @@ function getRelationshipElements(part) {
112033
112033
  return getRelationshipsRoot(part)?.elements ?? [];
112034
112034
  }
112035
112035
  function resolvePartIdFromRefId(editor, headerFooterRefId) {
112036
- const relsRoot = getConverter$3(editor)?.convertedXml?.["word/_rels/document.xml.rels"]?.elements?.find((el) => el.name === "Relationships");
112036
+ const relsRoot = getConverter$4(editor)?.convertedXml?.["word/_rels/document.xml.rels"]?.elements?.find((el) => el.name === "Relationships");
112037
112037
  if (!relsRoot?.elements)
112038
112038
  return null;
112039
112039
  for (const el of relsRoot.elements) {
@@ -112079,14 +112079,14 @@ function resolveHeaderFooterRId(partId, relsData, editor) {
112079
112079
  return rId;
112080
112080
  }
112081
112081
  if (editor) {
112082
- const localRels = getConverter$3(editor)?.convertedXml?.["word/_rels/document.xml.rels"];
112082
+ const localRels = getConverter$4(editor)?.convertedXml?.["word/_rels/document.xml.rels"];
112083
112083
  if (localRels)
112084
112084
  return resolveRIdFromRelsData(localRels, partId);
112085
112085
  }
112086
112086
  return null;
112087
112087
  }
112088
112088
  function exportSubEditorToPart(mainEditor, subEditor, headerFooterRefId, type) {
112089
- const converter = getConverter$3(mainEditor);
112089
+ const converter = getConverter$4(mainEditor);
112090
112090
  if (!converter?.exportToXmlJson)
112091
112091
  return false;
112092
112092
  const partId = resolvePartIdFromRefId(mainEditor, headerFooterRefId);
@@ -112152,7 +112152,7 @@ function exportSubEditorToPart(mainEditor, subEditor, headerFooterRefId, type) {
112152
112152
  }
112153
112153
  }
112154
112154
  function registerExistingHeaderFooterDescriptors(editor) {
112155
- const converter = getConverter$3(editor);
112155
+ const converter = getConverter$4(editor);
112156
112156
  if (!converter?.convertedXml)
112157
112157
  return;
112158
112158
  const relsRoot = converter.convertedXml["word/_rels/document.xml.rels"]?.elements?.find((el) => el.name === "Relationships");
@@ -112234,7 +112234,7 @@ function buildSectionMarginsForAttrs(sectPr) {
112234
112234
  };
112235
112235
  }
112236
112236
  function syncConverterBodySection(editor, sectPr) {
112237
- const converter = getConverter$2(editor);
112237
+ const converter = getConverter$3(editor);
112238
112238
  if (!converter)
112239
112239
  return;
112240
112240
  converter.bodySectPr = cloneXmlElement(sectPr);
@@ -112272,7 +112272,7 @@ function syncConverterBodySection(editor, sectPr) {
112272
112272
  if (margins.gutter !== undefined)
112273
112273
  pageMargins.gutter = margins.gutter;
112274
112274
  }
112275
- function getConverter$2(editor) {
112275
+ function getConverter$3(editor) {
112276
112276
  return editor.converter;
112277
112277
  }
112278
112278
  function applySectPrToProjection(editor, projection, sectPr, options) {
@@ -112408,12 +112408,12 @@ function ensureExplicitHeaderFooterSlot(editor, input) {
112408
112408
  }
112409
112409
  return result;
112410
112410
  }
112411
- function getConverter$1(editor) {
112411
+ function getConverter$2(editor) {
112412
112412
  return editor.converter;
112413
112413
  }
112414
112414
  function resolveHeaderFooterSlotRuntime(hostEditor, locator, options = {}) {
112415
112415
  const storyKey = buildStoryKey(locator);
112416
- const converter = getConverter$1(hostEditor);
112416
+ const converter = getConverter$2(hostEditor);
112417
112417
  if (!converter)
112418
112418
  throw new DocumentApiAdapterError("STORY_NOT_FOUND", `Cannot resolve header/footer slot: no converter available on the editor.`, { storyKey });
112419
112419
  const resolution = locator.resolution ?? "effective";
@@ -112489,7 +112489,7 @@ function buildSlotCommit(locator, storyEditor, sourceRefId, requiresLocalMateria
112489
112489
  }
112490
112490
  function resolveHeaderFooterPartRuntime(hostEditor, locator) {
112491
112491
  const storyKey = buildStoryKey(locator);
112492
- const converter = getConverter$1(hostEditor);
112492
+ const converter = getConverter$2(hostEditor);
112493
112493
  if (!converter)
112494
112494
  throw new DocumentApiAdapterError("STORY_NOT_FOUND", `Cannot resolve header/footer part: no converter available.`, { storyKey });
112495
112495
  const pmJson = findPmJsonByRefId(converter, locator.refId);
@@ -112525,7 +112525,7 @@ function resolveHeaderFooterPartRuntime(hostEditor, locator) {
112525
112525
  }
112526
112526
  function exportAndSyncCache(hostEditor, subEditor, refId, hfType) {
112527
112527
  exportSubEditorToPart(hostEditor, subEditor, refId, hfType);
112528
- const conv = getConverter$1(hostEditor);
112528
+ const conv = getConverter$2(hostEditor);
112529
112529
  if (!conv)
112530
112530
  return;
112531
112531
  const pmJson = typeof subEditor.getUpdatedJson === "function" ? subEditor.getUpdatedJson() : subEditor.getJSON?.();
@@ -112589,7 +112589,7 @@ function findPmJsonByRefId(converter, refId) {
112589
112589
  }
112590
112590
  return null;
112591
112591
  }
112592
- function getConverter(editor) {
112592
+ function getConverter$1(editor) {
112593
112593
  return editor.converter;
112594
112594
  }
112595
112595
  function getRootElement(part) {
@@ -112601,11 +112601,21 @@ function getNoteElements(part, childElementName) {
112601
112601
  return [];
112602
112602
  return root2.elements.filter((el) => el.name === childElementName);
112603
112603
  }
112604
- function textToNoteOoxmlParagraphs(text$2) {
112604
+ function textToNoteOoxmlParagraphs(text$2, childElementName) {
112605
+ const styleName = childElementName === "w:endnote" ? "EndnoteText" : "FootnoteText";
112606
+ const pPr = {
112607
+ type: "element",
112608
+ name: "w:pPr",
112609
+ elements: [{
112610
+ type: "element",
112611
+ name: "w:pStyle",
112612
+ attributes: { "w:val": styleName }
112613
+ }]
112614
+ };
112605
112615
  return text$2.split(/\r?\n/).map((line) => ({
112606
112616
  type: "element",
112607
112617
  name: "w:p",
112608
- elements: line.length > 0 ? [{
112618
+ elements: [structuredClone(pPr), ...line.length > 0 ? [{
112609
112619
  type: "element",
112610
112620
  name: "w:r",
112611
112621
  elements: [{
@@ -112617,7 +112627,7 @@ function textToNoteOoxmlParagraphs(text$2) {
112617
112627
  text: line
112618
112628
  }]
112619
112629
  }]
112620
- }] : []
112630
+ }] : []]
112621
112631
  }));
112622
112632
  }
112623
112633
  function ensureFootnoteRefRun(elements, childElementName) {
@@ -112664,7 +112674,7 @@ function addNoteElement(part, config$43, noteId, text$2) {
112664
112674
  root2.elements = [];
112665
112675
  if (root2.elements.find((el) => el.name === config$43.childElementName && el.attributes?.["w:id"] === noteId))
112666
112676
  throw new Error(`addNoteElement: note id "${noteId}" already exists in ${config$43.partId}`);
112667
- const paragraphs = textToNoteOoxmlParagraphs(text$2);
112677
+ const paragraphs = textToNoteOoxmlParagraphs(text$2, config$43.childElementName);
112668
112678
  ensureFootnoteRefRun(paragraphs, config$43.childElementName);
112669
112679
  const noteElement = {
112670
112680
  type: "element",
@@ -112679,23 +112689,13 @@ function updateNoteElement(part, config$43, noteId, text$2) {
112679
112689
  const target = getNoteElements(part, config$43.childElementName).find((el) => el.attributes?.["w:id"] === noteId);
112680
112690
  if (!target)
112681
112691
  return false;
112682
- const paragraphs = textToNoteOoxmlParagraphs(text$2);
112692
+ const paragraphs = textToNoteOoxmlParagraphs(text$2, config$43.childElementName);
112683
112693
  ensureFootnoteRefRun(paragraphs, config$43.childElementName);
112684
112694
  target.elements = paragraphs;
112685
112695
  return true;
112686
112696
  }
112687
- function removeNoteElement(part, config$43, noteId) {
112688
- const root2 = getRootElement(part);
112689
- if (!root2?.elements)
112690
- return false;
112691
- const index2 = root2.elements.findIndex((el) => el.name === config$43.childElementName && el.attributes?.["w:id"] === noteId);
112692
- if (index2 < 0)
112693
- return false;
112694
- root2.elements.splice(index2, 1);
112695
- return true;
112696
- }
112697
112697
  function rebuildDerivedCache(editor, config$43, part) {
112698
- const converter = getConverter(editor);
112698
+ const converter = getConverter$1(editor);
112699
112699
  if (!converter)
112700
112700
  return;
112701
112701
  if (typeof converter.reimportNotePart === "function")
@@ -112800,6 +112800,21 @@ function createNotePartDescriptor(config$43) {
112800
112800
  function getNotesConfig(type) {
112801
112801
  return type === "endnote" ? ENDNOTES_CONFIG : FOOTNOTES_CONFIG;
112802
112802
  }
112803
+ function markSessionManagedNoteId(editor, type, noteId) {
112804
+ const converter = editor.converter;
112805
+ if (!converter)
112806
+ return;
112807
+ if (!converter.sessionManagedNoteIds)
112808
+ converter.sessionManagedNoteIds = {
112809
+ footnotes: /* @__PURE__ */ new Set,
112810
+ endnotes: /* @__PURE__ */ new Set
112811
+ };
112812
+ converter.sessionManagedNoteIds[getNotesConfig(type).converterKey].add(String(noteId));
112813
+ editor.emit?.(NOTE_TOMBSTONE_EVENT, {
112814
+ type,
112815
+ noteId: String(noteId)
112816
+ });
112817
+ }
112803
112818
  function bootstrapNotesPart(editor, type) {
112804
112819
  const converter = editor.converter;
112805
112820
  if (!converter?.convertedXml)
@@ -112808,6 +112823,33 @@ function bootstrapNotesPart(editor, type) {
112808
112823
  if (converter.convertedXml[config$43.partId] !== undefined)
112809
112824
  return;
112810
112825
  converter.convertedXml[config$43.partId] = createInitialNotesPart(config$43);
112826
+ ensureSpecialNotesListInSettings(converter.convertedXml, config$43);
112827
+ }
112828
+ function ensureSpecialNotesListInSettings(convertedXml, config$43) {
112829
+ const settingsRoot = getRootElement(convertedXml["word/settings.xml"]);
112830
+ if (!settingsRoot)
112831
+ return;
112832
+ if (!settingsRoot.elements)
112833
+ settingsRoot.elements = [];
112834
+ const prName = config$43.childElementName === "w:endnote" ? "w:endnotePr" : "w:footnotePr";
112835
+ let pr = settingsRoot.elements.find((el) => el.name === prName);
112836
+ if (!pr) {
112837
+ pr = {
112838
+ type: "element",
112839
+ name: prName,
112840
+ elements: []
112841
+ };
112842
+ settingsRoot.elements.push(pr);
112843
+ }
112844
+ if (!pr.elements)
112845
+ pr.elements = [];
112846
+ for (const id2 of ["-1", "0"])
112847
+ if (!pr.elements.some((el) => el.name === config$43.childElementName && el.attributes?.["w:id"] === id2))
112848
+ pr.elements.push({
112849
+ type: "element",
112850
+ name: config$43.childElementName,
112851
+ attributes: { "w:id": id2 }
112852
+ });
112811
112853
  }
112812
112854
  function isPmJsonNode(value) {
112813
112855
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -112917,6 +112959,469 @@ function normalizeNotePmJson(docJson) {
112917
112959
  const normalized = normalizeNotePmNode(docJson);
112918
112960
  return isPmJsonNode(normalized) ? normalized : docJson;
112919
112961
  }
112962
+ function isSpecialEntry(entry) {
112963
+ return SPECIAL_NOTE_TYPES.has(entry.type ?? "");
112964
+ }
112965
+ function normalizeNoteId(entry) {
112966
+ return String(entry.id ?? "");
112967
+ }
112968
+ function findNoteEntryById(entries2, noteId) {
112969
+ if (!Array.isArray(entries2))
112970
+ return;
112971
+ let fallback;
112972
+ for (const entry of entries2) {
112973
+ if (String(entry.id ?? "") !== noteId)
112974
+ continue;
112975
+ if (!isSpecialEntry(entry))
112976
+ return entry;
112977
+ fallback ??= entry;
112978
+ }
112979
+ return fallback;
112980
+ }
112981
+ function enumerateEffectiveNoteEntries(entries2) {
112982
+ if (!Array.isArray(entries2))
112983
+ return [];
112984
+ const orderedIds = [];
112985
+ const effectiveById = /* @__PURE__ */ new Map;
112986
+ for (const entry of entries2) {
112987
+ const noteId = normalizeNoteId(entry);
112988
+ if (!effectiveById.has(noteId)) {
112989
+ orderedIds.push(noteId);
112990
+ effectiveById.set(noteId, entry);
112991
+ continue;
112992
+ }
112993
+ if (isSpecialEntry(effectiveById.get(noteId)) && !isSpecialEntry(entry))
112994
+ effectiveById.set(noteId, entry);
112995
+ }
112996
+ return orderedIds.map((noteId) => effectiveById.get(noteId));
112997
+ }
112998
+ function getConverterStore(editor) {
112999
+ return editor.converter ?? {};
113000
+ }
113001
+ function isLegacyFootnoteMap(value) {
113002
+ return value != null && typeof value === "object" && !Array.isArray(value);
113003
+ }
113004
+ function extractTextFromNode(node3) {
113005
+ if (node3 == null)
113006
+ return "";
113007
+ if (typeof node3 === "string")
113008
+ return node3;
113009
+ if (typeof node3 !== "object")
113010
+ return "";
113011
+ const candidate = node3;
113012
+ if (typeof candidate.text === "string")
113013
+ return candidate.text;
113014
+ if (!Array.isArray(candidate.content))
113015
+ return "";
113016
+ return candidate.content.map((child) => extractTextFromNode(child)).join("");
113017
+ }
113018
+ function extractTextFromContent(content$2) {
113019
+ if (typeof content$2 === "string")
113020
+ return content$2;
113021
+ if (!Array.isArray(content$2))
113022
+ return "";
113023
+ return content$2.map((node3) => extractTextFromNode(node3)).filter((text$2) => text$2.length > 0).join(`
113024
+ `);
113025
+ }
113026
+ function resolveCollectionContent(collection, noteId) {
113027
+ if (!collection)
113028
+ return "";
113029
+ if (Array.isArray(collection))
113030
+ return extractTextFromContent(findNoteEntryById(collection, noteId)?.content);
113031
+ if (isLegacyFootnoteMap(collection))
113032
+ return collection[noteId]?.content ?? "";
113033
+ return "";
113034
+ }
113035
+ function findAllFootnotes(doc$2, typeFilter) {
113036
+ const results = [];
113037
+ doc$2.descendants((node3, pos) => {
113038
+ if (node3.type.name === "footnoteReference") {
113039
+ if (!typeFilter || typeFilter === "footnote") {
113040
+ const noteId = String(node3.attrs?.id ?? "");
113041
+ results.push({
113042
+ node: node3,
113043
+ pos,
113044
+ noteId,
113045
+ type: "footnote"
113046
+ });
113047
+ }
113048
+ } else if (node3.type.name === "endnoteReference") {
113049
+ if (!typeFilter || typeFilter === "endnote") {
113050
+ const noteId = String(node3.attrs?.id ?? "");
113051
+ results.push({
113052
+ node: node3,
113053
+ pos,
113054
+ noteId,
113055
+ type: "endnote"
113056
+ });
113057
+ }
113058
+ }
113059
+ return true;
113060
+ });
113061
+ return results;
113062
+ }
113063
+ function resolveFootnoteTarget(doc$2, target) {
113064
+ const found$1 = findAllFootnotes(doc$2).find((f2) => f2.noteId === target.noteId);
113065
+ if (!found$1)
113066
+ throw new DocumentApiAdapterError("TARGET_NOT_FOUND", `Footnote/endnote with noteId "${target.noteId}" not found.`);
113067
+ return found$1;
113068
+ }
113069
+ function resolveDisplayNumber(editor, resolved) {
113070
+ const store = getConverterStore(editor);
113071
+ const numberMap = resolved.type === "footnote" ? store.footnoteNumberById : store.endnoteNumberById;
113072
+ if (numberMap && numberMap[resolved.noteId] !== undefined)
113073
+ return String(numberMap[resolved.noteId]);
113074
+ return resolved.noteId;
113075
+ }
113076
+ function resolveContent(editor, resolved) {
113077
+ const store = getConverterStore(editor);
113078
+ return resolveCollectionContent(resolved.type === "footnote" ? store.footnotes : store.endnotes, resolved.noteId);
113079
+ }
113080
+ function extractFootnoteInfo(editor, resolved) {
113081
+ return {
113082
+ address: {
113083
+ kind: "entity",
113084
+ entityType: "footnote",
113085
+ noteId: resolved.noteId
113086
+ },
113087
+ type: resolved.type,
113088
+ noteId: resolved.noteId,
113089
+ displayNumber: resolveDisplayNumber(editor, resolved),
113090
+ content: resolveContent(editor, resolved)
113091
+ };
113092
+ }
113093
+ function buildFootnoteDiscoveryItem(editor, resolved, evaluatedRevision) {
113094
+ const domain2 = {
113095
+ address: {
113096
+ kind: "entity",
113097
+ entityType: "footnote",
113098
+ noteId: resolved.noteId
113099
+ },
113100
+ type: resolved.type,
113101
+ noteId: resolved.noteId,
113102
+ displayNumber: resolveDisplayNumber(editor, resolved),
113103
+ content: resolveContent(editor, resolved)
113104
+ };
113105
+ const handle2 = buildResolvedHandle(resolved.noteId, "stable", "node");
113106
+ return buildDiscoveryItem(`footnote:${resolved.noteId}:${evaluatedRevision}`, handle2, domain2);
113107
+ }
113108
+ function footnoteSuccess(address2) {
113109
+ return {
113110
+ success: true,
113111
+ footnote: address2
113112
+ };
113113
+ }
113114
+ function footnoteFailure(code$1, message) {
113115
+ return {
113116
+ success: false,
113117
+ failure: {
113118
+ code: code$1,
113119
+ message
113120
+ }
113121
+ };
113122
+ }
113123
+ function configSuccess() {
113124
+ return { success: true };
113125
+ }
113126
+ function getConverter(editor) {
113127
+ const converter = editor.converter;
113128
+ if (!converter)
113129
+ throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", "converter not available.");
113130
+ return converter;
113131
+ }
113132
+ function toNonNegativeInteger(value) {
113133
+ const num = Number(value);
113134
+ if (!Number.isInteger(num) || !Number.isFinite(num) || num < 0)
113135
+ return null;
113136
+ return num;
113137
+ }
113138
+ function collectUsedNoteIds(editor, converter, type) {
113139
+ const used = /* @__PURE__ */ new Set;
113140
+ const config$43 = getNotesConfig(type);
113141
+ for (const ref2 of findAllFootnotes(editor.state.doc, type)) {
113142
+ const parsed = toNonNegativeInteger(ref2.noteId);
113143
+ if (parsed != null)
113144
+ used.add(parsed);
113145
+ }
113146
+ const ooxmlPart = converter.convertedXml?.[config$43.partId];
113147
+ if (ooxmlPart)
113148
+ for (const el of getNoteElements(ooxmlPart, config$43.childElementName)) {
113149
+ const parsed = toNonNegativeInteger(el.attributes?.["w:id"]);
113150
+ if (parsed != null)
113151
+ used.add(parsed);
113152
+ }
113153
+ const cache = converter[config$43.converterKey];
113154
+ if (Array.isArray(cache))
113155
+ for (const entry of cache) {
113156
+ const parsed = toNonNegativeInteger(entry.id);
113157
+ if (parsed != null)
113158
+ used.add(parsed);
113159
+ }
113160
+ return used;
113161
+ }
113162
+ function allocateNextNoteId(editor, converter, type) {
113163
+ const used = collectUsedNoteIds(editor, converter, type);
113164
+ let candidate = 1;
113165
+ while (used.has(candidate))
113166
+ candidate += 1;
113167
+ return String(candidate);
113168
+ }
113169
+ function footnotesListWrapper(editor, query2) {
113170
+ const doc$2 = editor.state.doc;
113171
+ const revision = getRevision(editor);
113172
+ const { total, items: paged } = paginate(findAllFootnotes(doc$2, query2?.type).map((f2) => buildFootnoteDiscoveryItem(editor, f2, revision)), query2?.offset, query2?.limit);
113173
+ return buildDiscoveryResult({
113174
+ evaluatedRevision: revision,
113175
+ total,
113176
+ items: paged,
113177
+ page: {
113178
+ limit: query2?.limit ?? total,
113179
+ offset: query2?.offset ?? 0,
113180
+ returned: paged.length
113181
+ }
113182
+ });
113183
+ }
113184
+ function footnotesGetWrapper(editor, input) {
113185
+ return extractFootnoteInfo(editor, resolveFootnoteTarget(editor.state.doc, input.target));
113186
+ }
113187
+ function footnotesInsertWrapper(editor, input, options) {
113188
+ rejectTrackedMode("footnotes.insert", options);
113189
+ checkRevision(editor, options?.expectedRevision);
113190
+ if (editor.options?.parentEditor)
113191
+ return footnoteFailure("INVALID_TARGET", "footnotes.insert: footnotes can only be inserted into the document body, not inside a footnote, endnote, header, or footer.");
113192
+ if (input.at === undefined) {
113193
+ if (editor.presentationEditor?.getActiveStoryLocator?.() != null)
113194
+ return footnoteFailure("INVALID_TARGET", 'footnotes.insert: cannot insert at the cursor while a header, footer, footnote, or endnote is being edited. Exit the active story or pass an explicit "at" target.');
113195
+ }
113196
+ const converter = getConverter(editor);
113197
+ const notesConfig = getNotesConfig(input.type);
113198
+ const noteId = allocateNextNoteId(editor, converter, input.type);
113199
+ const address2 = {
113200
+ kind: "entity",
113201
+ entityType: "footnote",
113202
+ noteId
113203
+ };
113204
+ if (input.body !== undefined)
113205
+ return footnoteFailure("CAPABILITY_UNAVAILABLE", "footnotes.insert structured body content is only available on v2-backed sessions.");
113206
+ if (options?.dryRun)
113207
+ return footnoteSuccess(address2);
113208
+ const nodeTypeName = input.type === "endnote" ? "endnoteReference" : "footnoteReference";
113209
+ const nodeType = editor.schema.nodes[nodeTypeName];
113210
+ if (!nodeType)
113211
+ throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", `footnotes.insert: node type "${nodeTypeName}" is not registered in the schema.`);
113212
+ const resolved = input.at ? resolveInlineInsertPosition(editor, input.at, "footnotes.insert") : {
113213
+ from: editor.state.selection.head,
113214
+ to: editor.state.selection.head
113215
+ };
113216
+ const { success } = compoundMutation({
113217
+ editor,
113218
+ source: `footnotes.insert:${input.type}`,
113219
+ affectedParts: [notesConfig.partId],
113220
+ execute: () => {
113221
+ bootstrapNotesPart(editor, input.type);
113222
+ mutatePart({
113223
+ editor,
113224
+ partId: notesConfig.partId,
113225
+ operation: "mutate",
113226
+ source: `footnotes.insert:${input.type}`,
113227
+ mutate({ part }) {
113228
+ addNoteElement(part, notesConfig, noteId, input.content);
113229
+ }
113230
+ });
113231
+ const node3 = nodeType.create({ id: noteId });
113232
+ const { tr } = editor.state;
113233
+ tr.insert(resolved.from, node3);
113234
+ editor.dispatch(tr);
113235
+ markSessionManagedNoteId(editor, input.type, noteId);
113236
+ clearIndexCache(editor);
113237
+ return true;
113238
+ }
113239
+ });
113240
+ if (!success)
113241
+ return footnoteFailure("NO_OP", "Insert operation produced no change.");
113242
+ return footnoteSuccess(address2);
113243
+ }
113244
+ function footnotesUpdateWrapper(editor, input, options) {
113245
+ rejectTrackedMode("footnotes.update", options);
113246
+ const resolved = resolveFootnoteTarget(editor.state.doc, input.target);
113247
+ const address2 = {
113248
+ kind: "entity",
113249
+ entityType: "footnote",
113250
+ noteId: resolved.noteId
113251
+ };
113252
+ if (input.patch.body !== undefined)
113253
+ return footnoteFailure("CAPABILITY_UNAVAILABLE", "footnotes.update structured body content is only available on v2-backed sessions.");
113254
+ if (options?.dryRun || input.patch.content === undefined)
113255
+ return footnoteSuccess(address2);
113256
+ const notesConfig = getNotesConfig(resolved.type);
113257
+ mutatePart({
113258
+ editor,
113259
+ partId: notesConfig.partId,
113260
+ operation: "mutate",
113261
+ source: `footnotes.update:${resolved.type}`,
113262
+ expectedRevision: options?.expectedRevision,
113263
+ mutate({ part }) {
113264
+ updateNoteElement(part, notesConfig, resolved.noteId, input.patch.content);
113265
+ }
113266
+ });
113267
+ return footnoteSuccess(address2);
113268
+ }
113269
+ function footnotesRemoveWrapper(editor, input, options) {
113270
+ rejectTrackedMode("footnotes.remove", options);
113271
+ checkRevision(editor, options?.expectedRevision);
113272
+ const resolved = resolveFootnoteTarget(editor.state.doc, input.target);
113273
+ const address2 = {
113274
+ kind: "entity",
113275
+ entityType: "footnote",
113276
+ noteId: resolved.noteId
113277
+ };
113278
+ if (options?.dryRun)
113279
+ return footnoteSuccess(address2);
113280
+ if (!removeNoteReferenceAt(editor, {
113281
+ pos: resolved.pos,
113282
+ noteId: resolved.noteId,
113283
+ type: resolved.type
113284
+ }))
113285
+ return footnoteFailure("NO_OP", "Remove operation produced no change.");
113286
+ return footnoteSuccess(address2);
113287
+ }
113288
+ function removeNoteReferenceAt(editor, ref2) {
113289
+ const notesConfig = getNotesConfig(ref2.type);
113290
+ const { success } = compoundMutation({
113291
+ editor,
113292
+ source: `footnotes.remove:${ref2.type}`,
113293
+ affectedParts: [notesConfig.partId],
113294
+ execute: () => {
113295
+ const { tr } = editor.state;
113296
+ const node3 = tr.doc.nodeAt(ref2.pos);
113297
+ if (!node3)
113298
+ return false;
113299
+ tr.delete(ref2.pos, ref2.pos + node3.nodeSize);
113300
+ editor.dispatch(tr);
113301
+ markSessionManagedNoteId(editor, ref2.type, ref2.noteId);
113302
+ clearIndexCache(editor);
113303
+ return true;
113304
+ }
113305
+ });
113306
+ if (success)
113307
+ closeUndoGroup(editor);
113308
+ return success;
113309
+ }
113310
+ function removeNoteEverywhere(editor, input) {
113311
+ const refs = findAllFootnotes(editor.state.doc, input.type).filter((f2) => f2.noteId === input.noteId);
113312
+ if (refs.length === 0)
113313
+ return footnoteFailure("NO_OP", `No ${input.type} reference with id "${input.noteId}" found.`);
113314
+ const notesConfig = getNotesConfig(input.type);
113315
+ const address2 = {
113316
+ kind: "entity",
113317
+ entityType: "footnote",
113318
+ noteId: input.noteId
113319
+ };
113320
+ const { success } = compoundMutation({
113321
+ editor,
113322
+ source: `footnotes.removeEverywhere:${input.type}`,
113323
+ affectedParts: [notesConfig.partId],
113324
+ execute: () => {
113325
+ const { tr } = editor.state;
113326
+ [...refs].sort((a, b) => b.pos - a.pos).forEach((ref2) => {
113327
+ const node3 = tr.doc.nodeAt(ref2.pos);
113328
+ if (node3)
113329
+ tr.delete(ref2.pos, ref2.pos + node3.nodeSize);
113330
+ });
113331
+ try {
113332
+ tr.setSelection(Selection.near(tr.doc.resolve(Math.min(refs[0].pos, tr.doc.content.size)), 1));
113333
+ } catch {}
113334
+ editor.dispatch(tr);
113335
+ markSessionManagedNoteId(editor, input.type, input.noteId);
113336
+ clearIndexCache(editor);
113337
+ return true;
113338
+ }
113339
+ });
113340
+ if (!success)
113341
+ return footnoteFailure("NO_OP", "Remove operation produced no change.");
113342
+ closeUndoGroup(editor);
113343
+ return footnoteSuccess(address2);
113344
+ }
113345
+ function footnotesConfigureWrapper(editor, input, options) {
113346
+ rejectTrackedMode("footnotes.configure", options);
113347
+ const prElementName = input.type === "endnote" ? "w:endnotePr" : "w:footnotePr";
113348
+ mutatePart({
113349
+ editor,
113350
+ partId: "word/settings.xml",
113351
+ operation: "mutate",
113352
+ source: `footnotes.configure:${input.type}`,
113353
+ dryRun: options?.dryRun,
113354
+ expectedRevision: options?.expectedRevision,
113355
+ mutate({ part }) {
113356
+ const root2 = part?.elements?.[0];
113357
+ if (!root2)
113358
+ return;
113359
+ if (!root2.elements)
113360
+ root2.elements = [];
113361
+ const elements = root2.elements;
113362
+ let prElement = elements.find((el) => el.name === prElementName);
113363
+ if (!prElement) {
113364
+ prElement = {
113365
+ type: "element",
113366
+ name: prElementName,
113367
+ elements: []
113368
+ };
113369
+ elements.push(prElement);
113370
+ }
113371
+ if (!prElement.elements)
113372
+ prElement.elements = [];
113373
+ if (!input.numbering)
113374
+ return;
113375
+ const setOrRemoveChild = (name, value) => {
113376
+ if (value === undefined)
113377
+ return;
113378
+ const children = prElement.elements;
113379
+ const existing = children.findIndex((el) => el.name === name);
113380
+ const newEl = {
113381
+ type: "element",
113382
+ name,
113383
+ attributes: { "w:val": value }
113384
+ };
113385
+ if (existing >= 0)
113386
+ children[existing] = newEl;
113387
+ else
113388
+ children.push(newEl);
113389
+ };
113390
+ setOrRemoveChild("w:numFmt", input.numbering.format);
113391
+ setOrRemoveChild("w:numStart", input.numbering.start !== undefined ? String(input.numbering.start) : undefined);
113392
+ if (input.numbering.restartPolicy !== undefined)
113393
+ setOrRemoveChild("w:numRestart", RESTART_POLICY_TO_OOXML[input.numbering.restartPolicy] ?? input.numbering.restartPolicy);
113394
+ setOrRemoveChild("w:pos", input.numbering.position);
113395
+ }
113396
+ });
113397
+ if (!options?.dryRun && prElementName === "w:footnotePr")
113398
+ syncFootnotePropertiesCache(editor);
113399
+ return configSuccess();
113400
+ }
113401
+ function syncFootnotePropertiesCache(editor) {
113402
+ const converter = getConverter(editor);
113403
+ if (!converter?.footnoteProperties || converter.footnoteProperties.source !== "settings")
113404
+ return;
113405
+ const prElement = (converter.convertedXml?.["word/settings.xml"]?.elements?.[0]?.elements ?? []).find((el) => el.name === "w:footnotePr");
113406
+ if (prElement)
113407
+ converter.footnoteProperties.originalXml = structuredClone(prElement);
113408
+ else
113409
+ converter.footnoteProperties = null;
113410
+ }
113411
+ function isNoteContentEmpty(doc$2) {
113412
+ let hasContent2 = false;
113413
+ doc$2.descendants((node3) => {
113414
+ if (hasContent2)
113415
+ return false;
113416
+ if (node3.isText) {
113417
+ if ((node3.text ?? "").trim().length > 0)
113418
+ hasContent2 = true;
113419
+ } else if (node3.isAtom && node3.type.name !== "text")
113420
+ hasContent2 = true;
113421
+ return !hasContent2;
113422
+ });
113423
+ return !hasContent2;
113424
+ }
112920
113425
  function resolveNoteRuntime(hostEditor, locator) {
112921
113426
  const storyKey = buildStoryKey(locator);
112922
113427
  const converter = hostEditor.converter;
@@ -112951,34 +113456,63 @@ function resolveNoteRuntime(hostEditor, locator) {
112951
113456
  }
112952
113457
  function commitNoteRuntime(hostEditor, storyEditor, locator, isFootnote) {
112953
113458
  const notesConfig = getNotesConfig(isFootnote ? "footnote" : "endnote");
112954
- const conv = hostEditor.converter;
112955
- const pmJson = typeof storyEditor.getUpdatedJson === "function" ? storyEditor.getUpdatedJson() : storyEditor.getJSON();
112956
- if (conv?.exportToXmlJson && pmJson) {
112957
- let ooxmlElements = null;
112958
- try {
112959
- const { result } = conv.exportToXmlJson({
112960
- data: pmJson,
112961
- editor: storyEditor,
112962
- editorSchema: storyEditor.schema,
112963
- isHeaderFooter: true,
112964
- comments: [],
112965
- commentDefinitions: []
112966
- });
112967
- ooxmlElements = result?.elements?.[0]?.elements ?? null;
112968
- } catch {}
112969
- if (ooxmlElements && ooxmlElements.length > 0) {
112970
- mutatePart({
112971
- editor: hostEditor,
112972
- partId: notesConfig.partId,
112973
- operation: "mutate",
112974
- source: `story-runtime:commit:${locator.storyType}`,
112975
- mutate({ part }) {
112976
- updateNoteContentFromOoxml(part, notesConfig, locator.noteId, ooxmlElements);
112977
- }
112978
- });
113459
+ if (isNoteContentEmpty(storyEditor.state.doc)) {
113460
+ if (Boolean(TrackChangesBasePluginKey.getState(hostEditor.state)?.isTrackChangesActive))
112979
113461
  return;
112980
- }
113462
+ removeEmptiedNote(hostEditor, locator);
113463
+ return;
112981
113464
  }
113465
+ if (commitRichNoteContent(hostEditor, storyEditor, locator, notesConfig))
113466
+ return;
113467
+ commitPlainTextNoteContent(hostEditor, storyEditor, locator, notesConfig);
113468
+ }
113469
+ function removeEmptiedNote(hostEditor, locator) {
113470
+ removeNoteEverywhere(hostEditor, {
113471
+ noteId: locator.noteId,
113472
+ type: locator.storyType
113473
+ });
113474
+ }
113475
+ function stripNoteReferenceNodes(node3) {
113476
+ if (!Array.isArray(node3.content))
113477
+ return node3;
113478
+ return {
113479
+ ...node3,
113480
+ content: node3.content.filter((child) => !NOTE_REFERENCE_NODE_TYPES.has(child?.type ?? "")).map((child) => stripNoteReferenceNodes(child))
113481
+ };
113482
+ }
113483
+ function commitRichNoteContent(hostEditor, storyEditor, locator, notesConfig) {
113484
+ const conv = hostEditor.converter;
113485
+ const rawPmJson = typeof storyEditor.getUpdatedJson === "function" ? storyEditor.getUpdatedJson() : storyEditor.getJSON();
113486
+ if (!conv?.exportToXmlJson || !rawPmJson)
113487
+ return false;
113488
+ const pmJson = stripNoteReferenceNodes(rawPmJson);
113489
+ let ooxmlElements = null;
113490
+ try {
113491
+ const { result } = conv.exportToXmlJson({
113492
+ data: pmJson,
113493
+ editor: storyEditor,
113494
+ editorSchema: storyEditor.schema,
113495
+ isHeaderFooter: true,
113496
+ comments: [],
113497
+ commentDefinitions: []
113498
+ });
113499
+ ooxmlElements = result?.elements?.[0]?.elements ?? null;
113500
+ } catch {}
113501
+ if (!ooxmlElements || ooxmlElements.length === 0)
113502
+ return false;
113503
+ const elements = ooxmlElements;
113504
+ mutatePart({
113505
+ editor: hostEditor,
113506
+ partId: notesConfig.partId,
113507
+ operation: "mutate",
113508
+ source: `story-runtime:commit:${locator.storyType}`,
113509
+ mutate({ part }) {
113510
+ updateNoteContentFromOoxml(part, notesConfig, locator.noteId, elements);
113511
+ }
113512
+ });
113513
+ return true;
113514
+ }
113515
+ function commitPlainTextNoteContent(hostEditor, storyEditor, locator, notesConfig) {
112982
113516
  const doc$2 = storyEditor.state.doc;
112983
113517
  const text$2 = doc$2.textBetween(0, doc$2.content.size, `
112984
113518
  `, `
@@ -132620,6 +133154,38 @@ Docs: https://docs.superdoc.dev/getting-started/fonts`);
132620
133154
  if (base$1.elements?.[0])
132621
133155
  base$1.elements[0].name = config$43.rootName;
132622
133156
  return base$1;
133157
+ }, collectReferencedNoteIds = (xmlNode, referenceName, found$1 = /* @__PURE__ */ new Set) => {
133158
+ if (!xmlNode || typeof xmlNode !== "object")
133159
+ return found$1;
133160
+ if (xmlNode.name === referenceName && xmlNode.attributes?.["w:id"] != null)
133161
+ found$1.add(String(xmlNode.attributes["w:id"]));
133162
+ if (Array.isArray(xmlNode.elements))
133163
+ xmlNode.elements.forEach((child) => collectReferencedNoteIds(child, referenceName, found$1));
133164
+ return found$1;
133165
+ }, pruneSessionDeletedNotesPart = (partXml, { converter, documentXml, type }) => {
133166
+ const config$43 = type === "endnote" ? ENDNOTES_CONFIG$1 : FOOTNOTES_CONFIG$1;
133167
+ const registry = converter?.sessionManagedNoteIds?.[config$43.sessionRegistryKey];
133168
+ const root2 = partXml?.elements?.[0];
133169
+ if (!root2?.elements || !registry || registry.size === 0)
133170
+ return partXml;
133171
+ const referenced = collectReferencedNoteIds(documentXml, config$43.referenceName);
133172
+ const keep = (el) => {
133173
+ if (el?.name !== config$43.noteName)
133174
+ return true;
133175
+ const noteType = el.attributes?.["w:type"];
133176
+ if (noteType === "separator" || noteType === "continuationSeparator")
133177
+ return true;
133178
+ const id2 = String(el.attributes?.["w:id"]);
133179
+ const numericId = Number(id2);
133180
+ if (Number.isFinite(numericId) && numericId <= 0)
133181
+ return true;
133182
+ return !registry.has(id2) || referenced.has(id2);
133183
+ };
133184
+ if (root2.elements.every(keep))
133185
+ return partXml;
133186
+ const copy$1 = carbonCopy(partXml);
133187
+ copy$1.elements[0].elements = copy$1.elements[0].elements.filter(keep);
133188
+ return copy$1;
132623
133189
  }, prepareNotesXmlForExport = ({ notes, editor, converter, convertedXml, config: config$43 }) => {
132624
133190
  let updatedXml = convertedXml;
132625
133191
  if (config$43.applySettingsSideEffects) {
@@ -134744,6 +135310,18 @@ Docs: https://docs.superdoc.dev/getting-started/fonts`);
134744
135310
  delete sanitizedRunProperties.vertAlign;
134745
135311
  delete sanitizedRunProperties.position;
134746
135312
  return sanitizedRunProperties;
135313
+ }, withReferenceDataAttrs = (run$1, params3) => {
135314
+ const rawType = params3.node.type;
135315
+ const kind = (typeof rawType === "string" ? rawType : rawType?.name) === "endnoteReference" ? "endnote" : "footnote";
135316
+ const id2 = params3.node.attrs?.id;
135317
+ return {
135318
+ ...run$1,
135319
+ dataAttrs: {
135320
+ ...run$1.dataAttrs,
135321
+ "data-note-reference": kind,
135322
+ ...id2 != null ? { "data-note-id": String(id2) } : {}
135323
+ }
135324
+ };
134747
135325
  }, copyReferencePmPositions = (run$1, params3) => {
134748
135326
  const refPos = params3.positions.get(params3.node);
134749
135327
  if (!refPos)
@@ -136091,7 +136669,7 @@ Docs: https://docs.superdoc.dev/getting-started/fonts`);
136091
136669
  return;
136092
136670
  updateGhostListMarkerOffsets(node3, paragraphBlocks, context);
136093
136671
  applyGhostListMarkerOffsets(node3, paragraphBlocks, context);
136094
- }, INLINE_CONVERTERS_REGISTRY, SHAPE_CONVERTERS_REGISTRY, JUSTIFICATION_TO_ALIGN, DEFAULT_FONT = "Times New Roman", DEFAULT_SIZE2, nodeHandlers, converters, CommentMarkName = "commentMark", LINK_MARK_NAME = "link", COMMENT_MARK_NAME, SUPPORTED_INLINE_TYPES, FALLBACK_PREFIX, UUID_LIKE_PATTERN, ALIAS_ELIGIBLE_TYPES, cacheByEditor, OBJECT_REPLACEMENT_CHAR = "", LINE_NUMBER_RESTART_VALUES, PAGE_NUMBER_FORMAT_VALUES, PAGE_NUMBER_CHAPTER_SEPARATOR_VALUES, SECTION_ORIENTATION_VALUES, SECTION_VERTICAL_ALIGN_VALUES, readSectPrHeaderFooterRefs, PIXELS_PER_INCH = 96, SECTION_PAGE_NUMBER_FORMATS, SETTINGS_PART_PATH = "word/settings.xml", VALID_EDIT_MODES, DOCUMENT_RELS_PATH = "word/_rels/document.xml.rels", RELS_XMLNS = "http://schemas.openxmlformats.org/package/2006/relationships", HEADER_RELATIONSHIP_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", WORDPROCESSINGML_XMLNS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", OFFICE_DOCUMENT_RELS_XMLNS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", RELATIONSHIP_ID_PATTERN, HEADER_FILE_PATTERN, FOOTER_FILE_PATTERN, SOURCE_HEADER_FOOTER_LOCAL = "header-footer-sync:local", HEADER_PATTERN, FOOTER_PATTERN, DEFAULT_HDR_FTR_ATTRS, HEADER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", VALID_VARIANTS, FOOTNOTES_PART_ID = "word/footnotes.xml", ENDNOTES_PART_ID = "word/endnotes.xml", FOOTNOTES_CONFIG, ENDNOTES_CONFIG, NOTES_XMLNS, footnotesPartDescriptor, endnotesPartDescriptor, storeByEditor, liveSessionsByHost, cacheByHost, hostStoreSyncedKeys, BODY_LOCATOR, findMarkPosition = (doc$2, pos, markName) => {
136672
+ }, INLINE_CONVERTERS_REGISTRY, SHAPE_CONVERTERS_REGISTRY, JUSTIFICATION_TO_ALIGN, DEFAULT_FONT = "Times New Roman", DEFAULT_SIZE2, nodeHandlers, converters, CommentMarkName = "commentMark", LINK_MARK_NAME = "link", COMMENT_MARK_NAME, SUPPORTED_INLINE_TYPES, FALLBACK_PREFIX, UUID_LIKE_PATTERN, ALIAS_ELIGIBLE_TYPES, cacheByEditor, OBJECT_REPLACEMENT_CHAR = "", LINE_NUMBER_RESTART_VALUES, PAGE_NUMBER_FORMAT_VALUES, PAGE_NUMBER_CHAPTER_SEPARATOR_VALUES, SECTION_ORIENTATION_VALUES, SECTION_VERTICAL_ALIGN_VALUES, readSectPrHeaderFooterRefs, PIXELS_PER_INCH = 96, SECTION_PAGE_NUMBER_FORMATS, SETTINGS_PART_PATH = "word/settings.xml", VALID_EDIT_MODES, DOCUMENT_RELS_PATH = "word/_rels/document.xml.rels", RELS_XMLNS = "http://schemas.openxmlformats.org/package/2006/relationships", HEADER_RELATIONSHIP_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", WORDPROCESSINGML_XMLNS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", OFFICE_DOCUMENT_RELS_XMLNS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", RELATIONSHIP_ID_PATTERN, HEADER_FILE_PATTERN, FOOTER_FILE_PATTERN, SOURCE_HEADER_FOOTER_LOCAL = "header-footer-sync:local", HEADER_PATTERN, FOOTER_PATTERN, DEFAULT_HDR_FTR_ATTRS, HEADER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", VALID_VARIANTS, FOOTNOTES_PART_ID = "word/footnotes.xml", ENDNOTES_PART_ID = "word/endnotes.xml", FOOTNOTES_CONFIG, ENDNOTES_CONFIG, NOTES_XMLNS, footnotesPartDescriptor, endnotesPartDescriptor, NOTE_TOMBSTONE_EVENT = "note-tombstoned", SPECIAL_NOTE_TYPES, RESTART_POLICY_TO_OOXML, findMarkPosition = (doc$2, pos, markName) => {
136095
136673
  const $pos = doc$2.resolve(pos);
136096
136674
  const parent = $pos.parent;
136097
136675
  const start = parent.childAfter($pos.parentOffset);
@@ -136264,7 +136842,155 @@ Docs: https://docs.superdoc.dev/getting-started/fonts`);
136264
136842
  sourceId: stringOf(primary.sourceId),
136265
136843
  revisionGroupId: stringOf(primary.revisionGroupId) || representativeRevisionId
136266
136844
  });
136267
- }, stringOf = (value) => typeof value === "string" ? value : value == null ? "" : String(value), groupedCache, SDT_NODE_NAMES, SDT_BLOCK_NAME = "structuredContentBlock", SDT_INLINE_NAME = "structuredContent", SDT_NODE_TYPES, VALID_CONTROL_TYPES, VALID_LOCK_MODES2, VALID_APPEARANCES, FIELD_LIKE_SDT_TYPES, liveDocumentCountsCache, BIBLIOGRAPHY_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", CUSTOM_XML_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml", CUSTOM_XML_PROPS_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps", DEFAULT_SELECTED_STYLE = "/APA.XSL", DEFAULT_STYLE_NAME = "APA", DEFAULT_VERSION = "6", API_TO_OOXML_SOURCE_TYPE, OOXML_TO_API_SOURCE_TYPE, SIMPLE_FIELD_TO_XML_TAG, XML_TAG_TO_SIMPLE_FIELD, import_lib2, FONT_FAMILY_FALLBACKS, DEFAULT_GENERIC_FALLBACK = "sans-serif", DEFAULT_FONT_SIZE_PT = 10, CURRENT_APP_VERSION = "1.41.0", SUPERDOC_DOCUMENT_ORIGIN_PROPERTY = "SuperdocDocumentOrigin", STORED_DOCUMENT_ORIGINS, collectRunDefaultProperties = (runProps, { allowOverrideTypeface = true, allowOverrideSize = true, themeResolver, state }) => {
136845
+ }, stringOf = (value) => typeof value === "string" ? value : value == null ? "" : String(value), TrackChangesBasePluginKey, TrackChangesBasePlugin = () => {
136846
+ return new Plugin({
136847
+ key: TrackChangesBasePluginKey,
136848
+ state: {
136849
+ init(_, state) {
136850
+ return {
136851
+ isTrackChangesActive: false,
136852
+ onlyOriginalShown: false,
136853
+ onlyModifiedShown: false,
136854
+ pendingDeadKeyPlaceholder: null,
136855
+ decorations: getTrackChangesDecorations(state, false, false)
136856
+ };
136857
+ },
136858
+ apply(tr, oldState, prevEditorState, newEditorState) {
136859
+ const meta = tr.getMeta(TrackChangesBasePluginKey);
136860
+ const pendingDeadKeyPlaceholder = meta && Object.prototype.hasOwnProperty.call(meta, "pendingDeadKeyPlaceholder") ? meta.pendingDeadKeyPlaceholder : oldState.pendingDeadKeyPlaceholder;
136861
+ if (meta && meta.type === "TRACK_CHANGES_ENABLE")
136862
+ return {
136863
+ ...oldState,
136864
+ isTrackChangesActive: meta.value === true,
136865
+ pendingDeadKeyPlaceholder,
136866
+ decorations: getTrackChangesDecorations(newEditorState, oldState.onlyOriginalShown, oldState.onlyModifiedShown)
136867
+ };
136868
+ if (meta && meta.type === "SHOW_ONLY_ORIGINAL")
136869
+ return {
136870
+ ...oldState,
136871
+ onlyOriginalShown: meta.value === true,
136872
+ onlyModifiedShown: false,
136873
+ pendingDeadKeyPlaceholder,
136874
+ decorations: getTrackChangesDecorations(newEditorState, meta.value === true, false)
136875
+ };
136876
+ if (meta && meta.type === "SHOW_ONLY_MODIFIED")
136877
+ return {
136878
+ ...oldState,
136879
+ onlyOriginalShown: false,
136880
+ onlyModifiedShown: meta.value === true,
136881
+ pendingDeadKeyPlaceholder,
136882
+ decorations: getTrackChangesDecorations(newEditorState, false, meta.value === true)
136883
+ };
136884
+ if (!tr.docChanged)
136885
+ return {
136886
+ ...oldState,
136887
+ pendingDeadKeyPlaceholder
136888
+ };
136889
+ if (!meta) {
136890
+ let mightAffectTrackChanges = false;
136891
+ tr.steps.forEach((step2) => {
136892
+ const replaceStep$1 = step2;
136893
+ if (replaceStep$1.slice || replaceStep$1.from !== replaceStep$1.to)
136894
+ mightAffectTrackChanges = true;
136895
+ });
136896
+ if (mightAffectTrackChanges)
136897
+ return {
136898
+ ...oldState,
136899
+ pendingDeadKeyPlaceholder,
136900
+ decorations: getTrackChangesDecorations(newEditorState, oldState.onlyOriginalShown, oldState.onlyModifiedShown)
136901
+ };
136902
+ return {
136903
+ ...oldState,
136904
+ pendingDeadKeyPlaceholder,
136905
+ decorations: oldState.decorations.map(tr.mapping, tr.doc)
136906
+ };
136907
+ }
136908
+ return {
136909
+ ...oldState,
136910
+ pendingDeadKeyPlaceholder,
136911
+ decorations: getTrackChangesDecorations(newEditorState, oldState.onlyOriginalShown, oldState.onlyModifiedShown)
136912
+ };
136913
+ }
136914
+ },
136915
+ props: { decorations(state) {
136916
+ return this.getState(state)?.decorations;
136917
+ } }
136918
+ });
136919
+ }, getTrackChangesDecorations = (state, onlyOriginalShown, onlyModifiedShown) => {
136920
+ if (!state.doc || !state.doc.nodeSize || onlyModifiedShown && onlyOriginalShown)
136921
+ return DecorationSet.empty;
136922
+ const decorations = [];
136923
+ const trackedChanges = getTrackChanges(state);
136924
+ addStructuralRowDecorations(decorations, state, onlyOriginalShown, onlyModifiedShown);
136925
+ if (!trackedChanges.length)
136926
+ return decorations.length ? DecorationSet.create(state.doc, decorations) : DecorationSet.empty;
136927
+ trackedChanges.forEach(({ mark, from: from5, to }) => {
136928
+ if (mark.type.name === "trackInsert")
136929
+ if (onlyOriginalShown) {
136930
+ const decoration = Decoration.inline(from5, to, { class: "track-insert-dec hidden" });
136931
+ decorations.push(decoration);
136932
+ } else if (onlyModifiedShown) {
136933
+ const decoration = Decoration.inline(from5, to, { class: "track-insert-dec normal" });
136934
+ decorations.push(decoration);
136935
+ } else {
136936
+ const decoration = Decoration.inline(from5, to, { class: "track-insert-dec highlighted" });
136937
+ decorations.push(decoration);
136938
+ }
136939
+ if (mark.type.name === "trackDelete")
136940
+ if (onlyOriginalShown) {
136941
+ const decoration = Decoration.inline(from5, to, { class: "track-delete-dec normal" });
136942
+ decorations.push(decoration);
136943
+ } else if (onlyModifiedShown) {
136944
+ const decoration = Decoration.inline(from5, to, { class: "track-delete-dec hidden" });
136945
+ decorations.push(decoration);
136946
+ } else {
136947
+ const decorationInline = Decoration.inline(from5, to, { class: "track-delete-dec highlighted" });
136948
+ decorations.push(decorationInline);
136949
+ const decorationWidget = Decoration.widget(from5, () => {
136950
+ const span = document.createElement("span");
136951
+ span.classList.add("track-delete-widget");
136952
+ return span;
136953
+ }, {
136954
+ ignoreSelection: true,
136955
+ key: "stable-key"
136956
+ });
136957
+ decorations.push(decorationWidget);
136958
+ }
136959
+ if (mark.type.name === "trackFormat")
136960
+ if (onlyOriginalShown) {
136961
+ const decoration = Decoration.inline(from5, to, { class: "track-format-dec before" });
136962
+ decorations.push(decoration);
136963
+ } else if (onlyModifiedShown) {
136964
+ const decoration = Decoration.inline(from5, to, { class: "track-format-dec normal" });
136965
+ decorations.push(decoration);
136966
+ } else {
136967
+ const decoration = Decoration.inline(from5, to, { class: "track-format-dec highlighted" });
136968
+ decorations.push(decoration);
136969
+ }
136970
+ });
136971
+ return DecorationSet.create(state.doc, decorations);
136972
+ }, addStructuralRowDecorations = (decorations, state, onlyOriginalShown, onlyModifiedShown) => {
136973
+ const structuralChanges = enumerateStructuralRowChanges(state);
136974
+ if (!structuralChanges.length)
136975
+ return;
136976
+ for (const change of structuralChanges) {
136977
+ const isInsert = change.side === "insertion";
136978
+ const baseClass = isInsert ? "track-row-insert-dec" : "track-row-delete-dec";
136979
+ let mode = "highlighted";
136980
+ if (onlyOriginalShown)
136981
+ mode = isInsert ? "hidden" : "normal";
136982
+ else if (onlyModifiedShown)
136983
+ mode = isInsert ? "normal" : "hidden";
136984
+ for (const row of change.rows)
136985
+ decorations.push(Decoration.node(row.from, row.to, {
136986
+ class: `${baseClass} ${mode}`,
136987
+ "data-track-change-id": change.id,
136988
+ "data-track-change-kind": change.subtype,
136989
+ "data-track-change-author": change.author || "",
136990
+ "data-track-change-date": change.date || ""
136991
+ }));
136992
+ }
136993
+ }, NOTE_REFERENCE_NODE_TYPES, storeByEditor, liveSessionsByHost, cacheByHost, hostStoreSyncedKeys, BODY_LOCATOR, groupedCache, SDT_NODE_NAMES, SDT_BLOCK_NAME = "structuredContentBlock", SDT_INLINE_NAME = "structuredContent", SDT_NODE_TYPES, VALID_CONTROL_TYPES, VALID_LOCK_MODES2, VALID_APPEARANCES, FIELD_LIKE_SDT_TYPES, liveDocumentCountsCache, BIBLIOGRAPHY_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", CUSTOM_XML_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml", CUSTOM_XML_PROPS_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps", DEFAULT_SELECTED_STYLE = "/APA.XSL", DEFAULT_STYLE_NAME = "APA", DEFAULT_VERSION = "6", API_TO_OOXML_SOURCE_TYPE, OOXML_TO_API_SOURCE_TYPE, SIMPLE_FIELD_TO_XML_TAG, XML_TAG_TO_SIMPLE_FIELD, import_lib2, FONT_FAMILY_FALLBACKS, DEFAULT_GENERIC_FALLBACK = "sans-serif", DEFAULT_FONT_SIZE_PT = 10, CURRENT_APP_VERSION = "1.41.0", SUPERDOC_DOCUMENT_ORIGIN_PROPERTY = "SuperdocDocumentOrigin", STORED_DOCUMENT_ORIGINS, collectRunDefaultProperties = (runProps, { allowOverrideTypeface = true, allowOverrideSize = true, themeResolver, state }) => {
136268
136994
  if (!runProps?.elements?.length || !state)
136269
136995
  return;
136270
136996
  const fontsNode = runProps.elements.find((el) => el.name === "w:rFonts");
@@ -136298,7 +137024,7 @@ Docs: https://docs.superdoc.dev/getting-started/fonts`);
136298
137024
  state.kern = kernNode.attributes["w:val"];
136299
137025
  }
136300
137026
  }, SuperConverter;
136301
- var init_SuperConverter_0i3YuAr2_es = __esm(() => {
137027
+ var init_SuperConverter_Bdmhv7BA_es = __esm(() => {
136302
137028
  init_rolldown_runtime_Bg48TavK_es();
136303
137029
  init_jszip_C49i9kUs_es();
136304
137030
  init_xml_js_CqGKpaft_es();
@@ -156029,7 +156755,7 @@ var init_SuperConverter_0i3YuAr2_es = __esm(() => {
156029
156755
  ];
156030
156756
  },
156031
156757
  afterCommit({ editor, part, source }) {
156032
- const converter = getConverter$8(editor);
156758
+ const converter = getConverter$9(editor);
156033
156759
  if (!converter)
156034
156760
  return;
156035
156761
  if (source.startsWith("collab:remote:") || source === "templates.apply")
@@ -156210,7 +156936,7 @@ var init_SuperConverter_0i3YuAr2_es = __esm(() => {
156210
156936
  tokenize: tokenizeCodeText
156211
156937
  };
156212
156938
  content$1 = {
156213
- resolve: resolveContent,
156939
+ resolve: resolveContent$1,
156214
156940
  tokenize: tokenizeContent
156215
156941
  };
156216
156942
  continuationConstruct = {
@@ -163568,6 +164294,8 @@ var init_SuperConverter_0i3YuAr2_es = __esm(() => {
163568
164294
  noteName: "w:footnote",
163569
164295
  refName: "w:footnoteRef",
163570
164296
  refStyle: "FootnoteReference",
164297
+ referenceName: "w:footnoteReference",
164298
+ sessionRegistryKey: "footnotes",
163571
164299
  relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
163572
164300
  relationshipTarget: "footnotes.xml",
163573
164301
  applySettingsSideEffects: true
@@ -163579,6 +164307,8 @@ var init_SuperConverter_0i3YuAr2_es = __esm(() => {
163579
164307
  noteName: "w:endnote",
163580
164308
  refName: "w:endnoteRef",
163581
164309
  refStyle: "EndnoteReference",
164310
+ referenceName: "w:endnoteReference",
164311
+ sessionRegistryKey: "endnotes",
163582
164312
  relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes",
163583
164313
  relationshipTarget: "endnotes.xml",
163584
164314
  applySettingsSideEffects: false
@@ -164074,6 +164804,14 @@ var init_SuperConverter_0i3YuAr2_es = __esm(() => {
164074
164804
  };
164075
164805
  footnotesPartDescriptor = createNotePartDescriptor(FOOTNOTES_CONFIG);
164076
164806
  endnotesPartDescriptor = createNotePartDescriptor(ENDNOTES_CONFIG);
164807
+ SPECIAL_NOTE_TYPES = new Set(["separator", "continuationSeparator"]);
164808
+ RESTART_POLICY_TO_OOXML = {
164809
+ continuous: "continuous",
164810
+ eachSection: "eachSect",
164811
+ eachPage: "eachPage"
164812
+ };
164813
+ TrackChangesBasePluginKey = new PluginKey("TrackChangesBase");
164814
+ NOTE_REFERENCE_NODE_TYPES = new Set(["footnoteReference", "endnoteReference"]);
164077
164815
  storeByEditor = /* @__PURE__ */ new WeakMap;
164078
164816
  liveSessionsByHost = /* @__PURE__ */ new WeakMap;
164079
164817
  cacheByHost = /* @__PURE__ */ new WeakMap;
@@ -165290,7 +166028,7 @@ var init_SuperConverter_0i3YuAr2_es = __esm(() => {
165290
166028
  };
165291
166029
  });
165292
166030
 
165293
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-DYCEnt7x.es.js
166031
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-VA4azb5D.es.js
165294
166032
  function parseSizeUnit(val = "0") {
165295
166033
  const length3 = val.toString() || "0";
165296
166034
  const value = Number.parseFloat(length3);
@@ -175939,10 +176677,17 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, MARK_KEYS, STEP_OP_CATALOG_UNFROZEN2, P
175939
176677
  rebindEvents();
175940
176678
  notifyListeners();
175941
176679
  };
176680
+ let refreshQueued = false;
175942
176681
  const handleChange = () => {
175943
- if (destroyed)
176682
+ if (destroyed || refreshQueued)
175944
176683
  return;
175945
- refreshControllerState();
176684
+ refreshQueued = true;
176685
+ queueMicrotask(() => {
176686
+ refreshQueued = false;
176687
+ if (destroyed)
176688
+ return;
176689
+ refreshControllerState();
176690
+ });
175946
176691
  };
175947
176692
  rebindEvents();
175948
176693
  return {
@@ -175976,9 +176721,9 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, MARK_KEYS, STEP_OP_CATALOG_UNFROZEN2, P
175976
176721
  }
175977
176722
  };
175978
176723
  };
175979
- var init_create_headless_toolbar_DYCEnt7x_es = __esm(() => {
176724
+ var init_create_headless_toolbar_VA4azb5D_es = __esm(() => {
175980
176725
  init_rolldown_runtime_Bg48TavK_es();
175981
- init_SuperConverter_0i3YuAr2_es();
176726
+ init_SuperConverter_Bdmhv7BA_es();
175982
176727
  init_jszip_C49i9kUs_es();
175983
176728
  init_uuid_B2wVPhPi_es();
175984
176729
  init_constants_D9qj59G2_es();
@@ -226072,7 +226817,7 @@ var init_remark_gfm_DCND_V_3_es = __esm(() => {
226072
226817
  init_remark_gfm_BUJjZJLy_es();
226073
226818
  });
226074
226819
 
226075
- // ../../packages/superdoc/dist/chunks/src-COxdGpKV.es.js
226820
+ // ../../packages/superdoc/dist/chunks/src-C3y2aHWQ.es.js
226076
226821
  function deleteProps(obj, propOrProps) {
226077
226822
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
226078
226823
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -227114,10 +227859,122 @@ function updateMigrationStatus(metaMap, status, error3, ydoc) {
227114
227859
  };
227115
227860
  metaMap.set(META_PARTS_MIGRATION_KEY, updated);
227116
227861
  }
227862
+ function getConverter$92(editor) {
227863
+ return editor.converter;
227864
+ }
227865
+ function bucketFor(type) {
227866
+ return type === "endnote" ? "endnotes" : "footnotes";
227867
+ }
227868
+ function ensureRegistry(converter) {
227869
+ if (!converter.sessionManagedNoteIds)
227870
+ converter.sessionManagedNoteIds = {
227871
+ footnotes: /* @__PURE__ */ new Set,
227872
+ endnotes: /* @__PURE__ */ new Set
227873
+ };
227874
+ return converter.sessionManagedNoteIds;
227875
+ }
227876
+ function noteTombstoneKey(type, noteId) {
227877
+ return `${NOTE_TOMBSTONE_META_PREFIX}${type}:${noteId}`;
227878
+ }
227879
+ function parseNoteTombstoneKey(key2) {
227880
+ if (!key2.startsWith("noteTombstone:"))
227881
+ return null;
227882
+ const rest = key2.slice(14);
227883
+ const sep = rest.indexOf(":");
227884
+ if (sep <= 0)
227885
+ return null;
227886
+ const type = rest.slice(0, sep);
227887
+ const noteId = rest.slice(sep + 1);
227888
+ if (type !== "footnote" && type !== "endnote" || noteId.length === 0)
227889
+ return null;
227890
+ return {
227891
+ type,
227892
+ noteId
227893
+ };
227894
+ }
227895
+ function publishNoteTombstone(ydoc, type, noteId) {
227896
+ ydoc.getMap(META_MAP_KEY$1).set(noteTombstoneKey(type, String(noteId)), true);
227897
+ }
227898
+ function clearNoteTombstonesFromMeta(ydoc) {
227899
+ const metaMap = ydoc.getMap(META_MAP_KEY$1);
227900
+ for (const key2 of [...metaMap.keys()])
227901
+ if (key2.startsWith("noteTombstone:"))
227902
+ metaMap.delete(key2);
227903
+ }
227904
+ function publishSessionManagedNoteIds(ydoc, registry2) {
227905
+ if (!registry2)
227906
+ return;
227907
+ for (const noteId of registry2.footnotes)
227908
+ publishNoteTombstone(ydoc, "footnote", noteId);
227909
+ for (const noteId of registry2.endnotes)
227910
+ publishNoteTombstone(ydoc, "endnote", noteId);
227911
+ }
227912
+ function hydrateNoteTombstonesFromMeta(editor, ydoc) {
227913
+ const converter = getConverter$92(editor);
227914
+ if (!converter)
227915
+ return;
227916
+ const metaMap = ydoc.getMap(META_MAP_KEY$1);
227917
+ let registry2 = null;
227918
+ for (const key2 of metaMap.keys()) {
227919
+ const parsed = parseNoteTombstoneKey(key2);
227920
+ if (!parsed)
227921
+ continue;
227922
+ registry2 = registry2 ?? ensureRegistry(converter);
227923
+ registry2[bucketFor(parsed.type)].add(parsed.noteId);
227924
+ }
227925
+ }
227926
+ function registerNoteTombstoneSync(editor, ydoc) {
227927
+ const metaMap = ydoc.getMap(META_MAP_KEY$1);
227928
+ const onTombstoned = (...args$1) => {
227929
+ const payload = args$1[0];
227930
+ const type = payload?.type;
227931
+ if (type !== "footnote" && type !== "endnote")
227932
+ return;
227933
+ if (payload?.noteId == null)
227934
+ return;
227935
+ publishNoteTombstone(ydoc, type, String(payload.noteId));
227936
+ };
227937
+ editor.on?.(NOTE_TOMBSTONE_EVENT, onTombstoned);
227938
+ const observer = (event) => {
227939
+ const converter = getConverter$92(editor);
227940
+ if (!converter)
227941
+ return;
227942
+ let registry2 = null;
227943
+ event.changes.keys.forEach((change, key2) => {
227944
+ const parsed = parseNoteTombstoneKey(key2);
227945
+ if (!parsed)
227946
+ return;
227947
+ if (change.action === "delete") {
227948
+ converter.sessionManagedNoteIds?.[bucketFor(parsed.type)]?.delete(parsed.noteId);
227949
+ return;
227950
+ }
227951
+ registry2 = registry2 ?? ensureRegistry(converter);
227952
+ registry2[bucketFor(parsed.type)].add(parsed.noteId);
227953
+ });
227954
+ };
227955
+ metaMap.observe(observer);
227956
+ let pendingProviderCleanup;
227957
+ const provider = editor.options?.collaborationProvider;
227958
+ const hydrate = () => {
227959
+ if (editor.isDestroyed)
227960
+ return;
227961
+ hydrateNoteTombstonesFromMeta(editor, ydoc);
227962
+ };
227963
+ if (!provider || isCollaborationProviderSynced(provider))
227964
+ hydrate();
227965
+ else
227966
+ pendingProviderCleanup = onCollaborationProviderSynced(provider, hydrate);
227967
+ return { destroy() {
227968
+ editor.off?.(NOTE_TOMBSTONE_EVENT, onTombstoned);
227969
+ metaMap.unobserve(observer);
227970
+ pendingProviderCleanup?.();
227971
+ } };
227972
+ }
227117
227973
  function seedPartsFromEditor(editor, ydoc, options) {
227118
227974
  const convertedXml = editor.converter?.convertedXml;
227119
227975
  if (!convertedXml)
227120
227976
  return;
227977
+ const sessionManagedNoteIds = editor.converter?.sessionManagedNoteIds;
227121
227978
  const partsMap = ydoc.getMap(PARTS_MAP_KEY);
227122
227979
  const metaMap = ydoc.getMap(META_MAP_KEY);
227123
227980
  const replaceExisting = options?.replaceExisting ?? false;
@@ -227127,6 +227984,7 @@ function seedPartsFromEditor(editor, ydoc, options) {
227127
227984
  for (const key2 of [...partsMap.keys()])
227128
227985
  if (!EXCLUDED_PART_IDS.has(key2) && !snapshotKeys.has(key2))
227129
227986
  partsMap.delete(key2);
227987
+ clearNoteTombstonesFromMeta(ydoc);
227130
227988
  }
227131
227989
  for (const key2 of snapshotKeys) {
227132
227990
  if (!replaceExisting && partsMap.has(key2))
@@ -227138,6 +227996,7 @@ function seedPartsFromEditor(editor, ydoc, options) {
227138
227996
  });
227139
227997
  partsMap.set(key2, envelope);
227140
227998
  }
227999
+ publishSessionManagedNoteIds(ydoc, sessionManagedNoteIds);
227141
228000
  const capability = {
227142
228001
  version: 1,
227143
228002
  enabledAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -228090,11 +228949,11 @@ function syncSplitParagraphRunProperties(attrs, runProperties) {
228090
228949
  paragraphProperties: nextParagraphProperties
228091
228950
  };
228092
228951
  }
228093
- function getConverter$92(editor) {
228952
+ function getConverter$82(editor) {
228094
228953
  return editor.converter;
228095
228954
  }
228096
228955
  function readTranslatedLinkedStyles(editor) {
228097
- return getConverter$92(editor)?.translatedLinkedStyles ?? null;
228956
+ return getConverter$82(editor)?.translatedLinkedStyles ?? null;
228098
228957
  }
228099
228958
  function findRangeById(doc$12, id2) {
228100
228959
  let from$1 = null, to = null;
@@ -228661,6 +229520,31 @@ function chainCommands(...commands$1) {
228661
229520
  return false;
228662
229521
  };
228663
229522
  }
229523
+ function findParagraphDepth$1($pos) {
229524
+ for (let depth = $pos.depth;depth >= 1; depth -= 1)
229525
+ if ($pos.node(depth).type.name === "paragraph")
229526
+ return depth;
229527
+ return null;
229528
+ }
229529
+ function restoreParagraphPropertiesAfterDispatch(dispatch, sourceProps) {
229530
+ if (!sourceProps?.styleId)
229531
+ return dispatch;
229532
+ return (tr) => {
229533
+ const $head = tr.selection.$head;
229534
+ const depth = findParagraphDepth$1($head);
229535
+ if (depth) {
229536
+ const paragraph2 = $head.node(depth);
229537
+ if (paragraph2.attrs?.paragraphProperties?.styleId == null) {
229538
+ const pos = $head.before(depth);
229539
+ tr.setNodeMarkup(pos, undefined, {
229540
+ ...paragraph2.attrs,
229541
+ paragraphProperties: sourceProps
229542
+ });
229543
+ }
229544
+ }
229545
+ dispatch(tr);
229546
+ };
229547
+ }
228664
229548
  function resolveHeaderFooterSelection({ tr }) {
228665
229549
  return tr?.selection;
228666
229550
  }
@@ -228948,6 +229832,58 @@ function shallowEqual$2(a2, b$1) {
228948
229832
  return false;
228949
229833
  return true;
228950
229834
  }
229835
+ function markerEndingAt(node3, boundaryPos) {
229836
+ if (isNoteReference(node3))
229837
+ return {
229838
+ node: node3,
229839
+ pos: boundaryPos - node3.nodeSize
229840
+ };
229841
+ if (node3?.type.name === "run" && isNoteReference(node3.lastChild)) {
229842
+ const marker = node3.lastChild;
229843
+ return {
229844
+ node: marker,
229845
+ pos: boundaryPos - 1 - marker.nodeSize
229846
+ };
229847
+ }
229848
+ return null;
229849
+ }
229850
+ function markerStartingAt(node3, boundaryPos) {
229851
+ if (isNoteReference(node3))
229852
+ return {
229853
+ node: node3,
229854
+ pos: boundaryPos
229855
+ };
229856
+ if (node3?.type.name === "run" && isNoteReference(node3.firstChild))
229857
+ return {
229858
+ node: node3.firstChild,
229859
+ pos: boundaryPos + 1
229860
+ };
229861
+ return null;
229862
+ }
229863
+ function getPreviousNoteMarker(state) {
229864
+ const { $from } = state.selection;
229865
+ if ($from.parent.type.name === "run" && $from.parentOffset === 0) {
229866
+ const runStart = $from.before($from.depth);
229867
+ return markerEndingAt(state.doc.resolve(runStart).nodeBefore, runStart);
229868
+ }
229869
+ return markerEndingAt($from.nodeBefore, $from.pos);
229870
+ }
229871
+ function getNextNoteMarker(state) {
229872
+ const { $from } = state.selection;
229873
+ if ($from.parent.type.name === "run" && $from.parentOffset === $from.parent.content.size) {
229874
+ const runEnd = $from.after($from.depth);
229875
+ return markerStartingAt(state.doc.resolve(runEnd).nodeAfter, runEnd);
229876
+ }
229877
+ return markerStartingAt($from.nodeAfter, $from.pos);
229878
+ }
229879
+ function selectNoteMarker(state, dispatch, marker) {
229880
+ if (dispatch) {
229881
+ const from$1 = marker.pos;
229882
+ const to = marker.pos + marker.node.nodeSize;
229883
+ dispatch(state.tr.setMeta(SELECT_FOOTNOTE_MARKER_META, true).setSelection(TextSelection.create(state.doc, from$1, to)));
229884
+ }
229885
+ return true;
229886
+ }
228951
229887
  function findAncestorDepth$3($pos, predicate) {
228952
229888
  for (let depth = $pos.depth;depth > 0; depth -= 1)
228953
229889
  if (predicate($pos.node(depth)))
@@ -229766,7 +230702,8 @@ function createNumberingPlugin(editor) {
229766
230702
  if (isFromPlugin || !forcePluginPass && !forceFullRecompute && !hasDocChanges)
229767
230703
  return null;
229768
230704
  if (!forcePluginPass && !forceFullRecompute) {
229769
- if (transactions.every((tr$1) => isInlineOnlyChange(tr$1)))
230705
+ const numberingIrrelevant = (tr$1) => tr$1.getMeta("blockNodeMetadataUpdate") === true || isInlineOnlyChange(tr$1);
230706
+ if (transactions.every(numberingIrrelevant))
229770
230707
  return null;
229771
230708
  }
229772
230709
  const hasNumberedParagraphInRange = (doc$12, from$1, to) => {
@@ -229879,6 +230816,49 @@ function createNumberingPlugin(editor) {
229879
230816
  }
229880
230817
  });
229881
230818
  }
230819
+ function createNoteStyleGuardPlugin(editor) {
230820
+ return new Plugin({
230821
+ key: noteStyleGuardPluginKey,
230822
+ appendTransaction(transactions, _oldState, newState) {
230823
+ if (!transactions.some((tr$1) => tr$1.docChanged))
230824
+ return null;
230825
+ if (!isNoteStorySession(editor))
230826
+ return null;
230827
+ const paragraphs = [];
230828
+ newState.doc.forEach((node3, offset$1) => {
230829
+ if (node3.type.name === "paragraph")
230830
+ paragraphs.push({
230831
+ node: node3,
230832
+ pos: offset$1
230833
+ });
230834
+ });
230835
+ if (!paragraphs.some(({ node: node3 }) => (node3.attrs?.paragraphProperties?.styleId ?? null) === null))
230836
+ return null;
230837
+ const styledProps = (index2, step3) => {
230838
+ for (let i3 = index2 + step3;i3 >= 0 && i3 < paragraphs.length; i3 += step3) {
230839
+ const props = paragraphs[i3].node.attrs?.paragraphProperties;
230840
+ if (props?.styleId)
230841
+ return props;
230842
+ }
230843
+ return null;
230844
+ };
230845
+ let tr = null;
230846
+ paragraphs.forEach(({ node: node3, pos }, index2) => {
230847
+ if ((node3.attrs?.paragraphProperties?.styleId ?? null) !== null)
230848
+ return;
230849
+ const sourceProps = styledProps(index2, -1) ?? styledProps(index2, 1);
230850
+ if (!sourceProps)
230851
+ return;
230852
+ tr = tr ?? newState.tr;
230853
+ tr.setNodeMarkup(pos, undefined, {
230854
+ ...node3.attrs,
230855
+ paragraphProperties: sourceProps
230856
+ });
230857
+ });
230858
+ return tr;
230859
+ }
230860
+ });
230861
+ }
229882
230862
  function createLeadingCaretPlugin() {
229883
230863
  return new Plugin({ props: { decorations(state) {
229884
230864
  if (typeof document === "undefined")
@@ -230249,6 +231229,52 @@ function hasOnlyBreakContent(node3) {
230249
231229
  });
230250
231230
  return hasBreak && !hasOtherContent;
230251
231231
  }
231232
+ function canInsertNoteAtCursor(editor) {
231233
+ if (!editor)
231234
+ return false;
231235
+ if (editor.options?.parentEditor)
231236
+ return false;
231237
+ if (editor.presentationEditor?.getActiveStoryLocator?.() != null)
231238
+ return false;
231239
+ return true;
231240
+ }
231241
+ function insertFootnoteAtCursor(editor) {
231242
+ if (!canInsertNoteAtCursor(editor))
231243
+ return false;
231244
+ const result = editor.doc?.footnotes?.insert({
231245
+ type: "footnote",
231246
+ content: ""
231247
+ });
231248
+ if (!result?.success)
231249
+ return false;
231250
+ const noteId = result.footnote?.noteId;
231251
+ if (noteId != null)
231252
+ editor.presentationEditor?.activateNoteSession?.({
231253
+ storyType: "footnote",
231254
+ noteId: String(noteId)
231255
+ });
231256
+ return true;
231257
+ }
231258
+ function getSelectedNoteMarker(state) {
231259
+ const { from: from$1, to, empty: empty$1 } = state.selection;
231260
+ if (empty$1)
231261
+ return null;
231262
+ const node3 = state.doc.nodeAt(from$1);
231263
+ const type = NOTE_TYPE_BY_NODE[node3?.type?.name];
231264
+ if (!type || from$1 + node3.nodeSize !== to)
231265
+ return null;
231266
+ return {
231267
+ pos: from$1,
231268
+ noteId: String(node3.attrs?.id ?? ""),
231269
+ type
231270
+ };
231271
+ }
231272
+ function deleteSelectedNoteMarker(editor) {
231273
+ const marker = getSelectedNoteMarker(editor.state);
231274
+ if (!marker)
231275
+ return false;
231276
+ return removeNoteReferenceAt(editor, marker);
231277
+ }
230252
231278
  function getParagraphContext(paragraph2, startPos, helpers, revision, compute) {
230253
231279
  const cached = cache$1.get(paragraph2);
230254
231280
  if (cached && cached.revision === revision)
@@ -235253,6 +236279,15 @@ function isPresenting(editor) {
235253
236279
  function getCurrentCoords(editor, selection) {
235254
236280
  const presentationEditor = editor.presentationEditor;
235255
236281
  const layoutSpaceCoords = presentationEditor.computeCaretLayoutRect(selection.head);
236282
+ const caretRect = (presentationEditor?.visibleHost?.ownerDocument ?? document).querySelector(".presentation-editor__selection-caret")?.getBoundingClientRect?.();
236283
+ if (caretRect && caretRect.height > 0)
236284
+ return {
236285
+ clientX: caretRect.left,
236286
+ clientY: caretRect.top,
236287
+ height: caretRect.height,
236288
+ x: layoutSpaceCoords?.x ?? caretRect.left,
236289
+ y: layoutSpaceCoords?.y ?? caretRect.top
236290
+ };
235256
236291
  if (!layoutSpaceCoords)
235257
236292
  return null;
235258
236293
  const clientCoords = presentationEditor.denormalizeClientPoint(layoutSpaceCoords.x, layoutSpaceCoords.y, layoutSpaceCoords.pageIndex, layoutSpaceCoords.height);
@@ -235273,12 +236308,130 @@ function resolveLineBoundaryPosition(editor, selection, key2) {
235273
236308
  const lineEl = findLineElementAtPoint(doc$12, caretX, coords.clientY + coords.height / 2);
235274
236309
  if (!lineEl)
235275
236310
  return null;
235276
- const pmStart = Number(lineEl.dataset?.pmStart);
235277
- const pmEnd = Number(lineEl.dataset?.pmEnd);
236311
+ let pmStart = Number(lineEl.dataset?.pmStart);
236312
+ let pmEnd = Number(lineEl.dataset?.pmEnd);
235278
236313
  if (!Number.isFinite(pmStart) || !Number.isFinite(pmEnd))
235279
236314
  return null;
236315
+ ({ pmStart, pmEnd } = translateStaleNoteLineRange(editor, lineEl, pmStart, pmEnd));
235280
236316
  return key2 === "Home" ? pmStart : pmEnd;
235281
236317
  }
236318
+ function caretPointFromClientPoint(ownerDoc, x, y$1) {
236319
+ if (typeof ownerDoc.caretRangeFromPoint === "function") {
236320
+ const range = ownerDoc.caretRangeFromPoint(x, y$1);
236321
+ if (range?.startContainer)
236322
+ return {
236323
+ node: range.startContainer,
236324
+ offset: range.startOffset
236325
+ };
236326
+ }
236327
+ if (typeof ownerDoc.caretPositionFromPoint === "function") {
236328
+ const caret = ownerDoc.caretPositionFromPoint(x, y$1);
236329
+ if (caret?.offsetNode)
236330
+ return {
236331
+ node: caret.offsetNode,
236332
+ offset: caret.offset
236333
+ };
236334
+ }
236335
+ return null;
236336
+ }
236337
+ function resolvePositionAtClientPoint(ownerDoc, lineEl, clientX) {
236338
+ const lineRect = lineEl.getBoundingClientRect?.();
236339
+ if (!lineRect || lineRect.height === 0)
236340
+ return null;
236341
+ const y$1 = lineRect.top + lineRect.height / 2;
236342
+ const x = Math.max(lineRect.left, Math.min(clientX, lineRect.right - 1));
236343
+ const win = ownerDoc.defaultView;
236344
+ if (!win)
236345
+ return null;
236346
+ const hit = caretPointFromClientPoint(ownerDoc, x, y$1);
236347
+ if (hit?.node) {
236348
+ const node3 = hit.node;
236349
+ const leaf = (node3.nodeType === win.Node.TEXT_NODE ? node3.parentElement : node3)?.closest?.("[data-pm-start][data-pm-end]");
236350
+ if (leaf && lineEl.contains(leaf)) {
236351
+ const pmStart = Number(leaf.dataset?.pmStart);
236352
+ const pmEnd = Number(leaf.dataset?.pmEnd);
236353
+ if (Number.isFinite(pmStart)) {
236354
+ let offset$1 = 0;
236355
+ const walker = ownerDoc.createTreeWalker(leaf, win.NodeFilter.SHOW_TEXT);
236356
+ let current = walker.nextNode();
236357
+ while (current) {
236358
+ if (current === node3) {
236359
+ offset$1 += hit.offset;
236360
+ break;
236361
+ }
236362
+ offset$1 += current.textContent?.length ?? 0;
236363
+ current = walker.nextNode();
236364
+ }
236365
+ const pos = pmStart + offset$1;
236366
+ return { pos: Number.isFinite(pmEnd) ? Math.min(pos, pmEnd) : pos };
236367
+ }
236368
+ }
236369
+ }
236370
+ const lineStart = Number(lineEl.dataset?.pmStart);
236371
+ const lineEnd = Number(lineEl.dataset?.pmEnd);
236372
+ if (clientX <= lineRect.left && Number.isFinite(lineStart))
236373
+ return { pos: lineStart };
236374
+ if (Number.isFinite(lineEnd))
236375
+ return { pos: lineEnd };
236376
+ return null;
236377
+ }
236378
+ function translateStaleNoteLineRange(editor, lineEl, pmStart, pmEnd) {
236379
+ if (!Boolean(editor?.options?.parentEditor && !editor?.options?.isHeaderOrFooter))
236380
+ return {
236381
+ pmStart,
236382
+ pmEnd
236383
+ };
236384
+ const fragEl = lineEl.closest?.("[data-block-id]");
236385
+ const blockIdAttr = fragEl?.getAttribute?.("data-block-id") ?? "";
236386
+ const doc$12 = editor.state?.doc;
236387
+ if (!fragEl || !blockIdAttr || !doc$12)
236388
+ return {
236389
+ pmStart,
236390
+ pmEnd
236391
+ };
236392
+ let fragmentFirstStart = Infinity;
236393
+ for (const line of fragEl.querySelectorAll(".superdoc-line[data-pm-start]")) {
236394
+ const start$1 = Number(line.dataset?.pmStart);
236395
+ if (Number.isFinite(start$1))
236396
+ fragmentFirstStart = Math.min(fragmentFirstStart, start$1);
236397
+ }
236398
+ if (!Number.isFinite(fragmentFirstStart))
236399
+ return {
236400
+ pmStart,
236401
+ pmEnd
236402
+ };
236403
+ let delta = null;
236404
+ doc$12.descendants((node3, pos) => {
236405
+ if (delta != null)
236406
+ return false;
236407
+ if (!node3.isBlock)
236408
+ return true;
236409
+ const id2 = node3.attrs?.sdBlockId;
236410
+ if (typeof id2 !== "string" || !id2 || !blockIdAttr.endsWith(id2))
236411
+ return true;
236412
+ let firstLeaf = null;
236413
+ node3.descendants((child, childPos) => {
236414
+ if (firstLeaf != null)
236415
+ return false;
236416
+ if (child.isInline && (child.isLeaf || child.isText)) {
236417
+ firstLeaf = pos + 1 + childPos;
236418
+ return false;
236419
+ }
236420
+ return true;
236421
+ });
236422
+ delta = (firstLeaf ?? pos + 1) - fragmentFirstStart;
236423
+ return false;
236424
+ });
236425
+ if (delta == null || delta === 0)
236426
+ return {
236427
+ pmStart,
236428
+ pmEnd
236429
+ };
236430
+ return {
236431
+ pmStart: pmStart + delta,
236432
+ pmEnd: pmEnd + delta
236433
+ };
236434
+ }
235282
236435
  function getAdjacentLineClientTarget(editor, coords, direction) {
235283
236436
  const doc$12 = editor.presentationEditor.visibleHost?.ownerDocument ?? document;
235284
236437
  const caretX = coords.clientX;
@@ -235294,24 +236447,20 @@ function getAdjacentLineClientTarget(editor, coords, direction) {
235294
236447
  const clientY = rect.top + rect.height / 2;
235295
236448
  if (!Number.isFinite(clientY))
235296
236449
  return null;
235297
- const pmStart = Number(adjacentLine.dataset?.pmStart);
235298
- const pmEnd = Number(adjacentLine.dataset?.pmEnd);
236450
+ let pmStart = Number(adjacentLine.dataset?.pmStart);
236451
+ let pmEnd = Number(adjacentLine.dataset?.pmEnd);
236452
+ if (Number.isFinite(pmStart) && Number.isFinite(pmEnd))
236453
+ ({ pmStart, pmEnd } = translateStaleNoteLineRange(editor, adjacentLine, pmStart, pmEnd));
235299
236454
  const isRtl = adjacentLine.closest?.('[dir="rtl"]') != null;
235300
236455
  return {
235301
236456
  clientY,
235302
236457
  pageIndex: Number.isFinite(pageIndex) ? pageIndex : undefined,
235303
236458
  pmStart: Number.isFinite(pmStart) ? pmStart : undefined,
235304
236459
  pmEnd: Number.isFinite(pmEnd) ? pmEnd : undefined,
235305
- isRtl
236460
+ isRtl,
236461
+ lineElement: adjacentLine
235306
236462
  };
235307
236463
  }
235308
- function getHitFromLayoutCoords(editor, goalX, clientY, coords, pageIndex) {
235309
- const presentationEditor = editor.presentationEditor;
235310
- const clientX = presentationEditor.denormalizeClientPoint(goalX, coords.y, pageIndex)?.x;
235311
- if (!Number.isFinite(clientX))
235312
- return null;
235313
- return presentationEditor.hitTest(clientX, clientY);
235314
- }
235315
236464
  function buildSelection(state, pos, extend) {
235316
236465
  const { doc: doc$12, selection } = state;
235317
236466
  if (selection instanceof NodeSelection || selection instanceof CellSelection)
@@ -242789,7 +243938,7 @@ function makeTrackedChangeAnchorKey(ref$1) {
242789
243938
  function makeCommentAnchorKey(commentId) {
242790
243939
  return `${COMMENT_ANCHOR_KEY_PREFIX}${commentId}`;
242791
243940
  }
242792
- function getConverter$82(editor) {
243941
+ function getConverter$72(editor) {
242793
243942
  return editor.converter;
242794
243943
  }
242795
243944
  function toRevisionCapableNoteId(note) {
@@ -242806,7 +243955,7 @@ function enumerateRevisionCapableStories(editor) {
242806
243955
  kind: "story",
242807
243956
  storyType: "body"
242808
243957
  }];
242809
- const converter = getConverter$82(editor);
243958
+ const converter = getConverter$72(editor);
242810
243959
  if (!converter)
242811
243960
  return stories;
242812
243961
  if (converter.headers)
@@ -242823,10 +243972,11 @@ function enumerateRevisionCapableStories(editor) {
242823
243972
  storyType: "headerFooterPart",
242824
243973
  refId
242825
243974
  });
242826
- if (Array.isArray(converter.footnotes))
243975
+ if (Array.isArray(converter.footnotes)) {
243976
+ const tombstoned = collectTombstonedNoteIds(editor, converter, "footnote");
242827
243977
  for (const note of converter.footnotes) {
242828
243978
  const noteId = toRevisionCapableNoteId(note);
242829
- if (!noteId)
243979
+ if (!noteId || tombstoned.has(noteId))
242830
243980
  continue;
242831
243981
  stories.push({
242832
243982
  kind: "story",
@@ -242834,10 +243984,12 @@ function enumerateRevisionCapableStories(editor) {
242834
243984
  noteId
242835
243985
  });
242836
243986
  }
242837
- if (Array.isArray(converter.endnotes))
243987
+ }
243988
+ if (Array.isArray(converter.endnotes)) {
243989
+ const tombstoned = collectTombstonedNoteIds(editor, converter, "endnote");
242838
243990
  for (const note of converter.endnotes) {
242839
243991
  const noteId = toRevisionCapableNoteId(note);
242840
- if (!noteId)
243992
+ if (!noteId || tombstoned.has(noteId))
242841
243993
  continue;
242842
243994
  stories.push({
242843
243995
  kind: "story",
@@ -242845,8 +243997,26 @@ function enumerateRevisionCapableStories(editor) {
242845
243997
  noteId
242846
243998
  });
242847
243999
  }
244000
+ }
242848
244001
  return stories;
242849
244002
  }
244003
+ function collectTombstonedNoteIds(editor, converter, type) {
244004
+ const registry2 = converter.sessionManagedNoteIds?.[type === "endnote" ? "endnotes" : "footnotes"];
244005
+ if (!registry2 || registry2.size === 0)
244006
+ return /* @__PURE__ */ new Set;
244007
+ const referenceNodeName = type === "endnote" ? "endnoteReference" : "footnoteReference";
244008
+ const referenced = /* @__PURE__ */ new Set;
244009
+ editor.state?.doc?.descendants((node3) => {
244010
+ if (node3.type?.name === referenceNodeName && node3.attrs?.id != null)
244011
+ referenced.add(String(node3.attrs.id));
244012
+ return true;
244013
+ });
244014
+ const tombstoned = /* @__PURE__ */ new Set;
244015
+ for (const id2 of registry2)
244016
+ if (!referenced.has(id2))
244017
+ tombstoned.add(id2);
244018
+ return tombstoned;
244019
+ }
242850
244020
  function classifyStoryKind(locator) {
242851
244021
  switch (locator.storyType) {
242852
244022
  case "body":
@@ -254262,10 +255432,10 @@ function registerBuiltInExecutors() {
254262
255432
  };
254263
255433
  } });
254264
255434
  }
254265
- function getConverter$72(editor) {
255435
+ function getConverter$62(editor) {
254266
255436
  return editor.converter;
254267
255437
  }
254268
- function getConverter$62(editor) {
255438
+ function getConverter$52(editor) {
254269
255439
  return editor.converter;
254270
255440
  }
254271
255441
  function createEmptyHeaderFooterJson() {
@@ -254278,7 +255448,7 @@ function createEmptyHeaderFooterJson() {
254278
255448
  };
254279
255449
  }
254280
255450
  function syncHeaderFooterCaches(editor, part) {
254281
- const converter = getConverter$62(editor);
255451
+ const converter = getConverter$52(editor);
254282
255452
  if (!converter)
254283
255453
  return;
254284
255454
  const relsRoot = getRelationshipsRoot(part);
@@ -254340,7 +255510,7 @@ function createTableWrapper(editor, input2, options) {
254340
255510
  });
254341
255511
  return adapterResult;
254342
255512
  }
254343
- function getConverter$52(editor) {
255513
+ function getConverter$42(editor) {
254344
255514
  return editor.converter;
254345
255515
  }
254346
255516
  function toSectionFailure2(code6, message) {
@@ -254408,7 +255578,7 @@ function buildSectionMarginsForAttrs2(sectPr) {
254408
255578
  };
254409
255579
  }
254410
255580
  function syncConverterBodySection2(editor, sectPr) {
254411
- const converter = getConverter$52(editor);
255581
+ const converter = getConverter$42(editor);
254412
255582
  if (!converter)
254413
255583
  return;
254414
255584
  converter.bodySectPr = cloneXmlElement(sectPr);
@@ -254528,7 +255698,7 @@ function createSectionBreakNode(editor, breakParagraphId, input2) {
254528
255698
  return paragraphNode;
254529
255699
  }
254530
255700
  function updateGlobalTitlePageFlag(editor) {
254531
- const converter = getConverter$52(editor);
255701
+ const converter = getConverter$42(editor);
254532
255702
  if (!converter)
254533
255703
  return;
254534
255704
  const anyTitlePage = resolveSectionProjections(editor).some((entry) => entry.domain.titlePage === true);
@@ -254612,7 +255782,7 @@ function sectionsSetTitlePageAdapter(editor, input2, options) {
254612
255782
  }
254613
255783
  function sectionsSetOddEvenHeadersFootersAdapter(editor, input2, options) {
254614
255784
  rejectTrackedMode("sections.setOddEvenHeadersFooters", options);
254615
- const converter = getConverter$52(editor);
255785
+ const converter = getConverter$42(editor);
254616
255786
  if (!converter)
254617
255787
  throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", "sections.setOddEvenHeadersFooters requires an active document converter.");
254618
255788
  return mutatePart({
@@ -254648,13 +255818,13 @@ function sectionsSetSectionDirectionAdapter(editor, input2, options) {
254648
255818
  }
254649
255819
  function sectionsSetHeaderFooterRefAdapter(editor, input2, options) {
254650
255820
  return sectionMutationBySectPr$1(editor, input2, options, "sections.setHeaderFooterRef", (sectPr, _projection, _sections, dryRun) => {
254651
- const converter = getConverter$52(editor) ?? null;
255821
+ const converter = getConverter$42(editor) ?? null;
254652
255822
  return setHeaderFooterRefMutation(sectPr, input2.kind, input2.variant, input2.refId, converter, "sections.setHeaderFooterRef", dryRun);
254653
255823
  });
254654
255824
  }
254655
255825
  function sectionsClearHeaderFooterRefAdapter(editor, input2, options) {
254656
255826
  return sectionMutationBySectPr$1(editor, input2, options, "sections.clearHeaderFooterRef", (sectPr, _projection, _sections, dryRun) => {
254657
- const converter = getConverter$52(editor) ?? null;
255827
+ const converter = getConverter$42(editor) ?? null;
254658
255828
  clearHeaderFooterRefMutation(sectPr, input2.kind, input2.variant, converter, dryRun);
254659
255829
  });
254660
255830
  }
@@ -258503,11 +259673,11 @@ function createContentControlsAdapter(editor) {
258503
259673
  create: (input2, options) => createWrapper(editor, input2, options)
258504
259674
  };
258505
259675
  }
258506
- function getConverter$42(editor) {
259676
+ function getConverter$32(editor) {
258507
259677
  return editor.converter;
258508
259678
  }
258509
259679
  function requireConverter$1(editor, operationName) {
258510
- const converter = getConverter$42(editor);
259680
+ const converter = getConverter$32(editor);
258511
259681
  if (!converter)
258512
259682
  throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", `${operationName} requires an active document converter.`);
258513
259683
  return converter;
@@ -258613,7 +259783,7 @@ function headerFootersResolveAdapter(editor, input2) {
258613
259783
  function headerFootersRefsSetAdapter(editor, input2, options) {
258614
259784
  const { section, headerFooterKind, variant } = input2.target;
258615
259785
  const result = sectionMutationBySectPr(editor, { target: section }, options, "headerFooters.refs.set", (sectPr, _projection, _sections, dryRun) => {
258616
- const converter = getConverter$42(editor) ?? null;
259786
+ const converter = getConverter$32(editor) ?? null;
258617
259787
  return setHeaderFooterRefMutation(sectPr, headerFooterKind, variant, input2.refId, converter, "headerFooters.refs.set", dryRun);
258618
259788
  });
258619
259789
  invalidateSlotRuntimesAfterRefChange(editor, result, options);
@@ -258622,7 +259792,7 @@ function headerFootersRefsSetAdapter(editor, input2, options) {
258622
259792
  function headerFootersRefsClearAdapter(editor, input2, options) {
258623
259793
  const { section, headerFooterKind, variant } = input2.target;
258624
259794
  const result = sectionMutationBySectPr(editor, { target: section }, options, "headerFooters.refs.clear", (sectPr, _projection, _sections, dryRun) => {
258625
- clearHeaderFooterRefMutation(sectPr, headerFooterKind, variant, getConverter$42(editor) ?? null, dryRun);
259795
+ clearHeaderFooterRefMutation(sectPr, headerFooterKind, variant, getConverter$32(editor) ?? null, dryRun);
258626
259796
  });
258627
259797
  invalidateSlotRuntimesAfterRefChange(editor, result, options);
258628
259798
  return result;
@@ -258859,42 +260029,6 @@ function headerFootersPartsDeleteAdapter(editor, input2, options) {
258859
260029
  partPath
258860
260030
  };
258861
260031
  }
258862
- function isSpecialEntry(entry) {
258863
- return SPECIAL_NOTE_TYPES.has(entry.type ?? "");
258864
- }
258865
- function normalizeNoteId(entry) {
258866
- return String(entry.id ?? "");
258867
- }
258868
- function findNoteEntryById(entries2, noteId) {
258869
- if (!Array.isArray(entries2))
258870
- return;
258871
- let fallback;
258872
- for (const entry of entries2) {
258873
- if (String(entry.id ?? "") !== noteId)
258874
- continue;
258875
- if (!isSpecialEntry(entry))
258876
- return entry;
258877
- fallback ??= entry;
258878
- }
258879
- return fallback;
258880
- }
258881
- function enumerateEffectiveNoteEntries(entries2) {
258882
- if (!Array.isArray(entries2))
258883
- return [];
258884
- const orderedIds = [];
258885
- const effectiveById = /* @__PURE__ */ new Map;
258886
- for (const entry of entries2) {
258887
- const noteId = normalizeNoteId(entry);
258888
- if (!effectiveById.has(noteId)) {
258889
- orderedIds.push(noteId);
258890
- effectiveById.set(noteId, entry);
258891
- continue;
258892
- }
258893
- if (isSpecialEntry(effectiveById.get(noteId)) && !isSpecialEntry(entry))
258894
- effectiveById.set(noteId, entry);
258895
- }
258896
- return orderedIds.map((noteId) => effectiveById.get(noteId));
258897
- }
258898
260032
  function normalizeStory(locator) {
258899
260033
  if (!locator || locator.storyType === "body")
258900
260034
  return;
@@ -259863,11 +260997,11 @@ function invalidateConverterCachesForPath(converter, partName) {
259863
260997
  version: null
259864
260998
  };
259865
260999
  }
259866
- function getConverter$32(editor) {
261000
+ function getConverter$22(editor) {
259867
261001
  return editor.converter ?? null;
259868
261002
  }
259869
261003
  function getConvertedXml$1(editor) {
259870
- return getConverter$32(editor)?.convertedXml ?? {};
261004
+ return getConverter$22(editor)?.convertedXml ?? {};
259871
261005
  }
259872
261006
  function toSummary$1(record) {
259873
261007
  const summary = {
@@ -259982,7 +261116,7 @@ function customXmlPartsCreateWrapper(editor, input2, options) {
259982
261116
  const probe = safeValidate(() => createCustomXmlPart(getConvertedXml$1(editor), {
259983
261117
  content: input2.content,
259984
261118
  schemaRefs: input2.schemaRefs
259985
- }, getConverter$32(editor)));
261119
+ }, getConverter$22(editor)));
259986
261120
  if (isWriteFailure(probe))
259987
261121
  return {
259988
261122
  changed: false,
@@ -260044,7 +261178,7 @@ function customXmlPartsPatchWrapper(editor, input2, options) {
260044
261178
  const probe = safeValidate(() => patchCustomXmlPart(getConvertedXml$1(editor), input2.target, {
260045
261179
  content: input2.content,
260046
261180
  schemaRefs: input2.schemaRefs
260047
- }, getConverter$32(editor)));
261181
+ }, getConverter$22(editor)));
260048
261182
  if (isWriteFailure(probe))
260049
261183
  return {
260050
261184
  changed: false,
@@ -260090,7 +261224,7 @@ function customXmlPartsRemoveWrapper(editor, input2, options) {
260090
261224
  changed: false,
260091
261225
  payload: targetNotFound()
260092
261226
  };
260093
- if (!removeCustomXmlPart(getConvertedXml$1(editor), input2.target, getConverter$32(editor)))
261227
+ if (!removeCustomXmlPart(getConvertedXml$1(editor), input2.target, getConverter$22(editor)))
260094
261228
  return {
260095
261229
  changed: false,
260096
261230
  payload: targetNotFound()
@@ -260131,14 +261265,14 @@ function failure(code6, message) {
260131
261265
  }
260132
261266
  };
260133
261267
  }
260134
- function getConverter$22(editor) {
261268
+ function getConverter$12(editor) {
260135
261269
  return editor.converter ?? null;
260136
261270
  }
260137
261271
  function getConvertedXml2(editor) {
260138
- return getConverter$22(editor)?.convertedXml ?? {};
261272
+ return getConverter$12(editor)?.convertedXml ?? {};
260139
261273
  }
260140
261274
  function markConverterDirty(editor) {
260141
- const converter = getConverter$22(editor);
261275
+ const converter = getConverter$12(editor);
260142
261276
  if (!converter)
260143
261277
  return;
260144
261278
  converter.documentModified = true;
@@ -260364,7 +261498,7 @@ function anchorOverlaps(editor, id2, within$1) {
260364
261498
  }
260365
261499
  function writeEntry(editor, namespace, id2, payload, dryRun) {
260366
261500
  const convertedXml = getConvertedXml2(editor);
260367
- const converter = getConverter$22(editor);
261501
+ const converter = getConverter$12(editor);
260368
261502
  const existing = findPartByNamespace(convertedXml, namespace);
260369
261503
  const entries2 = existing?.entries.filter((entry) => entry.id !== id2) ?? [];
260370
261504
  const next2 = {
@@ -260393,7 +261527,7 @@ function writeEntry(editor, namespace, id2, payload, dryRun) {
260393
261527
  }
260394
261528
  function removeEntry(editor, id2, dryRun) {
260395
261529
  const convertedXml = getConvertedXml2(editor);
260396
- const converter = getConverter$22(editor);
261530
+ const converter = getConverter$12(editor);
260397
261531
  const part = listMetadataParts(convertedXml).find((candidate) => candidate.entries.some((entry) => entry.id === id2));
260398
261532
  if (!part)
260399
261533
  return false;
@@ -260570,11 +261704,11 @@ function createAnchoredMetadataAdapter(editor) {
260570
261704
  resolve: (input2) => metadataResolveWrapper(editor, input2)
260571
261705
  };
260572
261706
  }
260573
- function getConverter$12(editor) {
261707
+ function getConverter2(editor) {
260574
261708
  return editor.converter ?? undefined;
260575
261709
  }
260576
261710
  function requireConverter(editor, operationName) {
260577
- const converter = getConverter$12(editor);
261711
+ const converter = getConverter2(editor);
260578
261712
  if (!converter)
260579
261713
  throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", `${operationName} requires an active document converter.`);
260580
261714
  return converter;
@@ -260597,7 +261731,7 @@ function protectionGetAdapter(editor) {
260597
261731
  const stored = getProtectionStorage(editor);
260598
261732
  if (stored?.initialized)
260599
261733
  return stored.state;
260600
- const converter = getConverter$12(editor);
261734
+ const converter = getConverter2(editor);
260601
261735
  return parseProtectionState(converter ? readSettingsRoot(converter) : null);
260602
261736
  }
260603
261737
  function protectionSetEditingRestrictionAdapter(editor, input2, options) {
@@ -260967,374 +262101,6 @@ function findMarkerPositions(editor, id2) {
260967
262101
  end: end$1
260968
262102
  };
260969
262103
  }
260970
- function getConverterStore(editor) {
260971
- return editor.converter ?? {};
260972
- }
260973
- function isLegacyFootnoteMap(value) {
260974
- return value != null && typeof value === "object" && !Array.isArray(value);
260975
- }
260976
- function extractTextFromNode(node3) {
260977
- if (node3 == null)
260978
- return "";
260979
- if (typeof node3 === "string")
260980
- return node3;
260981
- if (typeof node3 !== "object")
260982
- return "";
260983
- const candidate = node3;
260984
- if (typeof candidate.text === "string")
260985
- return candidate.text;
260986
- if (!Array.isArray(candidate.content))
260987
- return "";
260988
- return candidate.content.map((child) => extractTextFromNode(child)).join("");
260989
- }
260990
- function extractTextFromContent(content3) {
260991
- if (typeof content3 === "string")
260992
- return content3;
260993
- if (!Array.isArray(content3))
260994
- return "";
260995
- return content3.map((node3) => extractTextFromNode(node3)).filter((text5) => text5.length > 0).join(`
260996
- `);
260997
- }
260998
- function resolveCollectionContent(collection, noteId) {
260999
- if (!collection)
261000
- return "";
261001
- if (Array.isArray(collection))
261002
- return extractTextFromContent(findNoteEntryById(collection, noteId)?.content);
261003
- if (isLegacyFootnoteMap(collection))
261004
- return collection[noteId]?.content ?? "";
261005
- return "";
261006
- }
261007
- function findAllFootnotes(doc$12, typeFilter) {
261008
- const results = [];
261009
- doc$12.descendants((node3, pos) => {
261010
- if (node3.type.name === "footnoteReference") {
261011
- if (!typeFilter || typeFilter === "footnote") {
261012
- const noteId = String(node3.attrs?.id ?? "");
261013
- results.push({
261014
- node: node3,
261015
- pos,
261016
- noteId,
261017
- type: "footnote"
261018
- });
261019
- }
261020
- } else if (node3.type.name === "endnoteReference") {
261021
- if (!typeFilter || typeFilter === "endnote") {
261022
- const noteId = String(node3.attrs?.id ?? "");
261023
- results.push({
261024
- node: node3,
261025
- pos,
261026
- noteId,
261027
- type: "endnote"
261028
- });
261029
- }
261030
- }
261031
- return true;
261032
- });
261033
- return results;
261034
- }
261035
- function resolveFootnoteTarget(doc$12, target) {
261036
- const found2 = findAllFootnotes(doc$12).find((f2) => f2.noteId === target.noteId);
261037
- if (!found2)
261038
- throw new DocumentApiAdapterError("TARGET_NOT_FOUND", `Footnote/endnote with noteId "${target.noteId}" not found.`);
261039
- return found2;
261040
- }
261041
- function resolveDisplayNumber$2(editor, resolved) {
261042
- const store = getConverterStore(editor);
261043
- const numberMap = resolved.type === "footnote" ? store.footnoteNumberById : store.endnoteNumberById;
261044
- if (numberMap && numberMap[resolved.noteId] !== undefined)
261045
- return String(numberMap[resolved.noteId]);
261046
- return resolved.noteId;
261047
- }
261048
- function resolveContent2(editor, resolved) {
261049
- const store = getConverterStore(editor);
261050
- return resolveCollectionContent(resolved.type === "footnote" ? store.footnotes : store.endnotes, resolved.noteId);
261051
- }
261052
- function extractFootnoteInfo(editor, resolved) {
261053
- return {
261054
- address: {
261055
- kind: "entity",
261056
- entityType: "footnote",
261057
- noteId: resolved.noteId
261058
- },
261059
- type: resolved.type,
261060
- noteId: resolved.noteId,
261061
- displayNumber: resolveDisplayNumber$2(editor, resolved),
261062
- content: resolveContent2(editor, resolved)
261063
- };
261064
- }
261065
- function buildFootnoteDiscoveryItem(editor, resolved, evaluatedRevision) {
261066
- const domain2 = {
261067
- address: {
261068
- kind: "entity",
261069
- entityType: "footnote",
261070
- noteId: resolved.noteId
261071
- },
261072
- type: resolved.type,
261073
- noteId: resolved.noteId,
261074
- displayNumber: resolveDisplayNumber$2(editor, resolved),
261075
- content: resolveContent2(editor, resolved)
261076
- };
261077
- const handle3 = buildResolvedHandle(resolved.noteId, "stable", "node");
261078
- return buildDiscoveryItem(`footnote:${resolved.noteId}:${evaluatedRevision}`, handle3, domain2);
261079
- }
261080
- function footnoteSuccess(address2) {
261081
- return {
261082
- success: true,
261083
- footnote: address2
261084
- };
261085
- }
261086
- function footnoteFailure(code6, message) {
261087
- return {
261088
- success: false,
261089
- failure: {
261090
- code: code6,
261091
- message
261092
- }
261093
- };
261094
- }
261095
- function configSuccess$1() {
261096
- return { success: true };
261097
- }
261098
- function getConverter2(editor) {
261099
- const converter = editor.converter;
261100
- if (!converter)
261101
- throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", "converter not available.");
261102
- return converter;
261103
- }
261104
- function toNonNegativeInteger(value) {
261105
- const num = Number(value);
261106
- if (!Number.isInteger(num) || !Number.isFinite(num) || num < 0)
261107
- return null;
261108
- return num;
261109
- }
261110
- function collectUsedNoteIds(editor, converter, type) {
261111
- const used = /* @__PURE__ */ new Set;
261112
- const config2 = getNotesConfig(type);
261113
- for (const ref$1 of findAllFootnotes(editor.state.doc, type)) {
261114
- const parsed = toNonNegativeInteger(ref$1.noteId);
261115
- if (parsed != null)
261116
- used.add(parsed);
261117
- }
261118
- const ooxmlPart = converter.convertedXml?.[config2.partId];
261119
- if (ooxmlPart)
261120
- for (const el of getNoteElements(ooxmlPart, config2.childElementName)) {
261121
- const parsed = toNonNegativeInteger(el.attributes?.["w:id"]);
261122
- if (parsed != null)
261123
- used.add(parsed);
261124
- }
261125
- const cache$2 = converter[config2.converterKey];
261126
- if (Array.isArray(cache$2))
261127
- for (const entry of cache$2) {
261128
- const parsed = toNonNegativeInteger(entry.id);
261129
- if (parsed != null)
261130
- used.add(parsed);
261131
- }
261132
- return used;
261133
- }
261134
- function allocateNextNoteId(editor, converter, type) {
261135
- const used = collectUsedNoteIds(editor, converter, type);
261136
- let candidate = 1;
261137
- while (used.has(candidate))
261138
- candidate += 1;
261139
- return String(candidate);
261140
- }
261141
- function footnotesListWrapper(editor, query2) {
261142
- const doc$12 = editor.state.doc;
261143
- const revision = getRevision(editor);
261144
- const { total, items: paged } = paginate(findAllFootnotes(doc$12, query2?.type).map((f2) => buildFootnoteDiscoveryItem(editor, f2, revision)), query2?.offset, query2?.limit);
261145
- return buildDiscoveryResult({
261146
- evaluatedRevision: revision,
261147
- total,
261148
- items: paged,
261149
- page: {
261150
- limit: query2?.limit ?? total,
261151
- offset: query2?.offset ?? 0,
261152
- returned: paged.length
261153
- }
261154
- });
261155
- }
261156
- function footnotesGetWrapper(editor, input2) {
261157
- return extractFootnoteInfo(editor, resolveFootnoteTarget(editor.state.doc, input2.target));
261158
- }
261159
- function footnotesInsertWrapper(editor, input2, options) {
261160
- rejectTrackedMode("footnotes.insert", options);
261161
- checkRevision(editor, options?.expectedRevision);
261162
- const converter = getConverter2(editor);
261163
- const notesConfig = getNotesConfig(input2.type);
261164
- const noteId = allocateNextNoteId(editor, converter, input2.type);
261165
- const address2 = {
261166
- kind: "entity",
261167
- entityType: "footnote",
261168
- noteId
261169
- };
261170
- if (input2.body !== undefined)
261171
- return footnoteFailure("CAPABILITY_UNAVAILABLE", "footnotes.insert structured body content is only available on v2-backed sessions.");
261172
- if (options?.dryRun)
261173
- return footnoteSuccess(address2);
261174
- const nodeTypeName = input2.type === "endnote" ? "endnoteReference" : "footnoteReference";
261175
- const nodeType = editor.schema.nodes[nodeTypeName];
261176
- if (!nodeType)
261177
- throw new DocumentApiAdapterError("CAPABILITY_UNAVAILABLE", `footnotes.insert: node type "${nodeTypeName}" is not registered in the schema.`);
261178
- const resolved = resolveInlineInsertPosition(editor, input2.at, "footnotes.insert");
261179
- const { success } = compoundMutation({
261180
- editor,
261181
- source: `footnotes.insert:${input2.type}`,
261182
- affectedParts: [notesConfig.partId],
261183
- execute: () => {
261184
- bootstrapNotesPart(editor, input2.type);
261185
- mutatePart({
261186
- editor,
261187
- partId: notesConfig.partId,
261188
- operation: "mutate",
261189
- source: `footnotes.insert:${input2.type}`,
261190
- mutate({ part }) {
261191
- addNoteElement(part, notesConfig, noteId, input2.content);
261192
- }
261193
- });
261194
- const node3 = nodeType.create({ id: noteId });
261195
- const { tr } = editor.state;
261196
- tr.insert(resolved.from, node3);
261197
- editor.dispatch(tr);
261198
- clearIndexCache(editor);
261199
- return true;
261200
- }
261201
- });
261202
- if (!success)
261203
- return footnoteFailure("NO_OP", "Insert operation produced no change.");
261204
- return footnoteSuccess(address2);
261205
- }
261206
- function footnotesUpdateWrapper(editor, input2, options) {
261207
- rejectTrackedMode("footnotes.update", options);
261208
- const resolved = resolveFootnoteTarget(editor.state.doc, input2.target);
261209
- const address2 = {
261210
- kind: "entity",
261211
- entityType: "footnote",
261212
- noteId: resolved.noteId
261213
- };
261214
- if (input2.patch.body !== undefined)
261215
- return footnoteFailure("CAPABILITY_UNAVAILABLE", "footnotes.update structured body content is only available on v2-backed sessions.");
261216
- if (options?.dryRun || input2.patch.content === undefined)
261217
- return footnoteSuccess(address2);
261218
- const notesConfig = getNotesConfig(resolved.type);
261219
- mutatePart({
261220
- editor,
261221
- partId: notesConfig.partId,
261222
- operation: "mutate",
261223
- source: `footnotes.update:${resolved.type}`,
261224
- expectedRevision: options?.expectedRevision,
261225
- mutate({ part }) {
261226
- updateNoteElement(part, notesConfig, resolved.noteId, input2.patch.content);
261227
- }
261228
- });
261229
- return footnoteSuccess(address2);
261230
- }
261231
- function footnotesRemoveWrapper(editor, input2, options) {
261232
- rejectTrackedMode("footnotes.remove", options);
261233
- checkRevision(editor, options?.expectedRevision);
261234
- const resolved = resolveFootnoteTarget(editor.state.doc, input2.target);
261235
- const address2 = {
261236
- kind: "entity",
261237
- entityType: "footnote",
261238
- noteId: resolved.noteId
261239
- };
261240
- if (options?.dryRun)
261241
- return footnoteSuccess(address2);
261242
- const notesConfig = getNotesConfig(resolved.type);
261243
- const { success } = compoundMutation({
261244
- editor,
261245
- source: `footnotes.remove:${resolved.type}`,
261246
- affectedParts: [notesConfig.partId],
261247
- execute: () => {
261248
- const { tr } = editor.state;
261249
- const node3 = tr.doc.nodeAt(resolved.pos);
261250
- if (!node3)
261251
- return false;
261252
- tr.delete(resolved.pos, resolved.pos + node3.nodeSize);
261253
- editor.dispatch(tr);
261254
- if (!findAllFootnotes(editor.state.doc, resolved.type).some((f2) => f2.noteId === resolved.noteId))
261255
- mutatePart({
261256
- editor,
261257
- partId: notesConfig.partId,
261258
- operation: "mutate",
261259
- source: `footnotes.remove:${resolved.type}`,
261260
- mutate({ part }) {
261261
- removeNoteElement(part, notesConfig, resolved.noteId);
261262
- }
261263
- });
261264
- clearIndexCache(editor);
261265
- return true;
261266
- }
261267
- });
261268
- if (!success)
261269
- return footnoteFailure("NO_OP", "Remove operation produced no change.");
261270
- return footnoteSuccess(address2);
261271
- }
261272
- function footnotesConfigureWrapper(editor, input2, options) {
261273
- rejectTrackedMode("footnotes.configure", options);
261274
- const prElementName = input2.type === "endnote" ? "w:endnotePr" : "w:footnotePr";
261275
- mutatePart({
261276
- editor,
261277
- partId: "word/settings.xml",
261278
- operation: "mutate",
261279
- source: `footnotes.configure:${input2.type}`,
261280
- dryRun: options?.dryRun,
261281
- expectedRevision: options?.expectedRevision,
261282
- mutate({ part }) {
261283
- const root3 = part?.elements?.[0];
261284
- if (!root3)
261285
- return;
261286
- if (!root3.elements)
261287
- root3.elements = [];
261288
- const elements = root3.elements;
261289
- let prElement = elements.find((el) => el.name === prElementName);
261290
- if (!prElement) {
261291
- prElement = {
261292
- type: "element",
261293
- name: prElementName,
261294
- elements: []
261295
- };
261296
- elements.push(prElement);
261297
- }
261298
- if (!prElement.elements)
261299
- prElement.elements = [];
261300
- if (!input2.numbering)
261301
- return;
261302
- const setOrRemoveChild = (name, value) => {
261303
- if (value === undefined)
261304
- return;
261305
- const children = prElement.elements;
261306
- const existing = children.findIndex((el) => el.name === name);
261307
- const newEl = {
261308
- type: "element",
261309
- name,
261310
- attributes: { "w:val": value }
261311
- };
261312
- if (existing >= 0)
261313
- children[existing] = newEl;
261314
- else
261315
- children.push(newEl);
261316
- };
261317
- setOrRemoveChild("w:numFmt", input2.numbering.format);
261318
- setOrRemoveChild("w:numStart", input2.numbering.start !== undefined ? String(input2.numbering.start) : undefined);
261319
- if (input2.numbering.restartPolicy !== undefined)
261320
- setOrRemoveChild("w:numRestart", RESTART_POLICY_TO_OOXML[input2.numbering.restartPolicy] ?? input2.numbering.restartPolicy);
261321
- setOrRemoveChild("w:pos", input2.numbering.position);
261322
- }
261323
- });
261324
- if (!options?.dryRun && prElementName === "w:footnotePr")
261325
- syncFootnotePropertiesCache(editor);
261326
- return configSuccess$1();
261327
- }
261328
- function syncFootnotePropertiesCache(editor) {
261329
- const converter = getConverter2(editor);
261330
- if (!converter?.footnoteProperties || converter.footnoteProperties.source !== "settings")
261331
- return;
261332
- const prElement = (converter.convertedXml?.["word/settings.xml"]?.elements?.[0]?.elements ?? []).find((el) => el.name === "w:footnotePr");
261333
- if (prElement)
261334
- converter.footnoteProperties.originalXml = structuredClone(prElement);
261335
- else
261336
- converter.footnoteProperties = null;
261337
- }
261338
262104
  function findAllCrossRefs(doc$12) {
261339
262105
  const results = [];
261340
262106
  doc$12.descendants((node3, pos) => {
@@ -262383,7 +263149,7 @@ function captionFailure(code6, message) {
262383
263149
  }
262384
263150
  };
262385
263151
  }
262386
- function configSuccess() {
263152
+ function configSuccess2() {
262387
263153
  return { success: true };
262388
263154
  }
262389
263155
  function configFailure(code6, message) {
@@ -262539,7 +263305,7 @@ function captionsRemoveWrapper(editor, input2, options) {
262539
263305
  function captionsConfigureWrapper(editor, input2, options) {
262540
263306
  rejectTrackedMode("captions.configure", options);
262541
263307
  if (options?.dryRun)
262542
- return configSuccess();
263308
+ return configSuccess2();
262543
263309
  if (!receiptApplied$3(executeDomainCommand(editor, () => {
262544
263310
  const { tr } = editor.state;
262545
263311
  let changed = false;
@@ -262578,7 +263344,7 @@ function captionsConfigureWrapper(editor, input2, options) {
262578
263344
  return true;
262579
263345
  }, { expectedRevision: options?.expectedRevision })))
262580
263346
  return configFailure("NO_OP", "Configure produced no change.");
262581
- return configSuccess();
263347
+ return configSuccess2();
262582
263348
  }
262583
263349
  function fieldSuccess(address2) {
262584
263350
  return {
@@ -275443,7 +276209,94 @@ function invalidateHeaderFooterCache(cache$2, cacheState, headerBlocks, footerBl
275443
276209
  HeaderFooterCacheLogger.logInvalidation(invalidationReasons.join(", "), uniqueBlockIds);
275444
276210
  }
275445
276211
  }
275446
- async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, options, measureBlock$1, headerFooter, previousMeasures, fontRuntime) {
276212
+ async function measureNoteBlocks(ids, blocksById, constraints, measureBlock$1, fontSignature) {
276213
+ const needed = /* @__PURE__ */ new Map;
276214
+ ids.forEach((id2) => {
276215
+ (blocksById.get(id2) ?? []).forEach((block) => {
276216
+ if (block?.id && !needed.has(block.id))
276217
+ needed.set(block.id, block);
276218
+ });
276219
+ });
276220
+ const blocks2 = Array.from(needed.values());
276221
+ const measuresById = /* @__PURE__ */ new Map;
276222
+ await Promise.all(blocks2.map(async (block) => {
276223
+ const cached = measureCache.get(block, constraints.maxWidth, constraints.maxHeight, fontSignature);
276224
+ if (cached) {
276225
+ measuresById.set(block.id, cached);
276226
+ return;
276227
+ }
276228
+ const measurement = await measureBlock$1(block, constraints);
276229
+ measureCache.set(block, constraints.maxWidth, constraints.maxHeight, measurement, fontSignature);
276230
+ measuresById.set(block.id, measurement);
276231
+ }));
276232
+ return {
276233
+ blocks: blocks2,
276234
+ measuresById
276235
+ };
276236
+ }
276237
+ function computeNoteBodyHeights(footnotesInput, measures) {
276238
+ const totalMap = /* @__PURE__ */ new Map;
276239
+ const firstLineMap = /* @__PURE__ */ new Map;
276240
+ footnotesInput.blocksById.forEach((blocks2, footnoteId) => {
276241
+ let total = 0;
276242
+ let firstLine = 0;
276243
+ for (const block of blocks2) {
276244
+ const measure = measures.get(block.id);
276245
+ if (!measure)
276246
+ continue;
276247
+ if (measure.kind === "paragraph") {
276248
+ const measureH = measure.totalHeight;
276249
+ if (typeof measureH === "number" && Number.isFinite(measureH))
276250
+ total += measureH;
276251
+ const spacing = block.attrs?.spacing;
276252
+ const after2 = spacing?.after ?? spacing?.lineSpaceAfter;
276253
+ if (typeof after2 === "number" && Number.isFinite(after2) && after2 > 0)
276254
+ total += after2;
276255
+ if (firstLine === 0) {
276256
+ const lines = measure.lines;
276257
+ const lh = lines && lines.length > 0 ? lines[0].lineHeight : undefined;
276258
+ if (typeof lh === "number" && Number.isFinite(lh) && lh > 0)
276259
+ firstLine = lh;
276260
+ }
276261
+ } else if (measure.kind === "image" || measure.kind === "drawing") {
276262
+ const measureH = measure.height;
276263
+ if (typeof measureH === "number" && Number.isFinite(measureH))
276264
+ total += measureH;
276265
+ if (firstLine === 0 && typeof measureH === "number" && Number.isFinite(measureH))
276266
+ firstLine = measureH;
276267
+ } else if (measure.kind === "table") {
276268
+ const measureH = measure.totalHeight;
276269
+ if (typeof measureH === "number" && Number.isFinite(measureH))
276270
+ total += measureH;
276271
+ if (firstLine === 0 && typeof measureH === "number" && Number.isFinite(measureH))
276272
+ firstLine = measureH;
276273
+ } else if (measure.kind === "list" && block.kind === "list") {
276274
+ for (const item of block.items) {
276275
+ const itemMeasure = measure.items.find((entry) => entry.itemId === item.id);
276276
+ if (!itemMeasure?.paragraph?.lines)
276277
+ continue;
276278
+ for (const line of itemMeasure.paragraph.lines)
276279
+ total += line.lineHeight ?? 0;
276280
+ total += getParagraphSpacingAfter(item.paragraph);
276281
+ }
276282
+ if (firstLine === 0) {
276283
+ const lh = measure.items[0]?.paragraph?.lines?.[0]?.lineHeight;
276284
+ if (typeof lh === "number" && Number.isFinite(lh) && lh > 0)
276285
+ firstLine = lh;
276286
+ }
276287
+ }
276288
+ }
276289
+ if (total > 0)
276290
+ totalMap.set(footnoteId, total);
276291
+ if (firstLine > 0)
276292
+ firstLineMap.set(footnoteId, firstLine);
276293
+ });
276294
+ return {
276295
+ totalMap,
276296
+ firstLineMap
276297
+ };
276298
+ }
276299
+ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, options, measureBlock$1, headerFooter, previousMeasures, fontRuntime, warmStart) {
275447
276300
  const fontSignature = fontRuntime?.fontContext?.fontSignature ?? "";
275448
276301
  const previousFontSignature = fontRuntime?.previousFontSignature ?? "";
275449
276302
  const isSemanticFlow = options.flowMode === "semantic";
@@ -275624,9 +276477,35 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275624
276477
  }
275625
276478
  perfLog$1(`[Perf] 4.1.6 Pre-layout footers for height: ${(performance.now() - footerPreStart).toFixed(2)}ms`);
275626
276479
  }
276480
+ const earlyFootnotesInput = isFootnotesLayoutInput(options.footnotes) ? options.footnotes : null;
276481
+ const warmSeed = warmStart?.footnoteReserveSeed ?? null;
276482
+ const warmSeedUsable = !isSemanticFlow && warmSeed !== null && warmSeed.reserves.some((h$2) => h$2 > 0) && warmSeed.fontSignature === fontSignature && warmSeed.measurementWidth === measurementWidth && warmSeed.measurementHeight === measurementHeight && earlyFootnotesInput !== null && earlyFootnotesInput.refs.length > 0 && earlyFootnotesInput.blocksById.size > 0;
276483
+ let seededInitialLayout = false;
276484
+ let seededInitialOptions = {};
276485
+ if (warmSeedUsable) {
276486
+ const earlyFootnoteWidth = resolveFootnoteMeasurementWidth(options, nextBlocks);
276487
+ if (earlyFootnoteWidth > 0) {
276488
+ const { measuresById } = await measureNoteBlocks(new Set(earlyFootnotesInput.refs.map((ref$1) => ref$1.id)), earlyFootnotesInput.blocksById, {
276489
+ maxWidth: earlyFootnoteWidth,
276490
+ maxHeight: measurementHeight
276491
+ }, measureBlock$1, fontSignature);
276492
+ const { totalMap, firstLineMap } = computeNoteBodyHeights(earlyFootnotesInput, measuresById);
276493
+ seededInitialOptions = {
276494
+ footnoteReservedByPageIndex: warmSeed.reserves,
276495
+ footnotes: {
276496
+ ...earlyFootnotesInput,
276497
+ bodyHeightById: totalMap,
276498
+ firstLineHeightById: firstLineMap,
276499
+ ...typeof warmSeed.separatorSpacingBefore === "number" && Number.isFinite(warmSeed.separatorSpacingBefore) ? { separatorSpacingBefore: warmSeed.separatorSpacingBefore } : {}
276500
+ }
276501
+ };
276502
+ seededInitialLayout = true;
276503
+ }
276504
+ }
275627
276505
  const layoutStart = performance.now();
275628
276506
  let layout = layoutDocument(nextBlocks, measures, {
275629
276507
  ...options,
276508
+ ...seededInitialOptions,
275630
276509
  headerContentHeights,
275631
276510
  footerContentHeights,
275632
276511
  headerContentHeightsBySectionRef,
@@ -275673,6 +276552,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275673
276552
  const relayoutStart = performance.now();
275674
276553
  layout = layoutDocument(currentBlocks, currentMeasures, {
275675
276554
  ...options,
276555
+ ...seededInitialOptions,
275676
276556
  headerContentHeights,
275677
276557
  footerContentHeights,
275678
276558
  headerContentHeightsBySectionRef,
@@ -275707,6 +276587,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275707
276587
  }
275708
276588
  let extraBlocks;
275709
276589
  let extraMeasures;
276590
+ let nextFootnoteReserveSeed = null;
275710
276591
  const footnotesInput = isFootnotesLayoutInput(options.footnotes) ? options.footnotes : null;
275711
276592
  if (!isSemanticFlow && footnotesInput && footnotesInput.refs.length > 0 && footnotesInput.blocksById.size > 0) {
275712
276593
  const gap = typeof footnotesInput.gap === "number" && Number.isFinite(footnotesInput.gap) ? footnotesInput.gap : 2;
@@ -275732,31 +276613,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275732
276613
  });
275733
276614
  return ids;
275734
276615
  };
275735
- const measureFootnoteBlocks = async (ids) => {
275736
- const needed = /* @__PURE__ */ new Map;
275737
- ids.forEach((id2) => {
275738
- (footnotesInput.blocksById.get(id2) ?? []).forEach((block) => {
275739
- if (block?.id && !needed.has(block.id))
275740
- needed.set(block.id, block);
275741
- });
275742
- });
275743
- const blocks2 = Array.from(needed.values());
275744
- const measuresById$1 = /* @__PURE__ */ new Map;
275745
- await Promise.all(blocks2.map(async (block) => {
275746
- const cached = measureCache.get(block, footnoteConstraints.maxWidth, footnoteConstraints.maxHeight, fontSignature);
275747
- if (cached) {
275748
- measuresById$1.set(block.id, cached);
275749
- return;
275750
- }
275751
- const measurement = await measureBlock$1(block, footnoteConstraints);
275752
- measureCache.set(block, footnoteConstraints.maxWidth, footnoteConstraints.maxHeight, measurement, fontSignature);
275753
- measuresById$1.set(block.id, measurement);
275754
- }));
275755
- return {
275756
- blocks: blocks2,
275757
- measuresById: measuresById$1
275758
- };
275759
- };
276616
+ const measureFootnoteBlocks = (ids) => measureNoteBlocks(ids, footnotesInput.blocksById, footnoteConstraints, measureBlock$1, fontSignature);
275760
276617
  const computeFootnoteLayoutPlan = (layoutForPages, idsByColumn$1, measuresById$1, baseReserves = [], pageColumns$1) => {
275761
276618
  const pageCount = layoutForPages.pages.length;
275762
276619
  const slicesByPage = /* @__PURE__ */ new Map;
@@ -276025,6 +276882,33 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
276025
276882
  lastAnchorRenderedLines
276026
276883
  });
276027
276884
  }
276885
+ const clusterDemandFor = (targetPageIndex, lastEntryFirstLineOnly) => {
276886
+ let demand = 0;
276887
+ for (let cIdx = 0;cIdx < columnCount; cIdx += 1) {
276888
+ const ids = idsByColumn$1.get(targetPageIndex)?.get(cIdx) ?? [];
276889
+ if (ids.length === 0)
276890
+ continue;
276891
+ let columnCluster = 0;
276892
+ for (let i3 = 0;i3 < ids.length; i3 += 1) {
276893
+ const isLast = i3 === ids.length - 1;
276894
+ columnCluster += lastEntryFirstLineOnly && isLast ? firstLineOf(ids[i3]) : fullHeightOf(ids[i3]);
276895
+ if (i3 > 0)
276896
+ columnCluster += safeGap;
276897
+ }
276898
+ if (columnCluster > demand)
276899
+ demand = columnCluster;
276900
+ }
276901
+ return demand;
276902
+ };
276903
+ const maxBandFor = (targetPageIndex) => {
276904
+ const page = layoutForPages.pages?.[targetPageIndex];
276905
+ const size$1 = page?.size ?? layoutForPages.pageSize ?? DEFAULT_PAGE_SIZE$1;
276906
+ const top$1 = normalizeMargin(page?.margins?.top, DEFAULT_MARGINS$1.top);
276907
+ const bottom$1 = normalizeMargin(page?.margins?.bottom, DEFAULT_MARGINS$1.bottom);
276908
+ const physicalContentHeight = Math.max(0, size$1.h - top$1 - bottom$1);
276909
+ return Math.max(0, physicalContentHeight - MIN_FOOTNOTE_BODY_HEIGHT * 20);
276910
+ };
276911
+ const bandOverhead = safeSeparatorSpacingBefore + continuationDividerHeight + safeTopPadding;
276028
276912
  if (pageIndex + 1 < pageCount) {
276029
276913
  let continuationDemand = 0;
276030
276914
  pendingByColumn.forEach((entries2) => {
@@ -276035,37 +276919,22 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
276035
276919
  });
276036
276920
  });
276037
276921
  });
276038
- let nextClusterDemand = 0;
276039
- for (let cIdx = 0;cIdx < columnCount; cIdx += 1) {
276040
- const idsNext = idsByColumn$1.get(pageIndex + 1)?.get(cIdx) ?? [];
276041
- if (idsNext.length === 0)
276042
- continue;
276043
- let columnCluster = 0;
276044
- for (let i3 = 0;i3 < idsNext.length; i3 += 1) {
276045
- const isLast = i3 === idsNext.length - 1;
276046
- columnCluster += isLast ? firstLineOf(idsNext[i3]) : fullHeightOf(idsNext[i3]);
276047
- if (i3 > 0)
276048
- columnCluster += safeGap;
276049
- }
276050
- if (columnCluster > nextClusterDemand)
276051
- nextClusterDemand = columnCluster;
276052
- }
276922
+ const nextClusterDemand = clusterDemandFor(pageIndex + 1, true);
276053
276923
  if (continuationDemand > 0 || nextClusterDemand > 0) {
276054
- const overhead = safeSeparatorSpacingBefore + continuationDividerHeight + safeTopPadding;
276055
- const nextPage = layoutForPages.pages?.[pageIndex + 1];
276056
- const nextPageSize = nextPage?.size ?? layoutForPages.pageSize ?? DEFAULT_PAGE_SIZE$1;
276057
- const nextTop = normalizeMargin(nextPage?.margins?.top, DEFAULT_MARGINS$1.top);
276058
- const nextBottomRaw = normalizeMargin(nextPage?.margins?.bottom, DEFAULT_MARGINS$1.bottom);
276059
- const physicalContentHeight = Math.max(0, nextPageSize.h - nextTop - nextBottomRaw);
276060
- const minBodyHeight = MIN_FOOTNOTE_BODY_HEIGHT * 20;
276061
- const nextPageMaxBand = Math.max(0, physicalContentHeight - minBodyHeight);
276062
- const overheadForBand = nextClusterDemand > 0 || continuationDemand > 0 ? overhead : 0;
276924
+ const nextPageMaxBand = maxBandFor(pageIndex + 1);
276925
+ const overheadForBand = nextClusterDemand > 0 || continuationDemand > 0 ? bandOverhead : 0;
276063
276926
  const clusterRoomPx = nextClusterDemand > 0 ? Math.min(nextClusterDemand, Math.max(0, nextPageMaxBand - overheadForBand)) : 0;
276064
276927
  const continuationRoomPx = Math.max(0, nextPageMaxBand - overheadForBand - clusterRoomPx);
276065
276928
  const continuationToReservePx = Math.min(continuationDemand, continuationRoomPx);
276066
276929
  const finalReserve = Math.min(clusterRoomPx + continuationToReservePx + overheadForBand, nextPageMaxBand);
276067
276930
  reserves$1[pageIndex + 1] = Math.max(reserves$1[pageIndex + 1] ?? 0, Math.ceil(finalReserve));
276068
276931
  }
276932
+ } else {
276933
+ const clusterDemand = clusterDemandFor(pageIndex, false);
276934
+ if (clusterDemand > 0 && (reserves$1[pageIndex] ?? 0) < clusterDemand) {
276935
+ const finalReserve = Math.min(clusterDemand + bandOverhead, maxBandFor(pageIndex));
276936
+ reserves$1[pageIndex] = Math.max(reserves$1[pageIndex] ?? 0, Math.ceil(finalReserve));
276937
+ }
276069
276938
  }
276070
276939
  }
276071
276940
  if (cappedPages.size > 0)
@@ -276339,62 +277208,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
276339
277208
  let bodyHeightById = /* @__PURE__ */ new Map;
276340
277209
  let firstLineHeightById = /* @__PURE__ */ new Map;
276341
277210
  const refreshBodyHeights = (measures$1) => {
276342
- const totalMap = /* @__PURE__ */ new Map;
276343
- const firstLineMap = /* @__PURE__ */ new Map;
276344
- footnotesInput.blocksById.forEach((blocks2, footnoteId) => {
276345
- let total = 0;
276346
- let firstLine = 0;
276347
- for (const block of blocks2) {
276348
- const measure = measures$1.get(block.id);
276349
- if (!measure)
276350
- continue;
276351
- if (measure.kind === "paragraph") {
276352
- const measureH = measure.totalHeight;
276353
- if (typeof measureH === "number" && Number.isFinite(measureH))
276354
- total += measureH;
276355
- const spacing = block.attrs?.spacing;
276356
- const after2 = spacing?.after ?? spacing?.lineSpaceAfter;
276357
- if (typeof after2 === "number" && Number.isFinite(after2) && after2 > 0)
276358
- total += after2;
276359
- if (firstLine === 0) {
276360
- const lines = measure.lines;
276361
- const lh = lines && lines.length > 0 ? lines[0].lineHeight : undefined;
276362
- if (typeof lh === "number" && Number.isFinite(lh) && lh > 0)
276363
- firstLine = lh;
276364
- }
276365
- } else if (measure.kind === "image" || measure.kind === "drawing") {
276366
- const measureH = measure.height;
276367
- if (typeof measureH === "number" && Number.isFinite(measureH))
276368
- total += measureH;
276369
- if (firstLine === 0 && typeof measureH === "number" && Number.isFinite(measureH))
276370
- firstLine = measureH;
276371
- } else if (measure.kind === "table") {
276372
- const measureH = measure.totalHeight;
276373
- if (typeof measureH === "number" && Number.isFinite(measureH))
276374
- total += measureH;
276375
- if (firstLine === 0 && typeof measureH === "number" && Number.isFinite(measureH))
276376
- firstLine = measureH;
276377
- } else if (measure.kind === "list" && block.kind === "list") {
276378
- for (const item of block.items) {
276379
- const itemMeasure = measure.items.find((entry) => entry.itemId === item.id);
276380
- if (!itemMeasure?.paragraph?.lines)
276381
- continue;
276382
- for (const line of itemMeasure.paragraph.lines)
276383
- total += line.lineHeight ?? 0;
276384
- total += getParagraphSpacingAfter(item.paragraph);
276385
- }
276386
- if (firstLine === 0) {
276387
- const lh = measure.items[0]?.paragraph?.lines?.[0]?.lineHeight;
276388
- if (typeof lh === "number" && Number.isFinite(lh) && lh > 0)
276389
- firstLine = lh;
276390
- }
276391
- }
276392
- }
276393
- if (total > 0)
276394
- totalMap.set(footnoteId, total);
276395
- if (firstLine > 0)
276396
- firstLineMap.set(footnoteId, firstLine);
276397
- });
277211
+ const { totalMap, firstLineMap } = computeNoteBodyHeights(footnotesInput, measures$1);
276398
277212
  bodyHeightById = totalMap;
276399
277213
  firstLineHeightById = firstLineMap;
276400
277214
  };
@@ -276438,21 +277252,36 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
276438
277252
  let { columns: pageColumns, idsByColumn } = resolveFootnoteAssignments(layout);
276439
277253
  let { measuresById } = await measureFootnoteBlocks(allFootnoteIds);
276440
277254
  refreshBodyHeights(measuresById);
276441
- let plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, [], pageColumns);
277255
+ let plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, seededInitialLayout && warmSeed ? warmSeed.reserves : [], pageColumns);
276442
277256
  let reserves = plan.reserves;
276443
277257
  logFootnoteLayoutPhase("initial-plan", layout, reserves, plan.reserves, { assignedFootnoteCount: collectFootnoteIdsByColumn(idsByColumn).size });
277258
+ let seededSep;
277259
+ let seedApplied = false;
277260
+ if (warmSeedUsable && warmSeed && reserves.some((h$2) => h$2 > 0)) {
277261
+ reserves = warmSeed.reserves.slice();
277262
+ seededSep = warmSeed.separatorSpacingBefore;
277263
+ seedApplied = true;
277264
+ if (typeof seededSep === "number" && Number.isFinite(seededSep))
277265
+ plan = {
277266
+ ...plan,
277267
+ separatorSpacingBefore: seededSep
277268
+ };
277269
+ }
276444
277270
  if (reserves.some((h$2) => h$2 > 0)) {
276445
277271
  let reservesStabilized = false;
276446
- const seenReserveVectors = [reserves.slice()];
276447
- for (let pass = 0;pass < MAX_FOOTNOTE_LAYOUT_PASSES; pass += 1) {
277272
+ if (seedApplied && seededInitialLayout && plan.reserves.length === reserves.length && plan.reserves.every((h$2, i3) => (reserves[i3] ?? 0) === h$2) && reserves.every((h$2, i3) => (plan.reserves[i3] ?? 0) === h$2) && (seededSep === undefined || plan.separatorSpacingBefore === seededSep))
277273
+ reservesStabilized = true;
277274
+ const seenReserveVectors = seedApplied ? [] : [reserves.slice()];
277275
+ for (let pass = 0;!reservesStabilized && pass < MAX_FOOTNOTE_LAYOUT_PASSES; pass += 1) {
276448
277276
  layout = relayout(reserves, plan.separatorSpacingBefore);
276449
277277
  ({ columns: pageColumns, idsByColumn } = resolveFootnoteAssignments(layout));
276450
277278
  ({ measuresById } = await measureFootnoteBlocks(allFootnoteIds));
276451
277279
  refreshBodyHeights(measuresById);
276452
277280
  plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, reserves, pageColumns);
276453
277281
  const nextReserves = plan.reserves;
277282
+ const sepConsistent = !seedApplied || pass > 0 || plan.separatorSpacingBefore === seededSep || seededSep === undefined;
276454
277283
  logFootnoteLayoutPhase(`reserve-loop-pass-${pass + 1}`, layout, reserves, nextReserves, { assignedFootnoteCount: collectFootnoteIdsByColumn(idsByColumn).size });
276455
- if (nextReserves.length === reserves.length && nextReserves.every((h$2, i3) => (reserves[i3] ?? 0) === h$2) && reserves.every((h$2, i3) => (nextReserves[i3] ?? 0) === h$2)) {
277284
+ if (sepConsistent && nextReserves.length === reserves.length && nextReserves.every((h$2, i3) => (reserves[i3] ?? 0) === h$2) && reserves.every((h$2, i3) => (nextReserves[i3] ?? 0) === h$2)) {
276456
277285
  reserves = nextReserves;
276457
277286
  reservesStabilized = true;
276458
277287
  break;
@@ -276711,6 +277540,16 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
276711
277540
  });
276712
277541
  extraBlocks = injected ? alignedBlocks.concat(injected.decorativeBlocks) : alignedBlocks;
276713
277542
  extraMeasures = injected ? alignedMeasures.concat(injected.decorativeMeasures) : alignedMeasures;
277543
+ if (reservesAppliedToLayout.some((h$2) => h$2 > 0))
277544
+ nextFootnoteReserveSeed = {
277545
+ reserves: reservesAppliedToLayout.slice(),
277546
+ separatorSpacingBefore: finalPlan.separatorSpacingBefore,
277547
+ fontSignature,
277548
+ measurementWidth,
277549
+ measurementHeight
277550
+ };
277551
+ if (!(finalPlan.reserves.length <= reservesAppliedToLayout.length && reservesAppliedToLayout.every((h$2, i3) => (finalPlan.reserves[i3] ?? 0) === (h$2 ?? 0)) && finalPlan.reserves.every((h$2, i3) => (reservesAppliedToLayout[i3] ?? 0) === (h$2 ?? 0))))
277552
+ perfLog$1(`[Perf] 4.5 footnote warm-start: captured a near-fixed-point (stabilized=${reservesStabilized}); next run settles it`);
276714
277553
  }
276715
277554
  }
276716
277555
  }
@@ -276759,7 +277598,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
276759
277598
  headers,
276760
277599
  footers,
276761
277600
  extraBlocks,
276762
- extraMeasures
277601
+ extraMeasures,
277602
+ footnoteReserveSeed: nextFootnoteReserveSeed
276763
277603
  };
276764
277604
  }
276765
277605
  function hydrateTableTextboxMeasures(blocks2, remeasure) {
@@ -279555,6 +280395,7 @@ function buildFootnotesInput(editorState, converter, converterContext, themeColo
279555
280395
  if (refs.length === 0)
279556
280396
  return null;
279557
280397
  const blocksById = /* @__PURE__ */ new Map;
280398
+ const docDefaultRunProps = resolveDocDefaultRunProps(converterContext);
279558
280399
  idsInUse.forEach((id2) => {
279559
280400
  try {
279560
280401
  const footnoteDoc = resolveNoteDocJson(id2, importedFootnotes, renderOverride);
@@ -279575,7 +280416,7 @@ function buildFootnotesInput(editorState, converter, converterContext, themeColo
279575
280416
  if (result?.blocks?.length) {
279576
280417
  if (!customMarkIds.has(id2)) {
279577
280418
  const numFmtForId = footnoteFormatById?.[id2] ?? footnoteNumberFormat;
279578
- ensureFootnoteMarker(result.blocks, id2, footnoteNumberById, numFmtForId);
280419
+ ensureFootnoteMarker(result.blocks, id2, footnoteNumberById, numFmtForId, docDefaultRunProps);
279579
280420
  }
279580
280421
  blocksById.set(id2, result.blocks);
279581
280422
  }
@@ -279602,21 +280443,32 @@ function resolveDisplayNumber$1(id2, footnoteNumberById) {
279602
280443
  return num;
279603
280444
  return 1;
279604
280445
  }
279605
- function resolveMarkerFontFamily$1(firstTextRun) {
279606
- return typeof firstTextRun?.fontFamily === "string" ? firstTextRun.fontFamily : DEFAULT_MARKER_FONT_FAMILY$1;
280446
+ function resolveDocDefaultRunProps(converterContext) {
280447
+ return converterContext?.translatedLinkedStyles?.docDefaults?.runProperties;
280448
+ }
280449
+ function resolveMarkerFontFamily$1(firstTextRun, docDefaults) {
280450
+ if (typeof firstTextRun?.fontFamily === "string")
280451
+ return firstTextRun.fontFamily;
280452
+ const ascii = docDefaults?.fontFamily?.ascii;
280453
+ if (typeof ascii === "string" && ascii.length > 0)
280454
+ return ascii;
280455
+ return DEFAULT_MARKER_FONT_FAMILY$1;
279607
280456
  }
279608
- function resolveMarkerBaseFontSize$1(firstTextRun) {
280457
+ function resolveMarkerBaseFontSize$1(firstTextRun, docDefaults) {
279609
280458
  if (typeof firstTextRun?.fontSize === "number" && Number.isFinite(firstTextRun.fontSize) && firstTextRun.fontSize > 0)
279610
280459
  return firstTextRun.fontSize;
280460
+ const halfPoints = docDefaults?.fontSize;
280461
+ if (typeof halfPoints === "number" && Number.isFinite(halfPoints) && halfPoints > 0)
280462
+ return halfPoints / 2 / 0.75;
279611
280463
  return DEFAULT_MARKER_FONT_SIZE$1;
279612
280464
  }
279613
- function buildMarkerRun$1(markerText, firstTextRun) {
280465
+ function buildMarkerRun$1(markerText, firstTextRun, docDefaults) {
279614
280466
  const markerRun = {
279615
280467
  kind: "text",
279616
280468
  text: `${markerText} `,
279617
280469
  dataAttrs: { [FOOTNOTE_MARKER_DATA_ATTR]: "true" },
279618
- fontFamily: resolveMarkerFontFamily$1(firstTextRun),
279619
- fontSize: resolveMarkerBaseFontSize$1(firstTextRun) * SUBSCRIPT_SUPERSCRIPT_SCALE,
280470
+ fontFamily: resolveMarkerFontFamily$1(firstTextRun, docDefaults),
280471
+ fontSize: resolveMarkerBaseFontSize$1(firstTextRun, docDefaults) * SUBSCRIPT_SUPERSCRIPT_SCALE,
279620
280472
  vertAlign: "superscript"
279621
280473
  };
279622
280474
  if (firstTextRun?.color != null)
@@ -279655,12 +280507,12 @@ function syncMarkerRun$1(target, source) {
279655
280507
  delete target.pmStart;
279656
280508
  delete target.pmEnd;
279657
280509
  }
279658
- function ensureFootnoteMarker(blocks2, id2, footnoteNumberById, footnoteNumberFormat) {
280510
+ function ensureFootnoteMarker(blocks2, id2, footnoteNumberById, footnoteNumberFormat, docDefaults) {
279659
280511
  const firstParagraph = blocks2.find((b$1) => b$1?.kind === "paragraph");
279660
280512
  if (!firstParagraph)
279661
280513
  return;
279662
280514
  const runs2 = Array.isArray(firstParagraph.runs) ? firstParagraph.runs : [];
279663
- const normalizedMarkerRun = buildMarkerRun$1(formatFootnoteCardinal(resolveDisplayNumber$1(id2, footnoteNumberById), footnoteNumberFormat), runs2.find((run2) => typeof run2.text === "string" && !isFootnoteMarker(run2)));
280515
+ const normalizedMarkerRun = buildMarkerRun$1(formatFootnoteCardinal(resolveDisplayNumber$1(id2, footnoteNumberById), footnoteNumberFormat), runs2.find((run2) => typeof run2.text === "string" && !isFootnoteMarker(run2)), docDefaults);
279664
280516
  const existingMarker = runs2.find(isFootnoteMarker);
279665
280517
  if (existingMarker) {
279666
280518
  syncMarkerRun$1(existingMarker, normalizedMarkerRun);
@@ -280276,7 +281128,7 @@ function isSemanticFootnoteBlockId(blockId) {
280276
281128
  function isRenderedNoteBlockId(blockId) {
280277
281129
  return typeof blockId === "string" && (blockId.startsWith("footnote-") || blockId.startsWith("endnote-") || isSemanticFootnoteBlockId(blockId));
280278
281130
  }
280279
- function parseRenderedNoteTarget$1(blockId) {
281131
+ function parseRenderedNoteTarget(blockId) {
280280
281132
  if (typeof blockId !== "string" || blockId.length === 0)
280281
281133
  return null;
280282
281134
  if (blockId.startsWith("footnote-")) {
@@ -280307,6 +281159,88 @@ function isSameRenderedNoteTarget(left$1, right$1) {
280307
281159
  return false;
280308
281160
  return left$1.storyType === right$1.storyType && left$1.noteId === right$1.noteId;
280309
281161
  }
281162
+ function renderedNoteBlockIdPrefixes(target) {
281163
+ return [`${target.storyType}-${target.noteId}-`, `__sd_semantic_${target.storyType}-${target.noteId}-`];
281164
+ }
281165
+ function resolveNoteReferenceAtPointer(options) {
281166
+ const { target, clientX, clientY, doc: doc$12, ownerDocument } = options;
281167
+ const fromTarget = noteTargetFromPmStartElement(target?.closest?.("[data-pm-start]"), doc$12);
281168
+ if (fromTarget)
281169
+ return fromTarget;
281170
+ if (typeof ownerDocument.elementsFromPoint !== "function")
281171
+ return null;
281172
+ for (const element3 of ownerDocument.elementsFromPoint(clientX, clientY)) {
281173
+ if (!(element3 instanceof HTMLElement))
281174
+ continue;
281175
+ const resolved = noteTargetFromPmStartElement(element3.closest("[data-pm-start]"), doc$12);
281176
+ if (resolved)
281177
+ return resolved;
281178
+ }
281179
+ return null;
281180
+ }
281181
+ function noteTargetFromPmStartElement(refEl, doc$12) {
281182
+ if (!refEl || !doc$12)
281183
+ return null;
281184
+ if (refEl.closest(HEADER_FOOTER_CONTAINER_SELECTOR))
281185
+ return null;
281186
+ if (isRenderedNoteBlockId(refEl.closest("[data-block-id]")?.getAttribute("data-block-id") ?? ""))
281187
+ return null;
281188
+ const pmStart = Number(refEl.getAttribute("data-pm-start"));
281189
+ if (!Number.isFinite(pmStart) || pmStart < 0 || pmStart >= doc$12.content.size)
281190
+ return null;
281191
+ const node3 = doc$12.nodeAt(pmStart);
281192
+ if (node3?.type?.name === "crossReference")
281193
+ return noteTargetFromCrossReference(doc$12, node3.attrs?.target);
281194
+ return noteTargetFromReferenceNode(node3);
281195
+ }
281196
+ function noteTargetFromReferenceNode(node3) {
281197
+ const nodeType = node3?.type?.name;
281198
+ if (nodeType !== "footnoteReference" && nodeType !== "endnoteReference")
281199
+ return null;
281200
+ const noteId = node3?.attrs?.id;
281201
+ if (noteId == null || String(noteId).length === 0)
281202
+ return null;
281203
+ return {
281204
+ storyType: nodeType === "endnoteReference" ? "endnote" : "footnote",
281205
+ noteId: String(noteId)
281206
+ };
281207
+ }
281208
+ function noteTargetFromCrossReference(doc$12, bookmarkName) {
281209
+ if (typeof bookmarkName !== "string" || bookmarkName.length === 0)
281210
+ return null;
281211
+ let startPos = -1;
281212
+ let rangeEnd = -1;
281213
+ let bookmarkId = null;
281214
+ let foundEnd = false;
281215
+ doc$12.descendants((node3, pos) => {
281216
+ if (foundEnd)
281217
+ return false;
281218
+ if (startPos < 0) {
281219
+ if (node3.type?.name === "bookmarkStart" && node3.attrs?.name === bookmarkName) {
281220
+ startPos = pos;
281221
+ rangeEnd = pos + node3.nodeSize;
281222
+ bookmarkId = node3.attrs?.id;
281223
+ }
281224
+ return true;
281225
+ }
281226
+ if (node3.type?.name === "bookmarkEnd" && bookmarkId != null && node3.attrs?.id === bookmarkId) {
281227
+ rangeEnd = pos;
281228
+ foundEnd = true;
281229
+ return false;
281230
+ }
281231
+ return true;
281232
+ });
281233
+ if (startPos < 0)
281234
+ return null;
281235
+ let result = null;
281236
+ doc$12.nodesBetween(startPos, rangeEnd, (node3) => {
281237
+ if (result)
281238
+ return false;
281239
+ result = noteTargetFromReferenceNode(node3);
281240
+ return !result;
281241
+ });
281242
+ return result;
281243
+ }
280310
281244
  function isOutsidePageBodyContent(layout, x, pageIndex, pageLocalY) {
280311
281245
  if (!Number.isFinite(x) || !Number.isFinite(pageIndex) || !Number.isFinite(pageLocalY))
280312
281246
  return false;
@@ -281312,6 +282246,173 @@ function computeSelectionRectsFromVisibleTextOffsets(options, fromOffset, toOffs
281312
282246
  }
281313
282247
  return layoutRects;
281314
282248
  }
282249
+ function resolvePmPoint(containers, pos, anchor) {
282250
+ if (!Number.isFinite(pos))
282251
+ return null;
282252
+ if (anchor?.sdBlockId) {
282253
+ const blockContainers = containers.filter((el) => (el.getAttribute("data-block-id") ?? "").endsWith(anchor.sdBlockId));
282254
+ if (blockContainers.length) {
282255
+ const blockLines = collectRenderedLineElements(blockContainers).map((line) => ({
282256
+ line,
282257
+ pmStart: getPmStart(line),
282258
+ pmEnd: getPmEnd(line)
282259
+ })).filter((entry) => entry.pmStart != null && entry.pmEnd != null).sort((a2, b$1) => a2.pmStart - b$1.pmStart || a2.pmEnd - b$1.pmEnd);
282260
+ if (blockLines.length) {
282261
+ const delta = anchor.currentStart - blockLines[0].pmStart;
282262
+ const resolved = resolvePmPoint(blockContainers, Math.max(blockLines[0].pmStart, Math.min(pos - delta, blockLines[blockLines.length - 1].pmEnd)));
282263
+ if (resolved)
282264
+ return resolved;
282265
+ }
282266
+ }
282267
+ return null;
282268
+ }
282269
+ const lines = collectRenderedLineElements(containers).map((line) => ({
282270
+ line,
282271
+ pmStart: getPmStart(line),
282272
+ pmEnd: getPmEnd(line)
282273
+ })).filter((entry) => entry.pmStart != null && entry.pmEnd != null).sort((a2, b$1) => a2.pmStart - b$1.pmStart || a2.pmEnd - b$1.pmEnd);
282274
+ let lineElement = null;
282275
+ let resolvedPos = pos;
282276
+ let sawEarlierLine = false;
282277
+ for (const { line, pmStart, pmEnd } of lines) {
282278
+ if (pos > pmEnd) {
282279
+ sawEarlierLine = true;
282280
+ continue;
282281
+ }
282282
+ if (pos < pmStart) {
282283
+ if (sawEarlierLine && !lineElement) {
282284
+ lineElement = line;
282285
+ resolvedPos = pmStart;
282286
+ }
282287
+ break;
282288
+ }
282289
+ lineElement = line;
282290
+ resolvedPos = pos;
282291
+ if (pos < pmEnd)
282292
+ break;
282293
+ }
282294
+ if (!lineElement)
282295
+ return null;
282296
+ const pageElement = lineElement.closest(`.${DOM_CLASS_NAMES.PAGE}[data-page-index]`);
282297
+ if (!pageElement)
282298
+ return null;
282299
+ const leaves = collectLeafPmElements(lineElement);
282300
+ let leaf = null;
282301
+ for (const candidate of leaves) {
282302
+ const pmStart = getPmStart(candidate);
282303
+ const pmEnd = getPmEnd(candidate);
282304
+ if (pmStart == null || pmEnd == null || resolvedPos < pmStart || resolvedPos > pmEnd)
282305
+ continue;
282306
+ leaf = candidate;
282307
+ if (resolvedPos < pmEnd)
282308
+ break;
282309
+ }
282310
+ if (!leaf)
282311
+ return null;
282312
+ const leafPmStart = getPmStart(leaf) ?? 0;
282313
+ const walker = (leaf.ownerDocument ?? document).createTreeWalker(leaf, NodeFilter.SHOW_TEXT);
282314
+ let remaining = Math.max(0, resolvedPos - leafPmStart);
282315
+ let lastTextNode = null;
282316
+ let currentNode = walker.nextNode();
282317
+ while (currentNode) {
282318
+ const textNode = currentNode;
282319
+ const textLength = textNode.textContent?.length ?? 0;
282320
+ if (textLength > 0) {
282321
+ lastTextNode = textNode;
282322
+ if (remaining <= textLength)
282323
+ return {
282324
+ node: textNode,
282325
+ offset: remaining,
282326
+ pageElement,
282327
+ lineElement
282328
+ };
282329
+ remaining -= textLength;
282330
+ }
282331
+ currentNode = walker.nextNode();
282332
+ }
282333
+ if (!lastTextNode)
282334
+ return null;
282335
+ return {
282336
+ node: lastTextNode,
282337
+ offset: lastTextNode.textContent?.length ?? 0,
282338
+ pageElement,
282339
+ lineElement
282340
+ };
282341
+ }
282342
+ function computeCaretRectFromPmPosition(options, pos, anchor) {
282343
+ const point5 = resolvePmPoint(options.containers, pos, anchor);
282344
+ if (!point5)
282345
+ return null;
282346
+ const range = (point5.node.ownerDocument ?? document).createRange();
282347
+ range.setStart(point5.node, point5.offset);
282348
+ range.setEnd(point5.node, point5.offset);
282349
+ const rangeRect = range.getBoundingClientRect();
282350
+ const lineRect = point5.lineElement.getBoundingClientRect();
282351
+ const pageRect = point5.pageElement.getBoundingClientRect();
282352
+ const pageIndex = Number(point5.pageElement.dataset.pageIndex ?? "NaN");
282353
+ if (!Number.isFinite(pageIndex))
282354
+ return null;
282355
+ const localX = (rangeRect.left - pageRect.left) / options.zoom;
282356
+ const localY = (lineRect.top - pageRect.top) / options.zoom;
282357
+ if (!Number.isFinite(localX) || !Number.isFinite(localY))
282358
+ return null;
282359
+ return {
282360
+ pageIndex,
282361
+ x: localX,
282362
+ y: pageIndex * (options.pageHeight + options.pageGap) + localY,
282363
+ width: 1,
282364
+ height: Math.max(1, lineRect.height / options.zoom)
282365
+ };
282366
+ }
282367
+ function computeSelectionRectsFromPmRange(options, from$1, to, anchors) {
282368
+ if (!Number.isFinite(from$1) || !Number.isFinite(to))
282369
+ return null;
282370
+ const startPos = Math.min(from$1, to);
282371
+ const endPos = Math.max(from$1, to);
282372
+ if (startPos === endPos)
282373
+ return [];
282374
+ const startPoint = resolvePmPoint(options.containers, startPos, from$1 <= to ? anchors?.from : anchors?.to);
282375
+ const endPoint = resolvePmPoint(options.containers, endPos, from$1 <= to ? anchors?.to : anchors?.from);
282376
+ if (!startPoint || !endPoint)
282377
+ return null;
282378
+ const range = (startPoint.node.ownerDocument ?? document).createRange();
282379
+ try {
282380
+ range.setStart(startPoint.node, startPoint.offset);
282381
+ range.setEnd(endPoint.node, endPoint.offset);
282382
+ } catch {
282383
+ return null;
282384
+ }
282385
+ const rawRects = Array.from(range.getClientRects());
282386
+ const pageElements = [];
282387
+ for (const pageElement of [startPoint.pageElement, endPoint.pageElement])
282388
+ if (!pageElements.includes(pageElement))
282389
+ pageElements.push(pageElement);
282390
+ const rects = deduplicateOverlappingRects(rawRects);
282391
+ const layoutRects = [];
282392
+ for (const rect of rects) {
282393
+ if (!Number.isFinite(rect.width) || !Number.isFinite(rect.height) || rect.width <= 0 || rect.height <= 0)
282394
+ continue;
282395
+ const pageElement = findPageElementForRect(rect, pageElements);
282396
+ if (!pageElement)
282397
+ continue;
282398
+ const pageRect = pageElement.getBoundingClientRect();
282399
+ const pageIndex = Number(pageElement.dataset.pageIndex ?? "NaN");
282400
+ if (!Number.isFinite(pageIndex))
282401
+ continue;
282402
+ const localX = (rect.left - pageRect.left) / options.zoom;
282403
+ const localY = (rect.top - pageRect.top) / options.zoom;
282404
+ if (!Number.isFinite(localX) || !Number.isFinite(localY))
282405
+ continue;
282406
+ layoutRects.push({
282407
+ pageIndex,
282408
+ x: localX,
282409
+ y: pageIndex * (options.pageHeight + options.pageGap) + localY,
282410
+ width: Math.max(1, rect.width / options.zoom),
282411
+ height: Math.max(1, rect.height / options.zoom)
282412
+ });
282413
+ }
282414
+ return layoutRects;
282415
+ }
281315
282416
  function collectVisibleTextModel(containers) {
281316
282417
  const lines = collectRenderedLineElements(containers);
281317
282418
  if (!lines.length)
@@ -286226,7 +287327,7 @@ function isTextRun$12(run2) {
286226
287327
  function isEndnoteMarker(run2) {
286227
287328
  return isTextRun$12(run2) && Boolean(run2.dataAttrs?.[ENDNOTE_MARKER_DATA_ATTR]);
286228
287329
  }
286229
- function resolveDisplayNumber(id2, endnoteNumberById) {
287330
+ function resolveDisplayNumber2(id2, endnoteNumberById) {
286230
287331
  if (!endnoteNumberById || typeof endnoteNumberById !== "object")
286231
287332
  return 1;
286232
287333
  const num = endnoteNumberById[id2];
@@ -286294,7 +287395,7 @@ function ensureEndnoteMarker(blocks2, id2, endnoteNumberById, endnoteNumberForma
286294
287395
  const runs2 = Array.isArray(firstParagraph.runs) ? firstParagraph.runs : [];
286295
287396
  firstParagraph.runs = runs2;
286296
287397
  const firstTextRun = runs2.find((run2) => isTextRun$12(run2) && !isEndnoteMarker(run2) && run2.text.length > 0);
286297
- const markerRun = buildMarkerRun(formatFootnoteCardinal(resolveDisplayNumber(id2, endnoteNumberById), endnoteNumberFormat), firstTextRun);
287398
+ const markerRun = buildMarkerRun(formatFootnoteCardinal(resolveDisplayNumber2(id2, endnoteNumberById), endnoteNumberFormat), firstTextRun);
286298
287399
  if (runs2[0] && isTextRun$12(runs2[0]) && isEndnoteMarker(runs2[0])) {
286299
287400
  syncMarkerRun(runs2[0], markerRun);
286300
287401
  return;
@@ -286769,32 +287870,6 @@ function serializePerIdNumbering(order$1, numberById, formatById) {
286769
287870
  }
286770
287871
  return parts.join(";");
286771
287872
  }
286772
- function parseRenderedNoteTarget(blockId) {
286773
- if (typeof blockId !== "string" || blockId.length === 0)
286774
- return null;
286775
- if (blockId.startsWith("footnote-")) {
286776
- const noteId = blockId.slice(9).split("-")[0] ?? "";
286777
- return noteId ? {
286778
- storyType: "footnote",
286779
- noteId
286780
- } : null;
286781
- }
286782
- if (blockId.startsWith("__sd_semantic_footnote-")) {
286783
- const noteId = blockId.slice(23).split("-")[0] ?? "";
286784
- return noteId ? {
286785
- storyType: "footnote",
286786
- noteId
286787
- } : null;
286788
- }
286789
- if (blockId.startsWith("endnote-")) {
286790
- const noteId = blockId.slice(8).split("-")[0] ?? "";
286791
- return noteId ? {
286792
- storyType: "endnote",
286793
- noteId
286794
- } : null;
286795
- }
286796
- return null;
286797
- }
286798
287873
  function escapeAttrValue(value) {
286799
287874
  const cssApi = typeof globalThis === "object" && globalThis && "CSS" in globalThis ? globalThis.CSS : undefined;
286800
287875
  if (typeof cssApi?.escape === "function")
@@ -288495,7 +289570,7 @@ var Node$13 = class Node$14 {
288495
289570
  let $pos = doc$12.resolve(this.pos);
288496
289571
  return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos);
288497
289572
  }
288498
- }, handleKeyDown2, Gapcursor, PARTS_MAP_KEY = "parts", META_MAP_KEY = "meta", META_PARTS_SCHEMA_VERSION_KEY = "partsSchemaVersion", META_PARTS_MIGRATION_KEY = "partsMigration", META_PARTS_LAST_HYDRATED_AT_KEY = "partsLastHydratedAt", META_PARTS_FALLBACK_MODE_KEY = "partsFallbackMode", META_PARTS_CAPABILITY_KEY = "partsCapability", SOURCE_COLLAB_REMOTE_PARTS = "collab:remote:parts", SOURCE_COLLAB_REMOTE_PREFIX = "collab:remote:", EXCLUDED_PART_IDS, CRITICAL_PART_IDS, isApplyingRemoteParts = false, SCHEMA_ATOM_NODE_NAMES, NORMALIZE_YJS_FRAGMENT_ORIGIN, headlessBindingStateByEditor, headlessCleanupRegisteredEditors, META_BODY_SECT_PR_KEY = "bodySectPr", BODY_SECT_PR_SYNC_META_KEY = "bodySectPrSync", collaborationCleanupByEditor, registerHeadlessBindingCleanup = (editor, cleanup) => {
289573
+ }, handleKeyDown2, Gapcursor, PARTS_MAP_KEY = "parts", META_MAP_KEY = "meta", META_PARTS_SCHEMA_VERSION_KEY = "partsSchemaVersion", META_PARTS_MIGRATION_KEY = "partsMigration", META_PARTS_LAST_HYDRATED_AT_KEY = "partsLastHydratedAt", META_PARTS_FALLBACK_MODE_KEY = "partsFallbackMode", META_PARTS_CAPABILITY_KEY = "partsCapability", SOURCE_COLLAB_REMOTE_PARTS = "collab:remote:parts", SOURCE_COLLAB_REMOTE_PREFIX = "collab:remote:", EXCLUDED_PART_IDS, CRITICAL_PART_IDS, isApplyingRemoteParts = false, META_MAP_KEY$1 = "meta", NOTE_TOMBSTONE_META_PREFIX = "noteTombstone:", SCHEMA_ATOM_NODE_NAMES, NORMALIZE_YJS_FRAGMENT_ORIGIN, headlessBindingStateByEditor, headlessCleanupRegisteredEditors, META_BODY_SECT_PR_KEY = "bodySectPr", BODY_SECT_PR_SYNC_META_KEY = "bodySectPrSync", collaborationCleanupByEditor, registerHeadlessBindingCleanup = (editor, cleanup) => {
288499
289574
  if (!cleanup || headlessCleanupRegisteredEditors.has(editor))
288500
289575
  return;
288501
289576
  headlessCleanupRegisteredEditors.add(editor);
@@ -288584,6 +289659,7 @@ var Node$13 = class Node$14 {
288584
289659
  cleanup.metaMap?.unobserve?.(cleanup.metaMapObserver);
288585
289660
  cleanup.partSyncHandle?.destroy();
288586
289661
  cleanup.partSyncPendingCleanup?.();
289662
+ cleanup.noteTombstoneSyncHandle?.destroy();
288587
289663
  cleanup.bodySectPrPendingCleanup?.();
288588
289664
  if (cleanup.bodySectPrTransactionHandler && typeof editor.off === "function")
288589
289665
  editor.off("transaction", cleanup.bodySectPrTransactionHandler);
@@ -289403,7 +290479,7 @@ var Node$13 = class Node$14 {
289403
290479
  tr.setDocAttribute("bodySectPr", sectPr);
289404
290480
  tr.setMeta("forceUpdatePagination", true);
289405
290481
  return true;
289406
- }, Document$1, Text$2, OxmlNode, isLinkedParagraphStyleId = (editor, styleId$1) => {
290482
+ }, Document$1, Text$2, OxmlNode, isNoteStorySession = (editor) => Boolean(editor?.options?.parentEditor && !editor?.options?.isHeaderOrFooter), isLinkedParagraphStyleId = (editor, styleId$1) => {
289407
290483
  if (!styleId$1)
289408
290484
  return false;
289409
290485
  const styleDefinition = readTranslatedLinkedStyles(editor)?.styles?.[styleId$1];
@@ -289418,6 +290494,8 @@ var Node$13 = class Node$14 {
289418
290494
  }, clearInheritedLinkedStyleId = (attrs, editor, { emptyParagraph = false } = {}) => {
289419
290495
  if (!emptyParagraph)
289420
290496
  return attrs;
290497
+ if (isNoteStorySession(editor))
290498
+ return attrs;
289421
290499
  if (!attrs || typeof attrs !== "object")
289422
290500
  return attrs;
289423
290501
  const paragraphProperties = attrs.paragraphProperties;
@@ -289431,154 +290509,6 @@ var Node$13 = class Node$14 {
289431
290509
  styleId: null
289432
290510
  }
289433
290511
  };
289434
- }, TrackChangesBasePluginKey, TrackChangesBasePlugin = () => {
289435
- return new Plugin({
289436
- key: TrackChangesBasePluginKey,
289437
- state: {
289438
- init(_$1, state) {
289439
- return {
289440
- isTrackChangesActive: false,
289441
- onlyOriginalShown: false,
289442
- onlyModifiedShown: false,
289443
- pendingDeadKeyPlaceholder: null,
289444
- decorations: getTrackChangesDecorations(state, false, false)
289445
- };
289446
- },
289447
- apply(tr, oldState, prevEditorState, newEditorState) {
289448
- const meta2 = tr.getMeta(TrackChangesBasePluginKey);
289449
- const pendingDeadKeyPlaceholder = meta2 && Object.prototype.hasOwnProperty.call(meta2, "pendingDeadKeyPlaceholder") ? meta2.pendingDeadKeyPlaceholder : oldState.pendingDeadKeyPlaceholder;
289450
- if (meta2 && meta2.type === "TRACK_CHANGES_ENABLE")
289451
- return {
289452
- ...oldState,
289453
- isTrackChangesActive: meta2.value === true,
289454
- pendingDeadKeyPlaceholder,
289455
- decorations: getTrackChangesDecorations(newEditorState, oldState.onlyOriginalShown, oldState.onlyModifiedShown)
289456
- };
289457
- if (meta2 && meta2.type === "SHOW_ONLY_ORIGINAL")
289458
- return {
289459
- ...oldState,
289460
- onlyOriginalShown: meta2.value === true,
289461
- onlyModifiedShown: false,
289462
- pendingDeadKeyPlaceholder,
289463
- decorations: getTrackChangesDecorations(newEditorState, meta2.value === true, false)
289464
- };
289465
- if (meta2 && meta2.type === "SHOW_ONLY_MODIFIED")
289466
- return {
289467
- ...oldState,
289468
- onlyOriginalShown: false,
289469
- onlyModifiedShown: meta2.value === true,
289470
- pendingDeadKeyPlaceholder,
289471
- decorations: getTrackChangesDecorations(newEditorState, false, meta2.value === true)
289472
- };
289473
- if (!tr.docChanged)
289474
- return {
289475
- ...oldState,
289476
- pendingDeadKeyPlaceholder
289477
- };
289478
- if (!meta2) {
289479
- let mightAffectTrackChanges = false;
289480
- tr.steps.forEach((step3) => {
289481
- const replaceStep$2 = step3;
289482
- if (replaceStep$2.slice || replaceStep$2.from !== replaceStep$2.to)
289483
- mightAffectTrackChanges = true;
289484
- });
289485
- if (mightAffectTrackChanges)
289486
- return {
289487
- ...oldState,
289488
- pendingDeadKeyPlaceholder,
289489
- decorations: getTrackChangesDecorations(newEditorState, oldState.onlyOriginalShown, oldState.onlyModifiedShown)
289490
- };
289491
- return {
289492
- ...oldState,
289493
- pendingDeadKeyPlaceholder,
289494
- decorations: oldState.decorations.map(tr.mapping, tr.doc)
289495
- };
289496
- }
289497
- return {
289498
- ...oldState,
289499
- pendingDeadKeyPlaceholder,
289500
- decorations: getTrackChangesDecorations(newEditorState, oldState.onlyOriginalShown, oldState.onlyModifiedShown)
289501
- };
289502
- }
289503
- },
289504
- props: { decorations(state) {
289505
- return this.getState(state)?.decorations;
289506
- } }
289507
- });
289508
- }, getTrackChangesDecorations = (state, onlyOriginalShown, onlyModifiedShown) => {
289509
- if (!state.doc || !state.doc.nodeSize || onlyModifiedShown && onlyOriginalShown)
289510
- return DecorationSet.empty;
289511
- const decorations = [];
289512
- const trackedChanges = getTrackChanges(state);
289513
- addStructuralRowDecorations(decorations, state, onlyOriginalShown, onlyModifiedShown);
289514
- if (!trackedChanges.length)
289515
- return decorations.length ? DecorationSet.create(state.doc, decorations) : DecorationSet.empty;
289516
- trackedChanges.forEach(({ mark: mark2, from: from$1, to }) => {
289517
- if (mark2.type.name === "trackInsert")
289518
- if (onlyOriginalShown) {
289519
- const decoration = Decoration.inline(from$1, to, { class: "track-insert-dec hidden" });
289520
- decorations.push(decoration);
289521
- } else if (onlyModifiedShown) {
289522
- const decoration = Decoration.inline(from$1, to, { class: "track-insert-dec normal" });
289523
- decorations.push(decoration);
289524
- } else {
289525
- const decoration = Decoration.inline(from$1, to, { class: "track-insert-dec highlighted" });
289526
- decorations.push(decoration);
289527
- }
289528
- if (mark2.type.name === "trackDelete")
289529
- if (onlyOriginalShown) {
289530
- const decoration = Decoration.inline(from$1, to, { class: "track-delete-dec normal" });
289531
- decorations.push(decoration);
289532
- } else if (onlyModifiedShown) {
289533
- const decoration = Decoration.inline(from$1, to, { class: "track-delete-dec hidden" });
289534
- decorations.push(decoration);
289535
- } else {
289536
- const decorationInline = Decoration.inline(from$1, to, { class: "track-delete-dec highlighted" });
289537
- decorations.push(decorationInline);
289538
- const decorationWidget = Decoration.widget(from$1, () => {
289539
- const span = document.createElement("span");
289540
- span.classList.add("track-delete-widget");
289541
- return span;
289542
- }, {
289543
- ignoreSelection: true,
289544
- key: "stable-key"
289545
- });
289546
- decorations.push(decorationWidget);
289547
- }
289548
- if (mark2.type.name === "trackFormat")
289549
- if (onlyOriginalShown) {
289550
- const decoration = Decoration.inline(from$1, to, { class: "track-format-dec before" });
289551
- decorations.push(decoration);
289552
- } else if (onlyModifiedShown) {
289553
- const decoration = Decoration.inline(from$1, to, { class: "track-format-dec normal" });
289554
- decorations.push(decoration);
289555
- } else {
289556
- const decoration = Decoration.inline(from$1, to, { class: "track-format-dec highlighted" });
289557
- decorations.push(decoration);
289558
- }
289559
- });
289560
- return DecorationSet.create(state.doc, decorations);
289561
- }, addStructuralRowDecorations = (decorations, state, onlyOriginalShown, onlyModifiedShown) => {
289562
- const structuralChanges = enumerateStructuralRowChanges(state);
289563
- if (!structuralChanges.length)
289564
- return;
289565
- for (const change of structuralChanges) {
289566
- const isInsert = change.side === "insertion";
289567
- const baseClass = isInsert ? "track-row-insert-dec" : "track-row-delete-dec";
289568
- let mode = "highlighted";
289569
- if (onlyOriginalShown)
289570
- mode = isInsert ? "hidden" : "normal";
289571
- else if (onlyModifiedShown)
289572
- mode = isInsert ? "normal" : "hidden";
289573
- for (const row2 of change.rows)
289574
- decorations.push(Decoration.node(row2.from, row2.to, {
289575
- class: `${baseClass} ${mode}`,
289576
- "data-track-change-id": change.id,
289577
- "data-track-change-kind": change.subtype,
289578
- "data-track-change-author": change.author || "",
289579
- "data-track-change-date": change.date || ""
289580
- }));
289581
- }
289582
290512
  }, resolveCommentMeta = ({ converter, importedId }) => {
289583
290513
  const matchingImportedComment = (converter?.comments || []).find((c) => c.importedId == importedId);
289584
290514
  const resolvedCommentId = matchingImportedComment?.commentId ?? (importedId ? String(importedId) : v4_default());
@@ -291299,8 +292229,16 @@ var Node$13 = class Node$14 {
291299
292229
  if (dispatch)
291300
292230
  dispatch(state.tr.setSelection(new AllSelection(state.doc)));
291301
292231
  return true;
291302
- }, selectTextblockStart, selectTextblockEnd, backspace, del3, pcBaseKeymap, macBaseKeymap, liftEmptyBlock$1 = () => ({ state, dispatch }) => liftEmptyBlock(state, dispatch), createParagraphNear$1 = () => ({ state, dispatch }) => {
291303
- return createParagraphNear(state, dispatch);
292232
+ }, selectTextblockStart, selectTextblockEnd, backspace, del3, pcBaseKeymap, macBaseKeymap, liftEmptyBlock$1 = () => ({ state, dispatch, editor }) => {
292233
+ if (!dispatch || !isNoteStorySession(editor))
292234
+ return liftEmptyBlock(state, dispatch);
292235
+ const sourceDepth = findParagraphDepth$1(state.selection.$from);
292236
+ return liftEmptyBlock(state, restoreParagraphPropertiesAfterDispatch(dispatch, sourceDepth ? state.selection.$from.node(sourceDepth).attrs?.paragraphProperties : null));
292237
+ }, createParagraphNear$1 = () => ({ state, dispatch, editor }) => {
292238
+ if (!dispatch || !isNoteStorySession(editor))
292239
+ return createParagraphNear(state, dispatch);
292240
+ const sourceDepth = findParagraphDepth$1(state.selection.$from);
292241
+ return createParagraphNear(state, restoreParagraphPropertiesAfterDispatch(dispatch, sourceDepth ? state.selection.$from.node(sourceDepth).attrs?.paragraphProperties : null));
291304
292242
  }, newlineInCode$1 = () => ({ state, dispatch }) => newlineInCode(state, dispatch), exitCode$1 = () => ({ state, dispatch }) => {
291305
292243
  return exitCode(state, dispatch);
291306
292244
  }, setMark = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
@@ -291394,7 +292332,7 @@ var Node$13 = class Node$14 {
291394
292332
  if (isMarkActive(state, type, attrs))
291395
292333
  return commands$1.unsetMark(type, { extendEmptyMarkRange });
291396
292334
  return commands$1.setMark(type, attrs);
291397
- }, clearNodes = () => ({ state, tr, dispatch }) => {
292335
+ }, clearNodes = () => ({ state, tr, dispatch, editor }) => {
291398
292336
  const { selection } = tr;
291399
292337
  const { ranges } = selection;
291400
292338
  if (!dispatch)
@@ -291412,7 +292350,8 @@ var Node$13 = class Node$14 {
291412
292350
  const targetLiftDepth = liftTarget(nodeRange);
291413
292351
  if (node3.type.isTextblock) {
291414
292352
  const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
291415
- tr.setNodeMarkup(nodeRange.start, defaultType);
292353
+ const preservedAttrs = isNoteStorySession(editor) ? { paragraphProperties: node3.attrs?.paragraphProperties } : undefined;
292354
+ tr.setNodeMarkup(nodeRange.start, defaultType, preservedAttrs);
291416
292355
  }
291417
292356
  if (targetLiftDepth || targetLiftDepth === 0)
291418
292357
  tr.lift(nodeRange, targetLiftDepth);
@@ -291541,9 +292480,10 @@ var Node$13 = class Node$14 {
291541
292480
  dispatch(tr);
291542
292481
  }
291543
292482
  return true;
291544
- }, joinUp$1 = () => ({ state, dispatch }) => joinUp(state, dispatch), joinDown$1 = () => ({ state, dispatch }) => joinDown(state, dispatch), joinBackward$1 = () => ({ state, dispatch }) => {
292483
+ }, joinUp$1 = () => ({ state, dispatch }) => joinUp(state, dispatch), joinDown$1 = () => ({ state, dispatch }) => joinDown(state, dispatch), joinBackward$1 = () => ({ state, dispatch, editor }) => {
291545
292484
  const { selection, doc: doc$12 } = state;
291546
292485
  const { $from } = selection;
292486
+ const guardedDispatch = (paragraphProps) => isNoteStorySession(editor) ? restoreParagraphPropertiesAfterDispatch(dispatch, paragraphProps) : dispatch;
291547
292487
  if (!$from.parent.isTextblock || $from.parentOffset > 0)
291548
292488
  return joinBackward(state, dispatch);
291549
292489
  const beforePos = $from.before();
@@ -291552,8 +292492,14 @@ var Node$13 = class Node$14 {
291552
292492
  const isList$12 = (node3) => node3?.type.name === "orderedList" || node3?.type.name === "bulletList";
291553
292493
  if (isList$12(nodeBefore) || isList$12(nodeAfter))
291554
292494
  return false;
291555
- return joinBackward(state, dispatch);
291556
- }, joinForward$1 = () => ({ state, dispatch }) => {
292495
+ const survivorProps = nodeBefore?.type?.name === "paragraph" ? nodeBefore.attrs?.paragraphProperties : findParagraphDepth$1($from) ? $from.node(findParagraphDepth$1($from)).attrs?.paragraphProperties : null;
292496
+ return joinBackward(state, dispatch ? guardedDispatch(survivorProps) : dispatch);
292497
+ }, joinForward$1 = () => ({ state, dispatch, editor }) => {
292498
+ if (dispatch && isNoteStorySession(editor)) {
292499
+ const depth = findParagraphDepth$1(state.selection.$from);
292500
+ const props = depth ? state.selection.$from.node(depth).attrs?.paragraphProperties : null;
292501
+ dispatch = restoreParagraphPropertiesAfterDispatch(dispatch, props);
292502
+ }
291557
292503
  const { selection, doc: doc$12 } = state;
291558
292504
  const { $from } = selection;
291559
292505
  if (!$from.parent.isTextblock || $from.parentOffset > 0)
@@ -292148,6 +293094,22 @@ var Node$13 = class Node$14 {
292148
293094
  dispatch(tr.scrollIntoView());
292149
293095
  }
292150
293096
  return true;
293097
+ }, SELECT_FOOTNOTE_MARKER_META = "selectFootnoteMarker", isNoteReference = (node3) => node3?.type.name === "footnoteReference" || node3?.type.name === "endnoteReference", selectFootnoteMarkerBefore = () => ({ state, dispatch }) => {
293098
+ const { selection } = state;
293099
+ if (!selection.empty)
293100
+ return false;
293101
+ const marker = getPreviousNoteMarker(state);
293102
+ if (!marker)
293103
+ return false;
293104
+ return selectNoteMarker(state, dispatch, marker);
293105
+ }, selectFootnoteMarkerAfter = () => ({ state, dispatch }) => {
293106
+ const { selection } = state;
293107
+ if (!selection.empty)
293108
+ return false;
293109
+ const marker = getNextNoteMarker(state);
293110
+ if (!marker)
293111
+ return false;
293112
+ return selectNoteMarker(state, dispatch, marker);
292151
293113
  }, selectBlockSdtBeforeTextBlockStart = () => selectAdjacentBlockSdtContent("before"), selectBlockSdtAfterTextBlockEnd = () => selectAdjacentBlockSdtContent("after"), deleteBlockSdtAtTextBlockStart = () => ({ state, dispatch }) => {
292152
293114
  const { selection } = state;
292153
293115
  if (!selection.empty)
@@ -292973,7 +293935,7 @@ var Node$13 = class Node$14 {
292973
293935
  if (nodeViewMap.get(this.node) === this)
292974
293936
  nodeViewMap.delete(this.node);
292975
293937
  }
292976
- }, shouldAddLeadingCaret = (node3) => {
293938
+ }, noteStyleGuardPluginKey, shouldAddLeadingCaret = (node3) => {
292977
293939
  if (node3.type.name !== "paragraph")
292978
293940
  return false;
292979
293941
  if (node3.childCount === 0)
@@ -292990,7 +293952,7 @@ var Node$13 = class Node$14 {
292990
293952
  return editor?.options?.isHeadless ?? false;
292991
293953
  }, shouldSkipNodeView = (editor) => {
292992
293954
  return isHeadless(editor);
292993
- }, CSS_LENGTH_TO_PT, CSS_ALIGN_TO_OOXML, bulletInputRegex, orderedInputRegex, Paragraph, Heading, CommentRangeStart, CommentRangeEnd, CommentReference, CommentsMark, toSuperscriptDigits$1 = (value) => {
293955
+ }, CSS_LENGTH_TO_PT, CSS_ALIGN_TO_OOXML, bulletInputRegex, orderedInputRegex, Paragraph, Heading, CommentRangeStart, CommentRangeEnd, CommentReference, CommentsMark, NOTE_TYPE_BY_NODE, toSuperscriptDigits$1 = (value) => {
292994
293956
  const map$12 = {
292995
293957
  0: "⁰",
292996
293958
  1: "¹",
@@ -301238,7 +302200,10 @@ var Node$13 = class Node$14 {
301238
302200
  default:
301239
302201
  return { kind: "unknown" };
301240
302202
  }
301241
- }, DRAGGABLE_SELECTOR, VerticalNavigationPluginKey, createDefaultState = () => ({ goalX: null }), VerticalNavigation, STRONG_RTL_CHAR_RE$1, STRONG_LTR_CHAR_RE, isStrongRtl = (char) => STRONG_RTL_CHAR_RE$1.test(char), isStrongLtr = (char) => STRONG_LTR_CHAR_RE.test(char), hasMixedDirectionBoundary = (leftChar, rightChar) => isStrongRtl(leftChar) && isStrongLtr(rightChar) || isStrongLtr(leftChar) && isStrongRtl(rightChar), resolveCaretPoint = (doc$12, range) => {
302203
+ }, DRAGGABLE_SELECTOR, VerticalNavigationPluginKey, createDefaultState = () => ({
302204
+ goalX: null,
302205
+ goalClientX: null
302206
+ }), VerticalNavigation, STRONG_RTL_CHAR_RE$1, STRONG_LTR_CHAR_RE, isStrongRtl = (char) => STRONG_RTL_CHAR_RE$1.test(char), isStrongLtr = (char) => STRONG_LTR_CHAR_RE.test(char), hasMixedDirectionBoundary = (leftChar, rightChar) => isStrongRtl(leftChar) && isStrongLtr(rightChar) || isStrongLtr(leftChar) && isStrongRtl(rightChar), resolveCaretPoint = (doc$12, range) => {
301242
302207
  const rect = range.getBoundingClientRect();
301243
302208
  if (rect && Number.isFinite(rect.left) && Number.isFinite(rect.top)) {
301244
302209
  if (rect.width === 0 && rect.height === 0)
@@ -303244,6 +304209,8 @@ var Node$13 = class Node$14 {
303244
304209
  },
303245
304210
  () => commands$1.deleteBlockSdtAtTextBlockStart(),
303246
304211
  () => commands$1.selectInlineSdtBeforeRunStart(),
304212
+ () => commands$1.selectFootnoteMarkerBefore?.() ?? false,
304213
+ () => commands$1.deleteSelectedNoteMarker?.() ?? false,
303247
304214
  () => commands$1.selectBlockSdtBeforeTextBlockStart(),
303248
304215
  () => commands$1.moveIntoBlockSdtBeforeTextBlockStart(),
303249
304216
  () => commands$1.backspaceEmptyRunParagraph(),
@@ -303263,6 +304230,8 @@ var Node$13 = class Node$14 {
303263
304230
  return editor.commands.first(({ commands: commands$1 }) => [
303264
304231
  () => commands$1.deleteBlockSdtAtTextBlockStart(),
303265
304232
  () => commands$1.selectInlineSdtAfterRunEnd(),
304233
+ () => commands$1.selectFootnoteMarkerAfter?.() ?? false,
304234
+ () => commands$1.deleteSelectedNoteMarker?.() ?? false,
303266
304235
  () => commands$1.selectBlockSdtAfterTextBlockEnd(),
303267
304236
  () => commands$1.moveIntoBlockSdtAfterTextBlockEnd(),
303268
304237
  () => commands$1.deleteSkipEmptyRun(),
@@ -305136,7 +306105,7 @@ var Node$13 = class Node$14 {
305136
306105
  return () => {};
305137
306106
  const handle3 = setInterval(callback, intervalMs);
305138
306107
  return () => clearInterval(handle3);
305139
- }, HISTORY_UNSAFE_OPS, CANONICAL_COMMENT_IGNORED_KEYS, INITIAL_HASH, ROUND_CONSTANTS, V1_COVERAGE, V2_COVERAGE, SNAPSHOT_VERSION_V2 = "sd-diff-snapshot/v2", PAYLOAD_VERSION_V1 = "sd-diff-payload/v1", PAYLOAD_VERSION_V2 = "sd-diff-payload/v2", ENGINE_ID = "super-editor", STAGED_CONVERTER_KEYS, DiffServiceError, TC_LEVEL_MIN = 1, TC_LEVEL_MAX = 9, ALLOWED_WRAP_ATTRS, WRAP_TYPES_SUPPORTING_SIDE, WRAP_TYPES_SUPPORTING_DISTANCES, RELATIVE_HEIGHT_MIN = 0, RELATIVE_HEIGHT_MAX = 4294967295, FORBIDDEN_RAW_PATCH_NAMES, CONTROL_TYPE_SDT_PR_ELEMENTS, DEFAULT_CHECKBOX_SYMBOL_FONT2 = "MS Gothic", DEFAULT_CHECKBOX_CHECKED_HEX2 = "2612", DEFAULT_CHECKBOX_UNCHECKED_HEX2 = "2610", VARIANT_ORDER, KIND_ORDER, HEADER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", DOCUMENT_RELS_PATH2 = "word/_rels/document.xml.rels", HEADER_FILE_PATTERN2, FOOTER_FILE_PATTERN2, SPECIAL_NOTE_TYPES, BOOKMARK_SCAN_REVISION_PREFIX = "bookmark-scan:", import_lib4, CUSTOM_XML_DATA_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml", CUSTOM_XML_PROPS_RELATIONSHIP_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps", CUSTOM_XML_DATASTORE_NAMESPACE = "http://schemas.openxmlformats.org/officeDocument/2006/customXml", SETTINGS_PART, RESTART_POLICY_TO_OOXML, VALID_DISPLAYS, REFERENCE_BLOCK_PREFIX, CAPTION_STYLE_NAMES, CAPTION_PARAGRAPH_STYLE_ID = "Caption", CAPTION_FORMAT_TO_OOXML, DOCUMENT_STAT_FIELD_TYPES, TOA_LEADER_REVERSE_MAP, EDGE_NODE_TYPES, CONTENT_TYPES_PART_ID = "[Content_Types].xml", CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types", contentTypesPartDescriptor, empty_exports, init_empty, CURRENT_APP_VERSION2 = "1.41.0", PIXELS_PER_INCH2 = 96, MAX_HEIGHT_BUFFER_PX = 50, MAX_WIDTH_BUFFER_PX = 20, TRACKED_REVIEW_MARK_NAMES2, isTrackedReviewMark = (mark2) => Boolean(mark2?.type?.name && TRACKED_REVIEW_MARK_NAMES2.has(mark2.type.name)), trackedReviewMarkKey = (mark2) => {
306108
+ }, HISTORY_UNSAFE_OPS, CANONICAL_COMMENT_IGNORED_KEYS, INITIAL_HASH, ROUND_CONSTANTS, V1_COVERAGE, V2_COVERAGE, SNAPSHOT_VERSION_V2 = "sd-diff-snapshot/v2", PAYLOAD_VERSION_V1 = "sd-diff-payload/v1", PAYLOAD_VERSION_V2 = "sd-diff-payload/v2", ENGINE_ID = "super-editor", STAGED_CONVERTER_KEYS, DiffServiceError, TC_LEVEL_MIN = 1, TC_LEVEL_MAX = 9, ALLOWED_WRAP_ATTRS, WRAP_TYPES_SUPPORTING_SIDE, WRAP_TYPES_SUPPORTING_DISTANCES, RELATIVE_HEIGHT_MIN = 0, RELATIVE_HEIGHT_MAX = 4294967295, FORBIDDEN_RAW_PATCH_NAMES, CONTROL_TYPE_SDT_PR_ELEMENTS, DEFAULT_CHECKBOX_SYMBOL_FONT2 = "MS Gothic", DEFAULT_CHECKBOX_CHECKED_HEX2 = "2612", DEFAULT_CHECKBOX_UNCHECKED_HEX2 = "2610", VARIANT_ORDER, KIND_ORDER, HEADER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", FOOTER_RELATIONSHIP_TYPE3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", DOCUMENT_RELS_PATH2 = "word/_rels/document.xml.rels", HEADER_FILE_PATTERN2, FOOTER_FILE_PATTERN2, BOOKMARK_SCAN_REVISION_PREFIX = "bookmark-scan:", import_lib4, CUSTOM_XML_DATA_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml", CUSTOM_XML_PROPS_RELATIONSHIP_TYPE2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps", CUSTOM_XML_DATASTORE_NAMESPACE = "http://schemas.openxmlformats.org/officeDocument/2006/customXml", SETTINGS_PART, VALID_DISPLAYS, REFERENCE_BLOCK_PREFIX, CAPTION_STYLE_NAMES, CAPTION_PARAGRAPH_STYLE_ID = "Caption", CAPTION_FORMAT_TO_OOXML, DOCUMENT_STAT_FIELD_TYPES, TOA_LEADER_REVERSE_MAP, EDGE_NODE_TYPES, CONTENT_TYPES_PART_ID = "[Content_Types].xml", CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types", contentTypesPartDescriptor, empty_exports, init_empty, CURRENT_APP_VERSION2 = "1.41.0", PIXELS_PER_INCH2 = 96, MAX_HEIGHT_BUFFER_PX = 50, MAX_WIDTH_BUFFER_PX = 20, TRACKED_REVIEW_MARK_NAMES2, isTrackedReviewMark = (mark2) => Boolean(mark2?.type?.name && TRACKED_REVIEW_MARK_NAMES2.has(mark2.type.name)), trackedReviewMarkKey = (mark2) => {
305140
306109
  if (!isTrackedReviewMark(mark2))
305141
306110
  return null;
305142
306111
  const id2 = typeof mark2.attrs?.id === "string" ? mark2.attrs.id : "";
@@ -307562,6 +308531,52 @@ menclose::after {
307562
308531
  pointer-events: none;
307563
308532
  background: var(--sd-menclose-h), var(--sd-menclose-v), var(--sd-menclose-up), var(--sd-menclose-down);
307564
308533
  }
308534
+ `, FOOTNOTE_STYLES = `
308535
+ [data-block-id^="footnote-"],
308536
+ [data-block-id^="endnote-"],
308537
+ [data-block-id^="__sd_semantic_footnote-"],
308538
+ [data-block-id^="__sd_semantic_endnote-"] {
308539
+ cursor: text;
308540
+ }
308541
+ /* SD-3400: body reference markers are interactive (double-click opens the
308542
+ * note). Pointer cursor + a hover pill signal clickability without affecting
308543
+ * layout (background/box-shadow are paint-only). */
308544
+ [data-note-reference] {
308545
+ cursor: pointer;
308546
+ border-radius: 2px;
308547
+ position: relative;
308548
+ }
308549
+ /* The painted digit is ~6x11px — far too small to hover or double-click
308550
+ * reliably. An invisible pseudo-element halo expands the interactive target
308551
+ * (hover, cursor, clicks all hit the marker span) without moving any text. */
308552
+ [data-note-reference]::after {
308553
+ content: '';
308554
+ position: absolute;
308555
+ inset: -4px -5px;
308556
+ }
308557
+ [data-note-reference]:hover {
308558
+ background-color: var(--sd-content-controls-block-hover-bg, #d3e3fd);
308559
+ box-shadow: 0 0 0 2px var(--sd-content-controls-block-hover-bg, #d3e3fd);
308560
+ }
308561
+
308562
+ /* SD-3400: while a note session is open, highlight the note's fragments at the
308563
+ * page bottom so the focus change is visible. Applied by PresentationEditor on
308564
+ * activation, re-applied after each paint, removed on session exit. The pulse
308565
+ * draws the eye when focus jumps from the body reference to the note. */
308566
+ .sd-note-session-active {
308567
+ background-color: rgba(98, 155, 231, 0.07);
308568
+ /* Thin accent bar with breathing room: the first shadow masks a 3px gap with
308569
+ * the page background, the second paints a 1px bar beyond it. Box-shadows
308570
+ * paint outside the box, so the note line itself is untouched. */
308571
+ box-shadow:
308572
+ -3px 0 0 0 var(--sd-page-bg, #ffffff),
308573
+ -4px 0 0 0 rgba(98, 155, 231, 0.55);
308574
+ animation: sd-note-activate-pulse 0.6s ease-out 1;
308575
+ }
308576
+ @keyframes sd-note-activate-pulse {
308577
+ 0% { background-color: rgba(98, 155, 231, 0.22); }
308578
+ 100% { background-color: rgba(98, 155, 231, 0.07); }
308579
+ }
307565
308580
  `, ensureStyleElement = (doc$12, markerAttribute, cssText) => {
307566
308581
  if (!doc$12?.head)
307567
308582
  return;
@@ -307589,6 +308604,8 @@ menclose::after {
307589
308604
  ensureStyleElement(doc$12, "data-superdoc-image-selection-styles", IMAGE_SELECTION_STYLES);
307590
308605
  }, ensureMathMencloseStyles = (doc$12) => {
307591
308606
  ensureStyleElement(doc$12, "data-superdoc-math-menclose-styles", MATH_MENCLOSE_STYLES);
308607
+ }, ensureFootnoteStyles = (doc$12) => {
308608
+ ensureStyleElement(doc$12, "data-superdoc-footnote-styles", FOOTNOTE_STYLES);
307592
308609
  }, gradientIdCounter = 0, clampNumber = (value, min$2, max$2) => Math.min(max$2, Math.max(min$2, value)), mergeSortedSegments = (segments) => {
307593
308610
  if (segments.length <= 1)
307594
308611
  return segments;
@@ -312741,6 +313758,7 @@ menclose::after {
312741
313758
  ensureSdtContainerStyles(doc$12);
312742
313759
  ensureImageSelectionStyles(doc$12);
312743
313760
  ensureMathMencloseStyles(doc$12);
313761
+ ensureFootnoteStyles(doc$12);
312744
313762
  if (!this.isSemanticFlow && this.options.ruler?.enabled)
312745
313763
  ensureRulerStyles(doc$12);
312746
313764
  mount.classList.add(CLASS_NAMES$1.container);
@@ -313563,7 +314581,9 @@ menclose::after {
313563
314581
  pageEl.replaceChild(replacement, current.element);
313564
314582
  current.element = replacement;
313565
314583
  current.signature = resolvedSig;
313566
- } else if (this.currentMapping)
314584
+ } else if (isNonBodyStoryBlockId(fragment2.blockId))
314585
+ this.updateStoryPositionAttributes(current.element, resolvedItem);
314586
+ else if (this.currentMapping)
313567
314587
  this.updatePositionAttributes(current.element, this.currentMapping);
313568
314588
  this.updateFragmentElement(current.element, fragment2, contextBase.section, resolvedItem);
313569
314589
  if (sdtBoundary?.widthOverride != null)
@@ -313594,6 +314614,50 @@ menclose::after {
313594
314614
  this.renderDecorationsForPage(pageEl, page, pageIndex);
313595
314615
  this.renderColumnSeparators(pageEl, page, page.width, page.height);
313596
314616
  }
314617
+ updateStoryPositionAttributes(fragmentEl, resolvedItem) {
314618
+ if (!resolvedItem || resolvedItem.kind !== "fragment")
314619
+ return;
314620
+ let freshStart;
314621
+ const block = "block" in resolvedItem ? resolvedItem.block : undefined;
314622
+ const firstLine = "content" in resolvedItem ? resolvedItem.content?.lines?.[0]?.line : undefined;
314623
+ if (block && firstLine) {
314624
+ const range = computeLinePmRange(block, firstLine);
314625
+ if (typeof range.pmStart === "number" && Number.isFinite(range.pmStart))
314626
+ freshStart = range.pmStart;
314627
+ }
314628
+ if (freshStart == null && block) {
314629
+ const runs2 = block.runs;
314630
+ if (Array.isArray(runs2)) {
314631
+ for (const run2 of runs2)
314632
+ if (typeof run2?.pmStart === "number" && Number.isFinite(run2.pmStart)) {
314633
+ freshStart = run2.pmStart;
314634
+ break;
314635
+ }
314636
+ }
314637
+ }
314638
+ if (freshStart == null || !Number.isFinite(freshStart))
314639
+ return;
314640
+ const elements = [fragmentEl, ...Array.from(fragmentEl.querySelectorAll("[data-pm-start], [data-pm-end]"))];
314641
+ let paintedStart = Infinity;
314642
+ for (const el of elements) {
314643
+ const start$1 = Number(el.dataset.pmStart);
314644
+ if (Number.isFinite(start$1))
314645
+ paintedStart = Math.min(paintedStart, start$1);
314646
+ }
314647
+ if (!Number.isFinite(paintedStart))
314648
+ return;
314649
+ const delta = freshStart - paintedStart;
314650
+ if (delta === 0)
314651
+ return;
314652
+ for (const el of elements) {
314653
+ const start$1 = Number(el.dataset.pmStart);
314654
+ if (el.dataset.pmStart !== undefined && el.dataset.pmStart !== "" && Number.isFinite(start$1))
314655
+ el.dataset.pmStart = String(start$1 + delta);
314656
+ const end$1 = Number(el.dataset.pmEnd);
314657
+ if (el.dataset.pmEnd !== undefined && el.dataset.pmEnd !== "" && Number.isFinite(end$1))
314658
+ el.dataset.pmEnd = String(end$1 + delta);
314659
+ }
314660
+ }
313597
314661
  updatePositionAttributes(fragmentEl, mapping) {
313598
314662
  if (fragmentEl.closest(".superdoc-page-header, .superdoc-page-footer"))
313599
314663
  return;
@@ -319166,7 +320230,7 @@ menclose::after {
319166
320230
  this.#onCursorsUpdate = null;
319167
320231
  this.#isSetup = false;
319168
320232
  }
319169
- }, SEMANTIC_FOOTNOTES_HEADING_BLOCK_ID = "__sd_semantic_footnotes_heading", SEMANTIC_FOOTNOTE_BLOCK_ID_PREFIX = "__sd_semantic_footnote", MULTI_CLICK_TIME_THRESHOLD_MS = 400, MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5, DRAG_SELECTION_DISTANCE_THRESHOLD_PX = 5, AUTO_SCROLL_EDGE_PX = 32, AUTO_SCROLL_MAX_SPEED_PX = 24, SCROLL_DETECTION_TOLERANCE_PX = 1, DEFAULT_PAGE_MARGIN_PX = 72, COMMENT_HIGHLIGHT_SELECTOR = ".superdoc-comment-highlight", TRACK_CHANGE_SELECTOR = "[data-track-change-id]", PM_TRACK_CHANGE_SELECTOR = ".track-insert[data-id], .track-delete[data-id], .track-format[data-id]", VISIBLE_HEADER_FOOTER_SELECTOR = ".superdoc-page-header, .superdoc-page-footer", VISIBLE_BODY_CONTENT_SELECTOR = ".superdoc-line, .superdoc-fragment, [data-block-id]", COMMENT_THREAD_HIT_TOLERANCE_PX = 3, INLINE_SDT_LABEL_SELECTOR, BLOCK_SDT_LABEL_SELECTOR, SDT_LABEL_SELECTOR, EMPTY_SDT_PLACEHOLDER_SELECTOR = ".superdoc-empty-sdt-placeholder", COMMENT_THREAD_HIT_SAMPLE_OFFSETS, clamp = (value, min$2, max$2) => Math.max(min$2, Math.min(max$2, value)), DRAG_SOURCE_SELECTOR = '[data-draggable="true"], [data-drag-source-kind]', EditorInputManager = class {
320233
+ }, SEMANTIC_FOOTNOTES_HEADING_BLOCK_ID = "__sd_semantic_footnotes_heading", SEMANTIC_FOOTNOTE_BLOCK_ID_PREFIX = "__sd_semantic_footnote", HEADER_FOOTER_CONTAINER_SELECTOR = ".superdoc-page-header, .superdoc-page-footer", MULTI_CLICK_TIME_THRESHOLD_MS = 400, MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5, DRAG_SELECTION_DISTANCE_THRESHOLD_PX = 5, AUTO_SCROLL_EDGE_PX = 32, AUTO_SCROLL_MAX_SPEED_PX = 24, SCROLL_DETECTION_TOLERANCE_PX = 1, DEFAULT_PAGE_MARGIN_PX = 72, COMMENT_HIGHLIGHT_SELECTOR = ".superdoc-comment-highlight", TRACK_CHANGE_SELECTOR = "[data-track-change-id]", PM_TRACK_CHANGE_SELECTOR = ".track-insert[data-id], .track-delete[data-id], .track-format[data-id]", VISIBLE_HEADER_FOOTER_SELECTOR = ".superdoc-page-header, .superdoc-page-footer", VISIBLE_BODY_CONTENT_SELECTOR = ".superdoc-line, .superdoc-fragment, [data-block-id]", COMMENT_THREAD_HIT_TOLERANCE_PX = 3, INLINE_SDT_LABEL_SELECTOR, BLOCK_SDT_LABEL_SELECTOR, SDT_LABEL_SELECTOR, EMPTY_SDT_PLACEHOLDER_SELECTOR = ".superdoc-empty-sdt-placeholder", COMMENT_THREAD_HIT_SAMPLE_OFFSETS, clamp = (value, min$2, max$2) => Math.max(min$2, Math.min(max$2, value)), DRAG_SOURCE_SELECTOR = '[data-draggable="true"], [data-drag-source-kind]', EditorInputManager = class {
319170
320234
  #deps = null;
319171
320235
  #callbacks = {};
319172
320236
  #isDragging = false;
@@ -319906,7 +320970,7 @@ menclose::after {
319906
320970
  this.#focusEditor();
319907
320971
  return;
319908
320972
  }
319909
- if (isNoteEditing && activeNoteTarget && !isSameRenderedNoteTarget(parseRenderedNoteTarget$1(rawHit.blockId), activeNoteTarget)) {
320973
+ if (isNoteEditing && activeNoteTarget && !isSameRenderedNoteTarget(parseRenderedNoteTarget(rawHit.blockId), activeNoteTarget)) {
319910
320974
  this.#callbacks.exitActiveStorySession?.();
319911
320975
  this.#focusEditor();
319912
320976
  return;
@@ -320155,6 +321219,15 @@ menclose::after {
320155
321219
  this.#stopAutoScroll();
320156
321220
  this.#callbacks.clearHoverRegion?.();
320157
321221
  }
321222
+ #resolveFootnoteReferenceTargetAtPointer(target, clientX, clientY) {
321223
+ return resolveNoteReferenceAtPointer({
321224
+ target,
321225
+ clientX,
321226
+ clientY,
321227
+ doc: this.#deps?.getEditor()?.state?.doc,
321228
+ ownerDocument: this.#deps?.getViewportHost()?.ownerDocument ?? document
321229
+ });
321230
+ }
320158
321231
  #handleDoubleClick(event) {
320159
321232
  if (!this.#deps)
320160
321233
  return;
@@ -320174,6 +321247,17 @@ menclose::after {
320174
321247
  const normalized = this.#callbacks.normalizeClientPoint?.(event.clientX, event.clientY);
320175
321248
  if (!normalized)
320176
321249
  return;
321250
+ const footnoteRefTarget = this.#resolveFootnoteReferenceTargetAtPointer(target, event.clientX, event.clientY);
321251
+ if (footnoteRefTarget) {
321252
+ event.preventDefault();
321253
+ event.stopPropagation();
321254
+ this.#callbacks.activateRenderedNoteSession?.(footnoteRefTarget, {
321255
+ clientX: event.clientX,
321256
+ clientY: event.clientY,
321257
+ pageIndex: normalized.pageIndex
321258
+ });
321259
+ return;
321260
+ }
320177
321261
  const clickedNoteTarget = this.#resolveRenderedNoteTargetAtPointer(target, event.clientX, event.clientY);
320178
321262
  if (clickedNoteTarget) {
320179
321263
  if (isSameRenderedNoteTarget(this.#getActiveRenderedNoteTarget(), clickedNoteTarget)) {
@@ -320271,12 +321355,20 @@ menclose::after {
320271
321355
  }
320272
321356
  #handleLinkClick(event, linkEl) {
320273
321357
  const href = linkEl.getAttribute("href") ?? "";
320274
- if (href.startsWith("#") && href.length > 1) {
321358
+ const isAnchorLink = href.startsWith("#") && href.length > 1;
321359
+ const noteTarget = parseRenderedNoteTarget(linkEl.closest("[data-block-id]")?.getAttribute("data-block-id") ?? "");
321360
+ if (isAnchorLink) {
320275
321361
  event.preventDefault();
320276
321362
  event.stopPropagation();
321363
+ this.#callbacks.exitActiveStorySession?.();
320277
321364
  this.#callbacks.goToAnchor?.(href);
320278
321365
  return;
320279
321366
  }
321367
+ let bodyPositionsMayBeStale = false;
321368
+ if (!noteTarget) {
321369
+ bodyPositionsMayBeStale = this.#getActiveRenderedNoteTarget() != null;
321370
+ this.#callbacks.exitActiveStorySession?.();
321371
+ }
320280
321372
  event.preventDefault();
320281
321373
  event.stopPropagation();
320282
321374
  const linkClickEvent = new CustomEvent("superdoc-link-click", {
@@ -320289,7 +321381,11 @@ menclose::after {
320289
321381
  tooltip: linkEl.getAttribute("title"),
320290
321382
  element: linkEl,
320291
321383
  clientX: event.clientX,
320292
- clientY: event.clientY
321384
+ clientY: event.clientY,
321385
+ noteTarget,
321386
+ bodyPositionsMayBeStale,
321387
+ ctrlKey: event.ctrlKey,
321388
+ metaKey: event.metaKey
320293
321389
  }
320294
321390
  });
320295
321391
  linkEl.dispatchEvent(linkClickEvent);
@@ -320845,7 +321941,7 @@ menclose::after {
320845
321941
  };
320846
321942
  }
320847
321943
  #resolveRenderedNoteTargetAtPointer(target, clientX, clientY) {
320848
- const parsedFromTarget = parseRenderedNoteTarget$1(target?.closest?.("[data-block-id]")?.getAttribute?.("data-block-id") ?? "");
321944
+ const parsedFromTarget = parseRenderedNoteTarget(target?.closest?.("[data-block-id]")?.getAttribute?.("data-block-id") ?? "");
320849
321945
  if (parsedFromTarget)
320850
321946
  return parsedFromTarget;
320851
321947
  const doc$12 = this.#deps?.getViewportHost()?.ownerDocument ?? document;
@@ -320854,7 +321950,7 @@ menclose::after {
320854
321950
  for (const element3 of doc$12.elementsFromPoint(clientX, clientY)) {
320855
321951
  if (!(element3 instanceof HTMLElement))
320856
321952
  continue;
320857
- const parsed = parseRenderedNoteTarget$1(element3.closest("[data-block-id]")?.getAttribute("data-block-id") ?? "");
321953
+ const parsed = parseRenderedNoteTarget(element3.closest("[data-block-id]")?.getAttribute("data-block-id") ?? "");
320858
321954
  if (parsed)
320859
321955
  return parsed;
320860
321956
  }
@@ -324003,6 +325099,83 @@ menclose::after {
324003
325099
  }
324004
325100
  }
324005
325101
  }
325102
+ }, ACTIVE_NOTE_CLASS = "sd-note-session-active", NoteSessionCoordinator = class {
325103
+ #deps;
325104
+ #activeTarget = null;
325105
+ #pendingScrollIntoView = false;
325106
+ constructor(deps) {
325107
+ this.#deps = deps;
325108
+ }
325109
+ onActivated(target, _session) {
325110
+ this.#activeTarget = target;
325111
+ this.#refreshHighlight();
325112
+ this.#pendingScrollIntoView = true;
325113
+ this.#scrollIntoView();
325114
+ }
325115
+ onPaint() {
325116
+ this.#refreshHighlight();
325117
+ this.#scrollIntoView();
325118
+ }
325119
+ onExit() {
325120
+ this.#activeTarget = null;
325121
+ this.#pendingScrollIntoView = false;
325122
+ this.#refreshHighlight();
325123
+ }
325124
+ #findActiveFragments(host) {
325125
+ const target = this.#activeTarget;
325126
+ if (!target)
325127
+ return [];
325128
+ const prefixes = renderedNoteBlockIdPrefixes(target);
325129
+ return Array.from(host.querySelectorAll("[data-block-id]")).filter((el) => {
325130
+ const id2 = el.getAttribute("data-block-id") ?? "";
325131
+ return prefixes.some((prefix2) => id2.startsWith(prefix2));
325132
+ });
325133
+ }
325134
+ #refreshHighlight() {
325135
+ const host = this.#deps.getHost();
325136
+ if (!host)
325137
+ return;
325138
+ if (this.#activeTarget && !this.#deps.hasActiveSession())
325139
+ this.#activeTarget = null;
325140
+ host.querySelectorAll(`.${ACTIVE_NOTE_CLASS}`).forEach((el) => el.classList.remove(ACTIVE_NOTE_CLASS));
325141
+ this.#findActiveFragments(host).forEach((el) => el.classList.add(ACTIVE_NOTE_CLASS));
325142
+ }
325143
+ #scrollIntoView() {
325144
+ if (!this.#pendingScrollIntoView)
325145
+ return;
325146
+ if (!this.#activeTarget) {
325147
+ this.#pendingScrollIntoView = false;
325148
+ return;
325149
+ }
325150
+ const host = this.#deps.getHost();
325151
+ if (!host)
325152
+ return;
325153
+ const fragment2 = this.#findActiveFragments(host)[0];
325154
+ if (!fragment2)
325155
+ return;
325156
+ this.#pendingScrollIntoView = false;
325157
+ const rect = fragment2.getBoundingClientRect();
325158
+ const scroller = this.#deps.getScrollContainer();
325159
+ const viewport$1 = scroller instanceof Window ? {
325160
+ top: 0,
325161
+ bottom: scroller.innerHeight
325162
+ } : scroller instanceof Element ? (() => {
325163
+ const r$1 = scroller.getBoundingClientRect();
325164
+ return {
325165
+ top: r$1.top,
325166
+ bottom: r$1.bottom
325167
+ };
325168
+ })() : {
325169
+ top: 0,
325170
+ bottom: window.innerHeight
325171
+ };
325172
+ if (rect.top >= viewport$1.top + 8 && rect.bottom <= viewport$1.bottom - 8)
325173
+ return;
325174
+ fragment2.scrollIntoView({
325175
+ block: "center",
325176
+ behavior: "smooth"
325177
+ });
325178
+ }
324006
325179
  }, ENDNOTE_MARKER_DATA_ATTR = "data-sd-endnote-number", DEFAULT_MARKER_FONT_FAMILY = "Arial", DEFAULT_MARKER_FONT_SIZE = 12, FontLateLoadReflowScheduler = class {
324007
325180
  #quietMs;
324008
325181
  #cooldownMs;
@@ -324594,13 +325767,13 @@ menclose::after {
324594
325767
  return;
324595
325768
  console.log(...args$1);
324596
325769
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions, TRACKED_MARK_NAMES;
324597
- var init_src_COxdGpKV_es = __esm(() => {
325770
+ var init_src_C3y2aHWQ_es = __esm(() => {
324598
325771
  init_rolldown_runtime_Bg48TavK_es();
324599
- init_SuperConverter_0i3YuAr2_es();
325772
+ init_SuperConverter_Bdmhv7BA_es();
324600
325773
  init_jszip_C49i9kUs_es();
324601
325774
  init_xml_js_CqGKpaft_es();
324602
325775
  init_uuid_B2wVPhPi_es();
324603
- init_create_headless_toolbar_DYCEnt7x_es();
325776
+ init_create_headless_toolbar_VA4azb5D_es();
324604
325777
  init_constants_D9qj59G2_es();
324605
325778
  init_unified_BDuVPlMu_es();
324606
325779
  init_remark_gfm_BUJjZJLy_es();
@@ -329644,7 +330817,7 @@ var init_src_COxdGpKV_es = __esm(() => {
329644
330817
  },
329645
330818
  "footnotes.insert": {
329646
330819
  memberPath: "footnotes.insert",
329647
- description: `Insert a new footnote or endnote at a target location.${FOOTNOTE_STRUCTURED_BODY_V1_NOTE2}`,
330820
+ description: `Insert a new footnote or endnote at a target location or the current selection.${FOOTNOTE_STRUCTURED_BODY_V1_NOTE2}`,
329648
330821
  expectedResult: "Returns a FootnoteMutationResult indicating success with the footnote address or a failure.",
329649
330822
  requiresDocumentContext: true,
329650
330823
  metadata: mutationOperation2({
@@ -331968,10 +333141,12 @@ ${err.toString()}`);
331968
333141
  partSyncHandle: null,
331969
333142
  partSyncPendingCleanup: null,
331970
333143
  bodySectPrPendingCleanup: null,
331971
- bodySectPrTransactionHandler: null
333144
+ bodySectPrTransactionHandler: null,
333145
+ noteTombstoneSyncHandle: null
331972
333146
  };
331973
333147
  collaborationCleanupByEditor.set(this.editor, cleanupState);
331974
333148
  registerBodySectPrSync(this.editor, this.options.ydoc, this.editor.options.collaborationProvider, cleanupState);
333149
+ cleanupState.noteTombstoneSyncHandle = registerNoteTombstoneSync(this.editor, this.options.ydoc);
331975
333150
  if (typeof this.editor.on === "function") {
331976
333151
  const editor = this.editor;
331977
333152
  const ydoc = this.options.ydoc;
@@ -333596,7 +334771,6 @@ ${err.toString()}`);
333596
334771
  return new OxmlNode2(config2);
333597
334772
  }
333598
334773
  };
333599
- TrackChangesBasePluginKey = new PluginKey("TrackChangesBase");
333600
334774
  TRACK_CHANGE_MARKS$1 = [
333601
334775
  TrackInsertMarkName,
333602
334776
  TrackDeleteMarkName,
@@ -334295,6 +335469,7 @@ ${err.toString()}`);
334295
335469
  DELETABLE_INLINE_ATOMS$1 = new Set(["noBreakHyphen"]);
334296
335470
  DELETABLE_INLINE_ATOMS = new Set(["noBreakHyphen"]);
334297
335471
  commands_exports = /* @__PURE__ */ __export3({
335472
+ SELECT_FOOTNOTE_MARKER_META: () => SELECT_FOOTNOTE_MARKER_META,
334298
335473
  SELECT_INLINE_SDT_BEFORE_RUN_START_META: () => SELECT_INLINE_SDT_BEFORE_RUN_START_META,
334299
335474
  backspaceAcrossRuns: () => backspaceAcrossRuns,
334300
335475
  backspaceAtomBefore: () => backspaceAtomBefore,
@@ -334345,6 +335520,8 @@ ${err.toString()}`);
334345
335520
  selectAll: () => selectAll$1,
334346
335521
  selectBlockSdtAfterTextBlockEnd: () => selectBlockSdtAfterTextBlockEnd,
334347
335522
  selectBlockSdtBeforeTextBlockStart: () => selectBlockSdtBeforeTextBlockStart,
335523
+ selectFootnoteMarkerAfter: () => selectFootnoteMarkerAfter,
335524
+ selectFootnoteMarkerBefore: () => selectFootnoteMarkerBefore,
334348
335525
  selectInlineSdtAfterRunEnd: () => selectInlineSdtAfterRunEnd,
334349
335526
  selectInlineSdtBeforeRunStart: () => selectInlineSdtBeforeRunStart,
334350
335527
  selectNodeBackward: () => selectNodeBackward$1,
@@ -334377,6 +335554,7 @@ ${err.toString()}`);
334377
335554
  updateNumberingProperties: () => updateNumberingProperties
334378
335555
  }, 1);
334379
335556
  nodeViewMap = /* @__PURE__ */ new WeakMap;
335557
+ noteStyleGuardPluginKey = new PluginKey("noteStyleGuard");
334380
335558
  CSS_LENGTH_TO_PT = {
334381
335559
  pt: 1,
334382
335560
  px: 72 / 96,
@@ -334637,7 +335815,8 @@ ${err.toString()}`);
334637
335815
  return true;
334638
335816
  } } } }),
334639
335817
  createLeadingCaretPlugin(),
334640
- createListBoundaryNavigationPlugin()
335818
+ createListBoundaryNavigationPlugin(),
335819
+ createNoteStyleGuardPlugin(this.editor)
334641
335820
  ];
334642
335821
  }
334643
335822
  });
@@ -334778,6 +335957,10 @@ ${err.toString()}`);
334778
335957
  return [CommentMarkName, Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
334779
335958
  }
334780
335959
  });
335960
+ NOTE_TYPE_BY_NODE = {
335961
+ footnoteReference: "footnote",
335962
+ endnoteReference: "endnote"
335963
+ };
334781
335964
  FootnoteReference = Node$13.create({
334782
335965
  name: "footnoteReference",
334783
335966
  group: "inline",
@@ -334800,6 +335983,28 @@ ${err.toString()}`);
334800
335983
  return new FootnoteReferenceNodeView(node3, getPos, decorations, editor, htmlAttributes);
334801
335984
  };
334802
335985
  },
335986
+ addCommands() {
335987
+ return {
335988
+ insertFootnote: () => ({ editor, tr, dispatch }) => {
335989
+ if (!dispatch)
335990
+ return canInsertNoteAtCursor(editor);
335991
+ const handled = insertFootnoteAtCursor(editor);
335992
+ if (handled)
335993
+ tr.setMeta("preventDispatch", true);
335994
+ return handled;
335995
+ },
335996
+ deleteSelectedNoteMarker: () => ({ editor, state, tr, dispatch }) => {
335997
+ if (!getSelectedNoteMarker(state))
335998
+ return false;
335999
+ if (!dispatch)
336000
+ return true;
336001
+ const handled = deleteSelectedNoteMarker(editor);
336002
+ if (handled)
336003
+ tr.setMeta("preventDispatch", true);
336004
+ return handled;
336005
+ }
336006
+ };
336007
+ },
334803
336008
  parseDOM() {
334804
336009
  return [{ tag: "sup[data-footnote-id]" }];
334805
336010
  },
@@ -349809,21 +351014,27 @@ function print() { __p += __j.call(arguments, '') }
349809
351014
  apply(tr, value) {
349810
351015
  const meta2 = tr.getMeta(VerticalNavigationPluginKey);
349811
351016
  if (meta2?.type === "vertical-move")
349812
- return { goalX: meta2.goalX ?? value.goalX ?? null };
351017
+ return {
351018
+ goalX: meta2.goalX ?? value.goalX ?? null,
351019
+ goalClientX: meta2.goalClientX ?? value.goalClientX ?? null
351020
+ };
349813
351021
  if (meta2?.type === "set-goal-x")
349814
351022
  return {
349815
351023
  ...value,
349816
- goalX: meta2.goalX ?? null
351024
+ goalX: meta2.goalX ?? null,
351025
+ goalClientX: meta2.goalClientX ?? null
349817
351026
  };
349818
351027
  if (meta2?.type === "reset-goal-x")
349819
351028
  return {
349820
351029
  ...value,
349821
- goalX: null
351030
+ goalX: null,
351031
+ goalClientX: null
349822
351032
  };
349823
351033
  if (tr.selectionSet)
349824
351034
  return {
349825
351035
  ...value,
349826
- goalX: null
351036
+ goalX: null,
351037
+ goalClientX: null
349827
351038
  };
349828
351039
  return value;
349829
351040
  }
@@ -349859,24 +351070,33 @@ function print() { __p += __j.call(arguments, '') }
349859
351070
  return false;
349860
351071
  if (!isPresenting(editor))
349861
351072
  return false;
349862
- let goalX = VerticalNavigationPluginKey.getState(view.state)?.goalX;
351073
+ const pluginState = VerticalNavigationPluginKey.getState(view.state);
351074
+ let goalX = pluginState?.goalX;
351075
+ let goalClientX = pluginState?.goalClientX;
349863
351076
  const coords = getCurrentCoords(editor, view.state.selection);
349864
351077
  if (!coords)
349865
351078
  return false;
349866
- if (goalX == null) {
351079
+ if (goalX == null || goalClientX == null) {
349867
351080
  goalX = coords?.x;
349868
- if (!Number.isFinite(goalX))
351081
+ goalClientX = coords?.clientX;
351082
+ if (!Number.isFinite(goalX) || !Number.isFinite(goalClientX))
349869
351083
  return false;
349870
351084
  view.dispatch(view.state.tr.setMeta(VerticalNavigationPluginKey, {
349871
351085
  type: "set-goal-x",
349872
- goalX
351086
+ goalX,
351087
+ goalClientX
349873
351088
  }));
349874
351089
  }
349875
351090
  const adjacent = getAdjacentLineClientTarget(editor, coords, event.key === "ArrowUp" ? -1 : 1);
349876
351091
  if (!adjacent)
349877
351092
  return false;
349878
- let hit = getHitFromLayoutCoords(editor, goalX, adjacent.clientY, coords, adjacent.pageIndex);
349879
- if (adjacent.pmStart != null && adjacent.pmEnd != null) {
351093
+ const isNoteSession = Boolean(editor?.options?.parentEditor && !editor?.options?.isHeaderOrFooter);
351094
+ let hit = null;
351095
+ if (isNoteSession && adjacent.lineElement)
351096
+ hit = resolvePositionAtClientPoint(editor.presentationEditor?.visibleHost?.ownerDocument ?? document, adjacent.lineElement, goalClientX);
351097
+ if (!hit)
351098
+ hit = editor.presentationEditor.hitTest(goalClientX, adjacent.clientY);
351099
+ if (!isNoteSession && adjacent.pmStart != null && adjacent.pmEnd != null) {
349880
351100
  const TOLERANCE = 5;
349881
351101
  const hitPos = hit?.pos;
349882
351102
  if (!hit || !Number.isFinite(hitPos) || hitPos < adjacent.pmStart - TOLERANCE || hitPos > adjacent.pmEnd + TOLERANCE)
@@ -349889,7 +351109,8 @@ function print() { __p += __j.call(arguments, '') }
349889
351109
  return false;
349890
351110
  view.dispatch(view.state.tr.setMeta(VerticalNavigationPluginKey, {
349891
351111
  type: "vertical-move",
349892
- goalX
351112
+ goalX,
351113
+ goalClientX
349893
351114
  }).setSelection(selection));
349894
351115
  return true;
349895
351116
  },
@@ -355652,7 +356873,7 @@ function print() { __p += __j.call(arguments, '') }
355652
356873
  stylesPartDescriptor = {
355653
356874
  id: STYLES_PART_ID,
355654
356875
  ensurePart(editor) {
355655
- const converter = getConverter$72(editor);
356876
+ const converter = getConverter$62(editor);
355656
356877
  if (converter?.convertedXml[STYLES_PART_ID])
355657
356878
  return converter.convertedXml[STYLES_PART_ID];
355658
356879
  return {
@@ -355667,7 +356888,7 @@ function print() { __p += __j.call(arguments, '') }
355667
356888
  },
355668
356889
  afterCommit(ctx$1) {
355669
356890
  if (ctx$1.source.startsWith("collab:remote:") || ctx$1.source === "templates.apply") {
355670
- const converter = getConverter$72(ctx$1.editor);
356891
+ const converter = getConverter$62(ctx$1.editor);
355671
356892
  if (converter)
355672
356893
  try {
355673
356894
  converter.translatedLinkedStyles = translateStyleDefinitions(converter.convertedXml);
@@ -356060,14 +357281,8 @@ function print() { __p += __j.call(arguments, '') }
356060
357281
  KIND_ORDER = ["header", "footer"];
356061
357282
  HEADER_FILE_PATTERN2 = /header(\d+)\.xml$/;
356062
357283
  FOOTER_FILE_PATTERN2 = /footer(\d+)\.xml$/;
356063
- SPECIAL_NOTE_TYPES = new Set(["separator", "continuationSeparator"]);
356064
357284
  import_lib4 = /* @__PURE__ */ __toESM2(require_lib(), 1);
356065
357285
  SETTINGS_PART = SETTINGS_PART_PATH;
356066
- RESTART_POLICY_TO_OOXML = {
356067
- continuous: "continuous",
356068
- eachSection: "eachSect",
356069
- eachPage: "eachPage"
356070
- };
356071
357286
  VALID_DISPLAYS = new Set([
356072
357287
  "content",
356073
357288
  "pageNumber",
@@ -357835,11 +359050,19 @@ function print() { __p += __j.call(arguments, '') }
357835
359050
  const hasCustomSettings = !!this.converter.convertedXml["word/settings.xml"]?.elements?.length;
357836
359051
  const customSettings = hasCustomSettings ? this.converter.schemaToXml(this.converter.convertedXml["word/settings.xml"]?.elements?.[0]) : null;
357837
359052
  const rels = this.converter.schemaToXml(this.converter.convertedXml["word/_rels/document.xml.rels"].elements[0]);
357838
- const footnotesData = this.converter.convertedXml["word/footnotes.xml"];
359053
+ const footnotesData = pruneSessionDeletedNotesPart(this.converter.convertedXml["word/footnotes.xml"], {
359054
+ converter: this.converter,
359055
+ documentXml: this.converter.convertedXml["word/document.xml"],
359056
+ type: "footnote"
359057
+ });
357839
359058
  const footnotesXml = footnotesData?.elements?.[0] ? this.converter.schemaToXml(footnotesData.elements[0]) : null;
357840
359059
  const footnotesRelsData = this.converter.convertedXml["word/_rels/footnotes.xml.rels"];
357841
359060
  const footnotesRelsXml = footnotesRelsData?.elements?.[0] ? this.converter.schemaToXml(footnotesRelsData.elements[0]) : null;
357842
- const endnotesData = this.converter.convertedXml["word/endnotes.xml"];
359061
+ const endnotesData = pruneSessionDeletedNotesPart(this.converter.convertedXml["word/endnotes.xml"], {
359062
+ converter: this.converter,
359063
+ documentXml: this.converter.convertedXml["word/document.xml"],
359064
+ type: "endnote"
359065
+ });
357843
359066
  const endnotesXml = endnotesData?.elements?.[0] ? this.converter.schemaToXml(endnotesData.elements[0]) : null;
357844
359067
  const endnotesRelsData = this.converter.convertedXml["word/_rels/endnotes.xml.rels"];
357845
359068
  const endnotesRelsXml = endnotesRelsData?.elements?.[0] ? this.converter.schemaToXml(endnotesRelsData.elements[0]) : null;
@@ -360055,6 +361278,7 @@ function print() { __p += __j.call(arguments, '') }
360055
361278
  #painterHost;
360056
361279
  #selectionOverlay;
360057
361280
  #permissionOverlay = null;
361281
+ #noteSessionCoordinator = null;
360058
361282
  #hiddenHost;
360059
361283
  #hiddenHostWrapper;
360060
361284
  #layoutOptions;
@@ -360066,6 +361290,7 @@ function print() { __p += __j.call(arguments, '') }
360066
361290
  bookmarks: /* @__PURE__ */ new Map
360067
361291
  };
360068
361292
  #layoutFontSignature = "";
361293
+ #footnoteReserveSeed = null;
360069
361294
  #layoutLookupBlocks = [];
360070
361295
  #layoutLookupMeasures = [];
360071
361296
  #flowBlockCache = new FlowBlockCache;
@@ -361445,6 +362670,7 @@ function print() { __p += __j.call(arguments, '') }
361445
362670
  measures: [],
361446
362671
  layout: null
361447
362672
  };
362673
+ this.#footnoteReserveSeed = null;
361448
362674
  this.#pendingDocChange = true;
361449
362675
  this.#scheduleRerender();
361450
362676
  }
@@ -362627,10 +363853,10 @@ function print() { __p += __j.call(arguments, '') }
362627
363853
  this.#editorInputManager?.clearCellAnchor();
362628
363854
  }
362629
363855
  };
362630
- const handleSelection = () => {
363856
+ const handleSelection = ({ transaction } = {}) => {
362631
363857
  if (!this.#editorInputManager?.isDragging)
362632
363858
  this.#shouldScrollSelectionIntoView = true;
362633
- this.#scheduleSelectionUpdate({ immediate: true });
363859
+ this.#scheduleSelectionUpdate({ immediate: !transaction?.docChanged });
362634
363860
  this.#updateLocalAwarenessCursor();
362635
363861
  this.#scheduleA11ySelectionAnnouncement();
362636
363862
  };
@@ -362739,6 +363965,7 @@ function print() { __p += __j.call(arguments, '') }
362739
363965
  this.#fontGate?.resetForDocumentChange();
362740
363966
  this.#fontController.reset();
362741
363967
  this.#layoutFontSignature = "";
363968
+ this.#footnoteReserveSeed = null;
362742
363969
  this.#fontController.applyInitialConfig(this.#options.fontAssets);
362743
363970
  this.#applyEmbeddedDocumentFonts();
362744
363971
  this.#resetFontReportStateForDocumentChange();
@@ -363906,7 +365133,8 @@ function print() { __p += __j.call(arguments, '') }
363906
365133
  const result = await incrementalLayout(previousBlocks, previousLayout, blocksForLayout, layoutOptions, (block, constraints) => measureBlock(block, constraints, fontMeasureContext), headerFooterInput ?? undefined, previousMeasures, {
363907
365134
  fontContext: fontMeasureContext,
363908
365135
  previousFontSignature
363909
- });
365136
+ }, { footnoteReserveSeed: this.#footnoteReserveSeed });
365137
+ this.#footnoteReserveSeed = result?.footnoteReserveSeed ?? null;
363910
365138
  perfLog(`[Perf] incrementalLayout: ${(perfNow() - incrementalLayoutStart).toFixed(2)}ms`);
363911
365139
  if (!result || typeof result !== "object") {
363912
365140
  this.#handleLayoutError("render", /* @__PURE__ */ new Error("incrementalLayout returned invalid result"));
@@ -364027,6 +365255,7 @@ function print() { __p += __j.call(arguments, '') }
364027
365255
  };
364028
365256
  this.emit("layoutUpdated", payload);
364029
365257
  this.emit("paginationUpdate", payload);
365258
+ this.#noteSessionCoordinator?.onPaint();
364030
365259
  this.#emitCommentPositions();
364031
365260
  this.#selectionSync.requestRender({ immediate: true });
364032
365261
  if (this.#remoteCursorManager?.hasRemoteCursors()) {
@@ -365146,22 +366375,39 @@ function print() { __p += __j.call(arguments, '') }
365146
366375
  surfaceKind: target.storyType === "endnote" ? "endnote" : "note"
365147
366376
  }
365148
366377
  });
365149
- const hit = this.hitTest(options.clientX, options.clientY);
365150
366378
  const doc$12 = session.editor.state?.doc;
365151
- if (hit && doc$12)
365152
- try {
365153
- const selection = this.#createCollapsedSelectionNearInlineContent(doc$12, hit.pos);
365154
- const tr = session.editor.state.tr.setSelection(selection);
365155
- session.editor.view?.dispatch(tr);
365156
- } catch {}
366379
+ if (typeof options.clientX === "number" && typeof options.clientY === "number" && doc$12) {
366380
+ const hit = this.hitTest(options.clientX, options.clientY);
366381
+ if (hit)
366382
+ try {
366383
+ const selection = this.#createCollapsedSelectionNearInlineContent(doc$12, hit.pos);
366384
+ const tr = session.editor.state.tr.setSelection(selection);
366385
+ session.editor.view?.dispatch(tr);
366386
+ } catch {}
366387
+ }
365157
366388
  session.editor.view?.focus();
365158
366389
  this.#shouldScrollSelectionIntoView = true;
365159
366390
  this.#scheduleSelectionUpdate({ immediate: true });
366391
+ this.#ensureNoteSessionCoordinator().onActivated(target, session);
365160
366392
  return true;
365161
366393
  }
366394
+ #ensureNoteSessionCoordinator() {
366395
+ if (!this.#noteSessionCoordinator)
366396
+ this.#noteSessionCoordinator = new NoteSessionCoordinator({
366397
+ getHost: () => this.#painterHost ?? this.#visibleHost,
366398
+ getScrollContainer: () => this.#scrollContainer,
366399
+ hasActiveSession: () => Boolean(this.#getActiveStorySession()),
366400
+ exitActiveSession: () => this.#exitActiveStorySession()
366401
+ });
366402
+ return this.#noteSessionCoordinator;
366403
+ }
366404
+ activateNoteSession(target) {
366405
+ return this.#activateRenderedNoteSession(target, {});
366406
+ }
365162
366407
  #exitActiveStorySession() {
365163
366408
  if (!this.#getActiveStorySession())
365164
366409
  return;
366410
+ this.#noteSessionCoordinator?.onExit();
365165
366411
  this.#storySessionManager?.exit();
365166
366412
  this.#pendingDocChange = true;
365167
366413
  this.#scheduleRerender();
@@ -365942,21 +367188,30 @@ function print() { __p += __j.call(arguments, '') }
365942
367188
  const layout = this.#layoutState.layout;
365943
367189
  if (!layout)
365944
367190
  return null;
365945
- const startOffset = this.#measureActiveEditorVisibleTextOffset(Math.min(from$1, to));
365946
- const endOffset = this.#measureActiveEditorVisibleTextOffset(Math.max(from$1, to));
365947
- if (startOffset == null || endOffset == null)
365948
- return null;
365949
367191
  const noteFragments = this.#getRenderedNoteFragmentElements(this.#collectNoteBlockIds(context));
365950
367192
  if (!noteFragments.length)
365951
367193
  return null;
365952
- const renderedStartOffset = this.#toRenderedNoteVisibleTextOffset(noteFragments, startOffset);
365953
- const renderedEndOffset = this.#toRenderedNoteVisibleTextOffset(noteFragments, endOffset);
365954
- return computeSelectionRectsFromVisibleTextOffsets({
367194
+ const geometryOptions = {
365955
367195
  containers: noteFragments,
365956
367196
  zoom: this.#layoutOptions.zoom ?? 1,
365957
367197
  pageHeight: this.#getBodyPageHeight(),
365958
367198
  pageGap: layout.pageGap ?? this.#getEffectivePageGap()
365959
- }, renderedStartOffset, renderedEndOffset);
367199
+ };
367200
+ const pmRects = computeSelectionRectsFromPmRange(geometryOptions, from$1, to, {
367201
+ from: this.#resolveNoteBlockAnchor(from$1),
367202
+ to: this.#resolveNoteBlockAnchor(to)
367203
+ });
367204
+ if (pmRects != null)
367205
+ return pmRects;
367206
+ if (this.#renderScheduled || this.#isRerendering || this.#pendingDocChange) {
367207
+ this.#scheduleSelectionUpdate({ immediate: false });
367208
+ return null;
367209
+ }
367210
+ const startOffset = this.#measureActiveEditorVisibleTextOffset(Math.min(from$1, to));
367211
+ const endOffset = this.#measureActiveEditorVisibleTextOffset(Math.max(from$1, to));
367212
+ if (startOffset == null || endOffset == null)
367213
+ return null;
367214
+ return computeSelectionRectsFromVisibleTextOffsets(geometryOptions, this.#toRenderedNoteVisibleTextOffset(noteFragments, startOffset), this.#toRenderedNoteVisibleTextOffset(noteFragments, endOffset));
365960
367215
  }
365961
367216
  #computeNoteSelectionRects(from$1, to) {
365962
367217
  const context = this.#buildActiveNoteLayoutContext();
@@ -365968,6 +367223,44 @@ function print() { __p += __j.call(arguments, '') }
365968
367223
  return domRects;
365969
367224
  return selectionToRects(layout, context.blocks, context.measures, from$1, to, this.#pageGeometryHelper ?? undefined);
365970
367225
  }
367226
+ #resolveNoteBlockAnchor(pos) {
367227
+ const doc$12 = this.getActiveEditor()?.state?.doc;
367228
+ if (!doc$12 || !Number.isFinite(pos))
367229
+ return null;
367230
+ try {
367231
+ const clamped = Math.max(0, Math.min(pos, doc$12.content.size));
367232
+ const $pos = doc$12.resolve(clamped);
367233
+ let blockDepth = 0;
367234
+ for (let depth = $pos.depth;depth >= 1; depth -= 1)
367235
+ if ($pos.node(depth).isBlock)
367236
+ blockDepth = depth;
367237
+ if (!blockDepth)
367238
+ return null;
367239
+ const blockNode = $pos.node(blockDepth);
367240
+ const sdBlockId = blockNode.attrs?.sdBlockId;
367241
+ if (typeof sdBlockId !== "string" || !sdBlockId)
367242
+ return null;
367243
+ const blockPos = $pos.before(blockDepth);
367244
+ let currentStart = null;
367245
+ doc$12.nodesBetween(blockPos, blockPos + blockNode.nodeSize, (node3, nodePos) => {
367246
+ if (currentStart != null)
367247
+ return false;
367248
+ if (node3.isInline && (node3.isLeaf || node3.isText)) {
367249
+ currentStart = nodePos;
367250
+ return false;
367251
+ }
367252
+ return true;
367253
+ });
367254
+ if (currentStart == null)
367255
+ currentStart = blockPos + 1;
367256
+ return {
367257
+ sdBlockId,
367258
+ currentStart
367259
+ };
367260
+ } catch {
367261
+ return null;
367262
+ }
367263
+ }
365971
367264
  #computeNoteDomCaretRect(context, pos) {
365972
367265
  const layout = this.#layoutState.layout;
365973
367266
  if (!layout)
@@ -365975,19 +367268,30 @@ function print() { __p += __j.call(arguments, '') }
365975
367268
  const noteBlockIds = this.#collectNoteBlockIds(context);
365976
367269
  if (noteBlockIds.size === 0)
365977
367270
  return null;
365978
- const textOffset = this.#measureActiveEditorVisibleTextOffset(pos);
365979
- if (textOffset == null)
365980
- return null;
365981
367271
  const noteFragments = this.#getRenderedNoteFragmentElements(noteBlockIds);
365982
367272
  if (!noteFragments.length)
365983
367273
  return null;
365984
- const renderedTextOffset = this.#toRenderedNoteVisibleTextOffset(noteFragments, textOffset);
365985
- return computeCaretRectFromVisibleTextOffset({
367274
+ const geometryOptions = {
365986
367275
  containers: noteFragments,
365987
367276
  zoom: this.#layoutOptions.zoom ?? 1,
365988
367277
  pageHeight: this.#getBodyPageHeight(),
365989
367278
  pageGap: layout.pageGap ?? this.#getEffectivePageGap()
365990
- }, renderedTextOffset);
367279
+ };
367280
+ const anchor = this.#resolveNoteBlockAnchor(pos);
367281
+ const anchoredRect = anchor ? computeCaretRectFromPmPosition(geometryOptions, pos, anchor) : null;
367282
+ if (anchoredRect)
367283
+ return anchoredRect;
367284
+ const pmRect = computeCaretRectFromPmPosition(geometryOptions, pos);
367285
+ if (pmRect)
367286
+ return pmRect;
367287
+ if (this.#renderScheduled || this.#isRerendering || this.#pendingDocChange) {
367288
+ this.#scheduleSelectionUpdate({ immediate: false });
367289
+ return null;
367290
+ }
367291
+ const textOffset = this.#measureActiveEditorVisibleTextOffset(pos);
367292
+ if (textOffset == null)
367293
+ return null;
367294
+ return computeCaretRectFromVisibleTextOffset(geometryOptions, this.#toRenderedNoteVisibleTextOffset(noteFragments, textOffset));
365991
367295
  }
365992
367296
  #computeNoteCaretRect(pos) {
365993
367297
  const context = this.#buildActiveNoteLayoutContext();
@@ -366324,6 +367628,7 @@ function print() { __p += __j.call(arguments, '') }
366324
367628
  error: error3,
366325
367629
  timestamp: Date.now()
366326
367630
  };
367631
+ this.#footnoteReserveSeed = null;
366327
367632
  if (phase === "initialization")
366328
367633
  this.#layoutErrorState = "failed";
366329
367634
  else
@@ -366692,11 +367997,11 @@ function print() { __p += __j.call(arguments, '') }
366692
367997
  ]);
366693
367998
  });
366694
367999
 
366695
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-C1LNsWpB.es.js
368000
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-Bi5_b_W1.es.js
366696
368001
  var DEFAULT_TEXT_ALIGN_OPTIONS, DEFAULT_LINE_HEIGHT_OPTIONS, DEFAULT_ZOOM_OPTIONS, DEFAULT_DOCUMENT_MODE_OPTIONS, DEFAULT_FONT_SIZE_OPTIONS, headlessToolbarConstants, MOD_ALIASES, ALT_ALIASES, CTRL_ALIASES, SHIFT_ALIASES, BUILTIN_CONTEXT_MENU_GROUPS, BUILTIN_GROUP_ORDER, RESERVED_PROXY_PROPERTY_NAMES, ALL_TOOLBAR_COMMAND_IDS, EMPTY_ACTIVE_IDS, FONT_SIZE_OPTIONS;
366697
- var init_create_super_doc_ui_C1LNsWpB_es = __esm(() => {
366698
- init_SuperConverter_0i3YuAr2_es();
366699
- init_create_headless_toolbar_DYCEnt7x_es();
368002
+ var init_create_super_doc_ui_Bi5_b_W1_es = __esm(() => {
368003
+ init_SuperConverter_Bdmhv7BA_es();
368004
+ init_create_headless_toolbar_VA4azb5D_es();
366700
368005
  DEFAULT_TEXT_ALIGN_OPTIONS = [
366701
368006
  {
366702
368007
  label: "Left",
@@ -366987,15 +368292,15 @@ var init_zipper_BxRAi0_5_es = __esm(() => {
366987
368292
 
366988
368293
  // ../../packages/superdoc/dist/super-editor.es.js
366989
368294
  var init_super_editor_es = __esm(() => {
366990
- init_src_COxdGpKV_es();
366991
- init_SuperConverter_0i3YuAr2_es();
368295
+ init_src_C3y2aHWQ_es();
368296
+ init_SuperConverter_Bdmhv7BA_es();
366992
368297
  init_jszip_C49i9kUs_es();
366993
368298
  init_xml_js_CqGKpaft_es();
366994
- init_create_headless_toolbar_DYCEnt7x_es();
368299
+ init_create_headless_toolbar_VA4azb5D_es();
366995
368300
  init_constants_D9qj59G2_es();
366996
368301
  init_unified_BDuVPlMu_es();
366997
368302
  init_DocxZipper_BzS208BW_es();
366998
- init_create_super_doc_ui_C1LNsWpB_es();
368303
+ init_create_super_doc_ui_Bi5_b_W1_es();
366999
368304
  init_ui_CGB3qmy3_es();
367000
368305
  init_eventemitter3_UwU_CLPU_es();
367001
368306
  init_errors_C_DoKMoN_es();