@superdoc-dev/cli 0.16.0-next.4 → 0.16.0-next.5

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 +1524 -223
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -68110,7 +68110,7 @@ var init_remark_gfm_BhnWr3yf_es = __esm(() => {
68110
68110
  emptyOptions2 = {};
68111
68111
  });
68112
68112
 
68113
- // ../../packages/superdoc/dist/chunks/SuperConverter-nmIRMGtB.es.js
68113
+ // ../../packages/superdoc/dist/chunks/SuperConverter-LqX_f8x4.es.js
68114
68114
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
68115
68115
  const fieldValue = extension$1.config[field];
68116
68116
  if (typeof fieldValue === "function")
@@ -98476,7 +98476,7 @@ function importNoteEntries({ partXml, childElementName, filename, docx, editor,
98476
98476
  const idNumber = Number(id2);
98477
98477
  const originalXml = carbonCopy(el);
98478
98478
  const type = el?.attributes?.["w:type"] || null;
98479
- if (type === "separator" || type === "continuationSeparator") {
98479
+ if (type === "separator" || type === "continuationSeparator" || type === "continuationNotice") {
98480
98480
  results.push({
98481
98481
  id: id2,
98482
98482
  type,
@@ -102188,17 +102188,78 @@ function buildReferenceMarkerRun(displayText, params3) {
102188
102188
  fontSize: baseFontSize * SUBSCRIPT_SUPERSCRIPT_SCALE
102189
102189
  }, params3);
102190
102190
  }
102191
+ function toUpperRoman(num) {
102192
+ if (num < 1 || num > 3999)
102193
+ return String(num);
102194
+ const values = [
102195
+ 1000,
102196
+ 900,
102197
+ 500,
102198
+ 400,
102199
+ 100,
102200
+ 90,
102201
+ 50,
102202
+ 40,
102203
+ 10,
102204
+ 9,
102205
+ 5,
102206
+ 4,
102207
+ 1
102208
+ ];
102209
+ const numerals = [
102210
+ "M",
102211
+ "CM",
102212
+ "D",
102213
+ "CD",
102214
+ "C",
102215
+ "XC",
102216
+ "L",
102217
+ "XL",
102218
+ "X",
102219
+ "IX",
102220
+ "V",
102221
+ "IV",
102222
+ "I"
102223
+ ];
102224
+ let result = "";
102225
+ let remaining = num;
102226
+ for (let i$1 = 0;i$1 < values.length; i$1 += 1)
102227
+ while (remaining >= values[i$1]) {
102228
+ result += numerals[i$1];
102229
+ remaining -= values[i$1];
102230
+ }
102231
+ return result;
102232
+ }
102233
+ function toUpperLetter(num) {
102234
+ if (num < 1)
102235
+ return "A";
102236
+ let result = "";
102237
+ let n = num;
102238
+ while (n > 0) {
102239
+ const remainder = (n - 1) % 26;
102240
+ result = String.fromCharCode(65 + remainder) + result;
102241
+ n = Math.floor((n - 1) / 26);
102242
+ }
102243
+ return result;
102244
+ }
102191
102245
  function footnoteReferenceToBlock(params3) {
102192
102246
  const { node: node3, converterContext } = params3;
102193
- const id2 = node3.attrs?.id;
102194
- const displayId = resolveFootnoteDisplayNumber(id2, converterContext.footnoteNumberById) ?? id2 ?? "*";
102195
- return buildReferenceMarkerRun(String(displayId), params3);
102247
+ const attrs = node3.attrs;
102248
+ const id2 = attrs?.id;
102249
+ if (isCustomMarkFollows(attrs?.customMarkFollows))
102250
+ return buildReferenceMarkerRun("", params3);
102251
+ const cardinal = resolveFootnoteDisplayNumber(id2, converterContext.footnoteNumberById);
102252
+ const key = id2 == null ? null : String(id2);
102253
+ const numFmt = key && converterContext.footnoteFormatById?.[key] || converterContext.footnoteNumberFormat;
102254
+ return buildReferenceMarkerRun(cardinal != null ? formatFootnoteCardinal(cardinal, numFmt) : id2 != null ? String(id2) : "*", params3);
102196
102255
  }
102197
102256
  function endnoteReferenceToBlock(params3) {
102198
102257
  const { node: node3, converterContext } = params3;
102199
102258
  const id2 = node3.attrs?.id;
102200
- const displayId = resolveEndnoteDisplayNumber(id2, converterContext.endnoteNumberById) ?? id2 ?? "*";
102201
- return buildReferenceMarkerRun(String(displayId), params3);
102259
+ const cardinal = resolveEndnoteDisplayNumber(id2, converterContext.endnoteNumberById);
102260
+ const key = id2 == null ? null : String(id2);
102261
+ const numFmt = key && converterContext.endnoteFormatById?.[key] || converterContext.endnoteNumberFormat;
102262
+ return buildReferenceMarkerRun(cardinal != null ? formatFootnoteCardinal(cardinal, numFmt) : id2 != null ? String(id2) : "*", params3);
102202
102263
  }
102203
102264
  function runNodeChildrenToRuns({ node: node3, inheritedMarks, sdtMetadata, converterContext, paragraphProperties, visitNode }) {
102204
102265
  const mergedMarks = [...node3.marks ?? [], ...inheritedMarks ?? []];
@@ -106753,6 +106814,147 @@ function setDefaultTableStyle(settingsRoot, styleId) {
106753
106814
  function removeDefaultTableStyle(settingsRoot) {
106754
106815
  settingsRoot.elements = ensureSettingsRootElements(settingsRoot).filter((entry) => entry.name !== "w:defaultTableStyle");
106755
106816
  }
106817
+ function readFootnoteNumberFormat(settingsRoot) {
106818
+ return readNoteNumberFormat(settingsRoot, "w:footnotePr");
106819
+ }
106820
+ function readEndnoteNumberFormat(settingsRoot) {
106821
+ return readNoteNumberFormat(settingsRoot, "w:endnotePr");
106822
+ }
106823
+ function readNoteNumberFormat(settingsRoot, containerName) {
106824
+ const container = settingsRoot.elements?.find((entry) => entry.name === containerName);
106825
+ if (!container || !Array.isArray(container.elements))
106826
+ return null;
106827
+ const numFmt = container.elements.find((entry) => entry.name === "w:numFmt");
106828
+ if (!numFmt)
106829
+ return null;
106830
+ const val = numFmt.attributes?.["w:val"];
106831
+ return typeof val === "string" && val.length > 0 ? val : null;
106832
+ }
106833
+ function readFootnoteNumberStart(settingsRoot) {
106834
+ return readNoteNumberStart(settingsRoot, "w:footnotePr");
106835
+ }
106836
+ function readEndnoteNumberStart(settingsRoot) {
106837
+ return readNoteNumberStart(settingsRoot, "w:endnotePr");
106838
+ }
106839
+ function readNoteNumberStart(settingsRoot, containerName) {
106840
+ const container = settingsRoot.elements?.find((entry) => entry.name === containerName);
106841
+ if (!container || !Array.isArray(container.elements))
106842
+ return null;
106843
+ const numStart = container.elements.find((entry) => entry.name === "w:numStart");
106844
+ if (!numStart)
106845
+ return null;
106846
+ const val = numStart.attributes?.["w:val"];
106847
+ if (typeof val !== "string" && typeof val !== "number")
106848
+ return null;
106849
+ const n = Number(val);
106850
+ return Number.isFinite(n) && n >= 1 ? Math.floor(n) : null;
106851
+ }
106852
+ function readFootnotePosition(settingsRoot) {
106853
+ return readNotePosition(settingsRoot, "w:footnotePr");
106854
+ }
106855
+ function readEndnotePosition(settingsRoot) {
106856
+ return readNotePosition(settingsRoot, "w:endnotePr");
106857
+ }
106858
+ function readNotePosition(settingsRoot, containerName) {
106859
+ const container = settingsRoot.elements?.find((entry) => entry.name === containerName);
106860
+ if (!container || !Array.isArray(container.elements))
106861
+ return null;
106862
+ const el = container.elements.find((entry) => entry.name === "w:pos");
106863
+ if (!el)
106864
+ return null;
106865
+ const val = el.attributes?.["w:val"];
106866
+ if (val === "pageBottom" || val === "beneathText" || val === "sectEnd" || val === "docEnd")
106867
+ return val;
106868
+ return null;
106869
+ }
106870
+ function readFootnoteNumberRestart(settingsRoot) {
106871
+ return readNoteNumberRestart(settingsRoot, "w:footnotePr");
106872
+ }
106873
+ function readEndnoteNumberRestart(settingsRoot) {
106874
+ return readNoteNumberRestart(settingsRoot, "w:endnotePr");
106875
+ }
106876
+ function readNoteNumberRestart(settingsRoot, containerName) {
106877
+ const container = settingsRoot.elements?.find((entry) => entry.name === containerName);
106878
+ if (!container || !Array.isArray(container.elements))
106879
+ return null;
106880
+ const el = container.elements.find((entry) => entry.name === "w:numRestart");
106881
+ if (!el)
106882
+ return null;
106883
+ const val = el.attributes?.["w:val"];
106884
+ if (val === "continuous" || val === "eachPage" || val === "eachSect")
106885
+ return val;
106886
+ return null;
106887
+ }
106888
+ function readSectionNoteConfigs(documentRoot, containerName) {
106889
+ const result = /* @__PURE__ */ new Map;
106890
+ if (!documentRoot)
106891
+ return result;
106892
+ const bodyEl = findBody(documentRoot);
106893
+ if (!bodyEl)
106894
+ return result;
106895
+ let sectionIndex = 0;
106896
+ for (const child of bodyEl.elements ?? [])
106897
+ if (child.name === "w:sectPr") {
106898
+ const config$42 = extractSectionNoteConfig(child, containerName);
106899
+ if (config$42)
106900
+ result.set(sectionIndex, config$42);
106901
+ sectionIndex += 1;
106902
+ } else if (child.name === "w:p") {
106903
+ const sectPr = findChildByName(findChildByName(child, "w:pPr"), "w:sectPr");
106904
+ if (sectPr) {
106905
+ const config$42 = extractSectionNoteConfig(sectPr, containerName);
106906
+ if (config$42)
106907
+ result.set(sectionIndex, config$42);
106908
+ sectionIndex += 1;
106909
+ }
106910
+ }
106911
+ return result;
106912
+ }
106913
+ function findBody(root2) {
106914
+ if (root2.name === "w:body")
106915
+ return root2;
106916
+ if (!Array.isArray(root2.elements))
106917
+ return null;
106918
+ for (const child of root2.elements) {
106919
+ if (child.name === "w:body")
106920
+ return child;
106921
+ const inner = child.elements?.find((g2) => g2.name === "w:body");
106922
+ if (inner)
106923
+ return inner;
106924
+ }
106925
+ return null;
106926
+ }
106927
+ function findChildByName(parent, name) {
106928
+ if (!parent)
106929
+ return null;
106930
+ return parent.elements?.find((entry) => entry.name === name) ?? null;
106931
+ }
106932
+ function extractSectionNoteConfig(sectPr, containerName) {
106933
+ const container = findChildByName(sectPr, containerName);
106934
+ if (!container)
106935
+ return null;
106936
+ const config$42 = {};
106937
+ const numFmt = findChildByName(container, "w:numFmt");
106938
+ if (numFmt) {
106939
+ const val = numFmt.attributes?.["w:val"];
106940
+ if (typeof val === "string" && val.length > 0)
106941
+ config$42.numFmt = val;
106942
+ }
106943
+ const numStart = findChildByName(container, "w:numStart");
106944
+ if (numStart) {
106945
+ const val = numStart.attributes?.["w:val"];
106946
+ const n = typeof val === "string" || typeof val === "number" ? Number(val) : NaN;
106947
+ if (Number.isFinite(n) && n >= 1)
106948
+ config$42.numStart = Math.floor(n);
106949
+ }
106950
+ const numRestart = findChildByName(container, "w:numRestart");
106951
+ if (numRestart) {
106952
+ const val = numRestart.attributes?.["w:val"];
106953
+ if (val === "continuous" || val === "eachPage" || val === "eachSect")
106954
+ config$42.numRestart = val;
106955
+ }
106956
+ return Object.keys(config$42).length > 0 ? config$42 : null;
106957
+ }
106756
106958
  function hasOddEvenHeadersFooters(settingsRoot) {
106757
106959
  return settingsRoot.elements?.some((entry) => entry.name === "w:evenAndOddHeaders") === true;
106758
106960
  }
@@ -121737,7 +121939,7 @@ var isRegExp = (value) => {
121737
121939
  }, handleAlpha = (path2, lvlText) => generateNumbering(path2, lvlText, intToAlpha), handleLowerAlpha = (path2, lvlText) => {
121738
121940
  const result = handleAlpha(path2, lvlText);
121739
121941
  return result ? result.toLowerCase() : null;
121740
- }, handleOrdinal = (path2, lvlText) => generateNumbering(path2, lvlText, ordinalFormatter), handleCustom = (path2, lvlText, customFormat) => generateFromCustom(path2, lvlText, customFormat), handleJapaneseCounting = (path2, lvlText) => generateNumbering(path2, lvlText, intToJapaneseCounting), handleDecimalZero = (path2, lvlText) => generateNumbering(path2, lvlText, decimalZeroFormatter), listIndexMap, generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
121942
+ }, handleOrdinal = (path2, lvlText) => generateNumbering(path2, lvlText, ordinalFormatter), handleOrdinalText = (path2, lvlText) => generateNumbering(path2, lvlText, ordinalTextFormatter), handleCardinalText = (path2, lvlText) => generateNumbering(path2, lvlText, cardinalTextFormatter), handleCustom = (path2, lvlText, customFormat) => generateFromCustom(path2, lvlText, customFormat), handleJapaneseCounting = (path2, lvlText) => generateNumbering(path2, lvlText, intToJapaneseCounting), handleDecimalZero = (path2, lvlText) => generateNumbering(path2, lvlText, decimalZeroFormatter), listIndexMap, generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
121741
121943
  if (typeof lvlText !== "string")
121742
121944
  return null;
121743
121945
  const handler$1 = listIndexMap[listNumberingType];
@@ -121759,6 +121961,32 @@ var isRegExp = (value) => {
121759
121961
  ];
121760
121962
  const lastTwo = value % 100;
121761
121963
  return `${value}${suffixes[(lastTwo - 20) % 10] || suffixes[lastTwo] || suffixes[0]}`;
121964
+ }, ONES_ORDINAL, TENS_ORDINAL, ONES_CARDINAL, TENS_CARDINAL, ordinalTextFormatter = (value) => {
121965
+ if (!Number.isFinite(value) || value < 1)
121966
+ return "";
121967
+ if (value < ONES_ORDINAL.length)
121968
+ return ONES_ORDINAL[value];
121969
+ if (value < 100) {
121970
+ const t = Math.floor(value / 10);
121971
+ const o = value % 10;
121972
+ if (o === 0)
121973
+ return TENS_ORDINAL[t];
121974
+ return `${TENS_CARDINAL[t]}-${ONES_ORDINAL[o]}`;
121975
+ }
121976
+ return ordinalFormatter(value);
121977
+ }, cardinalTextFormatter = (value) => {
121978
+ if (!Number.isFinite(value) || value < 1)
121979
+ return "";
121980
+ if (value < ONES_CARDINAL.length)
121981
+ return ONES_CARDINAL[value];
121982
+ if (value < 100) {
121983
+ const t = Math.floor(value / 10);
121984
+ const o = value % 10;
121985
+ if (o === 0)
121986
+ return TENS_CARDINAL[t];
121987
+ return `${TENS_CARDINAL[t]}-${ONES_CARDINAL[o]}`;
121988
+ }
121989
+ return String(value);
121762
121990
  }, decimalZeroFormatter = (value, idx) => {
121763
121991
  if (value >= 10 || idx === 0)
121764
121992
  return String(value);
@@ -129059,7 +129287,33 @@ var isRegExp = (value) => {
129059
129287
  inheritedMarks: stripVerticalPositioningFromMarks(params3.inheritedMarks),
129060
129288
  runProperties: stripVerticalPositioningFromRunProperties(params3.runProperties),
129061
129289
  node: buildSyntheticTextNode(displayText, stripVerticalPositioningFromMarks(params3.node.marks))
129062
- }), resolveFootnoteDisplayNumber = (id2, footnoteNumberById) => {
129290
+ }), SUPPORTED_FORMATS, formatFootnoteCardinal = (cardinal, numFmt) => {
129291
+ const fmt = numFmt && SUPPORTED_FORMATS.has(numFmt) ? numFmt : "decimal";
129292
+ const num = Math.max(1, cardinal);
129293
+ switch (fmt) {
129294
+ case "decimal":
129295
+ return String(num);
129296
+ case "upperRoman":
129297
+ return toUpperRoman(num);
129298
+ case "lowerRoman":
129299
+ return toUpperRoman(num).toLowerCase();
129300
+ case "upperLetter":
129301
+ return toUpperLetter(num);
129302
+ case "lowerLetter":
129303
+ return toUpperLetter(num).toLowerCase();
129304
+ case "numberInDash":
129305
+ return `-${num}-`;
129306
+ default:
129307
+ return String(num);
129308
+ }
129309
+ }, isCustomMarkFollows = (value) => {
129310
+ if (value === true || value === 1)
129311
+ return true;
129312
+ if (typeof value !== "string")
129313
+ return false;
129314
+ const v = value.trim().toLowerCase();
129315
+ return v === "1" || v === "true" || v === "on";
129316
+ }, resolveFootnoteDisplayNumber = (id2, footnoteNumberById) => {
129063
129317
  const key = id2 == null ? null : String(id2);
129064
129318
  if (!key)
129065
129319
  return null;
@@ -130249,7 +130503,7 @@ var isRegExp = (value) => {
130249
130503
  state.kern = kernNode.attributes["w:val"];
130250
130504
  }
130251
130505
  }, SuperConverter;
130252
- var init_SuperConverter_nmIRMGtB_es = __esm(() => {
130506
+ var init_SuperConverter_LqX_f8x4_es = __esm(() => {
130253
130507
  init_rolldown_runtime_Bg48TavK_es();
130254
130508
  init_jszip_C49i9kUs_es();
130255
130509
  init_xml_js_CqGKpaft_es();
@@ -160177,9 +160431,79 @@ var init_SuperConverter_nmIRMGtB_es = __esm(() => {
160177
160431
  lowerLetter: handleLowerAlpha,
160178
160432
  upperLetter: handleAlpha,
160179
160433
  ordinal: handleOrdinal,
160434
+ ordinalText: handleOrdinalText,
160435
+ cardinalText: handleCardinalText,
160180
160436
  custom: handleCustom,
160181
160437
  japaneseCounting: handleJapaneseCounting
160182
160438
  };
160439
+ ONES_ORDINAL = [
160440
+ "",
160441
+ "First",
160442
+ "Second",
160443
+ "Third",
160444
+ "Fourth",
160445
+ "Fifth",
160446
+ "Sixth",
160447
+ "Seventh",
160448
+ "Eighth",
160449
+ "Ninth",
160450
+ "Tenth",
160451
+ "Eleventh",
160452
+ "Twelfth",
160453
+ "Thirteenth",
160454
+ "Fourteenth",
160455
+ "Fifteenth",
160456
+ "Sixteenth",
160457
+ "Seventeenth",
160458
+ "Eighteenth",
160459
+ "Nineteenth"
160460
+ ];
160461
+ TENS_ORDINAL = [
160462
+ "",
160463
+ "",
160464
+ "Twentieth",
160465
+ "Thirtieth",
160466
+ "Fortieth",
160467
+ "Fiftieth",
160468
+ "Sixtieth",
160469
+ "Seventieth",
160470
+ "Eightieth",
160471
+ "Ninetieth"
160472
+ ];
160473
+ ONES_CARDINAL = [
160474
+ "",
160475
+ "One",
160476
+ "Two",
160477
+ "Three",
160478
+ "Four",
160479
+ "Five",
160480
+ "Six",
160481
+ "Seven",
160482
+ "Eight",
160483
+ "Nine",
160484
+ "Ten",
160485
+ "Eleven",
160486
+ "Twelve",
160487
+ "Thirteen",
160488
+ "Fourteen",
160489
+ "Fifteen",
160490
+ "Sixteen",
160491
+ "Seventeen",
160492
+ "Eighteen",
160493
+ "Nineteen"
160494
+ ];
160495
+ TENS_CARDINAL = [
160496
+ "",
160497
+ "",
160498
+ "Twenty",
160499
+ "Thirty",
160500
+ "Forty",
160501
+ "Fifty",
160502
+ "Sixty",
160503
+ "Seventy",
160504
+ "Eighty",
160505
+ "Ninety"
160506
+ ];
160183
160507
  normalizeChars = new Set([
160184
160508
  "",
160185
160509
  "",
@@ -167436,6 +167760,14 @@ var init_SuperConverter_nmIRMGtB_es = __esm(() => {
167436
167760
  this.name = "NotInlineNodeError";
167437
167761
  }
167438
167762
  };
167763
+ SUPPORTED_FORMATS = new Set([
167764
+ "decimal",
167765
+ "upperRoman",
167766
+ "lowerRoman",
167767
+ "upperLetter",
167768
+ "lowerLetter",
167769
+ "numberInDash"
167770
+ ]);
167439
167771
  sdtMetadataCache = /* @__PURE__ */ new Map;
167440
167772
  NON_RENDERED_STRUCTURAL_INLINE_TYPES = new Set([
167441
167773
  "bookmarkEnd",
@@ -168938,7 +169270,7 @@ var init_SuperConverter_nmIRMGtB_es = __esm(() => {
168938
169270
  };
168939
169271
  });
168940
169272
 
168941
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-7bitVHMJ.es.js
169273
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-BOETXxAI.es.js
168942
169274
  function parseSizeUnit(val = "0") {
168943
169275
  const length3 = val.toString() || "0";
168944
169276
  const value = Number.parseFloat(length3);
@@ -179269,8 +179601,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, normalizeActorId = (value) => {
179269
179601
  }
179270
179602
  };
179271
179603
  };
179272
- var init_create_headless_toolbar_7bitVHMJ_es = __esm(() => {
179273
- init_SuperConverter_nmIRMGtB_es();
179604
+ var init_create_headless_toolbar_BOETXxAI_es = __esm(() => {
179605
+ init_SuperConverter_LqX_f8x4_es();
179274
179606
  init_uuid_qzgm05fK_es();
179275
179607
  init_constants_D_X7xF4s_es();
179276
179608
  init_dist_B8HfvhaK_es();
@@ -228433,7 +228765,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
228433
228765
  init_remark_gfm_BhnWr3yf_es();
228434
228766
  });
228435
228767
 
228436
- // ../../packages/superdoc/dist/chunks/src-BrZa8lMN.es.js
228768
+ // ../../packages/superdoc/dist/chunks/src-iuHADPff.es.js
228437
228769
  function deleteProps(obj, propOrProps) {
228438
228770
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
228439
228771
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -268133,7 +268465,9 @@ function resolveParagraphContent(fragment2, block, measure) {
268133
268465
  bold: m$1.run?.bold,
268134
268466
  italic: m$1.run?.italic,
268135
268467
  color: m$1.run?.color,
268136
- letterSpacing: m$1.run?.letterSpacing
268468
+ letterSpacing: m$1.run?.letterSpacing,
268469
+ allCaps: m$1.run?.allCaps,
268470
+ smallCaps: m$1.run?.smallCaps
268137
268471
  },
268138
268472
  sourceAnchor: block.sourceAnchor
268139
268473
  };
@@ -269098,25 +269432,6 @@ function normalizeLines(measure) {
269098
269432
  lineHeight: measure.totalHeight || 0
269099
269433
  }];
269100
269434
  }
269101
- function sliceLines(lines, startIndex, availableHeight) {
269102
- let height = 0;
269103
- let index2 = startIndex;
269104
- while (index2 < lines.length) {
269105
- const lineHeight = lines[index2].lineHeight || 0;
269106
- if (height > 0 && height + lineHeight > availableHeight)
269107
- break;
269108
- height += lineHeight;
269109
- index2 += 1;
269110
- }
269111
- if (index2 === startIndex) {
269112
- height = lines[startIndex].lineHeight || 0;
269113
- index2 += 1;
269114
- }
269115
- return {
269116
- toLine: index2,
269117
- height
269118
- };
269119
- }
269120
269435
  function shouldSuppressOwnSpacing(ownStyleId, ownContextualSpacing, adjacentStyleId) {
269121
269436
  return ownContextualSpacing && !!ownStyleId && !!adjacentStyleId && ownStyleId === adjacentStyleId;
269122
269437
  }
@@ -269412,14 +269727,56 @@ function layoutParagraphBlock(ctx$1, anchors) {
269412
269727
  }
269413
269728
  else
269414
269729
  state.trailingSpacing = 0;
269415
- if (state.cursorY >= state.contentBottom)
269730
+ const FN_SAFETY_MARGIN_PX = 1;
269731
+ const fallbackBandOverhead = (refsTotal) => refsTotal > 0 ? 22 + Math.max(0, refsTotal - 1) * 2 : 0;
269732
+ const bandOverhead = (refsTotal) => {
269733
+ if (refsTotal <= 0)
269734
+ return 0;
269735
+ const fromCtx = ctx$1.getFootnoteBandOverhead?.(refsTotal);
269736
+ return (typeof fromCtx === "number" && Number.isFinite(fromCtx) && fromCtx >= 0 ? fromCtx : fallbackBandOverhead(refsTotal)) + FN_SAFETY_MARGIN_PX;
269737
+ };
269738
+ const rawContentBottom = state.contentBottom + state.pageFootnoteReserve;
269739
+ const computeEffectiveBottom = (extraDemand, extraRefs) => {
269740
+ const totalDemand = extraDemand;
269741
+ const totalRefs = state.footnoteRefsThisPage + extraRefs;
269742
+ const demandWithOverhead = totalDemand > 0 ? totalDemand + bandOverhead(totalRefs) : 0;
269743
+ const reservedSpace = Math.max(state.pageFootnoteReserve, demandWithOverhead);
269744
+ const minBodyLineHeight = lines[fromLine]?.lineHeight ?? 0;
269745
+ const maxAdditional = Math.max(0, rawContentBottom - state.topMargin - minBodyLineHeight);
269746
+ return rawContentBottom - Math.min(reservedSpace, maxAdditional);
269747
+ };
269748
+ const computeFootnoteClusterDemand = (pmStart, pmEnd) => {
269749
+ const candidate = ctx$1.getFootnoteAnchorsForBlockId ? ctx$1.getFootnoteAnchorsForBlockId(block.id, pmStart, pmEnd) : [];
269750
+ const committed = state.footnoteAnchorsThisPage ?? [];
269751
+ if (candidate.length === 0 && committed.length === 0)
269752
+ return 0;
269753
+ let demand = 0;
269754
+ for (const anchor of committed)
269755
+ demand += anchor.fullHeight;
269756
+ for (const anchor of candidate)
269757
+ demand += anchor.fullHeight;
269758
+ return demand;
269759
+ };
269760
+ const previewRange = computeFragmentPmRange2(block, lines, fromLine, fromLine + 1);
269761
+ const previewRefs = ctx$1.getFootnoteRefCountForBlockId ? ctx$1.getFootnoteRefCountForBlockId(block.id, previewRange.pmStart, previewRange.pmEnd) : 0;
269762
+ const computePreviewBottom = () => {
269763
+ return computeEffectiveBottom(computeFootnoteClusterDemand(previewRange.pmStart ?? 0, previewRange.pmEnd ?? 0), previewRefs);
269764
+ };
269765
+ let effectiveBottom = computePreviewBottom();
269766
+ if (state.cursorY >= effectiveBottom) {
269416
269767
  state = advanceColumn(state);
269417
- if (state.contentBottom - state.cursorY <= 0)
269768
+ effectiveBottom = computePreviewBottom();
269769
+ }
269770
+ if (effectiveBottom - state.cursorY <= 0) {
269418
269771
  state = advanceColumn(state);
269772
+ effectiveBottom = computePreviewBottom();
269773
+ }
269419
269774
  const nextLineHeight = lines[fromLine].lineHeight || 0;
269420
- const remainingHeight = state.contentBottom - state.cursorY;
269421
- if (state.page.fragments.length > 0 && remainingHeight < nextLineHeight)
269775
+ const remainingHeight = effectiveBottom - state.cursorY;
269776
+ if (state.page.fragments.length > 0 && remainingHeight < nextLineHeight) {
269422
269777
  state = advanceColumn(state);
269778
+ effectiveBottom = computePreviewBottom();
269779
+ }
269423
269780
  let effectiveColumnWidth = columnWidth;
269424
269781
  let offsetX = 0;
269425
269782
  if (didRemeasureForFloats) {
@@ -269427,9 +269784,50 @@ function layoutParagraphBlock(ctx$1, anchors) {
269427
269784
  offsetX = narrowestOffsetX;
269428
269785
  }
269429
269786
  const borderVertical = borderExpansion.top + borderExpansion.bottom;
269430
- const availableForSlice = Math.max(0, state.contentBottom - state.cursorY - borderVertical);
269431
- const slice2 = sliceLines(lines, fromLine, availableForSlice);
269787
+ let toLine = fromLine;
269788
+ let height = 0;
269789
+ let sliceDemand = 0;
269790
+ let sliceRefs = 0;
269791
+ while (toLine < lines.length) {
269792
+ const lineHeight = lines[toLine].lineHeight || 0;
269793
+ const range = computeFragmentPmRange2(block, lines, fromLine, toLine + 1);
269794
+ const orderedDemand = computeFootnoteClusterDemand(range.pmStart ?? 0, range.pmEnd ?? 0);
269795
+ const nextRefs = ctx$1.getFootnoteRefCountForBlockId ? ctx$1.getFootnoteRefCountForBlockId(block.id, range.pmStart, range.pmEnd) : 0;
269796
+ if (toLine === fromLine) {
269797
+ height = lineHeight;
269798
+ sliceDemand = orderedDemand;
269799
+ sliceRefs = nextRefs;
269800
+ toLine = fromLine + 1;
269801
+ continue;
269802
+ }
269803
+ if (state.cursorY + height + lineHeight + borderVertical > computeEffectiveBottom(orderedDemand, nextRefs))
269804
+ break;
269805
+ height += lineHeight;
269806
+ sliceDemand = orderedDemand;
269807
+ sliceRefs = nextRefs;
269808
+ toLine += 1;
269809
+ }
269810
+ const slice2 = {
269811
+ toLine,
269812
+ height
269813
+ };
269432
269814
  const fragmentHeight = slice2.height;
269815
+ if (sliceDemand > 0 || sliceRefs > 0) {
269816
+ state.footnoteDemandThisPage = sliceDemand;
269817
+ state.footnoteRefsThisPage = (state.footnoteRefsThisPage ?? 0) + sliceRefs;
269818
+ }
269819
+ if (ctx$1.getFootnoteAnchorsForBlockId) {
269820
+ const committedRange = computeFragmentPmRange2(block, lines, fromLine, toLine);
269821
+ const newAnchors = ctx$1.getFootnoteAnchorsForBlockId(block.id, committedRange.pmStart, committedRange.pmEnd);
269822
+ if (newAnchors.length > 0) {
269823
+ if (!state.footnoteAnchorsThisPage)
269824
+ state.footnoteAnchorsThisPage = [];
269825
+ const seen = new Set(state.footnoteAnchorsThisPage.map((a2) => a2.refId));
269826
+ for (const a2 of newAnchors)
269827
+ if (!seen.has(a2.refId))
269828
+ state.footnoteAnchorsThisPage.push(a2);
269829
+ }
269830
+ }
269433
269831
  const adjustedX = columnX(state.columnIndex) + offsetX + negativeLeftIndent;
269434
269832
  const adjustedWidth = effectiveColumnWidth - negativeLeftIndent - negativeRightIndent;
269435
269833
  const fragment2 = {
@@ -270856,8 +271254,10 @@ function createPaginator(opts) {
270856
271254
  footer: footerDistance
270857
271255
  };
270858
271256
  const pageSizeOverride = currentPageSize.w !== defaultPageSize.w || currentPageSize.h !== defaultPageSize.h ? currentPageSize : undefined;
271257
+ const pageIndex = pages.length;
271258
+ const pageFootnoteReserve = opts.getFootnoteReserveForPage?.(pageIndex) ?? 0;
270859
271259
  const state = {
270860
- page: opts.createPage(pages.length + 1, pageMargins, pageSizeOverride),
271260
+ page: opts.createPage(pageIndex + 1, pageMargins, pageSizeOverride),
270861
271261
  cursorY: topMargin,
270862
271262
  columnIndex: 0,
270863
271263
  topMargin,
@@ -270867,7 +271267,11 @@ function createPaginator(opts) {
270867
271267
  trailingSpacing: 0,
270868
271268
  lastParagraphStyleId: undefined,
270869
271269
  lastParagraphContextualSpacing: false,
270870
- maxCursorY: topMargin
271270
+ maxCursorY: topMargin,
271271
+ pageFootnoteReserve,
271272
+ footnoteDemandThisPage: 0,
271273
+ footnoteRefsThisPage: 0,
271274
+ footnoteAnchorsThisPage: []
270871
271275
  };
270872
271276
  states.push(state);
270873
271277
  pages.push(state.page);
@@ -270893,6 +271297,8 @@ function createPaginator(opts) {
270893
271297
  state.trailingSpacing = 0;
270894
271298
  state.lastParagraphStyleId = undefined;
270895
271299
  state.lastParagraphContextualSpacing = false;
271300
+ state.footnoteAnchorsThisPage = [];
271301
+ state.footnoteRefsThisPage = 0;
270896
271302
  return state;
270897
271303
  }
270898
271304
  return startNewPage();
@@ -270912,7 +271318,7 @@ function createPaginator(opts) {
270912
271318
  pruneTrailingEmptyPages
270913
271319
  };
270914
271320
  }
270915
- function toUpperRoman(num) {
271321
+ function toUpperRoman2(num) {
270916
271322
  if (num < 1 || num > 3999)
270917
271323
  return String(num);
270918
271324
  const values = [
@@ -270955,9 +271361,9 @@ function toUpperRoman(num) {
270955
271361
  return result;
270956
271362
  }
270957
271363
  function toLowerRoman(num) {
270958
- return toUpperRoman(num).toLowerCase();
271364
+ return toUpperRoman2(num).toLowerCase();
270959
271365
  }
270960
- function toUpperLetter(num) {
271366
+ function toUpperLetter2(num) {
270961
271367
  if (num < 1)
270962
271368
  return "A";
270963
271369
  let result = "";
@@ -270970,7 +271376,7 @@ function toUpperLetter(num) {
270970
271376
  return result;
270971
271377
  }
270972
271378
  function toLowerLetter(num) {
270973
- return toUpperLetter(num).toLowerCase();
271379
+ return toUpperLetter2(num).toLowerCase();
270974
271380
  }
270975
271381
  function formatPageNumber(pageNumber, format) {
270976
271382
  const num = Math.max(1, pageNumber);
@@ -270978,11 +271384,11 @@ function formatPageNumber(pageNumber, format) {
270978
271384
  case "decimal":
270979
271385
  return String(num);
270980
271386
  case "upperRoman":
270981
- return toUpperRoman(num);
271387
+ return toUpperRoman2(num);
270982
271388
  case "lowerRoman":
270983
271389
  return toLowerRoman(num);
270984
271390
  case "upperLetter":
270985
- return toUpperLetter(num);
271391
+ return toUpperLetter2(num);
270986
271392
  case "lowerLetter":
270987
271393
  return toLowerLetter(num);
270988
271394
  case "numberInDash":
@@ -272024,6 +272430,135 @@ function layoutDocument(blocks2, measures, options = {}) {
272024
272430
  }
272025
272431
  return page;
272026
272432
  };
272433
+ const footnoteAnchorsByBlockId = (() => {
272434
+ const out = /* @__PURE__ */ new Map;
272435
+ const refs = options.footnotes?.refs;
272436
+ const bodyHeights = options.footnotes?.bodyHeightById;
272437
+ const firstLineHeights = options.footnotes?.firstLineHeightById;
272438
+ if (!Array.isArray(refs) || refs.length === 0 || !bodyHeights)
272439
+ return out;
272440
+ const resolveBlockPmRange = (block) => {
272441
+ const attrsRange = block.attrs;
272442
+ let pmStart = typeof attrsRange?.pmStart === "number" ? attrsRange.pmStart : undefined;
272443
+ let pmEnd = typeof attrsRange?.pmEnd === "number" ? attrsRange.pmEnd : undefined;
272444
+ if (pmStart == null && block.kind === "paragraph") {
272445
+ const runs2 = block.runs;
272446
+ if (Array.isArray(runs2))
272447
+ for (const run2 of runs2) {
272448
+ const rs = run2.pmStart;
272449
+ const re2 = run2.pmEnd;
272450
+ if (typeof rs === "number")
272451
+ pmStart = pmStart == null ? rs : Math.min(pmStart, rs);
272452
+ if (typeof re2 === "number")
272453
+ pmEnd = pmEnd == null ? re2 : Math.max(pmEnd, re2);
272454
+ }
272455
+ }
272456
+ if (pmStart == null)
272457
+ return null;
272458
+ return {
272459
+ pmStart,
272460
+ pmEnd: pmEnd ?? pmStart + 1
272461
+ };
272462
+ };
272463
+ const refByPos = /* @__PURE__ */ new Map;
272464
+ const seenIds = /* @__PURE__ */ new Set;
272465
+ for (const ref$1 of refs) {
272466
+ if (seenIds.has(ref$1.id))
272467
+ continue;
272468
+ seenIds.add(ref$1.id);
272469
+ refByPos.set(ref$1.pos, ref$1.id);
272470
+ }
272471
+ const recordIfHit = (range, topLevelId) => {
272472
+ for (const [pos, refId] of refByPos.entries()) {
272473
+ if (pos < range.pmStart || pos > range.pmEnd)
272474
+ continue;
272475
+ const fullHeight = bodyHeights.get(refId);
272476
+ if (typeof fullHeight !== "number" || !Number.isFinite(fullHeight) || fullHeight <= 0)
272477
+ continue;
272478
+ const firstLineRaw = firstLineHeights?.get(refId);
272479
+ const firstLineHeight = typeof firstLineRaw === "number" && Number.isFinite(firstLineRaw) && firstLineRaw > 0 ? Math.min(firstLineRaw, fullHeight) : fullHeight;
272480
+ const list5 = out.get(topLevelId) ?? [];
272481
+ list5.push({
272482
+ pmPos: pos,
272483
+ refId,
272484
+ fullHeight,
272485
+ firstLineHeight
272486
+ });
272487
+ out.set(topLevelId, list5);
272488
+ refByPos.delete(pos);
272489
+ }
272490
+ };
272491
+ for (const block of blocks2) {
272492
+ if (refByPos.size === 0)
272493
+ break;
272494
+ const range = resolveBlockPmRange(block);
272495
+ if (range)
272496
+ recordIfHit(range, block.id);
272497
+ if (block.kind === "table")
272498
+ for (const row2 of block.rows ?? [])
272499
+ for (const cell2 of row2.cells ?? []) {
272500
+ const cellChildren = cell2.blocks ? cell2.blocks : cell2.paragraph ? [cell2.paragraph] : [];
272501
+ for (const child of cellChildren) {
272502
+ const childRange = resolveBlockPmRange(child);
272503
+ if (childRange)
272504
+ recordIfHit(childRange, block.id);
272505
+ }
272506
+ }
272507
+ }
272508
+ for (const list5 of out.values())
272509
+ list5.sort((a2, b$1) => a2.pmPos - b$1.pmPos);
272510
+ return out;
272511
+ })();
272512
+ const getFootnoteAnchorsForBlockId = (blockId, pmStart, pmEnd) => {
272513
+ const entries2 = footnoteAnchorsByBlockId.get(blockId);
272514
+ if (!entries2 || entries2.length === 0)
272515
+ return [];
272516
+ if (pmStart == null || pmEnd == null)
272517
+ return entries2;
272518
+ const out = [];
272519
+ for (const e of entries2)
272520
+ if (e.pmPos >= pmStart && e.pmPos <= pmEnd)
272521
+ out.push(e);
272522
+ return out;
272523
+ };
272524
+ const getFootnoteDemandForBlockId = (blockId, pmStart, pmEnd, committed) => {
272525
+ const candidate = getFootnoteAnchorsForBlockId(blockId, pmStart, pmEnd);
272526
+ if (candidate.length === 0 && (!committed || committed.length === 0))
272527
+ return 0;
272528
+ const cluster = committed && committed.length > 0 ? [...committed, ...candidate] : candidate;
272529
+ if (cluster.length === 0)
272530
+ return 0;
272531
+ let total = 0;
272532
+ for (let i4 = 0;i4 < cluster.length - 1; i4 += 1)
272533
+ total += cluster[i4].fullHeight;
272534
+ total += cluster[cluster.length - 1].firstLineHeight;
272535
+ return total;
272536
+ };
272537
+ const getFootnoteRefCountForBlockId = (blockId, pmStart, pmEnd) => {
272538
+ const entries2 = footnoteAnchorsByBlockId.get(blockId);
272539
+ if (!entries2 || entries2.length === 0)
272540
+ return 0;
272541
+ if (pmStart == null || pmEnd == null)
272542
+ return entries2.length;
272543
+ let count2 = 0;
272544
+ for (const e of entries2)
272545
+ if (e.pmPos >= pmStart && e.pmPos <= pmEnd)
272546
+ count2 += 1;
272547
+ return count2;
272548
+ };
272549
+ const getFootnoteBandOverhead = (() => {
272550
+ const fn2 = options.footnotes;
272551
+ const safeNum = (v, fallback) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : fallback;
272552
+ const topPadding = safeNum(fn2?.topPadding, 6);
272553
+ const dividerHeight = safeNum(fn2?.dividerHeight, 6);
272554
+ const separatorSpacingBefore = safeNum(fn2?.separatorSpacingBefore, 12);
272555
+ const gap = safeNum(fn2?.gap, 2);
272556
+ return (refsTotal) => {
272557
+ if (refsTotal <= 0)
272558
+ return 0;
272559
+ return topPadding + dividerHeight + separatorSpacingBefore + Math.max(0, refsTotal - 1) * gap;
272560
+ };
272561
+ })();
272027
272562
  let pageCount = 0;
272028
272563
  let activeNumberFormat = "decimal";
272029
272564
  let activePageCounter = 1;
@@ -272062,15 +272597,19 @@ function layoutDocument(blocks2, measures, options = {}) {
272062
272597
  let activeSectionIndex = initialSectionMetadata?.sectionIndex ?? 0;
272063
272598
  let pendingSectionIndex = null;
272064
272599
  const sectionFirstPageNumbers = /* @__PURE__ */ new Map;
272600
+ const readFootnoteReserveForPageIndex = (pageIndex) => {
272601
+ const reserves = options.footnoteReservedByPageIndex;
272602
+ const reserve = Array.isArray(reserves) ? reserves[pageIndex] : 0;
272603
+ return typeof reserve === "number" && Number.isFinite(reserve) && reserve > 0 ? reserve : 0;
272604
+ };
272065
272605
  const paginator = createPaginator({
272066
272606
  margins: paginatorMargins,
272067
272607
  getActiveTopMargin: () => activeTopMargin,
272068
272608
  getActiveBottomMargin: () => {
272069
- const reserves = options.footnoteReservedByPageIndex;
272070
272609
  const pageIndex = Math.max(0, pageCount - 1);
272071
- const reserve = Array.isArray(reserves) ? reserves[pageIndex] : 0;
272072
- return activeBottomMargin + (typeof reserve === "number" && Number.isFinite(reserve) && reserve > 0 ? reserve : 0);
272610
+ return activeBottomMargin + readFootnoteReserveForPageIndex(pageIndex);
272073
272611
  },
272612
+ getFootnoteReserveForPage: (pageIndex) => readFootnoteReserveForPageIndex(pageIndex),
272074
272613
  getActiveHeaderDistance: () => activeHeaderDistance,
272075
272614
  getActiveFooterDistance: () => activeFooterDistance,
272076
272615
  getActivePageSize: () => activePageSize,
@@ -272703,7 +273242,11 @@ function layoutDocument(blocks2, measures, options = {}) {
272703
273242
  columnX,
272704
273243
  floatManager,
272705
273244
  remeasureParagraph: options.remeasureParagraph,
272706
- overrideSpacingAfter
273245
+ overrideSpacingAfter,
273246
+ getFootnoteDemandForBlockId,
273247
+ getFootnoteRefCountForBlockId,
273248
+ getFootnoteBandOverhead,
273249
+ getFootnoteAnchorsForBlockId
272707
273250
  }, anchorsForPara ? {
272708
273251
  anchoredDrawings: anchorsForPara,
272709
273252
  pageWidth: activePageSize.w,
@@ -273040,6 +273583,14 @@ function layoutDocument(blocks2, measures, options = {}) {
273040
273583
  }
273041
273584
  state.page.columnRegions = regions;
273042
273585
  }
273586
+ for (let i4 = 0;i4 < pages.length && i4 < paginator.states.length; i4++) {
273587
+ const s2 = paginator.states[i4];
273588
+ const maxY = s2.maxCursorY ?? 0;
273589
+ const cursorY = s2.cursorY ?? 0;
273590
+ const trailing = s2.trailingSpacing ?? 0;
273591
+ const adjusted = Math.max(maxY, cursorY) - (cursorY >= maxY ? trailing : 0);
273592
+ pages[i4].bodyMaxY = Math.max(s2.topMargin ?? 0, adjusted);
273593
+ }
273043
273594
  return {
273044
273595
  pageSize,
273045
273596
  pages,
@@ -274523,9 +275074,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274523
275074
  headerFooter = undefined;
274524
275075
  nextBlocks = rewriteSectionBreaksForSemanticFlow(nextBlocks, options);
274525
275076
  }
274526
- const dirtyStart = performance.now();
274527
275077
  const dirty = computeDirtyRegions(previousBlocks, nextBlocks);
274528
- performance.now() - dirtyStart;
274529
275078
  if (dirty.deletedBlockIds.length > 0)
274530
275079
  measureCache.invalidate(dirty.deletedBlockIds);
274531
275080
  const perSectionConstraints = computePerSectionConstraints(options, nextBlocks);
@@ -274716,7 +275265,6 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274716
275265
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
274717
275266
  });
274718
275267
  perfLog$1(`[Perf] 4.2 Layout document (pagination): ${(performance.now() - layoutStart).toFixed(2)}ms`);
274719
- layout.pages.length;
274720
275268
  const maxIterations = 3;
274721
275269
  let currentBlocks = nextBlocks;
274722
275270
  let currentMeasures = measures;
@@ -274800,7 +275348,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274800
275348
  const safeTopPadding = Math.max(0, topPadding);
274801
275349
  const safeDividerHeight = Math.max(0, dividerHeight);
274802
275350
  const continuationDividerHeight = safeDividerHeight;
274803
- const continuationDividerWidthFactor = 0.3;
275351
+ const SEPARATOR_DEFAULT_WIDTH_FACTOR = 0.5;
274804
275352
  const footnoteWidth = resolveFootnoteMeasurementWidth(options, currentBlocks);
274805
275353
  if (footnoteWidth > 0) {
274806
275354
  const footnoteConstraints = {
@@ -274848,6 +275396,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274848
275396
  const hasContinuationByColumn = /* @__PURE__ */ new Map;
274849
275397
  const rangesByFootnoteId = /* @__PURE__ */ new Map;
274850
275398
  const cappedPages = /* @__PURE__ */ new Set;
275399
+ const ledgersByPage = /* @__PURE__ */ new Map;
274851
275400
  collectFootnoteIdsByColumn(idsByColumn$1).forEach((id2) => {
274852
275401
  const blocks2 = footnotesInput.blocksById.get(id2) ?? [];
274853
275402
  rangesByFootnoteId.set(id2, buildFootnoteRanges(blocks2, measuresById$1));
@@ -274860,25 +275409,23 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274860
275409
  const maxReserve = computeMaxFootnoteReserve(layoutForPages, pageIndex, baseReserve);
274861
275410
  const columns = pageColumns$1.get(pageIndex);
274862
275411
  const columnCount = Math.max(1, Math.floor(columns?.count ?? 1));
274863
- let demand = 0;
274864
- for (let columnIndex = 0;columnIndex < columnCount; columnIndex += 1) {
274865
- const ids = idsByColumn$1.get(pageIndex)?.get(columnIndex) ?? [];
274866
- let columnDemand = 0;
274867
- ids.forEach((id2, idx) => {
274868
- const ranges = rangesByFootnoteId.get(id2) ?? [];
274869
- let rangesHeight = 0;
274870
- ranges.forEach((range) => {
274871
- const spacingAfter = "spacingAfter" in range ? range.spacingAfter ?? 0 : 0;
274872
- rangesHeight += range.height + spacingAfter;
274873
- });
274874
- columnDemand += rangesHeight + (idx > 0 ? safeGap : 0);
275412
+ const placementCeiling = maxReserve;
275413
+ const fullHeightOf = (id2) => {
275414
+ const ranges = rangesByFootnoteId.get(id2) ?? [];
275415
+ let total = 0;
275416
+ ranges.forEach((range) => {
275417
+ const spacingAfter = "spacingAfter" in range ? range.spacingAfter ?? 0 : 0;
275418
+ total += range.height + spacingAfter;
274875
275419
  });
274876
- if (columnDemand > 0)
274877
- columnDemand += safeSeparatorSpacingBefore + safeDividerHeight + safeTopPadding;
274878
- if (columnDemand > demand)
274879
- demand = columnDemand;
274880
- }
274881
- const placementCeiling = demand > 0 ? Math.min(Math.ceil(demand), maxReserve) : maxReserve;
275420
+ return total;
275421
+ };
275422
+ const firstLineOf = (id2) => {
275423
+ const measured = firstLineHeightById.get(id2);
275424
+ if (typeof measured === "number" && Number.isFinite(measured) && measured > 0)
275425
+ return measured;
275426
+ const ranges = rangesByFootnoteId.get(id2) ?? [];
275427
+ return ranges.length > 0 ? ranges[0].height : 0;
275428
+ };
274882
275429
  const pendingForPage = /* @__PURE__ */ new Map;
274883
275430
  pendingByColumn.forEach((entries2, columnIndex) => {
274884
275431
  const targetIndex = columnIndex < columnCount ? columnIndex : Math.max(0, columnCount - 1);
@@ -274886,6 +275433,21 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274886
275433
  list5.push(...entries2);
274887
275434
  pendingForPage.set(targetIndex, list5);
274888
275435
  });
275436
+ const continuationInForPage = [];
275437
+ pendingForPage.forEach((entries2) => {
275438
+ entries2.forEach((entry) => {
275439
+ let total = 0;
275440
+ entry.ranges.forEach((range) => {
275441
+ const spacingAfter = "spacingAfter" in range ? range.spacingAfter ?? 0 : 0;
275442
+ total += range.height + spacingAfter;
275443
+ });
275444
+ continuationInForPage.push({
275445
+ id: entry.id,
275446
+ remainingRangeCount: entry.ranges.length,
275447
+ remainingHeightPx: total
275448
+ });
275449
+ });
275450
+ });
274889
275451
  pendingByColumn = /* @__PURE__ */ new Map;
274890
275452
  const pageSlices = [];
274891
275453
  let pageReserve = 0;
@@ -274893,9 +275455,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274893
275455
  let usedHeight = 0;
274894
275456
  const columnSlices = [];
274895
275457
  const nextPending = [];
274896
- let stopPlacement = false;
274897
275458
  const columnKey = footnoteColumnKey(pageIndex, columnIndex);
274898
- const placeFootnote = (id2, ranges, isContinuation) => {
275459
+ const placeFootnote = (id2, ranges, isContinuation, isLastOnPage) => {
274899
275460
  if (!ranges || ranges.length === 0)
274900
275461
  return {
274901
275462
  placed: false,
@@ -274904,12 +275465,17 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274904
275465
  const isFirstSlice = columnSlices.length === 0;
274905
275466
  const overhead = isFirstSlice ? (isFirstSlice ? safeSeparatorSpacingBefore : 0) + (isFirstSlice ? isContinuation ? continuationDividerHeight : safeDividerHeight : 0) + safeTopPadding : 0;
274906
275467
  const gapBefore = !isFirstSlice ? safeGap : 0;
274907
- const { slice: slice2, remainingRanges } = fitFootnoteContent(id2, ranges, Math.max(0, placementCeiling - usedHeight - overhead - gapBefore), pageIndex, columnIndex, isContinuation, measuresById$1, isFirstSlice && placementCeiling > 0);
275468
+ const { slice: slice2, remainingRanges } = fitFootnoteContent(id2, ranges, Math.max(0, placementCeiling - usedHeight - overhead - gapBefore), pageIndex, columnIndex, isContinuation, measuresById$1, (isLastOnPage || isContinuation) && placementCeiling > 0);
274908
275469
  if (slice2.ranges.length === 0)
274909
275470
  return {
274910
275471
  placed: false,
274911
275472
  remaining: ranges
274912
275473
  };
275474
+ if (!isLastOnPage && !isContinuation && remainingRanges.length > 0)
275475
+ return {
275476
+ placed: false,
275477
+ remaining: ranges
275478
+ };
274913
275479
  if (isFirstSlice) {
274914
275480
  usedHeight += overhead;
274915
275481
  if (isContinuation)
@@ -274924,19 +275490,25 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274924
275490
  remaining: remainingRanges
274925
275491
  };
274926
275492
  };
275493
+ const ids = idsByColumn$1.get(pageIndex)?.get(columnIndex) ?? [];
275494
+ const lastIdx = ids.length - 1;
275495
+ let clusterReserve = 0;
275496
+ for (let i4 = 0;i4 < ids.length; i4 += 1) {
275497
+ clusterReserve += i4 === lastIdx ? firstLineOf(ids[i4]) : fullHeightOf(ids[i4]);
275498
+ if (i4 > 0)
275499
+ clusterReserve += safeGap;
275500
+ }
275501
+ usedHeight += clusterReserve;
274927
275502
  const pending = pendingForPage.get(columnIndex) ?? [];
274928
- for (const entry of pending) {
274929
- if (stopPlacement) {
274930
- nextPending.push(entry);
274931
- continue;
274932
- }
275503
+ for (let pendingIdx = 0;pendingIdx < pending.length; pendingIdx += 1) {
275504
+ const entry = pending[pendingIdx];
274933
275505
  if (!entry.ranges || entry.ranges.length === 0)
274934
275506
  continue;
274935
- const result = placeFootnote(entry.id, entry.ranges, true);
275507
+ const result = placeFootnote(entry.id, entry.ranges, true, false);
274936
275508
  if (!result.placed) {
274937
- nextPending.push(entry);
274938
- stopPlacement = true;
274939
- continue;
275509
+ for (let deferIdx = pendingIdx;deferIdx < pending.length; deferIdx += 1)
275510
+ nextPending.push(pending[deferIdx]);
275511
+ break;
274940
275512
  }
274941
275513
  if (result.remaining.length > 0)
274942
275514
  nextPending.push({
@@ -274944,36 +275516,33 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274944
275516
  ranges: result.remaining
274945
275517
  });
274946
275518
  }
274947
- if (!stopPlacement) {
274948
- const ids = idsByColumn$1.get(pageIndex)?.get(columnIndex) ?? [];
274949
- for (let idIndex = 0;idIndex < ids.length; idIndex += 1) {
274950
- const id2 = ids[idIndex];
274951
- const ranges = rangesByFootnoteId.get(id2) ?? [];
274952
- if (ranges.length === 0)
274953
- continue;
274954
- const result = placeFootnote(id2, ranges, false);
274955
- if (!result.placed) {
275519
+ usedHeight -= clusterReserve;
275520
+ for (let idIndex = 0;idIndex < ids.length; idIndex += 1) {
275521
+ const id2 = ids[idIndex];
275522
+ const ranges = rangesByFootnoteId.get(id2) ?? [];
275523
+ if (ranges.length === 0)
275524
+ continue;
275525
+ const result = placeFootnote(id2, ranges, false, idIndex === lastIdx);
275526
+ if (!result.placed) {
275527
+ nextPending.push({
275528
+ id: id2,
275529
+ ranges
275530
+ });
275531
+ for (let remainingIndex = idIndex + 1;remainingIndex < ids.length; remainingIndex += 1) {
275532
+ const remainingId = ids[remainingIndex];
275533
+ const remainingRanges = rangesByFootnoteId.get(remainingId) ?? [];
274956
275534
  nextPending.push({
274957
- id: id2,
274958
- ranges
275535
+ id: remainingId,
275536
+ ranges: remainingRanges
274959
275537
  });
274960
- for (let remainingIndex = idIndex + 1;remainingIndex < ids.length; remainingIndex += 1) {
274961
- const remainingId = ids[remainingIndex];
274962
- const remainingRanges = rangesByFootnoteId.get(remainingId) ?? [];
274963
- nextPending.push({
274964
- id: remainingId,
274965
- ranges: remainingRanges
274966
- });
274967
- }
274968
- stopPlacement = true;
274969
- break;
274970
275538
  }
274971
- if (result.remaining.length > 0)
274972
- nextPending.push({
274973
- id: id2,
274974
- ranges: result.remaining
274975
- });
275539
+ break;
274976
275540
  }
275541
+ if (result.remaining.length > 0)
275542
+ nextPending.push({
275543
+ id: id2,
275544
+ ranges: result.remaining
275545
+ });
274977
275546
  }
274978
275547
  if (columnSlices.length > 0) {
274979
275548
  const rawReserve = Math.max(0, Math.ceil(usedHeight));
@@ -274988,7 +275557,148 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
274988
275557
  }
274989
275558
  if (pageSlices.length > 0)
274990
275559
  slicesByPage.set(pageIndex, pageSlices);
274991
- reserves$1[pageIndex] = pageReserve;
275560
+ reserves$1[pageIndex] = Math.max(reserves$1[pageIndex] ?? 0, pageReserve);
275561
+ {
275562
+ const idsOnPage = (() => {
275563
+ const out = [];
275564
+ for (let cIdx = 0;cIdx < columnCount; cIdx += 1) {
275565
+ const colIds = idsByColumn$1.get(pageIndex)?.get(cIdx) ?? [];
275566
+ for (const id2 of colIds)
275567
+ if (!out.includes(id2))
275568
+ out.push(id2);
275569
+ }
275570
+ return out;
275571
+ })();
275572
+ const seenNewAnchor = /* @__PURE__ */ new Set;
275573
+ const mandatorySliceIds = [];
275574
+ const continuationSliceIds = [];
275575
+ const extendedSliceIds = [];
275576
+ let actualBandHeight = 0;
275577
+ const overheadBase = Math.max(0, separatorSpacingBefore) + safeDividerHeight + safeTopPadding;
275578
+ for (const slice2 of pageSlices) {
275579
+ if (slice2.isContinuation)
275580
+ continuationSliceIds.push(slice2.id);
275581
+ else if (!seenNewAnchor.has(slice2.id)) {
275582
+ mandatorySliceIds.push(slice2.id);
275583
+ seenNewAnchor.add(slice2.id);
275584
+ } else
275585
+ extendedSliceIds.push(slice2.id);
275586
+ actualBandHeight += slice2.totalHeight;
275587
+ }
275588
+ if (pageSlices.length > 0)
275589
+ actualBandHeight += overheadBase + safeGap * Math.max(0, pageSlices.length - 1);
275590
+ let mandatoryReserve = 0;
275591
+ let preferredReserve = 0;
275592
+ let continuationInHeight = 0;
275593
+ for (const entry of continuationInForPage)
275594
+ continuationInHeight += entry.remainingHeightPx;
275595
+ if (continuationInHeight > 0) {
275596
+ mandatoryReserve += continuationInHeight;
275597
+ preferredReserve += continuationInHeight;
275598
+ if (idsOnPage.length > 0) {
275599
+ mandatoryReserve += safeGap;
275600
+ preferredReserve += safeGap;
275601
+ }
275602
+ }
275603
+ if (idsOnPage.length > 0) {
275604
+ for (let i4 = 0;i4 < idsOnPage.length; i4 += 1) {
275605
+ const isLast = i4 === idsOnPage.length - 1;
275606
+ mandatoryReserve += isLast ? firstLineOf(idsOnPage[i4]) : fullHeightOf(idsOnPage[i4]);
275607
+ preferredReserve += fullHeightOf(idsOnPage[i4]);
275608
+ if (i4 > 0) {
275609
+ mandatoryReserve += safeGap;
275610
+ preferredReserve += safeGap;
275611
+ }
275612
+ }
275613
+ mandatoryReserve += overheadBase;
275614
+ preferredReserve += overheadBase;
275615
+ } else if (continuationInHeight > 0) {
275616
+ mandatoryReserve += overheadBase;
275617
+ preferredReserve += overheadBase;
275618
+ }
275619
+ let lastAnchorRenderedLines = 0;
275620
+ if (idsOnPage.length > 0) {
275621
+ const lastId = idsOnPage[idsOnPage.length - 1];
275622
+ for (const slice2 of pageSlices) {
275623
+ if (slice2.id !== lastId || slice2.isContinuation)
275624
+ continue;
275625
+ for (const range of slice2.ranges)
275626
+ if (range.kind === "paragraph" || range.kind === "list-item")
275627
+ lastAnchorRenderedLines += Math.max(0, range.toLine - range.fromLine);
275628
+ else
275629
+ lastAnchorRenderedLines += 1;
275630
+ }
275631
+ }
275632
+ const continuationOut = [];
275633
+ pendingByColumn.forEach((entries2) => {
275634
+ entries2.forEach((entry) => {
275635
+ let total = 0;
275636
+ entry.ranges.forEach((range) => {
275637
+ const spacingAfter = "spacingAfter" in range ? range.spacingAfter ?? 0 : 0;
275638
+ total += range.height + spacingAfter;
275639
+ });
275640
+ continuationOut.push({
275641
+ id: entry.id,
275642
+ remainingRangeCount: entry.ranges.length,
275643
+ remainingHeightPx: total
275644
+ });
275645
+ });
275646
+ });
275647
+ ledgersByPage.set(pageIndex, {
275648
+ anchorIds: idsOnPage,
275649
+ mandatorySliceIds,
275650
+ continuationSliceIds,
275651
+ extendedSliceIds,
275652
+ continuationIn: continuationInForPage,
275653
+ continuationOut,
275654
+ mandatoryReservePx: Math.ceil(mandatoryReserve),
275655
+ preferredReservePx: Math.ceil(preferredReserve),
275656
+ actualBandHeightPx: Math.ceil(actualBandHeight),
275657
+ lastAnchorRenderedLines
275658
+ });
275659
+ }
275660
+ if (pageIndex + 1 < pageCount) {
275661
+ let continuationDemand = 0;
275662
+ pendingByColumn.forEach((entries2) => {
275663
+ entries2.forEach((entry) => {
275664
+ entry.ranges.forEach((range) => {
275665
+ const spacingAfter = "spacingAfter" in range ? range.spacingAfter ?? 0 : 0;
275666
+ continuationDemand += range.height + spacingAfter;
275667
+ });
275668
+ });
275669
+ });
275670
+ let nextClusterDemand = 0;
275671
+ for (let cIdx = 0;cIdx < columnCount; cIdx += 1) {
275672
+ const idsNext = idsByColumn$1.get(pageIndex + 1)?.get(cIdx) ?? [];
275673
+ if (idsNext.length === 0)
275674
+ continue;
275675
+ let columnCluster = 0;
275676
+ for (let i4 = 0;i4 < idsNext.length; i4 += 1) {
275677
+ const isLast = i4 === idsNext.length - 1;
275678
+ columnCluster += isLast ? firstLineOf(idsNext[i4]) : fullHeightOf(idsNext[i4]);
275679
+ if (i4 > 0)
275680
+ columnCluster += safeGap;
275681
+ }
275682
+ if (columnCluster > nextClusterDemand)
275683
+ nextClusterDemand = columnCluster;
275684
+ }
275685
+ if (continuationDemand > 0 || nextClusterDemand > 0) {
275686
+ const overhead = safeSeparatorSpacingBefore + continuationDividerHeight + safeTopPadding;
275687
+ const nextPage = layoutForPages.pages?.[pageIndex + 1];
275688
+ const nextPageSize = nextPage?.size ?? layoutForPages.pageSize ?? DEFAULT_PAGE_SIZE$1;
275689
+ const nextTop = normalizeMargin(nextPage?.margins?.top, DEFAULT_MARGINS$1.top);
275690
+ const nextBottomRaw = normalizeMargin(nextPage?.margins?.bottom, DEFAULT_MARGINS$1.bottom);
275691
+ const physicalContentHeight = Math.max(0, nextPageSize.h - nextTop - nextBottomRaw);
275692
+ const minBodyHeight = MIN_FOOTNOTE_BODY_HEIGHT * 20;
275693
+ const nextPageMaxBand = Math.max(0, physicalContentHeight - minBodyHeight);
275694
+ const overheadForBand = nextClusterDemand > 0 || continuationDemand > 0 ? overhead : 0;
275695
+ const clusterRoomPx = nextClusterDemand > 0 ? Math.min(nextClusterDemand, Math.max(0, nextPageMaxBand - overheadForBand)) : 0;
275696
+ const continuationRoomPx = Math.max(0, nextPageMaxBand - overheadForBand - clusterRoomPx);
275697
+ const continuationToReservePx = Math.min(continuationDemand, continuationRoomPx);
275698
+ const finalReserve = Math.min(clusterRoomPx + continuationToReservePx + overheadForBand, nextPageMaxBand);
275699
+ reserves$1[pageIndex + 1] = Math.max(reserves$1[pageIndex + 1] ?? 0, Math.ceil(finalReserve));
275700
+ }
275701
+ }
274992
275702
  }
274993
275703
  if (cappedPages.size > 0)
274994
275704
  console.warn("[layout] Footnote reserve capped to preserve body area", { pages: Array.from(cappedPages) });
@@ -275001,7 +275711,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275001
275711
  slicesByPage,
275002
275712
  reserves: reserves$1,
275003
275713
  hasContinuationByColumn,
275004
- separatorSpacingBefore: safeSeparatorSpacingBefore
275714
+ separatorSpacingBefore: safeSeparatorSpacingBefore,
275715
+ ledgersByPage
275005
275716
  };
275006
275717
  };
275007
275718
  const injectFragments = (layoutForPages, plan$1, measuresById$1, reservesByPageIndex, blockById, pageColumns$1) => {
@@ -275010,6 +275721,23 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275010
275721
  for (let pageIndex = 0;pageIndex < layoutForPages.pages.length; pageIndex++) {
275011
275722
  const page = layoutForPages.pages[pageIndex];
275012
275723
  page.footnoteReserved = Math.max(0, reservesByPageIndex[pageIndex] ?? plan$1.reserves[pageIndex] ?? 0);
275724
+ const draft = plan$1.ledgersByPage.get(pageIndex);
275725
+ if (draft)
275726
+ page.footnoteLedger = {
275727
+ pageIndex,
275728
+ anchorIds: draft.anchorIds,
275729
+ mandatorySliceIds: draft.mandatorySliceIds,
275730
+ continuationSliceIds: draft.continuationSliceIds,
275731
+ extendedSliceIds: draft.extendedSliceIds,
275732
+ continuationIn: draft.continuationIn,
275733
+ continuationOut: draft.continuationOut,
275734
+ mandatoryReservePx: draft.mandatoryReservePx,
275735
+ preferredReservePx: draft.preferredReservePx,
275736
+ actualBandHeightPx: draft.actualBandHeightPx,
275737
+ appliedBodyReservePx: page.footnoteReserved ?? 0,
275738
+ deadReservePx: Math.max(0, (page.footnoteReserved ?? 0) - draft.actualBandHeightPx),
275739
+ lastAnchorRenderedLines: draft.lastAnchorRenderedLines
275740
+ };
275013
275741
  const slices = plan$1.slicesByPage.get(pageIndex) ?? [];
275014
275742
  if (slices.length === 0)
275015
275743
  continue;
@@ -275025,7 +275753,10 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275025
275753
  left: marginLeft,
275026
275754
  contentWidth: pageContentWidth
275027
275755
  };
275028
- const bandTopY = pageSize.h - (page.margins.bottom ?? 0);
275756
+ const physicalBottomMargin = Math.max(0, (page.margins.bottom ?? 0) - (page.footnoteReserved ?? 0));
275757
+ const pageBottomLimit = pageSize.h - physicalBottomMargin;
275758
+ const bodyMaxYValue = page.bodyMaxY;
275759
+ const bodyMaxY = typeof bodyMaxYValue === "number" && Number.isFinite(bodyMaxYValue) ? bodyMaxYValue : pageSize.h - (page.margins.bottom ?? 0);
275029
275760
  const slicesByColumn = /* @__PURE__ */ new Map;
275030
275761
  slices.forEach((slice2) => {
275031
275762
  const columnIndex = Number.isFinite(slice2.columnIndex) ? slice2.columnIndex : 0;
@@ -275044,9 +275775,16 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275044
275775
  return;
275045
275776
  const columnKey = footnoteColumnKey(pageIndex, columnIndex);
275046
275777
  const isContinuation = plan$1.hasContinuationByColumn.get(columnKey) ?? false;
275047
- let cursorY = bandTopY + Math.max(0, plan$1.separatorSpacingBefore);
275778
+ const colSeparatorHeight = isContinuation ? continuationDividerHeight : safeDividerHeight;
275779
+ let colTotalBandHeight = Math.max(0, plan$1.separatorSpacingBefore) + colSeparatorHeight + safeTopPadding;
275780
+ for (let s2 = 0;s2 < columnSlices.length; s2 += 1) {
275781
+ colTotalBandHeight += columnSlices[s2].totalHeight;
275782
+ if (s2 > 0)
275783
+ colTotalBandHeight += safeGap;
275784
+ }
275785
+ let cursorY = Math.max(bodyMaxY, pageBottomLimit - colTotalBandHeight) + Math.max(0, plan$1.separatorSpacingBefore);
275048
275786
  const separatorHeight = isContinuation ? continuationDividerHeight : safeDividerHeight;
275049
- const separatorWidth = isContinuation ? Math.max(0, contentWidth * continuationDividerWidthFactor) : contentWidth;
275787
+ const separatorWidth = isContinuation ? contentWidth : Math.max(0, contentWidth * SEPARATOR_DEFAULT_WIDTH_FACTOR);
275050
275788
  if (separatorHeight > 0 && separatorWidth > 0) {
275051
275789
  const separatorId = isContinuation ? `footnote-continuation-separator-page-${page.number}-col-${columnIndex}` : `footnote-separator-page-${page.number}-col-${columnIndex}`;
275052
275790
  decorativeBlocks.push({
@@ -275222,9 +275960,77 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275222
275960
  idsByColumn: assignFootnotesToColumns(layoutForPages, footnotesInput.refs, columns)
275223
275961
  };
275224
275962
  };
275225
- const relayout = (footnoteReservedByPageIndex) => layoutDocument(currentBlocks, currentMeasures, {
275963
+ let bodyHeightById = /* @__PURE__ */ new Map;
275964
+ let firstLineHeightById = /* @__PURE__ */ new Map;
275965
+ const refreshBodyHeights = (measures$1) => {
275966
+ const totalMap = /* @__PURE__ */ new Map;
275967
+ const firstLineMap = /* @__PURE__ */ new Map;
275968
+ footnotesInput.blocksById.forEach((blocks2, footnoteId) => {
275969
+ let total = 0;
275970
+ let firstLine = 0;
275971
+ for (const block of blocks2) {
275972
+ const measure = measures$1.get(block.id);
275973
+ if (!measure)
275974
+ continue;
275975
+ if (measure.kind === "paragraph") {
275976
+ const measureH = measure.totalHeight;
275977
+ if (typeof measureH === "number" && Number.isFinite(measureH))
275978
+ total += measureH;
275979
+ const spacing = block.attrs?.spacing;
275980
+ const after2 = spacing?.after ?? spacing?.lineSpaceAfter;
275981
+ if (typeof after2 === "number" && Number.isFinite(after2) && after2 > 0)
275982
+ total += after2;
275983
+ if (firstLine === 0) {
275984
+ const lines = measure.lines;
275985
+ const lh = lines && lines.length > 0 ? lines[0].lineHeight : undefined;
275986
+ if (typeof lh === "number" && Number.isFinite(lh) && lh > 0)
275987
+ firstLine = lh;
275988
+ }
275989
+ } else if (measure.kind === "image" || measure.kind === "drawing") {
275990
+ const measureH = measure.height;
275991
+ if (typeof measureH === "number" && Number.isFinite(measureH))
275992
+ total += measureH;
275993
+ if (firstLine === 0 && typeof measureH === "number" && Number.isFinite(measureH))
275994
+ firstLine = measureH;
275995
+ } else if (measure.kind === "table") {
275996
+ const measureH = measure.totalHeight;
275997
+ if (typeof measureH === "number" && Number.isFinite(measureH))
275998
+ total += measureH;
275999
+ if (firstLine === 0 && typeof measureH === "number" && Number.isFinite(measureH))
276000
+ firstLine = measureH;
276001
+ } else if (measure.kind === "list" && block.kind === "list") {
276002
+ for (const item of block.items) {
276003
+ const itemMeasure = measure.items.find((entry) => entry.itemId === item.id);
276004
+ if (!itemMeasure?.paragraph?.lines)
276005
+ continue;
276006
+ for (const line of itemMeasure.paragraph.lines)
276007
+ total += line.lineHeight ?? 0;
276008
+ total += getParagraphSpacingAfter(item.paragraph);
276009
+ }
276010
+ if (firstLine === 0) {
276011
+ const lh = measure.items[0]?.paragraph?.lines?.[0]?.lineHeight;
276012
+ if (typeof lh === "number" && Number.isFinite(lh) && lh > 0)
276013
+ firstLine = lh;
276014
+ }
276015
+ }
276016
+ }
276017
+ if (total > 0)
276018
+ totalMap.set(footnoteId, total);
276019
+ if (firstLine > 0)
276020
+ firstLineMap.set(footnoteId, firstLine);
276021
+ });
276022
+ bodyHeightById = totalMap;
276023
+ firstLineHeightById = firstLineMap;
276024
+ };
276025
+ const relayout = (footnoteReservedByPageIndex, plannerSeparatorSpacingBefore) => layoutDocument(currentBlocks, currentMeasures, {
275226
276026
  ...options,
275227
276027
  footnoteReservedByPageIndex,
276028
+ footnotes: {
276029
+ ...footnotesInput,
276030
+ bodyHeightById,
276031
+ firstLineHeightById,
276032
+ ...typeof plannerSeparatorSpacingBefore === "number" && Number.isFinite(plannerSeparatorSpacingBefore) ? { separatorSpacingBefore: plannerSeparatorSpacingBefore } : {}
276033
+ },
275228
276034
  headerContentHeights,
275229
276035
  footerContentHeights,
275230
276036
  headerContentHeightsBySectionRef,
@@ -275233,17 +276039,20 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275233
276039
  footerContentHeightsByRId,
275234
276040
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
275235
276041
  });
276042
+ const allFootnoteIds = new Set(footnotesInput.refs.map((ref$1) => ref$1.id));
275236
276043
  let { columns: pageColumns, idsByColumn } = resolveFootnoteAssignments(layout);
275237
- let { measuresById } = await measureFootnoteBlocks(collectFootnoteIdsByColumn(idsByColumn));
276044
+ let { measuresById } = await measureFootnoteBlocks(allFootnoteIds);
276045
+ refreshBodyHeights(measuresById);
275238
276046
  let plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, [], pageColumns);
275239
276047
  let reserves = plan.reserves;
275240
276048
  if (reserves.some((h$2) => h$2 > 0)) {
275241
276049
  let reservesStabilized = false;
275242
276050
  const seenReserveVectors = [reserves.slice()];
275243
276051
  for (let pass = 0;pass < MAX_FOOTNOTE_LAYOUT_PASSES; pass += 1) {
275244
- layout = relayout(reserves);
276052
+ layout = relayout(reserves, plan.separatorSpacingBefore);
275245
276053
  ({ columns: pageColumns, idsByColumn } = resolveFootnoteAssignments(layout));
275246
- ({ measuresById } = await measureFootnoteBlocks(collectFootnoteIdsByColumn(idsByColumn)));
276054
+ ({ measuresById } = await measureFootnoteBlocks(allFootnoteIds));
276055
+ refreshBodyHeights(measuresById);
275247
276056
  plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, reserves, pageColumns);
275248
276057
  const nextReserves = plan.reserves;
275249
276058
  if (nextReserves.length === reserves.length && nextReserves.every((h$2, i4) => (reserves[i4] ?? 0) === h$2) && reserves.every((h$2, i4) => (nextReserves[i4] ?? 0) === h$2)) {
@@ -275270,12 +276079,53 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275270
276079
  return true;
275271
276080
  };
275272
276081
  const applyReserves = async (target) => {
275273
- layout = relayout(target);
276082
+ layout = relayout(target, finalPlan.separatorSpacingBefore);
275274
276083
  reservesAppliedToLayout = target;
275275
276084
  ({ columns: finalPageColumns, idsByColumn: finalIdsByColumn } = resolveFootnoteAssignments(layout));
275276
- ({ blocks: finalBlocks, measuresById: finalMeasuresById } = await measureFootnoteBlocks(collectFootnoteIdsByColumn(finalIdsByColumn)));
276085
+ ({ blocks: finalBlocks, measuresById: finalMeasuresById } = await measureFootnoteBlocks(allFootnoteIds));
276086
+ refreshBodyHeights(finalMeasuresById);
275277
276087
  finalPlan = computeFootnoteLayoutPlan(layout, finalIdsByColumn, finalMeasuresById, reservesAppliedToLayout, finalPageColumns);
275278
276088
  };
276089
+ const buildFootnoteLedgers = (plan$1, appliedReserves, pageCount) => {
276090
+ const ledgers = [];
276091
+ for (let pageIndex = 0;pageIndex < pageCount; pageIndex += 1) {
276092
+ const draft = plan$1.ledgersByPage.get(pageIndex);
276093
+ if (!draft)
276094
+ continue;
276095
+ const appliedBodyReservePx = Math.max(0, appliedReserves[pageIndex] ?? plan$1.reserves[pageIndex] ?? 0);
276096
+ ledgers.push({
276097
+ pageIndex,
276098
+ anchorIds: draft.anchorIds,
276099
+ mandatorySliceIds: draft.mandatorySliceIds,
276100
+ continuationSliceIds: draft.continuationSliceIds,
276101
+ extendedSliceIds: draft.extendedSliceIds,
276102
+ continuationIn: draft.continuationIn,
276103
+ continuationOut: draft.continuationOut,
276104
+ mandatoryReservePx: draft.mandatoryReservePx,
276105
+ preferredReservePx: draft.preferredReservePx,
276106
+ actualBandHeightPx: draft.actualBandHeightPx,
276107
+ appliedBodyReservePx,
276108
+ deadReservePx: Math.max(0, appliedBodyReservePx - draft.actualBandHeightPx),
276109
+ lastAnchorRenderedLines: draft.lastAnchorRenderedLines
276110
+ });
276111
+ }
276112
+ return ledgers;
276113
+ };
276114
+ const capReserveForRelayout = (requestedReserve, pageIndex, referenceLayout, referenceReserves) => {
276115
+ const requested = Number.isFinite(requestedReserve) ? Math.max(0, requestedReserve) : 0;
276116
+ const page = referenceLayout.pages?.[pageIndex];
276117
+ if (!page)
276118
+ return requested;
276119
+ const pageSize = page.size ?? referenceLayout.pageSize ?? DEFAULT_PAGE_SIZE$1;
276120
+ const topMargin = normalizeMargin(page.margins?.top, DEFAULT_MARGINS$1.top);
276121
+ const bottomWithReserve = normalizeMargin(page.margins?.bottom, DEFAULT_MARGINS$1.bottom);
276122
+ const currentReserve = Number.isFinite(referenceReserves[pageIndex]) ? Math.max(0, referenceReserves[pageIndex]) : 0;
276123
+ const physicalBottomMargin = Math.max(0, bottomWithReserve - currentReserve);
276124
+ const physicalContentHeight = pageSize.h - topMargin - physicalBottomMargin;
276125
+ if (!Number.isFinite(physicalContentHeight))
276126
+ return requested;
276127
+ return Math.min(requested, Math.max(0, physicalContentHeight - MIN_FOOTNOTE_BODY_HEIGHT));
276128
+ };
275279
276129
  const growReserves = async (maxPasses) => {
275280
276130
  const seen = [reservesAppliedToLayout.slice()];
275281
276131
  for (let pass = 0;pass < maxPasses; pass += 1) {
@@ -275301,6 +276151,74 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275301
276151
  }
275302
276152
  return false;
275303
276153
  };
276154
+ const GROW_MAX_PASSES = 10;
276155
+ const PREFERRED_RESERVE_MAX_CANDIDATES = 12;
276156
+ const PREFERRED_RESERVE_MAX_ACCEPTED_CANDIDATES = PREFERRED_RESERVE_MAX_CANDIDATES;
276157
+ const PREFERRED_RESERVE_WINDOW_AHEAD = 3;
276158
+ const runPreferredReserveTrials = async () => {
276159
+ let acceptedPreferredTrials = 0;
276160
+ let rejectedPreferredTrials = 0;
276161
+ const rejectedPreferredPages = /* @__PURE__ */ new Set;
276162
+ for (let candidatePass = 0;candidatePass < PREFERRED_RESERVE_MAX_CANDIDATES; candidatePass += 1) {
276163
+ const beforeLayout = layout;
276164
+ const beforePlan = finalPlan;
276165
+ const beforeReserves = reservesAppliedToLayout.slice();
276166
+ const beforeLedgers = buildFootnoteLedgers(beforePlan, beforeReserves, beforeLayout.pages.length);
276167
+ const candidate = getPreferredReserveCandidates(beforeLedgers).find((entry) => !rejectedPreferredPages.has(entry.pageIndex));
276168
+ if (!candidate)
276169
+ break;
276170
+ const targetReserves = getPreferredReserveTrialTargets(candidate, beforeReserves[candidate.pageIndex] ?? 0);
276171
+ let acceptedCandidate = false;
276172
+ for (const targetReserve of targetReserves) {
276173
+ const trialReserves = beforeReserves.slice();
276174
+ const cappedPreferredReserve = capReserveForRelayout(targetReserve, candidate.pageIndex, beforeLayout, beforeReserves);
276175
+ trialReserves[candidate.pageIndex] = Math.max(trialReserves[candidate.pageIndex] ?? 0, cappedPreferredReserve);
276176
+ await applyReserves(trialReserves);
276177
+ const trialConverged = await growReserves(GROW_MAX_PASSES);
276178
+ const afterLedgers = buildFootnoteLedgers(finalPlan, reservesAppliedToLayout, layout.pages.length);
276179
+ const score = scoreFootnoteWindow({
276180
+ beforeLayout,
276181
+ afterLayout: layout,
276182
+ candidatePageIndex: candidate.pageIndex,
276183
+ candidateAnchorId: candidate.anchorIds[candidate.anchorIds.length - 1],
276184
+ beforeLedger: beforeLedgers,
276185
+ afterLedger: afterLedgers,
276186
+ windowAhead: PREFERRED_RESERVE_WINDOW_AHEAD
276187
+ });
276188
+ if (trialConverged && score.accept) {
276189
+ if (layoutDebugEnabled$1)
276190
+ console.log("[incrementalLayout] Accepted footnote preferred-reserve trial", {
276191
+ pageIndex: candidate.pageIndex,
276192
+ targetReserve,
276193
+ score
276194
+ });
276195
+ acceptedPreferredTrials += 1;
276196
+ acceptedCandidate = true;
276197
+ break;
276198
+ }
276199
+ if (layoutDebugEnabled$1)
276200
+ console.log("[incrementalLayout] Rejected footnote preferred-reserve trial", {
276201
+ pageIndex: candidate.pageIndex,
276202
+ targetReserve,
276203
+ trialConverged,
276204
+ score
276205
+ });
276206
+ await applyReserves(beforeReserves);
276207
+ }
276208
+ if (acceptedCandidate) {
276209
+ if (acceptedPreferredTrials >= PREFERRED_RESERVE_MAX_ACCEPTED_CANDIDATES)
276210
+ break;
276211
+ continue;
276212
+ }
276213
+ rejectedPreferredTrials += 1;
276214
+ rejectedPreferredPages.add(candidate.pageIndex);
276215
+ }
276216
+ if (layoutDebugEnabled$1 && (acceptedPreferredTrials > 0 || rejectedPreferredTrials > 0))
276217
+ console.log("[incrementalLayout] Footnote preferred-reserve trials", {
276218
+ accepted: acceptedPreferredTrials,
276219
+ rejected: rejectedPreferredTrials
276220
+ });
276221
+ };
275304
276222
  const TIGHTEN_SLACK_PX = 8;
275305
276223
  if ((() => {
275306
276224
  const plan$1 = finalPlan.reserves;
@@ -275313,10 +276231,11 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275313
276231
  return true;
275314
276232
  if (a2 >= TIGHTEN_SLACK_PX && p$12 === 0)
275315
276233
  return true;
276234
+ if (a2 >= TIGHTEN_SLACK_PX && a2 - p$12 > TIGHTEN_SLACK_PX)
276235
+ return true;
275316
276236
  }
275317
276237
  return false;
275318
276238
  })()) {
275319
- const GROW_MAX_PASSES = 10;
275320
276239
  if (!await growReserves(GROW_MAX_PASSES))
275321
276240
  console.warn("[incrementalLayout] Footnote post-reserve loop did not converge; some pages may have footnotes overflowing the reserved band.");
275322
276241
  const MAX_TIGHTEN_ITERATIONS = 8;
@@ -275325,16 +276244,26 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275325
276244
  for (let i4 = 0;i4 < reservesAppliedToLayout.length; i4 += 1) {
275326
276245
  const applied = reservesAppliedToLayout[i4] ?? 0;
275327
276246
  const planned = finalPlan.reserves[i4] ?? 0;
275328
- if (applied >= TIGHTEN_SLACK_PX && planned === 0)
275329
- pagesToTighten.push(i4);
276247
+ if (applied < TIGHTEN_SLACK_PX)
276248
+ continue;
276249
+ if (planned === 0)
276250
+ pagesToTighten.push({
276251
+ i: i4,
276252
+ target: 0
276253
+ });
276254
+ else if (applied - planned > TIGHTEN_SLACK_PX)
276255
+ pagesToTighten.push({
276256
+ i: i4,
276257
+ target: planned
276258
+ });
275330
276259
  }
275331
276260
  if (pagesToTighten.length === 0)
275332
276261
  break;
275333
276262
  const safeApplied = reservesAppliedToLayout.slice();
275334
276263
  const safePageCount = layout.pages.length;
275335
276264
  const tightened = reservesAppliedToLayout.slice();
275336
- for (const i4 of pagesToTighten)
275337
- tightened[i4] = 0;
276265
+ for (const { i: i4, target } of pagesToTighten)
276266
+ tightened[i4] = target;
275338
276267
  await applyReserves(tightened);
275339
276268
  if (!await growReserves(GROW_MAX_PASSES) || layout.pages.length > safePageCount) {
275340
276269
  await applyReserves(safeApplied);
@@ -275342,6 +276271,30 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
275342
276271
  }
275343
276272
  }
275344
276273
  }
276274
+ const ONE_LINE_TAIL_PX = 24;
276275
+ const runWidowOrphanAbsorb = async () => {
276276
+ const ledgers = buildFootnoteLedgers(finalPlan, reservesAppliedToLayout, layout.pages.length);
276277
+ const target = reservesAppliedToLayout.slice();
276278
+ let bumped = 0;
276279
+ for (const ledger of ledgers) {
276280
+ const tailPx = ledger.continuationOut.reduce((s2, e) => s2 + (e.remainingHeightPx || 0), 0);
276281
+ if (tailPx <= 0 || tailPx > ONE_LINE_TAIL_PX)
276282
+ continue;
276283
+ const requested = capReserveForRelayout(ledger.preferredReservePx, ledger.pageIndex, layout, reservesAppliedToLayout);
276284
+ if (requested > (target[ledger.pageIndex] ?? 0)) {
276285
+ target[ledger.pageIndex] = requested;
276286
+ bumped += 1;
276287
+ }
276288
+ }
276289
+ if (bumped === 0)
276290
+ return;
276291
+ const safeApplied = reservesAppliedToLayout.slice();
276292
+ await applyReserves(target);
276293
+ if (!await growReserves(GROW_MAX_PASSES))
276294
+ await applyReserves(safeApplied);
276295
+ };
276296
+ await runWidowOrphanAbsorb();
276297
+ await runPreferredReserveTrials();
275345
276298
  const blockById = /* @__PURE__ */ new Map;
275346
276299
  finalBlocks.forEach((block) => {
275347
276300
  blockById.set(block.id, block);
@@ -277757,15 +278710,95 @@ function createLayoutMetrics(perf, startMark, layout, blocks2) {
277757
278710
  pageCount: layout.pages?.length ?? 0
277758
278711
  };
277759
278712
  }
278713
+ function computeNoteNumbering(editorState, noteTypeName, options) {
278714
+ const numberById = {};
278715
+ const formatById = {};
278716
+ const order$1 = [];
278717
+ if (!editorState)
278718
+ return {
278719
+ numberById,
278720
+ order: order$1
278721
+ };
278722
+ const seen = /* @__PURE__ */ new Set;
278723
+ const sectionConfigs = options.sectionConfigs ?? /* @__PURE__ */ new Map;
278724
+ const refPageById = options.refPageById;
278725
+ let sectionIndex = 0;
278726
+ let lastPage = null;
278727
+ let anyOverride = false;
278728
+ const restartFor = (s2) => sectionConfigs.get(s2)?.numRestart ?? options.defaultRestart ?? "continuous";
278729
+ const numStartFor = (s2) => sectionConfigs.get(s2)?.numStart ?? options.startCounter;
278730
+ const numFmtFor = (s2) => sectionConfigs.get(s2)?.numFmt ?? options.defaultNumFmt;
278731
+ let counter = numStartFor(0);
278732
+ try {
278733
+ editorState.doc?.descendants?.((node3) => {
278734
+ const typeName = node3?.type?.name;
278735
+ if (typeName === "sectionBreak") {
278736
+ const nextSection = sectionIndex + 1;
278737
+ const nextRestart = restartFor(nextSection);
278738
+ if (nextRestart === "eachSect" || nextRestart === "eachPage") {
278739
+ counter = numStartFor(nextSection);
278740
+ lastPage = null;
278741
+ }
278742
+ sectionIndex = nextSection;
278743
+ return;
278744
+ }
278745
+ if (typeName !== noteTypeName)
278746
+ return;
278747
+ const rawId = node3?.attrs?.id;
278748
+ if (rawId == null)
278749
+ return;
278750
+ const key2 = String(rawId);
278751
+ if (!key2 || seen.has(key2))
278752
+ return;
278753
+ seen.add(key2);
278754
+ order$1.push(key2);
278755
+ if (isCustomMarkFollows2(node3?.attrs?.customMarkFollows))
278756
+ return;
278757
+ if (refPageById && restartFor(sectionIndex) === "eachPage") {
278758
+ const thisPage = refPageById.get(key2) ?? 0;
278759
+ if (lastPage !== null && thisPage !== lastPage)
278760
+ counter = numStartFor(sectionIndex);
278761
+ lastPage = thisPage;
278762
+ }
278763
+ numberById[key2] = counter;
278764
+ const fmt = numFmtFor(sectionIndex);
278765
+ if (fmt) {
278766
+ formatById[key2] = fmt;
278767
+ if (sectionConfigs.has(sectionIndex) && sectionConfigs.get(sectionIndex)?.numFmt)
278768
+ anyOverride = true;
278769
+ }
278770
+ counter += 1;
278771
+ });
278772
+ } catch (_$1) {}
278773
+ return anyOverride ? {
278774
+ numberById,
278775
+ formatById,
278776
+ order: order$1
278777
+ } : {
278778
+ numberById,
278779
+ order: order$1
278780
+ };
278781
+ }
278782
+ function isCustomMarkFollows2(value) {
278783
+ if (value === true || value === 1)
278784
+ return true;
278785
+ if (typeof value !== "string")
278786
+ return false;
278787
+ const v = value.trim().toLowerCase();
278788
+ return v === "1" || v === "true" || v === "on";
278789
+ }
277760
278790
  function buildFootnotesInput(editorState, converter, converterContext, themeColors, renderOverride = null, resolveTrackedChangeColor) {
277761
278791
  if (!editorState)
277762
278792
  return null;
277763
278793
  const footnoteNumberById = converterContext?.footnoteNumberById;
278794
+ const footnoteNumberFormat = converterContext?.footnoteNumberFormat;
278795
+ const footnoteFormatById = converterContext?.footnoteFormatById;
277764
278796
  const importedFootnotes = Array.isArray(converter?.footnotes) ? converter.footnotes : [];
277765
278797
  if (importedFootnotes.length === 0)
277766
278798
  return null;
277767
278799
  const refs = [];
277768
278800
  const idsInUse = /* @__PURE__ */ new Set;
278801
+ const customMarkIds = /* @__PURE__ */ new Set;
277769
278802
  editorState.doc.descendants((node3, pos) => {
277770
278803
  if (node3.type?.name !== "footnoteReference")
277771
278804
  return;
@@ -277779,6 +278812,8 @@ function buildFootnotesInput(editorState, converter, converterContext, themeColo
277779
278812
  pos: insidePos
277780
278813
  });
277781
278814
  idsInUse.add(key2);
278815
+ if (isCustomMarkFollows2(node3.attrs?.customMarkFollows))
278816
+ customMarkIds.add(key2);
277782
278817
  });
277783
278818
  if (refs.length === 0)
277784
278819
  return null;
@@ -277801,7 +278836,10 @@ function buildFootnotesInput(editorState, converter, converterContext, themeColo
277801
278836
  resolveTrackedChangeColor
277802
278837
  });
277803
278838
  if (result?.blocks?.length) {
277804
- ensureFootnoteMarker(result.blocks, id2, footnoteNumberById);
278839
+ if (!customMarkIds.has(id2)) {
278840
+ const numFmtForId = footnoteFormatById?.[id2] ?? footnoteNumberFormat;
278841
+ ensureFootnoteMarker(result.blocks, id2, footnoteNumberById, numFmtForId);
278842
+ }
277805
278843
  blocksById.set(id2, result.blocks);
277806
278844
  }
277807
278845
  } catch (_$1) {}
@@ -277827,9 +278865,6 @@ function resolveDisplayNumber$1(id2, footnoteNumberById) {
277827
278865
  return num;
277828
278866
  return 1;
277829
278867
  }
277830
- function resolveMarkerText(value) {
277831
- return String(value ?? "");
277832
- }
277833
278868
  function resolveMarkerFontFamily$1(firstTextRun) {
277834
278869
  return typeof firstTextRun?.fontFamily === "string" ? firstTextRun.fontFamily : DEFAULT_MARKER_FONT_FAMILY$1;
277835
278870
  }
@@ -277841,18 +278876,12 @@ function resolveMarkerBaseFontSize$1(firstTextRun) {
277841
278876
  function buildMarkerRun$1(markerText, firstTextRun) {
277842
278877
  const markerRun = {
277843
278878
  kind: "text",
277844
- text: markerText,
278879
+ text: `${markerText} `,
277845
278880
  dataAttrs: { [FOOTNOTE_MARKER_DATA_ATTR]: "true" },
277846
278881
  fontFamily: resolveMarkerFontFamily$1(firstTextRun),
277847
278882
  fontSize: resolveMarkerBaseFontSize$1(firstTextRun) * SUBSCRIPT_SUPERSCRIPT_SCALE,
277848
278883
  vertAlign: "superscript"
277849
278884
  };
277850
- if (typeof firstTextRun?.bold === "boolean")
277851
- markerRun.bold = firstTextRun.bold;
277852
- if (typeof firstTextRun?.italic === "boolean")
277853
- markerRun.italic = firstTextRun.italic;
277854
- if (typeof firstTextRun?.letterSpacing === "number" && Number.isFinite(firstTextRun.letterSpacing))
277855
- markerRun.letterSpacing = firstTextRun.letterSpacing;
277856
278885
  if (firstTextRun?.color != null)
277857
278886
  markerRun.color = firstTextRun.color;
277858
278887
  return markerRun;
@@ -277889,12 +278918,12 @@ function syncMarkerRun$1(target, source) {
277889
278918
  delete target.pmStart;
277890
278919
  delete target.pmEnd;
277891
278920
  }
277892
- function ensureFootnoteMarker(blocks2, id2, footnoteNumberById) {
278921
+ function ensureFootnoteMarker(blocks2, id2, footnoteNumberById, footnoteNumberFormat) {
277893
278922
  const firstParagraph = blocks2.find((b$1) => b$1?.kind === "paragraph");
277894
278923
  if (!firstParagraph)
277895
278924
  return;
277896
278925
  const runs2 = Array.isArray(firstParagraph.runs) ? firstParagraph.runs : [];
277897
- const normalizedMarkerRun = buildMarkerRun$1(resolveMarkerText(resolveDisplayNumber$1(id2, footnoteNumberById)), runs2.find((run2) => typeof run2.text === "string" && !isFootnoteMarker(run2)));
278926
+ const normalizedMarkerRun = buildMarkerRun$1(formatFootnoteCardinal(resolveDisplayNumber$1(id2, footnoteNumberById), footnoteNumberFormat), runs2.find((run2) => typeof run2.text === "string" && !isFootnoteMarker(run2)));
277898
278927
  const existingMarker = runs2.find(isFootnoteMarker);
277899
278928
  if (existingMarker) {
277900
278929
  syncMarkerRun$1(existingMarker, normalizedMarkerRun);
@@ -283847,11 +284876,14 @@ function buildEndnoteBlocks(editorState, converter, converterContext, themeColor
283847
284876
  if (!editorState)
283848
284877
  return [];
283849
284878
  const endnoteNumberById = converterContext?.endnoteNumberById;
284879
+ const endnoteNumberFormat = converterContext?.endnoteNumberFormat;
284880
+ const endnoteFormatById = converterContext?.endnoteFormatById;
283850
284881
  const importedEndnotes = Array.isArray(converter?.endnotes) ? converter.endnotes : [];
283851
284882
  if (importedEndnotes.length === 0)
283852
284883
  return [];
283853
284884
  const orderedEndnoteIds = [];
283854
284885
  const seen = /* @__PURE__ */ new Set;
284886
+ const customMarkIds = /* @__PURE__ */ new Set;
283855
284887
  editorState.doc.descendants((node3) => {
283856
284888
  if (node3.type?.name !== "endnoteReference")
283857
284889
  return;
@@ -283863,6 +284895,8 @@ function buildEndnoteBlocks(editorState, converter, converterContext, themeColor
283863
284895
  return;
283864
284896
  seen.add(key2);
283865
284897
  orderedEndnoteIds.push(key2);
284898
+ if (isCustomMarkFollows2(node3.attrs?.customMarkFollows))
284899
+ customMarkIds.add(key2);
283866
284900
  });
283867
284901
  if (orderedEndnoteIds.length === 0)
283868
284902
  return [];
@@ -283885,7 +284919,10 @@ function buildEndnoteBlocks(editorState, converter, converterContext, themeColor
283885
284919
  resolveTrackedChangeColor
283886
284920
  });
283887
284921
  if (result?.blocks?.length) {
283888
- ensureEndnoteMarker(result.blocks, id2, endnoteNumberById);
284922
+ if (!customMarkIds.has(id2)) {
284923
+ const numFmtForId = endnoteFormatById?.[id2] ?? endnoteNumberFormat;
284924
+ ensureEndnoteMarker(result.blocks, id2, endnoteNumberById, numFmtForId);
284925
+ }
283889
284926
  blocks2.push(...result.blocks);
283890
284927
  }
283891
284928
  } catch {}
@@ -283917,18 +284954,12 @@ function resolveMarkerBaseFontSize(firstTextRun) {
283917
284954
  function buildMarkerRun(markerText, firstTextRun) {
283918
284955
  const markerRun = {
283919
284956
  kind: "text",
283920
- text: markerText,
284957
+ text: `${markerText} `,
283921
284958
  dataAttrs: { [ENDNOTE_MARKER_DATA_ATTR]: "true" },
283922
284959
  fontFamily: resolveMarkerFontFamily(firstTextRun),
283923
284960
  fontSize: resolveMarkerBaseFontSize(firstTextRun) * SUBSCRIPT_SUPERSCRIPT_SCALE,
283924
284961
  vertAlign: "superscript"
283925
284962
  };
283926
- if (typeof firstTextRun?.bold === "boolean")
283927
- markerRun.bold = firstTextRun.bold;
283928
- if (typeof firstTextRun?.italic === "boolean")
283929
- markerRun.italic = firstTextRun.italic;
283930
- if (typeof firstTextRun?.letterSpacing === "number" && Number.isFinite(firstTextRun.letterSpacing))
283931
- markerRun.letterSpacing = firstTextRun.letterSpacing;
283932
284963
  if (firstTextRun?.color != null)
283933
284964
  markerRun.color = firstTextRun.color;
283934
284965
  return markerRun;
@@ -283965,14 +284996,14 @@ function resolveEndnoteDocJson(id2, importedEndnotes, renderOverride) {
283965
284996
  content: cloneNoteContentJson(content3)
283966
284997
  });
283967
284998
  }
283968
- function ensureEndnoteMarker(blocks2, id2, endnoteNumberById) {
284999
+ function ensureEndnoteMarker(blocks2, id2, endnoteNumberById, endnoteNumberFormat) {
283969
285000
  const firstParagraph = blocks2.find((block) => block.kind === "paragraph");
283970
285001
  if (!firstParagraph)
283971
285002
  return;
283972
285003
  const runs2 = Array.isArray(firstParagraph.runs) ? firstParagraph.runs : [];
283973
285004
  firstParagraph.runs = runs2;
283974
285005
  const firstTextRun = runs2.find((run2) => isTextRun$12(run2) && !isEndnoteMarker(run2) && run2.text.length > 0);
283975
- const markerRun = buildMarkerRun(String(resolveDisplayNumber(id2, endnoteNumberById)), firstTextRun);
285006
+ const markerRun = buildMarkerRun(formatFootnoteCardinal(resolveDisplayNumber(id2, endnoteNumberById), endnoteNumberFormat), firstTextRun);
283976
285007
  if (runs2[0] && isTextRun$12(runs2[0]) && isEndnoteMarker(runs2[0])) {
283977
285008
  syncMarkerRun(runs2[0], markerRun);
283978
285009
  return;
@@ -284192,6 +285223,22 @@ function ensureEditorMovableObjectInteractionStyles(doc$12) {
284192
285223
  doc$12.head?.appendChild(styleEl);
284193
285224
  movableObjectInteractionStylesInjected = true;
284194
285225
  }
285226
+ function serializeSectionConfigs(map$12) {
285227
+ if (map$12.size === 0)
285228
+ return "";
285229
+ return [...map$12.entries()].sort((a2, b$1) => a2[0] - b$1[0]).map(([i4, c]) => `${i4}:${c.numFmt ?? ""}/${c.numStart ?? ""}/${c.numRestart ?? ""}`).join(";");
285230
+ }
285231
+ function serializePerIdNumbering(order$1, numberById, formatById) {
285232
+ if (order$1.length === 0)
285233
+ return "";
285234
+ const parts = [];
285235
+ for (const id2 of order$1) {
285236
+ const n = numberById[id2];
285237
+ const f2 = formatById?.[id2] ?? "";
285238
+ parts.push(`${id2}:${n ?? ""}/${f2}`);
285239
+ }
285240
+ return parts.join(";");
285241
+ }
284195
285242
  function parseRenderedNoteTarget(blockId) {
284196
285243
  if (typeof blockId !== "string" || blockId.length === 0)
284197
285244
  return null;
@@ -305205,6 +306252,10 @@ menclose::after {
305205
306252
  markerEl.style.color = run2.color;
305206
306253
  if (run2.letterSpacing != null)
305207
306254
  markerEl.style.letterSpacing = `${run2.letterSpacing}px`;
306255
+ if (run2.allCaps)
306256
+ markerEl.style.textTransform = "uppercase";
306257
+ else if (run2.smallCaps)
306258
+ markerEl.style.fontVariant = "small-caps";
305208
306259
  markerContainer.appendChild(markerEl);
305209
306260
  if (sourceAnchor)
305210
306261
  applySourceAnchorDataset(markerEl, sourceAnchor);
@@ -313166,6 +314217,208 @@ menclose::after {
313166
314217
  this.constraintsHash = "";
313167
314218
  this.sectionMetadataHash = "";
313168
314219
  }
314220
+ }, DEFAULT_WINDOW_AHEAD = 3, DEFAULT_PREFERRED_DELTA_THRESHOLD_PX = 8, DEFAULT_MANDATORY_ONLY_TOLERANCE_PX = 2, DEFAULT_DEAD_RESERVE_BLOAT_THRESHOLD_PX = 128, DEFAULT_WHOLE_DOCUMENT_DEAD_RESERVE_BLOAT_THRESHOLD_PX = 128, FULL_ANCHOR_RENDER_SENTINEL, DEFAULT_TRIAL_TARGET_COUNT = 12, isMandatoryOnlyFootnotePage = (ledger, preferredDeltaThresholdPx = DEFAULT_PREFERRED_DELTA_THRESHOLD_PX, mandatoryOnlyTolerancePx = DEFAULT_MANDATORY_ONLY_TOLERANCE_PX) => {
314221
+ if (ledger.anchorIds.length === 0)
314222
+ return false;
314223
+ return Math.abs(ledger.actualBandHeightPx - ledger.mandatoryReservePx) <= mandatoryOnlyTolerancePx && ledger.preferredReservePx - ledger.mandatoryReservePx > preferredDeltaThresholdPx && ledger.lastAnchorRenderedLines <= 1;
314224
+ }, isSplitLastAnchorFootnotePage = (ledger, preferredDeltaThresholdPx = DEFAULT_PREFERRED_DELTA_THRESHOLD_PX) => {
314225
+ if (ledger.anchorIds.length === 0)
314226
+ return false;
314227
+ const lastAnchorId = ledger.anchorIds[ledger.anchorIds.length - 1];
314228
+ if (!ledger.continuationOut.some((entry) => entry.id === lastAnchorId))
314229
+ return false;
314230
+ return ledger.preferredReservePx - ledger.mandatoryReservePx > preferredDeltaThresholdPx && ledger.actualBandHeightPx < ledger.preferredReservePx - preferredDeltaThresholdPx;
314231
+ }, getPreferredReserveCandidates = (ledgers, preferredDeltaThresholdPx = DEFAULT_PREFERRED_DELTA_THRESHOLD_PX, mandatoryOnlyTolerancePx = DEFAULT_MANDATORY_ONLY_TOLERANCE_PX) => {
314232
+ return ledgers.filter((ledger) => isMandatoryOnlyFootnotePage(ledger, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx) || isSplitLastAnchorFootnotePage(ledger, preferredDeltaThresholdPx)).map((ledger) => ({
314233
+ pageIndex: ledger.pageIndex,
314234
+ anchorIds: ledger.anchorIds.slice(),
314235
+ mandatoryReservePx: ledger.mandatoryReservePx,
314236
+ preferredReservePx: ledger.preferredReservePx,
314237
+ reserveDeltaPx: ledger.preferredReservePx - ledger.mandatoryReservePx,
314238
+ actualBandHeightPx: ledger.actualBandHeightPx,
314239
+ lastAnchorRenderedLines: ledger.lastAnchorRenderedLines
314240
+ }));
314241
+ }, getPreferredReserveTrialTargets = (candidate, currentReservePx, preferredDeltaThresholdPx = DEFAULT_PREFERRED_DELTA_THRESHOLD_PX, maxTargets = DEFAULT_TRIAL_TARGET_COUNT) => {
314242
+ const current = Number.isFinite(currentReservePx) ? Math.max(0, currentReservePx) : 0;
314243
+ const floor$1 = Math.max(current, candidate.mandatoryReservePx);
314244
+ const ceiling = Math.max(floor$1, candidate.preferredReservePx);
314245
+ const delta = ceiling - floor$1;
314246
+ if (delta <= preferredDeltaThresholdPx)
314247
+ return [];
314248
+ const targets = /* @__PURE__ */ new Set;
314249
+ const addTarget = (value) => {
314250
+ if (!Number.isFinite(value))
314251
+ return;
314252
+ const rounded = Math.ceil(Math.max(floor$1, Math.min(ceiling, value)));
314253
+ if (rounded - floor$1 > preferredDeltaThresholdPx)
314254
+ targets.add(rounded);
314255
+ };
314256
+ [
314257
+ 1,
314258
+ 0.75,
314259
+ 0.5,
314260
+ 0.33,
314261
+ 0.25,
314262
+ 0.15
314263
+ ].forEach((fraction) => addTarget(floor$1 + delta * fraction));
314264
+ [
314265
+ 96,
314266
+ 72,
314267
+ 48,
314268
+ 24,
314269
+ 12
314270
+ ].forEach((px) => addTarget(floor$1 + Math.min(delta, px)));
314271
+ return Array.from(targets).sort((a2, b$1) => b$1 - a2).slice(0, Math.max(1, maxTargets));
314272
+ }, getWindowBounds = (layout, candidatePageIndex, windowAhead) => ({
314273
+ windowStart: Math.max(0, candidatePageIndex),
314274
+ windowEnd: Math.min(layout.pages.length - 1, candidatePageIndex + Math.max(0, windowAhead))
314275
+ }), getDocumentBounds = (layout) => ({
314276
+ windowStart: 0,
314277
+ windowEnd: Math.max(0, layout.pages.length - 1)
314278
+ }), isInWindow = (ledger, windowStart, windowEnd) => ledger.pageIndex >= windowStart && ledger.pageIndex <= windowEnd, getLastAnchorId = (ledger) => {
314279
+ if (!ledger || ledger.anchorIds.length === 0)
314280
+ return;
314281
+ return ledger.anchorIds[ledger.anchorIds.length - 1];
314282
+ }, collectLedgerDiagnostics = (ledgers, windowStart, windowEnd, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx) => {
314283
+ const diagnostics = {
314284
+ mandatoryOnlyCount: 0,
314285
+ mandatoryOnlyAnchorIds: /* @__PURE__ */ new Set,
314286
+ deadReserveSum: 0,
314287
+ clusterSplitCount: 0,
314288
+ clusterSplitAnchorIds: /* @__PURE__ */ new Set
314289
+ };
314290
+ for (const ledger of ledgers) {
314291
+ if (!isInWindow(ledger, windowStart, windowEnd))
314292
+ continue;
314293
+ diagnostics.deadReserveSum += Math.max(0, ledger.deadReservePx);
314294
+ if (isMandatoryOnlyFootnotePage(ledger, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx)) {
314295
+ diagnostics.mandatoryOnlyCount += 1;
314296
+ const id2 = getLastAnchorId(ledger);
314297
+ if (id2)
314298
+ diagnostics.mandatoryOnlyAnchorIds.add(id2);
314299
+ }
314300
+ const anchorIds = new Set(ledger.anchorIds);
314301
+ let splitsCurrentAnchorCluster = false;
314302
+ for (const entry of ledger.continuationOut) {
314303
+ if (!anchorIds.has(entry.id))
314304
+ continue;
314305
+ diagnostics.clusterSplitAnchorIds.add(entry.id);
314306
+ splitsCurrentAnchorCluster = true;
314307
+ }
314308
+ if (splitsCurrentAnchorCluster)
314309
+ diagnostics.clusterSplitCount += 1;
314310
+ }
314311
+ return diagnostics;
314312
+ }, hasNewId = (after2, before2) => {
314313
+ for (const id2 of after2)
314314
+ if (!before2.has(id2))
314315
+ return true;
314316
+ return false;
314317
+ }, getCandidateRenderedLines = (ledgers, candidateAnchorId) => {
314318
+ if (!candidateAnchorId)
314319
+ return;
314320
+ const anchorLedger = ledgers.find((ledger) => ledger.anchorIds.includes(candidateAnchorId));
314321
+ if (!anchorLedger)
314322
+ return;
314323
+ if (getLastAnchorId(anchorLedger) === candidateAnchorId)
314324
+ return anchorLedger.lastAnchorRenderedLines;
314325
+ return FULL_ANCHOR_RENDER_SENTINEL;
314326
+ }, candidateRenderedLinesImproved = (before2, after2) => typeof before2.candidateRenderedLines === "number" && typeof after2.candidateRenderedLines === "number" && after2.candidateRenderedLines > before2.candidateRenderedLines, summarizeFootnoteWindow = (layout, ledgers, candidatePageIndex, windowAhead = DEFAULT_WINDOW_AHEAD, preferredDeltaThresholdPx = DEFAULT_PREFERRED_DELTA_THRESHOLD_PX, mandatoryOnlyTolerancePx = DEFAULT_MANDATORY_ONLY_TOLERANCE_PX, candidateAnchorId) => {
314327
+ const { windowStart, windowEnd } = getWindowBounds(layout, candidatePageIndex, windowAhead);
314328
+ const diagnostics = collectLedgerDiagnostics(ledgers, windowStart, windowEnd, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx);
314329
+ return {
314330
+ totalPages: layout.pages.length,
314331
+ mandatoryOnlyCount: diagnostics.mandatoryOnlyCount,
314332
+ deadReserveSum: diagnostics.deadReserveSum,
314333
+ clusterSplitCount: diagnostics.clusterSplitCount,
314334
+ candidateRenderedLines: getCandidateRenderedLines(ledgers, candidateAnchorId)
314335
+ };
314336
+ }, scoreFootnoteWindow = (input2) => {
314337
+ const windowAhead = input2.windowAhead ?? DEFAULT_WINDOW_AHEAD;
314338
+ const preferredDeltaThresholdPx = input2.preferredDeltaThresholdPx ?? DEFAULT_PREFERRED_DELTA_THRESHOLD_PX;
314339
+ const mandatoryOnlyTolerancePx = input2.mandatoryOnlyTolerancePx ?? DEFAULT_MANDATORY_ONLY_TOLERANCE_PX;
314340
+ const deadReserveBloatThresholdPx = input2.deadReserveBloatThresholdPx ?? DEFAULT_DEAD_RESERVE_BLOAT_THRESHOLD_PX;
314341
+ const wholeDocumentDeadReserveBloatThresholdPx = input2.wholeDocumentDeadReserveBloatThresholdPx ?? DEFAULT_WHOLE_DOCUMENT_DEAD_RESERVE_BLOAT_THRESHOLD_PX;
314342
+ const beforeCandidateLedger = input2.beforeLedger.find((ledger) => ledger.pageIndex === input2.candidatePageIndex);
314343
+ const candidateAnchorId = input2.candidateAnchorId ?? getLastAnchorId(beforeCandidateLedger);
314344
+ const before2 = summarizeFootnoteWindow(input2.beforeLayout, input2.beforeLedger, input2.candidatePageIndex, windowAhead, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx, candidateAnchorId);
314345
+ const after2 = summarizeFootnoteWindow(input2.afterLayout, input2.afterLedger, input2.candidatePageIndex, windowAhead, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx, candidateAnchorId);
314346
+ const beforeBounds = getWindowBounds(input2.beforeLayout, input2.candidatePageIndex, windowAhead);
314347
+ const afterBounds = getWindowBounds(input2.afterLayout, input2.candidatePageIndex, windowAhead);
314348
+ const beforeWindowDiagnostics = collectLedgerDiagnostics(input2.beforeLedger, beforeBounds.windowStart, beforeBounds.windowEnd, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx);
314349
+ const afterWindowDiagnostics = collectLedgerDiagnostics(input2.afterLedger, afterBounds.windowStart, afterBounds.windowEnd, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx);
314350
+ const beforeDocumentBounds = getDocumentBounds(input2.beforeLayout);
314351
+ const afterDocumentBounds = getDocumentBounds(input2.afterLayout);
314352
+ const beforeDocumentDiagnostics = collectLedgerDiagnostics(input2.beforeLedger, beforeDocumentBounds.windowStart, beforeDocumentBounds.windowEnd, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx);
314353
+ const afterDocumentDiagnostics = collectLedgerDiagnostics(input2.afterLedger, afterDocumentBounds.windowStart, afterDocumentBounds.windowEnd, preferredDeltaThresholdPx, mandatoryOnlyTolerancePx);
314354
+ const eliminatesSplitInWindow = beforeWindowDiagnostics.clusterSplitCount > afterWindowDiagnostics.clusterSplitCount;
314355
+ const eliminatesSplitInDoc = beforeDocumentDiagnostics.clusterSplitCount > afterDocumentDiagnostics.clusterSplitCount;
314356
+ if (after2.totalPages > before2.totalPages) {
314357
+ if (!(after2.totalPages === before2.totalPages + 1 && eliminatesSplitInDoc))
314358
+ return {
314359
+ accept: false,
314360
+ reason: "page-count-grew",
314361
+ before: before2,
314362
+ after: after2
314363
+ };
314364
+ }
314365
+ if (after2.clusterSplitCount > before2.clusterSplitCount || hasNewId(afterWindowDiagnostics.clusterSplitAnchorIds, beforeWindowDiagnostics.clusterSplitAnchorIds))
314366
+ return {
314367
+ accept: false,
314368
+ reason: "cluster-spill",
314369
+ before: before2,
314370
+ after: after2
314371
+ };
314372
+ if (afterDocumentDiagnostics.clusterSplitAnchorIds.size > beforeDocumentDiagnostics.clusterSplitAnchorIds.size || hasNewId(afterDocumentDiagnostics.clusterSplitAnchorIds, beforeDocumentDiagnostics.clusterSplitAnchorIds))
314373
+ return {
314374
+ accept: false,
314375
+ reason: "cluster-spill",
314376
+ before: before2,
314377
+ after: after2
314378
+ };
314379
+ if (hasNewId(afterWindowDiagnostics.mandatoryOnlyAnchorIds, beforeWindowDiagnostics.mandatoryOnlyAnchorIds))
314380
+ return {
314381
+ accept: false,
314382
+ reason: "new-mandatory-only",
314383
+ before: before2,
314384
+ after: after2
314385
+ };
314386
+ if (hasNewId(afterDocumentDiagnostics.mandatoryOnlyAnchorIds, beforeDocumentDiagnostics.mandatoryOnlyAnchorIds))
314387
+ return {
314388
+ accept: false,
314389
+ reason: "new-mandatory-only",
314390
+ before: before2,
314391
+ after: after2
314392
+ };
314393
+ const windowDeadAllowance = eliminatesSplitInWindow ? deadReserveBloatThresholdPx * 2 : deadReserveBloatThresholdPx;
314394
+ const docDeadAllowance = eliminatesSplitInDoc ? wholeDocumentDeadReserveBloatThresholdPx * 2 : wholeDocumentDeadReserveBloatThresholdPx;
314395
+ if (after2.deadReserveSum > before2.deadReserveSum + windowDeadAllowance)
314396
+ return {
314397
+ accept: false,
314398
+ reason: "dead-reserve-bloat",
314399
+ before: before2,
314400
+ after: after2
314401
+ };
314402
+ if (afterDocumentDiagnostics.deadReserveSum > beforeDocumentDiagnostics.deadReserveSum + docDeadAllowance)
314403
+ return {
314404
+ accept: false,
314405
+ reason: "dead-reserve-bloat",
314406
+ before: before2,
314407
+ after: after2
314408
+ };
314409
+ if (!candidateRenderedLinesImproved(before2, after2))
314410
+ return {
314411
+ accept: false,
314412
+ reason: "candidate-not-improved",
314413
+ before: before2,
314414
+ after: after2
314415
+ };
314416
+ return {
314417
+ accept: true,
314418
+ reason: "globally-safe",
314419
+ before: before2,
314420
+ after: after2
314421
+ };
313169
314422
  }, measureCache, headerMeasureCache, headerFooterCacheState, layoutDebugEnabled$1, perfLog$1 = (...args$1) => {
313170
314423
  if (!layoutDebugEnabled$1)
313171
314424
  return;
@@ -313361,6 +314614,9 @@ menclose::after {
313361
314614
  const bottomWithReserve = normalizeMargin(page.margins?.bottom, DEFAULT_MARGINS$1.bottom);
313362
314615
  const baseReserveSafe = Number.isFinite(baseReserve) ? Math.max(0, baseReserve) : 0;
313363
314616
  const bottomMargin = Math.max(0, bottomWithReserve - baseReserveSafe);
314617
+ const bodyMaxY = page.bodyMaxY;
314618
+ if (typeof bodyMaxY === "number" && Number.isFinite(bodyMaxY) && bodyMaxY > topMargin)
314619
+ return Math.max(0, pageSize.h - bottomMargin - bodyMaxY);
313364
314620
  const availableForBody = pageSize.h - topMargin - bottomMargin;
313365
314621
  if (!Number.isFinite(availableForBody))
313366
314622
  return 0;
@@ -313525,14 +314781,17 @@ menclose::after {
313525
314781
  toLine: splitLine,
313526
314782
  height: sumLineHeights$1(measure.lines, range.fromLine, splitLine)
313527
314783
  };
313528
- if (splitLine >= range.toLine)
313529
- return getRangeRenderHeight(fitted) <= availableHeight ? {
313530
- fitted,
313531
- remaining: null
313532
- } : {
314784
+ if (splitLine >= range.toLine) {
314785
+ if (fitted.height <= availableHeight)
314786
+ return {
314787
+ fitted,
314788
+ remaining: null
314789
+ };
314790
+ return {
313533
314791
  fitted: null,
313534
314792
  remaining: range
313535
314793
  };
314794
+ }
313536
314795
  return {
313537
314796
  fitted,
313538
314797
  remaining: {
@@ -313588,9 +314847,14 @@ menclose::after {
313588
314847
  }
313589
314848
  if (range.kind === "paragraph") {
313590
314849
  const split3 = splitRangeAtHeight(range, remainingSpace, measuresById);
313591
- if (split3.fitted && getRangeRenderHeight(split3.fitted) <= remainingSpace) {
313592
- fittedRanges.push(split3.fitted);
313593
- usedHeight += getRangeRenderHeight(split3.fitted);
314850
+ if (split3.fitted) {
314851
+ const fittedBodyHeight = split3.fitted.height;
314852
+ const fittedFullHeight = getRangeRenderHeight(split3.fitted);
314853
+ const charged = !split3.remaining ? fittedBodyHeight : fittedFullHeight;
314854
+ if (charged <= remainingSpace) {
314855
+ fittedRanges.push(split3.fitted);
314856
+ usedHeight += charged;
314857
+ }
313594
314858
  }
313595
314859
  if (split3.remaining)
313596
314860
  remainingRanges = [split3.remaining, ...inputRanges.slice(index2 + 1)];
@@ -319527,13 +320791,13 @@ menclose::after {
319527
320791
  return;
319528
320792
  console.log(...args$1);
319529
320793
  }, 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;
319530
- var init_src_BrZa8lMN_es = __esm(() => {
320794
+ var init_src_iuHADPff_es = __esm(() => {
319531
320795
  init_rolldown_runtime_Bg48TavK_es();
319532
- init_SuperConverter_nmIRMGtB_es();
320796
+ init_SuperConverter_LqX_f8x4_es();
319533
320797
  init_jszip_C49i9kUs_es();
319534
320798
  init_xml_js_CqGKpaft_es();
319535
320799
  init_uuid_qzgm05fK_es();
319536
- init_create_headless_toolbar_7bitVHMJ_es();
320800
+ init_create_headless_toolbar_BOETXxAI_es();
319537
320801
  init_constants_D_X7xF4s_es();
319538
320802
  init_dist_B8HfvhaK_es();
319539
320803
  init_unified_Dsuw2be5_es();
@@ -346534,6 +347798,7 @@ function print() { __p += __j.call(arguments, '') }
346534
347798
  "odd"
346535
347799
  ];
346536
347800
  TWIPS_PER_PX$2 = 1440 / 96;
347801
+ FULL_ANCHOR_RENDER_SENTINEL = Number.MAX_SAFE_INTEGER;
346537
347802
  init_dist4();
346538
347803
  measureCache = new MeasureCache;
346539
347804
  headerMeasureCache = new HeaderFooterLayoutCache;
@@ -347385,6 +348650,10 @@ function print() { __p += __j.call(arguments, '') }
347385
348650
  #flowBlockCache = new FlowBlockCache;
347386
348651
  #footnoteNumberSignature = null;
347387
348652
  #endnoteNumberSignature = null;
348653
+ #warnedUnsupportedRestart = {
348654
+ footnote: false,
348655
+ endnote: false
348656
+ };
347388
348657
  #painterAdapter = new PresentationPainterAdapter;
347389
348658
  #pageGeometryHelper = null;
347390
348659
  #dragDropManager = null;
@@ -347702,6 +348971,12 @@ function print() { __p += __j.call(arguments, '') }
347702
348971
  throw error3;
347703
348972
  }
347704
348973
  }
348974
+ #warnUnsupportedNumberingRestart(kind) {
348975
+ if (this.#warnedUnsupportedRestart[kind])
348976
+ return;
348977
+ this.#warnedUnsupportedRestart[kind] = true;
348978
+ console.warn(`[PresentationEditor] ${kind} numRestart="eachPage" is not yet supported (requires a two-pass pagination handshake). Falling back to "continuous". Tracked for follow-up.`);
348979
+ }
347705
348980
  #wrapOffscreenEditorFocus(editor) {
347706
348981
  const view = editor?.view;
347707
348982
  if (!view || !view.dom || typeof view.focus !== "function")
@@ -350778,58 +352053,84 @@ function print() { __p += __j.call(arguments, '') }
350778
352053
  let converterContext = undefined;
350779
352054
  try {
350780
352055
  const converter$1 = this.#editor.converter;
350781
- const footnoteNumberById = {};
350782
- const footnoteOrder = [];
350783
- try {
350784
- const seen = /* @__PURE__ */ new Set;
350785
- let counter = 1;
350786
- this.#editor?.state?.doc?.descendants?.((node3) => {
350787
- if (node3?.type?.name !== "footnoteReference")
350788
- return;
350789
- const rawId = node3?.attrs?.id;
350790
- if (rawId == null)
350791
- return;
350792
- const key2 = String(rawId);
350793
- if (!key2 || seen.has(key2))
350794
- return;
350795
- seen.add(key2);
350796
- footnoteNumberById[key2] = counter;
350797
- footnoteOrder.push(key2);
350798
- counter += 1;
350799
- });
350800
- } catch (e) {
350801
- if (typeof console !== "undefined" && console.warn)
350802
- console.warn("[PresentationEditor] Failed to compute footnote numbering:", e);
352056
+ let defaultTableStyleId;
352057
+ let footnoteNumberFormat;
352058
+ let endnoteNumberFormat;
352059
+ let footnoteNumberStart = 1;
352060
+ let endnoteNumberStart = 1;
352061
+ let footnoteNumberRestart;
352062
+ let endnoteNumberRestart;
352063
+ let footnotePosition;
352064
+ let endnotePosition;
352065
+ let footnoteSectionConfigs = /* @__PURE__ */ new Map;
352066
+ let endnoteSectionConfigs = /* @__PURE__ */ new Map;
352067
+ if (converter$1) {
352068
+ const settingsRoot = readSettingsRoot(converter$1);
352069
+ if (settingsRoot) {
352070
+ defaultTableStyleId = readDefaultTableStyle(settingsRoot) ?? undefined;
352071
+ footnoteNumberFormat = readFootnoteNumberFormat(settingsRoot) ?? undefined;
352072
+ endnoteNumberFormat = readEndnoteNumberFormat(settingsRoot) ?? undefined;
352073
+ footnoteNumberStart = readFootnoteNumberStart(settingsRoot) ?? 1;
352074
+ endnoteNumberStart = readEndnoteNumberStart(settingsRoot) ?? 1;
352075
+ footnoteNumberRestart = readFootnoteNumberRestart(settingsRoot) ?? undefined;
352076
+ endnoteNumberRestart = readEndnoteNumberRestart(settingsRoot) ?? undefined;
352077
+ footnotePosition = readFootnotePosition(settingsRoot) ?? undefined;
352078
+ endnotePosition = readEndnotePosition(settingsRoot) ?? undefined;
352079
+ }
352080
+ const documentPart = converter$1.convertedXml?.["word/document.xml"];
352081
+ if (documentPart) {
352082
+ footnoteSectionConfigs = readSectionNoteConfigs(documentPart, "w:footnotePr");
352083
+ endnoteSectionConfigs = readSectionNoteConfigs(documentPart, "w:endnotePr");
352084
+ }
350803
352085
  }
350804
- const footnoteSignature = footnoteOrder.join("|");
352086
+ if (footnoteNumberRestart === "eachPage") {
352087
+ this.#warnUnsupportedNumberingRestart("footnote");
352088
+ footnoteNumberRestart = "continuous";
352089
+ }
352090
+ if (endnoteNumberRestart === "eachPage") {
352091
+ this.#warnUnsupportedNumberingRestart("endnote");
352092
+ endnoteNumberRestart = "continuous";
352093
+ }
352094
+ for (const [secIndex, cfg] of footnoteSectionConfigs)
352095
+ if (cfg.numRestart === "eachPage") {
352096
+ footnoteSectionConfigs.set(secIndex, {
352097
+ ...cfg,
352098
+ numRestart: "continuous"
352099
+ });
352100
+ this.#warnUnsupportedNumberingRestart("footnote");
352101
+ }
352102
+ for (const [secIndex, cfg] of endnoteSectionConfigs)
352103
+ if (cfg.numRestart === "eachPage") {
352104
+ endnoteSectionConfigs.set(secIndex, {
352105
+ ...cfg,
352106
+ numRestart: "continuous"
352107
+ });
352108
+ this.#warnUnsupportedNumberingRestart("endnote");
352109
+ }
352110
+ const footnoteNumbering = computeNoteNumbering(this.#editor?.state, "footnoteReference", {
352111
+ startCounter: footnoteNumberStart,
352112
+ defaultNumFmt: footnoteNumberFormat,
352113
+ defaultRestart: footnoteNumberRestart,
352114
+ sectionConfigs: footnoteSectionConfigs
352115
+ });
352116
+ const footnoteNumberById = footnoteNumbering.numberById;
352117
+ const footnoteFormatById = footnoteNumbering.formatById;
352118
+ const footnoteOrder = footnoteNumbering.order;
352119
+ const footnoteSignature = `${footnoteNumberStart}|${footnoteNumberFormat ?? ""}|${footnoteNumberRestart ?? ""}|${serializeSectionConfigs(footnoteSectionConfigs)}|${serializePerIdNumbering(footnoteOrder, footnoteNumberById, footnoteFormatById)}`;
350805
352120
  if (footnoteSignature !== this.#footnoteNumberSignature) {
350806
352121
  this.#flowBlockCache.clear();
350807
352122
  this.#footnoteNumberSignature = footnoteSignature;
350808
352123
  }
350809
- const endnoteNumberById = {};
350810
- const endnoteOrder = [];
350811
- try {
350812
- const seen = /* @__PURE__ */ new Set;
350813
- let counter = 1;
350814
- this.#editor?.state?.doc?.descendants?.((node3) => {
350815
- if (node3?.type?.name !== "endnoteReference")
350816
- return;
350817
- const rawId = node3?.attrs?.id;
350818
- if (rawId == null)
350819
- return;
350820
- const key2 = String(rawId);
350821
- if (!key2 || seen.has(key2))
350822
- return;
350823
- seen.add(key2);
350824
- endnoteNumberById[key2] = counter;
350825
- endnoteOrder.push(key2);
350826
- counter += 1;
350827
- });
350828
- } catch (e) {
350829
- if (typeof console !== "undefined" && console.warn)
350830
- console.warn("[PresentationEditor] Failed to compute endnote numbering:", e);
350831
- }
350832
- const endnoteSignature = endnoteOrder.join("|");
352124
+ const endnoteNumbering = computeNoteNumbering(this.#editor?.state, "endnoteReference", {
352125
+ startCounter: endnoteNumberStart,
352126
+ defaultNumFmt: endnoteNumberFormat,
352127
+ defaultRestart: endnoteNumberRestart,
352128
+ sectionConfigs: endnoteSectionConfigs
352129
+ });
352130
+ const endnoteNumberById = endnoteNumbering.numberById;
352131
+ const endnoteFormatById = endnoteNumbering.formatById;
352132
+ const endnoteOrder = endnoteNumbering.order;
352133
+ const endnoteSignature = `${endnoteNumberStart}|${endnoteNumberFormat ?? ""}|${endnoteNumberRestart ?? ""}|${serializeSectionConfigs(endnoteSectionConfigs)}|${serializePerIdNumbering(endnoteOrder, endnoteNumberById, endnoteFormatById)}`;
350833
352134
  if (endnoteSignature !== this.#endnoteNumberSignature) {
350834
352135
  this.#flowBlockCache.clear();
350835
352136
  this.#endnoteNumberSignature = endnoteSignature;
@@ -350840,16 +352141,16 @@ function print() { __p += __j.call(arguments, '') }
350840
352141
  converter$1["endnoteNumberById"] = endnoteNumberById;
350841
352142
  }
350842
352143
  } catch {}
350843
- let defaultTableStyleId;
350844
- if (converter$1) {
350845
- const settingsRoot = readSettingsRoot(converter$1);
350846
- if (settingsRoot)
350847
- defaultTableStyleId = readDefaultTableStyle(settingsRoot) ?? undefined;
350848
- }
350849
352144
  converterContext = converter$1 ? {
350850
352145
  docx: converter$1.convertedXml,
350851
352146
  ...Object.keys(footnoteNumberById).length ? { footnoteNumberById } : {},
350852
352147
  ...Object.keys(endnoteNumberById).length ? { endnoteNumberById } : {},
352148
+ ...footnoteNumberFormat ? { footnoteNumberFormat } : {},
352149
+ ...endnoteNumberFormat ? { endnoteNumberFormat } : {},
352150
+ ...footnoteFormatById && Object.keys(footnoteFormatById).length ? { footnoteFormatById } : {},
352151
+ ...endnoteFormatById && Object.keys(endnoteFormatById).length ? { endnoteFormatById } : {},
352152
+ ...footnotePosition ? { footnotePosition } : {},
352153
+ ...endnotePosition ? { endnotePosition } : {},
350853
352154
  translatedLinkedStyles: converter$1.translatedLinkedStyles,
350854
352155
  translatedNumbering: converter$1.translatedNumbering,
350855
352156
  ...defaultTableStyleId ? { defaultTableStyleId } : {}
@@ -353699,11 +355000,11 @@ function print() { __p += __j.call(arguments, '') }
353699
355000
  ]);
353700
355001
  });
353701
355002
 
353702
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-DZGOzt3u.es.js
355003
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-jemgYDso.es.js
353703
355004
  var 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;
353704
- var init_create_super_doc_ui_DZGOzt3u_es = __esm(() => {
353705
- init_SuperConverter_nmIRMGtB_es();
353706
- init_create_headless_toolbar_7bitVHMJ_es();
355005
+ var init_create_super_doc_ui_jemgYDso_es = __esm(() => {
355006
+ init_SuperConverter_LqX_f8x4_es();
355007
+ init_create_headless_toolbar_BOETXxAI_es();
353707
355008
  MOD_ALIASES = new Set([
353708
355009
  "Mod",
353709
355010
  "Meta",
@@ -353745,16 +355046,16 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
353745
355046
 
353746
355047
  // ../../packages/superdoc/dist/super-editor.es.js
353747
355048
  var init_super_editor_es = __esm(() => {
353748
- init_src_BrZa8lMN_es();
353749
- init_SuperConverter_nmIRMGtB_es();
355049
+ init_src_iuHADPff_es();
355050
+ init_SuperConverter_LqX_f8x4_es();
353750
355051
  init_jszip_C49i9kUs_es();
353751
355052
  init_xml_js_CqGKpaft_es();
353752
- init_create_headless_toolbar_7bitVHMJ_es();
355053
+ init_create_headless_toolbar_BOETXxAI_es();
353753
355054
  init_constants_D_X7xF4s_es();
353754
355055
  init_dist_B8HfvhaK_es();
353755
355056
  init_unified_Dsuw2be5_es();
353756
355057
  init_DocxZipper_nv_KfOqb_es();
353757
- init_create_super_doc_ui_DZGOzt3u_es();
355058
+ init_create_super_doc_ui_jemgYDso_es();
353758
355059
  init_ui_C5PAS9hY_es();
353759
355060
  init_eventemitter3_BnGqBE_Q_es();
353760
355061
  init_errors_CNaD6vcg_es();