@harbour-enterprises/superdoc 0.20.0-next.14 → 0.20.0-next.15

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 (107) hide show
  1. package/dist/chunks/{PdfViewer-_NPRPRHl.es.js → PdfViewer-D3gJ5ozH.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-D-erp24R.cjs → PdfViewer-DuEWa8ox.cjs} +1 -1
  3. package/dist/chunks/{index-duHcNiwD.cjs → index-D2h9q27o.cjs} +31 -8
  4. package/dist/chunks/{index-dMbV_syB.es.js → index-DiSIyVKk.es.js} +31 -8
  5. package/dist/chunks/{super-editor.es-BKurmwFy.es.js → super-editor.es-4Ig7dBJr.es.js} +2846 -851
  6. package/dist/chunks/{super-editor.es-ly_a915J.cjs → super-editor.es-lzaBZOn2.cjs} +2846 -851
  7. package/dist/core/SuperDoc.d.ts.map +1 -1
  8. package/dist/stores/comments-store.d.ts.map +1 -1
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-Brf9NxwA.js → converter-BJVy6JMW.js} +1971 -636
  11. package/dist/super-editor/chunks/{docx-zipper-Dld3TtPb.js → docx-zipper-DWDJGX0b.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-N0dhAC41.js → editor-BUCOmU2Y.js} +1026 -410
  13. package/dist/super-editor/chunks/{toolbar-CXinz1gO.js → toolbar-CiBIcgiI.js} +2 -2
  14. package/dist/super-editor/converter.es.js +1 -1
  15. package/dist/super-editor/docx-zipper.es.js +2 -2
  16. package/dist/super-editor/editor.es.js +3 -3
  17. package/dist/super-editor/file-zipper.es.js +1 -1
  18. package/dist/super-editor/src/components/toolbar/format-negation.d.ts +5 -0
  19. package/dist/super-editor/src/core/commands/index.d.ts +1 -0
  20. package/dist/super-editor/src/core/commands/toggleMarkCascade.d.ts +42 -0
  21. package/dist/super-editor/src/core/commands/types/index.d.ts +29 -1
  22. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts +5 -0
  23. package/dist/super-editor/src/core/super-converter/exporter.d.ts +8 -0
  24. package/dist/super-editor/src/core/super-converter/helpers.d.ts +2 -0
  25. package/dist/super-editor/src/core/super-converter/v2/importer/markImporter.d.ts +12 -0
  26. package/dist/super-editor/src/core/super-converter/v2/importer/runNodeImporter.d.ts +6 -6
  27. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/east-asian-regex.d.ts +1 -0
  28. package/dist/super-editor/src/core/super-converter/v3/handlers/constants/index.d.ts +1 -0
  29. package/dist/super-editor/src/core/super-converter/v3/handlers/index.d.ts +2 -12
  30. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/index.d.ts +3 -0
  31. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/attributes/w-val.d.ts +4 -0
  32. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/b-translator.d.ts +7 -0
  33. package/dist/super-editor/src/core/super-converter/v3/handlers/w/b/index.d.ts +1 -0
  34. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/index.d.ts +2 -0
  35. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-color.d.ts +4 -0
  36. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-shade.d.ts +4 -0
  37. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-theme-tint.d.ts +4 -0
  38. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/attributes/w-val.d.ts +4 -0
  39. package/dist/super-editor/src/core/super-converter/v3/handlers/w/color/color-translator.d.ts +7 -0
  40. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/index.d.ts +2 -0
  41. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/attributes/w-val.d.ts +4 -0
  42. package/dist/super-editor/src/core/super-converter/v3/handlers/w/highlight/highlight-translator.d.ts +4 -0
  43. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/index.d.ts +2 -0
  44. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/attributes/w-val.d.ts +4 -0
  45. package/dist/super-editor/src/core/super-converter/v3/handlers/w/i/i-translator.d.ts +7 -0
  46. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/index.d.ts +2 -0
  47. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-del.d.ts +4 -0
  48. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r-pr.d.ts +4 -0
  49. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/attributes/w-rsid-r.d.ts +4 -0
  50. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/helpers.d.ts +40 -0
  51. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/index.d.ts +3 -0
  52. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/split-run-properties.d.ts +9 -0
  53. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/helpers/track-change-helpers.d.ts +5 -0
  54. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/index.d.ts +1 -0
  55. package/dist/super-editor/src/core/super-converter/v3/handlers/w/r/r-translator.d.ts +4 -0
  56. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/index.d.ts +2 -0
  57. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-ascii.d.ts +4 -0
  58. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-cs.d.ts +4 -0
  59. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-east-asia.d.ts +4 -0
  60. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-hansi.d.ts +4 -0
  61. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/attributes/w-val.d.ts +4 -0
  62. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/index.d.ts +1 -0
  63. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rFonts/rFonts-translator.d.ts +5 -0
  64. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/index.d.ts +2 -0
  65. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/attributes/w-val.d.ts +4 -0
  66. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/index.d.ts +1 -0
  67. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rStyle/rstyle-translator.d.ts +7 -0
  68. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/index.d.ts +1 -0
  69. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/rpr-translator.d.ts +5 -0
  70. package/dist/super-editor/src/core/super-converter/v3/handlers/w/rpr/run-property-translators.d.ts +11 -0
  71. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/index.d.ts +2 -0
  72. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/attributes/w-val.d.ts +4 -0
  73. package/dist/super-editor/src/core/super-converter/v3/handlers/w/strike/strike-translator.d.ts +7 -0
  74. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/index.d.ts +2 -0
  75. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/attributes/w-val.d.ts +4 -0
  76. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sz/sz-translator.d.ts +4 -0
  77. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/index.d.ts +2 -0
  78. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/attributes/w-val.d.ts +4 -0
  79. package/dist/super-editor/src/core/super-converter/v3/handlers/w/szcs/szcs-translator.d.ts +4 -0
  80. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/index.d.ts +2 -0
  81. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-color.d.ts +4 -0
  82. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-color.d.ts +4 -0
  83. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-shade.d.ts +4 -0
  84. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-theme-tint.d.ts +4 -0
  85. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/attributes/w-val.d.ts +4 -0
  86. package/dist/super-editor/src/core/super-converter/v3/handlers/w/u/u-translator.d.ts +7 -0
  87. package/dist/super-editor/src/extensions/index.d.ts +2 -2
  88. package/dist/super-editor/src/extensions/linked-styles/index.d.ts +1 -0
  89. package/dist/super-editor/src/extensions/linked-styles/underline-css.d.ts +17 -0
  90. package/dist/super-editor/src/extensions/list-item/helpers/listItemTypography.d.ts +62 -0
  91. package/dist/super-editor/src/extensions/run/commands/index.d.ts +1 -0
  92. package/dist/super-editor/src/extensions/run/commands/split-run.d.ts +1 -0
  93. package/dist/super-editor/src/extensions/run/index.d.ts +1 -0
  94. package/dist/super-editor/src/extensions/run/run.d.ts +6 -0
  95. package/dist/super-editor/src/extensions/shared/cascade-toggle.d.ts +8 -0
  96. package/dist/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +12 -0
  97. package/dist/super-editor/src/extensions/tab/tab.d.ts +4 -0
  98. package/dist/super-editor/src/tests/helpers/getParagraphText.d.ts +2 -0
  99. package/dist/super-editor/super-editor.es.js +90 -21
  100. package/dist/super-editor/toolbar.es.js +2 -2
  101. package/dist/super-editor.cjs +1 -1
  102. package/dist/super-editor.es.js +1 -1
  103. package/dist/superdoc.cjs +2 -2
  104. package/dist/superdoc.es.js +2 -2
  105. package/dist/superdoc.umd.js +2877 -859
  106. package/dist/superdoc.umd.js.map +1 -1
  107. package/package.json +1 -1
@@ -14888,25 +14888,47 @@ const getContentTypesFromXml = (contentTypesXml) => {
14888
14888
  const defaults = xmlDoc.querySelectorAll("Default");
14889
14889
  return Array.from(defaults).map((item) => item.getAttribute("Extension"));
14890
14890
  };
14891
+ const DOCX_HIGHLIGHT_KEYWORD_MAP = /* @__PURE__ */ new Map([
14892
+ ["yellow", "FFFF00"],
14893
+ ["green", "00FF00"],
14894
+ ["blue", "0000FF"],
14895
+ ["cyan", "00FFFF"],
14896
+ ["magenta", "FF00FF"],
14897
+ ["red", "FF0000"],
14898
+ ["darkYellow", "808000"],
14899
+ ["darkGreen", "008000"],
14900
+ ["darkBlue", "000080"],
14901
+ ["darkCyan", "008080"],
14902
+ ["darkMagenta", "800080"],
14903
+ ["darkGray", "808080"],
14904
+ ["darkRed", "800000"],
14905
+ ["lightGray", "C0C0C0"],
14906
+ ["black", "000000"],
14907
+ ["white", "FFFFFF"]
14908
+ ]);
14909
+ const normalizeHexColor = (hex2) => {
14910
+ if (!hex2) return null;
14911
+ let value = hex2.replace("#", "").trim();
14912
+ if (!value) return null;
14913
+ value = value.toUpperCase();
14914
+ if (value.length === 3)
14915
+ value = value.split("").map((c2) => c2 + c2).join("");
14916
+ if (value.length === 8) value = value.slice(0, 6);
14917
+ return value;
14918
+ };
14891
14919
  const getHexColorFromDocxSystem = (docxColor) => {
14892
- const colorMap = /* @__PURE__ */ new Map([
14893
- ["yellow", "#ffff00"],
14894
- ["green", "#00ff00"],
14895
- ["blue", "#0000FFFF"],
14896
- ["cyan", "#00ffff"],
14897
- ["magenta", "#ff00ff"],
14898
- ["red", "#ff0000"],
14899
- ["darkYellow", "#808000FF"],
14900
- ["darkGreen", "#008000FF"],
14901
- ["darkBlue", "#000080"],
14902
- ["darkCyan", "#008080FF"],
14903
- ["darkMagenta", "#800080FF"],
14904
- ["darkGray", "#808080FF"],
14905
- ["darkRed", "#800000FF"],
14906
- ["lightGray", "#C0C0C0FF"],
14907
- ["black", "#000"]
14908
- ]);
14909
- return colorMap.get(docxColor) || null;
14920
+ const hex2 = DOCX_HIGHLIGHT_KEYWORD_MAP.get(docxColor);
14921
+ return hex2 ? `#${hex2}` : null;
14922
+ };
14923
+ const getDocxHighlightKeywordFromHex = (hexColor) => {
14924
+ if (!hexColor) return null;
14925
+ if (DOCX_HIGHLIGHT_KEYWORD_MAP.has(hexColor)) return hexColor;
14926
+ const normalized = normalizeHexColor(hexColor);
14927
+ if (!normalized) return null;
14928
+ for (const [keyword, hex2] of DOCX_HIGHLIGHT_KEYWORD_MAP.entries()) {
14929
+ if (hex2 === normalized) return keyword;
14930
+ }
14931
+ return null;
14910
14932
  };
14911
14933
  function isValidHexColor(color) {
14912
14934
  if (!color || typeof color !== "string") return false;
@@ -24294,37 +24316,37 @@ const _NodeTranslator = class _NodeTranslator2 {
24294
24316
  };
24295
24317
  __publicField$2(_NodeTranslator, "translatorTypes", TranslatorTypes);
24296
24318
  let NodeTranslator = _NodeTranslator;
24297
- const encode$A = (attributes) => {
24319
+ const encode$17 = (attributes) => {
24298
24320
  return attributes["w:type"];
24299
24321
  };
24300
- const decode$A = (attrs) => {
24322
+ const decode$_ = (attrs) => {
24301
24323
  const { lineBreakType } = attrs;
24302
24324
  return lineBreakType;
24303
24325
  };
24304
- const attrConfig$i = Object.freeze({
24326
+ const attrConfig$F = Object.freeze({
24305
24327
  xmlName: "w:type",
24306
24328
  sdName: "lineBreakType",
24307
- encode: encode$A,
24308
- decode: decode$A
24329
+ encode: encode$17,
24330
+ decode: decode$_
24309
24331
  });
24310
- const encode$z = (attributes) => {
24332
+ const encode$16 = (attributes) => {
24311
24333
  const xmlAttrValue = attributes["w:clear"];
24312
24334
  return xmlAttrValue;
24313
24335
  };
24314
- const decode$z = (attrs) => {
24336
+ const decode$Z = (attrs) => {
24315
24337
  const { clear } = attrs;
24316
24338
  return clear;
24317
24339
  };
24318
- const attrConfig$h = Object.freeze({
24340
+ const attrConfig$E = Object.freeze({
24319
24341
  xmlName: "w:clear",
24320
24342
  sdName: "clear",
24321
- encode: encode$z,
24322
- decode: decode$z
24343
+ encode: encode$16,
24344
+ decode: decode$Z
24323
24345
  });
24324
- const validXmlAttributes$b = [attrConfig$i, attrConfig$h];
24325
- const XML_NODE_NAME$h = "w:br";
24346
+ const validXmlAttributes$l = [attrConfig$F, attrConfig$E];
24347
+ const XML_NODE_NAME$t = "w:br";
24326
24348
  const SD_NODE_NAME$c = "lineBreak";
24327
- const encode$y = (_2, encodedAttrs) => {
24349
+ const encode$15 = (_2, encodedAttrs) => {
24328
24350
  const isPageBreak = encodedAttrs?.lineBreakType === "page";
24329
24351
  const translated = {
24330
24352
  type: isPageBreak ? "hardBreak" : "lineBreak"
@@ -24334,7 +24356,7 @@ const encode$y = (_2, encodedAttrs) => {
24334
24356
  }
24335
24357
  return translated;
24336
24358
  };
24337
- const decode$y = (params2, decodedAttrs) => {
24359
+ const decode$Y = (params2, decodedAttrs) => {
24338
24360
  const { node } = params2;
24339
24361
  if (!node) return;
24340
24362
  const wBreak = { name: "w:br" };
@@ -24351,63 +24373,125 @@ const decode$y = (params2, decodedAttrs) => {
24351
24373
  };
24352
24374
  return translated;
24353
24375
  };
24354
- const config$f = {
24355
- xmlName: XML_NODE_NAME$h,
24376
+ const config$r = {
24377
+ xmlName: XML_NODE_NAME$t,
24356
24378
  sdNodeOrKeyName: SD_NODE_NAME$c,
24357
24379
  type: NodeTranslator.translatorTypes.NODE,
24358
- encode: encode$y,
24359
- decode: decode$y,
24360
- attributes: validXmlAttributes$b
24380
+ encode: encode$15,
24381
+ decode: decode$Y,
24382
+ attributes: validXmlAttributes$l
24383
+ };
24384
+ const translator$15 = NodeTranslator.from(config$r);
24385
+ const encode$14 = (attributes) => attributes?.["w:val"];
24386
+ const decode$X = (attrs) => attrs?.highlight;
24387
+ const attrConfig$D = Object.freeze({
24388
+ xmlName: "w:val",
24389
+ sdName: "highlight",
24390
+ encode: encode$14,
24391
+ decode: decode$X
24392
+ });
24393
+ const validXmlAttributes$k = [attrConfig$D];
24394
+ const XML_NODE_NAME$s = "w:highlight";
24395
+ const SD_ATTR_KEY$f = "highlight";
24396
+ const DISABLED_TOKENS = /* @__PURE__ */ new Set(["transparent", "none", "inherit"]);
24397
+ const encode$13 = (params2, encodedAttrs = {}) => {
24398
+ const { nodes } = params2;
24399
+ const node = nodes?.[0];
24400
+ const value = encodedAttrs.highlight ?? node?.attributes?.["w:val"];
24401
+ return {
24402
+ type: "attr",
24403
+ xmlName: XML_NODE_NAME$s,
24404
+ sdNodeOrKeyName: SD_ATTR_KEY$f,
24405
+ attributes: { "w:val": value ?? null }
24406
+ };
24407
+ };
24408
+ const decode$W = (params2) => {
24409
+ const attrs = params2?.node?.attrs || {};
24410
+ const highlightValue = attrs.highlight ?? attrs.color ?? null;
24411
+ if (!highlightValue) return void 0;
24412
+ const normalizedValue = String(highlightValue).trim().toLowerCase();
24413
+ if (!normalizedValue) return void 0;
24414
+ if (DISABLED_TOKENS.has(normalizedValue)) {
24415
+ return {
24416
+ name: XML_NODE_NAME$s,
24417
+ attributes: { "w:val": "none" }
24418
+ };
24419
+ }
24420
+ const keyword = getDocxHighlightKeywordFromHex(highlightValue);
24421
+ if (keyword) {
24422
+ return {
24423
+ name: XML_NODE_NAME$s,
24424
+ attributes: { "w:val": keyword }
24425
+ };
24426
+ }
24427
+ const fill = normalizeHexColor(highlightValue);
24428
+ if (!fill) return void 0;
24429
+ return {
24430
+ name: "w:shd",
24431
+ attributes: {
24432
+ "w:color": "auto",
24433
+ "w:val": "clear",
24434
+ "w:fill": fill
24435
+ }
24436
+ };
24361
24437
  };
24362
- const translator$V = NodeTranslator.from(config$f);
24363
- const encode$x = (attributes) => {
24438
+ const config$q = {
24439
+ xmlName: XML_NODE_NAME$s,
24440
+ sdNodeOrKeyName: SD_ATTR_KEY$f,
24441
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
24442
+ encode: encode$13,
24443
+ decode: decode$W,
24444
+ attributes: validXmlAttributes$k
24445
+ };
24446
+ const translator$14 = NodeTranslator.from(config$q);
24447
+ const encode$12 = (attributes) => {
24364
24448
  return attributes["w:val"];
24365
24449
  };
24366
- const decode$x = (attrs) => {
24450
+ const decode$V = (attrs) => {
24367
24451
  const { tabSize } = attrs || {};
24368
24452
  return tabSize;
24369
24453
  };
24370
- const attrConfig$g = Object.freeze({
24454
+ const attrConfig$C = Object.freeze({
24371
24455
  xmlName: "w:val",
24372
24456
  sdName: "tabSize",
24373
- encode: encode$x,
24374
- decode: decode$x
24457
+ encode: encode$12,
24458
+ decode: decode$V
24375
24459
  });
24376
- const encode$w = (attributes) => {
24460
+ const encode$11 = (attributes) => {
24377
24461
  return attributes["w:leader"];
24378
24462
  };
24379
- const decode$w = (attrs) => {
24463
+ const decode$U = (attrs) => {
24380
24464
  const { leader } = attrs || {};
24381
24465
  return leader;
24382
24466
  };
24383
- const attrConfig$f = Object.freeze({
24467
+ const attrConfig$B = Object.freeze({
24384
24468
  xmlName: "w:leader",
24385
24469
  sdName: "leader",
24386
- encode: encode$w,
24387
- decode: decode$w
24470
+ encode: encode$11,
24471
+ decode: decode$U
24388
24472
  });
24389
- const encode$v = (attributes) => {
24473
+ const encode$10 = (attributes) => {
24390
24474
  return attributes["w:pos"];
24391
24475
  };
24392
- const decode$v = (attrs) => {
24476
+ const decode$T = (attrs) => {
24393
24477
  const { pos } = attrs || {};
24394
24478
  return pos;
24395
24479
  };
24396
- const attrConfig$e = Object.freeze({
24480
+ const attrConfig$A = Object.freeze({
24397
24481
  xmlName: "w:pos",
24398
24482
  sdName: "pos",
24399
- encode: encode$v,
24400
- decode: decode$v
24483
+ encode: encode$10,
24484
+ decode: decode$T
24401
24485
  });
24402
- const validXmlAttributes$a = [attrConfig$g, attrConfig$e, attrConfig$f];
24403
- const XML_NODE_NAME$g = "w:tab";
24486
+ const validXmlAttributes$j = [attrConfig$C, attrConfig$A, attrConfig$B];
24487
+ const XML_NODE_NAME$r = "w:tab";
24404
24488
  const SD_NODE_NAME$b = "tab";
24405
- const encode$u = (_2, encodedAttrs = {}) => {
24489
+ const encode$$ = (_2, encodedAttrs = {}) => {
24406
24490
  const translated = { type: "tab" };
24407
24491
  if (encodedAttrs) translated.attrs = { ...encodedAttrs };
24408
24492
  return translated;
24409
24493
  };
24410
- const decode$u = (params2, decodedAttrs = {}) => {
24494
+ const decode$S = (params2, decodedAttrs = {}) => {
24411
24495
  const { node } = params2 || {};
24412
24496
  if (!node) return;
24413
24497
  const wTab = { name: "w:tab" };
@@ -24423,15 +24507,15 @@ const decode$u = (params2, decodedAttrs = {}) => {
24423
24507
  }
24424
24508
  return translated;
24425
24509
  };
24426
- const config$e = {
24427
- xmlName: XML_NODE_NAME$g,
24510
+ const config$p = {
24511
+ xmlName: XML_NODE_NAME$r,
24428
24512
  sdNodeOrKeyName: SD_NODE_NAME$b,
24429
24513
  type: NodeTranslator.translatorTypes.NODE,
24430
- encode: encode$u,
24431
- decode: decode$u,
24432
- attributes: validXmlAttributes$a
24514
+ encode: encode$$,
24515
+ decode: decode$S,
24516
+ attributes: validXmlAttributes$j
24433
24517
  };
24434
- const translator$U = NodeTranslator.from(config$e);
24518
+ const translator$13 = NodeTranslator.from(config$p);
24435
24519
  const mergeTextNodes = (nodes) => {
24436
24520
  if (!nodes || !Array.isArray(nodes)) {
24437
24521
  return nodes;
@@ -24606,17 +24690,21 @@ function getMarkValue(markType, attributes, docx) {
24606
24690
  function getFontFamilyValue(attributes, docx) {
24607
24691
  const ascii = attributes["w:ascii"];
24608
24692
  const themeAscii = attributes["w:asciiTheme"];
24609
- if (!docx || !themeAscii) return ascii;
24610
- const theme = docx["word/theme/theme1.xml"];
24611
- if (!theme) return ascii;
24612
- const { elements: topElements } = theme;
24613
- const { elements } = topElements[0];
24614
- const themeElements = elements.find((el) => el.name === "a:themeElements");
24615
- const fontScheme = themeElements.elements.find((el) => el.name === "a:fontScheme");
24616
- const majorFont = fontScheme.elements.find((el) => el.name === "a:majorFont");
24617
- const latin = majorFont.elements.find((el) => el.name === "a:latin");
24618
- const typeface = latin.attributes["typeface"];
24619
- return typeface;
24693
+ let resolved = ascii;
24694
+ if (docx && themeAscii) {
24695
+ const theme = docx["word/theme/theme1.xml"];
24696
+ if (theme?.elements?.length) {
24697
+ const { elements: topElements } = theme;
24698
+ const { elements } = topElements[0] || {};
24699
+ const themeElements = elements?.find((el) => el.name === "a:themeElements");
24700
+ const fontScheme = themeElements?.elements?.find((el) => el.name === "a:fontScheme");
24701
+ const majorFont = fontScheme?.elements?.find((el) => el.name === "a:majorFont");
24702
+ const latin = majorFont?.elements?.find((el) => el.name === "a:latin");
24703
+ resolved = latin?.attributes?.typeface || resolved;
24704
+ }
24705
+ }
24706
+ if (!resolved) return null;
24707
+ return SuperConverter.toCssFontFamily(resolved, docx);
24620
24708
  }
24621
24709
  function getIndentValue(attributes) {
24622
24710
  let value = attributes["w:left"];
@@ -24637,7 +24725,11 @@ function getHighLightValue(attributes) {
24637
24725
  return getHexColorFromDocxSystem(attributes?.["w:val"]) || null;
24638
24726
  }
24639
24727
  function getStrikeValue(attributes) {
24640
- return attributes?.["w:val"] === "1" ? attributes["w:val"] : null;
24728
+ const raw = attributes?.["w:val"];
24729
+ if (raw === void 0 || raw === null) return "1";
24730
+ const value = String(raw).trim().toLowerCase();
24731
+ if (value === "1" || value === "true" || value === "on") return "1";
24732
+ return null;
24641
24733
  }
24642
24734
  const parseParagraphBorders = (pBdr) => {
24643
24735
  if (!pBdr || !pBdr.elements) return {};
@@ -24667,27 +24759,39 @@ const getParagraphIndent = (node, docx, styleId = "") => {
24667
24759
  right: 0,
24668
24760
  firstLine: 0,
24669
24761
  hanging: 0,
24670
- textIndent: 0
24762
+ textIndent: 0,
24763
+ explicitLeft: false,
24764
+ explicitRight: false,
24765
+ explicitFirstLine: false,
24766
+ explicitHanging: false
24671
24767
  };
24672
24768
  const { indent: pDefaultIndent = {} } = getDefaultParagraphStyle(docx, styleId);
24673
24769
  const pPr = node.elements?.find((el) => el.name === "w:pPr");
24674
24770
  const inLineIndentTag = pPr?.elements?.find((el) => el.name === "w:ind");
24675
24771
  const inLineIndent = inLineIndentTag?.attributes || {};
24676
- const leftIndent = inLineIndent?.["w:left"] || pDefaultIndent?.["w:left"];
24677
- const rightIndent = inLineIndent?.["w:right"] || pDefaultIndent?.["w:right"];
24678
- const firstLine = inLineIndent?.["w:firstLine"] || pDefaultIndent?.["w:firstLine"];
24679
- const hanging = inLineIndent?.["w:hanging"] || pDefaultIndent?.["w:hanging"];
24772
+ const inlineLeft = inLineIndent?.["w:left"];
24773
+ const inlineRight = inLineIndent?.["w:right"];
24774
+ const inlineFirstLine = inLineIndent?.["w:firstLine"];
24775
+ const inlineHanging = inLineIndent?.["w:hanging"];
24776
+ const leftIndent = inlineLeft ?? pDefaultIndent?.["w:left"];
24777
+ const rightIndent = inlineRight ?? pDefaultIndent?.["w:right"];
24778
+ const firstLine = inlineFirstLine ?? pDefaultIndent?.["w:firstLine"];
24779
+ const hanging = inlineHanging ?? pDefaultIndent?.["w:hanging"];
24680
24780
  if (leftIndent) {
24681
24781
  indent.left = twipsToPixels(leftIndent);
24782
+ indent.explicitLeft = inlineLeft !== void 0;
24682
24783
  }
24683
24784
  if (rightIndent) {
24684
24785
  indent.right = twipsToPixels(rightIndent);
24786
+ indent.explicitRight = inlineRight !== void 0;
24685
24787
  }
24686
24788
  if (firstLine) {
24687
24789
  indent.firstLine = twipsToPixels(firstLine);
24790
+ indent.explicitFirstLine = inlineFirstLine !== void 0;
24688
24791
  }
24689
24792
  if (hanging) {
24690
24793
  indent.hanging = twipsToPixels(hanging);
24794
+ indent.explicitHanging = inlineHanging !== void 0;
24691
24795
  }
24692
24796
  const textIndentValue = leftIndent - parseInt(hanging || 0) || 0;
24693
24797
  if (textIndentValue) {
@@ -25026,102 +25130,102 @@ const handleParagraphNode$1 = (params2) => {
25026
25130
  }
25027
25131
  return schemaNode;
25028
25132
  };
25029
- const encode$t = (attributes) => {
25133
+ const encode$_ = (attributes) => {
25030
25134
  return attributes["w:rsidDel"];
25031
25135
  };
25032
- const decode$t = (attrs) => {
25136
+ const decode$R = (attrs) => {
25033
25137
  return attrs.rsidDel;
25034
25138
  };
25035
- const attrConfig$d = Object.freeze({
25139
+ const attrConfig$z = Object.freeze({
25036
25140
  xmlName: "w:rsidDel",
25037
25141
  sdName: "rsidDel",
25038
- encode: encode$t,
25039
- decode: decode$t
25142
+ encode: encode$_,
25143
+ decode: decode$R
25040
25144
  });
25041
- const encode$s = (attributes) => {
25145
+ const encode$Z = (attributes) => {
25042
25146
  return attributes["w:rsidP"];
25043
25147
  };
25044
- const decode$s = (attrs) => {
25148
+ const decode$Q = (attrs) => {
25045
25149
  return attrs.rsidP;
25046
25150
  };
25047
- const attrConfig$c = Object.freeze({
25151
+ const attrConfig$y = Object.freeze({
25048
25152
  xmlName: "w:rsidP",
25049
25153
  sdName: "rsidP",
25050
- encode: encode$s,
25051
- decode: decode$s
25154
+ encode: encode$Z,
25155
+ decode: decode$Q
25052
25156
  });
25053
- const encode$r = (attributes) => {
25157
+ const encode$Y = (attributes) => {
25054
25158
  return attributes["w:rsidR"];
25055
25159
  };
25056
- const decode$r = (attrs) => {
25160
+ const decode$P = (attrs) => {
25057
25161
  return attrs.rsidR;
25058
25162
  };
25059
- const attrConfig$b = Object.freeze({
25163
+ const attrConfig$x = Object.freeze({
25060
25164
  xmlName: "w:rsidR",
25061
25165
  sdName: "rsidR",
25062
- encode: encode$r,
25063
- decode: decode$r
25166
+ encode: encode$Y,
25167
+ decode: decode$P
25064
25168
  });
25065
- const encode$q = (attributes) => {
25169
+ const encode$X = (attributes) => {
25066
25170
  return attributes["w:rsidRPr"];
25067
25171
  };
25068
- const decode$q = (attrs) => {
25172
+ const decode$O = (attrs) => {
25069
25173
  return attrs.rsidRPr;
25070
25174
  };
25071
- const attrConfig$a = Object.freeze({
25175
+ const attrConfig$w = Object.freeze({
25072
25176
  xmlName: "w:rsidRPr",
25073
25177
  sdName: "rsidRPr",
25074
- encode: encode$q,
25075
- decode: decode$q
25178
+ encode: encode$X,
25179
+ decode: decode$O
25076
25180
  });
25077
- const encode$p = (attributes) => {
25181
+ const encode$W = (attributes) => {
25078
25182
  return attributes["w:rsidRDefault"];
25079
25183
  };
25080
- const decode$p = (attrs) => {
25184
+ const decode$N = (attrs) => {
25081
25185
  return attrs.rsidRDefault;
25082
25186
  };
25083
- const attrConfig$9 = Object.freeze({
25187
+ const attrConfig$v = Object.freeze({
25084
25188
  xmlName: "w:rsidRDefault",
25085
25189
  sdName: "rsidRDefault",
25086
- encode: encode$p,
25087
- decode: decode$p
25190
+ encode: encode$W,
25191
+ decode: decode$N
25088
25192
  });
25089
- const encode$o = (attributes) => {
25193
+ const encode$V = (attributes) => {
25090
25194
  return attributes["w14:paraId"];
25091
25195
  };
25092
- const decode$o = (attrs) => {
25196
+ const decode$M = (attrs) => {
25093
25197
  return attrs.paraId;
25094
25198
  };
25095
- const attrConfig$8 = Object.freeze({
25199
+ const attrConfig$u = Object.freeze({
25096
25200
  xmlName: "w14:paraId",
25097
25201
  sdName: "paraId",
25098
- encode: encode$o,
25099
- decode: decode$o
25202
+ encode: encode$V,
25203
+ decode: decode$M
25100
25204
  });
25101
- const encode$n = (attributes) => {
25205
+ const encode$U = (attributes) => {
25102
25206
  return attributes["w14:textId"];
25103
25207
  };
25104
- const decode$n = (attrs) => {
25208
+ const decode$L = (attrs) => {
25105
25209
  return attrs.textId;
25106
25210
  };
25107
- const attrConfig$7 = Object.freeze({
25211
+ const attrConfig$t = Object.freeze({
25108
25212
  xmlName: "w14:textId",
25109
25213
  sdName: "textId",
25110
- encode: encode$n,
25111
- decode: decode$n
25214
+ encode: encode$U,
25215
+ decode: decode$L
25112
25216
  });
25113
- const validXmlAttributes$9 = [
25114
- attrConfig$8,
25115
- attrConfig$7,
25116
- attrConfig$b,
25117
- attrConfig$9,
25118
- attrConfig$c,
25119
- attrConfig$a,
25120
- attrConfig$d
25217
+ const validXmlAttributes$i = [
25218
+ attrConfig$u,
25219
+ attrConfig$t,
25220
+ attrConfig$x,
25221
+ attrConfig$v,
25222
+ attrConfig$y,
25223
+ attrConfig$w,
25224
+ attrConfig$z
25121
25225
  ];
25122
- const XML_NODE_NAME$f = "w:p";
25226
+ const XML_NODE_NAME$q = "w:p";
25123
25227
  const SD_NODE_NAME$a = "paragraph";
25124
- const encode$m = (params2, encodedAttrs = {}) => {
25228
+ const encode$T = (params2, encodedAttrs = {}) => {
25125
25229
  const node = handleParagraphNode$1(params2);
25126
25230
  if (!node) return void 0;
25127
25231
  if (encodedAttrs && Object.keys(encodedAttrs).length) {
@@ -25129,7 +25233,7 @@ const encode$m = (params2, encodedAttrs = {}) => {
25129
25233
  }
25130
25234
  return node;
25131
25235
  };
25132
- const decode$m = (params2, decodedAttrs = {}) => {
25236
+ const decode$K = (params2, decodedAttrs = {}) => {
25133
25237
  const translated = translateParagraphNode(params2);
25134
25238
  if (!translated) return void 0;
25135
25239
  if (decodedAttrs && Object.keys(decodedAttrs).length) {
@@ -25137,9 +25241,1164 @@ const decode$m = (params2, decodedAttrs = {}) => {
25137
25241
  }
25138
25242
  return translated;
25139
25243
  };
25244
+ const config$o = {
25245
+ xmlName: XML_NODE_NAME$q,
25246
+ sdNodeOrKeyName: SD_NODE_NAME$a,
25247
+ type: NodeTranslator.translatorTypes.NODE,
25248
+ encode: encode$T,
25249
+ decode: decode$K,
25250
+ attributes: validXmlAttributes$i
25251
+ };
25252
+ const translator$12 = NodeTranslator.from(config$o);
25253
+ const encode$S = (attributes) => {
25254
+ const raw = attributes?.["w:val"];
25255
+ if (raw === void 0 || raw === null) return void 0;
25256
+ if (typeof raw === "boolean") return raw;
25257
+ if (typeof raw === "number") return raw !== 0;
25258
+ const val = String(raw).trim().toLowerCase();
25259
+ if (val === "0" || val === "false" || val === "off") return false;
25260
+ if (val === "1" || val === "true" || val === "on") return true;
25261
+ return void 0;
25262
+ };
25263
+ const decode$J = (runProps) => {
25264
+ if (runProps?.bold === false) return "0";
25265
+ return void 0;
25266
+ };
25267
+ const attrConfig$s = Object.freeze({
25268
+ xmlName: "w:val",
25269
+ sdName: "bold",
25270
+ encode: encode$S,
25271
+ decode: decode$J
25272
+ });
25273
+ const validXmlAttributes$h = [attrConfig$s];
25274
+ const XML_NODE_NAME$p = "w:b";
25275
+ const SD_ATTR_KEY$e = "bold";
25276
+ const encode$R = (params2, encodedAttrs = {}) => {
25277
+ const { nodes } = params2;
25278
+ const node = nodes[0];
25279
+ if (!node) return void 0;
25280
+ const val = encodedAttrs?.[SD_ATTR_KEY$e];
25281
+ let attributes;
25282
+ if (val === false) attributes = { "w:val": "0" };
25283
+ else if (val === true)
25284
+ attributes = {};
25285
+ else attributes = node.attributes || {};
25286
+ return {
25287
+ type: "attr",
25288
+ xmlName: XML_NODE_NAME$p,
25289
+ sdNodeOrKeyName: SD_ATTR_KEY$e,
25290
+ attributes
25291
+ };
25292
+ };
25293
+ const config$n = {
25294
+ xmlName: XML_NODE_NAME$p,
25295
+ sdNodeOrKeyName: SD_ATTR_KEY$e,
25296
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25297
+ encode: encode$R,
25298
+ attributes: validXmlAttributes$h
25299
+ };
25300
+ const translator$11 = NodeTranslator.from(config$n);
25301
+ const XML_NODE_NAME$o = "w:i";
25302
+ const SD_ATTR_KEY$d = "italic";
25303
+ const encode$Q = (params2) => {
25304
+ const { nodes } = params2;
25305
+ const node = nodes?.[0];
25306
+ if (!node) return void 0;
25307
+ return {
25308
+ type: "attr",
25309
+ xmlName: XML_NODE_NAME$o,
25310
+ sdNodeOrKeyName: SD_ATTR_KEY$d,
25311
+ attributes: {
25312
+ "w:val": node.attributes?.["w:val"] ?? null
25313
+ }
25314
+ };
25315
+ };
25316
+ const config$m = {
25317
+ xmlName: XML_NODE_NAME$o,
25318
+ sdNodeOrKeyName: SD_ATTR_KEY$d,
25319
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25320
+ encode: encode$Q
25321
+ };
25322
+ const translator$10 = NodeTranslator.from(config$m);
25323
+ const encode$P = (attributes) => attributes?.["w:val"];
25324
+ const decode$I = (attrs) => attrs?.underline;
25325
+ const attrConfig$r = Object.freeze({
25326
+ xmlName: "w:val",
25327
+ sdName: "underline",
25328
+ encode: encode$P,
25329
+ decode: decode$I
25330
+ });
25331
+ const encode$O = (attributes) => attributes?.["w:color"];
25332
+ const decode$H = (attrs) => attrs?.color;
25333
+ const attrConfig$q = Object.freeze({
25334
+ xmlName: "w:color",
25335
+ sdName: "color",
25336
+ encode: encode$O,
25337
+ decode: decode$H
25338
+ });
25339
+ const encode$N = (attributes) => attributes?.["w:themeColor"];
25340
+ const decode$G = (attrs) => attrs?.themeColor;
25341
+ const attrConfig$p = Object.freeze({
25342
+ xmlName: "w:themeColor",
25343
+ sdName: "themeColor",
25344
+ encode: encode$N,
25345
+ decode: decode$G
25346
+ });
25347
+ const encode$M = (attributes) => attributes?.["w:themeTint"];
25348
+ const decode$F = (attrs) => attrs?.themeTint;
25349
+ const attrConfig$o = Object.freeze({
25350
+ xmlName: "w:themeTint",
25351
+ sdName: "themeTint",
25352
+ encode: encode$M,
25353
+ decode: decode$F
25354
+ });
25355
+ const encode$L = (attributes) => attributes?.["w:themeShade"];
25356
+ const decode$E = (attrs) => attrs?.themeShade;
25357
+ const attrConfig$n = Object.freeze({
25358
+ xmlName: "w:themeShade",
25359
+ sdName: "themeShade",
25360
+ encode: encode$L,
25361
+ decode: decode$E
25362
+ });
25363
+ const validXmlAttributes$g = [attrConfig$r, attrConfig$q, attrConfig$p, attrConfig$o, attrConfig$n];
25364
+ const XML_NODE_NAME$n = "w:u";
25365
+ const SD_ATTR_KEY$c = "underline";
25366
+ const encode$K = (params2, encodedAttrs = {}) => {
25367
+ const { nodes } = params2;
25368
+ const node = nodes?.[0];
25369
+ const sourceAttrs = node?.attributes || {};
25370
+ const underlineType = encodedAttrs.underline ?? sourceAttrs["w:val"];
25371
+ const color = encodedAttrs.color ?? sourceAttrs["w:color"];
25372
+ const themeColor = encodedAttrs.themeColor ?? sourceAttrs["w:themeColor"];
25373
+ const themeTint = encodedAttrs.themeTint ?? sourceAttrs["w:themeTint"];
25374
+ const themeShade = encodedAttrs.themeShade ?? sourceAttrs["w:themeShade"];
25375
+ const attributes = { "w:val": underlineType ?? null };
25376
+ if (color !== void 0 && color !== null) attributes["w:color"] = color;
25377
+ if (themeColor !== void 0 && themeColor !== null) attributes["w:themeColor"] = themeColor;
25378
+ if (themeTint !== void 0 && themeTint !== null) attributes["w:themeTint"] = themeTint;
25379
+ if (themeShade !== void 0 && themeShade !== null) attributes["w:themeShade"] = themeShade;
25380
+ return {
25381
+ type: "attr",
25382
+ xmlName: XML_NODE_NAME$n,
25383
+ sdNodeOrKeyName: SD_ATTR_KEY$c,
25384
+ attributes
25385
+ };
25386
+ };
25387
+ const decode$D = (params2) => {
25388
+ const attrs = params2?.node?.attrs || {};
25389
+ const underlineType = attrs.underlineType ?? attrs.underline ?? null;
25390
+ const color = attrs.underlineColor ?? attrs.color ?? null;
25391
+ const themeColor = attrs.underlineThemeColor ?? attrs.themeColor ?? null;
25392
+ const themeTint = attrs.underlineThemeTint ?? attrs.themeTint ?? null;
25393
+ const themeShade = attrs.underlineThemeShade ?? attrs.themeShade ?? null;
25394
+ if (!underlineType && !color && !themeColor && !themeTint && !themeShade) return void 0;
25395
+ const attributes = {};
25396
+ if (underlineType) attributes["w:val"] = underlineType;
25397
+ if (color) {
25398
+ const normalized = normalizeHexColor(color);
25399
+ if (normalized) attributes["w:color"] = normalized;
25400
+ }
25401
+ if (themeColor) attributes["w:themeColor"] = themeColor;
25402
+ if (themeTint) attributes["w:themeTint"] = themeTint;
25403
+ if (themeShade) attributes["w:themeShade"] = themeShade;
25404
+ return {
25405
+ name: XML_NODE_NAME$n,
25406
+ attributes
25407
+ };
25408
+ };
25409
+ const config$l = {
25410
+ xmlName: XML_NODE_NAME$n,
25411
+ sdNodeOrKeyName: SD_ATTR_KEY$c,
25412
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25413
+ encode: encode$K,
25414
+ decode: decode$D,
25415
+ attributes: validXmlAttributes$g
25416
+ };
25417
+ const translator$$ = NodeTranslator.from(config$l);
25418
+ const encode$J = (attributes) => {
25419
+ const raw = attributes?.["w:val"];
25420
+ if (raw === void 0 || raw === null) return void 0;
25421
+ if (typeof raw === "boolean") return raw;
25422
+ if (typeof raw === "number") return raw !== 0;
25423
+ const val = String(raw).trim().toLowerCase();
25424
+ if (val === "0" || val === "false" || val === "off") return false;
25425
+ if (val === "1" || val === "true" || val === "on") return true;
25426
+ return void 0;
25427
+ };
25428
+ const decode$C = (attrs) => {
25429
+ if (attrs?.strike === false) return "0";
25430
+ return void 0;
25431
+ };
25432
+ const attrConfig$m = Object.freeze({
25433
+ xmlName: "w:val",
25434
+ sdName: "strike",
25435
+ encode: encode$J,
25436
+ decode: decode$C
25437
+ });
25438
+ const validXmlAttributes$f = [attrConfig$m];
25439
+ const XML_NODE_NAME$m = "w:strike";
25440
+ const SD_ATTR_KEY$b = "strike";
25441
+ const encode$I = (params2, encodedAttrs = {}) => {
25442
+ const { nodes } = params2;
25443
+ const node = nodes?.[0];
25444
+ if (!node) return void 0;
25445
+ const val = encodedAttrs?.[SD_ATTR_KEY$b];
25446
+ let attributes;
25447
+ if (val === false) attributes = { "w:val": "0" };
25448
+ else if (val === true) attributes = {};
25449
+ else attributes = { ...node.attributes || {} };
25450
+ if (attributes["w:val"] === void 0 && val !== true) attributes["w:val"] = null;
25451
+ else if (val === true && attributes["w:val"] === void 0) delete attributes["w:val"];
25452
+ return {
25453
+ type: "attr",
25454
+ xmlName: XML_NODE_NAME$m,
25455
+ sdNodeOrKeyName: SD_ATTR_KEY$b,
25456
+ attributes
25457
+ };
25458
+ };
25459
+ const config$k = {
25460
+ xmlName: XML_NODE_NAME$m,
25461
+ sdNodeOrKeyName: SD_ATTR_KEY$b,
25462
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25463
+ encode: encode$I,
25464
+ attributes: validXmlAttributes$f
25465
+ };
25466
+ const translator$_ = NodeTranslator.from(config$k);
25467
+ const encode$H = (attributes) => attributes?.["w:val"];
25468
+ const decode$B = (attrs) => attrs?.color;
25469
+ const attrConfig$l = Object.freeze({
25470
+ xmlName: "w:val",
25471
+ sdName: "color",
25472
+ encode: encode$H,
25473
+ decode: decode$B
25474
+ });
25475
+ const encode$G = (attributes) => attributes?.["w:themeColor"];
25476
+ const decode$A = (attrs) => attrs?.themeColor;
25477
+ const attrConfig$k = Object.freeze({
25478
+ xmlName: "w:themeColor",
25479
+ sdName: "themeColor",
25480
+ encode: encode$G,
25481
+ decode: decode$A
25482
+ });
25483
+ const encode$F = (attributes) => attributes?.["w:themeTint"];
25484
+ const decode$z = (attrs) => attrs?.themeTint;
25485
+ const attrConfig$j = Object.freeze({
25486
+ xmlName: "w:themeTint",
25487
+ sdName: "themeTint",
25488
+ encode: encode$F,
25489
+ decode: decode$z
25490
+ });
25491
+ const encode$E = (attributes) => attributes?.["w:themeShade"];
25492
+ const decode$y = (attrs) => attrs?.themeShade;
25493
+ const attrConfig$i = Object.freeze({
25494
+ xmlName: "w:themeShade",
25495
+ sdName: "themeShade",
25496
+ encode: encode$E,
25497
+ decode: decode$y
25498
+ });
25499
+ const validXmlAttributes$e = [attrConfig$l, attrConfig$k, attrConfig$j, attrConfig$i];
25500
+ const XML_NODE_NAME$l = "w:color";
25501
+ const SD_ATTR_KEY$a = "color";
25502
+ const encode$D = (params2, encodedAttrs = {}) => {
25503
+ const { nodes } = params2;
25504
+ const node = nodes?.[0];
25505
+ const sourceAttrs = node?.attributes || {};
25506
+ const value = encodedAttrs.color ?? sourceAttrs["w:val"];
25507
+ const themeColor = encodedAttrs.themeColor ?? sourceAttrs["w:themeColor"];
25508
+ const themeTint = encodedAttrs.themeTint ?? sourceAttrs["w:themeTint"];
25509
+ const themeShade = encodedAttrs.themeShade ?? sourceAttrs["w:themeShade"];
25510
+ const attributes = {};
25511
+ attributes["w:val"] = value ?? null;
25512
+ if (themeColor !== void 0 && themeColor !== null) attributes["w:themeColor"] = themeColor;
25513
+ if (themeTint !== void 0 && themeTint !== null) attributes["w:themeTint"] = themeTint;
25514
+ if (themeShade !== void 0 && themeShade !== null) attributes["w:themeShade"] = themeShade;
25515
+ return {
25516
+ type: "attr",
25517
+ xmlName: XML_NODE_NAME$l,
25518
+ sdNodeOrKeyName: SD_ATTR_KEY$a,
25519
+ attributes
25520
+ };
25521
+ };
25522
+ const config$j = {
25523
+ xmlName: XML_NODE_NAME$l,
25524
+ sdNodeOrKeyName: SD_ATTR_KEY$a,
25525
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25526
+ encode: encode$D,
25527
+ attributes: validXmlAttributes$e
25528
+ };
25529
+ const translator$Z = NodeTranslator.from(config$j);
25530
+ const encode$C = (attributes) => attributes?.["w:eastAsia"];
25531
+ const decode$x = (attrs) => attrs?.eastAsia;
25532
+ const attrConfig$h = Object.freeze({
25533
+ xmlName: "w:eastAsia",
25534
+ sdName: "eastAsia",
25535
+ encode: encode$C,
25536
+ decode: decode$x
25537
+ });
25538
+ const encode$B = (attributes) => attributes?.["w:ascii"];
25539
+ const decode$w = (attrs) => attrs?.ascii;
25540
+ const attrConfig$g = Object.freeze({
25541
+ xmlName: "w:ascii",
25542
+ sdName: "ascii",
25543
+ encode: encode$B,
25544
+ decode: decode$w
25545
+ });
25546
+ const encode$A = (attributes) => attributes?.["w:hAnsi"];
25547
+ const decode$v = (attrs) => attrs?.hAnsi;
25548
+ const attrConfig$f = Object.freeze({
25549
+ xmlName: "w:hAnsi",
25550
+ sdName: "hAnsi",
25551
+ encode: encode$A,
25552
+ decode: decode$v
25553
+ });
25554
+ const encode$z = (attributes) => attributes?.["w:cs"];
25555
+ const decode$u = (attrs) => attrs?.cs;
25556
+ const attrConfig$e = Object.freeze({
25557
+ xmlName: "w:cs",
25558
+ sdName: "cs",
25559
+ encode: encode$z,
25560
+ decode: decode$u
25561
+ });
25562
+ const encode$y = (attributes) => attributes?.["w:val"];
25563
+ const decode$t = (attrs) => attrs?.value;
25564
+ const attrConfig$d = Object.freeze({
25565
+ xmlName: "w:val",
25566
+ sdName: "value",
25567
+ encode: encode$y,
25568
+ decode: decode$t
25569
+ });
25570
+ const validXmlAttributes$d = [attrConfig$h, attrConfig$g, attrConfig$f, attrConfig$e, attrConfig$d];
25571
+ const XML_NODE_NAME$k = "w:rFonts";
25572
+ const SD_ATTR_KEY$9 = "fontFamily";
25573
+ const encode$x = (params2, encodedAttrs = {}) => {
25574
+ const { nodes } = params2;
25575
+ const node = nodes?.[0];
25576
+ const sourceAttrs = node?.attributes || {};
25577
+ const attributes = {};
25578
+ const setAttr = (xmlName, sdName) => {
25579
+ if (encodedAttrs[sdName] !== void 0 && encodedAttrs[sdName] !== null) {
25580
+ attributes[xmlName] = encodedAttrs[sdName];
25581
+ } else if (sourceAttrs[xmlName] !== void 0) {
25582
+ attributes[xmlName] = sourceAttrs[xmlName];
25583
+ }
25584
+ };
25585
+ setAttr("w:eastAsia", "eastAsia");
25586
+ setAttr("w:ascii", "ascii");
25587
+ setAttr("w:hAnsi", "hAnsi");
25588
+ setAttr("w:cs", "cs");
25589
+ setAttr("w:val", "value");
25590
+ Object.keys(sourceAttrs).forEach((key2) => {
25591
+ if (attributes[key2] === void 0) attributes[key2] = sourceAttrs[key2];
25592
+ });
25593
+ if (attributes["w:val"] === void 0 && attributes["w:eastAsia"]) {
25594
+ attributes["w:val"] = attributes["w:eastAsia"];
25595
+ }
25596
+ if (attributes["w:val"] === void 0) delete attributes["w:val"];
25597
+ return {
25598
+ type: "attr",
25599
+ xmlName: XML_NODE_NAME$k,
25600
+ sdNodeOrKeyName: SD_ATTR_KEY$9,
25601
+ attributes
25602
+ };
25603
+ };
25604
+ const config$i = {
25605
+ xmlName: XML_NODE_NAME$k,
25606
+ sdNodeOrKeyName: SD_ATTR_KEY$9,
25607
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25608
+ encode: encode$x,
25609
+ attributes: validXmlAttributes$d
25610
+ };
25611
+ const translator$Y = NodeTranslator.from(config$i);
25612
+ const encode$w = (attributes) => attributes?.["w:val"];
25613
+ const decode$s = (attrs) => attrs?.styleId;
25614
+ const attrConfig$c = Object.freeze({
25615
+ xmlName: "w:val",
25616
+ sdName: "styleId",
25617
+ encode: encode$w,
25618
+ decode: decode$s
25619
+ });
25620
+ const validXmlAttributes$c = [attrConfig$c];
25621
+ const XML_NODE_NAME$j = "w:rStyle";
25622
+ const SD_ATTR_KEY$8 = "styleId";
25623
+ const encode$v = (params2, encodedAttrs = {}) => {
25624
+ const { nodes } = params2;
25625
+ const node = nodes?.[0];
25626
+ const value = encodedAttrs.styleId ?? node?.attributes?.["w:val"];
25627
+ return {
25628
+ type: "attr",
25629
+ xmlName: XML_NODE_NAME$j,
25630
+ sdNodeOrKeyName: SD_ATTR_KEY$8,
25631
+ attributes: { "w:val": value ?? null }
25632
+ };
25633
+ };
25634
+ const config$h = {
25635
+ xmlName: XML_NODE_NAME$j,
25636
+ sdNodeOrKeyName: SD_ATTR_KEY$8,
25637
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25638
+ encode: encode$v,
25639
+ attributes: validXmlAttributes$c
25640
+ };
25641
+ const translator$X = NodeTranslator.from(config$h);
25642
+ const encode$u = (attributes) => attributes?.["w:val"];
25643
+ const decode$r = (attrs) => attrs?.fontSize;
25644
+ const attrConfig$b = Object.freeze({
25645
+ xmlName: "w:val",
25646
+ sdName: "fontSize",
25647
+ encode: encode$u,
25648
+ decode: decode$r
25649
+ });
25650
+ const validXmlAttributes$b = [attrConfig$b];
25651
+ const XML_NODE_NAME$i = "w:sz";
25652
+ const SD_ATTR_KEY$7 = "fontSize";
25653
+ const encode$t = (params2, encodedAttrs = {}) => {
25654
+ const { nodes } = params2;
25655
+ const node = nodes?.[0];
25656
+ const value = encodedAttrs.fontSize ?? node?.attributes?.["w:val"];
25657
+ return {
25658
+ type: "attr",
25659
+ xmlName: XML_NODE_NAME$i,
25660
+ sdNodeOrKeyName: SD_ATTR_KEY$7,
25661
+ attributes: { "w:val": value ?? null }
25662
+ };
25663
+ };
25664
+ const config$g = {
25665
+ xmlName: XML_NODE_NAME$i,
25666
+ sdNodeOrKeyName: SD_ATTR_KEY$7,
25667
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25668
+ encode: encode$t,
25669
+ attributes: validXmlAttributes$b
25670
+ };
25671
+ const translator$W = NodeTranslator.from(config$g);
25672
+ const encode$s = (attributes) => attributes?.["w:val"];
25673
+ const decode$q = (attrs) => attrs?.fontSizeCs;
25674
+ const attrConfig$a = Object.freeze({
25675
+ xmlName: "w:val",
25676
+ sdName: "fontSizeCs",
25677
+ encode: encode$s,
25678
+ decode: decode$q
25679
+ });
25680
+ const validXmlAttributes$a = [attrConfig$a];
25681
+ const XML_NODE_NAME$h = "w:szCs";
25682
+ const SD_ATTR_KEY$6 = "fontSizeCs";
25683
+ const encode$r = (params2, encodedAttrs = {}) => {
25684
+ const { nodes } = params2;
25685
+ const node = nodes?.[0];
25686
+ const value = encodedAttrs.fontSizeCs ?? node?.attributes?.["w:val"];
25687
+ return {
25688
+ type: "attr",
25689
+ xmlName: XML_NODE_NAME$h,
25690
+ sdNodeOrKeyName: SD_ATTR_KEY$6,
25691
+ attributes: { "w:val": value ?? null }
25692
+ };
25693
+ };
25694
+ const config$f = {
25695
+ xmlName: XML_NODE_NAME$h,
25696
+ sdNodeOrKeyName: SD_ATTR_KEY$6,
25697
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25698
+ encode: encode$r,
25699
+ attributes: validXmlAttributes$a
25700
+ };
25701
+ const translator$V = NodeTranslator.from(config$f);
25702
+ const runPropertyTranslators = Object.freeze({
25703
+ "w:b": translator$11,
25704
+ "w:i": translator$10,
25705
+ "w:u": translator$$,
25706
+ "w:strike": translator$_,
25707
+ "w:color": translator$Z,
25708
+ "w:highlight": translator$14,
25709
+ "w:rFonts": translator$Y,
25710
+ "w:rStyle": translator$X,
25711
+ "w:sz": translator$W,
25712
+ "w:szCs": translator$V
25713
+ });
25714
+ const rawRunPropertyXmlNames = Object.freeze(["w:lang", "w:shd"]);
25715
+ const RAW_CHILD_NAME_SET = new Set(rawRunPropertyXmlNames);
25716
+ const KNOWN_CHILD_XML_NAMES = /* @__PURE__ */ new Set([...Object.keys(runPropertyTranslators), ...RAW_CHILD_NAME_SET]);
25717
+ const toRunPropertyEntry = (candidate) => {
25718
+ if (!candidate || candidate.type !== "attr") return null;
25719
+ const xmlName = candidate.xmlName || candidate.name;
25720
+ if (!xmlName) return null;
25721
+ return {
25722
+ xmlName,
25723
+ attributes: { ...candidate.attributes || {} }
25724
+ };
25725
+ };
25726
+ const XML_NODE_NAME$g = "w:rPr";
25727
+ const SD_ATTR_KEY$5 = "runProperties";
25728
+ const encode$q = (params2) => {
25729
+ const { nodes } = params2;
25730
+ const node = nodes?.[0] || {};
25731
+ const contents = Array.isArray(node.elements) ? node.elements : [];
25732
+ const runPropsArray = contents.reduce(
25733
+ (acc, child) => {
25734
+ if (!child || typeof child !== "object") return acc;
25735
+ const xmlName = child.name;
25736
+ if (!KNOWN_CHILD_XML_NAMES.has(xmlName)) return acc;
25737
+ const translator2 = runPropertyTranslators[xmlName];
25738
+ let entry = null;
25739
+ if (translator2) {
25740
+ const encoded = translator2.encode({ ...params2, nodes: [child] }) || null;
25741
+ entry = toRunPropertyEntry(encoded);
25742
+ } else if (RAW_CHILD_NAME_SET.has(xmlName)) {
25743
+ entry = toRunPropertyEntry({
25744
+ type: "attr",
25745
+ xmlName,
25746
+ attributes: { ...child.attributes || {} }
25747
+ });
25748
+ }
25749
+ if (entry) acc.push(entry);
25750
+ return acc;
25751
+ },
25752
+ /** @type {{ xmlName: string, attributes: Record<string, any> }[]} */
25753
+ []
25754
+ );
25755
+ return {
25756
+ type: "attr",
25757
+ xmlName: "w:rPr",
25758
+ sdNodeOrKeyName: "runProperties",
25759
+ attributes: runPropsArray
25760
+ };
25761
+ };
25762
+ const config$e = {
25763
+ xmlName: XML_NODE_NAME$g,
25764
+ sdNodeOrKeyName: SD_ATTR_KEY$5,
25765
+ type: NodeTranslator.translatorTypes.ATTRIBUTE,
25766
+ encode: encode$q
25767
+ };
25768
+ const translator$U = NodeTranslator.from(config$e);
25769
+ const EAST_ASIAN_CHARACTER_REGEX = /[\u1100-\u11FF\u2E80-\u2EFF\u2F00-\u2FDF\u3040-\u30FF\u3100-\u312F\u3130-\u318F\u31A0-\u31BF\u3400-\u4DBF\u4E00-\u9FFF\uA960-\uA97F\uAC00-\uD7AF\uF900-\uFAFF\uFF00-\uFFEF]/u;
25770
+ const containsEastAsianCharacters = (text) => EAST_ASIAN_CHARACTER_REGEX.test(text);
25771
+ const collectRunProperties = (params2, rPrNode, translator2 = translator$U) => {
25772
+ if (!rPrNode) return { entries: [], hadRPr: false, styleChangeMarks: [] };
25773
+ const result = translator2.encode({ ...params2, nodes: [rPrNode] }) || {};
25774
+ let entries = [];
25775
+ if (Array.isArray(result.attributes) && result.attributes.length) {
25776
+ entries = result.attributes.map((attr) => ({
25777
+ xmlName: attr?.xmlName,
25778
+ attributes: { ...attr?.attributes || {} }
25779
+ }));
25780
+ } else if (Array.isArray(rPrNode.elements) && rPrNode.elements.length) {
25781
+ entries = rPrNode.elements.filter((el) => el && typeof el === "object").map((el) => ({
25782
+ xmlName: el.name,
25783
+ attributes: { ...el.attributes || {} }
25784
+ }));
25785
+ }
25786
+ const legacyMarks = parseMarks(rPrNode, [], params2?.docx) || [];
25787
+ const styleChangeMarks = handleStyleChangeMarks(rPrNode, legacyMarks) || [];
25788
+ return { entries, hadRPr: true, styleChangeMarks };
25789
+ };
25790
+ const buildRunAttrs = (encodedAttrs = {}, hadRPr, runProps) => {
25791
+ const base2 = { ...encodedAttrs || {} };
25792
+ if (hadRPr) {
25793
+ base2.runProperties = runProps.length ? runProps : null;
25794
+ }
25795
+ return base2;
25796
+ };
25797
+ const ensureInlineMarks = (marks, inlineMarks = []) => {
25798
+ inlineMarks.forEach(({ type: type2, attrs }) => {
25799
+ if (!type2) return;
25800
+ if (marks.some((mark) => mark?.type === type2)) return;
25801
+ marks.push(attrs ? { type: type2, attrs: { ...attrs } } : { type: type2 });
25802
+ });
25803
+ };
25804
+ const ensureTextStyleMark = (marks, textStyleAttrs) => {
25805
+ if (!textStyleAttrs) return;
25806
+ const existingTextStyle = marks.find((mark) => mark?.type === "textStyle");
25807
+ if (existingTextStyle) {
25808
+ existingTextStyle.attrs = { ...existingTextStyle.attrs || {}, ...textStyleAttrs };
25809
+ return;
25810
+ }
25811
+ marks.push({ type: "textStyle", attrs: { ...textStyleAttrs } });
25812
+ };
25813
+ const normalizeTextStyleAttrsForNode = (textStyleAttrs, node) => {
25814
+ if (!textStyleAttrs || typeof textStyleAttrs !== "object") return null;
25815
+ const normalized = { ...textStyleAttrs };
25816
+ const eastAsiaFont = normalized.eastAsiaFontFamily;
25817
+ if (eastAsiaFont) {
25818
+ delete normalized.eastAsiaFontFamily;
25819
+ const text = typeof node?.text === "string" ? node.text : null;
25820
+ const shouldUseEastAsia = typeof text === "string" && containsEastAsianCharacters(text);
25821
+ if (shouldUseEastAsia) {
25822
+ normalized.fontFamily = eastAsiaFont;
25823
+ }
25824
+ }
25825
+ return Object.keys(normalized).length ? normalized : null;
25826
+ };
25827
+ const applyRunMarks = (node, inlineMarks, textStyleAttrs) => {
25828
+ if (!node || typeof node !== "object") return node;
25829
+ const baseMarks = Array.isArray(node.marks) ? node.marks : [];
25830
+ const marks = baseMarks.map((mark) => cloneMark$1(mark));
25831
+ ensureInlineMarks(marks, inlineMarks);
25832
+ if (node.type === "text") {
25833
+ const normalizedTextStyle = normalizeTextStyleAttrsForNode(textStyleAttrs, node);
25834
+ ensureTextStyleMark(marks, normalizedTextStyle);
25835
+ }
25836
+ return { ...node, marks };
25837
+ };
25838
+ const deriveStyleMarks = ({ docx, paragraphStyleId, runStyleId }) => {
25839
+ const paragraphStyleMarks = collectStyleMarks(paragraphStyleId, docx);
25840
+ const runStyleMarks = collectStyleMarks(runStyleId, docx);
25841
+ const inlineMarks = mergeInlineMarkSets(paragraphStyleMarks.inlineMarks, runStyleMarks.inlineMarks);
25842
+ const textStyleAttrs = mergeTextStyleAttrs(paragraphStyleMarks.textStyleAttrs, runStyleMarks.textStyleAttrs);
25843
+ return { inlineMarks, textStyleAttrs };
25844
+ };
25845
+ const collectStyleMarks = (styleId, docx, seen = /* @__PURE__ */ new Set()) => {
25846
+ if (!styleId || !docx || seen.has(styleId)) return { inlineMarks: [], textStyleAttrs: null };
25847
+ seen.add(styleId);
25848
+ const chain = collectStyleChain(styleId, docx, seen);
25849
+ if (!chain.length) return { inlineMarks: [], textStyleAttrs: null };
25850
+ const inlineMap = /* @__PURE__ */ new Map();
25851
+ let textStyleAttrs = {};
25852
+ chain.forEach((styleTag) => {
25853
+ const marks = extractMarksFromStyle(styleTag, docx);
25854
+ marks.inlineMarks.forEach((mark) => {
25855
+ inlineMap.set(mark.type, mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
25856
+ });
25857
+ if (marks.textStyleAttrs) textStyleAttrs = { ...textStyleAttrs, ...marks.textStyleAttrs };
25858
+ });
25859
+ return {
25860
+ inlineMarks: Array.from(inlineMap.values()),
25861
+ textStyleAttrs: Object.keys(textStyleAttrs).length ? textStyleAttrs : null
25862
+ };
25863
+ };
25864
+ const collectStyleChain = (styleId, docx, seen) => {
25865
+ if (!styleId || !docx) return [];
25866
+ const styleTag = findStyleTag(docx, styleId);
25867
+ if (!styleTag || !styleTag.elements) return [];
25868
+ const basedOn = styleTag.elements?.find((el) => el.name === "w:basedOn")?.attributes?.["w:val"];
25869
+ let chain = [];
25870
+ if (basedOn && !seen.has(basedOn)) {
25871
+ seen.add(basedOn);
25872
+ chain = collectStyleChain(basedOn, docx, seen);
25873
+ }
25874
+ chain.push(styleTag);
25875
+ return chain;
25876
+ };
25877
+ const findStyleTag = (docx, styleId) => {
25878
+ const stylesFile = docx?.["word/styles.xml"];
25879
+ if (!stylesFile?.elements?.length) return null;
25880
+ const candidates = [];
25881
+ stylesFile.elements.forEach((el) => {
25882
+ if (!el) return;
25883
+ if (el.name === "w:styles" && Array.isArray(el.elements)) {
25884
+ el.elements.forEach((child) => {
25885
+ if (child?.name === "w:style") candidates.push(child);
25886
+ });
25887
+ return;
25888
+ }
25889
+ if (el.name === "w:style") {
25890
+ candidates.push(el);
25891
+ return;
25892
+ }
25893
+ if (Array.isArray(el.elements)) {
25894
+ el.elements.forEach((child) => {
25895
+ if (child?.name === "w:style") candidates.push(child);
25896
+ });
25897
+ }
25898
+ });
25899
+ return candidates.find((tag) => tag?.attributes?.["w:styleId"] === styleId) || null;
25900
+ };
25901
+ const extractMarksFromStyle = (styleTag, docx) => {
25902
+ const rPr = styleTag?.elements?.find((el) => el.name === "w:rPr");
25903
+ if (!rPr) return { inlineMarks: [], textStyleAttrs: null };
25904
+ const marks = parseMarks(rPr, [], docx) || [];
25905
+ const inlineMarks = [];
25906
+ let textStyleAttrs = {};
25907
+ marks.forEach((mark) => {
25908
+ if (!mark) return;
25909
+ if (mark.type === "textStyle") {
25910
+ const attrs = mark.attrs || {};
25911
+ if (Object.keys(attrs).length) textStyleAttrs = { ...textStyleAttrs, ...attrs };
25912
+ return;
25913
+ }
25914
+ if (mark.type) inlineMarks.push(mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
25915
+ });
25916
+ return {
25917
+ inlineMarks,
25918
+ textStyleAttrs: Object.keys(textStyleAttrs).length ? textStyleAttrs : null
25919
+ };
25920
+ };
25921
+ const mergeInlineMarkSets = (...markSets) => {
25922
+ const map3 = /* @__PURE__ */ new Map();
25923
+ markSets.filter(Boolean).forEach((marks) => {
25924
+ marks.forEach((mark) => {
25925
+ if (!mark || !mark.type) return;
25926
+ map3.set(mark.type, mark.attrs ? { type: mark.type, attrs: { ...mark.attrs } } : { type: mark.type });
25927
+ });
25928
+ });
25929
+ return Array.from(map3.values());
25930
+ };
25931
+ const mergeTextStyleAttrs = (...attrsList) => {
25932
+ const merged = attrsList.filter((attrs) => attrs && Object.keys(attrs).length).reduce((acc, attrs) => ({ ...acc, ...attrs }), {});
25933
+ return Object.keys(merged).length ? merged : null;
25934
+ };
25935
+ const cloneRunAttrs = (attrs) => {
25936
+ const clone = { ...attrs };
25937
+ if (Array.isArray(attrs?.runProperties)) {
25938
+ clone.runProperties = attrs.runProperties.map((entry) => ({
25939
+ xmlName: entry?.xmlName,
25940
+ attributes: { ...entry?.attributes || {} }
25941
+ }));
25942
+ }
25943
+ return clone;
25944
+ };
25945
+ const cloneMark$1 = (mark) => {
25946
+ if (!mark || typeof mark !== "object") return mark;
25947
+ const cloned = { ...mark };
25948
+ if (mark.attrs && typeof mark.attrs === "object") {
25949
+ cloned.attrs = { ...mark.attrs };
25950
+ if (Array.isArray(mark.attrs.runProperties)) {
25951
+ cloned.attrs.runProperties = mark.attrs.runProperties.map((entry) => ({
25952
+ xmlName: entry?.xmlName,
25953
+ attributes: { ...entry?.attributes || {} }
25954
+ }));
25955
+ }
25956
+ }
25957
+ return cloned;
25958
+ };
25959
+ const normalizeBool = (value) => {
25960
+ if (value === void 0 || value === null) return true;
25961
+ if (typeof value === "boolean") return value;
25962
+ if (typeof value === "number") return value !== 0;
25963
+ const normalized = String(value).trim().toLowerCase();
25964
+ if (normalized === "0" || normalized === "false" || normalized === "off") return false;
25965
+ if (normalized === "1" || normalized === "true" || normalized === "on") return true;
25966
+ return true;
25967
+ };
25968
+ const createRunPropertiesElement = (entries = []) => {
25969
+ if (!Array.isArray(entries) || !entries.length) return null;
25970
+ const elements = entries.map((entry) => {
25971
+ if (!entry || !entry.xmlName) return null;
25972
+ return {
25973
+ name: entry.xmlName,
25974
+ attributes: { ...entry.attributes || {} }
25975
+ };
25976
+ }).filter(Boolean);
25977
+ if (!elements.length) return null;
25978
+ return {
25979
+ name: "w:rPr",
25980
+ elements
25981
+ };
25982
+ };
25983
+ const cloneXmlNode = (nodeLike) => {
25984
+ if (!nodeLike || typeof nodeLike !== "object") return nodeLike;
25985
+ return {
25986
+ name: nodeLike.name,
25987
+ type: nodeLike.type,
25988
+ attributes: nodeLike.attributes ? { ...nodeLike.attributes } : void 0,
25989
+ elements: Array.isArray(nodeLike.elements) ? nodeLike.elements.map((el) => cloneXmlNode(el)) : void 0,
25990
+ text: nodeLike.text
25991
+ };
25992
+ };
25993
+ const applyRunPropertiesTemplate = (runNode, runPropertiesTemplate) => {
25994
+ if (!runNode || !runPropertiesTemplate) return;
25995
+ if (!Array.isArray(runNode.elements)) runNode.elements = [];
25996
+ let runProps = runNode.elements.find((el) => el?.name === "w:rPr");
25997
+ if (!runProps) {
25998
+ runProps = { name: "w:rPr", elements: [] };
25999
+ runNode.elements.unshift(runProps);
26000
+ }
26001
+ if (!Array.isArray(runProps.elements)) runProps.elements = [];
26002
+ if (runPropertiesTemplate.attributes) {
26003
+ runProps.attributes = {
26004
+ ...runProps.attributes || {},
26005
+ ...runPropertiesTemplate.attributes
26006
+ };
26007
+ }
26008
+ const isValidRunPropName = (name) => typeof name === "string" && name.includes(":");
26009
+ runProps.elements = runProps.elements.filter((entry) => isValidRunPropName(entry?.name));
26010
+ const existingNames = new Set(runProps.elements.map((el) => el?.name));
26011
+ (runPropertiesTemplate.elements || []).forEach((entry) => {
26012
+ if (!isValidRunPropName(entry?.name) || existingNames.has(entry.name)) return;
26013
+ runProps.elements.push(cloneXmlNode(entry));
26014
+ existingNames.add(entry.name);
26015
+ });
26016
+ };
26017
+ const splitRunProperties = (entries = [], docx = null) => {
26018
+ const remainingProps = [];
26019
+ const inlineMarks = [];
26020
+ const textStyleAttrs = {};
26021
+ let hasTextStyle = false;
26022
+ let highlightColor = null;
26023
+ let runStyleId = null;
26024
+ entries.forEach((entry) => {
26025
+ if (!entry || !entry.xmlName) return;
26026
+ const attributes = entry.attributes || {};
26027
+ switch (entry.xmlName) {
26028
+ case "w:b": {
26029
+ const val = normalizeBool(attributes["w:val"]);
26030
+ inlineMarks.push(val ? { type: "bold" } : { type: "bold", attrs: { value: "0" } });
26031
+ break;
26032
+ }
26033
+ case "w:i": {
26034
+ const val = normalizeBool(attributes["w:val"]);
26035
+ inlineMarks.push(val ? { type: "italic" } : { type: "italic", attrs: { value: "0" } });
26036
+ break;
26037
+ }
26038
+ case "w:u": {
26039
+ const rawVal = attributes["w:val"];
26040
+ const underlineType = rawVal == null || rawVal === "" ? "single" : String(rawVal);
26041
+ const attrs = {};
26042
+ if (underlineType.toLowerCase() === "none" || underlineType === "0") {
26043
+ attrs.underlineType = "none";
26044
+ } else {
26045
+ attrs.underlineType = underlineType;
26046
+ const colorRaw = attributes["w:color"];
26047
+ if (typeof colorRaw === "string" && colorRaw.toLowerCase() !== "auto") {
26048
+ const normalizedColor = normalizeHexColor(colorRaw);
26049
+ if (normalizedColor) attrs.underlineColor = `#${normalizedColor}`;
26050
+ }
26051
+ }
26052
+ if (attributes["w:themeColor"]) attrs.underlineThemeColor = attributes["w:themeColor"];
26053
+ if (attributes["w:themeTint"]) attrs.underlineThemeTint = attributes["w:themeTint"];
26054
+ if (attributes["w:themeShade"]) attrs.underlineThemeShade = attributes["w:themeShade"];
26055
+ inlineMarks.push({ type: "underline", attrs });
26056
+ break;
26057
+ }
26058
+ case "w:color": {
26059
+ const raw = attributes["w:val"];
26060
+ if (typeof raw === "string" && raw) {
26061
+ hasTextStyle = true;
26062
+ textStyleAttrs.color = `#${raw.replace("#", "").toUpperCase()}`;
26063
+ }
26064
+ break;
26065
+ }
26066
+ case "w:rFonts": {
26067
+ const asciiFamily = attributes["w:ascii"] || attributes["w:hAnsi"] || (attributes["w:eastAsia"] ? void 0 : attributes["w:val"]);
26068
+ const eastAsiaFamily = attributes["w:eastAsia"];
26069
+ if (asciiFamily) {
26070
+ hasTextStyle = true;
26071
+ textStyleAttrs.fontFamily = SuperConverter.toCssFontFamily(asciiFamily, docx);
26072
+ }
26073
+ if (eastAsiaFamily) {
26074
+ hasTextStyle = true;
26075
+ const eastAsiaCss = SuperConverter.toCssFontFamily(eastAsiaFamily, docx);
26076
+ if (!asciiFamily || eastAsiaCss !== textStyleAttrs.fontFamily) {
26077
+ textStyleAttrs.eastAsiaFontFamily = eastAsiaCss;
26078
+ }
26079
+ }
26080
+ break;
26081
+ }
26082
+ case "w:sz":
26083
+ case "w:szCs": {
26084
+ const rawSize = Number(attributes["w:val"]);
26085
+ if (Number.isFinite(rawSize) && rawSize > 0) {
26086
+ hasTextStyle = true;
26087
+ textStyleAttrs.fontSize = `${rawSize / 2}pt`;
26088
+ }
26089
+ break;
26090
+ }
26091
+ case "w:strike": {
26092
+ const val = normalizeBool(attributes["w:val"]);
26093
+ inlineMarks.push(val ? { type: "strike" } : { type: "strike", attrs: { value: "0" } });
26094
+ break;
26095
+ }
26096
+ case "w:highlight": {
26097
+ const color = attributes["w:val"];
26098
+ if (typeof color === "string" && color) {
26099
+ highlightColor = color.toLowerCase() === "none" ? "transparent" : color;
26100
+ }
26101
+ break;
26102
+ }
26103
+ case "w:shd": {
26104
+ const fill = attributes["w:fill"];
26105
+ const shdVal = attributes["w:val"];
26106
+ if (fill && String(fill).toLowerCase() !== "auto") {
26107
+ highlightColor = `#${String(fill).replace("#", "")}`;
26108
+ } else if (typeof shdVal === "string") {
26109
+ const normalized = shdVal.toLowerCase();
26110
+ if (normalized === "clear" || normalized === "nil" || normalized === "none") {
26111
+ highlightColor = "transparent";
26112
+ }
26113
+ }
26114
+ break;
26115
+ }
26116
+ case "w:rStyle": {
26117
+ if (typeof attributes["w:val"] === "string") runStyleId = attributes["w:val"];
26118
+ remainingProps.push({ xmlName: entry.xmlName, attributes: { ...attributes } });
26119
+ break;
26120
+ }
26121
+ default: {
26122
+ remainingProps.push({ xmlName: entry.xmlName, attributes: { ...attributes } });
26123
+ }
26124
+ }
26125
+ });
26126
+ if (highlightColor) inlineMarks.push({ type: "highlight", attrs: { color: highlightColor } });
26127
+ return {
26128
+ remainingProps,
26129
+ inlineMarks,
26130
+ textStyleAttrs: hasTextStyle ? textStyleAttrs : null,
26131
+ runStyleId
26132
+ };
26133
+ };
26134
+ const cloneMark = (mark) => {
26135
+ if (!mark) return mark;
26136
+ return {
26137
+ ...mark,
26138
+ attrs: mark.attrs ? { ...mark.attrs } : void 0
26139
+ };
26140
+ };
26141
+ const cloneNode = (node) => {
26142
+ if (!node || typeof node !== "object") return node;
26143
+ const cloned = { ...node };
26144
+ if (node.marks) cloned.marks = node.marks.map((mark) => cloneMark(mark));
26145
+ if (node.content) cloned.content = node.content.map((child) => cloneNode(child));
26146
+ if (node.elements) cloned.elements = node.elements.map((el) => cloneNode(el));
26147
+ if (node.attributes) cloned.attributes = { ...node.attributes };
26148
+ return cloned;
26149
+ };
26150
+ const cloneRuns = (runs = []) => runs.map((run2) => cloneNode(run2));
26151
+ const prepareRunTrackingContext = (node = {}) => {
26152
+ const marks = Array.isArray(node.marks) ? node.marks : [];
26153
+ const trackingMarks = marks.filter(
26154
+ (mark) => mark?.type === TrackInsertMarkName || mark?.type === TrackDeleteMarkName
26155
+ );
26156
+ if (!trackingMarks.length) {
26157
+ return { runNode: node, trackingMarksByType: /* @__PURE__ */ new Map() };
26158
+ }
26159
+ const trackingMarksByType = /* @__PURE__ */ new Map();
26160
+ trackingMarks.forEach((mark) => {
26161
+ if (mark?.type) trackingMarksByType.set(mark.type, cloneMark(mark));
26162
+ });
26163
+ const preservedMarks = marks.filter((mark) => mark?.type !== TrackInsertMarkName && mark?.type !== TrackDeleteMarkName).map((mark) => cloneMark(mark));
26164
+ const clonedContent = Array.isArray(node.content) ? node.content.map((child) => {
26165
+ const childClone = cloneNode(child);
26166
+ const childMarks = Array.isArray(childClone.marks) ? childClone.marks.slice() : [];
26167
+ trackingMarks.forEach((mark) => {
26168
+ childMarks.push(cloneMark(mark));
26169
+ });
26170
+ childClone.marks = childMarks;
26171
+ return childClone;
26172
+ }) : [];
26173
+ return {
26174
+ runNode: {
26175
+ ...cloneNode(node),
26176
+ marks: preservedMarks,
26177
+ content: clonedContent
26178
+ },
26179
+ trackingMarksByType
26180
+ };
26181
+ };
26182
+ const mapTrackingAttrs = (mark, attrMap) => {
26183
+ const source = mark?.attrs || {};
26184
+ const mapped = {};
26185
+ attrMap.forEach((targetKey, sourceKey) => {
26186
+ if (source[sourceKey] != null) mapped[targetKey] = source[sourceKey];
26187
+ });
26188
+ return mapped;
26189
+ };
26190
+ const renameTextElementsForDeletion = (node) => {
26191
+ if (!node || typeof node !== "object") return;
26192
+ if (node.name === "w:t") node.name = "w:delText";
26193
+ if (Array.isArray(node.elements)) node.elements.forEach(renameTextElementsForDeletion);
26194
+ };
26195
+ const ensureTrackedWrapper = (runs, trackingMarksByType = /* @__PURE__ */ new Map()) => {
26196
+ if (!Array.isArray(runs) || !runs.length) return runs;
26197
+ const firstRun = runs[0];
26198
+ if (firstRun?.name === "w:ins" || firstRun?.name === "w:del") {
26199
+ return runs;
26200
+ }
26201
+ if (!trackingMarksByType.size) return runs;
26202
+ if (trackingMarksByType.has(TrackInsertMarkName)) {
26203
+ const mark = trackingMarksByType.get(TrackInsertMarkName);
26204
+ const clonedRuns = cloneRuns(runs);
26205
+ const wrapper = {
26206
+ name: "w:ins",
26207
+ attributes: mapTrackingAttrs(
26208
+ mark,
26209
+ /* @__PURE__ */ new Map([
26210
+ ["id", "w:id"],
26211
+ ["author", "w:author"],
26212
+ ["authorEmail", "w:authorEmail"],
26213
+ ["date", "w:date"]
26214
+ ])
26215
+ ),
26216
+ elements: clonedRuns
26217
+ };
26218
+ return [wrapper];
26219
+ }
26220
+ if (trackingMarksByType.has(TrackDeleteMarkName)) {
26221
+ const mark = trackingMarksByType.get(TrackDeleteMarkName);
26222
+ const clonedRuns = cloneRuns(runs);
26223
+ clonedRuns.forEach(renameTextElementsForDeletion);
26224
+ const wrapper = {
26225
+ name: "w:del",
26226
+ attributes: mapTrackingAttrs(mark, /* @__PURE__ */ new Map([["id", "w:id"]])),
26227
+ elements: clonedRuns
26228
+ };
26229
+ return [wrapper];
26230
+ }
26231
+ return runs;
26232
+ };
26233
+ const encode$p = (attributes) => {
26234
+ return attributes["w:rsidR"];
26235
+ };
26236
+ const decode$p = (attrs) => {
26237
+ return attrs.rsidR;
26238
+ };
26239
+ const attrConfig$9 = Object.freeze({
26240
+ xmlName: "w:rsidR",
26241
+ sdName: "rsidR",
26242
+ encode: encode$p,
26243
+ decode: decode$p
26244
+ });
26245
+ const encode$o = (attributes) => {
26246
+ return attributes["w:rsidRPr"];
26247
+ };
26248
+ const decode$o = (attrs) => {
26249
+ return attrs.rsidRPr;
26250
+ };
26251
+ const attrConfig$8 = Object.freeze({
26252
+ xmlName: "w:rsidRPr",
26253
+ sdName: "rsidRPr",
26254
+ encode: encode$o,
26255
+ decode: decode$o
26256
+ });
26257
+ const encode$n = (attributes) => {
26258
+ return attributes["w:rsidDel"];
26259
+ };
26260
+ const decode$n = (attrs) => {
26261
+ return attrs.rsidDel;
26262
+ };
26263
+ const attrConfig$7 = Object.freeze({
26264
+ xmlName: "w:rsidDel",
26265
+ sdName: "rsidDel",
26266
+ encode: encode$n,
26267
+ decode: decode$n
26268
+ });
26269
+ const validXmlAttributes$9 = [attrConfig$9, attrConfig$8, attrConfig$7];
26270
+ const XML_NODE_NAME$f = "w:r";
26271
+ const SD_KEY_NAME = "run";
26272
+ const encode$m = (params2, encodedAttrs = {}) => {
26273
+ const { nodes = [], nodeListHandler } = params2 || {};
26274
+ const runNode = nodes[0];
26275
+ if (!runNode) return void 0;
26276
+ const elements = Array.isArray(runNode.elements) ? runNode.elements : [];
26277
+ const rPrNode = elements.find((child) => child?.name === "w:rPr");
26278
+ const contentElements = rPrNode ? elements.filter((el) => el !== rPrNode) : elements;
26279
+ const { entries: runPropEntries, hadRPr, styleChangeMarks } = collectRunProperties(params2, rPrNode);
26280
+ const { remainingProps, inlineMarks, textStyleAttrs, runStyleId } = splitRunProperties(runPropEntries, params2?.docx);
26281
+ const styleMarks = deriveStyleMarks({
26282
+ docx: params2?.docx,
26283
+ paragraphStyleId: params2?.parentStyleId,
26284
+ runStyleId
26285
+ });
26286
+ const mergedInlineMarks = mergeInlineMarkSets(styleMarks.inlineMarks, inlineMarks);
26287
+ let mergedTextStyleAttrs = mergeTextStyleAttrs(styleMarks.textStyleAttrs, textStyleAttrs);
26288
+ if (runStyleId) {
26289
+ mergedTextStyleAttrs = mergedTextStyleAttrs ? { ...mergedTextStyleAttrs, styleId: runStyleId } : { styleId: runStyleId };
26290
+ }
26291
+ const runAttrs = buildRunAttrs(encodedAttrs, hadRPr, remainingProps);
26292
+ let runLevelMarks = Array.isArray(runNode.marks) ? runNode.marks.map((mark) => cloneMark$1(mark)) : [];
26293
+ if (styleChangeMarks?.length) {
26294
+ runLevelMarks = [...runLevelMarks, ...styleChangeMarks.map((mark) => cloneMark$1(mark))];
26295
+ }
26296
+ const childParams = { ...params2, nodes: contentElements };
26297
+ const content = nodeListHandler?.handler(childParams) || [];
26298
+ const contentWithRunMarks = content.map((child) => {
26299
+ if (!child || typeof child !== "object") return child;
26300
+ const baseMarks = Array.isArray(child.marks) ? child.marks.map((mark) => cloneMark$1(mark)) : [];
26301
+ if (!runLevelMarks.length) return child;
26302
+ return { ...child, marks: [...baseMarks, ...runLevelMarks.map((mark) => cloneMark$1(mark))] };
26303
+ });
26304
+ const marked = contentWithRunMarks.map((child) => applyRunMarks(child, mergedInlineMarks, mergedTextStyleAttrs));
26305
+ const filtered = marked.filter(Boolean);
26306
+ const runNodeResult = {
26307
+ type: SD_KEY_NAME,
26308
+ content: filtered
26309
+ };
26310
+ const attrs = cloneRunAttrs(runAttrs);
26311
+ if (attrs && Object.keys(attrs).length) {
26312
+ if (attrs.runProperties == null) delete attrs.runProperties;
26313
+ if (Object.keys(attrs).length) runNodeResult.attrs = attrs;
26314
+ }
26315
+ if (runLevelMarks.length) {
26316
+ runNodeResult.marks = runLevelMarks.map((mark) => cloneMark$1(mark));
26317
+ }
26318
+ return runNodeResult;
26319
+ };
26320
+ const decode$m = (params2, decodedAttrs = {}) => {
26321
+ const { node } = params2 || {};
26322
+ if (!node) return void 0;
26323
+ const { runNode: runNodeForExport, trackingMarksByType } = prepareRunTrackingContext(node);
26324
+ const runAttrs = runNodeForExport.attrs || {};
26325
+ const runProperties = Array.isArray(runAttrs.runProperties) ? runAttrs.runProperties : [];
26326
+ const exportParams = { ...params2, node: runNodeForExport };
26327
+ if (!exportParams.editor) {
26328
+ exportParams.editor = { extensionService: { extensions: [] } };
26329
+ }
26330
+ const childElements = translateChildNodes(exportParams) || [];
26331
+ let runPropertiesElement = createRunPropertiesElement(runProperties);
26332
+ const markElements = processOutputMarks(Array.isArray(runNodeForExport.marks) ? runNodeForExport.marks : []);
26333
+ if (markElements.length) {
26334
+ if (!runPropertiesElement) {
26335
+ runPropertiesElement = generateRunProps(markElements);
26336
+ } else {
26337
+ if (!Array.isArray(runPropertiesElement.elements)) runPropertiesElement.elements = [];
26338
+ const existingNames = new Set(
26339
+ runPropertiesElement.elements.map((el) => el?.name).filter((name) => typeof name === "string")
26340
+ );
26341
+ markElements.forEach((element) => {
26342
+ if (!element || !element.name || existingNames.has(element.name)) return;
26343
+ runPropertiesElement.elements.push({ ...element, attributes: { ...element.attributes || {} } });
26344
+ existingNames.add(element.name);
26345
+ });
26346
+ }
26347
+ }
26348
+ const runPropsTemplate = runPropertiesElement ? cloneXmlNode(runPropertiesElement) : null;
26349
+ const applyBaseRunProps = (runNode) => applyRunPropertiesTemplate(runNode, runPropsTemplate);
26350
+ const runs = [];
26351
+ childElements.forEach((child) => {
26352
+ if (!child) return;
26353
+ if (child.name === "w:r") {
26354
+ const clonedRun = cloneXmlNode(child);
26355
+ applyBaseRunProps(clonedRun);
26356
+ runs.push(clonedRun);
26357
+ return;
26358
+ }
26359
+ if (child.name === "w:hyperlink") {
26360
+ const hyperlinkClone = cloneXmlNode(child);
26361
+ if (Array.isArray(hyperlinkClone.elements)) {
26362
+ hyperlinkClone.elements.forEach((run2) => applyBaseRunProps(run2));
26363
+ }
26364
+ runs.push(hyperlinkClone);
26365
+ return;
26366
+ }
26367
+ if (child.name === "w:ins" || child.name === "w:del") {
26368
+ const trackedClone = cloneXmlNode(child);
26369
+ if (Array.isArray(trackedClone.elements)) {
26370
+ trackedClone.elements.forEach((element) => {
26371
+ if (element?.name === "w:r") applyBaseRunProps(element);
26372
+ });
26373
+ }
26374
+ runs.push(trackedClone);
26375
+ return;
26376
+ }
26377
+ const runWrapper = { name: XML_NODE_NAME$f, elements: [] };
26378
+ applyBaseRunProps(runWrapper);
26379
+ if (!Array.isArray(runWrapper.elements)) runWrapper.elements = [];
26380
+ runWrapper.elements.push(cloneXmlNode(child));
26381
+ runs.push(runWrapper);
26382
+ });
26383
+ const trackedRuns = ensureTrackedWrapper(runs, trackingMarksByType);
26384
+ if (!trackedRuns.length) {
26385
+ const emptyRun = { name: XML_NODE_NAME$f, elements: [] };
26386
+ applyBaseRunProps(emptyRun);
26387
+ trackedRuns.push(emptyRun);
26388
+ }
26389
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
26390
+ trackedRuns.forEach((run2) => {
26391
+ run2.attributes = { ...run2.attributes || {}, ...decodedAttrs };
26392
+ });
26393
+ }
26394
+ if (trackedRuns.length === 1) {
26395
+ return trackedRuns[0];
26396
+ }
26397
+ return trackedRuns;
26398
+ };
25140
26399
  const config$d = {
25141
26400
  xmlName: XML_NODE_NAME$f,
25142
- sdNodeOrKeyName: SD_NODE_NAME$a,
26401
+ sdNodeOrKeyName: SD_KEY_NAME,
25143
26402
  type: NodeTranslator.translatorTypes.NODE,
25144
26403
  encode: encode$m,
25145
26404
  decode: decode$m,
@@ -26517,17 +27776,52 @@ const encode$d = (params2, encodedAttrs) => {
26517
27776
  const { nodes, docx, nodeListHandler } = params2;
26518
27777
  const node = nodes[0];
26519
27778
  let href = _resolveHref(docx, encodedAttrs);
26520
- const linkMark = { type: "link", attrs: { ...encodedAttrs, href } };
27779
+ const linkMark = { attrs: { ...encodedAttrs, href } };
26521
27780
  const runNodes = node.elements.filter((el) => el.name === "w:r");
26522
27781
  runNodes.forEach((runNode) => {
26523
- runNode.marks = [...runNode.marks || [], linkMark];
27782
+ const existingRunMarks = Array.isArray(runNode.marks) ? runNode.marks : [];
27783
+ const runMarksWithoutLink = existingRunMarks.filter((mark) => mark?.type !== "link");
27784
+ runNode.marks = runMarksWithoutLink;
26524
27785
  });
26525
27786
  const updatedNode = nodeListHandler.handler({
26526
27787
  ...params2,
26527
27788
  nodes: runNodes,
26528
27789
  path: [...params2.path || [], node]
26529
27790
  });
26530
- return updatedNode;
27791
+ const cloneMark2 = (mark) => {
27792
+ if (!mark || typeof mark !== "object") return mark;
27793
+ if (!mark.attrs) return { ...mark };
27794
+ return { ...mark, attrs: { ...mark.attrs } };
27795
+ };
27796
+ const ensureLinkMark = (child) => {
27797
+ if (!child || typeof child !== "object") return child;
27798
+ if (Array.isArray(child.content)) {
27799
+ const updatedContent = child.content.map((item) => ensureLinkMark(item));
27800
+ if (updatedContent !== child.content) {
27801
+ child = { ...child, content: updatedContent };
27802
+ }
27803
+ }
27804
+ if (child.type === "run") {
27805
+ const existingMarks2 = Array.isArray(child.marks) ? child.marks : [];
27806
+ const filteredMarks = existingMarks2.filter((mark) => mark?.type !== "link").map((mark) => cloneMark2(mark));
27807
+ if (filteredMarks.length !== existingMarks2.length) {
27808
+ if (filteredMarks.length) child = { ...child, marks: filteredMarks };
27809
+ else {
27810
+ const { marks, ...rest } = child;
27811
+ child = rest;
27812
+ }
27813
+ }
27814
+ return child;
27815
+ }
27816
+ if (child.type !== "text") return child;
27817
+ const existingMarks = Array.isArray(child.marks) ? child.marks.map((mark) => cloneMark2(mark)) : [];
27818
+ const hasLink = existingMarks.some((mark) => mark?.type === "link");
27819
+ if (hasLink) return child;
27820
+ const linkClone = { type: "link", attrs: { ...linkMark.attrs } };
27821
+ return { ...child, marks: [...existingMarks, linkClone] };
27822
+ };
27823
+ if (!Array.isArray(updatedNode)) return updatedNode;
27824
+ return updatedNode.map((child) => ensureLinkMark(child));
26531
27825
  };
26532
27826
  const _resolveHref = (docx, encodedAttrs) => {
26533
27827
  const rels = docx["word/_rels/document.xml.rels"];
@@ -27458,176 +28752,30 @@ const config$4 = {
27458
28752
  attributes: validXmlAttributes$4
27459
28753
  };
27460
28754
  const translator$4 = NodeTranslator.from(config$4);
27461
- const encode$a = (attributes) => {
27462
- return attributes["w:id"];
27463
- };
27464
- const decode$a = (attrs) => {
27465
- return attrs.id;
27466
- };
27467
- const attrConfig$6 = Object.freeze({
27468
- xmlName: "w:id",
27469
- sdName: "id",
27470
- encode: encode$a,
27471
- decode: decode$a
27472
- });
27473
- const encode$9 = (attributes) => {
27474
- return attributes["w:name"];
27475
- };
27476
- const decode$9 = (attrs) => {
27477
- return attrs.name;
27478
- };
27479
- const attrConfig$5 = Object.freeze({
27480
- xmlName: "w:name",
27481
- sdName: "name",
27482
- encode: encode$9,
27483
- decode: decode$9
27484
- });
27485
- const encode$8 = (attributes) => {
27486
- return attributes["w:colFirst"];
27487
- };
27488
- const decode$8 = (attrs) => {
27489
- return attrs.colFirst;
27490
- };
27491
- const attrConfig$4 = Object.freeze({
27492
- xmlName: "w:colFirst",
27493
- sdName: "colFirst",
27494
- encode: encode$8,
27495
- decode: decode$8
27496
- });
27497
- const encode$7 = (attributes) => {
27498
- return attributes["w:colLast"];
27499
- };
27500
- const decode$7 = (attrs) => {
27501
- return attrs.colLast;
27502
- };
27503
- const attrConfig$3 = Object.freeze({
27504
- xmlName: "w:colLast",
27505
- sdName: "colLast",
27506
- encode: encode$7,
27507
- decode: decode$7
27508
- });
27509
- const encode$6 = (attributes) => {
27510
- return attributes["w:displacedByCustomXml"];
27511
- };
27512
- const decode$6 = (attrs) => {
27513
- return attrs.displacedByCustomXml;
27514
- };
27515
- const attrConfig$2 = Object.freeze({
27516
- xmlName: "w:displacedByCustomXml",
27517
- sdName: "displacedByCustomXml",
27518
- encode: encode$6,
27519
- decode: decode$6
27520
- });
27521
- const validXmlAttributes$3 = [attrConfig$6, attrConfig$5, attrConfig$4, attrConfig$3, attrConfig$2];
27522
- const XML_NODE_NAME$3 = "w:bookmarkStart";
27523
- const SD_NODE_NAME$3 = "bookmarkStart";
27524
- const encode$5 = (params2, encodedAttrs = {}) => {
27525
- return {
27526
- type: "bookmarkStart",
27527
- attrs: encodedAttrs
27528
- };
27529
- };
27530
- const decode$5 = (params2, decodedAttrs = {}) => {
27531
- const result = {
27532
- name: "w:bookmarkStart",
27533
- elements: []
27534
- };
27535
- if (decodedAttrs && Object.keys(decodedAttrs).length) {
27536
- result.attributes = decodedAttrs;
27537
- }
27538
- return result;
27539
- };
27540
- const config$3 = {
27541
- xmlName: XML_NODE_NAME$3,
27542
- sdNodeOrKeyName: SD_NODE_NAME$3,
27543
- type: NodeTranslator.translatorTypes.NODE,
27544
- encode: encode$5,
27545
- decode: decode$5,
27546
- attributes: validXmlAttributes$3
27547
- };
27548
- const translator$3 = NodeTranslator.from(config$3);
27549
- const encode$4 = (attributes) => {
27550
- return attributes["w:id"];
27551
- };
27552
- const decode$4 = (attrs) => {
27553
- return attrs.id;
27554
- };
27555
- const attrConfig$1 = Object.freeze({
27556
- xmlName: "w:id",
27557
- sdName: "id",
27558
- encode: encode$4,
27559
- decode: decode$4
27560
- });
27561
- const encode$3 = (attributes) => {
27562
- return attributes["w:displacedByCustomXml"];
27563
- };
27564
- const decode$3 = (attrs) => {
27565
- return attrs.displacedByCustomXml;
27566
- };
27567
- const attrConfig = Object.freeze({
27568
- xmlName: "w:displacedByCustomXml",
27569
- sdName: "displacedByCustomXml",
27570
- encode: encode$3,
27571
- decode: decode$3
27572
- });
27573
- const validXmlAttributes$2 = [attrConfig$1, attrConfig];
27574
- const XML_NODE_NAME$2 = "w:bookmarkEnd";
27575
- const SD_NODE_NAME$2 = "bookmarkEnd";
27576
- const encode$2 = (params2, encodedAttrs = {}) => {
27577
- return {
27578
- type: "bookmarkEnd",
27579
- attrs: encodedAttrs
27580
- };
27581
- };
27582
- const decode$2 = (params2, decodedAttrs = {}) => {
27583
- const result = {
27584
- name: "w:bookmarkEnd",
27585
- elements: []
27586
- };
27587
- if (decodedAttrs && Object.keys(decodedAttrs).length) {
27588
- result.attributes = decodedAttrs;
27589
- }
27590
- return result;
27591
- };
27592
- const config$2 = {
27593
- xmlName: XML_NODE_NAME$2,
27594
- sdNodeOrKeyName: SD_NODE_NAME$2,
27595
- type: NodeTranslator.translatorTypes.NODE,
27596
- encode: encode$2,
27597
- decode: decode$2,
27598
- attributes: validXmlAttributes$2
27599
- };
27600
- const translator$2 = NodeTranslator.from(config$2);
27601
- const registeredHandlers = Object.freeze({
27602
- "w:br": translator$V,
27603
- "w:tab": translator$U,
27604
- "w:p": translator$T,
27605
- "wp:anchor": translator$5,
27606
- "wp:inline": translator$4,
27607
- "w:bookmarkStart": translator$3,
27608
- "w:bookmarkEnd": translator$2
27609
- });
27610
- const XML_NODE_NAME$1 = "w:drawing";
27611
- const SD_NODE_NAME$1 = [];
27612
- const validXmlAttributes$1 = [];
27613
- function encode$1(params2) {
28755
+ const XML_NODE_NAME$3 = "w:drawing";
28756
+ const SD_NODE_NAME$3 = [];
28757
+ const validXmlAttributes$3 = [];
28758
+ function encode$a(params2) {
27614
28759
  const nodes = params2.nodes;
27615
28760
  const node = nodes[0];
27616
- const validChildTranslators = ["wp:anchor", "wp:inline"];
28761
+ const translatorByChildName = {
28762
+ "wp:anchor": translator$5,
28763
+ "wp:inline": translator$4
28764
+ };
27617
28765
  return node.elements.reduce((acc, child) => {
27618
28766
  if (acc) return acc;
27619
- if (!validChildTranslators.includes(child.name)) return acc;
27620
- const translator2 = registeredHandlers[child.name];
28767
+ const translator2 = translatorByChildName[child.name];
28768
+ if (!translator2) return acc;
27621
28769
  return translator2.encode({ ...params2, extraParams: { node: child } }) || acc;
27622
28770
  }, null);
27623
28771
  }
27624
- function decode$1(params2) {
28772
+ function decode$a(params2) {
27625
28773
  const { node } = params2;
27626
28774
  if (!node || !node.type) {
27627
28775
  return null;
27628
28776
  }
27629
- const handlerName = node.attrs.isAnchor ? "wp:anchor" : "wp:inline";
27630
- const resultNode = registeredHandlers[handlerName].decode(params2);
28777
+ const childTranslator = node.attrs.isAnchor ? translator$5 : translator$4;
28778
+ const resultNode = childTranslator.decode(params2);
27631
28779
  return wrapTextInRun(
27632
28780
  {
27633
28781
  name: "w:drawing",
@@ -27636,15 +28784,15 @@ function decode$1(params2) {
27636
28784
  []
27637
28785
  );
27638
28786
  }
27639
- const config$1 = {
27640
- xmlName: XML_NODE_NAME$1,
27641
- sdNodeOrKeyName: SD_NODE_NAME$1,
28787
+ const config$3 = {
28788
+ xmlName: XML_NODE_NAME$3,
28789
+ sdNodeOrKeyName: SD_NODE_NAME$3,
27642
28790
  type: NodeTranslator.translatorTypes.NODE,
27643
- encode: encode$1,
27644
- decode: decode$1,
27645
- attributes: validXmlAttributes$1
28791
+ encode: encode$a,
28792
+ decode: decode$a,
28793
+ attributes: validXmlAttributes$3
27646
28794
  };
27647
- const translator$1 = NodeTranslator.from(config$1);
28795
+ const translator$3 = NodeTranslator.from(config$3);
27648
28796
  class CommandService {
27649
28797
  /**
27650
28798
  * @param {import('./commands/types/index.js').CommandServiceOptions} props
@@ -28982,7 +30130,7 @@ function prepareTextAnnotation(params2) {
28982
30130
  return getTextNodeForExport(attrs.displayLabel, [...marks, ...marksFromAttrs], params2);
28983
30131
  }
28984
30132
  function prepareImageAnnotation(params2, imageSize) {
28985
- return translator$1.decode({
30133
+ return translator$3.decode({
28986
30134
  ...params2,
28987
30135
  imageSize
28988
30136
  });
@@ -29219,10 +30367,10 @@ function translateStructuredContent(params2) {
29219
30367
  };
29220
30368
  return result;
29221
30369
  }
29222
- const XML_NODE_NAME = "w:sdt";
29223
- const SD_NODE_NAME = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
29224
- const validXmlAttributes = [];
29225
- function encode$B(params2) {
30370
+ const XML_NODE_NAME$2 = "w:sdt";
30371
+ const SD_NODE_NAME$2 = ["fieldAnnotation", "structuredContent", "structuredContentBlock", "documentSection"];
30372
+ const validXmlAttributes$2 = [];
30373
+ function encode$9(params2) {
29226
30374
  const nodes = params2.nodes;
29227
30375
  const node = nodes[0];
29228
30376
  const { type: sdtType, handler: handler2 } = sdtNodeTypeStrategy(node);
@@ -29232,7 +30380,7 @@ function encode$B(params2) {
29232
30380
  const result = handler2(params2);
29233
30381
  return result;
29234
30382
  }
29235
- function decode(params2) {
30383
+ function decode$9(params2) {
29236
30384
  const { node } = params2;
29237
30385
  if (!node || !node.type) {
29238
30386
  return null;
@@ -29248,44 +30396,193 @@ function decode(params2) {
29248
30396
  const result = decoder();
29249
30397
  return result;
29250
30398
  }
30399
+ const config$2 = {
30400
+ xmlName: XML_NODE_NAME$2,
30401
+ sdNodeOrKeyName: SD_NODE_NAME$2,
30402
+ type: NodeTranslator.translatorTypes.NODE,
30403
+ encode: encode$9,
30404
+ decode: decode$9,
30405
+ attributes: validXmlAttributes$2
30406
+ };
30407
+ const translator$2 = NodeTranslator.from(config$2);
30408
+ const encode$8 = (attributes) => {
30409
+ return attributes["w:id"];
30410
+ };
30411
+ const decode$8 = (attrs) => {
30412
+ return attrs.id;
30413
+ };
30414
+ const attrConfig$6 = Object.freeze({
30415
+ xmlName: "w:id",
30416
+ sdName: "id",
30417
+ encode: encode$8,
30418
+ decode: decode$8
30419
+ });
30420
+ const encode$7 = (attributes) => {
30421
+ return attributes["w:name"];
30422
+ };
30423
+ const decode$7 = (attrs) => {
30424
+ return attrs.name;
30425
+ };
30426
+ const attrConfig$5 = Object.freeze({
30427
+ xmlName: "w:name",
30428
+ sdName: "name",
30429
+ encode: encode$7,
30430
+ decode: decode$7
30431
+ });
30432
+ const encode$6 = (attributes) => {
30433
+ return attributes["w:colFirst"];
30434
+ };
30435
+ const decode$6 = (attrs) => {
30436
+ return attrs.colFirst;
30437
+ };
30438
+ const attrConfig$4 = Object.freeze({
30439
+ xmlName: "w:colFirst",
30440
+ sdName: "colFirst",
30441
+ encode: encode$6,
30442
+ decode: decode$6
30443
+ });
30444
+ const encode$5 = (attributes) => {
30445
+ return attributes["w:colLast"];
30446
+ };
30447
+ const decode$5 = (attrs) => {
30448
+ return attrs.colLast;
30449
+ };
30450
+ const attrConfig$3 = Object.freeze({
30451
+ xmlName: "w:colLast",
30452
+ sdName: "colLast",
30453
+ encode: encode$5,
30454
+ decode: decode$5
30455
+ });
30456
+ const encode$4 = (attributes) => {
30457
+ return attributes["w:displacedByCustomXml"];
30458
+ };
30459
+ const decode$4 = (attrs) => {
30460
+ return attrs.displacedByCustomXml;
30461
+ };
30462
+ const attrConfig$2 = Object.freeze({
30463
+ xmlName: "w:displacedByCustomXml",
30464
+ sdName: "displacedByCustomXml",
30465
+ encode: encode$4,
30466
+ decode: decode$4
30467
+ });
30468
+ const validXmlAttributes$1 = [attrConfig$6, attrConfig$5, attrConfig$4, attrConfig$3, attrConfig$2];
30469
+ const XML_NODE_NAME$1 = "w:bookmarkStart";
30470
+ const SD_NODE_NAME$1 = "bookmarkStart";
30471
+ const encode$3 = (params2, encodedAttrs = {}) => {
30472
+ return {
30473
+ type: "bookmarkStart",
30474
+ attrs: encodedAttrs
30475
+ };
30476
+ };
30477
+ const decode$3 = (params2, decodedAttrs = {}) => {
30478
+ const result = {
30479
+ name: "w:bookmarkStart",
30480
+ elements: []
30481
+ };
30482
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
30483
+ result.attributes = decodedAttrs;
30484
+ }
30485
+ return result;
30486
+ };
30487
+ const config$1 = {
30488
+ xmlName: XML_NODE_NAME$1,
30489
+ sdNodeOrKeyName: SD_NODE_NAME$1,
30490
+ type: NodeTranslator.translatorTypes.NODE,
30491
+ encode: encode$3,
30492
+ decode: decode$3,
30493
+ attributes: validXmlAttributes$1
30494
+ };
30495
+ const translator$1 = NodeTranslator.from(config$1);
30496
+ const encode$2 = (attributes) => {
30497
+ return attributes["w:id"];
30498
+ };
30499
+ const decode$2 = (attrs) => {
30500
+ return attrs.id;
30501
+ };
30502
+ const attrConfig$1 = Object.freeze({
30503
+ xmlName: "w:id",
30504
+ sdName: "id",
30505
+ encode: encode$2,
30506
+ decode: decode$2
30507
+ });
30508
+ const encode$1 = (attributes) => {
30509
+ return attributes["w:displacedByCustomXml"];
30510
+ };
30511
+ const decode$1 = (attrs) => {
30512
+ return attrs.displacedByCustomXml;
30513
+ };
30514
+ const attrConfig = Object.freeze({
30515
+ xmlName: "w:displacedByCustomXml",
30516
+ sdName: "displacedByCustomXml",
30517
+ encode: encode$1,
30518
+ decode: decode$1
30519
+ });
30520
+ const validXmlAttributes = [attrConfig$1, attrConfig];
30521
+ const XML_NODE_NAME = "w:bookmarkEnd";
30522
+ const SD_NODE_NAME = "bookmarkEnd";
30523
+ const encode$18 = (params2, encodedAttrs = {}) => {
30524
+ return {
30525
+ type: "bookmarkEnd",
30526
+ attrs: encodedAttrs
30527
+ };
30528
+ };
30529
+ const decode = (params2, decodedAttrs = {}) => {
30530
+ const result = {
30531
+ name: "w:bookmarkEnd",
30532
+ elements: []
30533
+ };
30534
+ if (decodedAttrs && Object.keys(decodedAttrs).length) {
30535
+ result.attributes = decodedAttrs;
30536
+ }
30537
+ return result;
30538
+ };
29251
30539
  const config = {
29252
30540
  xmlName: XML_NODE_NAME,
29253
30541
  sdNodeOrKeyName: SD_NODE_NAME,
29254
30542
  type: NodeTranslator.translatorTypes.NODE,
29255
- encode: encode$B,
30543
+ encode: encode$18,
29256
30544
  decode,
29257
30545
  attributes: validXmlAttributes
29258
30546
  };
29259
30547
  const translator = NodeTranslator.from(config);
30548
+ const isLineBreakOnlyRun = (node) => {
30549
+ if (!node) return false;
30550
+ if (node.type === "lineBreak" || node.type === "hardBreak") return true;
30551
+ if (node.type !== "run") return false;
30552
+ const runContent = Array.isArray(node.content) ? node.content : [];
30553
+ if (!runContent.length) return false;
30554
+ return runContent.every((child) => child?.type === "lineBreak" || child?.type === "hardBreak");
30555
+ };
29260
30556
  function exportSchemaToJson(params2) {
29261
30557
  const { type: type2 } = params2.node || {};
29262
30558
  const router = {
29263
30559
  doc: translateDocumentNode,
29264
30560
  body: translateBodyNode,
29265
30561
  heading: translateHeadingNode,
29266
- paragraph: translator$T,
30562
+ paragraph: translator$12,
30563
+ run: translator$T,
29267
30564
  text: translateTextNode,
29268
30565
  bulletList: translateList,
29269
30566
  orderedList: translateList,
29270
- lineBreak: translator$V,
30567
+ lineBreak: translator$15,
29271
30568
  table: translator$8,
29272
30569
  tableRow: translator$F,
29273
30570
  tableCell: translator$7,
29274
- bookmarkStart: translator$3,
29275
- bookmarkEnd: translator$2,
29276
- fieldAnnotation: translator,
29277
- tab: translator$U,
29278
- image: translator$1,
29279
- hardBreak: translator$V,
30571
+ bookmarkStart: translator$1,
30572
+ bookmarkEnd: translator,
30573
+ fieldAnnotation: translator$2,
30574
+ tab: translator$13,
30575
+ image: translator$3,
30576
+ hardBreak: translator$15,
29280
30577
  commentRangeStart: () => translateCommentNode(params2, "Start"),
29281
30578
  commentRangeEnd: () => translateCommentNode(params2, "End"),
29282
30579
  commentReference: () => null,
29283
30580
  shapeContainer: translateShapeContainer,
29284
30581
  shapeTextbox: translateShapeTextbox,
29285
30582
  contentBlock: translateContentBlock,
29286
- structuredContent: translator,
29287
- structuredContentBlock: translator,
29288
- documentSection: translator,
30583
+ structuredContent: translator$2,
30584
+ structuredContentBlock: translator$2,
30585
+ documentSection: translator$2,
29289
30586
  "page-number": translatePageNumberNode,
29290
30587
  "total-page-number": translateTotalPageNumberNode
29291
30588
  };
@@ -29424,21 +30721,32 @@ function generateParagraphProperties(node) {
29424
30721
  };
29425
30722
  pPrElements.push(spacingElement);
29426
30723
  }
29427
- if (indent && Object.values(indent).some((v2) => v2 !== 0)) {
29428
- const { left: left2, right: right2, firstLine, hanging } = indent;
30724
+ const hasIndent = !!indent;
30725
+ if (hasIndent) {
30726
+ const { left: left2, right: right2, firstLine, hanging, explicitLeft, explicitRight, explicitFirstLine, explicitHanging } = indent;
29429
30727
  const attributes = {};
29430
- if (left2 || left2 === 0) attributes["w:left"] = pixelsToTwips(left2);
29431
- if (right2 || right2 === 0) attributes["w:right"] = pixelsToTwips(right2);
29432
- if (firstLine || firstLine === 0) attributes["w:firstLine"] = pixelsToTwips(firstLine);
29433
- if (hanging || hanging === 0) attributes["w:hanging"] = pixelsToTwips(hanging);
29434
- if (textIndent && !attributes["w:left"]) {
30728
+ if (left2 !== void 0 && (left2 !== 0 || explicitLeft || textIndent)) {
30729
+ attributes["w:left"] = pixelsToTwips(left2);
30730
+ }
30731
+ if (right2 !== void 0 && (right2 !== 0 || explicitRight)) {
30732
+ attributes["w:right"] = pixelsToTwips(right2);
30733
+ }
30734
+ if (firstLine !== void 0 && (firstLine !== 0 || explicitFirstLine)) {
30735
+ attributes["w:firstLine"] = pixelsToTwips(firstLine);
30736
+ }
30737
+ if (hanging !== void 0 && (hanging !== 0 || explicitHanging)) {
30738
+ attributes["w:hanging"] = pixelsToTwips(hanging);
30739
+ }
30740
+ if (textIndent && attributes["w:left"] === void 0) {
29435
30741
  attributes["w:left"] = getTextIndentExportValue(textIndent);
29436
30742
  }
29437
- const indentElement = {
29438
- name: "w:ind",
29439
- attributes
29440
- };
29441
- pPrElements.push(indentElement);
30743
+ if (Object.keys(attributes).length) {
30744
+ const indentElement = {
30745
+ name: "w:ind",
30746
+ attributes
30747
+ };
30748
+ pPrElements.push(indentElement);
30749
+ }
29442
30750
  } else if (textIndent && textIndent !== "0in") {
29443
30751
  const indentElement = {
29444
30752
  name: "w:ind",
@@ -29488,12 +30796,17 @@ function generateParagraphProperties(node) {
29488
30796
  if (sectPr) {
29489
30797
  pPrElements.push(sectPr);
29490
30798
  }
30799
+ const mapTabVal = (value) => {
30800
+ if (!value || value === "start") return "left";
30801
+ if (value === "end") return "right";
30802
+ return value;
30803
+ };
29491
30804
  const { tabStops } = attrs;
29492
30805
  if (tabStops && tabStops.length > 0) {
29493
30806
  const tabElements = tabStops.map((tab) => {
29494
30807
  const posValue = tab.originalPos !== void 0 ? tab.originalPos : pixelsToTwips(tab.pos).toString();
29495
30808
  const tabAttributes = {
29496
- "w:val": tab.val || "start",
30809
+ "w:val": mapTabVal(tab.val),
29497
30810
  "w:pos": posValue
29498
30811
  };
29499
30812
  if (tab.leader) {
@@ -29848,6 +31161,11 @@ const convertMultipleListItemsIntoSingleNode = (listItem) => {
29848
31161
  collapsedParagraph.content.push(item);
29849
31162
  }
29850
31163
  });
31164
+ collapsedParagraph.content = collapsedParagraph.content.filter((node, index2, nodes) => {
31165
+ if (!isLineBreakOnlyRun(node)) return true;
31166
+ const prevNode = nodes[index2 - 1];
31167
+ return !(prevNode && isLineBreakOnlyRun(prevNode));
31168
+ });
29851
31169
  return collapsedParagraph;
29852
31170
  };
29853
31171
  const restoreIndent = (indent) => {
@@ -29901,13 +31219,27 @@ function translateMark(mark) {
29901
31219
  markElement.type = "element";
29902
31220
  break;
29903
31221
  case "italic":
29904
- delete markElement.attributes;
29905
- markElement.type = "element";
29906
- break;
29907
- case "underline":
31222
+ if (attrs?.value && attrs.value !== "1" && attrs.value !== true) {
31223
+ markElement.attributes["w:val"] = attrs.value;
31224
+ } else {
31225
+ delete markElement.attributes;
31226
+ }
29908
31227
  markElement.type = "element";
29909
- markElement.attributes["w:val"] = attrs.underlineType;
29910
31228
  break;
31229
+ case "underline": {
31230
+ const translated = translator$$.decode({
31231
+ node: {
31232
+ attrs: {
31233
+ underlineType: attrs.underlineType ?? attrs.underline ?? null,
31234
+ underlineColor: attrs.underlineColor ?? attrs.color ?? null,
31235
+ underlineThemeColor: attrs.underlineThemeColor ?? attrs.themeColor ?? null,
31236
+ underlineThemeTint: attrs.underlineThemeTint ?? attrs.themeTint ?? null,
31237
+ underlineThemeShade: attrs.underlineThemeShade ?? attrs.themeShade ?? null
31238
+ }
31239
+ }
31240
+ });
31241
+ return translated || {};
31242
+ }
29911
31243
  // Text style cases
29912
31244
  case "fontSize":
29913
31245
  value = attrs.fontSize;
@@ -29925,13 +31257,21 @@ function translateMark(mark) {
29925
31257
  markElement.name = "w:rStyle";
29926
31258
  markElement.attributes["w:val"] = attrs.styleId;
29927
31259
  break;
29928
- case "color":
29929
- let processedColor = attrs.color.replace(/^#/, "").replace(/;$/, "");
31260
+ case "color": {
31261
+ const rawColor = attrs.color;
31262
+ if (!rawColor) break;
31263
+ const normalized = String(rawColor).trim().toLowerCase();
31264
+ if (normalized === "inherit") {
31265
+ markElement.attributes["w:val"] = "auto";
31266
+ break;
31267
+ }
31268
+ let processedColor = String(rawColor).replace(/^#/, "").replace(/;$/, "");
29930
31269
  if (processedColor.startsWith("rgb")) {
29931
31270
  processedColor = rgbToHex(processedColor);
29932
31271
  }
29933
31272
  markElement.attributes["w:val"] = processedColor;
29934
31273
  break;
31274
+ }
29935
31275
  case "textAlign":
29936
31276
  markElement.attributes["w:val"] = attrs.textAlign;
29937
31277
  break;
@@ -29949,12 +31289,11 @@ function translateMark(mark) {
29949
31289
  case "lineHeight":
29950
31290
  markElement.attributes["w:line"] = linesToTwips(attrs.lineHeight);
29951
31291
  break;
29952
- case "highlight":
29953
- markElement.attributes["w:fill"] = attrs.color?.substring(1);
29954
- markElement.attributes["w:color"] = "auto";
29955
- markElement.attributes["w:val"] = "clear";
29956
- markElement.name = "w:shd";
29957
- break;
31292
+ case "highlight": {
31293
+ const highlightValue = attrs.color ?? attrs.highlight ?? null;
31294
+ const translated = translator$14.decode({ node: { attrs: { highlight: highlightValue } } });
31295
+ return translated || {};
31296
+ }
29958
31297
  }
29959
31298
  return markElement;
29960
31299
  }
@@ -30085,8 +31424,8 @@ generate_xml_as_list_fn = function(data, debug = false) {
30085
31424
  return final;
30086
31425
  };
30087
31426
  replaceSpecialCharacters_fn = function(text) {
30088
- if (!text) return;
30089
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
31427
+ if (text === void 0 || text === null) return text;
31428
+ return String(text).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
30090
31429
  };
30091
31430
  generateXml_fn = function(node) {
30092
31431
  if (!node) return null;
@@ -30102,7 +31441,7 @@ generateXml_fn = function(node) {
30102
31441
  else tag += ">";
30103
31442
  let tags = [tag];
30104
31443
  if (!name && node.type === "text") {
30105
- return node.text;
31444
+ return __privateMethod$2(this, _DocxExporter_instances, replaceSpecialCharacters_fn).call(this, node.text ?? "");
30106
31445
  }
30107
31446
  if (elements) {
30108
31447
  if (name === "w:instrText") {
@@ -30228,7 +31567,7 @@ const handleDrawingNode = (params2) => {
30228
31567
  if (mainNode.name === "w:drawing") node = mainNode;
30229
31568
  else node = mainNode.elements.find((el) => el.name === "w:drawing");
30230
31569
  if (!node) return { nodes: [], consumed: 0 };
30231
- const schemaNode = translator$1.encode(params2);
31570
+ const schemaNode = translator$3.encode(params2);
30232
31571
  const newNodes = schemaNode ? [schemaNode] : [];
30233
31572
  return { nodes: newNodes, consumed: 1 };
30234
31573
  };
@@ -30331,81 +31670,7 @@ const trackChangeNodeHandlerEntity = {
30331
31670
  handler: handleTrackChangeNode
30332
31671
  };
30333
31672
  const hyperlinkNodeHandlerEntity = generateV2HandlerEntity("hyperlinkNodeHandler", translator$6);
30334
- const handleRunNode = (params2) => {
30335
- const { nodes, nodeListHandler, parentStyleId, docx } = params2;
30336
- if (nodes.length === 0 || nodes[0].name !== "w:r") {
30337
- return { nodes: [], consumed: 0 };
30338
- }
30339
- const node = nodes[0];
30340
- const childParams = { ...params2, nodes: node.elements, path: [...params2.path || [], node] };
30341
- let processedRun = nodeListHandler.handler(childParams)?.filter((n) => n) || [];
30342
- const hasRunProperties = node.elements?.some((el) => el.name === "w:rPr");
30343
- const defaultNodeStyles = getMarksFromStyles(docx, parentStyleId);
30344
- if (hasRunProperties) {
30345
- const { marks = [] } = parseProperties(node);
30346
- let runStyleAttributes = [];
30347
- const runStyleElement = node.elements?.find((el) => el.name === "w:rPr")?.elements?.find((el) => el.name === "w:rStyle");
30348
- let runStyleId;
30349
- if (runStyleElement && runStyleElement.attributes?.["w:val"] && docx) {
30350
- runStyleId = runStyleElement.attributes["w:val"];
30351
- const runStyleDefinition = getMarksFromStyles(docx, runStyleId);
30352
- if (runStyleDefinition.marks && runStyleDefinition.marks.length > 0) {
30353
- runStyleAttributes = runStyleDefinition.marks;
30354
- }
30355
- }
30356
- let paragraphStyleAttributes = [];
30357
- if (defaultNodeStyles.marks) {
30358
- paragraphStyleAttributes = defaultNodeStyles.marks.filter((mark) => {
30359
- if (["bold"].includes(mark.type) && marks.find((m2) => m2.type === "bold")?.attrs?.value === "0") {
30360
- return false;
30361
- }
30362
- return true;
30363
- });
30364
- }
30365
- const combinedMarks = [...paragraphStyleAttributes];
30366
- runStyleAttributes.forEach((runStyle) => {
30367
- const exists2 = combinedMarks.some(
30368
- (mark) => mark.type === runStyle.type && JSON.stringify(mark.attrs || {}) === JSON.stringify(runStyle.attrs || {})
30369
- );
30370
- if (!exists2) {
30371
- combinedMarks.push(runStyle);
30372
- }
30373
- });
30374
- marks.forEach((mark) => {
30375
- const exists2 = combinedMarks.some(
30376
- (existing) => existing.type === mark.type && JSON.stringify(existing.attrs || {}) === JSON.stringify(mark.attrs || {})
30377
- );
30378
- if (!exists2) {
30379
- combinedMarks.push(mark);
30380
- }
30381
- });
30382
- if (runStyleId) combinedMarks.push({ type: "textStyle", attrs: { styleId: runStyleId } });
30383
- if (node.marks) combinedMarks.push(...node.marks);
30384
- const newMarks = createImportMarks(combinedMarks);
30385
- processedRun = processedRun.map((n) => {
30386
- const existingMarks = n.marks || [];
30387
- return {
30388
- ...n,
30389
- marks: [...newMarks, ...existingMarks]
30390
- };
30391
- });
30392
- }
30393
- return { nodes: processedRun, consumed: 1 };
30394
- };
30395
- const getMarksFromStyles = (docx, styleId) => {
30396
- const styles = docx?.["word/styles.xml"];
30397
- if (!styles) {
30398
- return {};
30399
- }
30400
- const styleTags = styles.elements[0].elements.filter((style22) => style22.name === "w:style");
30401
- const style2 = styleTags.find((tag) => tag.attributes["w:styleId"] === styleId) || {};
30402
- if (!style2) return {};
30403
- return parseProperties(style2);
30404
- };
30405
- const runNodeHandlerEntity = {
30406
- handlerName: "runNodeHandler",
30407
- handler: handleRunNode
30408
- };
31673
+ const runNodeHandlerEntity = generateV2HandlerEntity("runNodeHandler", translator$T);
30409
31674
  const handleTextNode = (params2) => {
30410
31675
  const { nodes, insideTrackChange } = params2;
30411
31676
  if (nodes.length === 0 || !(nodes[0].name === "w:t" || insideTrackChange && nodes[0].name === "w:delText")) {
@@ -30417,6 +31682,10 @@ const handleTextNode = (params2) => {
30417
31682
  let text;
30418
31683
  if (elements.length === 1) {
30419
31684
  text = elements[0].text;
31685
+ const xmlSpace = node.attributes?.["xml:space"] ?? elements[0]?.attributes?.["xml:space"];
31686
+ if (xmlSpace !== "preserve" && typeof text === "string") {
31687
+ text = text.replace(/^\s+/, "").replace(/\s+$/, "");
31688
+ }
30420
31689
  text = text.replace(/\[\[sdspace\]\]/g, "");
30421
31690
  } else if (!elements.length && "attributes" in node && node.attributes["xml:space"] === "preserve") {
30422
31691
  text = " ";
@@ -30442,7 +31711,7 @@ const handleParagraphNode = (params2) => {
30442
31711
  if (nodes.length === 0 || nodes[0].name !== "w:p") {
30443
31712
  return { nodes: [], consumed: 0 };
30444
31713
  }
30445
- const schemaNode = translator$T.encode(params2);
31714
+ const schemaNode = translator$12.encode(params2);
30446
31715
  const newNodes = schemaNode ? [schemaNode] : [];
30447
31716
  return { nodes: newNodes, consumed: 1 };
30448
31717
  };
@@ -30455,7 +31724,7 @@ const handleSdtNode = (params2) => {
30455
31724
  if (nodes.length === 0 || nodes[0].name !== "w:sdt") {
30456
31725
  return { nodes: [], consumed: 0 };
30457
31726
  }
30458
- const result = translator.encode(params2);
31727
+ const result = translator$2.encode(params2);
30459
31728
  if (!result) {
30460
31729
  return { nodes: [], consumed: 0 };
30461
31730
  }
@@ -30545,7 +31814,7 @@ const handler = (params2) => {
30545
31814
  if (nodes.length === 0 || nodes[0].name !== "w:br") {
30546
31815
  return { nodes: [], consumed: 0 };
30547
31816
  }
30548
- const result = translator$V.encode(params2);
31817
+ const result = translator$15.encode(params2);
30549
31818
  if (!result) return { nodes: [], consumed: 0 };
30550
31819
  return {
30551
31820
  nodes: [result],
@@ -30617,7 +31886,7 @@ const handleBookmarkStartNode = (params2) => {
30617
31886
  if (isCustomMarkBookmark(nodes[0], params2.editor)) {
30618
31887
  return handleBookmarkNode(params2);
30619
31888
  }
30620
- const node = translator$3.encode(params2);
31889
+ const node = translator$1.encode(params2);
30621
31890
  if (!node) return { nodes: [], consumed: 0 };
30622
31891
  return { nodes: [node], consumed: 1 };
30623
31892
  };
@@ -30649,7 +31918,7 @@ const handleBookmarkEndNode = (params2) => {
30649
31918
  if (!nodes.length || nodes[0].name !== "w:bookmarkEnd") {
30650
31919
  return { nodes: [], consumed: 0 };
30651
31920
  }
30652
- const node = translator$2.encode(params2);
31921
+ const node = translator.encode(params2);
30653
31922
  if (!node) return { nodes: [], consumed: 0 };
30654
31923
  return { nodes: [node], consumed: 1 };
30655
31924
  };
@@ -31288,7 +32557,7 @@ const handleTabNode = (params2) => {
31288
32557
  if (!nodes.length || nodes[0].name !== "w:tab") {
31289
32558
  return { nodes: [], consumed: 0 };
31290
32559
  }
31291
- const node = translator$U.encode(params2);
32560
+ const node = translator$13.encode(params2);
31292
32561
  return { nodes: [node], consumed: 1 };
31293
32562
  };
31294
32563
  const tabNodeEntityHandler = {
@@ -31737,6 +33006,16 @@ const isAlternatingHeadersOddEven = (docx) => {
31737
33006
  };
31738
33007
  const HYPERLINK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
31739
33008
  const HEADER_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
33009
+ const FONT_FAMILY_FALLBACKS = Object.freeze({
33010
+ swiss: "Arial, sans-serif",
33011
+ roman: "Times New Roman, serif",
33012
+ modern: "Courier New, monospace",
33013
+ script: "cursive",
33014
+ decorative: "fantasy",
33015
+ system: "system-ui",
33016
+ auto: "sans-serif"
33017
+ });
33018
+ const DEFAULT_GENERIC_FALLBACK = "sans-serif";
31740
33019
  const _SuperConverter = class _SuperConverter2 {
31741
33020
  constructor(params2 = null) {
31742
33021
  __privateAdd$2(this, _SuperConverter_instances);
@@ -31772,6 +33051,31 @@ const _SuperConverter = class _SuperConverter2 {
31772
33051
  this.documentId = params2?.documentId || null;
31773
33052
  if (this.docx.length || this.xml) this.parseFromXml();
31774
33053
  }
33054
+ static getFontTableEntry(docx, fontName) {
33055
+ if (!docx || !fontName) return null;
33056
+ const fontTable = docx["word/fontTable.xml"];
33057
+ if (!fontTable?.elements?.length) return null;
33058
+ const fontsNode = fontTable.elements.find((el) => el.name === "w:fonts");
33059
+ if (!fontsNode?.elements?.length) return null;
33060
+ return fontsNode.elements.find((el) => el?.attributes?.["w:name"] === fontName) || null;
33061
+ }
33062
+ static getFallbackFromFontTable(docx, fontName) {
33063
+ const fontEntry = _SuperConverter2.getFontTableEntry(docx, fontName);
33064
+ const family = fontEntry?.elements?.find((child) => child.name === "w:family")?.attributes?.["w:val"];
33065
+ if (!family) return null;
33066
+ const mapped = FONT_FAMILY_FALLBACKS[family.toLowerCase()];
33067
+ return mapped || DEFAULT_GENERIC_FALLBACK;
33068
+ }
33069
+ static toCssFontFamily(fontName, docx) {
33070
+ if (!fontName) return fontName;
33071
+ if (fontName.includes(",")) return fontName;
33072
+ const fallback = _SuperConverter2.getFallbackFromFontTable(docx, fontName) || DEFAULT_GENERIC_FALLBACK;
33073
+ const normalizedFallbackParts = fallback.split(",").map((part) => part.trim().toLowerCase()).filter(Boolean);
33074
+ if (normalizedFallbackParts.includes(fontName.trim().toLowerCase())) {
33075
+ return fallback;
33076
+ }
33077
+ return `${fontName}, ${fallback}`;
33078
+ }
31775
33079
  /**
31776
33080
  * Get the DocxHelpers object that contains utility functions for working with docx files.
31777
33081
  * @returns {import('./docx-helpers/docx-helpers.js').DocxHelpers} The DocxHelpers object.
@@ -31868,13 +33172,19 @@ const _SuperConverter = class _SuperConverter2 {
31868
33172
  if (rPrDefaults) {
31869
33173
  const rPr = rPrDefaults.elements?.find((el) => el.name === "w:rPr");
31870
33174
  const fonts = rPr?.elements?.find((el) => el.name === "w:rFonts");
31871
- typeface = fonts?.attributes["w:ascii"];
31872
- const fontSize2 = typeface ?? rPr?.elements?.find((el) => el.name === "w:sz")?.attributes["w:val"];
31873
- fontSizeNormal = !fontSizeNormal && fontSize2 ? Number(fontSize2) / 2 : null;
33175
+ if (fonts?.attributes?.["w:ascii"]) {
33176
+ typeface = fonts.attributes["w:ascii"];
33177
+ }
33178
+ const fontSizeRaw = rPr?.elements?.find((el) => el.name === "w:sz")?.attributes?.["w:val"];
33179
+ if (!fontSizeNormal && fontSizeRaw) {
33180
+ fontSizeNormal = Number(fontSizeRaw) / 2;
33181
+ }
31874
33182
  }
31875
- const fontSizePt = fontSizeNormal || Number(rElements.find((el) => el.name === "w:sz")?.attributes["w:val"]) / 2 || 10;
33183
+ const fallbackSz = Number(rElements.find((el) => el.name === "w:sz")?.attributes?.["w:val"]);
33184
+ const fontSizePt = fontSizeNormal ?? (Number.isFinite(fallbackSz) ? fallbackSz / 2 : void 0) ?? 10;
31876
33185
  const kern = rElements.find((el) => el.name === "w:kern")?.attributes["w:val"];
31877
- return { fontSizePt, kern, typeface, panose };
33186
+ const fontFamilyCss = _SuperConverter2.toCssFontFamily(typeface, this.convertedXml);
33187
+ return { fontSizePt, kern, typeface, panose, fontFamilyCss };
31878
33188
  }
31879
33189
  }
31880
33190
  getDocumentFonts() {
@@ -43711,6 +45021,96 @@ const toggleMark = (typeOrName, attrs = {}, options = {}) => ({ state: state2, c
43711
45021
  if (isActive2) return commands2.unsetMark(type2, { extendEmptyMarkRange });
43712
45022
  return commands2.setMark(type2, attrs);
43713
45023
  };
45024
+ const toggleMarkCascade = (markName, options = {}) => ({ state: state2, chain, editor }) => {
45025
+ const {
45026
+ negationAttrs = { value: "0" },
45027
+ isNegation = (attrs) => attrs?.value === "0",
45028
+ styleDetector = defaultStyleDetector,
45029
+ extendEmptyMarkRange = true
45030
+ } = options;
45031
+ const selectionMarks = getMarksFromSelection(state2) || [];
45032
+ const inlineMarks = selectionMarks.filter((m2) => m2.type?.name === markName);
45033
+ const hasNegation = inlineMarks.some((m2) => isNegation(m2.attrs || {}));
45034
+ const hasInline = inlineMarks.some((m2) => !isNegation(m2.attrs || {}));
45035
+ const styleOn = styleDetector({ state: state2, selectionMarks, markName, editor });
45036
+ const cmdChain = chain();
45037
+ if (hasNegation) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
45038
+ if (hasInline && styleOn) {
45039
+ return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
45040
+ }
45041
+ if (hasInline) return cmdChain.unsetMark(markName, { extendEmptyMarkRange }).run();
45042
+ if (styleOn) return cmdChain.setMark(markName, negationAttrs, { extendEmptyMarkRange }).run();
45043
+ return cmdChain.setMark(markName, {}, { extendEmptyMarkRange }).run();
45044
+ };
45045
+ function defaultStyleDetector({ state: state2, selectionMarks, markName, editor }) {
45046
+ try {
45047
+ const styleId = getEffectiveStyleId(state2, selectionMarks);
45048
+ if (!styleId || !editor?.converter?.linkedStyles) return false;
45049
+ const styles = editor.converter.linkedStyles;
45050
+ const seen = /* @__PURE__ */ new Set();
45051
+ let current = styleId;
45052
+ const key2 = mapMarkToStyleKey(markName);
45053
+ while (current && !seen.has(current)) {
45054
+ seen.add(current);
45055
+ const style2 = styles.find((s) => s.id === current);
45056
+ const def = style2?.definition?.styles || {};
45057
+ if (key2 in def) {
45058
+ const raw = def[key2];
45059
+ if (raw === void 0) return true;
45060
+ const val = raw?.value ?? raw;
45061
+ return isStyleTokenEnabled(val);
45062
+ }
45063
+ current = style2?.definition?.attrs?.basedOn || null;
45064
+ }
45065
+ return false;
45066
+ } catch {
45067
+ return false;
45068
+ }
45069
+ }
45070
+ function getEffectiveStyleId(state2, selectionMarks) {
45071
+ const sidFromMarks = getStyleIdFromMarks(selectionMarks);
45072
+ if (sidFromMarks) return sidFromMarks;
45073
+ const $from = state2.selection.$from;
45074
+ const before = $from.nodeBefore;
45075
+ const after = $from.nodeAfter;
45076
+ if (before && before.marks) {
45077
+ const sid = getStyleIdFromMarks(before.marks);
45078
+ if (sid) return sid;
45079
+ }
45080
+ if (after && after.marks) {
45081
+ const sid = getStyleIdFromMarks(after.marks);
45082
+ if (sid) return sid;
45083
+ }
45084
+ const ts = selectionMarks.find((m2) => m2.type?.name === "textStyle" && m2.attrs?.styleId);
45085
+ if (ts) return ts.attrs.styleId;
45086
+ const pos = state2.selection.$from.pos;
45087
+ const $pos = state2.doc.resolve(pos);
45088
+ for (let d2 = $pos.depth; d2 >= 0; d2--) {
45089
+ const n = $pos.node(d2);
45090
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
45091
+ }
45092
+ return null;
45093
+ }
45094
+ function getStyleIdFromMarks(marks) {
45095
+ if (!Array.isArray(marks)) return null;
45096
+ const textStyleMark = marks.find((m2) => m2.type?.name === "textStyle" && m2.attrs?.styleId);
45097
+ if (textStyleMark) return textStyleMark.attrs.styleId;
45098
+ return null;
45099
+ }
45100
+ function mapMarkToStyleKey(markName) {
45101
+ if (markName === "textStyle" || markName === "color") return "color";
45102
+ return markName;
45103
+ }
45104
+ function isStyleTokenEnabled(val) {
45105
+ if (val === false || val === 0) return false;
45106
+ if (typeof val === "string") {
45107
+ const normalized = val.trim().toLowerCase();
45108
+ if (!normalized) return false;
45109
+ if (["0", "false", "none", "inherit", "transparent"].includes(normalized)) return false;
45110
+ return true;
45111
+ }
45112
+ return !!val;
45113
+ }
43714
45114
  const clearNodes = () => ({ state: state2, tr, dispatch }) => {
43715
45115
  const { selection } = tr;
43716
45116
  const { ranges } = selection;
@@ -45056,11 +46456,14 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
45056
46456
  command,
45057
46457
  createParagraphNear,
45058
46458
  decreaseListIndent,
46459
+ defaultStyleDetector,
45059
46460
  deleteListItem,
45060
46461
  deleteSelection,
45061
46462
  exitCode,
45062
46463
  first,
46464
+ getEffectiveStyleId,
45063
46465
  getParaCtx,
46466
+ getStyleIdFromMarks,
45064
46467
  handleBackspaceNextToList,
45065
46468
  handleDeleteNextToList,
45066
46469
  increaseListIndent,
@@ -45069,12 +46472,14 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
45069
46472
  insertTabChar,
45070
46473
  insertTabCharacter,
45071
46474
  insertTabNode,
46475
+ isStyleTokenEnabled,
45072
46476
  joinBackward,
45073
46477
  joinDown,
45074
46478
  joinForward,
45075
46479
  joinUp,
45076
46480
  liftEmptyBlock,
45077
46481
  liftListItem,
46482
+ mapMarkToStyleKey,
45078
46483
  nearestListAt,
45079
46484
  newlineInCode,
45080
46485
  rebuildListNodeWithNewNum,
@@ -45094,6 +46499,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
45094
46499
  splitListItem,
45095
46500
  toggleList,
45096
46501
  toggleMark,
46502
+ toggleMarkCascade,
45097
46503
  toggleNode,
45098
46504
  undoInputRule,
45099
46505
  unsetAllMarks,
@@ -45109,6 +46515,7 @@ const Commands = Extension.create({
45109
46515
  });
45110
46516
  const handleEnter = (editor) => {
45111
46517
  return editor.commands.first(({ commands: commands2 }) => [
46518
+ () => commands2.splitRun(),
45112
46519
  () => commands2.newlineInCode(),
45113
46520
  () => commands2.createParagraphNear(),
45114
46521
  () => commands2.liftEmptyBlock(),
@@ -45142,6 +46549,7 @@ const Keymap = Extension.create({
45142
46549
  addShortcuts() {
45143
46550
  const baseKeymap = {
45144
46551
  Enter: () => handleEnter(this.editor),
46552
+ "Shift-Enter": () => this.editor.commands.insertLineBreak(),
45145
46553
  "Mod-Enter": () => this.editor.commands.exitCode(),
45146
46554
  Backspace: () => handleBackspace(this.editor),
45147
46555
  "Mod-Backspace": () => handleBackspace(this.editor),
@@ -46219,7 +47627,18 @@ const updateYdocDocxData = async (editor, ydoc) => {
46219
47627
  ydoc = ydoc || editor.options.ydoc;
46220
47628
  if (!ydoc) return;
46221
47629
  const metaMap = ydoc.getMap("meta");
46222
- const docx = [...metaMap.get("docx")];
47630
+ const docxValue = metaMap.get("docx");
47631
+ let docx = [];
47632
+ if (Array.isArray(docxValue)) {
47633
+ docx = [...docxValue];
47634
+ } else if (docxValue && typeof docxValue.toArray === "function") {
47635
+ docx = docxValue.toArray();
47636
+ } else if (docxValue && typeof docxValue[Symbol.iterator] === "function") {
47637
+ docx = Array.from(docxValue);
47638
+ }
47639
+ if (!docx.length && Array.isArray(editor.options.content)) {
47640
+ docx = [...editor.options.content];
47641
+ }
46223
47642
  const newXml = await editor.exportDocx({ getUpdatedDocs: true });
46224
47643
  Object.keys(newXml).forEach((key2) => {
46225
47644
  const fileIndex = docx.findIndex((item) => item.name === key2);
@@ -46297,7 +47716,7 @@ const createHeaderFooterEditor = ({
46297
47716
  currentPageNumber
46298
47717
  }) => {
46299
47718
  const parentStyles = editor.converter.getDocumentDefaultStyles();
46300
- const { fontSizePt, typeface } = parentStyles;
47719
+ const { fontSizePt, typeface, fontFamilyCss } = parentStyles;
46301
47720
  const fontSizeInPixles = fontSizePt * 1.3333;
46302
47721
  const lineHeight2 = fontSizeInPixles * 1.2;
46303
47722
  Object.assign(editorContainer.style, {
@@ -46310,7 +47729,7 @@ const createHeaderFooterEditor = ({
46310
47729
  left: "0",
46311
47730
  width: "auto",
46312
47731
  maxWidth: "none",
46313
- fontFamily: typeface,
47732
+ fontFamily: fontFamilyCss || typeface,
46314
47733
  fontSize: `${fontSizeInPixles}px`,
46315
47734
  lineHeight: `${lineHeight2}px`
46316
47735
  });
@@ -47140,7 +48559,6 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
47140
48559
  originalStep,
47141
48560
  originalStepIndex
47142
48561
  });
47143
- console.debug("[track-changes]: replaceStep");
47144
48562
  } else if (step instanceof AddMarkStep) {
47145
48563
  addMarkStep({
47146
48564
  state: state2,
@@ -47150,7 +48568,6 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
47150
48568
  user,
47151
48569
  date
47152
48570
  });
47153
- console.debug("[track-changes]: addMarkStep");
47154
48571
  } else if (step instanceof RemoveMarkStep) {
47155
48572
  removeMarkStep({
47156
48573
  state: state2,
@@ -47160,10 +48577,8 @@ const trackedTransaction = ({ tr, state: state2, user }) => {
47160
48577
  user,
47161
48578
  date
47162
48579
  });
47163
- console.debug("[track-changes]: removeMarkStep");
47164
48580
  } else {
47165
48581
  newTr.step(step);
47166
- console.log("[track-changes]: otherStep");
47167
48582
  }
47168
48583
  });
47169
48584
  if (tr.getMeta("inputType")) {
@@ -49233,9 +50648,10 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
49233
50648
  element.style.isolation = "isolate";
49234
50649
  proseMirror.style.outline = "none";
49235
50650
  proseMirror.style.border = "none";
49236
- const { typeface, fontSizePt } = this.converter.getDocumentDefaultStyles() ?? {};
49237
- if (typeface) {
49238
- element.style.fontFamily = typeface;
50651
+ const { typeface, fontSizePt, fontFamilyCss } = this.converter.getDocumentDefaultStyles() ?? {};
50652
+ const resolvedFontFamily = fontFamilyCss || typeface;
50653
+ if (resolvedFontFamily) {
50654
+ element.style.fontFamily = resolvedFontFamily;
49239
50655
  }
49240
50656
  if (fontSizePt) {
49241
50657
  element.style.fontSize = `${fontSizePt}pt`;
@@ -49523,12 +50939,15 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
49523
50939
  }
49524
50940
  destroyHeaderFooterEditors() {
49525
50941
  try {
49526
- const editors = [...this.converter.headerEditors, ...this.converter.footerEditors];
50942
+ const headerEditors = this.converter?.headerEditors ?? [];
50943
+ const footerEditors = this.converter?.footerEditors ?? [];
50944
+ if (!headerEditors.length && !footerEditors.length) return;
50945
+ const editors = [...headerEditors, ...footerEditors].filter(Boolean);
49527
50946
  for (let editorData of editors) {
49528
- editorData.editor.destroy();
50947
+ editorData?.editor?.destroy?.();
49529
50948
  }
49530
- this.converter.headerEditors.length = 0;
49531
- this.converter.footerEditors.length = 0;
50949
+ if (headerEditors.length) headerEditors.length = 0;
50950
+ if (footerEditors.length) footerEditors.length = 0;
49532
50951
  } catch (error) {
49533
50952
  this.emit("exception", { error, editor: this });
49534
50953
  console.error(error);
@@ -50602,6 +52021,7 @@ const FormatCommands = Extension.create({
50602
52021
  },
50603
52022
  addCommands() {
50604
52023
  return {
52024
+ toggleMarkCascade,
50605
52025
  /**
50606
52026
  * Clear all formatting (nodes and marks)
50607
52027
  * @category Command
@@ -51581,27 +53001,69 @@ const Text = Node$1.create({
51581
53001
  return {};
51582
53002
  }
51583
53003
  });
51584
- const RunItem = Node$1.create({
53004
+ const splitRun = () => (props) => {
53005
+ const { state: state2, view, tr } = props;
53006
+ const { $from, empty: empty2 } = state2.selection;
53007
+ if (!empty2) return false;
53008
+ if ($from.parent.type.name !== "run") return false;
53009
+ const handled = splitBlock(state2, (transaction) => {
53010
+ view.dispatch(transaction);
53011
+ });
53012
+ if (handled) {
53013
+ tr.setMeta("preventDispatch", true);
53014
+ }
53015
+ return handled;
53016
+ };
53017
+ const Run = OxmlNode.create({
51585
53018
  name: "run",
53019
+ oXmlName: "w:r",
51586
53020
  group: "inline",
51587
- content: "text*",
51588
53021
  inline: true,
53022
+ content: "inline*",
53023
+ selectable: false,
53024
+ childToAttributes: ["runProperties"],
51589
53025
  addOptions() {
51590
- return {};
51591
- },
51592
- parseDOM() {
51593
- return [{ tag: "run" }];
51594
- },
51595
- renderDOM() {
51596
- return ["run", 0];
53026
+ return {
53027
+ htmlAttributes: {
53028
+ "data-run": "1"
53029
+ }
53030
+ };
51597
53031
  },
51598
53032
  addAttributes() {
51599
53033
  return {
51600
- attributes: {
53034
+ runProperties: {
53035
+ default: null,
51601
53036
  rendered: false,
51602
- "aria-label": "Run node"
53037
+ keepOnSplit: true
53038
+ },
53039
+ rsidR: {
53040
+ default: null,
53041
+ rendered: false,
53042
+ keepOnSplit: true
53043
+ },
53044
+ rsidRPr: {
53045
+ default: null,
53046
+ rendered: false,
53047
+ keepOnSplit: true
53048
+ },
53049
+ rsidDel: {
53050
+ default: null,
53051
+ rendered: false,
53052
+ keepOnSplit: true
51603
53053
  }
51604
53054
  };
53055
+ },
53056
+ addCommands() {
53057
+ return {
53058
+ splitRun
53059
+ };
53060
+ },
53061
+ parseDOM() {
53062
+ return [{ tag: "span[data-run]" }];
53063
+ },
53064
+ renderDOM({ htmlAttributes }) {
53065
+ const base2 = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
53066
+ return ["span", base2, 0];
51605
53067
  }
51606
53068
  });
51607
53069
  const inputRegex$1 = /^\s*([-+*])\s$/;
@@ -51876,6 +53338,115 @@ const OrderedList = Node$1.create({
51876
53338
  ];
51877
53339
  }
51878
53340
  });
53341
+ const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
53342
+ const handler2 = listIndexMap[listNumberingType];
53343
+ return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
53344
+ };
53345
+ const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
53346
+ const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
53347
+ const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
53348
+ const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
53349
+ const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
53350
+ const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
53351
+ const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
53352
+ const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
53353
+ const listIndexMap = {
53354
+ decimal: handleDecimal,
53355
+ lowerRoman: handleLowerRoman,
53356
+ upperRoman: handleRoman,
53357
+ lowerLetter: handleLowerAlpha,
53358
+ upperLetter: handleAlpha,
53359
+ ordinal: handleOrdinal,
53360
+ custom: handleCustom,
53361
+ japaneseCounting: handleJapaneseCounting
53362
+ };
53363
+ const createNumbering = (values, lvlText) => {
53364
+ return values.reduce((acc, value, index2) => {
53365
+ return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
53366
+ }, lvlText);
53367
+ };
53368
+ const generateNumbering = (path, lvlText, formatter) => {
53369
+ const formattedValues = path.map(formatter);
53370
+ return createNumbering(formattedValues, lvlText);
53371
+ };
53372
+ const ordinalFormatter = (level) => {
53373
+ const suffixes = ["th", "st", "nd", "rd"];
53374
+ const value = level % 100;
53375
+ const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
53376
+ const p = level + suffix2;
53377
+ return p;
53378
+ };
53379
+ const generateFromCustom = (path, lvlText, customFormat) => {
53380
+ if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
53381
+ const match = customFormat.match(/(\d+)/);
53382
+ if (!match) throw new Error("Invalid format string: no numeric pattern found");
53383
+ const sample = match[1];
53384
+ const digitCount = sample.length;
53385
+ const index2 = path.pop();
53386
+ return String(index2).padStart(digitCount, "0");
53387
+ };
53388
+ const intToRoman = (num) => {
53389
+ const romanNumeralMap = [
53390
+ { value: 1e3, numeral: "M" },
53391
+ { value: 900, numeral: "CM" },
53392
+ { value: 500, numeral: "D" },
53393
+ { value: 400, numeral: "CD" },
53394
+ { value: 100, numeral: "C" },
53395
+ { value: 90, numeral: "XC" },
53396
+ { value: 50, numeral: "L" },
53397
+ { value: 40, numeral: "XL" },
53398
+ { value: 10, numeral: "X" },
53399
+ { value: 9, numeral: "IX" },
53400
+ { value: 5, numeral: "V" },
53401
+ { value: 4, numeral: "IV" },
53402
+ { value: 1, numeral: "I" }
53403
+ ];
53404
+ let result = "";
53405
+ for (const { value, numeral } of romanNumeralMap) {
53406
+ while (num >= value) {
53407
+ result += numeral;
53408
+ num -= value;
53409
+ }
53410
+ }
53411
+ return result;
53412
+ };
53413
+ const intToAlpha = (num) => {
53414
+ let result = "";
53415
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
53416
+ while (num > 0) {
53417
+ let index2 = (num - 1) % 26;
53418
+ result = alphabet[index2] + result;
53419
+ num = Math.floor((num - 1) / 26);
53420
+ }
53421
+ return result;
53422
+ };
53423
+ const intToJapaneseCounting = (num) => {
53424
+ const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
53425
+ const units = ["", "十", "百", "千"];
53426
+ if (num === 0) return "零";
53427
+ if (num < 10) return digits[num];
53428
+ let result = "";
53429
+ let tempNum = num;
53430
+ let unitIndex = 0;
53431
+ while (tempNum > 0) {
53432
+ const digit = tempNum % 10;
53433
+ if (digit !== 0) {
53434
+ const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
53435
+ result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
53436
+ } else if (result && tempNum > 0) {
53437
+ if (!result.startsWith("零") && tempNum % 100 !== 0) {
53438
+ result = "零" + result;
53439
+ }
53440
+ }
53441
+ tempNum = Math.floor(tempNum / 10);
53442
+ unitIndex++;
53443
+ if (unitIndex > 3) break;
53444
+ }
53445
+ if (num >= 10 && num < 20) {
53446
+ result = result.replace(/^一十/, "十");
53447
+ }
53448
+ return result;
53449
+ };
51879
53450
  const CustomSelectionPluginKey = new PluginKey("CustomSelection");
51880
53451
  const handleClickOutside = (event, editor) => {
51881
53452
  const editorElem = editor?.options?.element;
@@ -52156,6 +53727,7 @@ const getMarksStyle = (attrs) => {
52156
53727
  case "textStyle":
52157
53728
  const { fontFamily: fontFamily2, fontSize: fontSize2 } = attr.attrs;
52158
53729
  styles += `${fontFamily2 ? `font-family: ${fontFamily2};` : ""} ${fontSize2 ? `font-size: ${fontSize2};` : ""}`;
53730
+ break;
52159
53731
  }
52160
53732
  }
52161
53733
  return styles.trim();
@@ -52174,12 +53746,22 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52174
53746
  const linkedDefinitionStyles = { ...linkedStyle.definition.styles };
52175
53747
  const basedOnDefinitionStyles = { ...basedOnStyle?.definition?.styles };
52176
53748
  const resultStyles = { ...linkedDefinitionStyles };
52177
- if (!linkedDefinitionStyles["font-size"] && basedOnDefinitionStyles["font-size"]) {
52178
- resultStyles["font-size"] = basedOnDefinitionStyles["font-size"];
52179
- }
52180
- if (!linkedDefinitionStyles["text-transform"] && basedOnDefinitionStyles["text-transform"]) {
52181
- resultStyles["text-transform"] = basedOnDefinitionStyles["text-transform"];
52182
- }
53749
+ const inheritKeys = [
53750
+ "font-size",
53751
+ "font-family",
53752
+ "text-transform",
53753
+ "bold",
53754
+ "italic",
53755
+ "underline",
53756
+ "strike",
53757
+ "color",
53758
+ "highlight"
53759
+ ];
53760
+ inheritKeys.forEach((k) => {
53761
+ if (!linkedDefinitionStyles[k] && basedOnDefinitionStyles[k]) {
53762
+ resultStyles[k] = basedOnDefinitionStyles[k];
53763
+ }
53764
+ });
52183
53765
  Object.entries(resultStyles).forEach(([k, value]) => {
52184
53766
  const key2 = kebabCase$1(k);
52185
53767
  const flattenedMarks = [];
@@ -52194,6 +53776,10 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52194
53776
  }
52195
53777
  flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
52196
53778
  });
53779
+ const underlineNone = node?.marks?.some((m2) => m2.type?.name === "underline" && m2.attrs?.underlineType === "none");
53780
+ if (underlineNone) {
53781
+ markValue["text-decoration"] = "none";
53782
+ }
52197
53783
  const mark = flattenedMarks.find((n) => n.key === key2);
52198
53784
  const hasParentIndent = Object.keys(parent?.attrs?.indent || {});
52199
53785
  const hasParentSpacing = Object.keys(parent?.attrs?.spacing || {});
@@ -52210,10 +53796,28 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52210
53796
  if (rightIndent) markValue["margin-right"] = rightIndent + "px";
52211
53797
  if (firstLine) markValue["text-indent"] = firstLine + "px";
52212
53798
  } else if (key2 === "bold" && node) {
52213
- const val = value?.value;
52214
- if (!listTypes.includes(node.type.name) && val !== "0") {
53799
+ const boldValue = typeof value === "object" && value !== null ? value.value : value;
53800
+ const hasInlineBoldOff = node.marks?.some((m2) => m2.type?.name === "bold" && m2.attrs?.value === "0");
53801
+ const hasInlineBoldOn = node.marks?.some((m2) => m2.type?.name === "bold" && m2.attrs?.value !== "0");
53802
+ if (!listTypes.includes(node.type.name) && !hasInlineBoldOff && !hasInlineBoldOn && boldValue !== "0" && boldValue !== false) {
52215
53803
  markValue["font-weight"] = "bold";
52216
53804
  }
53805
+ } else if (key2 === "italic" && node) {
53806
+ const italicValue = typeof value === "object" && value !== null ? value.value : value;
53807
+ const hasInlineItalicOff = node.marks?.some((m2) => m2.type?.name === "italic" && m2.attrs?.value === "0");
53808
+ const hasInlineItalicOn = node.marks?.some((m2) => m2.type?.name === "italic" && m2.attrs?.value !== "0");
53809
+ if (!listTypes.includes(node.type.name) && !hasInlineItalicOff && !hasInlineItalicOn && italicValue !== "0" && italicValue !== false) {
53810
+ markValue["font-style"] = "italic";
53811
+ }
53812
+ } else if (key2 === "strike" && node) {
53813
+ const strikeValue = typeof value === "object" && value !== null ? value.value : value;
53814
+ const hasInlineStrikeOff = node.marks?.some((m2) => m2.type?.name === "strike" && m2.attrs?.value === "0");
53815
+ const hasInlineStrikeOn = node.marks?.some(
53816
+ (m2) => m2.type?.name === "strike" && (m2.attrs?.value === void 0 || m2.attrs?.value !== "0")
53817
+ );
53818
+ if (!listTypes.includes(node.type.name) && !hasInlineStrikeOff && !hasInlineStrikeOn && strikeValue !== "0" && strikeValue !== false) {
53819
+ markValue["text-decoration"] = "line-through";
53820
+ }
52217
53821
  } else if (key2 === "text-transform" && node) {
52218
53822
  if (!listTypes.includes(node.type.name)) {
52219
53823
  markValue[key2] = value;
@@ -52222,10 +53826,44 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
52222
53826
  if (!listTypes.includes(node.type.name)) {
52223
53827
  markValue[key2] = value;
52224
53828
  }
53829
+ } else if (key2 === "font-family" && node) {
53830
+ if (!listTypes.includes(node.type.name)) {
53831
+ markValue[key2] = value;
53832
+ }
52225
53833
  } else if (key2 === "color" && node) {
52226
53834
  if (!listTypes.includes(node.type.name)) {
52227
53835
  markValue[key2] = value;
52228
53836
  }
53837
+ } else if (key2 === "highlight" && node) {
53838
+ const hasInlineHighlight = node.marks?.some((m2) => m2.type?.name === "highlight");
53839
+ if (!listTypes.includes(node.type.name) && !hasInlineHighlight) {
53840
+ const color = typeof value === "string" ? value : value?.color;
53841
+ if (color) markValue["background-color"] = color;
53842
+ }
53843
+ } else if (key2 === "underline" && node) {
53844
+ const styleValRaw = value?.value ?? value ?? "";
53845
+ const styleVal = styleValRaw.toString().toLowerCase();
53846
+ const hasInlineUnderlineOff = node.marks?.some(
53847
+ (m2) => m2.type?.name === "underline" && m2.attrs?.underlineType === "none"
53848
+ );
53849
+ const hasInlineUnderlineOn = node.marks?.some(
53850
+ (m2) => m2.type?.name === "underline" && m2.attrs?.underlineType && m2.attrs.underlineType !== "none"
53851
+ );
53852
+ if (!listTypes.includes(node.type.name) && !hasInlineUnderlineOff && !hasInlineUnderlineOn) {
53853
+ if (styleVal && styleVal !== "none" && styleVal !== "0") {
53854
+ const colorVal = value && typeof value === "object" ? value.color || value.underlineColor || null : null;
53855
+ const css = getUnderlineCssString({ type: styleVal, color: colorVal });
53856
+ css.split(";").forEach((decl) => {
53857
+ const d2 = decl.trim();
53858
+ if (!d2) return;
53859
+ const idx = d2.indexOf(":");
53860
+ if (idx === -1) return;
53861
+ const k2 = d2.slice(0, idx).trim();
53862
+ const v2 = d2.slice(idx + 1).trim();
53863
+ markValue[k2] = v2;
53864
+ });
53865
+ }
53866
+ }
52229
53867
  } else if (typeof value === "string") {
52230
53868
  markValue[key2] = value;
52231
53869
  }
@@ -52358,23 +53996,51 @@ const createLinkedStylesPlugin = (editor) => {
52358
53996
  };
52359
53997
  const generateDecorations = (state2, styles) => {
52360
53998
  const decorations = [];
52361
- let lastStyleId = null;
52362
53999
  const doc2 = state2?.doc;
54000
+ const getParagraphStyleId = (pos) => {
54001
+ const $pos = state2.doc.resolve(pos);
54002
+ for (let d2 = $pos.depth; d2 >= 0; d2--) {
54003
+ const n = $pos.node(d2);
54004
+ if (n?.type?.name === "paragraph") return n.attrs?.styleId || null;
54005
+ }
54006
+ return null;
54007
+ };
52363
54008
  doc2.descendants((node, pos) => {
52364
54009
  const { name } = node.type;
52365
- if (node?.attrs?.styleId) lastStyleId = node.attrs.styleId;
52366
- if (name === "paragraph" && !node.attrs?.styleId) lastStyleId = null;
52367
- if (name !== "text" && name !== "listItem" && name !== "orderedList") return;
54010
+ if (name !== "text") return;
54011
+ const paragraphStyleId = getParagraphStyleId(pos);
54012
+ let runStyleId = null;
54013
+ let inlineTextStyleId = null;
52368
54014
  for (const mark of node.marks) {
52369
- if (mark.type.name === "textStyle" && mark.attrs.styleId) {
52370
- lastStyleId = mark.attrs.styleId;
52371
- }
52372
- }
52373
- const { linkedStyle, basedOnStyle } = getLinkedStyle(lastStyleId, styles);
52374
- if (!linkedStyle) return;
54015
+ if (mark.type.name === "run") {
54016
+ const rp = mark.attrs?.runProperties;
54017
+ if (rp && typeof rp === "object" && !Array.isArray(rp) && rp.styleId) runStyleId = rp.styleId;
54018
+ else if (Array.isArray(rp)) {
54019
+ const ent = rp.find((e) => e?.xmlName === "w:rStyle");
54020
+ const sid = ent?.attributes?.["w:val"];
54021
+ if (sid) runStyleId = sid;
54022
+ }
54023
+ } else if (mark.type.name === "textStyle" && mark.attrs?.styleId) {
54024
+ inlineTextStyleId = mark.attrs.styleId;
54025
+ }
54026
+ }
54027
+ const buildStyleMap = (sid) => {
54028
+ if (!sid) return {};
54029
+ const { linkedStyle, basedOnStyle: basedOnStyle2 } = getLinkedStyle(sid, styles);
54030
+ if (!linkedStyle) return {};
54031
+ const base2 = { ...basedOnStyle2?.definition?.styles || {} };
54032
+ return { ...base2, ...linkedStyle.definition?.styles || {} };
54033
+ };
54034
+ const pMap = buildStyleMap(paragraphStyleId);
54035
+ const tMap = buildStyleMap(inlineTextStyleId);
54036
+ const rMap = buildStyleMap(runStyleId);
54037
+ const finalStyles = { ...pMap, ...tMap, ...rMap };
54038
+ if (Object.keys(finalStyles).length === 0) return;
54039
+ const mergedLinkedStyle = { definition: { styles: finalStyles, attrs: {} } };
54040
+ const basedOnStyle = null;
52375
54041
  const $pos = state2.doc.resolve(pos);
52376
54042
  const parent = $pos.parent;
52377
- const styleString = generateLinkedStyleString(linkedStyle, basedOnStyle, node, parent);
54043
+ const styleString = generateLinkedStyleString(mergedLinkedStyle, basedOnStyle, node, parent);
52378
54044
  if (!styleString) return;
52379
54045
  const decoration = Decoration.inline(pos, pos + node.nodeSize, { style: styleString });
52380
54046
  decorations.push(decoration);
@@ -52503,115 +54169,298 @@ const LinkedStyles = Extension.create({
52503
54169
  };
52504
54170
  }
52505
54171
  });
52506
- const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
52507
- const handler2 = listIndexMap[listNumberingType];
52508
- return handler2 ? handler2(listLevel, lvlText, customFormat) : null;
52509
- };
52510
- const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
52511
- const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
52512
- const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
52513
- const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
52514
- const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
52515
- const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
52516
- const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
52517
- const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
52518
- const listIndexMap = {
52519
- decimal: handleDecimal,
52520
- lowerRoman: handleLowerRoman,
52521
- upperRoman: handleRoman,
52522
- lowerLetter: handleLowerAlpha,
52523
- upperLetter: handleAlpha,
52524
- ordinal: handleOrdinal,
52525
- custom: handleCustom,
52526
- japaneseCounting: handleJapaneseCounting
52527
- };
52528
- const createNumbering = (values, lvlText) => {
52529
- return values.reduce((acc, value, index2) => {
52530
- return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
52531
- }, lvlText);
52532
- };
52533
- const generateNumbering = (path, lvlText, formatter) => {
52534
- const formattedValues = path.map(formatter);
52535
- return createNumbering(formattedValues, lvlText);
52536
- };
52537
- const ordinalFormatter = (level) => {
52538
- const suffixes = ["th", "st", "nd", "rd"];
52539
- const value = level % 100;
52540
- const suffix2 = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
52541
- const p = level + suffix2;
52542
- return p;
52543
- };
52544
- const generateFromCustom = (path, lvlText, customFormat) => {
52545
- if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
52546
- const match = customFormat.match(/(\d+)/);
52547
- if (!match) throw new Error("Invalid format string: no numeric pattern found");
52548
- const sample = match[1];
52549
- const digitCount = sample.length;
52550
- const index2 = path.pop();
52551
- return String(index2).padStart(digitCount, "0");
52552
- };
52553
- const intToRoman = (num) => {
52554
- const romanNumeralMap = [
52555
- { value: 1e3, numeral: "M" },
52556
- { value: 900, numeral: "CM" },
52557
- { value: 500, numeral: "D" },
52558
- { value: 400, numeral: "CD" },
52559
- { value: 100, numeral: "C" },
52560
- { value: 90, numeral: "XC" },
52561
- { value: 50, numeral: "L" },
52562
- { value: 40, numeral: "XL" },
52563
- { value: 10, numeral: "X" },
52564
- { value: 9, numeral: "IX" },
52565
- { value: 5, numeral: "V" },
52566
- { value: 4, numeral: "IV" },
52567
- { value: 1, numeral: "I" }
52568
- ];
52569
- let result = "";
52570
- for (const { value, numeral } of romanNumeralMap) {
52571
- while (num >= value) {
52572
- result += numeral;
52573
- num -= value;
54172
+ function getUnderlineCssString({ type: type2 = "single", color = null, thickness = null, approximate = true } = {}) {
54173
+ const parts = [];
54174
+ const add = (k, v2) => {
54175
+ if (!v2) return;
54176
+ parts.push(`${k}: ${v2}`);
54177
+ };
54178
+ const lower = String(type2 || "single").toLowerCase();
54179
+ if (lower === "none" || lower === "0") {
54180
+ add("text-decoration", "none");
54181
+ return parts.join("; ");
54182
+ }
54183
+ add("text-decoration-line", "underline");
54184
+ const HEAVY = thickness || "0.2em";
54185
+ const THICK = thickness || "0.15em";
54186
+ switch (lower) {
54187
+ case "single":
54188
+ break;
54189
+ case "double":
54190
+ add("text-decoration-style", "double");
54191
+ break;
54192
+ case "thick":
54193
+ add("text-decoration-thickness", THICK);
54194
+ break;
54195
+ case "dotted":
54196
+ add("text-decoration-style", "dotted");
54197
+ break;
54198
+ case "dash":
54199
+ case "dashed":
54200
+ add("text-decoration-style", "dashed");
54201
+ break;
54202
+ case "dotdash":
54203
+ case "dotdotdash":
54204
+ case "dashlong":
54205
+ case "dashlongheavy":
54206
+ if (approximate) {
54207
+ add("text-decoration-style", "dashed");
54208
+ if (lower.includes("heavy")) add("text-decoration-thickness", HEAVY);
54209
+ }
54210
+ break;
54211
+ case "dottedheavy":
54212
+ add("text-decoration-style", "dotted");
54213
+ add("text-decoration-thickness", HEAVY);
54214
+ break;
54215
+ case "dashedheavy":
54216
+ add("text-decoration-style", "dashed");
54217
+ add("text-decoration-thickness", HEAVY);
54218
+ break;
54219
+ case "wavy":
54220
+ add("text-decoration-style", "wavy");
54221
+ break;
54222
+ case "wavyheavy":
54223
+ add("text-decoration-style", "wavy");
54224
+ add("text-decoration-thickness", HEAVY);
54225
+ break;
54226
+ case "wavydouble":
54227
+ if (approximate) {
54228
+ add("text-decoration-style", "wavy");
54229
+ add("text-decoration-thickness", HEAVY);
54230
+ }
54231
+ break;
54232
+ }
54233
+ if (color) add("text-decoration-color", color);
54234
+ return parts.join("; ");
54235
+ }
54236
+ function collectTextStyleMarks(listItem, markType) {
54237
+ const textStyleMarks = [];
54238
+ const seenMarks = /* @__PURE__ */ new Set();
54239
+ const attrs = {};
54240
+ if (!markType) {
54241
+ return {
54242
+ marks: textStyleMarks,
54243
+ attrs
54244
+ };
54245
+ }
54246
+ const collectMarks = (node) => {
54247
+ if (!node) return;
54248
+ const candidateMarks = Array.isArray(node.marks) ? node.marks : [];
54249
+ if (candidateMarks.length && typeof markType.isInSet === "function" && markType.isInSet(candidateMarks)) {
54250
+ candidateMarks.forEach((mark) => {
54251
+ if (mark.type === markType && !seenMarks.has(mark)) {
54252
+ seenMarks.add(mark);
54253
+ textStyleMarks.push(mark);
54254
+ }
54255
+ });
54256
+ }
54257
+ if (!node.isText && node.childCount) {
54258
+ node.forEach((child) => collectMarks(child));
54259
+ }
54260
+ };
54261
+ listItem.forEach((childNode) => {
54262
+ if (childNode.type?.name !== "paragraph") return;
54263
+ if (childNode.attrs?.lineHeight !== void 0) {
54264
+ attrs.lineHeight = childNode.attrs.lineHeight;
52574
54265
  }
54266
+ collectMarks(childNode);
54267
+ });
54268
+ return {
54269
+ marks: textStyleMarks,
54270
+ attrs
54271
+ };
54272
+ }
54273
+ function parseSizeFromRunProperties(listRunProperties) {
54274
+ const val = listRunProperties?.["w:val"] || listRunProperties?.["w:sz"];
54275
+ if (val == null) return null;
54276
+ const numeric = Number(val);
54277
+ if (Number.isNaN(numeric) || numeric <= 0) return null;
54278
+ const sizeInPoints = numeric / 2;
54279
+ return `${sizeInPoints}pt`;
54280
+ }
54281
+ function parseFontFamilyFromRunProperties(listRunProperties) {
54282
+ const ascii = listRunProperties?.["w:ascii"];
54283
+ const hAnsi = listRunProperties?.["w:hAnsi"];
54284
+ const eastAsia = listRunProperties?.["w:eastAsia"];
54285
+ return ascii || hAnsi || eastAsia || null;
54286
+ }
54287
+ function readNodeViewStyles(view) {
54288
+ const fallback = { fontSize: null, fontFamily: null, lineHeight: null };
54289
+ if (!view?.dom) return fallback;
54290
+ const inline = {
54291
+ fontSize: view.dom.style?.fontSize || null,
54292
+ fontFamily: view.dom.style?.fontFamily || null,
54293
+ lineHeight: view.dom.style?.lineHeight || null
54294
+ };
54295
+ if (inline.fontSize && inline.fontFamily && inline.lineHeight) return inline;
54296
+ const globalWindow = typeof window !== "undefined" ? window : void 0;
54297
+ if (globalWindow?.getComputedStyle) {
54298
+ const computed2 = globalWindow.getComputedStyle(view.dom);
54299
+ return {
54300
+ fontSize: inline.fontSize || computed2.fontSize,
54301
+ fontFamily: inline.fontFamily || computed2.fontFamily,
54302
+ lineHeight: inline.lineHeight || computed2.lineHeight
54303
+ };
52575
54304
  }
52576
- return result;
52577
- };
52578
- const intToAlpha = (num) => {
52579
- let result = "";
52580
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
52581
- while (num > 0) {
52582
- let index2 = (num - 1) % 26;
52583
- result = alphabet[index2] + result;
52584
- num = Math.floor((num - 1) / 26);
54305
+ return inline;
54306
+ }
54307
+ function getAdjacentListItemNodeView({ nodeView, pos, direction, activeNodeViews }) {
54308
+ if (!activeNodeViews) return null;
54309
+ let candidate = null;
54310
+ activeNodeViews.forEach((view) => {
54311
+ if (view === nodeView) return;
54312
+ let viewPos;
54313
+ try {
54314
+ viewPos = view.getPos();
54315
+ } catch {
54316
+ return;
54317
+ }
54318
+ if (typeof viewPos !== "number") return;
54319
+ if (viewPos < pos) {
54320
+ if (!candidate || viewPos > candidate.pos) candidate = { view, pos: viewPos };
54321
+ }
54322
+ });
54323
+ return candidate?.view ?? null;
54324
+ }
54325
+ function findSiblingListItem({ editor, pos, direction }) {
54326
+ if (typeof pos !== "number" || !editor?.view) return null;
54327
+ const { state: state2 } = editor.view;
54328
+ const $pos = state2.doc.resolve(pos);
54329
+ const parentDepth = $pos.depth - 1;
54330
+ if (parentDepth < 0) return null;
54331
+ const parent = $pos.node(parentDepth);
54332
+ if (!parent) return null;
54333
+ const indexInsideParent = $pos.index(parentDepth);
54334
+ const siblingIndex = indexInsideParent + direction;
54335
+ if (siblingIndex < 0 || siblingIndex >= parent.childCount) return null;
54336
+ const sibling = parent.child(siblingIndex);
54337
+ return sibling?.type?.name === "listItem" ? sibling : null;
54338
+ }
54339
+ function deriveFontStylesFromNode({ node, textStyleType, defaultFont, defaultSize, listRunProperties }) {
54340
+ const { marks: allMarks, attrs } = collectTextStyleMarks(node, textStyleType);
54341
+ const styleMarks = textStyleType ? allMarks.filter((m2) => m2.type === textStyleType) : [];
54342
+ const sizeMark = styleMarks.find((m2) => m2.attrs?.fontSize);
54343
+ const familyMark = styleMarks.find((m2) => m2.attrs?.fontFamily);
54344
+ let fontSize2 = defaultSize;
54345
+ if (sizeMark) {
54346
+ const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
54347
+ if (!Number.isNaN(value)) {
54348
+ fontSize2 = `${value}${unit}`;
54349
+ }
52585
54350
  }
52586
- return result;
52587
- };
52588
- const intToJapaneseCounting = (num) => {
52589
- const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
52590
- const units = ["", "十", "百", "千"];
52591
- if (num === 0) return "零";
52592
- if (num < 10) return digits[num];
52593
- let result = "";
52594
- let tempNum = num;
52595
- let unitIndex = 0;
52596
- while (tempNum > 0) {
52597
- const digit = tempNum % 10;
52598
- if (digit !== 0) {
52599
- const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
52600
- result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
52601
- } else if (result && tempNum > 0) {
52602
- if (!result.startsWith("零") && tempNum % 100 !== 0) {
52603
- result = "零" + result;
52604
- }
54351
+ let hasSize = Boolean(sizeMark);
54352
+ if (!hasSize && listRunProperties) {
54353
+ const sizeFromList = parseSizeFromRunProperties(listRunProperties);
54354
+ if (sizeFromList) {
54355
+ fontSize2 = sizeFromList;
54356
+ hasSize = true;
52605
54357
  }
52606
- tempNum = Math.floor(tempNum / 10);
52607
- unitIndex++;
52608
- if (unitIndex > 3) break;
52609
54358
  }
52610
- if (num >= 10 && num < 20) {
52611
- result = result.replace(/^一十/, "十");
54359
+ let fontFamily2 = familyMark?.attrs?.fontFamily ?? defaultFont;
54360
+ let hasFamily = Boolean(familyMark);
54361
+ if (!hasFamily && listRunProperties) {
54362
+ const fontFromList = parseFontFamilyFromRunProperties(listRunProperties);
54363
+ if (fontFromList) {
54364
+ fontFamily2 = fontFromList;
54365
+ hasFamily = true;
54366
+ }
52612
54367
  }
52613
- return result;
52614
- };
54368
+ let lineHeight2 = attrs.lineHeight;
54369
+ const firstChild = node.firstChild;
54370
+ const hasOnlyOnePar = node.childCount === 1 && firstChild?.type?.name === "paragraph";
54371
+ if (hasOnlyOnePar) {
54372
+ const par = firstChild;
54373
+ const parFirstChild = par?.firstChild;
54374
+ if (par?.childCount === 1 && parFirstChild?.type?.name === "fieldAnnotation") {
54375
+ const aFontSize = parFirstChild.attrs?.fontSize;
54376
+ const aFontFamily = parFirstChild.attrs?.fontFamily;
54377
+ if (!sizeMark && aFontSize) fontSize2 = aFontSize;
54378
+ if (!familyMark && aFontFamily) fontFamily2 = aFontFamily;
54379
+ }
54380
+ }
54381
+ return {
54382
+ fontSize: fontSize2,
54383
+ fontFamily: fontFamily2,
54384
+ lineHeight: lineHeight2,
54385
+ hasSize,
54386
+ hasFamily
54387
+ };
54388
+ }
54389
+ function getStylesFromLinkedStyles({ node, pos, editor }) {
54390
+ const { state: state2 } = editor.view;
54391
+ const linkedStyles = LinkedStylesPluginKey.getState(state2)?.decorations;
54392
+ const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
54393
+ const predicates = [
54394
+ (style22) => style22.includes("font-size") && style22.includes("font-family"),
54395
+ (style22) => style22.includes("font-size"),
54396
+ (style22) => style22.includes("font-family")
54397
+ ];
54398
+ let styleDeco;
54399
+ for (const predicateFn of predicates) {
54400
+ styleDeco = decorationsInPlace?.find((dec) => {
54401
+ const style22 = dec.type?.attrs?.style || "";
54402
+ return style22 && predicateFn(style22);
54403
+ });
54404
+ if (styleDeco) break;
54405
+ }
54406
+ const style2 = styleDeco?.type?.attrs?.style;
54407
+ const stylesArray = style2?.split(";") || [];
54408
+ const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1]?.trim();
54409
+ const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1]?.trim();
54410
+ return {
54411
+ font: fontFamilyFromStyles,
54412
+ size: fontSizeFromStyles
54413
+ };
54414
+ }
54415
+ function resolveListItemTypography({ node, pos, editor, nodeView, activeNodeViews }) {
54416
+ const defaults = getStylesFromLinkedStyles({ node, pos, editor });
54417
+ const textStyleType = getMarkType("textStyle", editor.schema);
54418
+ const currentStyles = deriveFontStylesFromNode({
54419
+ node,
54420
+ textStyleType,
54421
+ defaultFont: defaults.font,
54422
+ defaultSize: defaults.size,
54423
+ listRunProperties: node.attrs?.listRunProperties
54424
+ });
54425
+ if ((!currentStyles.hasSize || !currentStyles.hasFamily || !currentStyles.lineHeight) && editor?.view) {
54426
+ const previousListItem = findSiblingListItem({ editor, pos, direction: -1 });
54427
+ if (previousListItem) {
54428
+ const previousStyles = deriveFontStylesFromNode({
54429
+ node: previousListItem,
54430
+ textStyleType,
54431
+ defaultFont: defaults.font,
54432
+ defaultSize: defaults.size,
54433
+ listRunProperties: previousListItem.attrs?.listRunProperties
54434
+ });
54435
+ if (!currentStyles.hasSize && previousStyles.fontSize) currentStyles.fontSize = previousStyles.fontSize;
54436
+ if (!currentStyles.hasFamily && previousStyles.fontFamily) currentStyles.fontFamily = previousStyles.fontFamily;
54437
+ if (!currentStyles.lineHeight && previousStyles.lineHeight) currentStyles.lineHeight = previousStyles.lineHeight;
54438
+ }
54439
+ }
54440
+ if ((!currentStyles.fontSize || !currentStyles.fontFamily || !currentStyles.lineHeight) && nodeView) {
54441
+ const previousView = getAdjacentListItemNodeView({
54442
+ nodeView,
54443
+ pos,
54444
+ direction: -1,
54445
+ activeNodeViews
54446
+ });
54447
+ if (previousView) {
54448
+ const {
54449
+ fontSize: prevSize,
54450
+ fontFamily: prevFamily,
54451
+ lineHeight: prevLineHeight
54452
+ } = readNodeViewStyles(previousView);
54453
+ if (!currentStyles.fontSize && prevSize) currentStyles.fontSize = prevSize;
54454
+ if (!currentStyles.fontFamily && prevFamily) currentStyles.fontFamily = prevFamily;
54455
+ if (!currentStyles.lineHeight && prevLineHeight) currentStyles.lineHeight = prevLineHeight;
54456
+ }
54457
+ }
54458
+ return {
54459
+ fontSize: currentStyles.fontSize,
54460
+ fontFamily: currentStyles.fontFamily,
54461
+ lineHeight: currentStyles.lineHeight
54462
+ };
54463
+ }
52615
54464
  const MARKER_PADDING = 6;
52616
54465
  const MARKER_OFFSET_RIGHT = 4;
52617
54466
  const MIN_MARKER_WIDTH = 20;
@@ -52629,8 +54478,8 @@ class ListItemNodeView {
52629
54478
  this.decorations = decorations;
52630
54479
  this.view = editor.view;
52631
54480
  this.getPos = getPos;
52632
- activeListItemNodeViews.add(this);
52633
54481
  __privateMethod$1(this, _ListItemNodeView_instances, init_fn2).call(this);
54482
+ activeListItemNodeViews.add(this);
52634
54483
  }
52635
54484
  refreshIndentStyling() {
52636
54485
  const { attrs } = this.node;
@@ -52673,10 +54522,12 @@ class ListItemNodeView {
52673
54522
  update(node, decorations) {
52674
54523
  this.node = node;
52675
54524
  this.decorations = decorations;
52676
- const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = getTextStyleMarksFromLinkedStyles({
54525
+ const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = resolveListItemTypography({
52677
54526
  node,
52678
54527
  pos: this.getPos(),
52679
- editor: this.editor
54528
+ editor: this.editor,
54529
+ nodeView: this,
54530
+ activeNodeViews: activeListItemNodeViews
52680
54531
  });
52681
54532
  this.dom.style.fontSize = fontSize2;
52682
54533
  this.dom.style.fontFamily = fontFamily2 || "inherit";
@@ -52705,10 +54556,12 @@ init_fn2 = function() {
52705
54556
  }
52706
54557
  }
52707
54558
  const pos = this.getPos();
52708
- const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = getTextStyleMarksFromLinkedStyles({
54559
+ const { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 } = resolveListItemTypography({
52709
54560
  node: this.node,
52710
54561
  pos,
52711
- editor: this.editor
54562
+ editor: this.editor,
54563
+ nodeView: this,
54564
+ activeNodeViews: activeListItemNodeViews
52712
54565
  });
52713
54566
  this.dom = document.createElement("li");
52714
54567
  this.dom.className = "sd-editor-list-item-node-view";
@@ -52741,79 +54594,6 @@ function refreshAllListItemNodeViews() {
52741
54594
  }
52742
54595
  });
52743
54596
  }
52744
- function getListItemTextStyleMarks(listItem, markType) {
52745
- let textStyleMarks = [];
52746
- let attrs = {};
52747
- listItem.forEach((childNode) => {
52748
- if (childNode.type.name !== "paragraph") return;
52749
- attrs.lineHeight = childNode.attrs.lineHeight;
52750
- childNode.forEach((textNode) => {
52751
- let isTextNode = textNode.type.name === "text";
52752
- let hasTextStyleMarks = markType.isInSet(textNode.marks);
52753
- if (isTextNode && hasTextStyleMarks) {
52754
- let marks = textNode.marks.filter((mark) => mark.type === markType);
52755
- textStyleMarks.push(...marks);
52756
- }
52757
- });
52758
- });
52759
- return {
52760
- marks: textStyleMarks,
52761
- attrs
52762
- };
52763
- }
52764
- function getTextStyleMarksFromLinkedStyles({ node, pos, editor }) {
52765
- const { font: defaultFont, size: defaultSize } = getStylesFromLinkedStyles({ node, pos, editor });
52766
- const textStyleType = getMarkType("textStyle", editor.schema);
52767
- const { marks: allMarks, attrs: allAttrs } = getListItemTextStyleMarks(node, textStyleType);
52768
- const styleMarks = allMarks.filter((m2) => m2.type === textStyleType);
52769
- const sizeMark = styleMarks.find((m2) => m2.attrs.fontSize);
52770
- const familyMark = styleMarks.find((m2) => m2.attrs.fontFamily);
52771
- const lineHeight2 = allAttrs.lineHeight;
52772
- let fontSize2 = sizeMark ? (() => {
52773
- const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
52774
- return Number.isNaN(value) ? defaultSize : `${value}${unit}`;
52775
- })() : defaultSize;
52776
- let fontFamily2 = familyMark?.attrs.fontFamily ?? defaultFont;
52777
- const firstChild = node.firstChild;
52778
- const hasOnlyOnePar = node.childCount === 1 && firstChild?.type.name === "paragraph";
52779
- if (hasOnlyOnePar) {
52780
- const par = firstChild;
52781
- const parFirstChild = par?.firstChild;
52782
- if (par?.childCount === 1 && parFirstChild?.type.name === "fieldAnnotation") {
52783
- const aFontSize = parFirstChild.attrs.fontSize;
52784
- const aFontFamily = parFirstChild.attrs.fontFamily;
52785
- if (!sizeMark && aFontSize) fontSize2 = aFontSize;
52786
- if (!familyMark && aFontFamily) fontFamily2 = aFontFamily;
52787
- }
52788
- }
52789
- return { fontSize: fontSize2, fontFamily: fontFamily2, lineHeight: lineHeight2 };
52790
- }
52791
- const getStylesFromLinkedStyles = ({ node, pos, editor }) => {
52792
- const { state: state2 } = editor.view;
52793
- const linkedStyles = LinkedStylesPluginKey.getState(state2)?.decorations;
52794
- const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
52795
- const predicates = [
52796
- (style22) => style22.includes("font-size") && style22.includes("font-family"),
52797
- (style22) => style22.includes("font-size"),
52798
- (style22) => style22.includes("font-family")
52799
- ];
52800
- let styleDeco;
52801
- for (const predicateFn of predicates) {
52802
- styleDeco = decorationsInPlace?.find((dec) => {
52803
- const style22 = dec.type.attrs?.style || "";
52804
- return style22 && predicateFn(style22);
52805
- });
52806
- if (styleDeco) break;
52807
- }
52808
- const style2 = styleDeco?.type.attrs?.style;
52809
- const stylesArray = style2?.split(";") || [];
52810
- const fontSizeFromStyles = stylesArray.find((s) => s.includes("font-size"))?.split(":")[1].trim();
52811
- const fontFamilyFromStyles = stylesArray.find((s) => s.includes("font-family"))?.split(":")[1].trim();
52812
- return {
52813
- font: fontFamilyFromStyles,
52814
- size: fontSizeFromStyles
52815
- };
52816
- };
52817
54597
  const getVisibleIndent = (stylePpr, numDefPpr, inlineIndent) => {
52818
54598
  const styleIndentTag = stylePpr?.elements?.find((el) => el.name === "w:ind") || {};
52819
54599
  const styleIndent = parseIndentElement(styleIndentTag);
@@ -53547,6 +55327,211 @@ const CommentsMark = Mark2.create({
53547
55327
  return [CommentMarkName, Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
53548
55328
  }
53549
55329
  });
55330
+ const defaultTabDistance = 48;
55331
+ const defaultLineLength = 816;
55332
+ const getTabDecorations = (doc2, view, from2 = 0, to = null) => {
55333
+ const decorations = [];
55334
+ const paragraphCache = /* @__PURE__ */ new Map();
55335
+ const end2 = to ?? doc2.content.size;
55336
+ doc2.nodesBetween(from2, end2, (node, pos) => {
55337
+ if (node.type.name !== "tab") return;
55338
+ let extraStyles = "";
55339
+ const $pos = doc2.resolve(pos);
55340
+ const paragraphContext = getParagraphContext($pos, paragraphCache);
55341
+ if (!paragraphContext) return;
55342
+ try {
55343
+ const { tabStops, flattened, startPos } = paragraphContext;
55344
+ const entryIndex = flattened.findIndex((entry) => entry.pos === pos);
55345
+ if (entryIndex === -1) return;
55346
+ const indentWidth = getIndentWidth(view, startPos, paragraphContext.indent);
55347
+ const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
55348
+ const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos) + accumulatedTabWidth;
55349
+ let tabWidth;
55350
+ if (tabStops.length) {
55351
+ const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
55352
+ if (tabStop) {
55353
+ tabWidth = tabStop.pos - currentWidth;
55354
+ if (tabStop.val === "center" || tabStop.val === "end" || tabStop.val === "right") {
55355
+ const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
55356
+ const segmentStartPos = pos + node.nodeSize;
55357
+ const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
55358
+ const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos);
55359
+ tabWidth -= tabStop.val === "center" ? segmentWidth / 2 : segmentWidth;
55360
+ } else if (tabStop.val === "decimal" || tabStop.val === "num") {
55361
+ const breakChar = tabStop.decimalChar || ".";
55362
+ const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
55363
+ const integralWidth = decimalPos ? measureRangeWidth(view, pos + node.nodeSize, decimalPos) : measureRangeWidth(view, pos + node.nodeSize, startPos + paragraphContext.paragraph.nodeSize - 1);
55364
+ tabWidth -= integralWidth;
55365
+ }
55366
+ if (tabStop.leader) {
55367
+ const leaderStyles = {
55368
+ dot: "border-bottom: 1px dotted black;",
55369
+ heavy: "border-bottom: 2px solid black;",
55370
+ hyphen: "border-bottom: 1px solid black;",
55371
+ middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
55372
+ underscore: "border-bottom: 1px solid black;"
55373
+ };
55374
+ extraStyles += leaderStyles[tabStop.leader] || "";
55375
+ }
55376
+ }
55377
+ }
55378
+ if (!tabWidth || tabWidth < 1) {
55379
+ tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
55380
+ if (tabWidth === 0) tabWidth = defaultTabDistance;
55381
+ }
55382
+ const tabHeight = calcTabHeight($pos);
55383
+ decorations.push(
55384
+ Decoration.node(pos, pos + node.nodeSize, {
55385
+ style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
55386
+ })
55387
+ );
55388
+ paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
55389
+ } catch (error) {
55390
+ console.error("tab decoration error", error);
55391
+ }
55392
+ });
55393
+ return decorations;
55394
+ };
55395
+ function getParagraphContext($pos, cache2) {
55396
+ for (let depth = $pos.depth; depth >= 0; depth--) {
55397
+ const node = $pos.node(depth);
55398
+ if (node?.type?.name === "paragraph") {
55399
+ const startPos = $pos.start(depth);
55400
+ if (!cache2.has(startPos)) {
55401
+ cache2.set(startPos, {
55402
+ paragraph: node,
55403
+ paragraphDepth: depth,
55404
+ startPos,
55405
+ indent: node.attrs?.indent || {},
55406
+ tabStops: Array.isArray(node.attrs?.tabStops) ? node.attrs.tabStops : [],
55407
+ flattened: flattenParagraph(node, startPos),
55408
+ accumulatedTabWidth: 0
55409
+ });
55410
+ }
55411
+ return cache2.get(startPos);
55412
+ }
55413
+ }
55414
+ return null;
55415
+ }
55416
+ function flattenParagraph(paragraph, paragraphStartPos) {
55417
+ const entries = [];
55418
+ const walk = (node, basePos) => {
55419
+ if (!node) return;
55420
+ if (node.type?.name === "run") {
55421
+ node.forEach((child, offset2) => {
55422
+ const childPos = basePos + offset2 + 1;
55423
+ walk(child, childPos);
55424
+ });
55425
+ return;
55426
+ }
55427
+ entries.push({ node, pos: basePos - 1 });
55428
+ };
55429
+ paragraph.forEach((child, offset2) => {
55430
+ const childPos = paragraphStartPos + offset2 + 1;
55431
+ walk(child, childPos);
55432
+ });
55433
+ return entries;
55434
+ }
55435
+ function findNextTabIndex(flattened, fromIndex) {
55436
+ for (let i = fromIndex; i < flattened.length; i++) {
55437
+ if (flattened[i]?.node?.type?.name === "tab") {
55438
+ return i;
55439
+ }
55440
+ }
55441
+ return -1;
55442
+ }
55443
+ function findDecimalBreakPos(flattened, startIndex, breakChar) {
55444
+ for (let i = startIndex; i < flattened.length; i++) {
55445
+ const entry = flattened[i];
55446
+ if (!entry) break;
55447
+ if (entry.node.type?.name === "tab") break;
55448
+ if (entry.node.type?.name === "text") {
55449
+ const index2 = entry.node.text?.indexOf(breakChar);
55450
+ if (index2 !== void 0 && index2 !== -1) {
55451
+ return entry.pos + index2 + 1;
55452
+ }
55453
+ }
55454
+ }
55455
+ return null;
55456
+ }
55457
+ function measureRangeWidth(view, from2, to) {
55458
+ if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
55459
+ try {
55460
+ const range2 = document.createRange();
55461
+ const fromRef = view.domAtPos(from2);
55462
+ const toRef2 = view.domAtPos(to);
55463
+ range2.setStart(fromRef.node, fromRef.offset);
55464
+ range2.setEnd(toRef2.node, toRef2.offset);
55465
+ const rect = range2.getBoundingClientRect();
55466
+ range2.detach?.();
55467
+ return rect.width || 0;
55468
+ } catch {
55469
+ const startLeft = getLeftCoord(view, from2);
55470
+ const endLeft = getLeftCoord(view, to);
55471
+ if (startLeft == null || endLeft == null) return 0;
55472
+ return Math.max(0, endLeft - startLeft);
55473
+ }
55474
+ }
55475
+ function getIndentWidth(view, paragraphStartPos, indentAttrs = {}) {
55476
+ const marginLeft = getLeftCoord(view, paragraphStartPos);
55477
+ const lineLeft = getLeftCoord(view, paragraphStartPos + 1);
55478
+ if (marginLeft != null && lineLeft != null) {
55479
+ const diff = lineLeft - marginLeft;
55480
+ if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
55481
+ return diff;
55482
+ }
55483
+ }
55484
+ return calculateIndentFallback(indentAttrs);
55485
+ }
55486
+ function calculateIndentFallback(indentAttrs = {}) {
55487
+ if (!indentAttrs) return 0;
55488
+ const left2 = Number(indentAttrs.left) || 0;
55489
+ const firstLine = Number(indentAttrs.firstLine) || 0;
55490
+ const hanging = Number(indentAttrs.hanging) || 0;
55491
+ let textIndent = 0;
55492
+ if (firstLine && hanging) {
55493
+ textIndent = firstLine - hanging;
55494
+ } else if (firstLine) {
55495
+ textIndent = firstLine;
55496
+ } else if (hanging) {
55497
+ textIndent = -hanging;
55498
+ } else if (typeof indentAttrs.textIndent === "string") {
55499
+ const match = indentAttrs.textIndent.match(/(-?\d*\.?\d+)in$/);
55500
+ if (match) {
55501
+ textIndent = Number(match[1]) * 96;
55502
+ }
55503
+ }
55504
+ if (textIndent) return left2 + textIndent;
55505
+ if (left2) return left2;
55506
+ return 0;
55507
+ }
55508
+ function getLeftCoord(view, pos) {
55509
+ if (!Number.isFinite(pos)) return null;
55510
+ try {
55511
+ return view.coordsAtPos(pos).left;
55512
+ } catch {
55513
+ try {
55514
+ const ref2 = view.domAtPos(pos);
55515
+ const range2 = document.createRange();
55516
+ range2.setStart(ref2.node, ref2.offset);
55517
+ range2.setEnd(ref2.node, ref2.offset);
55518
+ const rect = range2.getBoundingClientRect();
55519
+ range2.detach?.();
55520
+ return rect.left;
55521
+ } catch {
55522
+ return null;
55523
+ }
55524
+ }
55525
+ }
55526
+ function calcTabHeight(pos) {
55527
+ const ptToPxRatio = 1.333;
55528
+ const defaultFontSize = 16;
55529
+ const defaultLineHeight = 1.1;
55530
+ const blockParent2 = pos.node(1);
55531
+ const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
55532
+ const fontSize2 = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
55533
+ return `${fontSize2 * defaultLineHeight}px`;
55534
+ }
53550
55535
  const TabNode = Node$1.create({
53551
55536
  name: "tab",
53552
55537
  group: "inline",
@@ -53584,8 +55569,7 @@ const TabNode = Node$1.create({
53584
55569
  };
53585
55570
  },
53586
55571
  addPmPlugins() {
53587
- const { view, schema } = this.editor;
53588
- const domSerializer = DOMSerializer.fromSchema(schema);
55572
+ const { view } = this.editor;
53589
55573
  const tabPlugin = new Plugin({
53590
55574
  name: "tabPlugin",
53591
55575
  key: new PluginKey("tabPlugin"),
@@ -53595,10 +55579,7 @@ const TabNode = Node$1.create({
53595
55579
  },
53596
55580
  apply(tr, { decorations }, _oldState, newState) {
53597
55581
  if (!decorations) {
53598
- decorations = DecorationSet.create(
53599
- newState.doc,
53600
- getTabDecorations(newState.doc, StepMap.empty, view, domSerializer)
53601
- );
55582
+ decorations = DecorationSet.create(newState.doc, getTabDecorations(newState.doc, view));
53602
55583
  }
53603
55584
  if (!tr.docChanged) {
53604
55585
  return { decorations };
@@ -53638,8 +55619,7 @@ const TabNode = Node$1.create({
53638
55619
  rangesToRecalculate.forEach(([start2, end2]) => {
53639
55620
  const oldDecorations = decorations.find(start2, end2);
53640
55621
  decorations = decorations.remove(oldDecorations);
53641
- const invertMapping = tr.mapping.invert();
53642
- const newDecorations = getTabDecorations(newState.doc, invertMapping, view, domSerializer, start2, end2);
55622
+ const newDecorations = getTabDecorations(newState.doc, view, start2, end2);
53643
55623
  decorations = decorations.add(newState.doc, newDecorations);
53644
55624
  });
53645
55625
  return { decorations };
@@ -53654,156 +55634,6 @@ const TabNode = Node$1.create({
53654
55634
  return [tabPlugin];
53655
55635
  }
53656
55636
  });
53657
- const defaultTabDistance = 48;
53658
- const defaultLineLength = 816;
53659
- const getTabDecorations = (doc2, invertMapping, view, domSerializer, from2 = 0, to = null) => {
53660
- if (!to) {
53661
- to = doc2.content.size;
53662
- }
53663
- const nodeWidthCache = {};
53664
- let decorations = [];
53665
- doc2.nodesBetween(from2, to, (node, pos, parent) => {
53666
- if (node.type.name === "tab") {
53667
- let extraStyles = "";
53668
- const $pos = doc2.resolve(pos);
53669
- const tabIndex = $pos.index($pos.depth);
53670
- const fistlineIndent = parent.attrs?.indent?.firstLine || 0;
53671
- const currentWidth = calcChildNodesWidth(
53672
- parent,
53673
- pos - $pos.parentOffset,
53674
- 0,
53675
- tabIndex,
53676
- domSerializer,
53677
- view,
53678
- invertMapping,
53679
- nodeWidthCache
53680
- ) + fistlineIndent;
53681
- let tabWidth;
53682
- if ($pos.depth === 1 && parent.attrs.tabStops && parent.attrs.tabStops.length > 0) {
53683
- const tabStop = parent.attrs.tabStops.find((tabStop2) => tabStop2.pos > currentWidth && tabStop2.val !== "clear");
53684
- if (tabStop) {
53685
- tabWidth = tabStop.pos - currentWidth;
53686
- if (["end", "center"].includes(tabStop.val)) {
53687
- let nextTabIndex = tabIndex + 1;
53688
- while (nextTabIndex < parent.childCount && parent.child(nextTabIndex).type.name !== "tab") {
53689
- nextTabIndex++;
53690
- }
53691
- const tabSectionWidth = calcChildNodesWidth(
53692
- parent,
53693
- pos - $pos.parentOffset,
53694
- tabIndex,
53695
- nextTabIndex,
53696
- domSerializer,
53697
- view,
53698
- invertMapping,
53699
- nodeWidthCache
53700
- );
53701
- tabWidth -= tabStop.val === "end" ? tabSectionWidth : tabSectionWidth / 2;
53702
- } else if (["decimal", "num"].includes(tabStop.val)) {
53703
- const breakChar = ".";
53704
- let nodeIndex = tabIndex + 1;
53705
- let integralWidth = 0;
53706
- let nodePos = pos - $pos.parentOffset;
53707
- while (nodeIndex < parent.childCount) {
53708
- const node2 = parent.child(nodeIndex);
53709
- if (node2.type.name === "tab") {
53710
- break;
53711
- }
53712
- const oldPos = invertMapping.map(nodePos);
53713
- if (node2.type.name === "text" && node2.text.includes(breakChar)) {
53714
- const modifiedNode = node2.cut(0, node2.text.indexOf(breakChar));
53715
- integralWidth += calcNodeWidth(domSerializer, modifiedNode, view, oldPos);
53716
- break;
53717
- }
53718
- integralWidth += calcNodeWidth(domSerializer, node2, view, oldPos);
53719
- nodeWidthCache[nodePos] = integralWidth;
53720
- nodePos += node2.nodeSize;
53721
- nodeIndex += 1;
53722
- }
53723
- tabWidth -= integralWidth;
53724
- }
53725
- if (tabStop.leader) {
53726
- if (tabStop.leader === "dot") {
53727
- extraStyles += `border-bottom: 1px dotted black;`;
53728
- } else if (tabStop.leader === "heavy") {
53729
- extraStyles += `border-bottom: 2px solid black;`;
53730
- } else if (tabStop.leader === "hyphen") {
53731
- extraStyles += `border-bottom: 1px solid black;`;
53732
- } else if (tabStop.leader === "middleDot") {
53733
- extraStyles += `border-bottom: 1px dotted black; margin-bottom: 2px;`;
53734
- } else if (tabStop.leader === "underscore") {
53735
- extraStyles += `border-bottom: 1px solid black;`;
53736
- }
53737
- }
53738
- }
53739
- }
53740
- if (!tabWidth || tabWidth < 1) {
53741
- tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
53742
- if (tabWidth === 0) {
53743
- tabWidth = defaultTabDistance;
53744
- }
53745
- }
53746
- nodeWidthCache[pos] = tabWidth;
53747
- const tabHeight = calcTabHeight($pos);
53748
- decorations.push(
53749
- Decoration.node(pos, pos + node.nodeSize, {
53750
- style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
53751
- })
53752
- );
53753
- }
53754
- });
53755
- return decorations;
53756
- };
53757
- function calcNodeWidth(domSerializer, node, view, oldPos) {
53758
- const oldDomNode = view.nodeDOM(oldPos);
53759
- const styleReference = oldDomNode ? oldDomNode.nodeName === "#text" ? oldDomNode.parentNode : oldDomNode : view.dom;
53760
- const temp = document.createElement("div");
53761
- const style2 = window.getComputedStyle(styleReference);
53762
- temp.style.cssText = `
53763
- position: absolute;
53764
- top: -9999px;
53765
- left: -9999px;
53766
- white-space: nowrap;
53767
- font-family: ${style2.fontFamily};
53768
- font-size: ${style2.fontSize};
53769
- font-weight: ${style2.fontWeight};
53770
- font-style: ${style2.fontStyle};
53771
- letter-spacing: ${style2.letterSpacing};
53772
- word-spacing: ${style2.wordSpacing};
53773
- text-transform: ${style2.textTransform};
53774
- display: inline-block;
53775
- `;
53776
- const domNode = domSerializer.serializeNode(node);
53777
- temp.appendChild(domNode);
53778
- document.body.appendChild(temp);
53779
- const width = temp.offsetWidth;
53780
- document.body.removeChild(temp);
53781
- return width;
53782
- }
53783
- function calcChildNodesWidth(parent, parentPos, startIndex, endIndex, domSerializer, view, invertMapping, nodeWidthCache) {
53784
- let pos = parentPos;
53785
- let width = 0;
53786
- for (let i = 0; i < endIndex; i++) {
53787
- const node = parent.child(i);
53788
- if (i >= startIndex) {
53789
- if (!nodeWidthCache[pos]) {
53790
- nodeWidthCache[pos] = calcNodeWidth(domSerializer, node, view, invertMapping.map(pos));
53791
- }
53792
- width += nodeWidthCache[pos];
53793
- }
53794
- pos += node.nodeSize;
53795
- }
53796
- return width;
53797
- }
53798
- function calcTabHeight(pos) {
53799
- const ptToPxRatio = 1.333;
53800
- const defaultFontSize = 16;
53801
- const defaultLineHeight = 1.1;
53802
- const blockParent2 = pos.node(1);
53803
- const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
53804
- const fontSize2 = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
53805
- return `${fontSize2 * defaultLineHeight}px`;
53806
- }
53807
55637
  const LineBreak = Node$1.create({
53808
55638
  name: "lineBreak",
53809
55639
  group: "inline",
@@ -59470,10 +61300,10 @@ const Image = Node$1.create({
59470
61300
  },
59471
61301
  padding: {
59472
61302
  default: {},
59473
- renderDOM: ({ size: size2 = {}, padding, marginOffset, transformData }) => {
61303
+ renderDOM: ({ size: size2 = {}, padding, marginOffset, transformData = {} }) => {
59474
61304
  let { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
59475
- const { rotation } = transformData ?? {};
59476
- const { height, width } = size2 ?? {};
61305
+ const { rotation } = transformData;
61306
+ const { height, width } = size2;
59477
61307
  if (rotation && height && width) {
59478
61308
  const { horizontal, vertical } = getRotationMargins(width, height, rotation);
59479
61309
  left2 += horizontal;
@@ -61264,6 +63094,30 @@ const TextStyle = Mark2.create({
61264
63094
  };
61265
63095
  }
61266
63096
  });
63097
+ function createCascadeToggleCommands({
63098
+ markName,
63099
+ setCommand,
63100
+ unsetCommand,
63101
+ toggleCommand,
63102
+ negationAttrs,
63103
+ isNegation,
63104
+ extendEmptyMarkRange
63105
+ } = {}) {
63106
+ if (!markName) throw new Error("createCascadeToggleCommands requires a markName");
63107
+ const capitalized = markName.charAt(0).toUpperCase() + markName.slice(1);
63108
+ const setName = setCommand ?? `set${capitalized}`;
63109
+ const unsetName = unsetCommand ?? `unset${capitalized}`;
63110
+ const toggleName = toggleCommand ?? `toggle${capitalized}`;
63111
+ const cascadeOptions = {};
63112
+ if (negationAttrs) cascadeOptions.negationAttrs = negationAttrs;
63113
+ if (typeof isNegation === "function") cascadeOptions.isNegation = isNegation;
63114
+ if (extendEmptyMarkRange !== void 0) cascadeOptions.extendEmptyMarkRange = extendEmptyMarkRange;
63115
+ return {
63116
+ [setName]: () => ({ commands: commands2 }) => commands2.setMark(markName),
63117
+ [unsetName]: () => ({ commands: commands2 }) => commands2.unsetMark(markName),
63118
+ [toggleName]: () => ({ commands: commands2 }) => commands2.toggleMarkCascade(markName, cascadeOptions)
63119
+ };
63120
+ }
61267
63121
  const Bold = Mark2.create({
61268
63122
  name: "bold",
61269
63123
  addOptions() {
@@ -61294,9 +63148,18 @@ const Bold = Mark2.create({
61294
63148
  ];
61295
63149
  },
61296
63150
  renderDOM({ htmlAttributes }) {
61297
- return ["strong", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63151
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63152
+ const { value, ...rest } = merged || {};
63153
+ if (value === "0") {
63154
+ return ["span", rest, 0];
63155
+ }
63156
+ return ["strong", rest, 0];
61298
63157
  },
61299
63158
  addCommands() {
63159
+ const { setBold, unsetBold, toggleBold } = createCascadeToggleCommands({
63160
+ markName: this.name,
63161
+ negationAttrs: { value: "0" }
63162
+ });
61300
63163
  return {
61301
63164
  /**
61302
63165
  * Apply bold formatting
@@ -61305,21 +63168,21 @@ const Bold = Mark2.create({
61305
63168
  * editor.commands.setBold()
61306
63169
  * @note '0' renders as normal weight
61307
63170
  */
61308
- setBold: () => ({ commands: commands2 }) => commands2.setMark(this.name),
63171
+ setBold,
61309
63172
  /**
61310
63173
  * Remove bold formatting
61311
63174
  * @category Command
61312
63175
  * @example
61313
63176
  * editor.commands.unsetBold()
61314
63177
  */
61315
- unsetBold: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
63178
+ unsetBold,
61316
63179
  /**
61317
63180
  * Toggle bold formatting
61318
63181
  * @category Command
61319
63182
  * @example
61320
63183
  * editor.commands.toggleBold()
61321
63184
  */
61322
- toggleBold: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
63185
+ toggleBold
61323
63186
  };
61324
63187
  },
61325
63188
  addShortcuts() {
@@ -61336,6 +63199,22 @@ const Italic = Mark2.create({
61336
63199
  htmlAttributes: {}
61337
63200
  };
61338
63201
  },
63202
+ addAttributes() {
63203
+ return {
63204
+ /**
63205
+ * @category Attribute
63206
+ * @param {string} [value] - Italic toggle value ('0' renders as normal)
63207
+ */
63208
+ value: {
63209
+ default: null,
63210
+ renderDOM: (attrs) => {
63211
+ if (!attrs.value) return {};
63212
+ if (attrs.value === "0") return { style: "font-style: normal" };
63213
+ return {};
63214
+ }
63215
+ }
63216
+ };
63217
+ },
61339
63218
  parseDOM() {
61340
63219
  return [
61341
63220
  { tag: "i" },
@@ -61345,9 +63224,18 @@ const Italic = Mark2.create({
61345
63224
  ];
61346
63225
  },
61347
63226
  renderDOM({ htmlAttributes }) {
61348
- return ["em", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63227
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63228
+ const { value, ...rest } = merged || {};
63229
+ if (value === "0") {
63230
+ return ["span", rest, 0];
63231
+ }
63232
+ return ["em", rest, 0];
61349
63233
  },
61350
63234
  addCommands() {
63235
+ const { setItalic, unsetItalic, toggleItalic } = createCascadeToggleCommands({
63236
+ markName: this.name,
63237
+ negationAttrs: { value: "0" }
63238
+ });
61351
63239
  return {
61352
63240
  /**
61353
63241
  * Apply italic formatting
@@ -61355,21 +63243,21 @@ const Italic = Mark2.create({
61355
63243
  * @example
61356
63244
  * editor.commands.setItalic()
61357
63245
  */
61358
- setItalic: () => ({ commands: commands2 }) => commands2.setMark(this.name),
63246
+ setItalic,
61359
63247
  /**
61360
63248
  * Remove italic formatting
61361
63249
  * @category Command
61362
63250
  * @example
61363
63251
  * editor.commands.unsetItalic()
61364
63252
  */
61365
- unsetItalic: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
63253
+ unsetItalic,
61366
63254
  /**
61367
63255
  * Toggle italic formatting
61368
63256
  * @category Command
61369
63257
  * @example
61370
63258
  * editor.commands.toggleItalic()
61371
63259
  */
61372
- toggleItalic: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
63260
+ toggleItalic
61373
63261
  };
61374
63262
  },
61375
63263
  addShortcuts() {
@@ -61394,7 +63282,16 @@ const Underline = Mark2.create({
61394
63282
  ];
61395
63283
  },
61396
63284
  renderDOM({ htmlAttributes }) {
61397
- return ["u", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63285
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63286
+ const type2 = merged?.underlineType;
63287
+ const color = merged?.underlineColor;
63288
+ const css = getUnderlineCssString({ type: type2, color });
63289
+ const { style: style2, ...rest } = merged || {};
63290
+ const styleString = [style2, css].filter(Boolean).join("; ");
63291
+ if (type2 === "none") {
63292
+ return ["span", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
63293
+ }
63294
+ return ["u", { ...rest, ...styleString ? { style: styleString } : {} }, 0];
61398
63295
  },
61399
63296
  addAttributes() {
61400
63297
  return {
@@ -61404,10 +63301,18 @@ const Underline = Mark2.create({
61404
63301
  */
61405
63302
  underlineType: {
61406
63303
  default: "single"
63304
+ },
63305
+ underlineColor: {
63306
+ default: null
61407
63307
  }
61408
63308
  };
61409
63309
  },
61410
63310
  addCommands() {
63311
+ const { setUnderline, unsetUnderline, toggleUnderline } = createCascadeToggleCommands({
63312
+ markName: this.name,
63313
+ negationAttrs: { underlineType: "none" },
63314
+ isNegation: (attrs) => attrs?.underlineType === "none"
63315
+ });
61411
63316
  return {
61412
63317
  /**
61413
63318
  * Apply underline formatting
@@ -61416,7 +63321,7 @@ const Underline = Mark2.create({
61416
63321
  * @example
61417
63322
  * setUnderline()
61418
63323
  */
61419
- setUnderline: () => ({ commands: commands2 }) => commands2.setMark(this.name),
63324
+ setUnderline,
61420
63325
  /**
61421
63326
  * Remove underline formatting
61422
63327
  * @category Command
@@ -61424,7 +63329,7 @@ const Underline = Mark2.create({
61424
63329
  * @example
61425
63330
  * unsetUnderline()
61426
63331
  */
61427
- unsetUnderline: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
63332
+ unsetUnderline,
61428
63333
  /**
61429
63334
  * Toggle underline formatting
61430
63335
  * @category Command
@@ -61432,7 +63337,7 @@ const Underline = Mark2.create({
61432
63337
  * @example
61433
63338
  * toggleUnderline()
61434
63339
  */
61435
- toggleUnderline: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
63340
+ toggleUnderline
61436
63341
  };
61437
63342
  },
61438
63343
  addShortcuts() {
@@ -61520,9 +63425,18 @@ const Strike = Mark2.create({
61520
63425
  ];
61521
63426
  },
61522
63427
  renderDOM({ htmlAttributes }) {
61523
- return ["s", Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
63428
+ const merged = Attribute2.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
63429
+ const { value, ...rest } = merged || {};
63430
+ if (value === "0") {
63431
+ return ["span", rest, 0];
63432
+ }
63433
+ return ["s", rest, 0];
61524
63434
  },
61525
63435
  addCommands() {
63436
+ const { setStrike, unsetStrike, toggleStrike } = createCascadeToggleCommands({
63437
+ markName: this.name,
63438
+ negationAttrs: { value: "0" }
63439
+ });
61526
63440
  return {
61527
63441
  /**
61528
63442
  * Apply strikethrough formatting
@@ -61530,26 +63444,38 @@ const Strike = Mark2.create({
61530
63444
  * @example
61531
63445
  * editor.commands.setStrike()
61532
63446
  */
61533
- setStrike: () => ({ commands: commands2 }) => {
61534
- return commands2.setMark(this.name);
61535
- },
63447
+ setStrike,
61536
63448
  /**
61537
63449
  * Remove strikethrough formatting
61538
63450
  * @category Command
61539
63451
  * @example
61540
63452
  * editor.commands.unsetStrike()
61541
63453
  */
61542
- unsetStrike: () => ({ commands: commands2 }) => {
61543
- return commands2.unsetMark(this.name);
61544
- },
63454
+ unsetStrike,
61545
63455
  /**
61546
63456
  * Toggle strikethrough formatting
61547
63457
  * @category Command
61548
63458
  * @example
61549
63459
  * editor.commands.toggleStrike()
61550
63460
  */
61551
- toggleStrike: () => ({ commands: commands2 }) => {
61552
- return commands2.toggleMark(this.name);
63461
+ toggleStrike
63462
+ };
63463
+ },
63464
+ addAttributes() {
63465
+ return {
63466
+ /**
63467
+ * @category Attribute
63468
+ * @param {string} [value] - Strike toggle value ('0' renders as normal)
63469
+ */
63470
+ value: {
63471
+ default: null,
63472
+ renderDOM: (attrs) => {
63473
+ if (!attrs.value) return {};
63474
+ if (attrs.value === "0") {
63475
+ return { style: "text-decoration: none" };
63476
+ }
63477
+ return {};
63478
+ }
61553
63479
  }
61554
63480
  };
61555
63481
  },
@@ -67690,7 +69616,7 @@ const getStarterExtensions = () => {
67690
69616
  Paragraph,
67691
69617
  LineBreak,
67692
69618
  HardBreak,
67693
- RunItem,
69619
+ Run,
67694
69620
  SlashMenu,
67695
69621
  Strike,
67696
69622
  TabNode,
@@ -80918,6 +82844,38 @@ const toolbarTexts = {
80918
82844
  documentViewingModeDescription: "View clean version of document only",
80919
82845
  linkedStyles: "Linked styles"
80920
82846
  };
82847
+ const isOffValue = (value) => {
82848
+ if (value == null) return false;
82849
+ const normalized = String(value).toLowerCase();
82850
+ return normalized === "0" || normalized === "false" || normalized === "off";
82851
+ };
82852
+ const negationChecks = {
82853
+ bold: (attrs = {}) => isOffValue(attrs.value),
82854
+ italic: (attrs = {}) => isOffValue(attrs.value),
82855
+ strike: (attrs = {}) => isOffValue(attrs.value),
82856
+ underline: (attrs = {}) => {
82857
+ const type2 = attrs.underlineType ?? attrs.value;
82858
+ if (type2 == null) return false;
82859
+ const normalized = String(type2).toLowerCase();
82860
+ return normalized === "none" || isOffValue(normalized);
82861
+ },
82862
+ color: (attrs = {}) => {
82863
+ const value = attrs.color;
82864
+ if (value == null) return true;
82865
+ return String(value).toLowerCase() === "inherit";
82866
+ },
82867
+ highlight: (attrs = {}) => {
82868
+ const value = attrs.color;
82869
+ if (value == null) return true;
82870
+ const normalized = String(value).toLowerCase();
82871
+ return normalized === "transparent" || normalized === "none";
82872
+ }
82873
+ };
82874
+ const isNegatedMark = (name, attrs = {}) => {
82875
+ const checker = negationChecks[name];
82876
+ if (typeof checker !== "function") return false;
82877
+ return Boolean(checker(attrs));
82878
+ };
80921
82879
  class SuperToolbar extends EventEmitter2 {
80922
82880
  /**
80923
82881
  * Creates a new SuperToolbar instance
@@ -81011,10 +82969,14 @@ class SuperToolbar extends EventEmitter2 {
81011
82969
  * @param {string} params.argument - The color to set
81012
82970
  * @returns {void}
81013
82971
  */
81014
- setColor: ({ item, argument }) => {
81015
- __privateMethod(this, _SuperToolbar_instances, runCommandWithArgumentOnly_fn).call(this, { item, argument }, () => {
81016
- this.activeEditor?.commands.setFieldAnnotationsTextColor(argument, true);
81017
- });
82972
+ setColor: ({ argument }) => {
82973
+ if (!argument || !this.activeEditor) return;
82974
+ const isNone = argument === "none";
82975
+ const value = isNone ? "inherit" : argument;
82976
+ if (this.activeEditor?.commands?.setColor) this.activeEditor.commands.setColor(value);
82977
+ const argValue = isNone ? null : argument;
82978
+ this.activeEditor?.commands.setFieldAnnotationsTextColor(argValue, true);
82979
+ this.updateToolbarState();
81018
82980
  },
81019
82981
  /**
81020
82982
  * Sets the highlight color for text
@@ -81023,12 +82985,14 @@ class SuperToolbar extends EventEmitter2 {
81023
82985
  * @param {string} params.argument - The highlight color to set
81024
82986
  * @returns {void}
81025
82987
  */
81026
- setHighlight: ({ item, argument }) => {
81027
- __privateMethod(this, _SuperToolbar_instances, runCommandWithArgumentOnly_fn).call(this, { item, argument, noArgumentCallback: true }, () => {
81028
- let arg = argument !== "none" ? argument : null;
81029
- this.activeEditor?.commands.setFieldAnnotationsTextHighlight(arg, true);
81030
- this.activeEditor?.commands.setCellBackground(arg);
81031
- });
82988
+ setHighlight: ({ argument }) => {
82989
+ if (!argument || !this.activeEditor) return;
82990
+ const inlineColor = argument !== "none" ? argument : "transparent";
82991
+ if (this.activeEditor?.commands?.setHighlight) this.activeEditor.commands.setHighlight(inlineColor);
82992
+ const argValue = argument !== "none" ? argument : null;
82993
+ this.activeEditor?.commands.setFieldAnnotationsTextHighlight(argValue, true);
82994
+ this.activeEditor?.commands.setCellBackground(argValue);
82995
+ this.updateToolbarState();
81032
82996
  },
81033
82997
  /**
81034
82998
  * Toggles the ruler visibility
@@ -81345,14 +83309,16 @@ class SuperToolbar extends EventEmitter2 {
81345
83309
  return item.activate();
81346
83310
  }
81347
83311
  }
81348
- const activeMark = marks.find((mark) => mark.name === item.name.value);
83312
+ const rawActiveMark = marks.find((mark) => mark.name === item.name.value);
83313
+ const markNegated = rawActiveMark ? isNegatedMark(rawActiveMark.name, rawActiveMark.attrs) : false;
83314
+ const activeMark = markNegated ? null : rawActiveMark;
81349
83315
  if (activeMark) {
81350
83316
  item.activate(activeMark.attrs);
81351
83317
  } else {
81352
83318
  item.deactivate();
81353
83319
  }
81354
83320
  const styleIdMark = marks.find((mark) => mark.name === "styleId");
81355
- if (!activeMark && styleIdMark?.attrs.styleId) {
83321
+ if (!activeMark && !markNegated && styleIdMark?.attrs.styleId) {
81356
83322
  const markToStyleMap = {
81357
83323
  fontSize: "font-size",
81358
83324
  fontFamily: "font-family",
@@ -81410,7 +83376,6 @@ class SuperToolbar extends EventEmitter2 {
81410
83376
  if (!command2) {
81411
83377
  return;
81412
83378
  }
81413
- this.log("(emmitCommand) Command:", command2, "\n item:", item, "\n argument:", argument, "\n option:", option);
81414
83379
  if (command2 in __privateGet(this, _interceptedCommands)) {
81415
83380
  return __privateGet(this, _interceptedCommands)[command2]({ item, argument });
81416
83381
  }
@@ -82973,6 +84938,36 @@ const _sfc_main = {
82973
84938
  }
82974
84939
  };
82975
84940
  const SuperInput = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4d5cff52"]]);
84941
+ const baseHandlers = {
84942
+ ...runPropertyTranslators,
84943
+ "w:br": translator$15,
84944
+ "w:cantSplit": translator$S,
84945
+ "w:cnfStyle": translator$R,
84946
+ "w:divId": translator$Q,
84947
+ "w:gridAfter": translator$P,
84948
+ "w:gridBefore": translator$O,
84949
+ "w:hidden": translator$N,
84950
+ "w:hyperlink": translator$6,
84951
+ "w:jc": translator$M,
84952
+ "w:p": translator$12,
84953
+ "w:r": translator$T,
84954
+ "w:rPr": translator$U,
84955
+ "w:sdt": translator$2,
84956
+ "w:tab": translator$13,
84957
+ "w:tblCellSpacing": translator$L,
84958
+ "w:tblHeader": translator$K,
84959
+ "w:tc": translator$7,
84960
+ "w:tr": translator$F,
84961
+ "w:trHeight": translator$J,
84962
+ "w:trPr": translator$G,
84963
+ "w:wAfter": translator$I,
84964
+ "w:wBefore": translator$H,
84965
+ "wp:anchor": translator$5,
84966
+ "wp:inline": translator$4,
84967
+ "w:bookmarkStart": translator$1,
84968
+ "w:bookmarkEnd": translator
84969
+ };
84970
+ const registeredHandlers = Object.freeze(baseHandlers);
82976
84971
  const Extensions = {
82977
84972
  Node: Node$1,
82978
84973
  Attribute: Attribute2,