@superdoc-dev/cli 0.2.0-next.73 → 0.2.0-next.75

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 +1034 -501
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -30728,7 +30728,7 @@ var init_remark_gfm_z_sDF4ss_es = __esm(() => {
30728
30728
  emptyOptions2 = {};
30729
30729
  });
30730
30730
 
30731
- // ../../packages/superdoc/dist/chunks/SuperConverter-B3_eOoDQ.es.js
30731
+ // ../../packages/superdoc/dist/chunks/SuperConverter-CDs2fwu4.es.js
30732
30732
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
30733
30733
  const fieldValue = extension$1.config[field];
30734
30734
  if (typeof fieldValue === "function")
@@ -39462,6 +39462,290 @@ function getHTMLFromFragment(fragment, schema, domDocument) {
39462
39462
  container.appendChild(documentFragment);
39463
39463
  return container.innerHTML;
39464
39464
  }
39465
+ function toProtocolSet(values) {
39466
+ const result = /* @__PURE__ */ new Set;
39467
+ if (!values)
39468
+ return result;
39469
+ values.forEach((value) => {
39470
+ if (typeof value === "string" && value.trim())
39471
+ result.add(value.trim().toLowerCase());
39472
+ });
39473
+ return result;
39474
+ }
39475
+ function buildAllowedProtocols$1(config$32 = {}) {
39476
+ const allowed = config$32.allowedProtocols?.length ? toProtocolSet(config$32.allowedProtocols) : new Set(DEFAULT_ALLOWED_PROTOCOLS);
39477
+ const optional = toProtocolSet(config$32.optionalProtocols);
39478
+ if (optional.size > 0)
39479
+ optional.forEach((protocol) => {
39480
+ if (OPTIONAL_PROTOCOLS.includes(protocol))
39481
+ allowed.add(protocol);
39482
+ });
39483
+ return allowed;
39484
+ }
39485
+ function normalizeBlocklist(values) {
39486
+ const hosts = /* @__PURE__ */ new Set;
39487
+ const urls = /* @__PURE__ */ new Set;
39488
+ if (!values)
39489
+ return {
39490
+ hosts,
39491
+ urls
39492
+ };
39493
+ values.forEach((entry) => {
39494
+ if (!entry || typeof entry !== "string")
39495
+ return;
39496
+ const trimmed = entry.trim().toLowerCase();
39497
+ if (!trimmed)
39498
+ return;
39499
+ if (trimmed.includes("://"))
39500
+ urls.add(trimmed);
39501
+ else
39502
+ hosts.add(trimmed);
39503
+ });
39504
+ return {
39505
+ hosts,
39506
+ urls
39507
+ };
39508
+ }
39509
+ function parseAnchorLink(trimmed) {
39510
+ if (!trimmed.startsWith("#"))
39511
+ return null;
39512
+ const anchor = trimmed.slice(1);
39513
+ if (!anchor || !ANCHOR_NAME_PATTERN.test(anchor))
39514
+ return null;
39515
+ return {
39516
+ href: `#${anchor}`,
39517
+ protocol: null,
39518
+ isExternal: false
39519
+ };
39520
+ }
39521
+ function isProtocolAllowed(scheme, allowedProtocols, blockedProtocols) {
39522
+ if (blockedProtocols.includes(scheme))
39523
+ return false;
39524
+ return allowedProtocols.has(scheme);
39525
+ }
39526
+ function isBlockedByRedirectList(normalizedHref, parsed, blocklist) {
39527
+ const { hosts, urls } = blocklist;
39528
+ const hostname2 = parsed.hostname ? parsed.hostname.toLowerCase() : "";
39529
+ if (hosts.size > 0 && hostname2 && hosts.has(hostname2))
39530
+ return true;
39531
+ if (urls.size > 0) {
39532
+ const hrefLower = normalizedHref.toLowerCase();
39533
+ for (const blockedUrl of urls)
39534
+ if (hrefLower.startsWith(blockedUrl))
39535
+ return true;
39536
+ }
39537
+ return false;
39538
+ }
39539
+ function sanitizeHref(raw, config$32 = {}) {
39540
+ if (typeof raw !== "string")
39541
+ return null;
39542
+ const trimmed = raw.trim();
39543
+ if (!trimmed)
39544
+ return null;
39545
+ const maxLength = typeof config$32.maxLength === "number" ? config$32.maxLength : DEFAULT_MAX_LENGTH;
39546
+ if (trimmed.length > maxLength)
39547
+ return null;
39548
+ const anchorResult = parseAnchorLink(trimmed);
39549
+ if (anchorResult !== null)
39550
+ return anchorResult;
39551
+ if (trimmed.startsWith("/") || trimmed.startsWith(".") || trimmed.startsWith("//") || /^www\./i.test(trimmed))
39552
+ return null;
39553
+ const schemeMatch = trimmed.match(/^([a-z0-9+.-]+):/i);
39554
+ if (!schemeMatch)
39555
+ return null;
39556
+ const scheme = schemeMatch[1].toLowerCase();
39557
+ if (!isProtocolAllowed(scheme, buildAllowedProtocols$1(config$32), BLOCKED_PROTOCOLS.concat(config$32.blockedProtocols ?? []).map((p) => p.toLowerCase())))
39558
+ return null;
39559
+ const hostStartIndex = trimmed.indexOf("://") + 3;
39560
+ let hostEndIndex = trimmed.indexOf("/", hostStartIndex);
39561
+ if (hostEndIndex === -1)
39562
+ hostEndIndex = trimmed.indexOf("?", hostStartIndex);
39563
+ if (hostEndIndex === -1)
39564
+ hostEndIndex = trimmed.indexOf("#", hostStartIndex);
39565
+ if (hostEndIndex === -1)
39566
+ hostEndIndex = trimmed.length;
39567
+ const rawHostname = trimmed.slice(hostStartIndex, hostEndIndex).toLowerCase();
39568
+ if (rawHostname && /[^\x00-\x7F]/.test(rawHostname)) {
39569
+ if (process$1.env.NODE_ENV === "development" || process$1.env.DEBUG_HYPERLINKS === "true")
39570
+ console.warn(`[URL Validation] Potential homograph attack detected in hostname: ${rawHostname.slice(0, 50)}`);
39571
+ }
39572
+ const queryStartIndex = trimmed.indexOf("?");
39573
+ if (queryStartIndex !== -1) {
39574
+ const queryString = trimmed.slice(queryStartIndex);
39575
+ if (/[<>"']/.test(queryString))
39576
+ return null;
39577
+ }
39578
+ let parsed;
39579
+ try {
39580
+ parsed = new URL(trimmed);
39581
+ } catch {
39582
+ return null;
39583
+ }
39584
+ const normalizedHref = trimmed;
39585
+ const blocklist = normalizeBlocklist(config$32.redirectBlocklist);
39586
+ if (isBlockedByRedirectList(normalizedHref, parsed, blocklist))
39587
+ return null;
39588
+ return {
39589
+ href: normalizedHref,
39590
+ protocol: scheme,
39591
+ isExternal: scheme === "http" || scheme === "https"
39592
+ };
39593
+ }
39594
+ function encodeTooltip(raw, maxLength = 500) {
39595
+ if (typeof raw !== "string")
39596
+ return null;
39597
+ const trimmed = raw.trim();
39598
+ if (!trimmed)
39599
+ return null;
39600
+ const limit = typeof maxLength === "number" && maxLength > 0 ? maxLength : 0;
39601
+ const wasTruncated = limit > 0 && trimmed.length > limit;
39602
+ return {
39603
+ text: limit > 0 && trimmed.length > limit ? trimmed.slice(0, limit) : trimmed,
39604
+ wasTruncated
39605
+ };
39606
+ }
39607
+ function maybeAddProtocol(text$2) {
39608
+ return /^www\./i.test(text$2) ? `https://${text$2}` : text$2;
39609
+ }
39610
+ function detectPasteUrl(text$2, protocols = []) {
39611
+ const trimmed = text$2?.trim();
39612
+ if (!trimmed)
39613
+ return null;
39614
+ if (/\s/.test(trimmed))
39615
+ return null;
39616
+ const result = sanitizeHref(maybeAddProtocol(trimmed), { allowedProtocols: buildAllowedProtocols(protocols) });
39617
+ return result ? { href: result.href } : null;
39618
+ }
39619
+ function canAllocateRels(editor) {
39620
+ return editor.options.mode === "docx" && !editor.options.isChildEditor && !editor.options.isHeaderOrFooter;
39621
+ }
39622
+ function handlePlainTextUrlPaste(editor, view, plainText, detected) {
39623
+ const { state } = view;
39624
+ const { selection } = state;
39625
+ if (!(selection instanceof TextSelection2))
39626
+ return false;
39627
+ const linkMarkType = editor.schema.marks.link;
39628
+ const underlineMarkType = editor.schema.marks.underline;
39629
+ if (!linkMarkType)
39630
+ return false;
39631
+ const rId = allocateRelationshipId(editor, detected.href);
39632
+ let tr = state.tr;
39633
+ let from = selection.from;
39634
+ let to = selection.to;
39635
+ const trimmedText = plainText.trim();
39636
+ if (selection.empty) {
39637
+ tr = tr.insertText(trimmedText, from);
39638
+ to = from + trimmedText.length;
39639
+ }
39640
+ tr = tr.addMark(from, to, linkMarkType.create({
39641
+ href: detected.href,
39642
+ rId
39643
+ }));
39644
+ if (underlineMarkType)
39645
+ tr = tr.addMark(from, to, underlineMarkType.create());
39646
+ view.dispatch(tr.scrollIntoView());
39647
+ return true;
39648
+ }
39649
+ function getChangedRangesFromTransaction(tr) {
39650
+ const maps = tr.mapping?.maps;
39651
+ if (!maps?.length)
39652
+ return [];
39653
+ const ranges = [];
39654
+ maps.forEach((map2) => {
39655
+ map2.forEach((oldStart, oldEnd, newStart, newEnd) => {
39656
+ ranges.push({
39657
+ from: newStart,
39658
+ to: newEnd
39659
+ });
39660
+ });
39661
+ });
39662
+ return mergeRanges(ranges, tr.doc.content.size);
39663
+ }
39664
+ function normalizePastedLinks(tr, editor, protocols) {
39665
+ const changedRanges = getChangedRangesFromTransaction(tr);
39666
+ if (!changedRanges.length)
39667
+ return;
39668
+ const linkMarkType = editor.schema.marks.link;
39669
+ if (!linkMarkType)
39670
+ return;
39671
+ const allowedProtocols = buildAllowedProtocols(protocols ?? resolveLinkProtocols(editor));
39672
+ for (const { from, to } of changedRanges)
39673
+ normalizeLinkMarksInRange(tr, editor, linkMarkType, from, to, allowedProtocols);
39674
+ }
39675
+ function resolveLinkProtocols(editor) {
39676
+ return editor.extensionService?.extensions?.find((e) => e.name === "link")?.options?.protocols ?? [];
39677
+ }
39678
+ function normalizeLinkMarksInRange(tr, editor, linkMarkType, from, to, allowedProtocols) {
39679
+ const linkSpans = [];
39680
+ tr.doc.nodesBetween(from, to, (node3, pos) => {
39681
+ if (!node3.isInline)
39682
+ return;
39683
+ const linkMark = node3.marks.find((m) => m.type === linkMarkType);
39684
+ if (!linkMark)
39685
+ return;
39686
+ linkSpans.push({
39687
+ from: pos,
39688
+ to: pos + node3.nodeSize,
39689
+ mark: linkMark
39690
+ });
39691
+ });
39692
+ for (let i2 = linkSpans.length - 1;i2 >= 0; i2--)
39693
+ normalizeOneLinkMark(tr, editor, linkMarkType, linkSpans[i2], allowedProtocols);
39694
+ }
39695
+ function normalizeOneLinkMark(tr, editor, linkMarkType, span, allowedProtocols) {
39696
+ const { from, to, mark } = span;
39697
+ const attrs = { ...mark.attrs };
39698
+ attrs.rId = null;
39699
+ const rawHref = attrs.href;
39700
+ const hasInternalRef = Boolean(attrs.anchor) || Boolean(attrs.name);
39701
+ if (!rawHref && hasInternalRef) {
39702
+ tr.removeMark(from, to, linkMarkType);
39703
+ tr.addMark(from, to, linkMarkType.create(attrs));
39704
+ return;
39705
+ }
39706
+ if (!rawHref) {
39707
+ tr.removeMark(from, to, linkMarkType);
39708
+ return;
39709
+ }
39710
+ const sanitized = sanitizeHref(maybeAddProtocol(rawHref), { allowedProtocols });
39711
+ if (!sanitized) {
39712
+ tr.removeMark(from, to, linkMarkType);
39713
+ return;
39714
+ }
39715
+ attrs.href = sanitized.href;
39716
+ if (canAllocateRels(editor))
39717
+ attrs.rId = allocateRelationshipId(editor, sanitized.href);
39718
+ tr.removeMark(from, to, linkMarkType);
39719
+ tr.addMark(from, to, linkMarkType.create(attrs));
39720
+ }
39721
+ function allocateRelationshipId(editor, href) {
39722
+ if (!canAllocateRels(editor))
39723
+ return null;
39724
+ try {
39725
+ const existing = findRelationshipIdFromTarget(href, editor);
39726
+ if (existing)
39727
+ return existing;
39728
+ return insertNewRelationship(href, "hyperlink", editor);
39729
+ } catch {
39730
+ return null;
39731
+ }
39732
+ }
39733
+ function buildAllowedProtocols(extras = []) {
39734
+ const normalized = normalizeProtocols(extras);
39735
+ return Array.from(new Set([...UrlValidationConstants.DEFAULT_ALLOWED_PROTOCOLS, ...normalized]));
39736
+ }
39737
+ function normalizeProtocols(protocols = []) {
39738
+ const result = [];
39739
+ for (const entry of protocols) {
39740
+ if (!entry)
39741
+ continue;
39742
+ if (typeof entry === "string" && entry.trim())
39743
+ result.push(entry.trim().toLowerCase());
39744
+ else if (typeof entry === "object" && typeof entry.scheme === "string" && entry.scheme.trim())
39745
+ result.push(entry.scheme.trim().toLowerCase());
39746
+ }
39747
+ return result;
39748
+ }
39465
39749
  function getStyleTagFromStyleId(styleId, docx) {
39466
39750
  const styles = docx["word/styles.xml"];
39467
39751
  if (!styles)
@@ -40095,12 +40379,19 @@ function handleHtmlPaste(html2, editor, source) {
40095
40379
  const isSingleParagraph = doc$1.childCount === 1 && doc$1.firstChild.type.name === "paragraph";
40096
40380
  if (isInParagraph && isSingleParagraph) {
40097
40381
  const paragraphContent = doc$1.firstChild.content;
40098
- dispatch(state.tr.replaceSelectionWith(paragraphContent, false));
40382
+ const tr = state.tr.replaceSelectionWith(paragraphContent, false);
40383
+ normalizePastedLinks(tr, editor);
40384
+ dispatch(tr);
40099
40385
  } else if (isInParagraph) {
40100
40386
  const slice = new Slice(doc$1.content, 0, 0);
40101
- dispatch(state.tr.replaceSelection(slice));
40102
- } else
40103
- dispatch(state.tr.replaceSelectionWith(doc$1, true));
40387
+ const tr = state.tr.replaceSelection(slice);
40388
+ normalizePastedLinks(tr, editor);
40389
+ dispatch(tr);
40390
+ } else {
40391
+ const tr = state.tr.replaceSelectionWith(doc$1, true);
40392
+ normalizePastedLinks(tr, editor);
40393
+ dispatch(tr);
40394
+ }
40104
40395
  return true;
40105
40396
  }
40106
40397
  function htmlHandler(html2, editor, domDocument) {
@@ -40140,7 +40431,7 @@ function sanitizeHtml(html2, forbiddenTags = [
40140
40431
  walkAndClean(container);
40141
40432
  return container;
40142
40433
  }
40143
- function handleClipboardPaste({ editor, view }, html2) {
40434
+ function handleClipboardPaste({ editor, view }, html2, plainText) {
40144
40435
  let source;
40145
40436
  if (!html2)
40146
40437
  source = "plain-text";
@@ -40151,8 +40442,12 @@ function handleClipboardPaste({ editor, view }, html2) {
40151
40442
  else
40152
40443
  source = "browser-html";
40153
40444
  switch (source) {
40154
- case "plain-text":
40155
- return false;
40445
+ case "plain-text": {
40446
+ const detected = detectPasteUrl(plainText, resolveLinkProtocols(editor));
40447
+ if (!detected)
40448
+ return false;
40449
+ return handlePlainTextUrlPaste(editor, view, plainText, detected);
40450
+ }
40156
40451
  case "word-html":
40157
40452
  if (editor.options.mode === "docx")
40158
40453
  return handleDocxPaste(html2, editor, view);
@@ -56127,6 +56422,165 @@ var isRegExp = (value) => {
56127
56422
  textBefore += node3.isAtom && !node3.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
56128
56423
  });
56129
56424
  return textBefore;
56425
+ }, DEFAULT_ALLOWED_PROTOCOLS, OPTIONAL_PROTOCOLS, BLOCKED_PROTOCOLS, DEFAULT_MAX_LENGTH = 2048, ANCHOR_NAME_PATTERN, UrlValidationConstants, RELATIONSHIP_TYPES, getDocumentRelationshipElements = (editor) => {
56426
+ const docx = editor.converter?.convertedXml;
56427
+ if (!docx)
56428
+ return [];
56429
+ const elements = docx["word/_rels/document.xml.rels"]?.elements;
56430
+ if (!Array.isArray(elements))
56431
+ return [];
56432
+ return elements.find((el) => el.name === "Relationships")?.elements || [];
56433
+ }, getMaxRelationshipIdInt = (relationships) => {
56434
+ const ids = [];
56435
+ relationships.forEach((rel) => {
56436
+ const splitId = rel.attributes.Id.split("rId");
56437
+ const parsedInt = parseInt(splitId[1], 10);
56438
+ if (Number.isInteger(parsedInt))
56439
+ ids.push(parsedInt);
56440
+ });
56441
+ if (ids.length === 0)
56442
+ return 0;
56443
+ return Math.max(...ids);
56444
+ }, findRelationshipIdFromTarget = (target, editor) => {
56445
+ if (!target)
56446
+ return null;
56447
+ if (target.startsWith("word/"))
56448
+ target = target.replace("word/", "");
56449
+ const existingLinkRel = getDocumentRelationshipElements(editor)?.find((rel) => rel.attributes.Target === target);
56450
+ if (existingLinkRel)
56451
+ return existingLinkRel.attributes.Id;
56452
+ }, insertNewRelationship = (target, type, editor) => {
56453
+ if (!target || typeof target !== "string")
56454
+ throw new Error("Target must be a non-empty string");
56455
+ if (!type || typeof type !== "string")
56456
+ throw new Error("Type must be a non-empty string");
56457
+ if (!editor)
56458
+ throw new Error("Editor instance is required");
56459
+ const mappedType = RELATIONSHIP_TYPES[type];
56460
+ if (!mappedType) {
56461
+ console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES).join(", ")}`);
56462
+ return null;
56463
+ }
56464
+ const existingRelId = findRelationshipIdFromTarget(target, editor);
56465
+ if (existingRelId) {
56466
+ console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
56467
+ return existingRelId;
56468
+ }
56469
+ const docx = editor.converter?.convertedXml;
56470
+ if (!docx) {
56471
+ console.error("No converted XML found in editor");
56472
+ return null;
56473
+ }
56474
+ const documentRels = docx["word/_rels/document.xml.rels"];
56475
+ if (!documentRels) {
56476
+ console.error("No document relationships found in the docx");
56477
+ return null;
56478
+ }
56479
+ const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
56480
+ if (!relationshipsTag) {
56481
+ console.error("No Relationships tag found in document relationships");
56482
+ return null;
56483
+ }
56484
+ if (!relationshipsTag.elements)
56485
+ relationshipsTag.elements = [];
56486
+ const newId = getNewRelationshipId(editor);
56487
+ if (!newId) {
56488
+ console.error("Failed to generate new relationship ID");
56489
+ return null;
56490
+ }
56491
+ const newRel = {
56492
+ type: "element",
56493
+ name: "Relationship",
56494
+ attributes: {
56495
+ Id: newId,
56496
+ Type: mappedType,
56497
+ Target: target
56498
+ }
56499
+ };
56500
+ if (type === "hyperlink")
56501
+ newRel.attributes.TargetMode = "External";
56502
+ relationshipsTag.elements.push(newRel);
56503
+ return newId;
56504
+ }, getNewRelationshipId = (editor) => {
56505
+ return `rId${getMaxRelationshipIdInt(getDocumentRelationshipElements(editor)) + 1}`;
56506
+ }, mergeRanges = (ranges, docSize) => {
56507
+ if (!ranges.length)
56508
+ return [];
56509
+ const sorted = ranges.map(({ from, to }) => ({
56510
+ from: Math.max(0, from),
56511
+ to: Math.min(docSize, to)
56512
+ })).filter(({ from, to }) => from < to).sort((a, b) => a.from - b.from);
56513
+ const merged = [];
56514
+ for (const range of sorted) {
56515
+ const last = merged[merged.length - 1];
56516
+ if (last && range.from <= last.to)
56517
+ last.to = Math.max(last.to, range.to);
56518
+ else
56519
+ merged.push({ ...range });
56520
+ }
56521
+ return merged;
56522
+ }, mapRangesThroughTransactions = (ranges, transactions, docSize) => {
56523
+ let mapped = ranges;
56524
+ transactions.forEach((tr) => {
56525
+ mapped = mapped.map(({ from, to }) => {
56526
+ const mappedFrom = tr.mapping.map(from, -1);
56527
+ const mappedTo = tr.mapping.map(to, 1);
56528
+ if (mappedFrom >= mappedTo)
56529
+ return null;
56530
+ return {
56531
+ from: mappedFrom,
56532
+ to: mappedTo
56533
+ };
56534
+ }).filter(Boolean);
56535
+ });
56536
+ return mergeRanges(mapped, docSize);
56537
+ }, collectChangedRangesThroughTransactions = (transactions, docSize, options = {}) => {
56538
+ const ranges = [];
56539
+ const extraRanges = Array.isArray(options.extraRanges) ? options.extraRanges : [];
56540
+ if (extraRanges.length) {
56541
+ const mappedExtras = mapRangesThroughTransactions(extraRanges, transactions, docSize);
56542
+ ranges.push(...mappedExtras);
56543
+ }
56544
+ transactions.forEach((tr, index2) => {
56545
+ if (!tr.docChanged)
56546
+ return;
56547
+ const perTransactionRanges = [];
56548
+ tr.steps.forEach((step$1) => {
56549
+ if (typeof step$1.from !== "number" || typeof step$1.to !== "number")
56550
+ return;
56551
+ const from = tr.mapping.map(step$1.from, 1);
56552
+ const to = tr.mapping.map(step$1.to, -1);
56553
+ if (from >= to)
56554
+ return;
56555
+ perTransactionRanges.push({
56556
+ from,
56557
+ to
56558
+ });
56559
+ });
56560
+ tr.mapping.maps.forEach((map2) => {
56561
+ map2.forEach((oldStart, oldEnd, newStart, newEnd) => {
56562
+ if (newStart !== oldStart || oldEnd !== newEnd)
56563
+ perTransactionRanges.push({
56564
+ from: newStart,
56565
+ to: newEnd
56566
+ });
56567
+ });
56568
+ });
56569
+ if (!perTransactionRanges.length)
56570
+ return;
56571
+ const mapped = mapRangesThroughTransactions(perTransactionRanges, transactions.slice(index2 + 1), docSize);
56572
+ ranges.push(...mapped);
56573
+ });
56574
+ return mergeRanges(ranges, docSize);
56575
+ }, clampRange = (start, end, docSize) => {
56576
+ const safeStart = Math.max(0, Math.min(start, docSize));
56577
+ const safeEnd = Math.max(0, Math.min(end, docSize));
56578
+ if (safeStart >= safeEnd)
56579
+ return null;
56580
+ return {
56581
+ start: safeStart,
56582
+ end: safeEnd
56583
+ };
56130
56584
  }, handleDecimal = (path2, lvlText) => generateNumbering(path2, lvlText, numberToStringFormatter), handleRoman = (path2, lvlText) => generateNumbering(path2, lvlText, intToRoman), handleLowerRoman = (path2, lvlText) => {
56131
56585
  const result = handleRoman(path2, lvlText);
56132
56586
  return result ? result.toLowerCase() : null;
@@ -57216,7 +57670,9 @@ var isRegExp = (value) => {
57216
57670
  const { dispatch } = editor.view;
57217
57671
  if (!dispatch)
57218
57672
  return false;
57219
- dispatch(view.state.tr.replaceSelectionWith(doc$1, true));
57673
+ const tr = view.state.tr.replaceSelectionWith(doc$1, true);
57674
+ normalizePastedLinks(tr, editor);
57675
+ dispatch(tr);
57220
57676
  return true;
57221
57677
  }, wrapTextsInRuns = (doc$1) => {
57222
57678
  const runType = doc$1.type?.schema?.nodes?.run;
@@ -57350,7 +57806,9 @@ var isRegExp = (value) => {
57350
57806
  const { dispatch } = editor.view;
57351
57807
  if (!dispatch)
57352
57808
  return false;
57353
- dispatch(view.state.tr.replaceSelectionWith(doc$1, true));
57809
+ const tr = view.state.tr.replaceSelectionWith(doc$1, true);
57810
+ normalizePastedLinks(tr, editor);
57811
+ dispatch(tr);
57354
57812
  return true;
57355
57813
  }, InputRule = class {
57356
57814
  match;
@@ -57484,13 +57942,15 @@ var isRegExp = (value) => {
57484
57942
  return false;
57485
57943
  },
57486
57944
  handlePaste(view, event, slice) {
57487
- const html2 = event.clipboardData.getData("text/html");
57945
+ const clipboard = event.clipboardData;
57946
+ const html2 = clipboard.getData("text/html");
57947
+ const plainText = clipboard.getData("text/plain");
57488
57948
  if (slice.content.content.filter((item) => item.type.name === "fieldAnnotation").length)
57489
57949
  return false;
57490
57950
  return handleClipboardPaste({
57491
57951
  editor,
57492
57952
  view
57493
- }, html2);
57953
+ }, html2, plainText);
57494
57954
  }
57495
57955
  },
57496
57956
  isInputRules: true
@@ -59948,87 +60408,6 @@ var isRegExp = (value) => {
59948
60408
  const copy$1 = JSON.parse(JSON.stringify(nodes));
59949
60409
  walk(copy$1);
59950
60410
  return copy$1;
59951
- }, RELATIONSHIP_TYPES, getDocumentRelationshipElements = (editor) => {
59952
- const docx = editor.converter?.convertedXml;
59953
- if (!docx)
59954
- return [];
59955
- const elements = docx["word/_rels/document.xml.rels"]?.elements;
59956
- if (!Array.isArray(elements))
59957
- return [];
59958
- return elements.find((el) => el.name === "Relationships")?.elements || [];
59959
- }, getMaxRelationshipIdInt = (relationships) => {
59960
- const ids = [];
59961
- relationships.forEach((rel) => {
59962
- const splitId = rel.attributes.Id.split("rId");
59963
- const parsedInt = parseInt(splitId[1], 10);
59964
- if (Number.isInteger(parsedInt))
59965
- ids.push(parsedInt);
59966
- });
59967
- if (ids.length === 0)
59968
- return 0;
59969
- return Math.max(...ids);
59970
- }, findRelationshipIdFromTarget = (target, editor) => {
59971
- if (!target)
59972
- return null;
59973
- if (target.startsWith("word/"))
59974
- target = target.replace("word/", "");
59975
- const existingLinkRel = getDocumentRelationshipElements(editor)?.find((rel) => rel.attributes.Target === target);
59976
- if (existingLinkRel)
59977
- return existingLinkRel.attributes.Id;
59978
- }, insertNewRelationship = (target, type, editor) => {
59979
- if (!target || typeof target !== "string")
59980
- throw new Error("Target must be a non-empty string");
59981
- if (!type || typeof type !== "string")
59982
- throw new Error("Type must be a non-empty string");
59983
- if (!editor)
59984
- throw new Error("Editor instance is required");
59985
- const mappedType = RELATIONSHIP_TYPES[type];
59986
- if (!mappedType) {
59987
- console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES).join(", ")}`);
59988
- return null;
59989
- }
59990
- const existingRelId = findRelationshipIdFromTarget(target, editor);
59991
- if (existingRelId) {
59992
- console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
59993
- return existingRelId;
59994
- }
59995
- const docx = editor.converter?.convertedXml;
59996
- if (!docx) {
59997
- console.error("No converted XML found in editor");
59998
- return null;
59999
- }
60000
- const documentRels = docx["word/_rels/document.xml.rels"];
60001
- if (!documentRels) {
60002
- console.error("No document relationships found in the docx");
60003
- return null;
60004
- }
60005
- const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
60006
- if (!relationshipsTag) {
60007
- console.error("No Relationships tag found in document relationships");
60008
- return null;
60009
- }
60010
- if (!relationshipsTag.elements)
60011
- relationshipsTag.elements = [];
60012
- const newId = getNewRelationshipId(editor);
60013
- if (!newId) {
60014
- console.error("Failed to generate new relationship ID");
60015
- return null;
60016
- }
60017
- const newRel = {
60018
- type: "element",
60019
- name: "Relationship",
60020
- attributes: {
60021
- Id: newId,
60022
- Type: mappedType,
60023
- Target: target
60024
- }
60025
- };
60026
- if (type === "hyperlink")
60027
- newRel.attributes.TargetMode = "External";
60028
- relationshipsTag.elements.push(newRel);
60029
- return newId;
60030
- }, getNewRelationshipId = (editor) => {
60031
- return `rId${getMaxRelationshipIdInt(getDocumentRelationshipElements(editor)) + 1}`;
60032
60411
  }, DocxHelpers, kebabCase = (str) => str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`), getDefaultStyleDefinition = (defaultStyleId, docx) => {
60033
60412
  const result = {
60034
60413
  lineSpaceBefore: null,
@@ -61165,7 +61544,7 @@ var isRegExp = (value) => {
61165
61544
  state.kern = kernNode.attributes["w:val"];
61166
61545
  }
61167
61546
  }, SuperConverter;
61168
- var init_SuperConverter_B3_eOoDQ_es = __esm(() => {
61547
+ var init_SuperConverter_CDs2fwu4_es = __esm(() => {
61169
61548
  init_rolldown_runtime_B2q5OVn9_es();
61170
61549
  init_jszip_ChlR43oI_es();
61171
61550
  init_xml_js_DLE8mr0n_es();
@@ -72063,6 +72442,39 @@ var init_SuperConverter_B3_eOoDQ_es = __esm(() => {
72063
72442
  SKIP_FIELD_PROCESSING_NODE_NAMES$1 = new Set(["w:drawing", "w:pict"]);
72064
72443
  SKIP_FIELD_PROCESSING_NODE_NAMES = new Set(["w:drawing", "w:pict"]);
72065
72444
  HEADER_FOOTER_FILENAME_PATTERN = /^(header|footer)\d*\.xml$/i;
72445
+ init_dist();
72446
+ DEFAULT_ALLOWED_PROTOCOLS = [
72447
+ "http",
72448
+ "https",
72449
+ "mailto",
72450
+ "tel",
72451
+ "sms"
72452
+ ];
72453
+ OPTIONAL_PROTOCOLS = [
72454
+ "ftp",
72455
+ "sftp",
72456
+ "irc"
72457
+ ];
72458
+ BLOCKED_PROTOCOLS = [
72459
+ "javascript",
72460
+ "data",
72461
+ "vbscript",
72462
+ "file",
72463
+ "ssh",
72464
+ "ws",
72465
+ "wss"
72466
+ ];
72467
+ ANCHOR_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
72468
+ UrlValidationConstants = {
72469
+ DEFAULT_ALLOWED_PROTOCOLS,
72470
+ OPTIONAL_PROTOCOLS,
72471
+ BLOCKED_PROTOCOLS,
72472
+ DEFAULT_MAX_LENGTH
72473
+ };
72474
+ RELATIONSHIP_TYPES = {
72475
+ image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
72476
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
72477
+ };
72066
72478
  listIndexMap = {
72067
72479
  decimal: handleDecimal,
72068
72480
  decimalZero: handleDecimalZero,
@@ -78739,10 +79151,6 @@ var init_SuperConverter_B3_eOoDQ_es = __esm(() => {
78739
79151
  handlerName: "handlePictNode",
78740
79152
  handler: handlePictNode
78741
79153
  };
78742
- RELATIONSHIP_TYPES = {
78743
- image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
78744
- hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
78745
- };
78746
79154
  DocxHelpers = {
78747
79155
  findRelationshipIdFromTarget,
78748
79156
  insertNewRelationship,
@@ -106109,9 +106517,9 @@ var init_remark_gfm_CjV8kaUy_es = __esm(() => {
106109
106517
  init_remark_gfm_z_sDF4ss_es();
106110
106518
  });
106111
106519
 
106112
- // ../../packages/superdoc/dist/chunks/src-D2HZLLOG.es.js
106113
- var exports_src_D2HZLLOG_es = {};
106114
- __export(exports_src_D2HZLLOG_es, {
106520
+ // ../../packages/superdoc/dist/chunks/src-Di9XuGnD.es.js
106521
+ var exports_src_Di9XuGnD_es = {};
106522
+ __export(exports_src_Di9XuGnD_es, {
106115
106523
  zt: () => defineMark,
106116
106524
  z: () => cM,
106117
106525
  yt: () => removeAwarenessStates,
@@ -128792,148 +129200,6 @@ function applyAlphaToSVG$1(svg2, alphaData) {
128792
129200
  function generateGradientId(prefix$2 = "gradient") {
128793
129201
  return `${prefix$2}-${Date.now()}-${gradientIdCounter++}-${Math.random().toString(36).substring(2, 11)}`;
128794
129202
  }
128795
- function toProtocolSet(values) {
128796
- const result = /* @__PURE__ */ new Set;
128797
- if (!values)
128798
- return result;
128799
- values.forEach((value) => {
128800
- if (typeof value === "string" && value.trim())
128801
- result.add(value.trim().toLowerCase());
128802
- });
128803
- return result;
128804
- }
128805
- function buildAllowedProtocols(config2 = {}) {
128806
- const allowed = config2.allowedProtocols?.length ? toProtocolSet(config2.allowedProtocols) : new Set(DEFAULT_ALLOWED_PROTOCOLS);
128807
- const optional = toProtocolSet(config2.optionalProtocols);
128808
- if (optional.size > 0)
128809
- optional.forEach((protocol) => {
128810
- if (OPTIONAL_PROTOCOLS.includes(protocol))
128811
- allowed.add(protocol);
128812
- });
128813
- return allowed;
128814
- }
128815
- function normalizeBlocklist(values) {
128816
- const hosts = /* @__PURE__ */ new Set;
128817
- const urls = /* @__PURE__ */ new Set;
128818
- if (!values)
128819
- return {
128820
- hosts,
128821
- urls
128822
- };
128823
- values.forEach((entry) => {
128824
- if (!entry || typeof entry !== "string")
128825
- return;
128826
- const trimmed = entry.trim().toLowerCase();
128827
- if (!trimmed)
128828
- return;
128829
- if (trimmed.includes("://"))
128830
- urls.add(trimmed);
128831
- else
128832
- hosts.add(trimmed);
128833
- });
128834
- return {
128835
- hosts,
128836
- urls
128837
- };
128838
- }
128839
- function parseAnchorLink(trimmed) {
128840
- if (!trimmed.startsWith("#"))
128841
- return null;
128842
- const anchor = trimmed.slice(1);
128843
- if (!anchor || !ANCHOR_NAME_PATTERN.test(anchor))
128844
- return null;
128845
- return {
128846
- href: `#${anchor}`,
128847
- protocol: null,
128848
- isExternal: false
128849
- };
128850
- }
128851
- function isProtocolAllowed(scheme, allowedProtocols, blockedProtocols) {
128852
- if (blockedProtocols.includes(scheme))
128853
- return false;
128854
- return allowedProtocols.has(scheme);
128855
- }
128856
- function isBlockedByRedirectList(normalizedHref, parsed, blocklist) {
128857
- const { hosts, urls } = blocklist;
128858
- const hostname2 = parsed.hostname ? parsed.hostname.toLowerCase() : "";
128859
- if (hosts.size > 0 && hostname2 && hosts.has(hostname2))
128860
- return true;
128861
- if (urls.size > 0) {
128862
- const hrefLower = normalizedHref.toLowerCase();
128863
- for (const blockedUrl of urls)
128864
- if (hrefLower.startsWith(blockedUrl))
128865
- return true;
128866
- }
128867
- return false;
128868
- }
128869
- function sanitizeHref(raw, config2 = {}) {
128870
- if (typeof raw !== "string")
128871
- return null;
128872
- const trimmed = raw.trim();
128873
- if (!trimmed)
128874
- return null;
128875
- const maxLength = typeof config2.maxLength === "number" ? config2.maxLength : DEFAULT_MAX_LENGTH;
128876
- if (trimmed.length > maxLength)
128877
- return null;
128878
- const anchorResult = parseAnchorLink(trimmed);
128879
- if (anchorResult !== null)
128880
- return anchorResult;
128881
- if (trimmed.startsWith("/") || trimmed.startsWith(".") || trimmed.startsWith("//") || /^www\./i.test(trimmed))
128882
- return null;
128883
- const schemeMatch = trimmed.match(/^([a-z0-9+.-]+):/i);
128884
- if (!schemeMatch)
128885
- return null;
128886
- const scheme = schemeMatch[1].toLowerCase();
128887
- if (!isProtocolAllowed(scheme, buildAllowedProtocols(config2), BLOCKED_PROTOCOLS.concat(config2.blockedProtocols ?? []).map((p$12) => p$12.toLowerCase())))
128888
- return null;
128889
- const hostStartIndex = trimmed.indexOf("://") + 3;
128890
- let hostEndIndex = trimmed.indexOf("/", hostStartIndex);
128891
- if (hostEndIndex === -1)
128892
- hostEndIndex = trimmed.indexOf("?", hostStartIndex);
128893
- if (hostEndIndex === -1)
128894
- hostEndIndex = trimmed.indexOf("#", hostStartIndex);
128895
- if (hostEndIndex === -1)
128896
- hostEndIndex = trimmed.length;
128897
- const rawHostname = trimmed.slice(hostStartIndex, hostEndIndex).toLowerCase();
128898
- if (rawHostname && /[^\x00-\x7F]/.test(rawHostname)) {
128899
- if (process$1.env.NODE_ENV === "development" || process$1.env.DEBUG_HYPERLINKS === "true")
128900
- console.warn(`[URL Validation] Potential homograph attack detected in hostname: ${rawHostname.slice(0, 50)}`);
128901
- }
128902
- const queryStartIndex = trimmed.indexOf("?");
128903
- if (queryStartIndex !== -1) {
128904
- const queryString = trimmed.slice(queryStartIndex);
128905
- if (/[<>"']/.test(queryString))
128906
- return null;
128907
- }
128908
- let parsed;
128909
- try {
128910
- parsed = new URL(trimmed);
128911
- } catch {
128912
- return null;
128913
- }
128914
- const normalizedHref = trimmed;
128915
- const blocklist = normalizeBlocklist(config2.redirectBlocklist);
128916
- if (isBlockedByRedirectList(normalizedHref, parsed, blocklist))
128917
- return null;
128918
- return {
128919
- href: normalizedHref,
128920
- protocol: scheme,
128921
- isExternal: scheme === "http" || scheme === "https"
128922
- };
128923
- }
128924
- function encodeTooltip(raw, maxLength = 500) {
128925
- if (typeof raw !== "string")
128926
- return null;
128927
- const trimmed = raw.trim();
128928
- if (!trimmed)
128929
- return null;
128930
- const limit = typeof maxLength === "number" && maxLength > 0 ? maxLength : 0;
128931
- const wasTruncated = limit > 0 && trimmed.length > limit;
128932
- return {
128933
- text: limit > 0 && trimmed.length > limit ? trimmed.slice(0, limit) : trimmed,
128934
- wasTruncated
128935
- };
128936
- }
128937
129203
  function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
128938
129204
  const marker = wordLayout?.marker;
128939
129205
  if (!marker)
@@ -140260,6 +140526,11 @@ function invalidateHeaderFooterCache(cache$3, cacheState, headerBlocks, footerBl
140260
140526
  }
140261
140527
  }
140262
140528
  async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, options, measureBlock$1, headerFooter, previousMeasures) {
140529
+ const isSemanticFlow = options.flowMode === "semantic";
140530
+ if (isSemanticFlow) {
140531
+ headerFooter = undefined;
140532
+ nextBlocks = rewriteSectionBreaksForSemanticFlow(nextBlocks, options);
140533
+ }
140263
140534
  const dirtyStart = performance.now();
140264
140535
  const dirty = computeDirtyRegions(previousBlocks, nextBlocks);
140265
140536
  performance.now() - dirtyStart;
@@ -140270,7 +140541,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
140270
140541
  if (measurementWidth <= 0 || measurementHeight <= 0)
140271
140542
  throw new Error("incrementalLayout: invalid measurement constraints resolved from options");
140272
140543
  const hasPreviousMeasures = Array.isArray(previousMeasures) && previousMeasures.length === previousBlocks.length;
140273
- const previousConstraints = hasPreviousMeasures ? resolveMeasurementConstraints(options, previousBlocks) : null;
140544
+ const previousConstraints = hasPreviousMeasures && !isSemanticFlow ? resolveMeasurementConstraints(options, previousBlocks) : null;
140274
140545
  const canReusePreviousMeasures = hasPreviousMeasures && previousConstraints?.measurementWidth === measurementWidth && previousConstraints?.measurementHeight === measurementHeight;
140275
140546
  const previousPerSectionConstraints = canReusePreviousMeasures ? computePerSectionConstraints(options, previousBlocks) : null;
140276
140547
  const previousMeasuresById = canReusePreviousMeasures ? new Map(previousBlocks.map((block, index2) => [block.id, previousMeasures[index2]])) : null;
@@ -140440,7 +140711,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
140440
140711
  let totalRemeasureTime = 0;
140441
140712
  let totalRelayoutTime = 0;
140442
140713
  let converged = true;
140443
- if (FeatureFlags.BODY_PAGE_TOKENS) {
140714
+ if (!isSemanticFlow && FeatureFlags.BODY_PAGE_TOKENS) {
140444
140715
  while (iteration < maxIterations) {
140445
140716
  const sections = options.sectionMetadata ?? [];
140446
140717
  const numberingCtx = buildNumberingContext(layout, sections);
@@ -140504,7 +140775,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
140504
140775
  let extraBlocks;
140505
140776
  let extraMeasures;
140506
140777
  const footnotesInput = isFootnotesLayoutInput(options.footnotes) ? options.footnotes : null;
140507
- if (footnotesInput && footnotesInput.refs.length > 0 && footnotesInput.blocksById.size > 0) {
140778
+ if (!isSemanticFlow && footnotesInput && footnotesInput.refs.length > 0 && footnotesInput.blocksById.size > 0) {
140508
140779
  const gap = typeof footnotesInput.gap === "number" && Number.isFinite(footnotesInput.gap) ? footnotesInput.gap : 2;
140509
140780
  const topPadding = typeof footnotesInput.topPadding === "number" && Number.isFinite(footnotesInput.topPadding) ? footnotesInput.topPadding : 6;
140510
140781
  const dividerHeight = typeof footnotesInput.dividerHeight === "number" && Number.isFinite(footnotesInput.dividerHeight) ? footnotesInput.dividerHeight : 6;
@@ -141037,6 +141308,37 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
141037
141308
  extraMeasures
141038
141309
  };
141039
141310
  }
141311
+ function rewriteSectionBreaksForSemanticFlow(blocks2, options) {
141312
+ const semanticPageSize = options.pageSize;
141313
+ const semanticMargins = options.margins;
141314
+ if (!semanticPageSize)
141315
+ return blocks2;
141316
+ if (!blocks2.some((b$1) => b$1.kind === "sectionBreak"))
141317
+ return blocks2;
141318
+ return blocks2.map((block) => {
141319
+ if (block.kind !== "sectionBreak")
141320
+ return block;
141321
+ const sb = block;
141322
+ return {
141323
+ ...sb,
141324
+ pageSize: {
141325
+ w: semanticPageSize.w,
141326
+ h: semanticPageSize.h
141327
+ },
141328
+ margins: {
141329
+ ...sb.margins,
141330
+ top: semanticMargins?.top,
141331
+ right: semanticMargins?.right,
141332
+ bottom: semanticMargins?.bottom,
141333
+ left: semanticMargins?.left
141334
+ },
141335
+ columns: {
141336
+ count: 1,
141337
+ gap: 0
141338
+ }
141339
+ };
141340
+ });
141341
+ }
141040
141342
  function computePerSectionConstraints(options, blocks2) {
141041
141343
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
141042
141344
  const defaultMargins = {
@@ -141080,6 +141382,18 @@ function computePerSectionConstraints(options, blocks2) {
141080
141382
  return result;
141081
141383
  }
141082
141384
  function resolveMeasurementConstraints(options, blocks2) {
141385
+ if (options.flowMode === "semantic") {
141386
+ const semanticContentWidth = options.semantic?.contentWidth;
141387
+ if (typeof semanticContentWidth === "number" && Number.isFinite(semanticContentWidth) && semanticContentWidth > 0) {
141388
+ const semanticTop = normalizeMargin(options.semantic?.marginTop, normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top));
141389
+ const semanticBottom = normalizeMargin(options.semantic?.marginBottom, normalizeMargin(options.margins?.bottom, DEFAULT_MARGINS$1.bottom));
141390
+ const measurementHeight$1 = Math.max(1, SEMANTIC_PAGE_HEIGHT_PX - (semanticTop + semanticBottom));
141391
+ return {
141392
+ measurementWidth: Math.max(1, Math.floor(semanticContentWidth)),
141393
+ measurementHeight: measurementHeight$1
141394
+ };
141395
+ }
141396
+ }
141083
141397
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
141084
141398
  const margins = {
141085
141399
  top: normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top),
@@ -142494,8 +142808,11 @@ function hitTestTable(layout, blocks2, measures, normalizedX, normalizedY, confi
142494
142808
  };
142495
142809
  return hitTestTableFragment(pageHit, blocks2, measures, point5);
142496
142810
  }
142811
+ function isSemanticFootnoteBlockId(blockId) {
142812
+ return typeof blockId === "string" && blockId.startsWith("__sd_semantic_footnote");
142813
+ }
142497
142814
  function isFootnoteBlockId(blockId) {
142498
- return typeof blockId === "string" && blockId.startsWith("footnote-");
142815
+ return typeof blockId === "string" && (blockId.startsWith("footnote-") || isSemanticFootnoteBlockId(blockId));
142499
142816
  }
142500
142817
  function isInRegisteredSurface(event) {
142501
142818
  const path2 = typeof event.composedPath === "function" ? event.composedPath() : [];
@@ -143771,6 +144088,90 @@ async function layoutWithPerSectionConstraints(kind, blocksByRId, sectionMetadat
143771
144088
  }
143772
144089
  }
143773
144090
  }
144091
+ function buildSemanticFootnoteBlocks(input2, footnotesMode) {
144092
+ if (!input2 || input2.refs.length === 0 || input2.blocksById.size === 0)
144093
+ return [];
144094
+ if ((footnotesMode ?? "endOfDocument") !== "endOfDocument")
144095
+ return [];
144096
+ const orderedFootnoteIds = [];
144097
+ const seen = /* @__PURE__ */ new Set;
144098
+ input2.refs.forEach((ref$1) => {
144099
+ if (!ref$1?.id || seen.has(ref$1.id))
144100
+ return;
144101
+ seen.add(ref$1.id);
144102
+ orderedFootnoteIds.push(ref$1.id);
144103
+ });
144104
+ if (orderedFootnoteIds.length === 0)
144105
+ return [];
144106
+ const result = [createSemanticFootnoteHeadingBlock(resolveSemanticFootnoteHeadingRunStyle(input2.blocksById, orderedFootnoteIds))];
144107
+ orderedFootnoteIds.forEach((id2, footnoteIndex) => {
144108
+ (input2.blocksById.get(id2) ?? []).forEach((block, blockIndex) => {
144109
+ result.push(cloneFlowBlockForSemanticFootnote(block, id2, footnoteIndex, blockIndex));
144110
+ });
144111
+ });
144112
+ return result;
144113
+ }
144114
+ function resolveSemanticFootnoteHeadingRunStyle(blocksById, orderedFootnoteIds) {
144115
+ for (const footnoteId of orderedFootnoteIds) {
144116
+ const blocks2 = blocksById.get(footnoteId) ?? [];
144117
+ for (const block of blocks2) {
144118
+ if (block.kind !== "paragraph")
144119
+ continue;
144120
+ for (const run2 of block.runs) {
144121
+ const fontFamily$1 = run2.fontFamily;
144122
+ const fontSize$1 = run2.fontSize;
144123
+ if (typeof fontFamily$1 === "string" && fontFamily$1.length > 0 && typeof fontSize$1 === "number") {
144124
+ if (Number.isFinite(fontSize$1) && fontSize$1 > 0)
144125
+ return {
144126
+ fontFamily: fontFamily$1,
144127
+ fontSize: fontSize$1
144128
+ };
144129
+ }
144130
+ }
144131
+ }
144132
+ }
144133
+ return {
144134
+ fontFamily: DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE.fontFamily,
144135
+ fontSize: DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE.fontSize
144136
+ };
144137
+ }
144138
+ function createSemanticFootnoteHeadingBlock(style$1) {
144139
+ return {
144140
+ kind: "paragraph",
144141
+ id: SEMANTIC_FOOTNOTES_HEADING_BLOCK_ID,
144142
+ attrs: { spacing: DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE.spacing },
144143
+ runs: [{
144144
+ kind: "text",
144145
+ text: "Footnotes",
144146
+ fontFamily: style$1.fontFamily,
144147
+ fontSize: style$1.fontSize,
144148
+ bold: DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE.bold
144149
+ }]
144150
+ };
144151
+ }
144152
+ function cloneFlowBlock(block) {
144153
+ return JSON.parse(JSON.stringify(block));
144154
+ }
144155
+ function stripPmRangesDeep(value) {
144156
+ if (Array.isArray(value)) {
144157
+ value.forEach((item) => stripPmRangesDeep(item));
144158
+ return;
144159
+ }
144160
+ if (!value || typeof value !== "object")
144161
+ return;
144162
+ const record = value;
144163
+ if ("pmStart" in record)
144164
+ delete record.pmStart;
144165
+ if ("pmEnd" in record)
144166
+ delete record.pmEnd;
144167
+ Object.values(record).forEach((nested) => stripPmRangesDeep(nested));
144168
+ }
144169
+ function cloneFlowBlockForSemanticFootnote(block, footnoteId, footnoteIndex, blockIndex) {
144170
+ const cloned = cloneFlowBlock(block);
144171
+ stripPmRangesDeep(cloned);
144172
+ cloned.id = `${SEMANTIC_FOOTNOTE_BLOCK_ID_PREFIX}-${footnoteId}-${footnoteIndex}-${blockIndex}-${block.id}`;
144173
+ return cloned;
144174
+ }
143774
144175
  function getBoundaries(ranges) {
143775
144176
  const set = /* @__PURE__ */ new Set;
143776
144177
  for (const r$1 of ranges) {
@@ -146159,7 +146560,7 @@ function createCascadeToggleCommands({ markName, setCommand, unsetCommand, toggl
146159
146560
  [toggleName]: () => ({ commands: commands$1 }) => commands$1.toggleMarkCascade(markName, cascadeOptions)
146160
146561
  };
146161
146562
  }
146162
- function normalizeProtocols(protocols = []) {
146563
+ function normalizeProtocols2(protocols = []) {
146163
146564
  const result = [];
146164
146565
  protocols.forEach((protocol) => {
146165
146566
  if (!protocol)
@@ -146174,7 +146575,7 @@ function normalizeProtocols(protocols = []) {
146174
146575
  function sanitizeLinkHref(href, protocols) {
146175
146576
  if (!href)
146176
146577
  return null;
146177
- const normalizedProtocols = Array.isArray(protocols) ? normalizeProtocols(protocols) : [];
146578
+ const normalizedProtocols = Array.isArray(protocols) ? normalizeProtocols2(protocols) : [];
146178
146579
  return sanitizeHref(href, { allowedProtocols: Array.from(new Set([...UrlValidationConstants.DEFAULT_ALLOWED_PROTOCOLS, ...normalizedProtocols])) });
146179
146580
  }
146180
146581
  function addLinkRelationship({ editor, href }) {
@@ -152869,10 +153270,10 @@ function getItems(context, customItems = [], includeDefaultItems = true) {
152869
153270
  if (typeof SelectionType.create === "function")
152870
153271
  view.dispatch(tr.setSelection(SelectionType.create(doc$2, safeFrom, safeTo)));
152871
153272
  }
152872
- if (!(html3 ? handleClipboardPaste({
153273
+ if (!handleClipboardPaste({
152873
153274
  editor: editor$1,
152874
153275
  view
152875
- }, html3) : false)) {
153276
+ }, html3, text5)) {
152876
153277
  const pasteEvent = createPasteEventShim({
152877
153278
  html: html3,
152878
153279
  text: text5
@@ -157174,84 +157575,6 @@ var Node$13 = class Node$14 {
157174
157575
  }
157175
157576
  return state;
157176
157577
  }
157177
- }, mergeRanges = (ranges, docSize) => {
157178
- if (!ranges.length)
157179
- return [];
157180
- const sorted = ranges.map(({ from: from$12, to }) => ({
157181
- from: Math.max(0, from$12),
157182
- to: Math.min(docSize, to)
157183
- })).filter(({ from: from$12, to }) => from$12 < to).sort((a2, b$1) => a2.from - b$1.from);
157184
- const merged = [];
157185
- for (const range of sorted) {
157186
- const last2 = merged[merged.length - 1];
157187
- if (last2 && range.from <= last2.to)
157188
- last2.to = Math.max(last2.to, range.to);
157189
- else
157190
- merged.push({ ...range });
157191
- }
157192
- return merged;
157193
- }, mapRangesThroughTransactions = (ranges, transactions, docSize) => {
157194
- let mapped = ranges;
157195
- transactions.forEach((tr) => {
157196
- mapped = mapped.map(({ from: from$12, to }) => {
157197
- const mappedFrom = tr.mapping.map(from$12, -1);
157198
- const mappedTo = tr.mapping.map(to, 1);
157199
- if (mappedFrom >= mappedTo)
157200
- return null;
157201
- return {
157202
- from: mappedFrom,
157203
- to: mappedTo
157204
- };
157205
- }).filter(Boolean);
157206
- });
157207
- return mergeRanges(mapped, docSize);
157208
- }, collectChangedRangesThroughTransactions = (transactions, docSize, options = {}) => {
157209
- const ranges = [];
157210
- const extraRanges = Array.isArray(options.extraRanges) ? options.extraRanges : [];
157211
- if (extraRanges.length) {
157212
- const mappedExtras = mapRangesThroughTransactions(extraRanges, transactions, docSize);
157213
- ranges.push(...mappedExtras);
157214
- }
157215
- transactions.forEach((tr, index2) => {
157216
- if (!tr.docChanged)
157217
- return;
157218
- const perTransactionRanges = [];
157219
- tr.steps.forEach((step3) => {
157220
- if (typeof step3.from !== "number" || typeof step3.to !== "number")
157221
- return;
157222
- const from$12 = tr.mapping.map(step3.from, 1);
157223
- const to = tr.mapping.map(step3.to, -1);
157224
- if (from$12 >= to)
157225
- return;
157226
- perTransactionRanges.push({
157227
- from: from$12,
157228
- to
157229
- });
157230
- });
157231
- tr.mapping.maps.forEach((map$22) => {
157232
- map$22.forEach((oldStart, oldEnd, newStart, newEnd) => {
157233
- if (newStart !== oldStart || oldEnd !== newEnd)
157234
- perTransactionRanges.push({
157235
- from: newStart,
157236
- to: newEnd
157237
- });
157238
- });
157239
- });
157240
- if (!perTransactionRanges.length)
157241
- return;
157242
- const mapped = mapRangesThroughTransactions(perTransactionRanges, transactions.slice(index2 + 1), docSize);
157243
- ranges.push(...mapped);
157244
- });
157245
- return mergeRanges(ranges, docSize);
157246
- }, clampRange = (start$1, end$1, docSize) => {
157247
- const safeStart = Math.max(0, Math.min(start$1, docSize));
157248
- const safeEnd = Math.max(0, Math.min(end$1, docSize));
157249
- if (safeStart >= safeEnd)
157250
- return null;
157251
- return {
157252
- start: safeStart,
157253
- end: safeEnd
157254
- };
157255
157578
  }, RUN_PROPERTIES_DERIVED_FROM_MARKS, RUN_PROPERTY_PRESERVE_META_KEY = "sdPreserveRunPropertiesKeys", calculateInlineRunPropertiesPlugin = (editor) => new Plugin({ appendTransaction(transactions, _oldState, newState) {
157256
157579
  const tr = newState.tr;
157257
157580
  if (!transactions.some((t) => t.docChanged))
@@ -164457,7 +164780,7 @@ var Node$13 = class Node$14 {
164457
164780
  styleEl.textContent = NATIVE_SELECTION_STYLES;
164458
164781
  doc$2.head?.appendChild(styleEl);
164459
164782
  nativeSelectionStylesInjected = true;
164460
- }, DEFAULT_ALLOWED_PROTOCOLS, OPTIONAL_PROTOCOLS, BLOCKED_PROTOCOLS, DEFAULT_MAX_LENGTH = 2048, ANCHOR_NAME_PATTERN, UrlValidationConstants, EMUS_PER_INCH = 914400, FONT_FAMILY_FALLBACKS2, DEFAULT_GENERIC_FALLBACK2 = "sans-serif", normalizeParts = (value) => (value || "").split(",").map((part) => part.trim()).filter(Boolean), splitOutsideQuotes = (str, delimiter) => {
164783
+ }, EMUS_PER_INCH = 914400, FONT_FAMILY_FALLBACKS2, DEFAULT_GENERIC_FALLBACK2 = "sans-serif", normalizeParts = (value) => (value || "").split(",").map((part) => part.trim()).filter(Boolean), splitOutsideQuotes = (str, delimiter) => {
164461
164784
  if (!str.includes('"') && !str.includes("'"))
164462
164785
  return str.split(delimiter).map((p$12) => p$12.trim()).filter(Boolean);
164463
164786
  const parts = [];
@@ -164822,7 +165145,7 @@ var Node$13 = class Node$14 {
164822
165145
  if (!Number.isFinite(value) || value < 0)
164823
165146
  return 0;
164824
165147
  return value;
164825
- }, COLUMN_MIN_WIDTH_PX = 25, COLUMN_MAX_WIDTH_PX = 200, ROW_MIN_HEIGHT_PX = 10, MIN_PARTIAL_ROW_HEIGHT = 20, ROW_HEIGHT_EPSILON = 0.1, DEFAULT_BALANCING_CONFIG, DEFAULT_PARAGRAPH_LINE_HEIGHT_PX = 20, DEFAULT_PAGE_SIZE$2, DEFAULT_MARGINS$2, COLUMN_EPSILON$1 = 0.0001, asBoolean = (value) => {
165148
+ }, COLUMN_MIN_WIDTH_PX = 25, COLUMN_MAX_WIDTH_PX = 200, ROW_MIN_HEIGHT_PX = 10, MIN_PARTIAL_ROW_HEIGHT = 20, ROW_HEIGHT_EPSILON = 0.1, DEFAULT_BALANCING_CONFIG, DEFAULT_PARAGRAPH_LINE_HEIGHT_PX = 20, SEMANTIC_PAGE_HEIGHT_PX = 1e6, DEFAULT_PAGE_SIZE$2, DEFAULT_MARGINS$2, COLUMN_EPSILON$1 = 0.0001, asBoolean = (value) => {
164826
165149
  if (value === true || value === 1)
164827
165150
  return true;
164828
165151
  if (typeof value === "string") {
@@ -166921,6 +167244,7 @@ var Node$13 = class Node$14 {
166921
167244
  const painter = new DomPainter(options.blocks, options.measures, {
166922
167245
  pageStyles: options.pageStyles,
166923
167246
  layoutMode: options.layoutMode,
167247
+ flowMode: options.flowMode,
166924
167248
  pageGap: options.pageGap,
166925
167249
  headerProvider: options.headerProvider,
166926
167250
  footerProvider: options.footerProvider,
@@ -171711,7 +172035,7 @@ var Node$13 = class Node$14 {
171711
172035
  this.#onCursorsUpdate = null;
171712
172036
  this.#isSetup = false;
171713
172037
  }
171714
- }, WORD_CHARACTER_REGEX, MULTI_CLICK_TIME_THRESHOLD_MS = 400, MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5, AUTO_SCROLL_EDGE_PX = 32, AUTO_SCROLL_MAX_SPEED_PX = 24, SCROLL_DETECTION_TOLERANCE_PX = 1, clamp = (value, min$2, max$2) => Math.max(min$2, Math.min(max$2, value)), EditorInputManager = class {
172038
+ }, WORD_CHARACTER_REGEX, SEMANTIC_FOOTNOTES_HEADING_BLOCK_ID = "__sd_semantic_footnotes_heading", SEMANTIC_FOOTNOTE_BLOCK_ID_PREFIX = "__sd_semantic_footnote", MULTI_CLICK_TIME_THRESHOLD_MS = 400, MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5, AUTO_SCROLL_EDGE_PX = 32, AUTO_SCROLL_MAX_SPEED_PX = 24, SCROLL_DETECTION_TOLERANCE_PX = 1, clamp = (value, min$2, max$2) => Math.max(min$2, Math.min(max$2, value)), EditorInputManager = class {
171715
172039
  #deps = null;
171716
172040
  #callbacks = {};
171717
172041
  #isDragging = false;
@@ -175471,11 +175795,11 @@ var Node$13 = class Node$14 {
175471
175795
  this.#hoverRegion = null;
175472
175796
  this.#overlayManager = null;
175473
175797
  }
175474
- }, SUBSCRIPT_SUPERSCRIPT_SCALE2 = 0.65, DEFAULT_PAGE_SIZE, DEFAULT_MARGINS, DEFAULT_PAGE_GAP = 24, DEFAULT_HORIZONTAL_PAGE_GAP = 20, layoutDebugEnabled, perfLog = (...args$1) => {
175798
+ }, DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE, SUBSCRIPT_SUPERSCRIPT_SCALE2 = 0.65, DEFAULT_PAGE_SIZE, DEFAULT_MARGINS, DEFAULT_PAGE_GAP = 24, DEFAULT_HORIZONTAL_PAGE_GAP = 20, layoutDebugEnabled, perfLog = (...args$1) => {
175475
175799
  if (!layoutDebugEnabled)
175476
175800
  return;
175477
175801
  console.log(...args$1);
175478
- }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, GLOBAL_PERFORMANCE, PresentationEditor, Color, FontFamily, FontSize, TextAlign, FormatCommands, DropCursorView = class {
175802
+ }, 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, Color, FontFamily, FontSize, TextAlign, FormatCommands, DropCursorView = class {
175479
175803
  constructor(editorView, options) {
175480
175804
  var _a;
175481
175805
  this.editorView = editorView;
@@ -180788,9 +181112,9 @@ var Node$13 = class Node$14 {
180788
181112
  trackedChanges: context.trackedChanges ?? []
180789
181113
  });
180790
181114
  }, _hoisted_1$6, _hoisted_2$2, _hoisted_3, _hoisted_4, ContextMenu_default, _hoisted_1$5, BasicUpload_default, _hoisted_1$4, MIN_WIDTH = 200, PPI = 96, alignment = "flex-end", Ruler_default, GenericPopover_default, _hoisted_1$3, _hoisted_2$1, RESIZE_HANDLE_WIDTH_PX = 9, RESIZE_HANDLE_HEIGHT_PX = 9, RESIZE_HANDLE_OFFSET_PX = 4, DRAG_OVERLAY_EXTENSION_PX = 1000, MIN_DRAG_OVERLAY_WIDTH_PX = 2000, THROTTLE_INTERVAL_MS = 16, MIN_RESIZE_DELTA_PX = 1, TableResizeOverlay_default, _hoisted_1$2, OVERLAY_EXPANSION_PX = 2000, RESIZE_HANDLE_SIZE_PX = 12, MOUSE_MOVE_THROTTLE_MS = 16, DIMENSION_CHANGE_THRESHOLD_PX = 1, Z_INDEX_OVERLAY = 10, Z_INDEX_HANDLE = 15, Z_INDEX_GUIDELINE = 20, ImageResizeOverlay_default, LINK_CLICK_DEBOUNCE_MS = 300, CURSOR_UPDATE_TIMEOUT_MS = 10, POPOVER_VERTICAL_OFFSET_PX = 15, LinkClickHandler_default, _hoisted_1$1, _hoisted_2, DOCX2 = "application/vnd.openxmlformats-officedocument.wordprocessingml.document", TABLE_RESIZE_HOVER_THRESHOLD = 8, TABLE_RESIZE_THROTTLE_MS = 16, SuperEditor_default, _hoisted_1, SuperInput_default, SlashMenu, Extensions;
180791
- var init_src_D2HZLLOG_es = __esm(() => {
181115
+ var init_src_Di9XuGnD_es = __esm(() => {
180792
181116
  init_rolldown_runtime_B2q5OVn9_es();
180793
- init_SuperConverter_B3_eOoDQ_es();
181117
+ init_SuperConverter_CDs2fwu4_es();
180794
181118
  init_jszip_ChlR43oI_es();
180795
181119
  init_uuid_2IzDu5nl_es();
180796
181120
  init_constants_CqvgVEDh_es();
@@ -194547,35 +194871,6 @@ function print() { __p += __j.call(arguments, '') }
194547
194871
  outline-offset: 2px;
194548
194872
  }
194549
194873
  `;
194550
- init_dist();
194551
- DEFAULT_ALLOWED_PROTOCOLS = [
194552
- "http",
194553
- "https",
194554
- "mailto",
194555
- "tel",
194556
- "sms"
194557
- ];
194558
- OPTIONAL_PROTOCOLS = [
194559
- "ftp",
194560
- "sftp",
194561
- "irc"
194562
- ];
194563
- BLOCKED_PROTOCOLS = [
194564
- "javascript",
194565
- "data",
194566
- "vbscript",
194567
- "file",
194568
- "ssh",
194569
- "ws",
194570
- "wss"
194571
- ];
194572
- ANCHOR_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
194573
- UrlValidationConstants = {
194574
- DEFAULT_ALLOWED_PROTOCOLS,
194575
- OPTIONAL_PROTOCOLS,
194576
- BLOCKED_PROTOCOLS,
194577
- DEFAULT_MAX_LENGTH
194578
- };
194579
194874
  96 / EMUS_PER_INCH;
194580
194875
  EMUS_PER_INCH / 96;
194581
194876
  FONT_FAMILY_FALLBACKS2 = Object.freeze({
@@ -194864,12 +195159,13 @@ function print() { __p += __j.call(arguments, '') }
194864
195159
  this.lastPaintSnapshot = null;
194865
195160
  this.options = options;
194866
195161
  this.layoutMode = options.layoutMode ?? "vertical";
195162
+ this.isSemanticFlow = (options.flowMode ?? "paginated") === "semantic";
194867
195163
  this.blockLookup = this.buildBlockLookup(blocks2, measures);
194868
195164
  this.headerProvider = options.headerProvider;
194869
195165
  this.footerProvider = options.footerProvider;
194870
195166
  const defaultGap = this.layoutMode === "horizontal" ? 20 : 24;
194871
195167
  this.pageGap = typeof options.pageGap === "number" && Number.isFinite(options.pageGap) ? Math.max(0, options.pageGap) : defaultGap;
194872
- if (this.layoutMode === "vertical" && options.virtualization?.enabled) {
195168
+ if (!this.isSemanticFlow && this.layoutMode === "vertical" && options.virtualization?.enabled) {
194873
195169
  this.virtualEnabled = true;
194874
195170
  this.virtualWindow = Math.max(1, options.virtualization.window ?? 5);
194875
195171
  this.virtualOverscan = Math.max(0, options.virtualization.overscan ?? 0);
@@ -195091,7 +195387,7 @@ function print() { __p += __j.call(arguments, '') }
195091
195387
  ensureSdtContainerStyles(doc$2);
195092
195388
  ensureImageSelectionStyles(doc$2);
195093
195389
  ensureNativeSelectionStyles(doc$2);
195094
- if (this.options.ruler?.enabled)
195390
+ if (!this.isSemanticFlow && this.options.ruler?.enabled)
195095
195391
  ensureRulerStyles(doc$2);
195096
195392
  mount$1.classList.add(CLASS_NAMES$1.container);
195097
195393
  if (this.mount && this.mount !== mount$1)
@@ -195101,6 +195397,19 @@ function print() { __p += __j.call(arguments, '') }
195101
195397
  this.mount = mount$1;
195102
195398
  this.beginPaintSnapshot(layout);
195103
195399
  this.totalPages = layout.pages.length;
195400
+ if (this.isSemanticFlow) {
195401
+ applyStyles$1(mount$1, containerStyles);
195402
+ mount$1.style.gap = "0px";
195403
+ mount$1.style.alignItems = "stretch";
195404
+ if (!this.currentLayout || this.pageStates.length === 0)
195405
+ this.fullRender(layout);
195406
+ else
195407
+ this.patchLayout(layout);
195408
+ this.currentLayout = layout;
195409
+ this.changedBlocks.clear();
195410
+ this.currentMapping = null;
195411
+ return;
195412
+ }
195104
195413
  let useDomSnapshotFallback = false;
195105
195414
  const mode = this.layoutMode;
195106
195415
  if (mode === "horizontal") {
@@ -195431,10 +195740,11 @@ function print() { __p += __j.call(arguments, '') }
195431
195740
  const el = this.doc.createElement("div");
195432
195741
  el.classList.add(CLASS_NAMES$1.page);
195433
195742
  applyStyles$1(el, pageStyles(width, height, this.getEffectivePageStyles()));
195743
+ this.applySemanticPageOverrides(el);
195434
195744
  el.dataset.layoutEpoch = String(this.layoutEpoch);
195435
195745
  el.dataset.pageNumber = String(page.number);
195436
195746
  el.dataset.pageIndex = String(pageIndex);
195437
- if (this.options.ruler?.enabled) {
195747
+ if (!this.isSemanticFlow && this.options.ruler?.enabled) {
195438
195748
  const rulerEl = this.renderPageRuler(width, page);
195439
195749
  if (rulerEl)
195440
195750
  el.appendChild(rulerEl);
@@ -195500,6 +195810,8 @@ function print() { __p += __j.call(arguments, '') }
195500
195810
  }
195501
195811
  }
195502
195812
  renderDecorationsForPage(pageEl, page, pageIndex) {
195813
+ if (this.isSemanticFlow)
195814
+ return;
195503
195815
  this.renderDecorationSection(pageEl, page, pageIndex, "header");
195504
195816
  this.renderDecorationSection(pageEl, page, pageIndex, "footer");
195505
195817
  }
@@ -195670,6 +195982,7 @@ function print() { __p += __j.call(arguments, '') }
195670
195982
  patchPage(state, page, pageSize, pageIndex) {
195671
195983
  const pageEl = state.element;
195672
195984
  applyStyles$1(pageEl, pageStyles(pageSize.w, pageSize.h, this.getEffectivePageStyles()));
195985
+ this.applySemanticPageOverrides(pageEl);
195673
195986
  pageEl.dataset.pageNumber = String(page.number);
195674
195987
  pageEl.dataset.layoutEpoch = String(this.layoutEpoch);
195675
195988
  const existing = new Map(state.fragments.map((frag) => [frag.key, frag]));
@@ -195762,6 +196075,7 @@ function print() { __p += __j.call(arguments, '') }
195762
196075
  const el = this.doc.createElement("div");
195763
196076
  el.classList.add(CLASS_NAMES$1.page);
195764
196077
  applyStyles$1(el, pageStyles(pageSize.w, pageSize.h, this.getEffectivePageStyles()));
196078
+ this.applySemanticPageOverrides(el);
195765
196079
  el.dataset.layoutEpoch = String(this.layoutEpoch);
195766
196080
  const contextBase = {
195767
196081
  pageNumber: page.number,
@@ -195788,7 +196102,24 @@ function print() { __p += __j.call(arguments, '') }
195788
196102
  fragments: fragmentStates
195789
196103
  };
195790
196104
  }
196105
+ applySemanticPageOverrides(el) {
196106
+ if (this.isSemanticFlow) {
196107
+ el.style.overflow = "visible";
196108
+ el.style.width = "100%";
196109
+ el.style.minWidth = "100%";
196110
+ }
196111
+ }
195791
196112
  getEffectivePageStyles() {
196113
+ if (this.isSemanticFlow) {
196114
+ const base$2 = this.options.pageStyles ?? {};
196115
+ return {
196116
+ ...base$2,
196117
+ background: base$2.background ?? "#fff",
196118
+ boxShadow: "none",
196119
+ border: "none",
196120
+ margin: "0"
196121
+ };
196122
+ }
195792
196123
  if (this.virtualEnabled && this.layoutMode === "vertical")
195793
196124
  return {
195794
196125
  ...this.options.pageStyles ?? {},
@@ -198970,6 +199301,15 @@ function print() { __p += __j.call(arguments, '') }
198970
199301
  this.#evictions = 0;
198971
199302
  }
198972
199303
  };
199304
+ DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE = {
199305
+ fontFamily: "Arial",
199306
+ fontSize: 14,
199307
+ bold: true,
199308
+ spacing: {
199309
+ before: 24,
199310
+ after: 12
199311
+ }
199312
+ };
198973
199313
  DEFAULT_PAGE_SIZE = {
198974
199314
  w: 612,
198975
199315
  h: 792
@@ -199054,6 +199394,10 @@ function print() { __p += __j.call(arguments, '') }
199054
199394
  #decorationBridge = new DecorationBridge;
199055
199395
  #decorationSyncRafHandle = null;
199056
199396
  #rafHandle = null;
199397
+ #semanticResizeObserver = null;
199398
+ #semanticResizeRaf = null;
199399
+ #semanticResizeDebounce = null;
199400
+ #lastSemanticContainerWidth = null;
199057
199401
  #editorListeners = [];
199058
199402
  #scrollHandler = null;
199059
199403
  #scrollContainer = null;
@@ -199100,14 +199444,21 @@ function print() { __p += __j.call(arguments, '') }
199100
199444
  maxVisible: rawPresence.maxVisible !== undefined ? Math.max(1, Math.min(rawPresence.maxVisible, 100)) : rawPresence.maxVisible,
199101
199445
  highlightOpacity: rawPresence.highlightOpacity !== undefined ? Math.max(0, Math.min(rawPresence.highlightOpacity, 1)) : rawPresence.highlightOpacity
199102
199446
  } : undefined;
199447
+ const requestedFlowMode = options.layoutEngineOptions?.flowMode === "semantic" ? "semantic" : "paginated";
199448
+ const requestedLayoutMode = options.layoutEngineOptions?.layoutMode ?? "vertical";
199103
199449
  this.#layoutOptions = {
199104
199450
  pageSize: options.layoutEngineOptions?.pageSize ?? DEFAULT_PAGE_SIZE,
199105
199451
  margins: options.layoutEngineOptions?.margins ?? DEFAULT_MARGINS,
199106
- virtualization: options.layoutEngineOptions?.virtualization,
199452
+ virtualization: requestedFlowMode === "semantic" ? {
199453
+ ...options.layoutEngineOptions?.virtualization ?? {},
199454
+ enabled: false
199455
+ } : options.layoutEngineOptions?.virtualization,
199107
199456
  zoom: options.layoutEngineOptions?.zoom ?? 1,
199108
199457
  pageStyles: options.layoutEngineOptions?.pageStyles,
199109
199458
  debugLabel: options.layoutEngineOptions?.debugLabel,
199110
- layoutMode: options.layoutEngineOptions?.layoutMode ?? "vertical",
199459
+ layoutMode: requestedFlowMode === "semantic" ? "vertical" : requestedLayoutMode,
199460
+ flowMode: requestedFlowMode,
199461
+ semanticOptions: options.layoutEngineOptions?.semanticOptions,
199111
199462
  trackedChanges: options.layoutEngineOptions?.trackedChanges,
199112
199463
  emitCommentPositionsInViewing: options.layoutEngineOptions?.emitCommentPositionsInViewing,
199113
199464
  enableCommentsInViewing: options.layoutEngineOptions?.enableCommentsInViewing,
@@ -199284,6 +199635,7 @@ function print() { __p += __j.call(arguments, '') }
199284
199635
  this.#setupDragHandlers();
199285
199636
  this.#setupInputBridge();
199286
199637
  this.#syncTrackedChangesPreferences();
199638
+ this.#setupSemanticResizeObserver();
199287
199639
  this.#registryKey = options.documentId || `__anonymous_${Date.now()}_${Math.random().toString(36).slice(2)}`;
199288
199640
  PresentationEditor2.#instances.set(this.#registryKey, this);
199289
199641
  this.#pendingDocChange = true;
@@ -199669,6 +200021,93 @@ function print() { __p += __j.call(arguments, '') }
199669
200021
  getLayoutOptions() {
199670
200022
  return { ...this.#layoutOptions };
199671
200023
  }
200024
+ #isSemanticFlowMode() {
200025
+ return this.#layoutOptions.flowMode === "semantic";
200026
+ }
200027
+ #resolveSemanticMargins(margins) {
200028
+ const mode = this.#layoutOptions.semanticOptions?.marginsMode ?? "firstSection";
200029
+ if (mode === "none")
200030
+ return {
200031
+ left: 0,
200032
+ right: 0,
200033
+ top: 0,
200034
+ bottom: 0
200035
+ };
200036
+ const clamp$2 = (value, fallback) => {
200037
+ const v = typeof value === "number" && Number.isFinite(value) ? value : fallback;
200038
+ return v >= 0 ? v : fallback;
200039
+ };
200040
+ if (mode === "custom") {
200041
+ const custom = this.#layoutOptions.semanticOptions?.customMargins;
200042
+ return {
200043
+ left: clamp$2(custom?.left, clamp$2(margins.left, DEFAULT_MARGINS.left)),
200044
+ right: clamp$2(custom?.right, clamp$2(margins.right, DEFAULT_MARGINS.right)),
200045
+ top: clamp$2(custom?.top, clamp$2(margins.top, DEFAULT_MARGINS.top)),
200046
+ bottom: clamp$2(custom?.bottom, clamp$2(margins.bottom, DEFAULT_MARGINS.bottom))
200047
+ };
200048
+ }
200049
+ return {
200050
+ left: clamp$2(margins.left, DEFAULT_MARGINS.left),
200051
+ right: clamp$2(margins.right, DEFAULT_MARGINS.right),
200052
+ top: 0,
200053
+ bottom: 0
200054
+ };
200055
+ }
200056
+ #resolveSemanticContainerInnerWidth() {
200057
+ const host = this.#visibleHost;
200058
+ if (!host)
200059
+ return DEFAULT_PAGE_SIZE.w;
200060
+ const style$1 = (host.ownerDocument?.defaultView ?? window).getComputedStyle(host);
200061
+ const paddingLeft = Number.parseFloat(style$1.paddingLeft ?? "0");
200062
+ const paddingRight = Number.parseFloat(style$1.paddingRight ?? "0");
200063
+ const horizontalPadding = (Number.isFinite(paddingLeft) ? paddingLeft : 0) + (Number.isFinite(paddingRight) ? paddingRight : 0);
200064
+ const clientWidth = host.clientWidth;
200065
+ if (Number.isFinite(clientWidth) && clientWidth > 0)
200066
+ return Math.max(1, clientWidth - horizontalPadding);
200067
+ const rectWidth = host.getBoundingClientRect().width;
200068
+ if (Number.isFinite(rectWidth) && rectWidth > 0)
200069
+ return Math.max(1, rectWidth - horizontalPadding);
200070
+ return Math.max(1, DEFAULT_PAGE_SIZE.w - horizontalPadding);
200071
+ }
200072
+ #setupSemanticResizeObserver() {
200073
+ if (!this.#isSemanticFlowMode())
200074
+ return;
200075
+ const ResizeObs = (this.#visibleHost.ownerDocument?.defaultView ?? window).ResizeObserver;
200076
+ if (typeof ResizeObs !== "function")
200077
+ return;
200078
+ this.#lastSemanticContainerWidth = this.#resolveSemanticContainerInnerWidth();
200079
+ this.#semanticResizeObserver = new ResizeObs(() => {
200080
+ this.#scheduleSemanticResizeRelayout();
200081
+ });
200082
+ this.#semanticResizeObserver.observe(this.#visibleHost);
200083
+ }
200084
+ #scheduleSemanticResizeRelayout() {
200085
+ if (!this.#isSemanticFlowMode())
200086
+ return;
200087
+ const view = this.#visibleHost.ownerDocument?.defaultView ?? window;
200088
+ if (this.#semanticResizeRaf == null)
200089
+ this.#semanticResizeRaf = view.requestAnimationFrame(() => {
200090
+ this.#semanticResizeRaf = null;
200091
+ this.#applySemanticResizeRelayout();
200092
+ });
200093
+ if (this.#semanticResizeDebounce != null)
200094
+ view.clearTimeout(this.#semanticResizeDebounce);
200095
+ this.#semanticResizeDebounce = view.setTimeout(() => {
200096
+ this.#semanticResizeDebounce = null;
200097
+ this.#applySemanticResizeRelayout();
200098
+ }, SEMANTIC_RESIZE_DEBOUNCE_MS);
200099
+ }
200100
+ #applySemanticResizeRelayout() {
200101
+ if (!this.#isSemanticFlowMode())
200102
+ return;
200103
+ const nextWidth = this.#resolveSemanticContainerInnerWidth();
200104
+ const prevWidth = this.#lastSemanticContainerWidth;
200105
+ if (prevWidth != null && Math.abs(nextWidth - prevWidth) < 1)
200106
+ return;
200107
+ this.#lastSemanticContainerWidth = nextWidth;
200108
+ this.#pendingDocChange = true;
200109
+ this.#scheduleRerender();
200110
+ }
199672
200111
  getPaintSnapshot() {
199673
200112
  return this.#domPainter?.getPaintSnapshot?.() ?? null;
199674
200113
  }
@@ -199679,6 +200118,8 @@ function print() { __p += __j.call(arguments, '') }
199679
200118
  return Array.from(this.#remoteCursorManager?.state.values() ?? []);
199680
200119
  }
199681
200120
  setLayoutMode(mode) {
200121
+ if (this.#isSemanticFlowMode())
200122
+ return;
199682
200123
  if (!mode || this.#layoutOptions.layoutMode === mode)
199683
200124
  return;
199684
200125
  this.#layoutOptions.layoutMode = mode;
@@ -200128,6 +200569,18 @@ function print() { __p += __j.call(arguments, '') }
200128
200569
  clearTimeout(this.#cursorUpdateTimer);
200129
200570
  this.#cursorUpdateTimer = null;
200130
200571
  }
200572
+ if (this.#semanticResizeRaf != null)
200573
+ safeCleanup(() => {
200574
+ (this.#visibleHost?.ownerDocument?.defaultView ?? window).cancelAnimationFrame(this.#semanticResizeRaf);
200575
+ this.#semanticResizeRaf = null;
200576
+ }, "Semantic resize RAF");
200577
+ if (this.#semanticResizeDebounce != null)
200578
+ safeCleanup(() => {
200579
+ (this.#visibleHost?.ownerDocument?.defaultView ?? window).clearTimeout(this.#semanticResizeDebounce);
200580
+ this.#semanticResizeDebounce = null;
200581
+ }, "Semantic resize debounce");
200582
+ this.#semanticResizeObserver?.disconnect();
200583
+ this.#semanticResizeObserver = null;
200131
200584
  if (this.#remoteCursorManager)
200132
200585
  safeCleanup(() => {
200133
200586
  this.#remoteCursorManager?.destroy();
@@ -200735,9 +201188,12 @@ function print() { __p += __j.call(arguments, '') }
200735
201188
  to: r$1.to
200736
201189
  })));
200737
201190
  this.#applyHtmlAnnotationMeasurements(blocks2);
201191
+ const isSemanticFlow = this.#isSemanticFlowMode();
200738
201192
  const baseLayoutOptions = this.#resolveLayoutOptions(blocks2, sectionMetadata);
200739
201193
  const footnotesLayoutInput = buildFootnotesInput(this.#editor?.state, this.#editor?.converter, converterContext, this.#editor?.converter?.themeColors ?? undefined);
200740
- const layoutOptions = footnotesLayoutInput ? {
201194
+ const semanticFootnoteBlocks = isSemanticFlow ? buildSemanticFootnoteBlocks(footnotesLayoutInput, this.#layoutOptions.semanticOptions?.footnotesMode) : [];
201195
+ const blocksForLayout = semanticFootnoteBlocks.length > 0 ? [...blocks2, ...semanticFootnoteBlocks] : blocks2;
201196
+ const layoutOptions = !isSemanticFlow && footnotesLayoutInput ? {
200741
201197
  ...baseLayoutOptions,
200742
201198
  footnotes: footnotesLayoutInput
200743
201199
  } : baseLayoutOptions;
@@ -200753,7 +201209,7 @@ function print() { __p += __j.call(arguments, '') }
200753
201209
  const headerFooterInput = this.#buildHeaderFooterInput();
200754
201210
  try {
200755
201211
  const incrementalLayoutStart = perfNow();
200756
- const result = await incrementalLayout(previousBlocks, previousLayout, blocks2, layoutOptions, (block, constraints) => measureBlock(block, constraints), headerFooterInput ?? undefined, previousMeasures);
201212
+ const result = await incrementalLayout(previousBlocks, previousLayout, blocksForLayout, layoutOptions, (block, constraints) => measureBlock(block, constraints), headerFooterInput ?? undefined, previousMeasures);
200757
201213
  perfLog(`[Perf] incrementalLayout: ${(perfNow() - incrementalLayoutStart).toFixed(2)}ms`);
200758
201214
  if (!result || typeof result !== "object") {
200759
201215
  this.#handleLayoutError("render", /* @__PURE__ */ new Error("incrementalLayout returned invalid result"));
@@ -200786,9 +201242,9 @@ function print() { __p += __j.call(arguments, '') }
200786
201242
  });
200787
201243
  if (this.#headerFooterSession)
200788
201244
  this.#headerFooterSession.multiSectionIdentifier = multiSectionId;
200789
- const anchorMap = computeAnchorMap(bookmarks, layout, blocks2);
201245
+ const anchorMap = computeAnchorMap(bookmarks, layout, blocksForLayout);
200790
201246
  this.#layoutState = {
200791
- blocks: blocks2,
201247
+ blocks: blocksForLayout,
200792
201248
  measures,
200793
201249
  layout,
200794
201250
  bookmarks,
@@ -200818,10 +201274,12 @@ function print() { __p += __j.call(arguments, '') }
200818
201274
  else
200819
201275
  this.#pageGeometryHelper.updateLayout(this.#layoutState.layout, pageGap);
200820
201276
  }
200821
- await this.#layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata);
200822
- this.#updateDecorationProviders(layout);
200823
- const painter = this.#ensurePainter(blocks2, measures);
200824
- if (typeof painter.setProviders === "function")
201277
+ if (!isSemanticFlow) {
201278
+ await this.#layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata);
201279
+ this.#updateDecorationProviders(layout);
201280
+ }
201281
+ const painter = this.#ensurePainter(blocksForLayout, measures);
201282
+ if (!isSemanticFlow && typeof painter.setProviders === "function")
200825
201283
  painter.setProviders(this.#headerFooterSession?.headerDecorationProvider, this.#headerFooterSession?.footerDecorationProvider);
200826
201284
  const headerBlocks = [];
200827
201285
  const headerMeasures = [];
@@ -200854,7 +201312,7 @@ function print() { __p += __j.call(arguments, '') }
200854
201312
  footerMeasures.push(...extraMeasures);
200855
201313
  }
200856
201314
  const painterSetDataStart = perfNow();
200857
- painter.setData?.(blocks2, measures, headerBlocks.length > 0 ? headerBlocks : undefined, headerMeasures.length > 0 ? headerMeasures : undefined, footerBlocks.length > 0 ? footerBlocks : undefined, footerMeasures.length > 0 ? footerMeasures : undefined);
201315
+ painter.setData?.(blocksForLayout, measures, headerBlocks.length > 0 ? headerBlocks : undefined, headerMeasures.length > 0 ? headerMeasures : undefined, footerBlocks.length > 0 ? footerBlocks : undefined, footerMeasures.length > 0 ? footerMeasures : undefined);
200858
201316
  perfLog(`[Perf] painter.setData: ${(perfNow() - painterSetDataStart).toFixed(2)}ms`);
200859
201317
  this.#domIndexObserverManager?.pause();
200860
201318
  const mapping = this.#pendingMapping;
@@ -200881,10 +201339,10 @@ function print() { __p += __j.call(arguments, '') }
200881
201339
  this.#layoutErrorState = "healthy";
200882
201340
  this.#dismissErrorBanner();
200883
201341
  this.#applyZoom();
200884
- const metrics = createLayoutMetrics(perf2, startMark, layout, blocks2);
201342
+ const metrics = createLayoutMetrics(perf2, startMark, layout, blocksForLayout);
200885
201343
  const payload = {
200886
201344
  layout,
200887
- blocks: blocks2,
201345
+ blocks: blocksForLayout,
200888
201346
  measures,
200889
201347
  metrics
200890
201348
  };
@@ -200917,6 +201375,7 @@ function print() { __p += __j.call(arguments, '') }
200917
201375
  blocks: blocks2,
200918
201376
  measures,
200919
201377
  layoutMode: this.#layoutOptions.layoutMode ?? "vertical",
201378
+ flowMode: this.#layoutOptions.flowMode ?? "paginated",
200920
201379
  virtualization: normalizedVirtualization,
200921
201380
  pageStyles: this.#layoutOptions.pageStyles,
200922
201381
  headerProvider: this.#headerFooterSession?.headerDecorationProvider,
@@ -201410,15 +201869,61 @@ function print() { __p += __j.call(arguments, '') }
201410
201869
  const columns = firstSection?.columns ?? defaults2.columns;
201411
201870
  this.#layoutOptions.pageSize = pageSize;
201412
201871
  this.#layoutOptions.margins = margins;
201872
+ const flowMode = this.#layoutOptions.flowMode ?? "paginated";
201873
+ const resolvedMargins = {
201874
+ top: margins.top,
201875
+ right: margins.right,
201876
+ bottom: margins.bottom,
201877
+ left: margins.left,
201878
+ ...margins.header != null ? { header: margins.header } : {},
201879
+ ...margins.footer != null ? { footer: margins.footer } : {}
201880
+ };
201881
+ if (flowMode === "semantic") {
201882
+ const semanticMargins = this.#resolveSemanticMargins(margins);
201883
+ const containerWidth = this.#resolveSemanticContainerInnerWidth();
201884
+ const semanticContentWidth = Math.max(MIN_SEMANTIC_CONTENT_WIDTH_PX, containerWidth - semanticMargins.left - semanticMargins.right);
201885
+ const semanticPageWidth = semanticContentWidth + semanticMargins.left + semanticMargins.right;
201886
+ this.#hiddenHost.style.width = `${semanticContentWidth}px`;
201887
+ this.#lastSemanticContainerWidth = containerWidth;
201888
+ return {
201889
+ flowMode: "semantic",
201890
+ pageSize: {
201891
+ w: semanticPageWidth,
201892
+ h: pageSize.h
201893
+ },
201894
+ margins: {
201895
+ ...resolvedMargins,
201896
+ top: semanticMargins.top,
201897
+ right: semanticMargins.right,
201898
+ bottom: semanticMargins.bottom,
201899
+ left: semanticMargins.left
201900
+ },
201901
+ columns: {
201902
+ count: 1,
201903
+ gap: 0
201904
+ },
201905
+ semantic: {
201906
+ contentWidth: semanticContentWidth,
201907
+ marginLeft: semanticMargins.left,
201908
+ marginRight: semanticMargins.right,
201909
+ marginTop: semanticMargins.top,
201910
+ marginBottom: semanticMargins.bottom
201911
+ },
201912
+ sectionMetadata
201913
+ };
201914
+ }
201413
201915
  this.#hiddenHost.style.width = `${pageSize.w}px`;
201414
201916
  return {
201917
+ flowMode: "paginated",
201415
201918
  pageSize,
201416
- margins,
201919
+ margins: resolvedMargins,
201417
201920
  ...columns ? { columns } : {},
201418
201921
  sectionMetadata
201419
201922
  };
201420
201923
  }
201421
201924
  #buildHeaderFooterInput() {
201925
+ if (this.#isSemanticFlowMode())
201926
+ return null;
201422
201927
  const adapter = this.#headerFooterSession?.adapter;
201423
201928
  if (!adapter)
201424
201929
  return null;
@@ -201711,6 +202216,8 @@ function print() { __p += __j.call(arguments, '') }
201711
202216
  });
201712
202217
  }
201713
202218
  #getEffectivePageGap() {
202219
+ if (this.#isSemanticFlowMode())
202220
+ return 0;
201714
202221
  if (this.#layoutOptions.virtualization?.enabled)
201715
202222
  return Math.max(0, this.#layoutOptions.virtualization.gap ?? DEFAULT_PAGE_GAP);
201716
202223
  if (this.#layoutOptions.layoutMode === "horizontal")
@@ -201810,6 +202317,21 @@ function print() { __p += __j.call(arguments, '') }
201810
202317
  };
201811
202318
  }
201812
202319
  #applyZoom() {
202320
+ if (this.#isSemanticFlowMode()) {
202321
+ this.#viewportHost.style.width = "100%";
202322
+ this.#viewportHost.style.minWidth = "";
202323
+ this.#viewportHost.style.minHeight = "";
202324
+ this.#viewportHost.style.transform = "";
202325
+ this.#painterHost.style.width = "100%";
202326
+ this.#painterHost.style.minHeight = "";
202327
+ this.#painterHost.style.transformOrigin = "";
202328
+ this.#painterHost.style.transform = "";
202329
+ this.#selectionOverlay.style.width = "100%";
202330
+ this.#selectionOverlay.style.height = "100%";
202331
+ this.#selectionOverlay.style.transformOrigin = "";
202332
+ this.#selectionOverlay.style.transform = "";
202333
+ return;
202334
+ }
201813
202335
  const zoom = this.#layoutOptions.zoom ?? 1;
201814
202336
  const layoutMode = this.#layoutOptions.layoutMode ?? "vertical";
201815
202337
  const pages = this.#layoutState.layout?.pages;
@@ -212067,8 +212589,8 @@ function print() { __p += __j.call(arguments, '') }
212067
212589
  return isObjectLike_default(value) && hasOwnProperty$8.call(value, "callee") && !propertyIsEnumerable$1.call(value, "callee");
212068
212590
  };
212069
212591
  stubFalse_default = stubFalse;
212070
- freeExports$2 = typeof exports_src_D2HZLLOG_es == "object" && exports_src_D2HZLLOG_es && !exports_src_D2HZLLOG_es.nodeType && exports_src_D2HZLLOG_es;
212071
- freeModule$2 = freeExports$2 && typeof module_src_D2HZLLOG_es == "object" && module_src_D2HZLLOG_es && !module_src_D2HZLLOG_es.nodeType && module_src_D2HZLLOG_es;
212592
+ freeExports$2 = typeof exports_src_Di9XuGnD_es == "object" && exports_src_Di9XuGnD_es && !exports_src_Di9XuGnD_es.nodeType && exports_src_Di9XuGnD_es;
212593
+ freeModule$2 = freeExports$2 && typeof module_src_Di9XuGnD_es == "object" && module_src_Di9XuGnD_es && !module_src_Di9XuGnD_es.nodeType && module_src_Di9XuGnD_es;
212072
212594
  Buffer$1 = freeModule$2 && freeModule$2.exports === freeExports$2 ? _root_default.Buffer : undefined;
212073
212595
  isBuffer_default = (Buffer$1 ? Buffer$1.isBuffer : undefined) || stubFalse_default;
212074
212596
  typedArrayTags = {};
@@ -212076,8 +212598,8 @@ function print() { __p += __j.call(arguments, '') }
212076
212598
  typedArrayTags[argsTag$1] = typedArrayTags[arrayTag$1] = typedArrayTags[arrayBufferTag$1] = typedArrayTags[boolTag$1] = typedArrayTags[dataViewTag$2] = typedArrayTags[dateTag$1] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag] = typedArrayTags[mapTag$2] = typedArrayTags[numberTag$1] = typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$1] = typedArrayTags[setTag$2] = typedArrayTags[stringTag$1] = typedArrayTags[weakMapTag$1] = false;
212077
212599
  _baseIsTypedArray_default = baseIsTypedArray;
212078
212600
  _baseUnary_default = baseUnary;
212079
- freeExports$1 = typeof exports_src_D2HZLLOG_es == "object" && exports_src_D2HZLLOG_es && !exports_src_D2HZLLOG_es.nodeType && exports_src_D2HZLLOG_es;
212080
- freeModule$1 = freeExports$1 && typeof module_src_D2HZLLOG_es == "object" && module_src_D2HZLLOG_es && !module_src_D2HZLLOG_es.nodeType && module_src_D2HZLLOG_es;
212601
+ freeExports$1 = typeof exports_src_Di9XuGnD_es == "object" && exports_src_Di9XuGnD_es && !exports_src_Di9XuGnD_es.nodeType && exports_src_Di9XuGnD_es;
212602
+ freeModule$1 = freeExports$1 && typeof module_src_Di9XuGnD_es == "object" && module_src_Di9XuGnD_es && !module_src_Di9XuGnD_es.nodeType && module_src_Di9XuGnD_es;
212081
212603
  freeProcess = freeModule$1 && freeModule$1.exports === freeExports$1 && _freeGlobal_default.process;
212082
212604
  _nodeUtil_default = function() {
212083
212605
  try {
@@ -212182,8 +212704,8 @@ function print() { __p += __j.call(arguments, '') }
212182
212704
  Stack.prototype.has = _stackHas_default;
212183
212705
  Stack.prototype.set = _stackSet_default;
212184
212706
  _Stack_default = Stack;
212185
- freeExports = typeof exports_src_D2HZLLOG_es == "object" && exports_src_D2HZLLOG_es && !exports_src_D2HZLLOG_es.nodeType && exports_src_D2HZLLOG_es;
212186
- freeModule = freeExports && typeof module_src_D2HZLLOG_es == "object" && module_src_D2HZLLOG_es && !module_src_D2HZLLOG_es.nodeType && module_src_D2HZLLOG_es;
212707
+ freeExports = typeof exports_src_Di9XuGnD_es == "object" && exports_src_Di9XuGnD_es && !exports_src_Di9XuGnD_es.nodeType && exports_src_Di9XuGnD_es;
212708
+ freeModule = freeExports && typeof module_src_Di9XuGnD_es == "object" && module_src_Di9XuGnD_es && !module_src_Di9XuGnD_es.nodeType && module_src_Di9XuGnD_es;
212187
212709
  Buffer4 = freeModule && freeModule.exports === freeExports ? _root_default.Buffer : undefined;
212188
212710
  allocUnsafe = Buffer4 ? Buffer4.allocUnsafe : undefined;
212189
212711
  _cloneBuffer_default = cloneBuffer;
@@ -219986,7 +220508,7 @@ function print() { __p += __j.call(arguments, '') }
219986
220508
  class: normalizeClass(["super-editor-container", { "web-layout": isWebLayout.value }]),
219987
220509
  style: normalizeStyle(containerStyle.value)
219988
220510
  }, [
219989
- __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Teleport, {
220511
+ __props.options.rulerContainer && rulersVisible.value && !isWebLayout.value && !!activeEditor.value ? (openBlock(), createBlock(Teleport, {
219990
220512
  key: 0,
219991
220513
  to: __props.options.rulerContainer
219992
220514
  }, [createBaseVNode("div", {
@@ -219996,7 +220518,7 @@ function print() { __p += __j.call(arguments, '') }
219996
220518
  class: "ruler superdoc-ruler",
219997
220519
  editor: activeEditor.value,
219998
220520
  onMarginChange: handleMarginChange
219999
- }, null, 8, ["editor"])], 4)], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createElementBlock("div", {
220521
+ }, null, 8, ["editor"])], 4)], 8, ["to"])) : rulersVisible.value && !isWebLayout.value && !!activeEditor.value ? (openBlock(), createElementBlock("div", {
220000
220522
  key: 1,
220001
220523
  class: "ruler-host",
220002
220524
  style: normalizeStyle(rulerHostStyle.value)
@@ -220129,7 +220651,7 @@ function print() { __p += __j.call(arguments, '') }
220129
220651
  ], 6);
220130
220652
  };
220131
220653
  }
220132
- }), [["__scopeId", "data-v-8a0d9ad4"]]);
220654
+ }), [["__scopeId", "data-v-ff351a2a"]]);
220133
220655
  _hoisted_1 = ["innerHTML"];
220134
220656
  SuperInput_default = /* @__PURE__ */ __plugin_vue_export_helper_default({
220135
220657
  __name: "SuperInput",
@@ -220263,8 +220785,8 @@ var init_zipper_DqXT7uTa_es = __esm(() => {
220263
220785
 
220264
220786
  // ../../packages/superdoc/dist/super-editor.es.js
220265
220787
  var init_super_editor_es = __esm(() => {
220266
- init_src_D2HZLLOG_es();
220267
- init_SuperConverter_B3_eOoDQ_es();
220788
+ init_src_Di9XuGnD_es();
220789
+ init_SuperConverter_CDs2fwu4_es();
220268
220790
  init_jszip_ChlR43oI_es();
220269
220791
  init_xml_js_DLE8mr0n_es();
220270
220792
  init_constants_CqvgVEDh_es();
@@ -239737,6 +240259,122 @@ var init_CommandService = () => {};
239737
240259
 
239738
240260
  // ../../packages/super-editor/src/core/helpers/getHTMLFromFragment.js
239739
240261
  var init_getHTMLFromFragment = () => {};
240262
+ // ../../shared/url-validation/index.js
240263
+ var init_url_validation = () => {};
240264
+
240265
+ // ../../packages/super-editor/src/core/super-converter/docx-helpers/docx-constants.js
240266
+ var RELATIONSHIP_TYPES2;
240267
+ var init_docx_constants = __esm(() => {
240268
+ RELATIONSHIP_TYPES2 = {
240269
+ image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
240270
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
240271
+ };
240272
+ });
240273
+
240274
+ // ../../packages/super-editor/src/core/super-converter/docx-helpers/document-rels.js
240275
+ var getDocumentRelationshipElements2 = (editor) => {
240276
+ const docx = editor.converter?.convertedXml;
240277
+ if (!docx)
240278
+ return [];
240279
+ const documentRels = docx["word/_rels/document.xml.rels"];
240280
+ const elements = documentRels?.elements;
240281
+ if (!Array.isArray(elements))
240282
+ return [];
240283
+ const relationshipTag = elements.find((el) => el.name === "Relationships");
240284
+ return relationshipTag?.elements || [];
240285
+ }, getMaxRelationshipIdInt2 = (relationships) => {
240286
+ const ids = [];
240287
+ relationships.forEach((rel) => {
240288
+ const splitId = rel.attributes.Id.split("rId");
240289
+ const parsedInt = parseInt(splitId[1], 10);
240290
+ if (Number.isInteger(parsedInt)) {
240291
+ ids.push(parsedInt);
240292
+ }
240293
+ });
240294
+ if (ids.length === 0)
240295
+ return 0;
240296
+ return Math.max(...ids);
240297
+ }, findRelationshipIdFromTarget2 = (target, editor) => {
240298
+ if (!target)
240299
+ return null;
240300
+ if (target.startsWith("word/"))
240301
+ target = target.replace("word/", "");
240302
+ const relationships = getDocumentRelationshipElements2(editor);
240303
+ const existingLinkRel = relationships?.find((rel) => rel.attributes.Target === target);
240304
+ if (existingLinkRel) {
240305
+ return existingLinkRel.attributes.Id;
240306
+ }
240307
+ }, insertNewRelationship2 = (target, type, editor) => {
240308
+ if (!target || typeof target !== "string") {
240309
+ throw new Error("Target must be a non-empty string");
240310
+ }
240311
+ if (!type || typeof type !== "string") {
240312
+ throw new Error("Type must be a non-empty string");
240313
+ }
240314
+ if (!editor) {
240315
+ throw new Error("Editor instance is required");
240316
+ }
240317
+ const mappedType = RELATIONSHIP_TYPES2[type];
240318
+ if (!mappedType) {
240319
+ console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES2).join(", ")}`);
240320
+ return null;
240321
+ }
240322
+ const existingRelId = findRelationshipIdFromTarget2(target, editor);
240323
+ if (existingRelId) {
240324
+ console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
240325
+ return existingRelId;
240326
+ }
240327
+ const docx = editor.converter?.convertedXml;
240328
+ if (!docx) {
240329
+ console.error("No converted XML found in editor");
240330
+ return null;
240331
+ }
240332
+ const documentRels = docx["word/_rels/document.xml.rels"];
240333
+ if (!documentRels) {
240334
+ console.error("No document relationships found in the docx");
240335
+ return null;
240336
+ }
240337
+ const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
240338
+ if (!relationshipsTag) {
240339
+ console.error("No Relationships tag found in document relationships");
240340
+ return null;
240341
+ }
240342
+ if (!relationshipsTag.elements) {
240343
+ relationshipsTag.elements = [];
240344
+ }
240345
+ const newId = getNewRelationshipId2(editor);
240346
+ if (!newId) {
240347
+ console.error("Failed to generate new relationship ID");
240348
+ return null;
240349
+ }
240350
+ const newRel = {
240351
+ type: "element",
240352
+ name: "Relationship",
240353
+ attributes: {
240354
+ Id: newId,
240355
+ Type: mappedType,
240356
+ Target: target
240357
+ }
240358
+ };
240359
+ if (type === "hyperlink") {
240360
+ newRel.attributes.TargetMode = "External";
240361
+ }
240362
+ relationshipsTag.elements.push(newRel);
240363
+ return newId;
240364
+ }, getNewRelationshipId2 = (editor) => {
240365
+ const relationships = getDocumentRelationshipElements2(editor);
240366
+ const maxIdInt = getMaxRelationshipIdInt2(relationships);
240367
+ return `rId${maxIdInt + 1}`;
240368
+ };
240369
+ var init_document_rels = __esm(() => {
240370
+ init_docx_constants();
240371
+ });
240372
+ // ../../packages/super-editor/src/core/inputRules/paste-link-normalizer.js
240373
+ var init_paste_link_normalizer = __esm(() => {
240374
+ init_url_validation();
240375
+ init_document_rels();
240376
+ });
240377
+
239740
240378
  // ../../packages/super-editor/src/core/helpers/pasteListHelpers.js
239741
240379
  function getStartNumber2(lvlText) {
239742
240380
  const match2 = lvlText.match(/^(\d+)/);
@@ -264631,114 +265269,6 @@ var init_documentFootnotesImporter = __esm(() => {
264631
265269
  init_docxImporter();
264632
265270
  });
264633
265271
 
264634
- // ../../packages/super-editor/src/core/super-converter/docx-helpers/docx-constants.js
264635
- var RELATIONSHIP_TYPES2;
264636
- var init_docx_constants = __esm(() => {
264637
- RELATIONSHIP_TYPES2 = {
264638
- image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
264639
- hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
264640
- };
264641
- });
264642
-
264643
- // ../../packages/super-editor/src/core/super-converter/docx-helpers/document-rels.js
264644
- var getDocumentRelationshipElements2 = (editor) => {
264645
- const docx = editor.converter?.convertedXml;
264646
- if (!docx)
264647
- return [];
264648
- const documentRels = docx["word/_rels/document.xml.rels"];
264649
- const elements = documentRels?.elements;
264650
- if (!Array.isArray(elements))
264651
- return [];
264652
- const relationshipTag = elements.find((el) => el.name === "Relationships");
264653
- return relationshipTag?.elements || [];
264654
- }, getMaxRelationshipIdInt2 = (relationships) => {
264655
- const ids = [];
264656
- relationships.forEach((rel) => {
264657
- const splitId = rel.attributes.Id.split("rId");
264658
- const parsedInt = parseInt(splitId[1], 10);
264659
- if (Number.isInteger(parsedInt)) {
264660
- ids.push(parsedInt);
264661
- }
264662
- });
264663
- if (ids.length === 0)
264664
- return 0;
264665
- return Math.max(...ids);
264666
- }, findRelationshipIdFromTarget2 = (target, editor) => {
264667
- if (!target)
264668
- return null;
264669
- if (target.startsWith("word/"))
264670
- target = target.replace("word/", "");
264671
- const relationships = getDocumentRelationshipElements2(editor);
264672
- const existingLinkRel = relationships?.find((rel) => rel.attributes.Target === target);
264673
- if (existingLinkRel) {
264674
- return existingLinkRel.attributes.Id;
264675
- }
264676
- }, insertNewRelationship2 = (target, type, editor) => {
264677
- if (!target || typeof target !== "string") {
264678
- throw new Error("Target must be a non-empty string");
264679
- }
264680
- if (!type || typeof type !== "string") {
264681
- throw new Error("Type must be a non-empty string");
264682
- }
264683
- if (!editor) {
264684
- throw new Error("Editor instance is required");
264685
- }
264686
- const mappedType = RELATIONSHIP_TYPES2[type];
264687
- if (!mappedType) {
264688
- console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES2).join(", ")}`);
264689
- return null;
264690
- }
264691
- const existingRelId = findRelationshipIdFromTarget2(target, editor);
264692
- if (existingRelId) {
264693
- console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
264694
- return existingRelId;
264695
- }
264696
- const docx = editor.converter?.convertedXml;
264697
- if (!docx) {
264698
- console.error("No converted XML found in editor");
264699
- return null;
264700
- }
264701
- const documentRels = docx["word/_rels/document.xml.rels"];
264702
- if (!documentRels) {
264703
- console.error("No document relationships found in the docx");
264704
- return null;
264705
- }
264706
- const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
264707
- if (!relationshipsTag) {
264708
- console.error("No Relationships tag found in document relationships");
264709
- return null;
264710
- }
264711
- if (!relationshipsTag.elements) {
264712
- relationshipsTag.elements = [];
264713
- }
264714
- const newId = getNewRelationshipId2(editor);
264715
- if (!newId) {
264716
- console.error("Failed to generate new relationship ID");
264717
- return null;
264718
- }
264719
- const newRel = {
264720
- type: "element",
264721
- name: "Relationship",
264722
- attributes: {
264723
- Id: newId,
264724
- Type: mappedType,
264725
- Target: target
264726
- }
264727
- };
264728
- if (type === "hyperlink") {
264729
- newRel.attributes.TargetMode = "External";
264730
- }
264731
- relationshipsTag.elements.push(newRel);
264732
- return newId;
264733
- }, getNewRelationshipId2 = (editor) => {
264734
- const relationships = getDocumentRelationshipElements2(editor);
264735
- const maxIdInt = getMaxRelationshipIdInt2(relationships);
264736
- return `rId${maxIdInt + 1}`;
264737
- };
264738
- var init_document_rels = __esm(() => {
264739
- init_docx_constants();
264740
- });
264741
-
264742
265272
  // ../../packages/super-editor/src/core/super-converter/docx-helpers/docx-helpers.js
264743
265273
  var DocxHelpers2;
264744
265274
  var init_docx_helpers = __esm(() => {
@@ -269570,6 +270100,7 @@ var wrapTextsInRuns2 = (doc4) => {
269570
270100
  var init_docx_paste = __esm(() => {
269571
270101
  init_dist3();
269572
270102
  init_InputRule();
270103
+ init_paste_link_normalizer();
269573
270104
  init_list_numbering_helpers();
269574
270105
  init_pasteListHelpers();
269575
270106
  init_list_numbering();
@@ -269595,6 +270126,7 @@ var init_html_helpers = __esm(() => {
269595
270126
  // ../../packages/super-editor/src/core/inputRules/google-docs-paste/google-docs-paste.js
269596
270127
  var init_google_docs_paste = __esm(() => {
269597
270128
  init_InputRule();
270129
+ init_paste_link_normalizer();
269598
270130
  init_list_numbering_helpers();
269599
270131
  init_html_helpers();
269600
270132
  init_pasteListHelpers();
@@ -269634,6 +270166,7 @@ var init_InputRule = __esm(() => {
269634
270166
  init_docx_paste();
269635
270167
  init_html_helpers();
269636
270168
  init_google_docs_paste();
270169
+ init_paste_link_normalizer();
269637
270170
  });
269638
270171
 
269639
270172
  // ../../packages/super-editor/src/core/helpers/catchAllSchema.js