@makhmudov.kay/az-editor 0.1.0-beta.5 → 0.1.0-beta.6

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Изменения
2
2
 
3
+ ## 0.1.0-beta.6
4
+
5
+ - Исправлена потеря `page-break-*` в Chromium. Поддерживаемые `break-*` приводятся к серверным `page-break-*` с учётом порядка деклараций; `page` соответствует `always`, `avoid-page` — `avoid`.
6
+ - Разрывы на абзацах, контейнерах и до/после таблиц сохраняются после правок и повторного открытия. Смежные правила одного разрыва не создают лишнюю страницу; явные пустые маркеры остаются разрывами.
7
+ - Сохраняются минимальные высоты строк таблиц, `cantSplit`, начальные повторяемые строки шапки и режим `table-layout:auto/fixed`. Ширина таблицы в абсолютных единицах не подгоняется молча под текстовую область.
8
+ - Потеря плавающего размещения таблицы теперь даёт `floating-table-position-lost` уровня `loss`. Строгий HTML-экспорт требует обработки этой диагностики; прямой DOCX-режим не изменён. Правило точной высоты строки диагностируется как `table-row-height-rule-lost`.
9
+ - В адресах диагностик появились необязательные `tableIndex` и `rowIndex` (с нуля, внутри XML-части).
10
+
11
+ Временный CSSOM/Vite-патч потребителя (`azEditorPaginationCompat`) для beta.4/beta.5 можно
12
+ убрать после установки beta.6 и проверки цикла редактирования. Новый формат метаданных,
13
+ изображения и расширение HTTP-контракта
14
+ в этот этап не входят; отсутствующие во входном HTML сведения не восстанавливаются.
15
+
3
16
  ## 0.1.0-beta.5
4
17
 
5
18
  - `HujjatPage`, `HujjatLocaleContent`, `validateHujjatPage` и `AzHtmlEditor.page`: ориентация A4, шрифт, межстрочный и абзацный интервалы учитываются при открытии.
package/README.md CHANGED
@@ -17,7 +17,7 @@ npm install @makhmudov.kay/az-editor@beta
17
17
  Для воспроизводимой установки опубликованной версии:
18
18
 
19
19
  ```sh
20
- npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.5
20
+ npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.6
21
21
  ```
22
22
 
23
23
  Требуются React и React DOM 19, Node.js `^24.15.0 || >=26.0.0` для установки/сборки,
package/dist/az-editor.js CHANGED
@@ -360,7 +360,7 @@ function P(e) {
360
360
  function F(e) {
361
361
  return /courier|mono|consolas/i.test(e) ? "freemono" : /arial|helvetica|calibri|sans|verdana|tahoma|segoe|roboto/i.test(e) ? "freesans" : "freeserif";
362
362
  }
363
- var I = new Set("div p span br hr b strong i em u s sub sup h1 h2 h3 h4 h5 h6 ul ol li table thead tbody tfoot tr td th".split(" ")), L = new Set("script style iframe object embed svg math img picture video audio canvas link meta form input textarea select button template noscript base frame frameset".split(" ")), ee = new Set("div p h1 h2 h3 h4 h5 h6 ul ol li table thead tbody tfoot tr td th br hr".split(" ")), te = new Set(("color font-family font-size font-weight font-style text-decoration text-align text-transform text-indent letter-spacing line-height white-space vertical-align background background-color width height margin padding border border-color border-width border-style border-collapse table-layout page-break-before page-break-after page-break-inside " + [
363
+ var I = new Set("div p span br hr b strong i em u s sub sup h1 h2 h3 h4 h5 h6 ul ol li table thead tbody tfoot tr td th".split(" ")), L = new Set("script style iframe object embed svg math img picture video audio canvas link meta form input textarea select button template noscript base frame frameset".split(" ")), ee = new Set("div p h1 h2 h3 h4 h5 h6 ul ol li table thead tbody tfoot tr td th br hr".split(" ")), te = new Set(("color font-family font-size font-weight font-style text-decoration text-align text-transform text-indent letter-spacing line-height white-space vertical-align background background-color width height margin padding border border-color border-width border-style border-collapse table-layout page-break-before page-break-after page-break-inside break-before break-after break-inside " + [
364
364
  "top",
365
365
  "right",
366
366
  "bottom",
@@ -391,6 +391,18 @@ function ne(e, t) {
391
391
  let e = F(a);
392
392
  a.replace(/['"]/g, "").toLowerCase() !== e && M(t, "font-substitution", `Шрифт ${a} заменён на ${e}.`), a = e;
393
393
  }
394
+ if (/^(page-)?break-(before|after|inside)$/.test(i)) {
395
+ let e = i.startsWith("break-");
396
+ if (a = a.toLowerCase(), e && a === "page" && i !== "break-inside" && (a = "always"), e && a === "avoid-page" && (a = "avoid"), ![
397
+ "auto",
398
+ "avoid",
399
+ ...i.endsWith("inside") ? [] : ["always"]
400
+ ].includes(a)) {
401
+ M(t, "page-break-value-unsupported", `Значение ${a} для ${i} не поддерживается HTML-адаптером.`);
402
+ continue;
403
+ }
404
+ e && (i = `page-${i}`);
405
+ }
394
406
  n.set(i, a);
395
407
  }
396
408
  }
@@ -480,11 +492,11 @@ function ae(e) {
480
492
  warnings: r
481
493
  };
482
494
  }
483
- function oe(e) {
495
+ function R(e) {
484
496
  if (!O.includes(e)) throw new A(`Неподдерживаемая локаль: ${e}.`);
485
497
  }
486
- function se(e, t) {
487
- oe(t);
498
+ function oe(e, t) {
499
+ R(t);
488
500
  let n = e[t];
489
501
  if (!n || !Array.isArray(n.blocks) || !n.blocks.length) throw new A(`Нет HTML-шаблона для локали ${t}.`);
490
502
  return n.blocks.map((e) => {
@@ -492,9 +504,9 @@ function se(e, t) {
492
504
  return e.props.html;
493
505
  }).join("");
494
506
  }
495
- function ce(e, t, n) {
496
- oe(t);
497
- for (let t of Object.keys(e)) oe(t);
507
+ function se(e, t, n) {
508
+ R(t);
509
+ for (let t of Object.keys(e)) R(t);
498
510
  let r = ae(n), i = structuredClone(e);
499
511
  return {
500
512
  ...r,
@@ -513,22 +525,22 @@ function ce(e, t, n) {
513
525
  }
514
526
  //#endregion
515
527
  //#region src/library/hujjat/xml.ts
516
- var R = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", z = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), B = (e, t) => Array.from(e?.children ?? []).filter((e) => e.namespaceURI === "http://schemas.openxmlformats.org/wordprocessingml/2006/main" && (!t || e.localName === t)), V = (e, t) => B(e, t)[0] ?? null, H = (e, t = "val") => e?.getAttributeNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", t) ?? "", U = (e, t) => H(V(e, t)), W = (e) => e !== null && ![
528
+ var z = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", ce = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), B = (e, t) => Array.from(e?.children ?? []).filter((e) => e.namespaceURI === "http://schemas.openxmlformats.org/wordprocessingml/2006/main" && (!t || e.localName === t)), V = (e, t) => B(e, t)[0] ?? null, H = (e, t = "val") => e?.getAttributeNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", t) ?? "", U = (e, t) => H(V(e, t)), W = (e) => e !== null && ![
517
529
  "0",
518
530
  "false",
519
531
  "off",
520
532
  "none"
521
- ].includes(H(e)), G = (e) => `${Number(e) / 20}pt`, le = (e) => Object.keys(e).length ? ` style="${z(Object.entries(e).map(([e, t]) => `${e}:${t}`).join(";"))}"` : "";
522
- function ue(e) {
533
+ ].includes(H(e)), G = (e) => `${Number(e) / 20}pt`, K = (e) => Object.keys(e).length ? ` style="${ce(Object.entries(e).map(([e, t]) => `${e}:${t}`).join(";"))}"` : "";
534
+ function le(e) {
523
535
  if (/<!DOCTYPE|<!ENTITY/i.test(e)) throw new A("XML с DTD/ENTITY не поддерживается.");
524
536
  let t = new DOMParser().parseFromString(e, "application/xml");
525
537
  if (t.querySelector("parsererror")) throw new A("Повреждённый XML в DOCX.");
526
538
  if (t.getElementsByTagName("*").length > 5e4) throw new A("Слишком сложный XML в DOCX.");
527
539
  return t;
528
540
  }
529
- async function K(e, t) {
541
+ async function q(e, t) {
530
542
  let n = e.file(t);
531
- return n ? ue(await new Promise((e, t) => {
543
+ return n ? le(await new Promise((e, t) => {
532
544
  let r = n.internalStream("uint8array"), i = 0, a = [];
533
545
  r.on("data", (e) => {
534
546
  i += e.length, i > 8388608 ? (r.pause(), t(new A("XML-часть DOCX превышает 8 МиБ."))) : a.push(e);
@@ -539,7 +551,7 @@ async function K(e, t) {
539
551
  }), r.resume();
540
552
  })) : null;
541
553
  }
542
- function q(e) {
554
+ function J(e) {
543
555
  let t = {};
544
556
  V(e, "vanish") && (t["--az-hidden"] = W(V(e, "vanish")) ? "1" : "0");
545
557
  let n = V(e, "rFonts"), r = H(n, "ascii") || H(n, "hAnsi") || H(n, "cs");
@@ -562,7 +574,7 @@ function q(e) {
562
574
  let o = H(V(e, "shd"), "fill");
563
575
  return /^[\da-f]{6}$/i.test(o) ? t["background-color"] = `#${o}` : U(e, "highlight") && U(e, "highlight") !== "none" && (t["background-color"] = U(e, "highlight")), ["superscript", "subscript"].includes(U(e, "vertAlign")) && (t["vertical-align"] = U(e, "vertAlign") === "superscript" ? "super" : "sub"), W(V(e, "caps")) && (t["text-transform"] = "uppercase"), U(e, "spacing") && (t["letter-spacing"] = G(U(e, "spacing"))), U(e, "position") && (t["--az-position"] = U(e, "position")), t;
564
576
  }
565
- function de(e) {
577
+ function ue(e) {
566
578
  let t = {}, n = U(e, "jc");
567
579
  n && (t["text-align"] = {
568
580
  both: "justify",
@@ -602,7 +614,7 @@ function de(e) {
602
614
  }
603
615
  return t;
604
616
  }
605
- function fe(e) {
617
+ function de(e) {
606
618
  if (!e) return;
607
619
  if (["nil", "none"].includes(H(e))) return "none";
608
620
  let t = {
@@ -614,7 +626,7 @@ function fe(e) {
614
626
  }
615
627
  //#endregion
616
628
  //#region src/library/hujjat/page-layout.ts
617
- function pe(e) {
629
+ function fe(e) {
618
630
  let t = E().page, n = V(e, "pgSz"), r = V(e, "pgMar"), i = (e, t, n) => H(e, t) === "" ? n : Number(H(e, t)), a = i(n, "w", t.widthTwips), o = i(n, "h", t.heightTwips);
619
631
  return E({ page: {
620
632
  widthTwips: a,
@@ -623,10 +635,10 @@ function pe(e) {
623
635
  margins: Object.fromEntries(Object.entries(t.margins).map(([e, t]) => [e, i(r, e, t)]))
624
636
  } }).page;
625
637
  }
626
- function me(e, t, n, r) {
627
- let i = E(t), a = Array.from(e.getElementsByTagNameNS(R, "sectPr")), o;
638
+ function pe(e, t, n, r) {
639
+ let i = E(t), a = Array.from(e.getElementsByTagNameNS(z, "sectPr")), o;
628
640
  try {
629
- o = a.map(pe);
641
+ o = a.map(fe);
630
642
  } catch (e) {
631
643
  M(n, "unsupported-page-layout", e instanceof Error ? e.message : "Неподдерживаемые параметры страницы.", "loss", {
632
644
  stage: "export",
@@ -659,7 +671,7 @@ function me(e, t, n, r) {
659
671
  }
660
672
  //#endregion
661
673
  //#region src/library/hujjat/paragraph-format.ts
662
- function he(e) {
674
+ function me(e) {
663
675
  let t, n = "auto";
664
676
  for (let r of e) {
665
677
  let e = V(r, "spacing");
@@ -672,16 +684,16 @@ function he(e) {
672
684
  rule: n
673
685
  } : void 0;
674
686
  }
675
- function ge(e) {
687
+ function he(e) {
676
688
  return e.rule === "auto" ? String(e.value / 240) : `${e.value / 20}pt`;
677
689
  }
678
- function _e(e) {
690
+ function ge(e) {
679
691
  return (parseFloat(e["font-size"]) || 12) + Math.abs(Number(e["--az-position"]) || 0) / 2;
680
692
  }
681
693
  //#endregion
682
694
  //#region src/library/hujjat/docx-chrome.ts
683
- async function ve(e, t, n, r, i) {
684
- let a = Object.keys(e.files).filter((e) => /^word\/(header|footer)[^/]*\.xml$/.test(e)), o = Array.from(t.getElementsByTagNameNS(R, "sectPr")).flatMap((e) => B(e).filter((e) => ["headerReference", "footerReference"].includes(e.localName)));
695
+ async function _e(e, t, n, r, i) {
696
+ let a = Object.keys(e.files).filter((e) => /^word\/(header|footer)[^/]*\.xml$/.test(e)), o = Array.from(t.getElementsByTagNameNS(z, "sectPr")).flatMap((e) => B(e).filter((e) => ["headerReference", "footerReference"].includes(e.localName)));
685
697
  if (n === void 0) {
686
698
  (a.length || o.length) && M(r, "header-footer-removed", "Для сохранения колонтитулов передайте page (или locales с page) в exportHujjat.", "loss", { stage: "export" });
687
699
  return;
@@ -689,7 +701,7 @@ async function ve(e, t, n, r, i) {
689
701
  let s = n === null ? null : structuredClone(n);
690
702
  if (!a.length && !o.length && !s?.header && !s?.footer) return s;
691
703
  s ??= {};
692
- let c = await K(e, "word/_rels/document.xml.rels"), l = W(V((await K(e, "word/settings.xml"))?.documentElement, "evenAndOddHeaders")), u = Array.from(c?.documentElement.children ?? []), d = /* @__PURE__ */ new Set();
704
+ let c = await q(e, "word/_rels/document.xml.rels"), l = W(V((await q(e, "word/settings.xml"))?.documentElement, "evenAndOddHeaders")), u = Array.from(c?.documentElement.children ?? []), d = /* @__PURE__ */ new Set();
693
705
  for (let n of ["header", "footer"]) {
694
706
  let a = o.filter((e) => e.localName === `${n}Reference`);
695
707
  if (l || a.some((e) => H(e, "type") !== "default") || a.length > 1 || Array.from(t.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "sectPr")).some((e) => W(V(e, "titlePg")))) {
@@ -713,7 +725,7 @@ async function ve(e, t, n, r, i) {
713
725
  continue;
714
726
  }
715
727
  d.add(h);
716
- let g = (await K(e, h))?.documentElement;
728
+ let g = (await q(e, h))?.documentElement;
717
729
  !g || g.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main" || g.localName !== (n === "header" ? "hdr" : "ftr") ? (s[n] = null, M(r, "header-footer-reference-unsupported", "Структура колонтитула повреждена.", "loss", {
718
730
  stage: "export",
719
731
  location: { part: h }
@@ -723,8 +735,8 @@ async function ve(e, t, n, r, i) {
723
735
  }
724
736
  //#endregion
725
737
  //#region src/library/hujjat/server-page.ts
726
- var ye = 102400;
727
- function J(e) {
738
+ var ve = 102400;
739
+ function ye(e) {
728
740
  if (e == null) return;
729
741
  let t = (e) => {
730
742
  throw new A(`Некорректное поле page.${e} в контракте Hujjat.`);
@@ -762,7 +774,7 @@ function J(e) {
762
774
  }
763
775
  }
764
776
  function be(e, t) {
765
- if (J(e), !e) return e;
777
+ if (ye(e), !e) return e;
766
778
  let n = structuredClone(e);
767
779
  for (let e of ["header", "footer"]) {
768
780
  let r = n[e];
@@ -776,7 +788,7 @@ function be(e, t) {
776
788
  }
777
789
  })));
778
790
  }
779
- return J(n), n;
791
+ return ye(n), n;
780
792
  }
781
793
  function xe(e, t = {}) {
782
794
  let n = E();
@@ -798,42 +810,42 @@ async function Se(e, t = {}, n) {
798
810
  let i = Object.keys(r.files);
799
811
  if (i.length > 2e3) throw new A("В DOCX более 2000 частей.");
800
812
  if (i.some((e) => /vbaProject\.bin$/i.test(e))) throw new A("DOCX с макросами не поддерживается.");
801
- let a = await K(r, "[Content_Types].xml");
813
+ let a = await q(r, "[Content_Types].xml");
802
814
  if (!Array.from(a?.getElementsByTagNameNS("*", "Override") ?? []).some((e) => e.getAttribute("PartName") === "/word/document.xml" && e.getAttribute("ContentType") === "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")) throw new A("Файл не является обычным DOCX.");
803
- let o = await K(r, "word/document.xml"), s = await K(r, "word/styles.xml"), c = await K(r, "word/numbering.xml"), l = V(o?.documentElement, "body");
815
+ let o = await q(r, "word/document.xml"), s = await q(r, "word/styles.xml"), c = await q(r, "word/numbering.xml"), l = V(o?.documentElement, "body");
804
816
  if (!l) throw new A("В DOCX нет поддерживаемой структуры документа.");
805
- let u = [], d = me(l, t, u, n === void 0 ? void 0 : xe(n).page), f, m = (e, t, n = "warning", r, i) => M(u, e, t, n, {
817
+ let u = [], d = pe(l, t, u, n === void 0 ? void 0 : xe(n).page), f, m = (e, t, n = "warning", r, i) => M(u, e, t, n, {
806
818
  stage: "export",
807
819
  location: f ? { ...f } : void 0,
808
820
  before: r,
809
821
  after: i
810
- }), h = (e, t) => m(e, t, "loss"), g = new Map(Array.from(l.getElementsByTagNameNS(R, "p")).map((e, t) => [e, t])), _ = "word/document.xml", v = 0;
822
+ }), h = (e, t) => m(e, t, "loss"), g = new Map(Array.from(l.getElementsByTagNameNS(z, "p")).map((e, t) => [e, t])), _ = new Map(Array.from(l.getElementsByTagNameNS(z, "tbl")).map((e, t) => [e, t])), v = "word/document.xml", y = 0;
811
823
  i.some((e) => /^word\/comments/.test(e)) && h("review-removed", "Комментарии Word не сохраняются в HTML.");
812
- let y = V(s?.documentElement, "docDefaults"), b = {
824
+ let b = V(s?.documentElement, "docDefaults"), x = {
813
825
  "margin-top": "0pt",
814
826
  "margin-bottom": "8px",
815
- ...de(V(V(y, "pPrDefault"), "pPr"))
816
- }, x = {
827
+ ...ue(V(V(b, "pPrDefault"), "pPr"))
828
+ }, S = {
817
829
  "font-family": "freeserif",
818
830
  "font-size": "12pt",
819
831
  color: "#111111",
820
- ...q(V(V(y, "rPrDefault"), "rPr"))
821
- }, S = new Map(B(s?.documentElement, "style").map((e) => [H(e, "styleId"), e]));
822
- function C(e, t = /* @__PURE__ */ new Set()) {
832
+ ...J(V(V(b, "rPrDefault"), "rPr"))
833
+ }, C = new Map(B(s?.documentElement, "style").map((e) => [H(e, "styleId"), e]));
834
+ function w(e, t = /* @__PURE__ */ new Set()) {
823
835
  if (!e || t.has(e) || t.size > 30) return [];
824
836
  t.add(e);
825
- let n = S.get(e);
826
- return n ? [...C(U(n, "basedOn"), t), n] : [];
837
+ let n = C.get(e);
838
+ return n ? [...w(U(n, "basedOn"), t), n] : [];
827
839
  }
828
- let w = B(s?.documentElement, "style").find((e) => H(e, "type") === "paragraph" && H(e, "default") === "1"), T = new Map(B(c?.documentElement, "num").map((e) => [H(e, "numId"), e])), E = new Map(B(c?.documentElement, "abstractNum").map((e) => [H(e, "abstractNumId"), e])), D = /* @__PURE__ */ new Set(), O = !1, k = 0, j = (e) => {
829
- if (++k > 5e4 || e > 80) throw new A("DOCX слишком сложный для HTML-адаптера.");
840
+ let T = B(s?.documentElement, "style").find((e) => H(e, "type") === "paragraph" && H(e, "default") === "1"), E = new Map(B(c?.documentElement, "num").map((e) => [H(e, "numId"), e])), D = new Map(B(c?.documentElement, "abstractNum").map((e) => [H(e, "abstractNumId"), e])), O = /* @__PURE__ */ new Set(), k = !1, j = 0, N = (e) => {
841
+ if (++j > 5e4 || e > 80) throw new A("DOCX слишком сложный для HTML-адаптера.");
830
842
  };
831
- function N(e, t, n) {
832
- if (j(n), e.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main") return h("unsupported-content", "Нестандартный объект Word не сохраняется в HTML."), "";
843
+ function P(e, t, n) {
844
+ if (N(n), e.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main") return h("unsupported-content", "Нестандартный объект Word не сохраняется в HTML."), "";
833
845
  switch (e.localName) {
834
- case "t": return z(Array.from(e.textContent ?? "").map((e) => {
835
- let t = e === " " && O ? "\xA0" : e;
836
- return O = e === " ", t;
846
+ case "t": return ce(Array.from(e.textContent ?? "").map((e) => {
847
+ let t = e === " " && k ? "\xA0" : e;
848
+ return k = e === " ", t;
837
849
  }).join(""));
838
850
  case "tab": return h("tab-normalized", "Положение текста после табуляции потеряно в HTML. Для точного расположения используйте исходный DOCX."), " ";
839
851
  case "br": return H(e, "type") === "page" ? "<div style=\"page-break-before:always\"></div>" : "<br>";
@@ -843,13 +855,13 @@ async function Se(e, t = {}, n) {
843
855
  case "r": {
844
856
  f = {
845
857
  ...f,
846
- runIndex: v++
858
+ runIndex: y++
847
859
  };
848
- let r = V(e, "rPr"), i = Object.assign({}, t, ...C(U(r, "rStyle")).map((e) => q(V(e, "rPr"))), q(r));
860
+ let r = V(e, "rPr"), i = Object.assign({}, t, ...w(U(r, "rStyle")).map((e) => J(V(e, "rPr"))), J(r));
849
861
  if (i["--az-hidden"] === "1") return h("hidden-text-removed", "Скрытый текст Word исключён из HTML."), "";
850
862
  Number(i["--az-position"]) && m("baseline-shift-lost", "Вертикальное смещение фрагмента Word не представлено в HTML.", "loss", Number(i["--az-position"]) / 2, 0);
851
863
  let a = Object.fromEntries(Object.entries(i).filter(([e]) => !e.startsWith("--az-")));
852
- return B(e).filter((e) => e.localName !== "rPr").map((e) => N(e, i, n + 1)).join("").split(/(<div style="page-break-before:always"><\/div>)/).map((e) => e.startsWith("<div ") ? e : e ? `<span${le(a)}>${e}</span>` : "").join("");
864
+ return B(e).filter((e) => e.localName !== "rPr").map((e) => P(e, i, n + 1)).join("").split(/(<div style="page-break-before:always"><\/div>)/).map((e) => e.startsWith("<div ") ? e : e ? `<span${K(a)}>${e}</span>` : "").join("");
853
865
  }
854
866
  case "hyperlink":
855
867
  M(u, "hyperlink-removed", "Ссылки сохраняются как текст без перехода.");
@@ -870,7 +882,7 @@ async function Se(e, t = {}, n) {
870
882
  case "fldSimple":
871
883
  h("field-flattened", "Поля Word сохраняют только имеющийся текстовый результат.");
872
884
  break;
873
- case "sdt": return h("content-control-flattened", "Элементы управления Word преобразуются в обычный текст."), V(e, "sdtContent") ? N(V(e, "sdtContent"), t, n + 1) : "";
885
+ case "sdt": return h("content-control-flattened", "Элементы управления Word преобразуются в обычный текст."), V(e, "sdtContent") ? P(V(e, "sdtContent"), t, n + 1) : "";
874
886
  case "sdtContent":
875
887
  case "smartTag":
876
888
  case "customXml": break;
@@ -883,122 +895,146 @@ async function Se(e, t = {}, n) {
883
895
  case "commentReference": return "";
884
896
  default: h("unsupported-inline", `Элемент Word ${e.localName} не поддерживается HTML-адаптером.`);
885
897
  }
886
- return Array.from(e.children).map((e) => N(e, t, n + 1)).join("");
898
+ return Array.from(e.children).map((e) => P(e, t, n + 1)).join("");
887
899
  }
888
- function P(e, n) {
900
+ function F(e, n) {
889
901
  f = {
890
- part: _,
902
+ part: v,
891
903
  paragraphIndex: g.get(e)
892
- }, v = 0;
893
- let r = V(e, "pPr"), i = C(U(r, "pStyle") || H(w, "styleId")), a = [...i.map((e) => V(e, "pPr")), r], o = Object.assign({}, b, ...a.map(de)), s = a.map((e) => V(e, "numPr")).filter(Boolean).at(-1), c = U(s, "numId"), l = Number(U(s, "ilvl") || 0), d = U(r, "pStyle") === "AzHujjatListContinuation";
894
- if (c && c !== "0" || d) {
895
- let e = T.get(c), t = de(V(B(E.get(U(e, "abstractNumId")), "lvl").find((e) => H(e, "ilvl") === String(l)), "pPr"));
896
- o["margin-left"] = G((parseFloat(o["margin-left"] ?? t["margin-left"] ?? "0") || 0) * 20 - 360), o["text-indent"] ??= t["text-indent"] ?? "0pt";
904
+ }, y = 0;
905
+ let r = V(e, "pPr"), i = w(U(r, "pStyle") || H(T, "styleId")), a = V(r, "spacing");
906
+ if (U(r, "pStyle") === "AzHujjatPageBoundary" && W(V(r, "pageBreakBefore")) && Array.from(r?.children ?? []).every((e) => e.namespaceURI === "http://schemas.openxmlformats.org/wordprocessingml/2006/main" && [
907
+ "pStyle",
908
+ "pageBreakBefore",
909
+ "spacing"
910
+ ].includes(e.localName)) && H(a, "before") === "0" && H(a, "after") === "0" && H(a, "line") === "1" && H(a, "lineRule") === "exact" && Array.from(e.children).every((e) => e === r)) return { html: "<div style=\"page-break-before:always\"></div>" };
911
+ let o = [...i.map((e) => V(e, "pPr")), r], s = Object.assign({}, x, ...o.map(ue)), c = o.map((e) => V(e, "numPr")).filter(Boolean).at(-1), l = U(c, "numId"), d = Number(U(c, "ilvl") || 0), p = U(r, "pStyle") === "AzHujjatListContinuation";
912
+ if (l && l !== "0" || p) {
913
+ let e = E.get(l), t = ue(V(B(D.get(U(e, "abstractNumId")), "lvl").find((e) => H(e, "ilvl") === String(d)), "pPr"));
914
+ s["margin-left"] = G((parseFloat(s["margin-left"] ?? t["margin-left"] ?? "0") || 0) * 20 - 360), s["text-indent"] ??= t["text-indent"] ?? "0pt";
897
915
  }
898
- parseFloat(o["text-indent"] ?? "0") < 0 && parseFloat(o["margin-left"] ?? "0") >= 0 && (o["padding-left"] = o["margin-left"] ?? "0pt", o["margin-left"] = "0pt");
899
- let p = he([V(V(y, "pPrDefault"), "pPr"), ...a]);
900
- p && (o["line-height"] = ge(p));
901
- let S = Object.assign({}, x, ...i.map((e) => q(V(e, "rPr")))), D = Array.from(e.getElementsByTagNameNS(R, "r")).map((e) => {
902
- let t = V(e, "rPr"), n = Object.assign({}, S, ...C(U(t, "rStyle")).map((e) => q(V(e, "rPr"))), q(t));
903
- return n["--az-hidden"] === "1" ? 0 : _e(n);
904
- }), k = o["line-height"];
905
- k && (/^\d*\.?\d+$/.test(k) ? Number(k) < 1 : k.endsWith("pt") && parseFloat(k) < Math.max(_e(S), ...D)) && (t.lineSpacingPolicy === "preserve" ? m("line-height-overlap-risk", "Авторский тесный интервал сохранён; строки могут перекрываться. Фактические метрики шрифта требуют проверки.", "warning", k, k) : (o["line-height"] = /^\d*\.?\d+$/.test(k) ? "1" : "normal", m("line-height-normalized", "Тесный межстрочный интервал нормализован по размерам фрагментов. Проверьте переносы на используемых шрифтах.", "warning", k, o["line-height"]))), p && p.rule !== "auto" && m("line-rule-lost", "CSS line-height не сохраняет различие правил Word exact и atLeast.", "warning", p.rule, "CSS line-height"), a.some((e) => V(e, "tabs")) && h("tab-stops-removed", "Позиции, типы и заполнители табуляции не поддерживаются HTML-блоком.");
906
- let A = [V(V(y, "pPrDefault"), "pPr"), ...a].map((e) => V(e, "widowControl")).filter(Boolean).at(-1);
907
- A && M(u, "widow-control-lost", "Правило висячих строк Word не представлено в HTML-контракте.", "loss", {
916
+ parseFloat(s["text-indent"] ?? "0") < 0 && parseFloat(s["margin-left"] ?? "0") >= 0 && (s["padding-left"] = s["margin-left"] ?? "0pt", s["margin-left"] = "0pt");
917
+ let _ = me([V(V(b, "pPrDefault"), "pPr"), ...o]);
918
+ _ && (s["line-height"] = he(_));
919
+ let C = Object.assign({}, S, ...i.map((e) => J(V(e, "rPr")))), O = Array.from(e.getElementsByTagNameNS(z, "r")).map((e) => {
920
+ let t = V(e, "rPr"), n = Object.assign({}, C, ...w(U(t, "rStyle")).map((e) => J(V(e, "rPr"))), J(t));
921
+ return n["--az-hidden"] === "1" ? 0 : ge(n);
922
+ }), A = s["line-height"];
923
+ A && (/^\d*\.?\d+$/.test(A) ? Number(A) < 1 : A.endsWith("pt") && parseFloat(A) < Math.max(ge(C), ...O)) && (t.lineSpacingPolicy === "preserve" ? m("line-height-overlap-risk", "Авторский тесный интервал сохранён; строки могут перекрываться. Фактические метрики шрифта требуют проверки.", "warning", A, A) : (s["line-height"] = /^\d*\.?\d+$/.test(A) ? "1" : "normal", m("line-height-normalized", "Тесный межстрочный интервал нормализован по размерам фрагментов. Проверьте переносы на используемых шрифтах.", "warning", A, s["line-height"]))), _ && _.rule !== "auto" && m("line-rule-lost", "CSS line-height не сохраняет различие правил Word exact и atLeast.", "warning", _.rule, "CSS line-height"), o.some((e) => V(e, "tabs")) && h("tab-stops-removed", "Позиции, типы и заполнители табуляции не поддерживаются HTML-блоком.");
924
+ let j = [V(V(b, "pPrDefault"), "pPr"), ...o].map((e) => V(e, "widowControl")).filter(Boolean).at(-1);
925
+ j && M(u, "widow-control-lost", "Правило висячих строк Word не представлено в HTML-контракте.", "loss", {
908
926
  stage: "export",
909
927
  location: { ...f },
910
- before: W(A),
928
+ before: W(j),
911
929
  after: null
912
- }), O = !0;
913
- let j = Array.from(e.children).filter((e) => e !== r).map((e) => N(e, S, n + 1)).join("").split("<div style=\"page-break-before:always\"></div>").map((e, t) => `${t ? "<div style=\"page-break-before:always\"></div>" : ""}<p${le(o)}>${e || "<br>"}</p>`).join("");
914
- if (c && c !== "0") {
915
- let e = T.get(c), t = B(E.get(U(e, "abstractNumId")), "lvl").find((e) => H(e, "ilvl") === String(l));
916
- if (!t) return M(u, "numbering-unsupported", "Не найдена нумерация списка.", "loss"), { html: j };
930
+ }), k = !0;
931
+ let N = Array.from(e.children).filter((e) => e !== r).map((e) => P(e, C, n + 1)).join("").split("<div style=\"page-break-before:always\"></div>").map((e, t) => `${t ? "<div style=\"page-break-before:always\"></div>" : ""}<p${K(s)}>${e || "<br>"}</p>`).join("");
932
+ if (l && l !== "0") {
933
+ let e = E.get(l), t = B(D.get(U(e, "abstractNumId")), "lvl").find((e) => H(e, "ilvl") === String(d));
934
+ if (!t) return M(u, "numbering-unsupported", "Не найдена нумерация списка.", "loss"), { html: N };
917
935
  let n = U(t, "numFmt");
918
- return (!["decimal", "bullet"].includes(n) || l || U(t, "start") && U(t, "start") !== "1" || V(e, "lvlOverride")) && M(u, "numbering-normalized", "Сложная нумерация/начальное число списка заменены обычным HTML-списком.", "loss"), {
919
- html: j,
936
+ return (!["decimal", "bullet"].includes(n) || d || U(t, "start") && U(t, "start") !== "1" || V(e, "lvlOverride")) && M(u, "numbering-normalized", "Сложная нумерация/начальное число списка заменены обычным HTML-списком.", "loss"), {
937
+ html: N,
920
938
  list: {
921
- id: c,
922
- level: Math.min(l, 8),
939
+ id: l,
940
+ level: Math.min(d, 8),
923
941
  tag: n === "bullet" ? "ul" : "ol"
924
942
  }
925
943
  };
926
944
  }
927
945
  return {
928
- html: j,
946
+ html: N,
929
947
  continuation: U(r, "pStyle") === "AzHujjatListContinuation"
930
948
  };
931
949
  }
932
- function F(e, t) {
933
- j(t);
934
- let n = V(e, "tblPr");
935
- U(n, "tblStyle") && M(u, "table-style-normalized", "Условные стили таблиц Word могут отличаться; проверьте границы и заливку.");
936
- let r = V(n, "tblBorders"), i = B(V(e, "tblGrid"), "gridCol").map((e) => Number(H(e, "w"))), a = H(V(n, "tblLayout"), "type") === "fixed", o = B(e, "tr"), s = /* @__PURE__ */ new Map(), c = Math.max(1, ...o.map((e) => B(e, "tc").reduce((e, t) => e + Number(U(V(t, "tcPr"), "gridSpan") || 1), 0))), l = [];
937
- o.forEach((e, u) => {
938
- let d = 0, f = [];
950
+ function I(e, t) {
951
+ N(t);
952
+ let n = V(e, "tblPr"), r = U(n, "tblStyle"), i = {
953
+ part: v,
954
+ tableIndex: _.get(e)
955
+ };
956
+ f = i, V(n, "tblpPr") && h("floating-table-position-lost", "Плавающее размещение таблицы Word не поддерживается текущим HTML-контрактом; таблица остаётся в потоке документа."), r && M(u, "table-style-normalized", "Условные стили таблиц Word могут отличаться; проверьте границы и заливку.");
957
+ let a = V(n, "tblBorders"), o = B(V(e, "tblGrid"), "gridCol").map((e) => Number(H(e, "w"))), s = H(V(n, "tblLayout"), "type") === "fixed", c = B(e, "tr"), l = /* @__PURE__ */ new Map(), d = Math.max(1, ...c.map((e) => B(e, "tc").reduce((e, t) => e + Number(U(V(t, "tcPr"), "gridSpan") || 1), 0))), p = [], m = [], g = 0;
958
+ c.forEach((e, r) => {
959
+ let f = V(e, "trPr"), _ = {}, v = {
960
+ ...i,
961
+ rowIndex: r
962
+ }, y = V(f, "trHeight");
963
+ y && H(y, "val") && H(y, "hRule") !== "auto" && (_.height = G(H(y, "val")), H(y, "hRule") === "exact" && M(u, "table-row-height-rule-lost", "Высота строки HTML задаёт минимум; правило Word exact станет atLeast.", "warning", {
964
+ stage: "export",
965
+ location: v,
966
+ before: "exact",
967
+ after: "atLeast"
968
+ })), V(f, "cantSplit") && (_["page-break-inside"] = W(V(f, "cantSplit")) ? "avoid" : "auto"), W(V(f, "tblHeader")) && (r === g ? g++ : M(u, "table-header-not-contiguous", "Повторяемая шапка вне начала таблицы не переносится в HTML.", "warning", {
969
+ stage: "export",
970
+ location: v
971
+ })), m.push(_);
972
+ let b = 0, x = [];
939
973
  Number(U(V(e, "trPr"), "gridBefore") || 0) && h("table-grid-unsupported", "Таблица с пропущенными начальными ячейками требует проверки.");
940
- for (let l of B(e, "tc")) {
941
- let e = V(l, "tcPr"), p = Number(U(e, "gridSpan") || 1), m = V(e, "vMerge");
942
- if (V(e, "hMerge") && h("legacy-table-merge", "Старый формат горизонтального объединения hMerge требует преобразования в gridSpan."), !Number.isInteger(p) || p < 1 || p > 100) throw new A("Объединение таблицы превышает предел 100 ячеек.");
943
- if (m && H(m) !== "restart" && s.has(d) && s.get(d).span === p) {
944
- let e = s.get(d);
974
+ for (let i of B(e, "tc")) {
975
+ let e = V(i, "tcPr"), u = Number(U(e, "gridSpan") || 1), f = V(e, "vMerge");
976
+ if (V(e, "hMerge") && h("legacy-table-merge", "Старый формат горизонтального объединения hMerge требует преобразования в gridSpan."), !Number.isInteger(u) || u < 1 || u > 100) throw new A("Объединение таблицы превышает предел 100 ячеек.");
977
+ if (f && H(f) !== "restart" && l.has(b) && l.get(b).span === u) {
978
+ let e = l.get(b);
945
979
  if (e.rowSpan++, e.rowSpan > 100) throw new A("Объединение таблицы превышает 100 строк.");
946
- l.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "t").length && l.textContent?.trim() && h("table-merge-content", "Текст в продолжении объединённой ячейки требует ручной проверки."), d += p;
980
+ i.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "t").length && i.textContent?.trim() && h("table-merge-content", "Текст в продолжении объединённой ячейки требует ручной проверки."), b += u;
947
981
  continue;
948
982
  }
949
- let g = {}, _ = V(e, "tcW");
950
- H(_, "type") === "dxa" ? g.width = G(H(_, "w")) : H(_, "type") === "pct" && (g.width = `${Number(H(_, "w")) / 50}%`);
951
- let v = i.slice(d, d + p);
952
- (a || !g.width) && v.length === p && v.every((e) => Number.isFinite(e) && e > 0) && (g.width = G(v.reduce((e, t) => e + t, 0)));
953
- let y = H(V(e, "shd"), "fill");
954
- /^[\da-f]{6}$/i.test(y) && (g["background-color"] = "#" + y), U(e, "vAlign") && (g["vertical-align"] = U(e, "vAlign") === "center" ? "middle" : U(e, "vAlign"));
983
+ let p = {}, m = V(e, "tcW");
984
+ H(m, "type") === "dxa" ? p.width = G(H(m, "w")) : H(m, "type") === "pct" && (p.width = `${Number(H(m, "w")) / 50}%`);
985
+ let g = o.slice(b, b + u);
986
+ (s || !p.width) && g.length === u && g.every((e) => Number.isFinite(e) && e > 0) && (p.width = G(g.reduce((e, t) => e + t, 0)));
987
+ let _ = H(V(e, "shd"), "fill");
988
+ /^[\da-f]{6}$/i.test(_) && (p["background-color"] = "#" + _), U(e, "vAlign") && (p["vertical-align"] = U(e, "vAlign") === "center" ? "middle" : U(e, "vAlign"));
955
989
  for (let t of [
956
990
  "top",
957
991
  "right",
958
992
  "bottom",
959
993
  "left"
960
994
  ]) {
961
- let i = V(V(e, "tcBorders"), t), a = t === "top" && u > 0 || t === "bottom" && u < o.length - 1 ? "insideH" : t === "left" && d > 0 || t === "right" && d + p < c ? "insideV" : t, s = V(r, a), l = fe(i ?? s);
962
- l && (g[`border-${t}`] = l);
995
+ let i = V(V(e, "tcBorders"), t), o = t === "top" && r > 0 || t === "bottom" && r < c.length - 1 ? "insideH" : t === "left" && b > 0 || t === "right" && b + u < d ? "insideV" : t, s = V(a, o), l = de(i ?? s);
996
+ l && (p[`border-${t}`] = l);
963
997
  let f = V(V(e, "tcMar"), t) ?? V(V(n, "tblCellMar"), t);
964
- f && H(f, "w") && (g[`padding-${t}`] = G(H(f, "w")));
998
+ f && H(f, "w") && (p[`padding-${t}`] = G(H(f, "w")));
965
999
  }
966
- let b = {
967
- element: l,
1000
+ let v = {
1001
+ element: i,
968
1002
  rowSpan: 1,
969
- span: p,
970
- html: I(l, t + 1),
971
- css: g
1003
+ span: u,
1004
+ html: L(i, t + 1),
1005
+ css: p
972
1006
  };
973
- for (let e = d; e < d + p; e++) s.delete(e);
974
- m && H(m) === "restart" && s.set(d, b), f.push(b), d += p;
1007
+ for (let e = b; e < b + u; e++) l.delete(e);
1008
+ f && H(f) === "restart" && l.set(b, v), x.push(v), b += u;
975
1009
  }
976
- for (let e of s.keys()) e >= d && s.delete(e);
977
- l.push(f);
1010
+ for (let e of l.keys()) e >= b && l.delete(e);
1011
+ p.push(x);
978
1012
  });
979
- let d = V(n, "tblW"), f = {
980
- width: H(d, "type") === "dxa" ? G(H(d, "w")) : H(d, "type") === "pct" ? `${Number(H(d, "w")) / 50}%` : "100%",
1013
+ let y = V(n, "tblW"), b = {
1014
+ width: H(y, "type") === "dxa" ? G(H(y, "w")) : H(y, "type") === "pct" ? `${Number(H(y, "w")) / 50}%` : "100%",
981
1015
  "border-collapse": "collapse"
982
- }, p = V(n, "tblInd");
983
- return H(p, "type") === "dxa" && (f["margin-left"] = G(H(p, "w"))), a && (f["table-layout"] = "fixed"), `<table${le(f)}>${l.map((e) => `<tr>${e.map((e) => `<td${e.span > 1 ? ` colspan="${e.span}"` : ""}${e.rowSpan > 1 ? ` rowspan="${e.rowSpan}"` : ""}${le(e.css)}>${e.html || "<p><br></p>"}</td>`).join("")}</tr>`).join("")}</table>`;
1016
+ }, x = V(n, "tblInd");
1017
+ H(x, "type") === "dxa" && (b["margin-left"] = G(H(x, "w"))), b["table-layout"] = s ? "fixed" : "auto";
1018
+ let S = p.map((e, t) => `<tr${K(m[t])}>${e.map((e) => `<td${e.span > 1 ? ` colspan="${e.span}"` : ""}${e.rowSpan > 1 ? ` rowspan="${e.rowSpan}"` : ""}${K(e.css)}>${e.html || "<p><br></p>"}</td>`).join("")}</tr>`);
1019
+ return `<table${K(b)}>${g ? `<thead>${S.slice(0, g).join("")}</thead>` : ""}<tbody>${S.slice(g).join("")}</tbody></table>`;
984
1020
  }
985
- function I(e, t) {
986
- j(t);
1021
+ function L(e, t) {
1022
+ N(t);
987
1023
  let n = "", r, i = () => {
988
1024
  r && (n += `</${r.tag}>`), r = void 0;
989
1025
  };
990
1026
  for (let a of Array.from(e.children)) if (a.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main") i(), h("unsupported-content", "Нестандартный блок Word не сохраняется в HTML.");
991
1027
  else if (a.localName === "p") {
992
- let e = P(a, t + 1);
993
- e.list ? ((r?.id !== e.list.id || r.tag !== e.list.tag) && (i(), r = e.list, r.tag === "ol" && D.has(r.id) && h("numbering-restart", "Продолжение нумерованного списка после другого блока начнётся с 1: Hujjat удаляет атрибут start."), D.add(r.id), n += `<${r.tag}>`), n += `<li>${e.html}</li>`) : e.continuation && r && n.endsWith("</li>") ? n = n.slice(0, -5) + e.html + "</li>" : (i(), n += e.html);
994
- } else a.localName === "tbl" ? (i(), n += F(a, t + 1)) : a.localName === "sectPr" || ([
1028
+ let e = F(a, t + 1);
1029
+ e.list ? ((r?.id !== e.list.id || r.tag !== e.list.tag) && (i(), r = e.list, r.tag === "ol" && O.has(r.id) && h("numbering-restart", "Продолжение нумерованного списка после другого блока начнётся с 1: Hujjat удаляет атрибут start."), O.add(r.id), n += `<${r.tag}>`), n += `<li>${e.html}</li>`) : e.continuation && r && n.endsWith("</li>") ? n = n.slice(0, -5) + e.html + "</li>" : (i(), n += e.html);
1030
+ } else a.localName === "tbl" ? (i(), n += I(a, t + 1)) : a.localName === "sectPr" || ([
995
1031
  "sdt",
996
1032
  "customXml",
997
1033
  "ins",
998
1034
  "del",
999
1035
  "moveFrom",
1000
1036
  "moveTo"
1001
- ].includes(a.localName) ? (i(), h("block-flattened", `Блок Word ${a.localName} преобразован без интерактивности/истории.`), ["del", "moveFrom"].includes(a.localName) || (n += I(V(a, "sdtContent") ?? a, t + 1))) : [
1037
+ ].includes(a.localName) ? (i(), h("block-flattened", `Блок Word ${a.localName} преобразован без интерактивности/истории.`), ["del", "moveFrom"].includes(a.localName) || (n += L(V(a, "sdtContent") ?? a, t + 1))) : [
1002
1038
  "tblPr",
1003
1039
  "tblGrid",
1004
1040
  "tcPr",
@@ -1009,20 +1045,20 @@ async function Se(e, t = {}, n) {
1009
1045
  ].includes(a.localName) || (i(), h("unsupported-block", `Блок Word ${a.localName} не поддерживается HTML-адаптером.`)));
1010
1046
  return i(), n;
1011
1047
  }
1012
- let L = I(l, 0) || "<p><br></p>", ee = await ve(r, l, n, u, (e, t) => (_ = t, D.clear(), g = new Map(Array.from(e.getElementsByTagNameNS(R, "p")).map((e, t) => [e, t])), I(e, 0) || "<p><br></p>"));
1013
- return d && n !== void 0 && d.page.orientation !== (ee?.orientation ?? "portrait") ? {
1014
- html: L,
1048
+ let ee = L(l, 0) || "<p><br></p>", te = await _e(r, l, n, u, (e, t) => (v = t, O.clear(), g = new Map(Array.from(e.getElementsByTagNameNS(z, "p")).map((e, t) => [e, t])), _ = new Map(Array.from(e.getElementsByTagNameNS(z, "tbl")).map((e, t) => [e, t])), L(e, 0) || "<p><br></p>"));
1049
+ return d && n !== void 0 && d.page.orientation !== (te?.orientation ?? "portrait") ? {
1050
+ html: ee,
1015
1051
  warnings: u,
1016
1052
  layout: d,
1017
1053
  page: {
1018
- ...ee,
1054
+ ...te,
1019
1055
  orientation: d.page.orientation
1020
1056
  }
1021
1057
  } : {
1022
- html: L,
1058
+ html: ee,
1023
1059
  warnings: u,
1024
1060
  layout: d,
1025
- page: ee
1061
+ page: te
1026
1062
  };
1027
1063
  }
1028
1064
  //#endregion
@@ -1086,7 +1122,7 @@ function Y(e) {
1086
1122
  let t = e.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
1087
1123
  return t ? t.slice(1).map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("") : Ee[e.toLowerCase()];
1088
1124
  }
1089
- function X(e) {
1125
+ function De(e) {
1090
1126
  if (e === "0") return 0;
1091
1127
  let t = e?.match(/^(-?\d*\.?\d+)(pt|px|in|cm|mm|pc)$/i);
1092
1128
  return t ? Number(t[1]) * {
@@ -1098,13 +1134,21 @@ function X(e) {
1098
1134
  pc: 12
1099
1135
  }[t[2].toLowerCase()] : void 0;
1100
1136
  }
1101
- var Z = (e) => {
1102
- let t = X(e);
1137
+ var X = (e) => {
1138
+ let t = De(e);
1103
1139
  return t === void 0 ? void 0 : Math.round(t * 20);
1104
- }, Q = (e, t) => (Z(e[`margin-${t}`]) ?? 0) + Math.max(0, Z(e[`padding-${t}`]) ?? 0);
1105
- function De(e, t) {
1140
+ }, Z = (e, t) => (X(e[`margin-${t}`]) ?? 0) + Math.max(0, X(e[`padding-${t}`]) ?? 0);
1141
+ function Q(e, t) {
1106
1142
  let n = { ...t }, r = e.style;
1107
1143
  for (let e of Array.from(r)) n[e] = r.getPropertyValue(e).trim();
1144
+ for (let e of [
1145
+ "before",
1146
+ "after",
1147
+ "inside"
1148
+ ]) {
1149
+ let t = `page-break-${e}`, i = r.getPropertyValue(t);
1150
+ i && (n[t] = i);
1151
+ }
1108
1152
  for (let e of ["margin", "padding"]) for (let t of [
1109
1153
  "top",
1110
1154
  "right",
@@ -1179,12 +1223,12 @@ async function ke(e, t, n = E(), r) {
1179
1223
  };
1180
1224
  r?.line_height !== void 0 && (h["line-height"] = String(r.line_height));
1181
1225
  function g(e) {
1182
- let t = `<w:rFonts w:ascii="${z(e["font-family"] || "freeserif")}" w:hAnsi="${z(e["font-family"] || "freeserif")}"/>`, n = X(e["font-size"]);
1183
- return n !== void 0 && (t += `<w:sz w:val="${Math.round(n * 2)}"/>`), e["font-weight"] && (t += `<w:b w:val="${e["font-weight"] === "bold" || Number(e["font-weight"]) >= 600 ? "1" : "0"}"/>`), e["font-style"] && (t += `<w:i w:val="${e["font-style"] === "italic" ? "1" : "0"}"/>`), e["text-decoration"] && (t += `<w:u w:val="${e["text-decoration"].includes("underline") ? "single" : "none"}"/><w:strike w:val="${e["text-decoration"].includes("line-through") ? "1" : "0"}"/>`), Y(e.color) && (t += `<w:color w:val="${Y(e.color)}"/>`), Y(e["background-color"]) && (t += `<w:shd w:fill="${Y(e["background-color"])}"/>`), ["super", "sub"].includes(e["vertical-align"]) && (t += `<w:vertAlign w:val="${e["vertical-align"] === "super" ? "superscript" : "subscript"}"/>`), e["text-transform"] === "uppercase" && (t += "<w:caps/>"), Z(e["letter-spacing"]) !== void 0 && (t += `<w:spacing w:val="${Z(e["letter-spacing"])}"/>`), t;
1226
+ let t = `<w:rFonts w:ascii="${ce(e["font-family"] || "freeserif")}" w:hAnsi="${ce(e["font-family"] || "freeserif")}"/>`, n = De(e["font-size"]);
1227
+ return n !== void 0 && (t += `<w:sz w:val="${Math.round(n * 2)}"/>`), e["font-weight"] && (t += `<w:b w:val="${e["font-weight"] === "bold" || Number(e["font-weight"]) >= 600 ? "1" : "0"}"/>`), e["font-style"] && (t += `<w:i w:val="${e["font-style"] === "italic" ? "1" : "0"}"/>`), e["text-decoration"] && (t += `<w:u w:val="${e["text-decoration"].includes("underline") ? "single" : "none"}"/><w:strike w:val="${e["text-decoration"].includes("line-through") ? "1" : "0"}"/>`), Y(e.color) && (t += `<w:color w:val="${Y(e.color)}"/>`), Y(e["background-color"]) && (t += `<w:shd w:fill="${Y(e["background-color"])}"/>`), ["super", "sub"].includes(e["vertical-align"]) && (t += `<w:vertAlign w:val="${e["vertical-align"] === "super" ? "superscript" : "subscript"}"/>`), e["text-transform"] === "uppercase" && (t += "<w:caps/>"), X(e["letter-spacing"]) !== void 0 && (t += `<w:spacing w:val="${X(e["letter-spacing"])}"/>`), t;
1184
1228
  }
1185
1229
  function _(e, t) {
1186
1230
  let n = "";
1187
- for (let r of e) r.nodeType === 3 ? r.textContent && (n += `<w:r><w:rPr>${g(t)}</w:rPr><w:t xml:space="preserve">${z(r.textContent)}</w:t></w:r>`) : r instanceof Element && (r.localName === "br" ? n += "<w:r><w:br/></w:r>" : n += _(r.childNodes, De(r, t)));
1231
+ for (let r of e) r.nodeType === 3 ? r.textContent && (n += `<w:r><w:rPr>${g(t)}</w:rPr><w:t xml:space="preserve">${ce(r.textContent)}</w:t></w:r>`) : r instanceof Element && (r.localName === "br" ? n += "<w:r><w:br/></w:r>" : n += _(r.childNodes, Q(r, t)));
1188
1232
  return n;
1189
1233
  }
1190
1234
  function v(e, r, a, o = i) {
@@ -1195,7 +1239,7 @@ async function ke(e, t, n = E(), r) {
1195
1239
  "center",
1196
1240
  "justify"
1197
1241
  ].includes(c) && (s += `<w:jc w:val="${c === "justify" ? "both" : c}"/>`);
1198
- let l = Math.max(o.before ?? 0, Z(r["margin-top"]) ?? 0), u = Math.max(o.after ?? 0, Z(r["margin-bottom"]) ?? (o.cell ? 0 : 120)), d = "", f = r["line-height"];
1242
+ let l = Math.max(o.before ?? 0, X(r["margin-top"]) ?? 0), u = Math.max(o.after ?? 0, X(r["margin-bottom"]) ?? (o.cell ? 0 : 120)), d = "", f = r["line-height"];
1199
1243
  if (f && /^\d*\.?\d+%?$/.test(f)) {
1200
1244
  let e = parseFloat(f) / (f.endsWith("%") ? 100 : 1), r = n.lineSpacingPolicy === "preserve";
1201
1245
  e < 1 && M(t, r ? "line-height-overlap-risk" : "line-height-normalized", r ? "Тесный интервал сохранён; проверьте наложение строк." : "Тесный интервал увеличен до одинарного; проверьте переносы.", "warning", {
@@ -1204,7 +1248,7 @@ async function ke(e, t, n = E(), r) {
1204
1248
  before: e,
1205
1249
  after: r ? e : 1
1206
1250
  }), d = ` w:line="${Math.round(Math.max(+!r, e) * 240)}" w:lineRule="auto"`;
1207
- } else X(f) !== void 0 && (d = ` w:line="${Math.max(0, Z(f))}" w:lineRule="atLeast"`);
1251
+ } else De(f) !== void 0 && (d = ` w:line="${Math.max(0, X(f))}" w:lineRule="atLeast"`);
1208
1252
  s += `<w:spacing w:before="${Math.max(0, l)}" w:after="${Math.max(0, u)}"${d}/>`;
1209
1253
  let p = "";
1210
1254
  for (let [e, t] of [
@@ -1212,7 +1256,7 @@ async function ke(e, t, n = E(), r) {
1212
1256
  ["margin-right", "right"],
1213
1257
  ["text-indent", "firstLine"]
1214
1258
  ]) {
1215
- let n = t === "left" ? o.left : t === "right" ? o.right : void 0, i = t === "left" || t === "right" ? Math.max(0, Z(r[`padding-${t}`]) ?? 0) : 0, s = Z(r[e]), c = s !== void 0 || i ? (s ?? 0) + i : void 0, l = a ? t === "left" ? 360 : t === "firstLine" ? a.pending ? -180 : 0 : void 0 : void 0, u = c === void 0 && !n && l === void 0 ? void 0 : (c ?? (t === "firstLine" ? l : 0) ?? 0) + (n ?? 0) + (t === "left" ? l ?? 0 : 0);
1259
+ let n = t === "left" ? o.left : t === "right" ? o.right : void 0, i = t === "left" || t === "right" ? Math.max(0, X(r[`padding-${t}`]) ?? 0) : 0, s = X(r[e]), c = s !== void 0 || i ? (s ?? 0) + i : void 0, l = a ? t === "left" ? 360 : t === "firstLine" ? a.pending ? -180 : 0 : void 0 : void 0, u = c === void 0 && !n && l === void 0 ? void 0 : (c ?? (t === "firstLine" ? l : 0) ?? 0) + (n ?? 0) + (t === "left" ? l ?? 0 : 0);
1216
1260
  u !== void 0 && (p += t === "firstLine" && u < 0 ? ` w:hanging="${-u}"` : ` w:${t}="${u}"`);
1217
1261
  }
1218
1262
  p && (s += `<w:ind${p}/>`);
@@ -1233,7 +1277,7 @@ async function ke(e, t, n = E(), r) {
1233
1277
  "avoid"
1234
1278
  ]
1235
1279
  ]) (r[e] === n || r[e] === "auto") && (s += `<w:${t} w:val="${r[e] === n ? "1" : "0"}"/>`);
1236
- return a && (a.pending ? s += `<w:numPr><w:ilvl w:val="0"/><w:numId w:val="${a.id}"/></w:numPr>` : s += "<w:pStyle w:val=\"AzHujjatListContinuation\"/>", a.pending = !1), `<w:p><w:pPr>${s}</w:pPr>${_(e, r)}</w:p>` + (r["page-break-after"] === "always" ? "<w:p><w:pPr><w:pageBreakBefore/></w:pPr></w:p>" : "");
1280
+ return a && (a.pending ? s += `<w:numPr><w:ilvl w:val="0"/><w:numId w:val="${a.id}"/></w:numPr>` : s += "<w:pStyle w:val=\"AzHujjatListContinuation\"/>", a.pending = !1), `<w:p><w:pPr>${s}</w:pPr>${_(e, r)}</w:p>`;
1237
1281
  }
1238
1282
  function y(e, t) {
1239
1283
  let n = e.style, r = n.getPropertyValue(`border-${t}-style`) || n.borderStyle, i = n.getPropertyValue(`border-${t}-width`) || n.borderWidth, a = n.getPropertyValue(`border-${t}-color`) || n.borderColor;
@@ -1243,14 +1287,14 @@ async function ke(e, t, n = E(), r) {
1243
1287
  dotted: "dotted",
1244
1288
  double: "double",
1245
1289
  none: "nil"
1246
- }[r] ?? "single"}" w:sz="${Math.max(0, Math.round((X(i) ?? .75) * 8))}" w:color="${Y(a) ?? "000000"}"/>`;
1290
+ }[r] ?? "single"}" w:sz="${Math.max(0, Math.round((De(i) ?? .75) * 8))}" w:color="${Y(a) ?? "000000"}"/>`;
1247
1291
  }
1248
1292
  function b(e, n, r) {
1249
- let i = Array.from(e.querySelectorAll("tr")).filter((t) => t.closest("table") === e), a = /* @__PURE__ */ new Map(), o = 1, s = [], c = n.width?.endsWith("%") ? parseFloat(n.width) : void 0, l = (r.left ?? 0) + (Z(n["margin-left"]) ?? 0), u = (r.right ?? 0) + (Z(n["margin-right"]) ?? 0), d = Math.max(1, r.width - l - u), f = Math.max(1, Math.round(Z(n.width) ?? (c === void 0 ? d : d * c / 100)));
1250
- (r.before || r.after || Z(n["margin-top"]) || Z(n["margin-bottom"])) && M(t, "table-margin-approximation", "Вертикальные отступы контейнера вокруг таблицы требуют проверки.");
1251
- let p = (e) => {
1293
+ let i = Array.from(e.querySelectorAll("tr")).filter((t) => t.closest("table") === e), a = /* @__PURE__ */ new Map(), o = 1, s = [], c = n.width?.endsWith("%") ? parseFloat(n.width) : void 0, u = (r.left ?? 0) + (X(n["margin-left"]) ?? 0), d = (r.right ?? 0) + (X(n["margin-right"]) ?? 0), f = Math.max(1, r.width - u - d), p = Math.max(1, Math.round(X(n.width) ?? (c === void 0 ? f : f * c / 100)));
1294
+ (r.before || r.after || X(n["margin-top"]) || X(n["margin-bottom"])) && M(t, "table-margin-approximation", "Вертикальные отступы контейнера вокруг таблицы требуют проверки.");
1295
+ let m = (e) => {
1252
1296
  if (e > 1e3) throw new A("Таблица содержит более 1000 столбцов с учётом объединённых ячеек.");
1253
- }, m = i.map((t) => {
1297
+ }, h = i.map((t) => {
1254
1298
  let r = 0, i = [];
1255
1299
  function c() {
1256
1300
  for (; a.has(r);) {
@@ -1260,21 +1304,21 @@ async function ke(e, t, n = E(), r) {
1260
1304
  span: e.span,
1261
1305
  rowSpan: 0,
1262
1306
  css: {}
1263
- }), --e.remaining === 0 && a.delete(r), r += e.span, p(r);
1307
+ }), --e.remaining === 0 && a.delete(r), r += e.span, m(r);
1264
1308
  }
1265
1309
  }
1266
1310
  for (let o of Array.from(t.children).filter((e) => e.localName === "td" || e.localName === "th")) {
1267
1311
  c();
1268
1312
  let t = Number(o.getAttribute("colspan") || 1), l = Number(o.getAttribute("rowspan") || 1);
1269
- p(r + t);
1313
+ m(r + t);
1270
1314
  let u = [], d = o.parentElement;
1271
1315
  for (; d && d !== e;) u.unshift(d), d = d.parentElement;
1272
- let m = (e) => ({
1316
+ let f = (e) => ({
1273
1317
  ...Oe(e),
1274
1318
  ...e["background-color"] ? { "background-color": e["background-color"] } : {}
1275
- }), h = De(o, m(u.reduce((e, t) => De(t, m(e)), n)));
1319
+ }), h = Q(o, f(u.reduce((e, t) => Q(t, f(e)), n)));
1276
1320
  o.localName === "th" && (h["font-weight"] = "bold");
1277
- let g = Z(h.width) ?? (h.width?.endsWith("%") ? parseFloat(h.width) * f / 100 : void 0);
1321
+ let g = X(h.width) ?? (h.width?.endsWith("%") ? parseFloat(h.width) * p / 100 : void 0);
1278
1322
  g !== void 0 && Number.isFinite(g) && g > 0 && s.push({
1279
1323
  column: r,
1280
1324
  span: t,
@@ -1302,44 +1346,55 @@ async function ke(e, t, n = E(), r) {
1302
1346
  c();
1303
1347
  }
1304
1348
  return o = Math.max(o, r), i;
1305
- }), h = Ce(o, f, s, t), g = "<w:p><w:pPr><w:spacing w:before=\"0\" w:after=\"0\"/></w:pPr></w:p>", _ = m.map((e) => `<w:tr>${e.map(({ element: e, column: t, span: n, rowSpan: r, css: i }) => {
1306
- let a = h.slice(t, t + n).reduce((e, t) => e + t, 0), o = `<w:tcW w:w="${a}" w:type="dxa"/>`;
1307
- if (n > 1 && (o += `<w:gridSpan w:val="${n}"/>`), r > 1 && (o += "<w:vMerge w:val=\"restart\"/>"), !e) return `<w:tc><w:tcPr>${o}${r === 0 ? "<w:vMerge/>" : ""}</w:tcPr>${g}</w:tc>`;
1308
- let s = Y(i["background-color"]);
1309
- s && (o += `<w:shd w:fill="${s}"/>`), [
1310
- "top",
1311
- "middle",
1312
- "bottom"
1313
- ].includes(i["vertical-align"]) && (o += `<w:vAlign w:val="${i["vertical-align"] === "middle" ? "center" : i["vertical-align"]}"/>`);
1314
- let c = [
1315
- "top",
1316
- "left",
1317
- "bottom",
1318
- "right"
1319
- ], l = c.map((t) => y(e, t)).join("");
1320
- l && (o += `<w:tcBorders>${l}</w:tcBorders>`);
1321
- let u = c.map((e) => Z(i[`padding-${e}`]) === void 0 ? "" : `<w:${e} w:w="${Math.max(0, Z(i[`padding-${e}`]))}" w:type="dxa"/>`).join("");
1322
- u && (o += `<w:tcMar>${u}</w:tcMar>`);
1323
- let d = Math.max(1, a - Math.max(0, Z(i["padding-left"]) ?? 0) - Math.max(0, Z(i["padding-right"]) ?? 0)), f = x(e.childNodes, Oe(i), void 0, {
1324
- width: d,
1325
- cell: !0
1326
- });
1327
- return (!f || f.endsWith("</w:tbl>")) && (f += g), `<w:tc><w:tcPr>${o}</w:tcPr>${f}</w:tc>`;
1328
- }).join("") || `<w:tc>${g}</w:tc>`}</w:tr>`).join(""), v = h.map((e) => `<w:gridCol w:w="${e}"/>`).join(""), b = c !== void 0 && !l && !u ? `<w:tblW w:w="${Math.round(c * 50)}" w:type="pct"/>` : `<w:tblW w:w="${f}" w:type="dxa"/>`, S = [
1349
+ }), g = Ce(o, p, s, t), _ = "<w:p><w:pPr><w:spacing w:before=\"0\" w:after=\"0\"/></w:pPr></w:p>", v = !0, b = h.map((e, n) => {
1350
+ let r = i[n], a = Q(r, {}), o = X(a.height), s = o !== void 0 && o >= 0 ? `<w:trHeight w:val="${o}" w:hRule="atLeast"/>` : "";
1351
+ ["avoid", "auto"].includes(a["page-break-inside"]) && (s += `<w:cantSplit w:val="${a["page-break-inside"] === "avoid" ? "1" : "0"}"/>`);
1352
+ let c = r.parentElement?.localName === "thead";
1353
+ return c && v ? s += "<w:tblHeader/>" : c && M(t, "table-header-not-contiguous", "Повторяемая шапка должна находиться в начале таблицы.", "warning", {
1354
+ stage: "import",
1355
+ location: { htmlPath: l.get(r) }
1356
+ }), c || (v = !1), `<w:tr>${s ? `<w:trPr>${s}</w:trPr>` : ""}${e.map(({ element: e, column: t, span: n, rowSpan: r, css: i }) => {
1357
+ let a = g.slice(t, t + n).reduce((e, t) => e + t, 0), o = `<w:tcW w:w="${a}" w:type="dxa"/>`;
1358
+ if (n > 1 && (o += `<w:gridSpan w:val="${n}"/>`), r > 1 && (o += "<w:vMerge w:val=\"restart\"/>"), !e) return `<w:tc><w:tcPr>${o}${r === 0 ? "<w:vMerge/>" : ""}</w:tcPr>${_}</w:tc>`;
1359
+ let s = Y(i["background-color"]);
1360
+ s && (o += `<w:shd w:fill="${s}"/>`), [
1361
+ "top",
1362
+ "middle",
1363
+ "bottom"
1364
+ ].includes(i["vertical-align"]) && (o += `<w:vAlign w:val="${i["vertical-align"] === "middle" ? "center" : i["vertical-align"]}"/>`);
1365
+ let c = [
1366
+ "top",
1367
+ "left",
1368
+ "bottom",
1369
+ "right"
1370
+ ], l = c.map((t) => y(e, t)).join("");
1371
+ l && (o += `<w:tcBorders>${l}</w:tcBorders>`);
1372
+ let u = c.map((e) => X(i[`padding-${e}`]) === void 0 ? "" : `<w:${e} w:w="${Math.max(0, X(i[`padding-${e}`]))}" w:type="dxa"/>`).join("");
1373
+ u && (o += `<w:tcMar>${u}</w:tcMar>`);
1374
+ let d = Math.max(1, a - Math.max(0, X(i["padding-left"]) ?? 0) - Math.max(0, X(i["padding-right"]) ?? 0)), f = C(S(e.childNodes, Oe(i), void 0, {
1375
+ width: d,
1376
+ cell: !0
1377
+ }));
1378
+ return (!f || f.endsWith("</w:tbl>")) && (f += _), `<w:tc><w:tcPr>${o}</w:tcPr>${f}</w:tc>`;
1379
+ }).join("") || `<w:tc>${_}</w:tc>`}</w:tr>`;
1380
+ }).join(""), x = g.map((e) => `<w:gridCol w:w="${e}"/>`).join(""), w = c !== void 0 && !u && !d ? `<w:tblW w:w="${Math.round(c * 50)}" w:type="pct"/>` : `<w:tblW w:w="${p}" w:type="dxa"/>`, T = [
1329
1381
  "top",
1330
1382
  "left",
1331
1383
  "bottom",
1332
1384
  "right"
1333
- ].map((t) => y(e, t)).join(""), C = n["table-layout"] === "auto" ? "autofit" : "fixed";
1334
- return `<w:tbl><w:tblPr>${b}${l ? `<w:tblInd w:w="${l}" w:type="dxa"/>` : ""}${S ? `<w:tblBorders>${S}</w:tblBorders>` : ""}<w:tblLayout w:type="${C}"/></w:tblPr><w:tblGrid>${v}</w:tblGrid>${_}</w:tbl>`;
1385
+ ].map((t) => y(e, t)).join(""), E = n["table-layout"] === "auto" ? "autofit" : "fixed";
1386
+ return `<w:tbl><w:tblPr>${w}${u ? `<w:tblInd w:w="${u}" w:type="dxa"/>` : ""}${T ? `<w:tblBorders>${T}</w:tblBorders>` : ""}<w:tblLayout w:type="${E}"/></w:tblPr><w:tblGrid>${x}</w:tblGrid>${b}</w:tbl>`;
1387
+ }
1388
+ function x(e, t) {
1389
+ return e.length && (e[0].before ||= t["page-break-before"] === "always", e[e.length - 1].after ||= t["page-break-after"] === "always"), e;
1335
1390
  }
1336
- function x(e, n, a, c = i) {
1337
- let u = "", d = [], f = 0, p = Array.from(e).filter((e) => e.nodeType !== 3 || e.textContent), m = (e, t = e) => ({
1391
+ function S(e, n, a, c = i) {
1392
+ let u = [], d = [], f = 0, p = Array.from(e).filter((e) => e.nodeType !== 3 || e.textContent), m = (e, t = e) => ({
1338
1393
  ...c,
1339
1394
  before: e === 0 ? c.before : void 0,
1340
1395
  after: t === p.length - 1 ? c.after : void 0
1341
1396
  }), h = (e) => {
1342
- d.length && (u += v(d, n, a, m(f, e))), d = [];
1397
+ d.length && u.push(...x([{ xml: v(d, n, a, m(f, e)) }], n)), d = [];
1343
1398
  };
1344
1399
  for (let [e, i] of p.entries()) {
1345
1400
  if (!(i instanceof Element) || !Te.has(i.localName)) {
@@ -1347,53 +1402,66 @@ async function ke(e, t, n = E(), r) {
1347
1402
  continue;
1348
1403
  }
1349
1404
  h(e - 1);
1350
- let p = De(i, Oe(n)), g = {
1405
+ let p = Q(i, Oe(n)), g = {
1351
1406
  ...m(e),
1352
1407
  htmlPath: l.get(i)
1353
1408
  };
1354
- if (i.localName === "p" && r?.paragraph_spacing !== void 0 && (p["margin-bottom"] ??= `${r.paragraph_spacing}pt`), r !== void 0 && i.localName === "h1" && (p["margin-bottom"] ??= "7.5pt"), i.localName === "table") u += b(i, p, g);
1409
+ if (i.localName === "p" && r?.paragraph_spacing !== void 0 && (p["margin-bottom"] ??= `${r.paragraph_spacing}pt`), r !== void 0 && i.localName === "h1" && (p["margin-bottom"] ??= "7.5pt"), i.localName === "table") u.push(...x([{
1410
+ xml: b(i, p, g),
1411
+ table: !0
1412
+ }], p));
1355
1413
  else if (i.localName === "ol" || i.localName === "ul") {
1356
1414
  let e = o++;
1357
1415
  s.push({
1358
1416
  id: e,
1359
1417
  tag: i.localName
1360
1418
  }), a && M(t, "nested-list-normalized", "Вложенный список при открытии становится отдельным списком.", "loss");
1361
- let n = Array.from(i.children).filter((e) => e.localName === "li");
1362
- for (let [t, r] of n.entries()) {
1363
- let i = {
1419
+ let n = Array.from(i.children).filter((e) => e.localName === "li"), r = [];
1420
+ for (let [t, i] of n.entries()) {
1421
+ let a = {
1364
1422
  id: e,
1365
1423
  pending: !0
1366
- }, a = De(r, Oe(p)), o = {
1424
+ }, o = Q(i, Oe(p)), s = {
1367
1425
  ...g,
1368
- before: Math.max(t === 0 ? g.before ?? 0 : 0, Z(a["margin-top"]) ?? 0),
1369
- after: Math.max(t === n.length - 1 ? g.after ?? 0 : 0, Z(a["margin-bottom"]) ?? 0),
1370
- left: (g.left ?? 0) + Q(p, "left") + Q(a, "left"),
1371
- right: (g.right ?? 0) + Q(p, "right") + Q(a, "right")
1372
- }, s = Object.fromEntries(Object.entries(a).filter(([e]) => !/^(margin|padding)(-|$)/.test(e)));
1373
- u += x(r.childNodes, s, i, o) || v([], s, i, o);
1426
+ before: Math.max(t === 0 ? g.before ?? 0 : 0, X(o["margin-top"]) ?? 0),
1427
+ after: Math.max(t === n.length - 1 ? g.after ?? 0 : 0, X(o["margin-bottom"]) ?? 0),
1428
+ left: (g.left ?? 0) + Z(p, "left") + Z(o, "left"),
1429
+ right: (g.right ?? 0) + Z(p, "right") + Z(o, "right")
1430
+ }, c = Object.fromEntries(Object.entries(o).filter(([e]) => !/^(margin|padding)(-|$)/.test(e))), l = S(i.childNodes, c, a, s);
1431
+ r.push(...x(l.length ? l : [{ xml: v([], c, a, s) }], o));
1374
1432
  }
1375
- } else i.localName === "div" && Array.from(i.children).some((e) => Te.has(e.localName)) ? (p["page-break-before"] === "always" && (u += v([], {
1376
- "page-break-before": "always",
1377
- "margin-bottom": "0pt"
1378
- })), u += x(i.childNodes, Oe(p), a, {
1433
+ u.push(...x(r, p));
1434
+ } else i.localName === "div" && Array.from(i.children).some((e) => Te.has(e.localName)) ? u.push(...x(S(i.childNodes, Oe(p), a, {
1379
1435
  ...g,
1380
- left: (g.left ?? 0) + Q(p, "left"),
1381
- right: (g.right ?? 0) + Q(p, "right"),
1382
- before: Math.max(g.before ?? 0, Z(p["margin-top"]) ?? 0),
1383
- after: Math.max(g.after ?? 0, Z(p["margin-bottom"]) ?? 0)
1384
- }), p["page-break-after"] === "always" && (u += v([], {
1385
- "page-break-before": "always",
1386
- "margin-bottom": "0pt"
1387
- }))) : i.localName === "hr" ? (M(t, "rule-normalized", "Разделитель HTML преобразован в строку."), u += v([document.createTextNode("────────────────")], p, void 0, c)) : u += v(i.childNodes, p, a, g);
1436
+ left: (g.left ?? 0) + Z(p, "left"),
1437
+ right: (g.right ?? 0) + Z(p, "right"),
1438
+ before: Math.max(g.before ?? 0, X(p["margin-top"]) ?? 0),
1439
+ after: Math.max(g.after ?? 0, X(p["margin-bottom"]) ?? 0)
1440
+ }), p)) : i.localName === "div" && !i.children.length && !i.textContent && p["page-break-before"] === "always" && Array.from(i.style).every((e) => ["page-break-before", "break-before"].includes(e)) ? u.push({
1441
+ xml: "",
1442
+ marker: !0
1443
+ }) : i.localName === "hr" ? (M(t, "rule-normalized", "Разделитель HTML преобразован в строку."), u.push(...x([{ xml: v([document.createTextNode("────────────────")], p, void 0, c) }], p))) : u.push(...x([{ xml: v(i.childNodes, p, a, g) }], p));
1388
1444
  }
1389
1445
  return h(p.length - 1), u;
1390
1446
  }
1391
- let S = x(a.childNodes, h) || "<w:p/>", C = c.map((e) => ({
1447
+ function C(e) {
1448
+ let t = "<w:p><w:pPr><w:pStyle w:val=\"AzHujjatPageBoundary\"/><w:pageBreakBefore/><w:spacing w:before=\"0\" w:after=\"0\" w:line=\"1\" w:lineRule=\"exact\"/></w:pPr></w:p>", n = "", r = !1, i = 0;
1449
+ for (let a of e) {
1450
+ if (a.marker) {
1451
+ i++;
1452
+ continue;
1453
+ }
1454
+ let e = Math.max(i, r || a.before ? 1 : 0);
1455
+ e ? (n += t.repeat(Math.max(0, e - 1)), a.table ? n += t + a.xml : n += a.xml.replace(/<w:pPr>(.*?)<\/w:pPr>/s, (e, t) => `<w:pPr>${t.replace(/<w:pageBreakBefore\b[^>]*\/>/g, "")}<w:pageBreakBefore/></w:pPr>`)) : n += a.xml, r = !!a.after, i = 0;
1456
+ }
1457
+ return n + t.repeat(i);
1458
+ }
1459
+ let w = C(S(a.childNodes, h)) || "<w:p/>", D = c.map((e) => ({
1392
1460
  ...e,
1393
- xml: x(e.root.childNodes, h) || "<w:p/>"
1461
+ xml: C(S(e.root.childNodes, h)) || "<w:p/>"
1394
1462
  }));
1395
- if (new TextEncoder().encode(S + C.map((e) => e.xml).join("")).byteLength > 8387584) throw new A("После преобразования HTML документ превышает допустимый размер XML (8 МиБ).");
1396
- let w = new Set("font-family font-size font-weight font-style color background-color text-align text-decoration text-transform vertical-align letter-spacing line-height margin margin-top margin-bottom margin-left margin-right text-indent width border border-style border-width border-color border-top border-right border-bottom border-left border-collapse table-layout padding padding-top padding-right padding-bottom padding-left page-break-before page-break-after page-break-inside".split(" "));
1463
+ if (new TextEncoder().encode(w + D.map((e) => e.xml).join("")).byteLength > 8387584) throw new A("После преобразования HTML документ превышает допустимый размер XML (8 МиБ).");
1464
+ let O = new Set("font-family font-size font-weight font-style color background-color text-align text-decoration text-transform vertical-align letter-spacing line-height margin margin-top margin-bottom margin-left margin-right text-indent width border border-style border-width border-color border-top border-right border-bottom border-left border-collapse table-layout padding padding-top padding-right padding-bottom padding-left page-break-before page-break-after page-break-inside break-before break-after break-inside".split(" "));
1397
1465
  for (let e of [a, ...c.map((e) => e.root)]) for (let n of e.querySelectorAll("[style]")) for (let e of Array.from(n.style)) {
1398
1466
  let r = n.style.getPropertyValue(e), i = ["td", "th"].includes(n.localName);
1399
1467
  e === "vertical-align" && !i && ![
@@ -1406,21 +1474,21 @@ async function ke(e, t, n = E(), r) {
1406
1474
  before: r,
1407
1475
  after: "baseline"
1408
1476
  });
1409
- let a = Te.has(n.localName) && !["table", "hr"].includes(n.localName);
1410
- (e.startsWith("padding") && !i && (!a || !["padding-left", "padding-right"].includes(e)) || e.startsWith("border") && !i && n.localName !== "table" || e === "font-size" && X(r) === void 0 || ["color", "background-color"].includes(e) && Y(r) === void 0 || !w.has(e) && !/^border-(top|right|bottom|left)-(width|style|color)$/.test(e)) && M(t, "html-style-approximation", `Стиль ${e} может измениться при открытии HTML в DOCX-редакторе.`, "warning", {
1477
+ let a = Te.has(n.localName) && !["table", "hr"].includes(n.localName), o = e.startsWith("padding") && !i && (!a || !["padding-left", "padding-right"].includes(e)) || e.startsWith("border") && !i && n.localName !== "table" || e === "font-size" && De(r) === void 0 || ["color", "background-color"].includes(e) && Y(r) === void 0, s = n.localName === "tr" && e === "height" && X(r) !== void 0 && X(r) >= 0;
1478
+ (o || !s && !O.has(e) && !/^border-(top|right|bottom|left)-(width|style|color)$/.test(e)) && M(t, "html-style-approximation", `Стиль ${e} может измениться при открытии HTML в DOCX-редакторе.`, "warning", {
1411
1479
  stage: "import",
1412
1480
  location: { htmlPath: l.get(n) },
1413
1481
  before: r
1414
1482
  });
1415
1483
  }
1416
- let D = new p();
1417
- D.file("[Content_Types].xml", "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/><Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/><Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/></Types>"), D.file("_rels/.rels", "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/></Relationships>"), D.file("word/_rels/document.xml.rels", "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rIdStyles\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rIdNumbering\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/></Relationships>");
1418
- let O = n.page, k = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", j = C.map(({ kind: e }) => `<w:${e}Reference w:type="default" r:id="rId${e}"/>`).join("");
1419
- for (let { kind: e, xml: t } of C) D.file(`word/${e}1.xml`, `<w:${e === "header" ? "hdr" : "ftr"} xmlns:w="${R}">${t}</w:${e === "header" ? "hdr" : "ftr"}>`);
1420
- let N = await D.file("[Content_Types].xml").async("string");
1421
- D.file("[Content_Types].xml", N.replace("</Types>", C.map(({ kind: e }) => `<Override PartName="/word/${e}1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${e}+xml"/>`).join("") + "</Types>"));
1422
- let P = await D.file("word/_rels/document.xml.rels").async("string");
1423
- return D.file("word/_rels/document.xml.rels", P.replace("</Relationships>", C.map(({ kind: e }) => `<Relationship Id="rId${e}" Type="${k}/${e}" Target="${e}1.xml"/>`).join("") + "</Relationships>")), D.file("word/document.xml", `<w:document xmlns:w="${R}" xmlns:r="${k}"><w:body>${S}<w:sectPr>${j}<w:pgSz w:w="${O.widthTwips}" w:h="${O.heightTwips}" w:orient="${O.orientation}"/><w:pgMar ${Object.entries(O.margins).map(([e, t]) => `w:${e}="${t}"`).join(" ")}/></w:sectPr></w:body></w:document>`), D.file("word/styles.xml", `<w:styles xmlns:w="${R}"><w:docDefaults><w:rPrDefault><w:rPr>${g(h)}</w:rPr></w:rPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:pPr><w:spacing w:after="120"/></w:pPr></w:style><w:style w:type="paragraph" w:styleId="AzHujjatListContinuation"><w:name w:val="List continuation"/><w:basedOn w:val="Normal"/></w:style></w:styles>`), D.file("word/numbering.xml", `<w:numbering xmlns:w="${R}">${s.map(({ id: e, tag: t }) => `<w:abstractNum w:abstractNumId="${e}"><w:multiLevelType w:val="singleLevel"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="${t === "ol" ? "decimal" : "bullet"}"/><w:lvlText w:val="${t === "ol" ? "%1." : "•"}"/><w:pPr><w:ind w:left="360" w:hanging="180"/></w:pPr></w:lvl></w:abstractNum><w:num w:numId="${e}"><w:abstractNumId w:val="${e}"/></w:num>`).join("")}</w:numbering>`), new Uint8Array(await D.generateAsync({
1484
+ let k = new p();
1485
+ k.file("[Content_Types].xml", "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/><Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/><Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/></Types>"), k.file("_rels/.rels", "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/></Relationships>"), k.file("word/_rels/document.xml.rels", "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rIdStyles\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rIdNumbering\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/></Relationships>");
1486
+ let j = n.page, N = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", P = D.map(({ kind: e }) => `<w:${e}Reference w:type="default" r:id="rId${e}"/>`).join("");
1487
+ for (let { kind: e, xml: t } of D) k.file(`word/${e}1.xml`, `<w:${e === "header" ? "hdr" : "ftr"} xmlns:w="${z}">${t}</w:${e === "header" ? "hdr" : "ftr"}>`);
1488
+ let F = await k.file("[Content_Types].xml").async("string");
1489
+ k.file("[Content_Types].xml", F.replace("</Types>", D.map(({ kind: e }) => `<Override PartName="/word/${e}1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${e}+xml"/>`).join("") + "</Types>"));
1490
+ let I = await k.file("word/_rels/document.xml.rels").async("string");
1491
+ return k.file("word/_rels/document.xml.rels", I.replace("</Relationships>", D.map(({ kind: e }) => `<Relationship Id="rId${e}" Type="${N}/${e}" Target="${e}1.xml"/>`).join("") + "</Relationships>")), k.file("word/document.xml", `<w:document xmlns:w="${z}" xmlns:r="${N}"><w:body>${w}<w:sectPr>${P}<w:pgSz w:w="${j.widthTwips}" w:h="${j.heightTwips}" w:orient="${j.orientation}"/><w:pgMar ${Object.entries(j.margins).map(([e, t]) => `w:${e}="${t}"`).join(" ")}/></w:sectPr></w:body></w:document>`), k.file("word/styles.xml", `<w:styles xmlns:w="${z}"><w:docDefaults><w:rPrDefault><w:rPr>${g(h)}</w:rPr></w:rPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:pPr><w:spacing w:after="120"/></w:pPr></w:style><w:style w:type="paragraph" w:styleId="AzHujjatListContinuation"><w:name w:val="List continuation"/><w:basedOn w:val="Normal"/></w:style><w:style w:type="paragraph" w:styleId="AzHujjatPageBoundary"><w:name w:val="Page boundary"/><w:basedOn w:val="Normal"/></w:style></w:styles>`), k.file("word/numbering.xml", `<w:numbering xmlns:w="${z}">${s.map(({ id: e, tag: t }) => `<w:abstractNum w:abstractNumId="${e}"><w:multiLevelType w:val="singleLevel"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="${t === "ol" ? "decimal" : "bullet"}"/><w:lvlText w:val="${t === "ol" ? "%1." : "•"}"/><w:pPr><w:ind w:left="360" w:hanging="180"/></w:pPr></w:lvl></w:abstractNum><w:num w:numId="${e}"><w:abstractNumId w:val="${e}"/></w:num>`).join("")}</w:numbering>`), new Uint8Array(await k.generateAsync({
1424
1492
  type: "arraybuffer",
1425
1493
  compression: "DEFLATE"
1426
1494
  }));
@@ -1429,12 +1497,12 @@ async function ke(e, t, n = E(), r) {
1429
1497
  //#region src/library/hujjat/docx.ts
1430
1498
  async function Ae(e, t) {
1431
1499
  let n = t.page === void 0 ? t.locales?.[t.locale]?.page : t.page;
1432
- J(n);
1433
- let r = await Se(e, t.layout, n), i = ce(t.locales ?? {}, t.locale, r.html);
1500
+ ye(n);
1501
+ let r = await Se(e, t.layout, n), i = se(t.locales ?? {}, t.locale, r.html);
1434
1502
  return i.warnings.unshift(...r.warnings), i.layout = r.layout, i.page = be(r.page, i), i.page !== void 0 && (i.locales[t.locale].page = structuredClone(i.page)), N(i.warnings, t.allowLossy), i;
1435
1503
  }
1436
1504
  async function je(e, t, n = {}) {
1437
- let r = ae(se(e, t));
1505
+ let r = ae(oe(e, t));
1438
1506
  r.page = be(e[t]?.page, r);
1439
1507
  let i = xe(r.page, n.layout);
1440
1508
  D(i.page, xe(r.page).page) || M(r.warnings, "layout-not-carried-by-html", "Геометрия layout отличается от настроек page на сервере. Текущий PDF-контракт поддерживает только ориентацию A4 и фиксированные поля.", "warning", { stage: "import" });
@@ -1451,16 +1519,16 @@ async function Me(e) {
1451
1519
  if (e.byteLength > 31457280) throw new A("DOCX превышает 30 МиБ.");
1452
1520
  let t = await p.loadAsync(e);
1453
1521
  if (Object.keys(t.files).length > 2e3) throw new A("В DOCX более 2000 частей.");
1454
- let [n, r] = await Promise.all([K(t, "word/document.xml"), K(t, "word/styles.xml")]), i = V(n?.documentElement, "body");
1522
+ let [n, r] = await Promise.all([q(t, "word/document.xml"), q(t, "word/styles.xml")]), i = V(n?.documentElement, "body");
1455
1523
  if (!i) throw new A("Нет структуры документа Word.");
1456
- let a = [], o = V(r?.documentElement, "docDefaults"), s = V(V(o, "pPrDefault"), "pPr"), c = q(V(V(o, "rPrDefault"), "rPr")), l = new Map(B(r?.documentElement, "style").map((e) => [H(e, "styleId"), e])), u = B(r?.documentElement, "style").find((e) => H(e, "type") === "paragraph" && H(e, "default") === "1");
1524
+ let a = [], o = V(r?.documentElement, "docDefaults"), s = V(V(o, "pPrDefault"), "pPr"), c = J(V(V(o, "rPrDefault"), "rPr")), l = new Map(B(r?.documentElement, "style").map((e) => [H(e, "styleId"), e])), u = B(r?.documentElement, "style").find((e) => H(e, "type") === "paragraph" && H(e, "default") === "1");
1457
1525
  function d(e, t = /* @__PURE__ */ new Set()) {
1458
1526
  if (!e || t.has(e) || t.size >= 30) return [];
1459
1527
  t.add(e);
1460
1528
  let n = l.get(e);
1461
1529
  return n ? [...d(U(n, "basedOn"), t), n] : [];
1462
1530
  }
1463
- let f = Array.from(i.getElementsByTagNameNS(R, "sectPr")), m = (e) => [V(e, "pgSz"), V(e, "pgMar")].map((e) => Array.from(e?.attributes ?? []).map((e) => [e.localName, e.value]).sort()).flat();
1531
+ let f = Array.from(i.getElementsByTagNameNS(z, "sectPr")), m = (e) => [V(e, "pgSz"), V(e, "pgMar")].map((e) => Array.from(e?.attributes ?? []).map((e) => [e.localName, e.value]).sort()).flat();
1464
1532
  return f.forEach((e, t) => {
1465
1533
  t && JSON.stringify(m(e)) !== JSON.stringify(m(f[0])) && M(a, "source-section-layout", "Раздел использует другую геометрию. Она сохраняется в DOCX; единый профиль HTML её не описывает.", "warning", {
1466
1534
  stage: "import",
@@ -1471,18 +1539,18 @@ async function Me(e) {
1471
1539
  before: JSON.stringify(m(e)),
1472
1540
  after: JSON.stringify(m(e))
1473
1541
  });
1474
- }), Array.from(i.getElementsByTagNameNS(R, "p")).forEach((e, t) => {
1542
+ }), Array.from(i.getElementsByTagNameNS(z, "p")).forEach((e, t) => {
1475
1543
  let n = {
1476
1544
  part: "word/document.xml",
1477
1545
  paragraphIndex: t
1478
- }, r = V(e, "pPr"), i = d(U(r, "pStyle") || H(u, "styleId")), o = he([
1546
+ }, r = V(e, "pPr"), i = d(U(r, "pStyle") || H(u, "styleId")), o = me([
1479
1547
  s,
1480
1548
  ...i.map((e) => V(e, "pPr")),
1481
1549
  r
1482
- ]), l = Object.assign({}, c, ...i.map((e) => q(V(e, "rPr")))), f = _e(l);
1483
- Array.from(e.getElementsByTagNameNS(R, "r")).forEach((e, t) => {
1484
- let r = V(e, "rPr"), i = Object.assign({}, l, ...d(U(r, "rStyle")).map((e) => q(V(e, "rPr"))), q(r));
1485
- i["--az-hidden"] !== "1" && (f = Math.max(f, _e(i)), Number(i["--az-position"]) && M(a, "source-baseline-shift", "Исходный фрагмент смещён по вертикали; сохранён без нормализации.", "warning", {
1550
+ ]), l = Object.assign({}, c, ...i.map((e) => J(V(e, "rPr")))), f = ge(l);
1551
+ Array.from(e.getElementsByTagNameNS(z, "r")).forEach((e, t) => {
1552
+ let r = V(e, "rPr"), i = Object.assign({}, l, ...d(U(r, "rStyle")).map((e) => J(V(e, "rPr"))), J(r));
1553
+ i["--az-hidden"] !== "1" && (f = Math.max(f, ge(i)), Number(i["--az-position"]) && M(a, "source-baseline-shift", "Исходный фрагмент смещён по вертикали; сохранён без нормализации.", "warning", {
1486
1554
  stage: "import",
1487
1555
  location: {
1488
1556
  ...n,
@@ -2200,7 +2268,7 @@ var Xe = {
2200
2268
  function Ze(e) {
2201
2269
  if (!e || !Object.keys(e).length) throw new A("Нет локалей шаблона.");
2202
2270
  for (let [t, n] of Object.entries(e)) {
2203
- if (oe(t), J(n?.page), !n || !Array.isArray(n.blocks) || !n.blocks.length) throw new A(`Нет блоков для ${t}.`);
2271
+ if (R(t), ye(n?.page), !n || !Array.isArray(n.blocks) || !n.blocks.length) throw new A(`Нет блоков для ${t}.`);
2204
2272
  for (let e of n.blocks) if (e.type === "html") {
2205
2273
  if (typeof e.props?.html != "string" || !e.props.html.trim()) throw new A(`Пустой HTML для ${t}.`);
2206
2274
  if (new TextEncoder().encode(e.props.html).length > 1048576) throw new A(`HTML для ${t} превышает 1 МБ.`);
@@ -2221,7 +2289,7 @@ async function $e(e) {
2221
2289
  let t = AbortSignal.any([AbortSignal.timeout(95e3), ...e.signal ? [e.signal] : []]);
2222
2290
  t.throwIfAborted(), Ze(e.locales);
2223
2291
  let n = e.locale ?? "uz";
2224
- oe(n);
2292
+ R(n);
2225
2293
  let r = new Headers(e.headers);
2226
2294
  r.set("Content-Type", "application/json"), r.set("Accept", "application/pdf, application/json");
2227
2295
  let i = await (e.fetcher ?? fetch)(e.url, {
@@ -2249,4 +2317,4 @@ async function $e(e) {
2249
2317
  };
2250
2318
  }
2251
2319
  //#endregion
2252
- export { Ie as AzDocumentEditor, Re as AzHtmlEditor, Be as DOCX_MIME, O as HUJJAT_LOCALES, ye as HUJJAT_MAX_CHROME_BYTES, k as HUJJAT_MAX_HTML_BYTES, C as HUJJAT_PAGE, A as HujjatCompatibilityError, ze as MAX_DOCX_BYTES, Me as analyzeDocxFormatting, Qe as createHujjatTemplatePayload, qe as downloadDocx, Ye as downloadPdf, Ke as exportFilename, Ae as exportHujjatDocx, je as importHujjatTemplate, Xe as pdfRenderProfile, Ge as readDocxFile, se as readHujjatHtml, $e as requestHujjatPreview, Je as requestPdf, E as resolveHtmlLayout, ae as sanitizeHujjatHtml, J as validateHujjatPage, P as validateHujjatVariable, ce as withHujjatLocale };
2320
+ export { Ie as AzDocumentEditor, Re as AzHtmlEditor, Be as DOCX_MIME, O as HUJJAT_LOCALES, ve as HUJJAT_MAX_CHROME_BYTES, k as HUJJAT_MAX_HTML_BYTES, C as HUJJAT_PAGE, A as HujjatCompatibilityError, ze as MAX_DOCX_BYTES, Me as analyzeDocxFormatting, Qe as createHujjatTemplatePayload, qe as downloadDocx, Ye as downloadPdf, Ke as exportFilename, Ae as exportHujjatDocx, je as importHujjatTemplate, Xe as pdfRenderProfile, Ge as readDocxFile, oe as readHujjatHtml, $e as requestHujjatPreview, Je as requestPdf, E as resolveHtmlLayout, ae as sanitizeHujjatHtml, ye as validateHujjatPage, P as validateHujjatVariable, se as withHujjatLocale };
@@ -38,6 +38,8 @@ export interface HujjatWarning {
38
38
  sectionIndex?: number;
39
39
  htmlPath?: string;
40
40
  runIndex?: number;
41
+ tableIndex?: number;
42
+ rowIndex?: number;
41
43
  };
42
44
  before?: string | number | boolean | null;
43
45
  after?: string | number | boolean | null;
@@ -1,7 +1,8 @@
1
1
  # Интеграция Az Editor в React-приложение
2
2
 
3
- Руководство описывает API `@makhmudov.kay/az-editor` версии `0.1.0-beta.5`.
3
+ Руководство описывает API `@makhmudov.kay/az-editor` версии `0.1.0-beta.6`.
4
4
  Поддержка серверного `page`, описанная ниже, добавлена в beta.5.
5
+ Совместимые исправления разрывов и строк таблиц добавлены в beta.6 и описаны ниже.
5
6
  Примеры написаны на TypeScript. Для JavaScript удалите аннотации типов и `import type`.
6
7
 
7
8
  ## Содержание
@@ -69,7 +70,7 @@ npm install @makhmudov.kay/az-editor@beta
69
70
  Для фиксации опубликованной версии:
70
71
 
71
72
  ```sh
72
- npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.5
73
+ npm install --save-exact @makhmudov.kay/az-editor@0.1.0-beta.6
73
74
  ```
74
75
 
75
76
  Тег `beta` может указывать на более новую версию. Сохраняйте lockfile и проверяйте
@@ -952,6 +953,40 @@ CSS ограничен шрифтом/цветом, базовым оформл
952
953
  пропорции колонок, `colspan` и `rowspan` сохраняются при повторном открытии.
953
954
  Противоречивые размеры нормализуются с предупреждением `table-width-normalized`.
954
955
 
956
+ **С beta.6:** абсолютная ширина таблицы сохраняется и при выходе
957
+ за текстовую область страницы; ширина в процентах рассчитывается от доступной области.
958
+ `<tr style="height:53.7pt">` задаёт минимальную высоту 1074 twips, а не точную высоту:
959
+ строка может расти с содержимым. Начальные строки `<thead>` становятся повторяемой шапкой;
960
+ `page-break-inside:avoid` / `auto` на `<tr>` сохраняют запрет / разрешение разрыва строки.
961
+ Режимы `table-layout:fixed` и `auto` проходят обратное преобразование.
962
+
963
+ ```html
964
+ <table style="width:566.85pt;table-layout:fixed">
965
+ <thead>
966
+ <tr style="page-break-inside:avoid"><th>Наименование</th><th>Значение</th></tr>
967
+ </thead>
968
+ <tbody>
969
+ <tr style="height:53.7pt"><td>Примечание</td><td><p><br></p></td></tr>
970
+ </tbody>
971
+ </table>
972
+ ```
973
+
974
+ `table-row-height-rule-lost` сообщает, что Word `exact` превращается в минимальную высоту.
975
+ `floating-table-position-lost` имеет уровень `loss`: содержание таблицы остаётся, но её
976
+ плавающее размещение не входит в текущий HTML-контракт. Адрес содержит `part`, `tableIndex`
977
+ и для строк `rowIndex`; индексы начинаются с нуля. Обработайте предупреждения через
978
+ существующий механизм диагностики перед разрешением экспорта с потерями.
979
+
980
+ **Разрывы с beta.6:** `break-before:page` и `break-after:page`
981
+ принимаются наряду с `page-break-*:always`. `avoid-page` преобразуется в `avoid`;
982
+ `auto` остаётся `auto`. При конфликте одного свойства действует последняя допустимая
983
+ декларация. В сохраняемом HTML используются только серверные имена `page-break-*`.
984
+ Разрыв до/после контейнера либо таблицы переносится на границу следующего блока.
985
+ Совпадающие правила на одной границе не создают второй разрыв. Явные пустые маркеры
986
+ `<div style="page-break-before:always"></div>` сохраняются, в том числе в конце документа.
987
+ Разрыв `page-break-after:always` на последнем содержательном блоке сам по себе не добавляет
988
+ пустую страницу. Автоматическая пагинация по-прежнему зависит от шрифтов и геометрии.
989
+
955
990
  Без `page.paragraph_spacing` абзацы внутри ячеек не получают дополнительный отступ 6pt после текста;
956
991
  явный `margin-bottom` сохраняется. Значение `line-height` в абсолютных единицах
957
992
  задаёт минимальную, а не жёсткую высоту строки (`atLeast`), чтобы крупный текст
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makhmudov.kay/az-editor",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-beta.6",
4
4
  "type": "module",
5
5
  "types": "./dist/library/index.d.ts",
6
6
  "sideEffects": [