pi-outpost 0.45.0 → 0.47.0

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 (103) hide show
  1. package/dist/contract/validate-structured-exchange.mjs +1 -1
  2. package/dist/pi-outpost-tools.mjs +1184 -470
  3. package/dist/pi-outpost.mjs +1719 -989
  4. package/dist/pi-outpost.sea.mjs +2 -2
  5. package/dist/sea-prep.blob +2 -2
  6. package/dist/skills/README.md +2 -2
  7. package/dist/skills/drawio/SKILL.md +12 -4
  8. package/dist/web/assets/{CodeEditor-DScL08xD.js → CodeEditor-BDtggYQl.js} +2 -2
  9. package/dist/web/assets/{PdfViewer-BCG92w49.js → PdfViewer-DhNNDuTB.js} +2 -2
  10. package/dist/web/assets/{abnfDiagram-WEYOIA3C-CDtRhqYU.js → abnfDiagram-WEYOIA3C-Dj3mV5cD.js} +1 -1
  11. package/dist/web/assets/{architecture-WOLXFQ4H-WBxUhvZg.js → architecture-WOLXFQ4H-DfIm6qJp.js} +1 -1
  12. package/dist/web/assets/{architectureDiagram-ZHVYKT53-D0dxQA-6.js → architectureDiagram-ZHVYKT53-DesvpuZO.js} +1 -1
  13. package/dist/web/assets/{blockDiagram-RJAE7QA3-BZwrQncg.js → blockDiagram-RJAE7QA3-DZKYWTVT.js} +1 -1
  14. package/dist/web/assets/{c4Diagram-XDPPPE54-BFNhLOS6.js → c4Diagram-XDPPPE54-BJ5QJyKU.js} +1 -1
  15. package/dist/web/assets/channel-CUIl51BP.js +1 -0
  16. package/dist/web/assets/{chunk-2E7WHVMD-CFMVvG35.js → chunk-2E7WHVMD-Ccal2EZV.js} +1 -1
  17. package/dist/web/assets/{chunk-4EMNKR2T-DNBJpWHa.js → chunk-4EMNKR2T-C1Ha7kZs.js} +1 -1
  18. package/dist/web/assets/{chunk-55XCU76K-m2_BGKXB.js → chunk-55XCU76K-D_RFo85h.js} +1 -1
  19. package/dist/web/assets/{chunk-7S6XSTFO-D5_WrDs1.js → chunk-7S6XSTFO-CbKG2whf.js} +1 -1
  20. package/dist/web/assets/{chunk-AQDTSKZB-ByVyf9Oz.js → chunk-AQDTSKZB-CV0pL9Ub.js} +1 -1
  21. package/dist/web/assets/{chunk-DSNLSHJZ-B3rs2TgX.js → chunk-DSNLSHJZ-jssKwfJs.js} +3 -3
  22. package/dist/web/assets/{chunk-HAGFOTED-Bguuewak.js → chunk-HAGFOTED-sbG-wLaw.js} +1 -1
  23. package/dist/web/assets/{chunk-HNE4Q36P-REv0b_Rl.js → chunk-HNE4Q36P-NQL5pc-1.js} +1 -1
  24. package/dist/web/assets/{chunk-NQOKRVIF-DlDs8eVX.js → chunk-NQOKRVIF-DS1Ro1wE.js} +1 -1
  25. package/dist/web/assets/{chunk-UHW7PFBP-QlYb9NYX.js → chunk-UHW7PFBP-DNdFaZ7_.js} +1 -1
  26. package/dist/web/assets/{chunk-VQ5W62QI-3wY_Pnz-.js → chunk-VQ5W62QI-Cp11Ry80.js} +1 -1
  27. package/dist/web/assets/{chunk-WQQL4CDK-D6vlPfqg.js → chunk-WQQL4CDK-4DgGrfra.js} +1 -1
  28. package/dist/web/assets/{chunk-YZO67HFG-ChAMbH2u.js → chunk-YZO67HFG-DHP_xcqn.js} +1 -1
  29. package/dist/web/assets/{chunk-ZAUX2LTX-DJYveMYE.js → chunk-ZAUX2LTX-BQhpR1qI.js} +1 -1
  30. package/dist/web/assets/{chunk-ZCHMQSOR-DBVZsxVg.js → chunk-ZCHMQSOR-B9AtuyJ5.js} +1 -1
  31. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-Bof6Wqvc.js → classDiagram-v2-4MYWR3UA-npGdzbo2.js} +1 -1
  32. package/dist/web/assets/conversationExport-DEc6uAKc.js +71 -0
  33. package/dist/web/assets/{cynefin-EF2NZ3EQ-D0dmmCqE.js → cynefin-EF2NZ3EQ-CeID8gB9.js} +1 -1
  34. package/dist/web/assets/{cynefinDiagram-WF24UDRP-jndeFZAh.js → cynefinDiagram-WF24UDRP-CyVndM-S.js} +1 -1
  35. package/dist/web/assets/{dagre-NK4GIZVX-B46rWONw.js → dagre-NK4GIZVX-u5v6sCf_.js} +1 -1
  36. package/dist/web/assets/{diagram-CBK3MWTC-DQucq1rH.js → diagram-CBK3MWTC-BmhxD9xj.js} +1 -1
  37. package/dist/web/assets/{diagram-I5XIIV2D-DM6H3IeP.js → diagram-I5XIIV2D-UsxMIhbs.js} +1 -1
  38. package/dist/web/assets/{diagram-ODIL2UCW-DSizZptj.js → diagram-ODIL2UCW-CEfcCXCE.js} +1 -1
  39. package/dist/web/assets/{diagram-PFBEJUXE-fpzY_PMW.js → diagram-PFBEJUXE-MUYDhKrk.js} +1 -1
  40. package/dist/web/assets/{diagram-RJA3I4VV-BpBj2ZDY.js → diagram-RJA3I4VV-B71trYQk.js} +1 -1
  41. package/dist/web/assets/{diagram-TYUNFSNR-Dfx0us8Y.js → diagram-TYUNFSNR-DLmu4STH.js} +1 -1
  42. package/dist/web/assets/{dist-CdOp4qX1.js → dist-BEPahcQA.js} +1 -1
  43. package/dist/web/assets/{dist-Cm0YAQW3.js → dist-BkUWIcY9.js} +1 -1
  44. package/dist/web/assets/{dist-ek5oj5g6.js → dist-C1HBbT14.js} +1 -1
  45. package/dist/web/assets/{dist-C71gHEdU.js → dist-D3i5wAL2.js} +1 -1
  46. package/dist/web/assets/{dist-DuB-TAXo.js → dist-Ded9gHFg.js} +1 -1
  47. package/dist/web/assets/{dist-Dab98uwr.js → dist-DteV7VmN.js} +1 -1
  48. package/dist/web/assets/{dist-BRfLEvQs.js → dist-HCk5OgEt.js} +1 -1
  49. package/dist/web/assets/{docxExport-DZsmBVpG.js → docxExport-CV6kgsFt.js} +2 -2
  50. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-CULqRtaP.js → ebnfDiagram-V4P3TTPT-B-6iPoQV.js} +1 -1
  51. package/dist/web/assets/{elk-QONTBCTQ-DDqQn-xG.js → elk-QONTBCTQ-CgqtV9Q_.js} +1 -1
  52. package/dist/web/assets/{erDiagram-KYQIGQAA-DE-crht8.js → erDiagram-KYQIGQAA-Cw9vK90c.js} +1 -1
  53. package/dist/web/assets/{eventmodeling-K75KTNOO-1SEWpiCE.js → eventmodeling-K75KTNOO-CHf1CFNW.js} +1 -1
  54. package/dist/web/assets/flowDiagram-IUGLLWBU-CH37AGFB.js +1 -0
  55. package/dist/web/assets/{ganttDiagram-R7GPNTJY-DSYOJbLs.js → ganttDiagram-R7GPNTJY-Dmj5wUxd.js} +1 -1
  56. package/dist/web/assets/{gitGraph-VSP46ZUC-DNWCkl3N.js → gitGraph-VSP46ZUC-CVvcUdjc.js} +1 -1
  57. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-CkBOylFC.js → gitGraphDiagram-PDYL7XHY-nVk22Ly7.js} +1 -1
  58. package/dist/web/assets/{index-DyhX4vzm.js → index-CeNyPy6Z.js} +310 -91
  59. package/dist/web/assets/index-m1s7LEHb.css +2 -0
  60. package/dist/web/assets/{info-OHQRW6UA-DZLo8j-J.js → info-OHQRW6UA-DwbjPahb.js} +1 -1
  61. package/dist/web/assets/{infoDiagram-MVDRKAX5-D-2ZSupm.js → infoDiagram-MVDRKAX5-lG6oGkFR.js} +1 -1
  62. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-CLrik0kB.js → ishikawaDiagram-HPEHV2GE-bhfMR94X.js} +1 -1
  63. package/dist/web/assets/{journeyDiagram-BOSHW7O7-CuyAWV-4.js → journeyDiagram-BOSHW7O7-C1-Ob4It.js} +1 -1
  64. package/dist/web/assets/{kanban-definition-FNSA4HC5-B2B1h8kE.js → kanban-definition-FNSA4HC5-DsXvcwK6.js} +1 -1
  65. package/dist/web/assets/{line-BQxlSu91.js → line-BqzYaALl.js} +1 -1
  66. package/dist/web/assets/{loadReferencedImage-C_UPJ3mE.js → loadReferencedImage-BVgIqRqX.js} +1 -1
  67. package/dist/web/assets/{mermaid-parser.core-DnjLN4bv.js → mermaid-parser.core-BzsUDPGk.js} +3 -3
  68. package/dist/web/assets/{mermaid.core-BKhoXFOd.js → mermaid.core-CIbJ01zL.js} +4 -4
  69. package/dist/web/assets/{mermaidToImage-B5d3JFJq.js → mermaidToImage-D72DvwWr.js} +4 -4
  70. package/dist/web/assets/{mindmap-definition-6OY57UG3-B0MUvVTB.js → mindmap-definition-6OY57UG3-CySroEda.js} +1 -1
  71. package/dist/web/assets/{packet-JDAUHWVQ-DAYWhrFA.js → packet-JDAUHWVQ-Djyhf31P.js} +1 -1
  72. package/dist/web/assets/{pdf-QxpddrQt.js → pdf-w-5-V5y9.js} +1 -1
  73. package/dist/web/assets/{pegDiagram-ECIUJNBX-BovEEioN.js → pegDiagram-ECIUJNBX-DjvY7oE9.js} +1 -1
  74. package/dist/web/assets/{pie-XZMESJXO-CXm4hROe.js → pie-XZMESJXO-CN90RHc2.js} +1 -1
  75. package/dist/web/assets/{pieDiagram-GNMPY74T-zAt-ronp.js → pieDiagram-GNMPY74T-Dpg4VK83.js} +1 -1
  76. package/dist/web/assets/{quadrantDiagram-D57K4MC3-DD6gVWLI.js → quadrantDiagram-D57K4MC3-B3QmHVxs.js} +1 -1
  77. package/dist/web/assets/{radar-ABXABTNO-CX9vnZE8.js → radar-ABXABTNO-Cx0tAsqB.js} +1 -1
  78. package/dist/web/assets/{railroad-I3PHUGI6-DkZJw3Kq.js → railroad-I3PHUGI6-CWKNhtID.js} +1 -1
  79. package/dist/web/assets/{railroad-abnf-LNEFI6M7-Df5H7zaX.js → railroad-abnf-LNEFI6M7-DKvcEeIf.js} +1 -1
  80. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-DtMyA7PD.js → railroad-ebnf-DWYD2UWJ-XYMXgt7o.js} +1 -1
  81. package/dist/web/assets/{railroad-peg-JR7BVNR7-EHQ8dXoM.js → railroad-peg-JR7BVNR7-DNyJRp4y.js} +1 -1
  82. package/dist/web/assets/{railroadDiagram-Y72NRBL7-CYwTGf8c.js → railroadDiagram-Y72NRBL7-D2P4MUSZ.js} +1 -1
  83. package/dist/web/assets/{requirementDiagram-EQYSW5RA-DYesZ7_S.js → requirementDiagram-EQYSW5RA-B4BtrrV8.js} +1 -1
  84. package/dist/web/assets/{sankeyDiagram-SY24JHO5-BNbhwAoN.js → sankeyDiagram-SY24JHO5-6LafRW7K.js} +1 -1
  85. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-DZMV2BnR.js → sequenceDiagram-BLEHNHQU-ekEpnVsg.js} +1 -1
  86. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-DJV9fjKn.js → stateDiagram-v2-A6IESKWZ-DEYl0pAs.js} +1 -1
  87. package/dist/web/assets/{swimlanes-B3ENRKFQ-Cn0Xjw21.js → swimlanes-B3ENRKFQ-B2bjC8Zx.js} +1 -1
  88. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-RoMCfGcC.js +8 -0
  89. package/dist/web/assets/{timeline-definition-JXYKGLGB-TKNDvdR3.js → timeline-definition-JXYKGLGB-9tQ1DYd2.js} +1 -1
  90. package/dist/web/assets/{treeView-D4JQ5SDB-D-kXzU-7.js → treeView-D4JQ5SDB-1uUVFCq3.js} +1 -1
  91. package/dist/web/assets/{treemap-SAJKECNS-kfOFBX69.js → treemap-SAJKECNS-BVofxWge.js} +1 -1
  92. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-wr_RVErP.js → usecaseDiagram-WPOLBNNX-GtuqVg4S.js} +1 -1
  93. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-DjYjzmE0.js → vennDiagram-Q3Y3IDCW-Be5IvYZC.js} +1 -1
  94. package/dist/web/assets/{wardley-7MLQ67FV-DXRVYxba.js → wardley-7MLQ67FV-yaELdUJI.js} +1 -1
  95. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-CjkG_WGZ.js → wardleyDiagram-IVAIDKWA-DYKdokCV.js} +1 -1
  96. package/dist/web/assets/{xychartDiagram-4URNHDU4-BmqrPYKm.js → xychartDiagram-4URNHDU4-B7bvwXaN.js} +1 -1
  97. package/dist/web/index.html +2 -2
  98. package/package.json +1 -1
  99. package/dist/web/assets/channel-BTON_fFR.js +0 -1
  100. package/dist/web/assets/conversationExport-DHYmlLaN.js +0 -71
  101. package/dist/web/assets/flowDiagram-IUGLLWBU-DX1p0mjx.js +0 -1
  102. package/dist/web/assets/index-DqQ_v17r.css +0 -2
  103. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BDNJvcfp.js +0 -8
@@ -493,9 +493,9 @@ function lookupRect(arr, fallback) {
493
493
  function lookupNormalRect(arr, fallback) {
494
494
  return isNumberArray(arr, 4) ? Util.normalizeRect(arr) : fallback;
495
495
  }
496
- function parseXFAPath(path21) {
496
+ function parseXFAPath(path22) {
497
497
  const positionPattern = /^(.+)\[(\d+)\]$/;
498
- return path21.split(".").map((component) => {
498
+ return path22.split(".").map((component) => {
499
499
  const m = component.match(positionPattern);
500
500
  return m ? {
501
501
  name: m[1],
@@ -3494,8 +3494,8 @@ function compilePatternInfo(ir2) {
3494
3494
  }
3495
3495
  return buffer;
3496
3496
  }
3497
- function compileFontPathInfo(path21) {
3498
- return path21.slice().buffer;
3497
+ function compileFontPathInfo(path22) {
3498
+ return path22.slice().buffer;
3499
3499
  }
3500
3500
  function getFloat214(view, offset) {
3501
3501
  return view.getInt16(offset) / 16384;
@@ -4730,11 +4730,11 @@ function createCmapTable(charCodeToGlyphId, toUnicodeExtraMap, numGlyphs) {
4730
4730
  }
4731
4731
  return table.data;
4732
4732
  }
4733
- function validateOS2Table(os2, file) {
4734
- file.pos = (file.start || 0) + os2.offset;
4733
+ function validateOS2Table(os22, file) {
4734
+ file.pos = (file.start || 0) + os22.offset;
4735
4735
  const version2 = file.getUint16();
4736
4736
  const minLength = [78, 86, 96, 96, 96, 100][version2];
4737
- if (minLength === void 0 || os2.length < minLength) {
4737
+ if (minLength === void 0 || os22.length < minLength) {
4738
4738
  return false;
4739
4739
  }
4740
4740
  file.skip(60);
@@ -4752,7 +4752,7 @@ function validateOS2Table(os2, file) {
4752
4752
  if (usWinAscent === 0) {
4753
4753
  return false;
4754
4754
  }
4755
- os2.data[8] = os2.data[9] = 0;
4755
+ os22.data[8] = os22.data[9] = 0;
4756
4756
  return true;
4757
4757
  }
4758
4758
  function createOS2Table(properties, charCodeToGlyphId, override2) {
@@ -4808,46 +4808,46 @@ function createOS2Table(properties, charCodeToGlyphId, override2) {
4808
4808
  }
4809
4809
  const winAscent = override2.yMax || typoAscent;
4810
4810
  const winDescent = -override2.yMin || -typoDescent;
4811
- const os2 = new DataBuilder({
4811
+ const os22 = new DataBuilder({
4812
4812
  exactLength: 96
4813
4813
  });
4814
- os2.setArray([0, 3]);
4815
- os2.setArray([2, 36]);
4816
- os2.setArray([1, 244]);
4817
- os2.setArray([0, 5]);
4818
- os2.skip(2);
4819
- os2.setArray([2, 138]);
4820
- os2.setArray([2, 187]);
4821
- os2.skip(2);
4822
- os2.setArray([0, 140]);
4823
- os2.setArray([2, 138]);
4824
- os2.setArray([2, 187]);
4825
- os2.skip(2);
4826
- os2.setArray([1, 223]);
4827
- os2.setArray([0, 49]);
4828
- os2.setArray([1, 2]);
4829
- os2.skip(2);
4830
- os2.setArray([0, 0, 6, properties.fixedPitch ? 9 : 0, 0, 0, 0, 0, 0, 0]);
4831
- os2.setInt32(ulUnicodeRange1);
4832
- os2.setInt32(ulUnicodeRange2);
4833
- os2.setInt32(ulUnicodeRange3);
4834
- os2.setInt32(ulUnicodeRange4);
4835
- os2.setArray([42, 50, 49, 42]);
4836
- os2.setInt16(properties.italicAngle ? 1 : 0);
4837
- os2.setInt16(firstCharIndex || properties.firstChar);
4838
- os2.setInt16(lastCharIndex || properties.lastChar);
4839
- os2.setInt16(typoAscent);
4840
- os2.setInt16(typoDescent);
4841
- os2.setArray([0, 100]);
4842
- os2.setInt16(winAscent);
4843
- os2.setInt16(winDescent);
4844
- os2.skip(4 + 4);
4845
- os2.setInt16(properties.xHeight);
4846
- os2.setInt16(properties.capHeight);
4847
- os2.skip(2);
4848
- os2.setInt16(firstCharIndex || properties.firstChar);
4849
- os2.setArray([0, 3]);
4850
- return os2.data;
4814
+ os22.setArray([0, 3]);
4815
+ os22.setArray([2, 36]);
4816
+ os22.setArray([1, 244]);
4817
+ os22.setArray([0, 5]);
4818
+ os22.skip(2);
4819
+ os22.setArray([2, 138]);
4820
+ os22.setArray([2, 187]);
4821
+ os22.skip(2);
4822
+ os22.setArray([0, 140]);
4823
+ os22.setArray([2, 138]);
4824
+ os22.setArray([2, 187]);
4825
+ os22.skip(2);
4826
+ os22.setArray([1, 223]);
4827
+ os22.setArray([0, 49]);
4828
+ os22.setArray([1, 2]);
4829
+ os22.skip(2);
4830
+ os22.setArray([0, 0, 6, properties.fixedPitch ? 9 : 0, 0, 0, 0, 0, 0, 0]);
4831
+ os22.setInt32(ulUnicodeRange1);
4832
+ os22.setInt32(ulUnicodeRange2);
4833
+ os22.setInt32(ulUnicodeRange3);
4834
+ os22.setInt32(ulUnicodeRange4);
4835
+ os22.setArray([42, 50, 49, 42]);
4836
+ os22.setInt16(properties.italicAngle ? 1 : 0);
4837
+ os22.setInt16(firstCharIndex || properties.firstChar);
4838
+ os22.setInt16(lastCharIndex || properties.lastChar);
4839
+ os22.setInt16(typoAscent);
4840
+ os22.setInt16(typoDescent);
4841
+ os22.setArray([0, 100]);
4842
+ os22.setInt16(winAscent);
4843
+ os22.setInt16(winDescent);
4844
+ os22.skip(4 + 4);
4845
+ os22.setInt16(properties.xHeight);
4846
+ os22.setInt16(properties.capHeight);
4847
+ os22.skip(2);
4848
+ os22.setInt16(firstCharIndex || properties.firstChar);
4849
+ os22.setArray([0, 3]);
4850
+ return os22.data;
4851
4851
  }
4852
4852
  function createPostTable(properties) {
4853
4853
  const post = new DataBuilder({
@@ -5634,7 +5634,7 @@ function getFamilyName(str2) {
5634
5634
  function generateFont({
5635
5635
  alias,
5636
5636
  local,
5637
- path: path21,
5637
+ path: path22,
5638
5638
  fallback,
5639
5639
  style,
5640
5640
  ultimate
@@ -5652,7 +5652,7 @@ function generateFont({
5652
5652
  if (alias) {
5653
5653
  const substitution = substitutionMap.get(alias);
5654
5654
  const aliasAppend = append || getStyleToAppend(style);
5655
- Object.assign(result, generateFont(substitution, src, localFontPath, useFallback && !fallback, usePath && !path21, aliasAppend));
5655
+ Object.assign(result, generateFont(substitution, src, localFontPath, useFallback && !fallback, usePath && !path22, aliasAppend));
5656
5656
  }
5657
5657
  if (style) {
5658
5658
  result.style = style;
@@ -5664,11 +5664,11 @@ function generateFont({
5664
5664
  const fallbackInfo = substitutionMap.get(fallback);
5665
5665
  const {
5666
5666
  ultimate: fallbackUltimate
5667
- } = generateFont(fallbackInfo, src, localFontPath, useFallback, usePath && !path21, append);
5667
+ } = generateFont(fallbackInfo, src, localFontPath, useFallback, usePath && !path22, append);
5668
5668
  result.ultimate ||= fallbackUltimate;
5669
5669
  }
5670
- if (usePath && path21 && localFontPath) {
5671
- src.push(`url(${localFontPath}${path21})`);
5670
+ if (usePath && path22 && localFontPath) {
5671
+ src.push(`url(${localFontPath}${path22})`);
5672
5672
  }
5673
5673
  return result;
5674
5674
  }
@@ -8089,13 +8089,13 @@ function writeXFADataForAcroform(str2, changes) {
8089
8089
  continue;
8090
8090
  }
8091
8091
  const {
8092
- path: path21,
8092
+ path: path22,
8093
8093
  value
8094
8094
  } = xfa;
8095
- if (!path21 || value === null) {
8095
+ if (!path22 || value === null) {
8096
8096
  continue;
8097
8097
  }
8098
- const nodePath = parseXFAPath(path21);
8098
+ const nodePath = parseXFAPath(path22);
8099
8099
  let node2 = xml.documentElement.searchNode(nodePath, 0);
8100
8100
  if (!node2 && nodePath.length > 1) {
8101
8101
  node2 = xml.documentElement.searchNode([nodePath.at(-1)], 0);
@@ -8103,7 +8103,7 @@ function writeXFADataForAcroform(str2, changes) {
8103
8103
  if (node2) {
8104
8104
  node2.childNodes = Array.isArray(value) ? value.map((val) => new SimpleDOMNode("value", val)) : [new SimpleDOMNode("#text", value)];
8105
8105
  } else {
8106
- warn(`Node not found for path: ${path21}`);
8106
+ warn(`Node not found for path: ${path22}`);
8107
8107
  }
8108
8108
  }
8109
8109
  const buffer = [];
@@ -29428,7 +29428,7 @@ var init_pdf_worker = __esm({
29428
29428
  if (this.#compiledGlyphs.has(glyphId) && this.#compiledCharCodes.has(charCode)) {
29429
29429
  return null;
29430
29430
  }
29431
- const path21 = this.#compiledGlyphs.getOrInsertComputed(glyphId, () => {
29431
+ const path22 = this.#compiledGlyphs.getOrInsertComputed(glyphId, () => {
29432
29432
  try {
29433
29433
  return this.compileGlyph(this.glyphs[glyphId], glyphId);
29434
29434
  } catch (ex) {
@@ -29436,10 +29436,10 @@ var init_pdf_worker = __esm({
29436
29436
  }
29437
29437
  });
29438
29438
  this.#compiledCharCodes.add(charCode);
29439
- if (path21 instanceof Error) {
29440
- throw path21;
29439
+ if (path22 instanceof Error) {
29440
+ throw path22;
29441
29441
  }
29442
- return compileFontPathInfo(path21);
29442
+ return compileFontPathInfo(path22);
29443
29443
  }
29444
29444
  compileGlyph(code3, glyphId) {
29445
29445
  if (!code3?.length || code3[0] === 14) {
@@ -47755,12 +47755,12 @@ var init_pdf_worker = __esm({
47755
47755
  get isXFAObjectArray() {
47756
47756
  return false;
47757
47757
  }
47758
- createNodes(path21) {
47758
+ createNodes(path22) {
47759
47759
  let root2 = this, node2 = null;
47760
47760
  for (const {
47761
47761
  name,
47762
47762
  index: index4
47763
- } of path21) {
47763
+ } of path22) {
47764
47764
  for (let i2 = 0, ii = isFinite(index4) ? index4 : 0; i2 <= ii; i2++) {
47765
47765
  const nsId = root2[$namespaceId] === NS_DATASETS ? -1 : root2[$namespaceId];
47766
47766
  node2 = new XmlObject(nsId, name);
@@ -57420,10 +57420,10 @@ var init_pdf_worker = __esm({
57420
57420
  });
57421
57421
  data.defaultFieldValue = this._decodeFormValue(defaultFieldValue);
57422
57422
  if (fieldValue === void 0 && annotationGlobals.xfaDatasets) {
57423
- const path21 = this._title.str;
57424
- if (path21) {
57423
+ const path22 = this._title.str;
57424
+ if (path22) {
57425
57425
  this._hasValueFromXFA = true;
57426
- data.fieldValue = fieldValue = annotationGlobals.xfaDatasets.getValue(path21);
57426
+ data.fieldValue = fieldValue = annotationGlobals.xfaDatasets.getValue(path22);
57427
57427
  }
57428
57428
  }
57429
57429
  if (fieldValue === void 0 && data.defaultFieldValue !== null) {
@@ -60209,11 +60209,11 @@ var init_pdf_worker = __esm({
60209
60209
  this.node = parser2.node;
60210
60210
  }
60211
60211
  }
60212
- getValue(path21) {
60213
- if (!this.node || !path21) {
60212
+ getValue(path22) {
60213
+ if (!this.node || !path22) {
60214
60214
  return "";
60215
60215
  }
60216
- const node2 = this.node.searchNode(parseXFAPath(path21), 0);
60216
+ const node2 = this.node.searchNode(parseXFAPath(path22), 0);
60217
60217
  if (!node2) {
60218
60218
  return "";
60219
60219
  }
@@ -67974,33 +67974,33 @@ function renderRichText({
67974
67974
  container.append(fragment);
67975
67975
  }
67976
67976
  function makePathFromDrawOPS(data) {
67977
- const path21 = new Path2D();
67977
+ const path22 = new Path2D();
67978
67978
  if (!data) {
67979
- return path21;
67979
+ return path22;
67980
67980
  }
67981
67981
  for (let i2 = 0, ii = data.length; i2 < ii; ) {
67982
67982
  switch (data[i2++]) {
67983
67983
  case DrawOPS2.moveTo:
67984
- path21.moveTo(data[i2++], data[i2++]);
67984
+ path22.moveTo(data[i2++], data[i2++]);
67985
67985
  break;
67986
67986
  case DrawOPS2.lineTo:
67987
- path21.lineTo(data[i2++], data[i2++]);
67987
+ path22.lineTo(data[i2++], data[i2++]);
67988
67988
  break;
67989
67989
  case DrawOPS2.curveTo:
67990
- path21.bezierCurveTo(data[i2++], data[i2++], data[i2++], data[i2++], data[i2++], data[i2++]);
67990
+ path22.bezierCurveTo(data[i2++], data[i2++], data[i2++], data[i2++], data[i2++], data[i2++]);
67991
67991
  break;
67992
67992
  case DrawOPS2.quadraticCurveTo:
67993
- path21.quadraticCurveTo(data[i2++], data[i2++], data[i2++], data[i2++]);
67993
+ path22.quadraticCurveTo(data[i2++], data[i2++], data[i2++], data[i2++]);
67994
67994
  break;
67995
67995
  case DrawOPS2.closePath:
67996
- path21.closePath();
67996
+ path22.closePath();
67997
67997
  break;
67998
67998
  default:
67999
67999
  warn2(`Unrecognized drawing path operator: ${data[i2 - 1]}`);
68000
68000
  break;
68001
68001
  }
68002
68002
  }
68003
- return path21;
68003
+ return path22;
68004
68004
  }
68005
68005
  function bindEvents(obj, element, names2) {
68006
68006
  for (const name of names2) {
@@ -68155,8 +68155,8 @@ function blend(fg, bg, alpha) {
68155
68155
  return Math.round(alpha * fg + (1 - alpha) * bg);
68156
68156
  }
68157
68157
  async function node_utils_fetchData(url) {
68158
- const fs19 = process.getBuiltinModule("fs/promises");
68159
- const data = await fs19.readFile(url);
68158
+ const fs20 = process.getBuiltinModule("fs/promises");
68159
+ const data = await fs20.readFile(url);
68160
68160
  return new Uint8Array(data);
68161
68161
  }
68162
68162
  function convertBlackAndWhiteToRGBA2({
@@ -68796,11 +68796,11 @@ function network_getArrayBuffer(val) {
68796
68796
  return typeof val !== "string" ? val : stringToBytes2(val).buffer;
68797
68797
  }
68798
68798
  function getReadableStream(url, opts = null) {
68799
- const fs19 = process.getBuiltinModule("fs");
68799
+ const fs20 = process.getBuiltinModule("fs");
68800
68800
  const {
68801
68801
  Readable
68802
68802
  } = process.getBuiltinModule("stream");
68803
- const readStream = fs19.createReadStream(url, opts);
68803
+ const readStream = fs20.createReadStream(url, opts);
68804
68804
  return Readable.toWeb(readStream);
68805
68805
  }
68806
68806
  function getNetworkStream(url) {
@@ -80614,9 +80614,9 @@ var init_pdf = __esm({
80614
80614
  return rule;
80615
80615
  }
80616
80616
  getPathGenerator(objs, character) {
80617
- let path21 = this.#compiledPaths.get(character);
80618
- if (path21) {
80619
- return path21;
80617
+ let path22 = this.#compiledPaths.get(character);
80618
+ if (path22) {
80619
+ return path22;
80620
80620
  }
80621
80621
  const objId = `${this.loadedName}_path_${character}`;
80622
80622
  let cmds;
@@ -80625,12 +80625,12 @@ var init_pdf = __esm({
80625
80625
  } catch (ex) {
80626
80626
  warn2(`getPathGenerator - ignoring character: "${ex}".`);
80627
80627
  }
80628
- path21 = makePathFromDrawOPS(cmds?.path);
80628
+ path22 = makePathFromDrawOPS(cmds?.path);
80629
80629
  if (!this.fontExtraProperties) {
80630
80630
  objs.delete(objId);
80631
80631
  }
80632
- this.#compiledPaths.set(character, path21);
80633
- return path21;
80632
+ this.#compiledPaths.set(character, path22);
80633
+ return path22;
80634
80634
  }
80635
80635
  get black() {
80636
80636
  return this.#fontData.black;
@@ -82453,7 +82453,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
82453
82453
  Util2.singularValueDecompose2dScale(this.baseTransform, scale);
82454
82454
  return [matrixScaleX * scale[0], matrixScaleY * scale[1]];
82455
82455
  }
82456
- drawPattern(owner, path21, useEOFill = false, [n, m], opIdx) {
82456
+ drawPattern(owner, path22, useEOFill = false, [n, m], opIdx) {
82457
82457
  const [x0, y0, x1, y1] = this.bbox;
82458
82458
  const dependencyTracker = owner.dependencyTracker;
82459
82459
  if (dependencyTracker) {
@@ -82461,9 +82461,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
82461
82461
  }
82462
82462
  owner.save();
82463
82463
  if (useEOFill) {
82464
- owner.ctx.clip(path21, "evenodd");
82464
+ owner.ctx.clip(path22, "evenodd");
82465
82465
  } else {
82466
- owner.ctx.clip(path21);
82466
+ owner.ctx.clip(path22);
82467
82467
  }
82468
82468
  owner.ctx.setTransform(...this.patternBaseMatrix);
82469
82469
  owner.ctx.translate(n * this.xstep, m * this.ystep);
@@ -83622,15 +83622,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83622
83622
  if (hasInnerCutout && maskX0 === layerOffsetX && maskY0 === layerOffsetY && maskX1 === layerOffsetX + layerWidth && maskY1 === layerOffsetY + layerHeight) {
83623
83623
  return;
83624
83624
  }
83625
- const path21 = new Path2D();
83626
- path21.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
83625
+ const path22 = new Path2D();
83626
+ path22.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
83627
83627
  if (hasInnerCutout) {
83628
- path21.rect(maskX0, maskY0, maskX1 - maskX0, maskY1 - maskY0);
83628
+ path22.rect(maskX0, maskY0, maskX1 - maskX0, maskY1 - maskY0);
83629
83629
  }
83630
83630
  layerCtx.save();
83631
83631
  layerCtx.globalAlpha = alpha / 255;
83632
83632
  layerCtx.setTransform(1, 0, 0, 1, 0, 0);
83633
- layerCtx.clip(path21, "evenodd");
83633
+ layerCtx.clip(path22, "evenodd");
83634
83634
  layerCtx.globalCompositeOperation = "destination-in";
83635
83635
  layerCtx.fillStyle = "#000000";
83636
83636
  layerCtx.fillRect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
@@ -83686,21 +83686,21 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83686
83686
  this._cachedScaleForStroking[0] = -1;
83687
83687
  }
83688
83688
  constructPath(opIdx, op2, data, minMax) {
83689
- let [path21] = data;
83689
+ let [path22] = data;
83690
83690
  if (!minMax) {
83691
- path21 ||= data[0] = new Path2D();
83691
+ path22 ||= data[0] = new Path2D();
83692
83692
  if (op2 !== OPS2.stroke && op2 !== OPS2.closeStroke) {
83693
83693
  this.current.tilingPatternDims = null;
83694
83694
  }
83695
- this[op2](opIdx, path21);
83695
+ this[op2](opIdx, path22);
83696
83696
  return;
83697
83697
  }
83698
83698
  if (this.dependencyTracker !== null) {
83699
83699
  const outerExtraSize = op2 === OPS2.stroke ? this.current.lineWidth / 2 : 0;
83700
83700
  this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, this.ctx, minMax[0] - outerExtraSize, minMax[2] + outerExtraSize, minMax[1] - outerExtraSize, minMax[3] + outerExtraSize).recordDependencies(opIdx, ["transform"]);
83701
83701
  }
83702
- if (!(path21 instanceof Path2D)) {
83703
- path21 = data[0] = makePathFromDrawOPS(path21);
83702
+ if (!(path22 instanceof Path2D)) {
83703
+ path22 = data[0] = makePathFromDrawOPS(path22);
83704
83704
  }
83705
83705
  Util2.axialAlignedBoundingBox(minMax, getCurrentTransform(this.ctx), this.current.minMax);
83706
83706
  const tilingDims = this.current.tilingPatternDims;
@@ -83712,13 +83712,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83712
83712
  this.current.fillColor.updatePatternDims(clippedBBox, tilingDims);
83713
83713
  }
83714
83714
  }
83715
- this[op2](opIdx, path21);
83715
+ this[op2](opIdx, path22);
83716
83716
  this._pathStartIdx = opIdx;
83717
83717
  }
83718
83718
  closePath(opIdx) {
83719
83719
  this.ctx.closePath();
83720
83720
  }
83721
- stroke(opIdx, path21, consumePath = true) {
83721
+ stroke(opIdx, path22, consumePath = true) {
83722
83722
  const started = consumePath && this.#beginKnockoutElement(this.current.strokeAlpha);
83723
83723
  const ctx = this.ctx;
83724
83724
  const strokeColor = this.current.strokeColor;
@@ -83730,26 +83730,26 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83730
83730
  ctx.strokeStyle = strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx);
83731
83731
  if (baseTransform) {
83732
83732
  const newPath = new Path2D();
83733
- newPath.addPath(path21, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
83734
- path21 = newPath;
83733
+ newPath.addPath(path22, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
83734
+ path22 = newPath;
83735
83735
  }
83736
- this.rescaleAndStroke(path21, false);
83736
+ this.rescaleAndStroke(path22, false);
83737
83737
  ctx.restore();
83738
83738
  } else {
83739
- this.rescaleAndStroke(path21, true);
83739
+ this.rescaleAndStroke(path22, true);
83740
83740
  }
83741
83741
  }
83742
83742
  this.dependencyTracker?.recordDependencies(opIdx, Dependencies.stroke);
83743
83743
  if (consumePath) {
83744
- this.consumePath(opIdx, path21, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
83744
+ this.consumePath(opIdx, path22, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
83745
83745
  }
83746
83746
  ctx.globalAlpha = this.current.fillAlpha;
83747
83747
  this.#endKnockoutElement(started);
83748
83748
  }
83749
- closeStroke(opIdx, path21) {
83750
- this.stroke(opIdx, path21);
83749
+ closeStroke(opIdx, path22) {
83750
+ this.stroke(opIdx, path22);
83751
83751
  }
83752
- fill(opIdx, path21, consumePath = true) {
83752
+ fill(opIdx, path22, consumePath = true) {
83753
83753
  const started = consumePath && this.#beginKnockoutElement(this.current.fillAlpha);
83754
83754
  const ctx = this.ctx;
83755
83755
  const fillColor = this.current.fillColor;
@@ -83761,10 +83761,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83761
83761
  const dims = this.current.tilingPatternDims;
83762
83762
  const tileIdx = dims && fillColor.canSkipPatternCanvas(dims);
83763
83763
  if (tileIdx) {
83764
- fillColor.drawPattern(this, path21, this.pendingEOFill, tileIdx, opIdx);
83764
+ fillColor.drawPattern(this, path22, this.pendingEOFill, tileIdx, opIdx);
83765
83765
  this.pendingEOFill = false;
83766
83766
  if (consumePath) {
83767
- this.consumePath(opIdx, path21, intersect);
83767
+ this.consumePath(opIdx, path22, intersect);
83768
83768
  }
83769
83769
  this.current.tilingPatternDims = null;
83770
83770
  this.#endKnockoutElement(started);
@@ -83776,17 +83776,17 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83776
83776
  ctx.fillStyle = fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx);
83777
83777
  if (baseTransform) {
83778
83778
  const newPath = new Path2D();
83779
- newPath.addPath(path21, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
83780
- path21 = newPath;
83779
+ newPath.addPath(path22, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
83780
+ path22 = newPath;
83781
83781
  }
83782
83782
  needRestore = true;
83783
83783
  }
83784
83784
  if (this.contentVisible && intersect !== null) {
83785
83785
  if (this.pendingEOFill) {
83786
- ctx.fill(path21, "evenodd");
83786
+ ctx.fill(path22, "evenodd");
83787
83787
  this.pendingEOFill = false;
83788
83788
  } else {
83789
- ctx.fill(path21);
83789
+ ctx.fill(path22);
83790
83790
  }
83791
83791
  }
83792
83792
  if (needRestore) {
@@ -83794,38 +83794,38 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83794
83794
  this.dependencyTracker?.restore(opIdx);
83795
83795
  }
83796
83796
  if (consumePath) {
83797
- this.consumePath(opIdx, path21, intersect);
83797
+ this.consumePath(opIdx, path22, intersect);
83798
83798
  }
83799
83799
  this.#endKnockoutElement(started);
83800
83800
  }
83801
- eoFill(opIdx, path21) {
83801
+ eoFill(opIdx, path22) {
83802
83802
  this.pendingEOFill = true;
83803
- this.fill(opIdx, path21);
83803
+ this.fill(opIdx, path22);
83804
83804
  }
83805
- fillStroke(opIdx, path21) {
83805
+ fillStroke(opIdx, path22) {
83806
83806
  const started = this.#beginKnockoutElement(Math.min(this.current.fillAlpha, this.current.strokeAlpha));
83807
- this.fill(opIdx, path21, false);
83808
- this.stroke(opIdx, path21, false);
83809
- this.consumePath(opIdx, path21);
83807
+ this.fill(opIdx, path22, false);
83808
+ this.stroke(opIdx, path22, false);
83809
+ this.consumePath(opIdx, path22);
83810
83810
  this.#endKnockoutElement(started);
83811
83811
  }
83812
- eoFillStroke(opIdx, path21) {
83812
+ eoFillStroke(opIdx, path22) {
83813
83813
  this.pendingEOFill = true;
83814
- this.fillStroke(opIdx, path21);
83814
+ this.fillStroke(opIdx, path22);
83815
83815
  }
83816
- closeFillStroke(opIdx, path21) {
83817
- this.fillStroke(opIdx, path21);
83816
+ closeFillStroke(opIdx, path22) {
83817
+ this.fillStroke(opIdx, path22);
83818
83818
  }
83819
- closeEOFillStroke(opIdx, path21) {
83819
+ closeEOFillStroke(opIdx, path22) {
83820
83820
  this.pendingEOFill = true;
83821
- this.fillStroke(opIdx, path21);
83821
+ this.fillStroke(opIdx, path22);
83822
83822
  }
83823
- endPath(opIdx, path21) {
83824
- this.consumePath(opIdx, path21);
83823
+ endPath(opIdx, path22) {
83824
+ this.consumePath(opIdx, path22);
83825
83825
  }
83826
- rawFillPath(opIdx, path21) {
83826
+ rawFillPath(opIdx, path22) {
83827
83827
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
83828
- this.ctx.fill(path21);
83828
+ this.ctx.fill(path22);
83829
83829
  this.dependencyTracker?.recordDependencies(opIdx, Dependencies.rawFillPath).recordOperation(opIdx);
83830
83830
  this.#endKnockoutElement(started);
83831
83831
  }
@@ -83864,12 +83864,12 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83864
83864
  x,
83865
83865
  y,
83866
83866
  fontSize,
83867
- path: path21
83867
+ path: path22
83868
83868
  } of paths) {
83869
- if (!path21) {
83869
+ if (!path22) {
83870
83870
  continue;
83871
83871
  }
83872
- newPath.addPath(path21, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x, y).scale(fontSize, -fontSize));
83872
+ newPath.addPath(path22, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x, y).scale(fontSize, -fontSize));
83873
83873
  }
83874
83874
  ctx.clip(newPath);
83875
83875
  }
@@ -83957,9 +83957,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83957
83957
  this.moveText(opIdx, 0, this.current.leading);
83958
83958
  this.dependencyTracker?.recordIncrementalData("moveText", this.dependencyTracker.getSimpleIndex("leading") ?? opIdx);
83959
83959
  }
83960
- #getScaledPath(path21, currentTransform, transform) {
83960
+ #getScaledPath(path22, currentTransform, transform) {
83961
83961
  const newPath = new Path2D();
83962
- newPath.addPath(path21, new DOMMatrix(transform).invertSelf().multiplySelf(currentTransform));
83962
+ newPath.addPath(path22, new DOMMatrix(transform).invertSelf().multiplySelf(currentTransform));
83963
83963
  return newPath;
83964
83964
  }
83965
83965
  paintChar(opIdx, character, x, y, patternFillTransform, patternStrokeTransform) {
@@ -83972,11 +83972,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83972
83972
  const isAddToPathSet = !!(textRenderingMode & TextRenderingMode2.ADD_TO_PATH_FLAG);
83973
83973
  const patternFill = current.patternFill && !font.missingFile;
83974
83974
  const patternStroke = current.patternStroke && !font.missingFile;
83975
- let path21;
83975
+ let path22;
83976
83976
  if ((font.disableFontFace || isAddToPathSet || patternFill || patternStroke) && !font.missingFile) {
83977
- path21 = font.getPathGenerator(this.commonObjs, character);
83977
+ path22 = font.getPathGenerator(this.commonObjs, character);
83978
83978
  }
83979
- if (path21 && (font.disableFontFace || patternFill || patternStroke)) {
83979
+ if (path22 && (font.disableFontFace || patternFill || patternStroke)) {
83980
83980
  ctx.save();
83981
83981
  ctx.translate(x, y);
83982
83982
  ctx.scale(fontSize, -fontSize);
@@ -83986,10 +83986,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
83986
83986
  if (patternFillTransform) {
83987
83987
  currentTransform = ctx.getTransform();
83988
83988
  ctx.setTransform(...patternFillTransform);
83989
- const scaledPath = this.#getScaledPath(path21, currentTransform, patternFillTransform);
83989
+ const scaledPath = this.#getScaledPath(path22, currentTransform, patternFillTransform);
83990
83990
  ctx.fill(scaledPath);
83991
83991
  } else {
83992
- ctx.fill(path21);
83992
+ ctx.fill(path22);
83993
83993
  }
83994
83994
  }
83995
83995
  if (fillStrokeMode === TextRenderingMode2.STROKE || fillStrokeMode === TextRenderingMode2.FILL_STROKE) {
@@ -84006,10 +84006,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
84006
84006
  const transf = Util2.transform([a, b, c, d, 0, 0], invPatternTransform);
84007
84007
  Util2.singularValueDecompose2dScale(transf, XY);
84008
84008
  ctx.lineWidth *= Math.max(XY[0], XY[1]) / fontSize;
84009
- ctx.stroke(this.#getScaledPath(path21, currentTransform, patternStrokeTransform));
84009
+ ctx.stroke(this.#getScaledPath(path22, currentTransform, patternStrokeTransform));
84010
84010
  } else {
84011
84011
  ctx.lineWidth /= fontSize;
84012
- ctx.stroke(path21);
84012
+ ctx.stroke(path22);
84013
84013
  }
84014
84014
  }
84015
84015
  ctx.restore();
@@ -84032,7 +84032,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
84032
84032
  x,
84033
84033
  y,
84034
84034
  fontSize,
84035
- path: path21
84035
+ path: path22
84036
84036
  });
84037
84037
  this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y);
84038
84038
  }
@@ -84425,9 +84425,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
84425
84425
  const [x0, y0, x1, y1] = group.bbox;
84426
84426
  clip.rect(x0, y0, x1 - x0, y1 - y0);
84427
84427
  if (group.matrix) {
84428
- const path21 = new Path2D();
84429
- path21.addPath(clip, new DOMMatrix(group.matrix));
84430
- clip = path21;
84428
+ const path22 = new Path2D();
84429
+ path22.addPath(clip, new DOMMatrix(group.matrix));
84430
+ clip = path22;
84431
84431
  }
84432
84432
  currentCtx.clip(clip);
84433
84433
  }
@@ -84486,9 +84486,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
84486
84486
  const [x0, y0, x1, y1] = group.bbox;
84487
84487
  clip.rect(x0, y0, x1 - x0, y1 - y0);
84488
84488
  if (group.matrix) {
84489
- const path21 = new Path2D();
84490
- path21.addPath(clip, new DOMMatrix(group.matrix));
84491
- clip = path21;
84489
+ const path22 = new Path2D();
84490
+ path22.addPath(clip, new DOMMatrix(group.matrix));
84491
+ clip = path22;
84492
84492
  }
84493
84493
  groupCtx.clip(clip);
84494
84494
  }
@@ -85023,7 +85023,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
85023
85023
  }
85024
85024
  endCompat(opIdx) {
85025
85025
  }
85026
- consumePath(opIdx, path21, clipBox) {
85026
+ consumePath(opIdx, path22, clipBox) {
85027
85027
  const isEmpty = this.current.isEmptyClip();
85028
85028
  if (this.pendingClip) {
85029
85029
  this.current.updateClipFromPath();
@@ -85035,9 +85035,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
85035
85035
  if (this.pendingClip) {
85036
85036
  if (!isEmpty) {
85037
85037
  if (this.pendingClip === EO_CLIP) {
85038
- ctx.clip(path21, "evenodd");
85038
+ ctx.clip(path22, "evenodd");
85039
85039
  } else {
85040
- ctx.clip(path21);
85040
+ ctx.clip(path22);
85041
85041
  }
85042
85042
  }
85043
85043
  this.pendingClip = null;
@@ -85106,7 +85106,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
85106
85106
  }
85107
85107
  return this._cachedScaleForStroking;
85108
85108
  }
85109
- rescaleAndStroke(path21, saveRestore) {
85109
+ rescaleAndStroke(path22, saveRestore) {
85110
85110
  const {
85111
85111
  ctx,
85112
85112
  current: {
@@ -85116,7 +85116,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
85116
85116
  const [scaleX, scaleY] = this.getScaleForStroking();
85117
85117
  if (scaleX === scaleY) {
85118
85118
  ctx.lineWidth = (lineWidth || 1) * scaleX;
85119
- ctx.stroke(path21);
85119
+ ctx.stroke(path22);
85120
85120
  return;
85121
85121
  }
85122
85122
  const SCALE_MATRIX = _CanvasGraphics.#SCALE_MATRIX ??= new DOMMatrix();
@@ -85128,7 +85128,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
85128
85128
  SCALE_MATRIX.a = 1 / scaleX;
85129
85129
  SCALE_MATRIX.d = 1 / scaleY;
85130
85130
  const newPath = new Path2D();
85131
- newPath.addPath(path21, SCALE_MATRIX);
85131
+ newPath.addPath(path22, SCALE_MATRIX);
85132
85132
  if (dashes.length > 0) {
85133
85133
  const scale = Math.max(scaleX, scaleY);
85134
85134
  ctx.setLineDash(dashes.map((x) => x / scale));
@@ -85852,8 +85852,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
85852
85852
  url
85853
85853
  } = stream._source;
85854
85854
  this._isStreamingSupported = !disableStream;
85855
- const fs19 = process.getBuiltinModule("fs/promises");
85856
- fs19.lstat(url).then((stat) => {
85855
+ const fs20 = process.getBuiltinModule("fs/promises");
85856
+ fs20.lstat(url).then((stat) => {
85857
85857
  const readableStream = getReadableStream(url);
85858
85858
  this._reader = readableStream.getReader();
85859
85859
  const {
@@ -96324,11 +96324,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
96324
96324
  };
96325
96325
  ContourDrawOutline = class extends InkDrawOutline {
96326
96326
  toSVGPath() {
96327
- let path21 = super.toSVGPath();
96328
- if (!path21.endsWith("Z")) {
96329
- path21 += "Z";
96327
+ let path22 = super.toSVGPath();
96328
+ if (!path22.endsWith("Z")) {
96329
+ path22 += "Z";
96330
96330
  }
96331
- return path21;
96331
+ return path22;
96332
96332
  }
96333
96333
  };
96334
96334
  es_uint8_array_from_base64_namespaceFn2();
@@ -99010,7 +99010,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
99010
99010
  }
99011
99011
  const drawLayer = textLayerData.drawLayer;
99012
99012
  let div = textLayerData.selectionDiv;
99013
- let path21 = textLayerData.path;
99013
+ let path22 = textLayerData.path;
99014
99014
  if (!div) {
99015
99015
  const clipPathId = `clip_selection_${_DrawLayer.#selectionId++}`;
99016
99016
  div = document.createElement("div");
@@ -99029,18 +99029,18 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
99029
99029
  const clipPath = _DrawLayer._svgFactory.createElement("clipPath");
99030
99030
  clipPath.setAttribute("id", clipPathId);
99031
99031
  clipPath.setAttribute("clipPathUnits", "objectBoundingBox");
99032
- path21 = _DrawLayer._svgFactory.createElement("path");
99033
- clipPath.append(path21);
99032
+ path22 = _DrawLayer._svgFactory.createElement("path");
99033
+ clipPath.append(path22);
99034
99034
  svg.append(clipPath);
99035
99035
  div.append(svg);
99036
- textLayerData.path = path21;
99036
+ textLayerData.path = path22;
99037
99037
  textLayerData.selectionDiv = div;
99038
99038
  }
99039
99039
  if (drawLayer.#parent && div.parentNode !== drawLayer.#parent) {
99040
99040
  drawLayer.#parent.append(div);
99041
99041
  this.#selections.add(div);
99042
99042
  }
99043
- path21.setAttribute("d", boxes.join(" "));
99043
+ path22.setAttribute("d", boxes.join(" "));
99044
99044
  }
99045
99045
  }
99046
99046
  static get _svgFactory() {
@@ -99087,13 +99087,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
99087
99087
  const root2 = this.#createSVG();
99088
99088
  const defs = _DrawLayer._svgFactory.createElement("defs");
99089
99089
  root2.append(defs);
99090
- const path21 = _DrawLayer._svgFactory.createElement("path");
99091
- defs.append(path21);
99090
+ const path22 = _DrawLayer._svgFactory.createElement("path");
99091
+ defs.append(path22);
99092
99092
  const pathId = `path_${id}`;
99093
- path21.setAttribute("id", pathId);
99094
- path21.setAttribute("vector-effect", "non-scaling-stroke");
99093
+ path22.setAttribute("id", pathId);
99094
+ path22.setAttribute("vector-effect", "non-scaling-stroke");
99095
99095
  if (isPathUpdatable) {
99096
- this.#toUpdate.set(id, path21);
99096
+ this.#toUpdate.set(id, path22);
99097
99097
  }
99098
99098
  const clipPathId = hasClip ? this.#createClipPath(defs, pathId) : null;
99099
99099
  const use = _DrawLayer._svgFactory.createElement("use");
@@ -99111,11 +99111,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
99111
99111
  const root2 = this.#createSVG();
99112
99112
  const defs = _DrawLayer._svgFactory.createElement("defs");
99113
99113
  root2.append(defs);
99114
- const path21 = _DrawLayer._svgFactory.createElement("path");
99115
- defs.append(path21);
99114
+ const path22 = _DrawLayer._svgFactory.createElement("path");
99115
+ defs.append(path22);
99116
99116
  const pathId = `path_${id}`;
99117
- path21.setAttribute("id", pathId);
99118
- path21.setAttribute("vector-effect", "non-scaling-stroke");
99117
+ path22.setAttribute("id", pathId);
99118
+ path22.setAttribute("vector-effect", "non-scaling-stroke");
99119
99119
  let maskId;
99120
99120
  if (mustRemoveSelfIntersections) {
99121
99121
  const mask = _DrawLayer._svgFactory.createElement("mask");
@@ -99162,7 +99162,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
99162
99162
  root: root2,
99163
99163
  bbox,
99164
99164
  rootClass,
99165
- path: path21
99165
+ path: path22
99166
99166
  } = properties;
99167
99167
  const element = typeof elementOrId === "number" ? this.#mapping.get(elementOrId) : elementOrId;
99168
99168
  if (!element) {
@@ -99182,10 +99182,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
99182
99182
  classList.toggle(className, value);
99183
99183
  }
99184
99184
  }
99185
- if (path21) {
99185
+ if (path22) {
99186
99186
  const defs = element.firstElementChild;
99187
99187
  const pathElement = defs.firstElementChild;
99188
- this.#updateProperties(pathElement, path21);
99188
+ this.#updateProperties(pathElement, path22);
99189
99189
  }
99190
99190
  }
99191
99191
  updateParent(id, layer) {
@@ -99492,11 +99492,11 @@ var require_extend = __commonJS({
99492
99492
  });
99493
99493
 
99494
99494
  // ../server/src/piOutpostTools.ts
99495
- import fs18 from "node:fs/promises";
99495
+ import fs19 from "node:fs/promises";
99496
99496
 
99497
99497
  // ../server/src/docxTool.ts
99498
- import fs16 from "node:fs/promises";
99499
- import path19 from "node:path";
99498
+ import fs17 from "node:fs/promises";
99499
+ import path20 from "node:path";
99500
99500
 
99501
99501
  // ../node_modules/typebox/build/system/memory/memory.mjs
99502
99502
  var memory_exports = {};
@@ -104621,16 +104621,21 @@ function renderSpans(spans) {
104621
104621
  for (const span of spans) {
104622
104622
  if (span.text === "") continue;
104623
104623
  const last = merged[merged.length - 1];
104624
- if (last !== void 0 && last.format === span.format) last.text += span.text;
104625
- else merged.push({ text: span.text, format: span.format });
104624
+ if (last !== void 0 && mergeable(last, span)) last.text += span.text;
104625
+ else merged.push({ ...span });
104626
104626
  }
104627
104627
  return merged.map((span) => {
104628
- if (span.format === 0) return span.text;
104628
+ if (span.raw === true || span.format === 0 && span.revision === void 0) return span.text;
104629
104629
  const match = /^(\s*)([\s\S]*?)(\s*)$/.exec(span.text);
104630
104630
  if (match === null || match[2] === "") return span.text;
104631
- return match[1] + wrapSpan(match[2], span.format) + match[3];
104631
+ const formatted = wrapSpan(match[2], span.format);
104632
+ const wrapped = span.revision === void 0 ? formatted : span.revision.open + formatted + span.revision.close;
104633
+ return match[1] + wrapped + match[3];
104632
104634
  }).join("");
104633
104635
  }
104636
+ function mergeable(a, b) {
104637
+ return a.raw !== true && b.raw !== true && a.format === b.format && a.revision?.open === b.revision?.open && a.revision?.close === b.revision?.close;
104638
+ }
104634
104639
  function countStruckSpans(markdown) {
104635
104640
  return Math.floor((markdown.match(/~~/g)?.length ?? 0) / 2);
104636
104641
  }
@@ -104978,6 +104983,8 @@ var MAX_ZIP_ENTRIES = 512;
104978
104983
  var MAX_PART_BYTES = 64 * 1024 * 1024;
104979
104984
  var MAX_PARSED_BLOCKS = 5e4;
104980
104985
  var DOCUMENT_PART = "word/document.xml";
104986
+ var COMMENTS_PART = "word/comments.xml";
104987
+ var COMMENTS_EXTENDED_PART = "word/commentsExtended.xml";
104981
104988
  var CONTENT_TYPES = "[Content_Types].xml";
104982
104989
  var OLE_MAGIC = Buffer.from([208, 207, 17, 224]);
104983
104990
  function toggleOn(value) {
@@ -104996,20 +105003,44 @@ function headingLevel(styleId, outlineLevel) {
104996
105003
  }
104997
105004
  return void 0;
104998
105005
  }
104999
- function parseBody(xml, deadline, pictureMarkerFor) {
105006
+ var sentinel = (payload) => `${payload}`;
105007
+ var INSERT_OPEN = sentinel("I");
105008
+ var INSERT_CLOSE = sentinel("i");
105009
+ var DELETE_OPEN = sentinel("D");
105010
+ var DELETE_CLOSE = sentinel("d");
105011
+ var ANCHOR_OPEN = sentinel("H");
105012
+ var ANCHOR_CLOSE = sentinel("h");
105013
+ var referenceSentinel = (id) => sentinel(`R${id}`);
105014
+ var CHANGE_RECORD = /^w:\w+(?:Pr|PrEx|Grid)Change$/;
105015
+ var REVISION_PRECEDENCE = ["del", "moveFrom", "moveTo", "ins"];
105016
+ function parseBody(xml, deadline, pictureMarkerFor, review) {
105000
105017
  const blocks = [];
105018
+ const show = review?.show === true;
105001
105019
  let paragraph2 = [];
105002
105020
  let paragraphHeading;
105003
105021
  let styleId;
105004
105022
  let outlineLevel;
105023
+ let paragraphDepth = 0;
105005
105024
  let tableDepth = 0;
105006
105025
  let rows = [];
105007
105026
  let row = [];
105008
105027
  let cell = [];
105009
105028
  let inCell = false;
105010
- let deletionDepth = 0;
105029
+ let rowPropertiesDepth = 0;
105030
+ let rowDeleted = false;
105031
+ let rowRevision;
105011
105032
  let textTarget = null;
105033
+ let textRevision;
105012
105034
  let events = 0;
105035
+ let changeRecordDepth = 0;
105036
+ const revisions = [];
105037
+ let revisionSerial = 0;
105038
+ let moveFromName;
105039
+ let moveToName;
105040
+ let group;
105041
+ let groupSerial = 0;
105042
+ const openComments = /* @__PURE__ */ new Set();
105043
+ const rangedComments = /* @__PURE__ */ new Set();
105013
105044
  let runFormat = 0;
105014
105045
  let runPropertiesDepth = 0;
105015
105046
  let paragraphPropertiesDepth = 0;
@@ -105022,24 +105053,185 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105022
105053
  if (toggleOn(value)) runFormat |= flag;
105023
105054
  else runFormat &= ~flag;
105024
105055
  };
105056
+ const target = () => inCell ? cell : paragraph2;
105057
+ const blockNumber = () => blocks.length + 1;
105058
+ const effectiveRevision = () => {
105059
+ if (rowRevision?.kind === "del") return rowRevision;
105060
+ let found;
105061
+ search: for (const kind of REVISION_PRECEDENCE) {
105062
+ for (let index4 = revisions.length - 1; index4 >= 0; index4--) {
105063
+ if (revisions[index4].kind === kind) {
105064
+ found = revisions[index4];
105065
+ break search;
105066
+ }
105067
+ }
105068
+ }
105069
+ return found?.kind === "ins" && rowRevision !== void 0 ? rowRevision : found;
105070
+ };
105071
+ const removes = (revision) => revision?.kind === "del" || revision?.kind === "moveFrom";
105072
+ const referenceFor = (layer, revision) => {
105073
+ let id;
105074
+ if (revision.row !== void 0) {
105075
+ revision.row.id ??= `r:${++groupSerial}`;
105076
+ id = revision.row.id;
105077
+ group = void 0;
105078
+ } else if (revision.kind === "moveFrom" || revision.kind === "moveTo") {
105079
+ id = revision.name !== void 0 ? `m:${revision.name}` : `m:#${revision.serial}`;
105080
+ group = void 0;
105081
+ } else {
105082
+ const key = `${revision.kind}\0${revision.author ?? ""}\0${revision.date ?? ""}`;
105083
+ if (group === void 0 || group.key !== key) group = { key, id: `r:${++groupSerial}` };
105084
+ id = group.id;
105085
+ }
105086
+ if (!layer.entries.has(id)) {
105087
+ layer.entries.set(id, {
105088
+ kind: revision.kind === "ins" ? "insertion" : revision.kind === "del" ? "deletion" : "move",
105089
+ ...revision.author !== void 0 ? { author: revision.author } : {},
105090
+ ...revision.date !== void 0 ? { date: revision.date } : {},
105091
+ visible: false,
105092
+ ...revision.row !== void 0 ? { row: true } : {}
105093
+ });
105094
+ }
105095
+ return id;
105096
+ };
105097
+ const note = (text7, revision) => {
105098
+ if (review === void 0) return void 0;
105099
+ if (revision === void 0) {
105100
+ if (text7 !== "") group = void 0;
105101
+ return void 0;
105102
+ }
105103
+ const id = referenceFor(review, revision);
105104
+ const entry = review.entries.get(id);
105105
+ if (/\S/.test(text7)) {
105106
+ entry.visible = true;
105107
+ if (revision.kind === "moveTo") entry.toBlock ??= blockNumber();
105108
+ else entry.block ??= blockNumber();
105109
+ }
105110
+ return removes(revision) ? { open: DELETE_OPEN, close: DELETE_CLOSE + referenceSentinel(id) } : { open: INSERT_OPEN, close: INSERT_CLOSE + referenceSentinel(id) };
105111
+ };
105112
+ const emit = (raw, revision) => {
105113
+ const text7 = show ? raw.replace(/[\u0001\u0002]/g, "") : raw;
105114
+ const markers = note(text7, revision);
105115
+ target().push(show && markers !== void 0 ? { text: text7, format: runFormat, revision: markers } : { text: text7, format: runFormat });
105116
+ };
105117
+ const pushRaw = (text7) => target().push({ text: text7, format: 0, raw: true });
105118
+ const noteComment = (layer, id) => {
105119
+ const key = `c:${id}`;
105120
+ const entry = layer.entries.get(key);
105121
+ if (entry === void 0) layer.entries.set(key, { kind: "comment", visible: true, block: blockNumber() });
105122
+ };
105123
+ const appendToLastBlock = (text7) => {
105124
+ const last = blocks[blocks.length - 1];
105125
+ if (last === void 0) return;
105126
+ if (last.kind === "paragraph") last.text += text7;
105127
+ else {
105128
+ const lastRow = last.rows[last.rows.length - 1];
105129
+ if (lastRow !== void 0 && lastRow.length > 0) lastRow[lastRow.length - 1] += text7;
105130
+ }
105131
+ };
105025
105132
  const flushParagraph = () => {
105026
105133
  const text7 = renderSpans(paragraph2).replace(/\s+/g, " ").trim();
105027
- paragraph2 = [];
105028
105134
  const heading3 = paragraphHeading;
105135
+ const plain = show && heading3 !== void 0 ? acceptedText(paragraph2) : void 0;
105136
+ paragraph2 = [];
105029
105137
  paragraphHeading = void 0;
105030
105138
  styleId = void 0;
105031
105139
  outlineLevel = void 0;
105032
105140
  if (text7 === "") return;
105033
- blocks.push(heading3 === void 0 ? { kind: "paragraph", text: text7 } : { kind: "paragraph", text: text7, heading: heading3 });
105141
+ blocks.push({
105142
+ kind: "paragraph",
105143
+ text: text7,
105144
+ ...heading3 !== void 0 ? { heading: heading3 } : {},
105145
+ ...plain !== void 0 ? { plain } : {}
105146
+ });
105034
105147
  };
105035
105148
  scanXml(xml, (event) => {
105036
105149
  if (++events % 2e3 === 0) deadline?.();
105037
105150
  if (blocks.length > MAX_PARSED_BLOCKS) return false;
105151
+ if (changeRecordDepth > 0) {
105152
+ if (event.kind === "open" && !event.selfClosing && CHANGE_RECORD.test(event.name)) changeRecordDepth++;
105153
+ else if (event.kind === "close" && CHANGE_RECORD.test(event.name)) changeRecordDepth--;
105154
+ return;
105155
+ }
105038
105156
  if (event.kind === "open") {
105157
+ if (CHANGE_RECORD.test(event.name)) {
105158
+ if (!event.selfClosing) changeRecordDepth = 1;
105159
+ return;
105160
+ }
105039
105161
  switch (event.name) {
105162
+ case "w:ins":
105040
105163
  case "w:del":
105041
- deletionDepth++;
105164
+ case "w:moveFrom":
105165
+ case "w:moveTo": {
105166
+ if (event.selfClosing) {
105167
+ if (rowPropertiesDepth > 0 && (event.name === "w:del" || event.name === "w:ins")) {
105168
+ if (event.name === "w:del") rowDeleted = true;
105169
+ const author2 = event.attributes["w:author"];
105170
+ const date2 = event.attributes["w:date"];
105171
+ rowRevision = {
105172
+ kind: event.name === "w:del" ? "del" : "ins",
105173
+ ...author2 !== void 0 ? { author: author2 } : {},
105174
+ ...date2 !== void 0 ? { date: date2 } : {},
105175
+ row: {},
105176
+ serial: ++revisionSerial
105177
+ };
105178
+ revisions.push(rowRevision);
105179
+ }
105180
+ return;
105181
+ }
105182
+ const kind = event.name.slice(2);
105183
+ const author = event.attributes["w:author"];
105184
+ const date = event.attributes["w:date"];
105185
+ const name = kind === "moveFrom" ? moveFromName : kind === "moveTo" ? moveToName : void 0;
105186
+ revisions.push({
105187
+ kind,
105188
+ ...author !== void 0 ? { author } : {},
105189
+ ...date !== void 0 ? { date } : {},
105190
+ ...name !== void 0 ? { name } : {},
105191
+ serial: ++revisionSerial
105192
+ });
105042
105193
  break;
105194
+ }
105195
+ case "w:moveFromRangeStart":
105196
+ moveFromName = event.attributes["w:name"];
105197
+ break;
105198
+ case "w:moveToRangeStart":
105199
+ moveToName = event.attributes["w:name"];
105200
+ break;
105201
+ case "w:moveFromRangeEnd":
105202
+ moveFromName = void 0;
105203
+ break;
105204
+ case "w:moveToRangeEnd":
105205
+ moveToName = void 0;
105206
+ break;
105207
+ case "w:commentRangeStart": {
105208
+ const id = event.attributes["w:id"];
105209
+ if (review === void 0 || id === void 0 || review.replies.has(id)) break;
105210
+ rangedComments.add(id);
105211
+ noteComment(review, id);
105212
+ if (show && openComments.size === 0 && paragraphDepth > 0) pushRaw(ANCHOR_OPEN);
105213
+ openComments.add(id);
105214
+ break;
105215
+ }
105216
+ case "w:commentRangeEnd": {
105217
+ const id = event.attributes["w:id"];
105218
+ if (id === void 0 || !openComments.delete(id)) break;
105219
+ if (!show) break;
105220
+ if (paragraphDepth > 0) {
105221
+ if (openComments.size === 0) pushRaw(ANCHOR_CLOSE);
105222
+ pushRaw(referenceSentinel(`c:${id}`));
105223
+ } else {
105224
+ appendToLastBlock(referenceSentinel(`c:${id}`));
105225
+ }
105226
+ break;
105227
+ }
105228
+ case "w:commentReference": {
105229
+ const id = event.attributes["w:id"];
105230
+ if (review === void 0 || id === void 0 || review.replies.has(id) || rangedComments.has(id)) break;
105231
+ noteComment(review, id);
105232
+ if (show) pushRaw(referenceSentinel(`c:${id}`));
105233
+ break;
105234
+ }
105043
105235
  case "w:tbl":
105044
105236
  if (tableDepth === 0) {
105045
105237
  flushParagraph();
@@ -105048,7 +105240,13 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105048
105240
  tableDepth++;
105049
105241
  break;
105050
105242
  case "w:tr":
105051
- if (tableDepth === 1) row = [];
105243
+ if (tableDepth === 1) {
105244
+ row = [];
105245
+ rowDeleted = false;
105246
+ }
105247
+ break;
105248
+ case "w:trPr":
105249
+ if (tableDepth === 1) rowPropertiesDepth++;
105052
105250
  break;
105053
105251
  case "w:tc":
105054
105252
  if (tableDepth === 1) {
@@ -105057,10 +105255,12 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105057
105255
  }
105058
105256
  break;
105059
105257
  case "w:p":
105258
+ paragraphDepth++;
105060
105259
  if (!inCell) {
105061
105260
  paragraph2 = [];
105062
105261
  paragraphHeading = void 0;
105063
105262
  }
105263
+ if (show && openComments.size > 0) pushRaw(ANCHOR_OPEN);
105064
105264
  break;
105065
105265
  case "w:pStyle":
105066
105266
  styleId = event.attributes["w:val"];
@@ -105088,8 +105288,17 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105088
105288
  applyToggle(ITALIC, event.attributes["w:val"]);
105089
105289
  break;
105090
105290
  case "w:t":
105091
- if (deletionDepth === 0) textTarget = inCell ? "cell" : "paragraph";
105291
+ case "w:delText": {
105292
+ const revision = effectiveRevision();
105293
+ if (removes(revision) ? show : event.name === "w:t") {
105294
+ textTarget = inCell ? "cell" : "paragraph";
105295
+ textRevision = revision;
105296
+ } else if (removes(revision)) {
105297
+ textTarget = "count";
105298
+ textRevision = revision;
105299
+ }
105092
105300
  break;
105301
+ }
105093
105302
  case "w:drawing":
105094
105303
  case "w:pict":
105095
105304
  drawingDepth++;
@@ -105110,12 +105319,12 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105110
105319
  if (drawingDepth > 0) pictureRel ??= event.attributes["r:id"];
105111
105320
  break;
105112
105321
  case "w:tab":
105113
- (inCell ? cell : paragraph2).push({ text: " ", format: runFormat });
105114
- break;
105115
105322
  case "w:br":
105116
- case "w:cr":
105117
- (inCell ? cell : paragraph2).push({ text: " ", format: runFormat });
105323
+ case "w:cr": {
105324
+ const revision = effectiveRevision();
105325
+ if (!removes(revision) || show) emit(" ", revision);
105118
105326
  break;
105327
+ }
105119
105328
  default:
105120
105329
  break;
105121
105330
  }
@@ -105123,8 +105332,8 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105123
105332
  return;
105124
105333
  }
105125
105334
  if (event.kind === "text") {
105126
- if (textTarget === "paragraph") paragraph2.push({ text: event.text, format: runFormat });
105127
- else if (textTarget === "cell") cell.push({ text: event.text, format: runFormat });
105335
+ if (textTarget === "count") note(event.text, textRevision);
105336
+ else if (textTarget !== null) emit(event.text, textRevision);
105128
105337
  return;
105129
105338
  }
105130
105339
  closeElement(event.name);
@@ -105132,17 +105341,32 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105132
105341
  function closeElement(name) {
105133
105342
  switch (name) {
105134
105343
  case "w:t":
105344
+ case "w:delText":
105135
105345
  textTarget = null;
105346
+ textRevision = void 0;
105136
105347
  break;
105348
+ case "w:ins":
105137
105349
  case "w:del":
105138
- if (deletionDepth > 0) deletionDepth--;
105350
+ case "w:moveFrom":
105351
+ case "w:moveTo": {
105352
+ const kind = name.slice(2);
105353
+ for (let index4 = revisions.length - 1; index4 >= 0; index4--) {
105354
+ if (revisions[index4].kind === kind) {
105355
+ revisions.splice(index4, 1);
105356
+ break;
105357
+ }
105358
+ }
105139
105359
  break;
105360
+ }
105140
105361
  case "w:pPr":
105141
105362
  if (paragraphPropertiesDepth > 0) paragraphPropertiesDepth--;
105142
105363
  break;
105143
105364
  case "w:rPr":
105144
105365
  if (paragraphPropertiesDepth === 0 && runPropertiesDepth > 0) runPropertiesDepth--;
105145
105366
  break;
105367
+ case "w:trPr":
105368
+ if (rowPropertiesDepth > 0) rowPropertiesDepth--;
105369
+ break;
105146
105370
  case "w:drawing":
105147
105371
  case "w:pict":
105148
105372
  if (drawingDepth > 0) drawingDepth--;
@@ -105164,6 +105388,9 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105164
105388
  runFormat = 0;
105165
105389
  break;
105166
105390
  case "w:p":
105391
+ if (paragraphDepth > 0) paragraphDepth--;
105392
+ if (show && openComments.size > 0) pushRaw(ANCHOR_CLOSE);
105393
+ group = void 0;
105167
105394
  if (inCell) cell.push({ text: " ", format: 0 });
105168
105395
  else {
105169
105396
  paragraphHeading = headingLevel(styleId, outlineLevel);
@@ -105177,7 +105404,11 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105177
105404
  }
105178
105405
  break;
105179
105406
  case "w:tr":
105180
- if (tableDepth === 1) rows.push(row);
105407
+ if (tableDepth === 1 && !(rowDeleted && !show)) rows.push(row);
105408
+ if (tableDepth === 1 && rowRevision !== void 0) {
105409
+ revisions.splice(revisions.indexOf(rowRevision), 1);
105410
+ rowRevision = void 0;
105411
+ }
105181
105412
  break;
105182
105413
  case "w:tbl":
105183
105414
  tableDepth--;
@@ -105198,6 +105429,182 @@ function parseBody(xml, deadline, pictureMarkerFor) {
105198
105429
  flushParagraph();
105199
105430
  return blocks;
105200
105431
  }
105432
+ function acceptedText(spans) {
105433
+ return spans.filter((span) => span.raw !== true && span.revision?.open !== DELETE_OPEN).map((span) => span.text).join("").replace(/\s+/g, " ").trim();
105434
+ }
105435
+ function parseComments(commentsXml, extendedXml) {
105436
+ const comments = /* @__PURE__ */ new Map();
105437
+ if (commentsXml === void 0) return comments;
105438
+ const lastParagraphOf = /* @__PURE__ */ new Map();
105439
+ let current;
105440
+ let text7 = "";
105441
+ let inText = false;
105442
+ let deletionDepth = 0;
105443
+ scanXml(commentsXml, (event) => {
105444
+ if (event.kind === "text") {
105445
+ if (inText) text7 += event.text;
105446
+ return;
105447
+ }
105448
+ const opening = event.kind === "open";
105449
+ switch (event.name) {
105450
+ case "w:comment":
105451
+ if (opening && !event.selfClosing) {
105452
+ const { "w:id": id, "w:author": author, "w:date": date } = event.attributes;
105453
+ current = id === void 0 ? void 0 : { id, ...author ? { author } : {}, ...date ? { date } : {}, paragraphs: [] };
105454
+ } else if (current !== void 0) {
105455
+ const { paragraphs, ...rest } = current;
105456
+ comments.set(current.id, { ...rest, text: paragraphs.filter((piece) => piece !== "").join(" / ") });
105457
+ current = void 0;
105458
+ }
105459
+ break;
105460
+ case "w:p":
105461
+ if (opening) {
105462
+ text7 = "";
105463
+ const paraId = event.attributes["w14:paraId"];
105464
+ if (current !== void 0 && paraId !== void 0) lastParagraphOf.set(current.id, paraId);
105465
+ }
105466
+ if (!opening || event.selfClosing) current?.paragraphs.push(text7.replace(/\s+/g, " ").trim());
105467
+ break;
105468
+ case "w:del":
105469
+ if (opening && !event.selfClosing) deletionDepth++;
105470
+ else if (!opening && deletionDepth > 0) deletionDepth--;
105471
+ break;
105472
+ case "w:t":
105473
+ inText = opening && !event.selfClosing && deletionDepth === 0;
105474
+ break;
105475
+ case "w:tab":
105476
+ case "w:br":
105477
+ if (opening) text7 += " ";
105478
+ break;
105479
+ default:
105480
+ break;
105481
+ }
105482
+ });
105483
+ if (extendedXml === void 0) return comments;
105484
+ const extended = /* @__PURE__ */ new Map();
105485
+ scanXml(extendedXml, (event) => {
105486
+ if (event.kind !== "open" || event.name !== "w15:commentEx") return;
105487
+ const paraId = event.attributes["w15:paraId"];
105488
+ if (paraId === void 0) return;
105489
+ const parent = event.attributes["w15:paraIdParent"];
105490
+ extended.set(paraId, { ...parent !== void 0 ? { parent } : {}, done: event.attributes["w15:done"] === "1" });
105491
+ });
105492
+ const byParagraph = new Map([...lastParagraphOf].map(([id, paraId]) => [paraId, id]));
105493
+ for (const comment of comments.values()) {
105494
+ const paraId = lastParagraphOf.get(comment.id);
105495
+ const record = paraId === void 0 ? void 0 : extended.get(paraId);
105496
+ if (record === void 0) continue;
105497
+ comment.done = record.done;
105498
+ if (record.parent !== void 0) {
105499
+ const parentId = byParagraph.get(record.parent);
105500
+ if (parentId !== void 0 && parentId !== comment.id) comment.parentId = parentId;
105501
+ }
105502
+ }
105503
+ for (const comment of comments.values()) {
105504
+ const seen = /* @__PURE__ */ new Set([comment.id]);
105505
+ let parent = comment.parentId === void 0 ? void 0 : comments.get(comment.parentId);
105506
+ while (parent?.parentId !== void 0 && !seen.has(parent.parentId)) {
105507
+ seen.add(parent.id);
105508
+ parent = comments.get(parent.parentId);
105509
+ }
105510
+ if (parent !== void 0) comment.parentId = parent.id;
105511
+ }
105512
+ return comments;
105513
+ }
105514
+ var SENTINELS = /\u0001([^\u0002]*)\u0002/g;
105515
+ var SENTINEL_SYNTAX = { I: "{++", i: "++}", D: "{--", d: "--}", H: "{==", h: "==}" };
105516
+ function numberReferences(blocks) {
105517
+ const labels = /* @__PURE__ */ new Map();
105518
+ const counters = { r: 0, m: 0, c: 0 };
105519
+ const visit2 = (text7) => {
105520
+ for (const match of text7.matchAll(SENTINELS)) {
105521
+ const payload = match[1];
105522
+ if (!payload.startsWith("R")) continue;
105523
+ const id = payload.slice(1);
105524
+ if (labels.has(id)) continue;
105525
+ const prefix = id[0];
105526
+ counters[prefix] = (counters[prefix] ?? 0) + 1;
105527
+ labels.set(id, `${prefix}${counters[prefix]}`);
105528
+ }
105529
+ };
105530
+ for (const block of blocks) {
105531
+ if (block.kind === "paragraph") visit2(block.text);
105532
+ else for (const row of block.rows) for (const value of row) visit2(value);
105533
+ }
105534
+ return labels;
105535
+ }
105536
+ function escapeForgedMarkers(text7) {
105537
+ return text7.replace(/\{(?=\+\+|--|==)/g, "\\{").replace(/(\+\+|--|==)\}/g, "$1\\}").replace(/\[(?=[rmc]\d+\])/g, "\\[");
105538
+ }
105539
+ function resolveSentinels(text7, labels) {
105540
+ const references = [];
105541
+ const tidied = text7.replace(/\u0001H\u0002(\s*)\u0001h\u0002/g, "$1");
105542
+ const resolved = escapeForgedMarkers(tidied).replace(SENTINELS, (_, payload) => {
105543
+ if (!payload.startsWith("R")) return SENTINEL_SYNTAX[payload] ?? "";
105544
+ const id = payload.slice(1);
105545
+ references.push(id);
105546
+ return `[${labels.get(id) ?? "?"}]`;
105547
+ });
105548
+ return { text: resolved, references };
105549
+ }
105550
+ function headingPaths(blocks) {
105551
+ const stack = [];
105552
+ return blocks.map((block) => {
105553
+ if (block.kind === "paragraph" && block.heading !== void 0) {
105554
+ while (stack.length > 0 && stack[stack.length - 1].level >= block.heading) stack.pop();
105555
+ stack.push({ level: block.heading, text: block.plain ?? block.text });
105556
+ }
105557
+ return stack.map((entry) => entry.text);
105558
+ });
105559
+ }
105560
+ var plural = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
105561
+ function dayOf(date) {
105562
+ if (date === void 0) return void 0;
105563
+ return /^\d{4}-\d{2}-\d{2}/.test(date) ? date.slice(0, 10) : date;
105564
+ }
105565
+ function attribution(author, date) {
105566
+ return `${author ?? "author not recorded"}, ${dayOf(date) ?? "date not recorded"}`;
105567
+ }
105568
+ var listed = (text7) => escapeForgedMarkers(text7.replace(/[\u0001\u0002]/g, ""));
105569
+ function reviewList(references, layer, labels, paths, comments) {
105570
+ const where = (block) => {
105571
+ const path22 = block === void 0 ? void 0 : paths[block - 1];
105572
+ return path22 === void 0 || path22.length === 0 ? "before the first heading" : path22.map(listed).join(" > ");
105573
+ };
105574
+ const lines = ["---", "Review layer, in document order:"];
105575
+ for (const id of references) {
105576
+ const entry = layer.entries.get(id);
105577
+ const label = labels.get(id);
105578
+ if (entry === void 0 || label === void 0) continue;
105579
+ if (entry.kind === "comment") {
105580
+ const comment = comments.get(id.slice(2));
105581
+ const state2 = comment?.done === true ? "resolved" : comment?.done === false ? "open" : "resolved state not recorded";
105582
+ lines.push(
105583
+ `- [${label}] comment, ${state2} \u2014 ${attribution(comment?.author, comment?.date)} \u2014 ${where(entry.block)}: \xAB ${listed(comment?.text ?? "")} \xBB`
105584
+ );
105585
+ for (const reply of comments.values()) {
105586
+ if (reply.parentId !== id.slice(2)) continue;
105587
+ lines.push(` - reply \u2014 ${attribution(reply.author, reply.date)}: \xAB ${listed(reply.text)} \xBB`);
105588
+ }
105589
+ } else if (entry.kind === "move") {
105590
+ lines.push(`- [${label}] moved \u2014 ${attribution(entry.author, entry.date)} \u2014 from ${where(entry.block)} to ${where(entry.toBlock)}`);
105591
+ } else {
105592
+ const kind = entry.row === true ? `table row ${entry.kind}` : entry.kind;
105593
+ lines.push(`- [${label}] ${kind} \u2014 ${attribution(entry.author, entry.date)} \u2014 ${where(entry.block ?? entry.toBlock)}`);
105594
+ }
105595
+ }
105596
+ return lines.join("\n");
105597
+ }
105598
+ function reviewCounts(layer) {
105599
+ let revisions = 0;
105600
+ let comments = 0;
105601
+ for (const entry of layer.entries.values()) {
105602
+ if (!entry.visible) continue;
105603
+ if (entry.kind === "comment") comments++;
105604
+ else revisions++;
105605
+ }
105606
+ return { revisions, comments };
105607
+ }
105201
105608
  function renderBlock(block, mode) {
105202
105609
  if (block.kind === "table") {
105203
105610
  if (mode === "text") {
@@ -105271,24 +105678,34 @@ async function extractDocx(bytes, options2 = {}) {
105271
105678
  if (documentXml === null) {
105272
105679
  throw new DocxError("unreadable", `This package has no ${DOCUMENT_PART}: it is not a Word document.`);
105273
105680
  }
105681
+ const show = options2.review === true;
105682
+ const comments = readComments(buffer, limits, show);
105683
+ const layer = {
105684
+ show,
105685
+ replies: new Set([...comments.values()].filter((comment) => comment.parentId !== void 0).map((comment) => comment.id)),
105686
+ entries: /* @__PURE__ */ new Map()
105687
+ };
105274
105688
  const pictures = [];
105275
105689
  let blocks;
105276
105690
  try {
105277
105691
  const marker = pictureMarkerIn(buffer, limits, pictures, deadline);
105278
- blocks = parseBody(documentXml.toString("utf8"), deadline, marker);
105692
+ blocks = parseBody(documentXml.toString("utf8"), deadline, marker, layer);
105279
105693
  } catch (error) {
105280
105694
  throw asDocxError(error);
105281
105695
  }
105282
105696
  const blockCount = blocks.length;
105283
105697
  if (blockCount === 0) {
105284
105698
  return {
105285
- markdown: "_This document has no extractable body content._\n\n> Headers, footers, footnotes, comments and text boxes are not read by this tool.",
105699
+ markdown: "_This document has no extractable body content._\n\n" + (show ? "> Headers, footers, footnotes and text boxes are not read by this tool." : "> Headers, footers, footnotes, comments and text boxes are not read by this tool."),
105286
105700
  blocks: [],
105287
105701
  blockCount: 0,
105288
- pictures
105702
+ pictures,
105703
+ ...show ? { review: reviewCounts(layer) } : {}
105289
105704
  };
105290
105705
  }
105291
105706
  const requested = options2.blocks ? parseBlockRange(options2.blocks, blockCount) : rangeTo(blockCount);
105707
+ const labels = show ? numberReferences(blocks) : /* @__PURE__ */ new Map();
105708
+ const shown = [];
105292
105709
  const pieces = [];
105293
105710
  const covered = [];
105294
105711
  let characters = 0;
@@ -105305,7 +105722,12 @@ async function extractDocx(bytes, options2 = {}) {
105305
105722
  break;
105306
105723
  }
105307
105724
  deadline();
105308
- const rendered = renderBlock(blocks[number - 1], mode);
105725
+ let rendered = renderBlock(blocks[number - 1], mode);
105726
+ if (show) {
105727
+ const resolved = resolveSentinels(rendered, labels);
105728
+ rendered = resolved.text;
105729
+ for (const id of resolved.references) if (!shown.includes(id)) shown.push(id);
105730
+ }
105309
105731
  covered.push(number);
105310
105732
  if (rendered === "") continue;
105311
105733
  characters += rendered.length;
@@ -105322,15 +105744,52 @@ async function extractDocx(bytes, options2 = {}) {
105322
105744
  `> Truncated: blocks ${describeBlocks(covered)} of ${blockCount} shown. Call again with blocks="${nextBlock}-${blockCount}" for the rest.`
105323
105745
  );
105324
105746
  }
105325
- const lead = struckThroughNotice(pieces.join("\n\n"));
105747
+ const leads = [struckThroughNotice(pieces.join("\n\n")), reviewNotice(layer, shown, labels)].filter((line) => line !== "");
105748
+ const list3 = show && shown.length > 0 ? [reviewList(shown, layer, labels, headingPaths(blocks), comments)] : [];
105749
+ const markdown = [...leads, ...pieces, ...list3, ...notes].join("\n\n");
105750
+ if (full && markdown.length > ABSOLUTE_MAX_CHARS) {
105751
+ throw new DocxError(
105752
+ "too-large",
105753
+ `This document is larger than the ${ABSOLUTE_MAX_CHARS} character ceiling for a single answer. Extract it to a file with output_path, or ask for a block range.`
105754
+ );
105755
+ }
105326
105756
  return {
105327
- markdown: [...lead ? [lead] : [], ...pieces, ...notes].join("\n\n"),
105757
+ markdown,
105328
105758
  blocks: covered,
105329
105759
  ...nextBlock === void 0 ? {} : { nextBlock },
105330
105760
  blockCount,
105331
- pictures
105761
+ pictures,
105762
+ ...show ? { review: reviewCounts(layer) } : {}
105332
105763
  };
105333
105764
  }
105765
+ function readComments(buffer, limits, review) {
105766
+ try {
105767
+ return parseComments(
105768
+ readZipEntry(buffer, COMMENTS_PART, limits)?.toString("utf8"),
105769
+ readZipEntry(buffer, COMMENTS_EXTENDED_PART, limits)?.toString("utf8")
105770
+ );
105771
+ } catch (error) {
105772
+ if (!review) return /* @__PURE__ */ new Map();
105773
+ const reason = asDocxError(error);
105774
+ throw new DocxError(reason.reason, `This document's comments could not be read: ${reason.message}`);
105775
+ }
105776
+ }
105777
+ function reviewNotice(layer, shown, labels) {
105778
+ const total = reviewCounts(layer);
105779
+ if (!layer.show) {
105780
+ if (total.revisions === 0 && total.comments === 0) return "";
105781
+ return `> This document holds ${plural(total.revisions, "tracked change")} and ${plural(total.comments, "comment")} that this reading does not show: it is the text with every change accepted, deletions left out and insertions read as ordinary text. Pass review: true to see each change and comment where it sits, with its author, date and section.`;
105782
+ }
105783
+ if (total.revisions === 0 && total.comments === 0) {
105784
+ return "> Review reading: this document holds no tracked change or comment; the text below is as written.";
105785
+ }
105786
+ const revisions = shown.filter((id) => !id.startsWith("c:") && labels.has(id)).length;
105787
+ const commentCount = shown.filter((id) => id.startsWith("c:") && labels.has(id)).length;
105788
+ if (revisions === 0 && commentCount === 0) {
105789
+ return "> Review reading: the blocks shown hold no tracked change or comment; other blocks of this document do.";
105790
+ }
105791
+ return `> Review reading: ${plural(revisions, "tracked change")} and ${plural(commentCount, "comment")} are marked below. \`{++text++}\` was inserted and \`{--text--}\` deleted; a moved passage is deleted at its origin and inserted at its destination, both marked with the same \`[mN]\`; \`{==text==}\` is the text a comment is about. Each \`[rN]\`, \`[mN]\` and \`[cN]\` is listed at the end with its author, date and section. Formatting changes are not shown.`;
105792
+ }
105334
105793
  function pictureMarkerIn(buffer, limits, pictures, deadline) {
105335
105794
  let targets;
105336
105795
  return (reference) => {
@@ -105727,10 +106186,10 @@ function heading(comment) {
105727
106186
  function renderComments(pageNumber, page) {
105728
106187
  if (page.comments.length === 0) return "";
105729
106188
  const out = [`### Comments on page ${pageNumber}`, ""];
105730
- let listed = 0;
106189
+ let listed2 = 0;
105731
106190
  const write = (comment, depth) => {
105732
- if (listed >= MAX_COMMENTS_PER_PAGE) return;
105733
- listed++;
106191
+ if (listed2 >= MAX_COMMENTS_PER_PAGE) return;
106192
+ listed2++;
105734
106193
  const indent2 = " ".repeat(depth);
105735
106194
  out.push(`${indent2}- ${heading(comment)}`);
105736
106195
  if (comment.remark !== "") out.push(...quoted(comment.remark, `${indent2} `));
@@ -105741,7 +106200,7 @@ function renderComments(pageNumber, page) {
105741
106200
  }
105742
106201
  };
105743
106202
  for (const comment of page.comments) write(comment, 0);
105744
- if (page.count > listed) out.push(`- _${page.count - listed} more comment${page.count - listed === 1 ? "" : "s"} on this page not listed._`);
106203
+ if (page.count > listed2) out.push(`- _${page.count - listed2} more comment${page.count - listed2 === 1 ? "" : "s"} on this page not listed._`);
105745
106204
  return out.join("\n");
105746
106205
  }
105747
106206
  var UNREADABLE_COMMENTS = "_The comments on this page could not be read._";
@@ -106644,6 +107103,7 @@ var DEFAULT_RENDER_TIMEOUT_MS = 12e4;
106644
107103
 
106645
107104
  // ../server/src/presentationRender.ts
106646
107105
  var RENDERER_NAMES = ["word", "powerpoint", "libreoffice", "onlyoffice"];
107106
+ var HOLD_KILL_MS = 3e4;
106647
107107
  var RenderError = class extends Error {
106648
107108
  constructor(message) {
106649
107109
  super(message);
@@ -106651,28 +107111,55 @@ var RenderError = class extends Error {
106651
107111
  }
106652
107112
  };
106653
107113
  var defaultRunner = (file, args, options2) => new Promise((resolve) => {
106654
- execFile(
106655
- file,
106656
- args,
106657
- // The signal is the turn's: a user who stops the agent must not leave an office
106658
- // application converting in the background for minutes.
106659
- { env: options2.env, timeout: options2.timeoutMs, windowsHide: true, maxBuffer: 4 * 1024 * 1024, ...options2.signal ? { signal: options2.signal } : {} },
106660
- (error, stdout, stderr) => {
106661
- const failure = error;
106662
- resolve({
106663
- code: failure === null ? 0 : typeof failure.code === "number" ? failure.code : null,
106664
- stdout: String(stdout ?? ""),
106665
- stderr: String(stderr ?? "") || (failure !== null && typeof failure.code === "string" ? `${failure.code}: ${failure.message}` : ""),
106666
- timedOut: failure?.killed === true
106667
- });
107114
+ const { signal, holdKillUntil } = options2;
107115
+ let timedOut = false;
107116
+ let seen = "";
107117
+ let held = false;
107118
+ let grace;
107119
+ const child2 = execFile(file, args, { env: options2.env, windowsHide: true, maxBuffer: 4 * 1024 * 1024 }, (error, stdout, stderr) => {
107120
+ clearTimeout(timer);
107121
+ clearTimeout(grace);
107122
+ signal?.removeEventListener("abort", stop);
107123
+ const failure = error;
107124
+ resolve({
107125
+ code: failure === null ? 0 : typeof failure.code === "number" ? failure.code : null,
107126
+ stdout: String(stdout ?? ""),
107127
+ stderr: String(stderr ?? "") || (failure !== null && typeof failure.code === "string" ? `${failure.code}: ${failure.message}` : ""),
107128
+ timedOut
107129
+ });
107130
+ });
107131
+ child2.stdout?.on("data", (chunk) => {
107132
+ seen += String(chunk);
107133
+ if (held && holdKillUntil?.test(seen)) child2.kill();
107134
+ });
107135
+ const end = () => {
107136
+ if (held) return;
107137
+ if (holdKillUntil === void 0 || holdKillUntil.test(seen)) {
107138
+ child2.kill();
107139
+ return;
106668
107140
  }
106669
- );
107141
+ held = true;
107142
+ grace = setTimeout(() => child2.kill(), options2.holdKillMs ?? HOLD_KILL_MS);
107143
+ };
107144
+ const timer = setTimeout(() => {
107145
+ timedOut = true;
107146
+ end();
107147
+ }, options2.timeoutMs);
107148
+ const stop = () => end();
107149
+ if (signal?.aborted) stop();
107150
+ else signal?.addEventListener("abort", stop, { once: true });
106670
107151
  });
106671
107152
  function defaultEnvironment() {
106672
107153
  return {
106673
107154
  platform: process.platform,
106674
107155
  env: process.env,
106675
107156
  run: defaultRunner,
107157
+ kill: (pid) => {
107158
+ try {
107159
+ process.kill(pid);
107160
+ } catch {
107161
+ }
107162
+ },
106676
107163
  isFile: async (file) => {
106677
107164
  try {
106678
107165
  const stat = await fs.stat(file);
@@ -106753,7 +107240,7 @@ var WORD_SCRIPT = [
106753
107240
  "$ErrorActionPreference = 'Stop'",
106754
107241
  "$app = $null; $doc = $null",
106755
107242
  "try {",
106756
- " $app = New-Object -ComObject Word.Application",
107243
+ ...startWordLines(),
106757
107244
  " $missing = [Type]::Missing",
106758
107245
  " $doc = $app.Documents.Open($env:PI_OUTPOST_RENDER_INPUT, $false, $true, $false, $missing, $missing, $missing, $missing, $missing, 0, $missing, $false)",
106759
107246
  " for ($i = 1; $i -le $doc.TablesOfContents.Count; $i++) { try { $doc.TablesOfContents.Item($i).Update() } catch { } }",
@@ -106763,12 +107250,27 @@ var WORD_SCRIPT = [
106763
107250
  " if ($app -ne $null -and $app.Documents.Count -eq 0) { $app.Quit([ref]0) }",
106764
107251
  "}"
106765
107252
  ].join("\n");
107253
+ function startWordLines() {
107254
+ return [
107255
+ " $running = @(Get-Process WINWORD -ErrorAction SilentlyContinue | ForEach-Object { $_.Id })",
107256
+ " $app = New-Object -ComObject Word.Application",
107257
+ " $started = @(Get-Process WINWORD -ErrorAction SilentlyContinue | Where-Object { $running -notcontains $_.Id })",
107258
+ " [Console]::Out.WriteLine('word-pid=' + $(if ($started.Count -eq 1) { $started[0].Id } else { 'unknown' }))"
107259
+ ];
107260
+ }
107261
+ var WORD_STARTED_LINE = /^word-pid=/m;
107262
+ var STARTED_WORD = /^word-pid=(\d+)\s*$/m;
107263
+ function stopStartedWord(result, environment, signal) {
107264
+ if (!result.timedOut && signal?.aborted !== true) return;
107265
+ const pid = STARTED_WORD.exec(result.stdout)?.[1];
107266
+ if (pid !== void 0) environment.kill?.(Number(pid));
107267
+ }
106766
107268
  function onlyOfficeScript(input, output) {
106767
107269
  return [`builder.OpenFile(${JSON.stringify(input)}, "");`, `builder.SaveFile("pdf", ${JSON.stringify(output)});`, "builder.CloseFile();", ""].join("\n");
106768
107270
  }
106769
107271
  function describeFailure(result, timeoutMs) {
106770
107272
  if (result.timedOut) return `did not finish within ${Math.round(timeoutMs / 1e3)} s`;
106771
- const detail = (result.stderr || result.stdout).trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
107273
+ const detail = (result.stderr || result.stdout.replace(/^word-pid=\S*\s*$/gm, "")).trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" ");
106772
107274
  return detail !== "" ? detail : `exited with code ${result.code ?? "unknown"}`;
106773
107275
  }
106774
107276
  async function hasOutput(file) {
@@ -106778,21 +107280,28 @@ async function hasOutput(file) {
106778
107280
  return false;
106779
107281
  }
106780
107282
  }
107283
+ function powershellPath(environment) {
107284
+ return environment.env.SystemRoot ? path2.win32.join(environment.env.SystemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : "powershell.exe";
107285
+ }
107286
+ function powershellArgs(script2) {
107287
+ return ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", script2];
107288
+ }
106781
107289
  async function convertWith(renderer, input, workDir, settings2, environment, signal) {
106782
107290
  const output = path2.join(workDir, `${path2.basename(input, path2.extname(input))}.pdf`);
106783
107291
  if (renderer === "powerpoint" || renderer === "word") {
106784
107292
  const application = renderer === "word" ? "Word" : "PowerPoint";
106785
107293
  if (environment.platform !== "win32") return { failure: `${application} automation is only available on Windows` };
106786
- const powershell = environment.env.SystemRoot ? path2.win32.join(environment.env.SystemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : "powershell.exe";
106787
107294
  const result2 = await environment.run(
106788
- powershell,
106789
- ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", renderer === "word" ? WORD_SCRIPT : POWERPOINT_SCRIPT],
107295
+ powershellPath(environment),
107296
+ powershellArgs(renderer === "word" ? WORD_SCRIPT : POWERPOINT_SCRIPT),
106790
107297
  {
106791
107298
  env: { ...environment.env, PI_OUTPOST_RENDER_INPUT: input, PI_OUTPOST_RENDER_OUTPUT: output },
106792
107299
  timeoutMs: settings2.timeoutMs,
106793
- signal
107300
+ signal,
107301
+ ...renderer === "word" ? { holdKillUntil: WORD_STARTED_LINE } : {}
106794
107302
  }
106795
107303
  );
107304
+ if (renderer === "word") stopStartedWord(result2, environment, signal);
106796
107305
  if (result2.code === 0 && await hasOutput(output)) return { pdf: output };
106797
107306
  return { failure: describeFailure(result2, settings2.timeoutMs) };
106798
107307
  }
@@ -106851,7 +107360,7 @@ async function convertToPdf(kind, source, settings2, environment, signal) {
106851
107360
  ].join("\n")
106852
107361
  );
106853
107362
  } finally {
106854
- await fs.rm(workDir, { recursive: true, force: true }).catch(() => {
107363
+ await fs.rm(workDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }).catch(() => {
106855
107364
  });
106856
107365
  }
106857
107366
  }
@@ -106984,12 +107493,12 @@ async function checkDocumentPdf(pdf, paragraphs) {
106984
107493
  }
106985
107494
 
106986
107495
  // ../server/src/extractionOutput.ts
106987
- import fs15 from "node:fs/promises";
106988
- import path18 from "node:path";
107496
+ import fs16 from "node:fs/promises";
107497
+ import path19 from "node:path";
106989
107498
 
106990
107499
  // ../server/src/sandbox.ts
106991
- import fs14 from "node:fs/promises";
106992
- import path17 from "node:path";
107500
+ import fs15 from "node:fs/promises";
107501
+ import path18 from "node:path";
106993
107502
  import {
106994
107503
  createBashToolDefinition,
106995
107504
  createPowerShellToolDefinition,
@@ -107976,8 +108485,8 @@ function parsePresentation(xml) {
107976
108485
  }
107977
108486
  function describeVisuals(visuals) {
107978
108487
  const parts = [];
107979
- const add = (count, singular, plural) => {
107980
- if (count > 0) parts.push(`${count} ${count === 1 ? singular : plural}`);
108488
+ const add = (count, singular, plural2) => {
108489
+ if (count > 0) parts.push(`${count} ${count === 1 ? singular : plural2}`);
107981
108490
  };
107982
108491
  add(visuals.images, "image", "images");
107983
108492
  add(visuals.charts, "chart", "charts");
@@ -124510,8 +125019,8 @@ var levelIn = (properties, paragraph2, styles2) => {
124510
125019
  const { entriesFromBookmark, headingStyleRange, stylesWithLevels = [], useAppliedParagraphOutlineLevel } = properties;
124511
125020
  if (paragraph2.text.trim() === "" || entriesFromBookmark && !paragraph2.bookmarks.has(entriesFromBookmark)) return;
124512
125021
  const names2 = [paragraph2.styleId, paragraph2.styleId === void 0 ? void 0 : (_styles$get2 = styles2.get(paragraph2.styleId)) === null || _styles$get2 === void 0 ? void 0 : _styles$get2.name].filter((name) => name !== void 0).map((name) => name.toLowerCase());
124513
- const listed = stylesWithLevels.find((style) => names2.includes(style.styleName.toLowerCase()));
124514
- if (listed) return listed.level;
125022
+ const listed2 = stylesWithLevels.find((style) => names2.includes(style.styleName.toLowerCase()));
125023
+ if (listed2) return listed2.level;
124515
125024
  const namesItsEntries = Boolean(headingStyleRange) || stylesWithLevels.length > 0 || Boolean(useAppliedParagraphOutlineLevel) || Boolean(properties.tcFieldIdentifier) || Boolean(properties.tcFieldLevelRange) || Boolean(properties.captionLabel) || Boolean(properties.captionLabelIncludingNumbers);
124516
125025
  const headingRange = headingStyleRange ? parseRange(headingStyleRange) : namesItsEntries ? void 0 : [1, 9];
124517
125026
  const heading3 = headingLevelOf(paragraph2.styleId, styles2);
@@ -128966,18 +129475,18 @@ var PackageParts = class {
128966
129475
  const taken = /* @__PURE__ */ new Set([...this.existingPaths, ...this.paths.values()]);
128967
129476
  let index4 = 1;
128968
129477
  while (taken.has(`${folder}/${name}${index4}.${extension2}`)) index4++;
128969
- const path21 = `${folder}/${name}${index4}.${extension2}`;
128970
- this.paths.set(part, path21);
128971
- this.contentTypes.addOverride(contentType, `/word/${path21}`);
128972
- return path21;
129478
+ const path22 = `${folder}/${name}${index4}.${extension2}`;
129479
+ this.paths.set(part, path22);
129480
+ this.contentTypes.addOverride(contentType, `/word/${path22}`);
129481
+ return path22;
128973
129482
  }
128974
129483
  /**
128975
129484
  * Each part added, with its path under word/, in the order they were added.
128976
129485
  */
128977
129486
  get Array() {
128978
- return [...this.paths].map(([part, path21]) => ({
129487
+ return [...this.paths].map(([part, path22]) => ({
128979
129488
  part,
128980
- path: path21
129489
+ path: path22
128981
129490
  }));
128982
129491
  }
128983
129492
  /**
@@ -128986,9 +129495,9 @@ var PackageParts = class {
128986
129495
  *
128987
129496
  * @param path - The part's path under word/
128988
129497
  */
128989
- createRelationships(path21) {
129498
+ createRelationships(path22) {
128990
129499
  const relationships = new Relationships();
128991
- this.folders.set(relationships, path21.slice(0, path21.indexOf("/")));
129500
+ this.folders.set(relationships, path22.slice(0, path22.indexOf("/")));
128992
129501
  return relationships;
128993
129502
  }
128994
129503
  /**
@@ -128997,10 +129506,10 @@ var PackageParts = class {
128997
129506
  *
128998
129507
  * @param path - The part's path under word/
128999
129508
  */
129000
- getTarget(relationships, path21) {
129509
+ getTarget(relationships, path22) {
129001
129510
  const from = this.folders.get(relationships);
129002
- if (from === void 0) return path21;
129003
- return path21.startsWith(`${from}/`) ? path21.slice(from.length + 1) : `../${path21}`;
129511
+ if (from === void 0) return path22;
129512
+ return path22.startsWith(`${from}/`) ? path22.slice(from.length + 1) : `../${path22}`;
129004
129513
  }
129005
129514
  };
129006
129515
  var createCompatibilitySetting = (version2) => new BuilderElement({
@@ -133630,11 +134139,11 @@ var xmlifyPart = (file, content3, prettify, relationships, standalone = true) =>
133630
134139
  encoding: "UTF-8"
133631
134140
  } : { encoding: "UTF-8" }
133632
134141
  });
133633
- var xmlifyPackagePart = (file, part, path21, prettify) => {
134142
+ var xmlifyPackagePart = (file, part, path22, prettify) => {
133634
134143
  const { content: content3 } = part.options;
133635
134144
  if (content3 instanceof Uint8Array) return [{
133636
134145
  data: content3,
133637
- path: `word/${path21}`
134146
+ path: `word/${path22}`
133638
134147
  }];
133639
134148
  if ("files" in content3) {
133640
134149
  const embedded = new import_jszip_min.default();
@@ -133644,16 +134153,16 @@ var xmlifyPackagePart = (file, part, path21, prettify) => {
133644
134153
  type: "uint8array",
133645
134154
  compression: "DEFLATE"
133646
134155
  }),
133647
- path: `word/${path21}`
134156
+ path: `word/${path22}`
133648
134157
  }];
133649
134158
  }
133650
- const relationships = file.PackageParts.createRelationships(path21);
134159
+ const relationships = file.PackageParts.createRelationships(path22);
133651
134160
  const data = xmlifyPart(file, content3, prettify, relationships);
133652
- const folder = path21.slice(0, path21.lastIndexOf("/"));
133653
- const name = path21.slice(path21.lastIndexOf("/") + 1);
134161
+ const folder = path22.slice(0, path22.lastIndexOf("/"));
134162
+ const name = path22.slice(path22.lastIndexOf("/") + 1);
133654
134163
  return [{
133655
134164
  data,
133656
- path: `word/${path21}`
134165
+ path: `word/${path22}`
133657
134166
  }, ...relationships.RelationshipCount > 0 ? [{
133658
134167
  data: xmlifyPart(file, relationships, prettify, relationships, false),
133659
134168
  path: `word/${folder}/_rels/${name}.rels`
@@ -133662,7 +134171,7 @@ var xmlifyPackagePart = (file, part, path21, prettify) => {
133662
134171
  var xmlifyPackageParts = (file, prettify, from = 0) => {
133663
134172
  const parts = file.PackageParts.Array.slice(from);
133664
134173
  if (parts.length === 0) return [];
133665
- return [...parts.flatMap(({ part, path: path21 }) => xmlifyPackagePart(file, part, path21, prettify)), ...xmlifyPackageParts(file, prettify, from + parts.length)];
134174
+ return [...parts.flatMap(({ part, path: path22 }) => xmlifyPackagePart(file, part, path22, prettify)), ...xmlifyPackageParts(file, prettify, from + parts.length)];
133666
134175
  };
133667
134176
  var _excluded = ["PackageParts"];
133668
134177
  var Compiler = class {
@@ -133700,7 +134209,7 @@ var Compiler = class {
133700
134209
  const map3 = new Map(Object.entries(xmlifiedFileMapping));
133701
134210
  for (const [, obj] of map3) if (Array.isArray(obj)) for (const subFile of obj) zip.file(subFile.path, encodeUtf8(subFile.data));
133702
134211
  else zip.file(obj.path, encodeUtf8(obj.data));
133703
- for (const { path: path21, data } of packageParts) zip.file(path21, typeof data === "string" ? encodeUtf8(data) : data);
134212
+ for (const { path: path22, data } of packageParts) zip.file(path22, typeof data === "string" ? encodeUtf8(data) : data);
133704
134213
  for (const subFile of overrides) zip.file(subFile.path, encodeUtf8(subFile.data));
133705
134214
  for (const data of file.Media.Array) if (data.type !== "svg") zip.file(`word/media/${data.fileName}`, data.data);
133706
134215
  else {
@@ -134484,12 +134993,12 @@ var altTextOf = (properties) => {
134484
134993
  var _properties$attribute, _properties$attribute2;
134485
134994
  return [(_properties$attribute = properties.attributes) === null || _properties$attribute === void 0 ? void 0 : _properties$attribute.descr, (_properties$attribute2 = properties.attributes) === null || _properties$attribute2 === void 0 ? void 0 : _properties$attribute2.title].flatMap((text7) => text7 === void 0 ? [] : [String(text7)]);
134486
134995
  };
134487
- var relationshipsPathOf = (path21) => {
134488
- const slash = path21.lastIndexOf("/");
134489
- return `${path21.slice(0, slash + 1)}_rels/${path21.slice(slash + 1)}.rels`;
134996
+ var relationshipsPathOf = (path22) => {
134997
+ const slash = path22.lastIndexOf("/");
134998
+ return `${path22.slice(0, slash + 1)}_rels/${path22.slice(slash + 1)}.rels`;
134490
134999
  };
134491
- var sourceOfRelationships = (path21) => path21.replace(/(^|\/)_rels\/([^/]*)\.rels$/, "$1$2");
134492
- var folderOf = (path21) => path21.slice(0, path21.lastIndexOf("/") + 1);
135000
+ var sourceOfRelationships = (path22) => path22.replace(/(^|\/)_rels\/([^/]*)\.rels$/, "$1$2");
135001
+ var folderOf = (path22) => path22.slice(0, path22.lastIndexOf("/") + 1);
134493
135002
  var resolveTarget = (from, target) => {
134494
135003
  const normalized = target.replace(/\\/g, "/");
134495
135004
  return (normalized.startsWith("/") ? normalized : `${folderOf(from)}${normalized}`).split("/").reduce((segments, segment4) => {
@@ -134515,18 +135024,18 @@ var relationshipsIn = (relationships) => {
134515
135024
  };
134516
135025
  var createTemplatePackage = (parts, binaryParts, file, context) => {
134517
135026
  const formatter2 = new Formatter();
134518
- const has = (path21) => parts.has(path21) || binaryParts.has(path21);
134519
- const findPath = (path21) => {
134520
- if (has(path21)) return path21;
135027
+ const has = (path22) => parts.has(path22) || binaryParts.has(path22);
135028
+ const findPath = (path22) => {
135029
+ if (has(path22)) return path22;
134521
135030
  const decoded = (() => {
134522
135031
  try {
134523
- return decodeURI(path21);
135032
+ return decodeURI(path22);
134524
135033
  } catch (_unused) {
134525
135034
  return;
134526
135035
  }
134527
135036
  })();
134528
135037
  if (decoded !== void 0 && has(decoded)) return decoded;
134529
- const lower = path21.toLowerCase();
135038
+ const lower = path22.toLowerCase();
134530
135039
  return [...parts.keys(), ...binaryParts.keys()].find((key) => key.toLowerCase() === lower);
134531
135040
  };
134532
135041
  const findRelationship = (from, id) => {
@@ -134541,27 +135050,27 @@ var createTemplatePackage = (parts, binaryParts, file, context) => {
134541
135050
  const target = (_relationship$attribu2 = relationship.attributes) === null || _relationship$attribu2 === void 0 ? void 0 : _relationship$attribu2.Target;
134542
135051
  return ((_relationship$attribu3 = relationship.attributes) === null || _relationship$attribu3 === void 0 ? void 0 : _relationship$attribu3.TargetMode) === "External" || target === void 0 ? void 0 : findPath(resolveTarget(from, String(target)));
134543
135052
  };
134544
- const isReferenced = (path21) => [...parts].some(([relationshipsPath, relationships]) => relationshipsPath.endsWith(".rels") && getFirstLevelElements(relationships, "Relationships").some((relationship) => pathOf(sourceOfRelationships(relationshipsPath), relationship) === path21));
134545
- const removePart = (path21) => {
134546
- parts.delete(path21);
134547
- binaryParts.delete(path21);
134548
- parts.delete(relationshipsPathOf(path21));
135053
+ const isReferenced = (path22) => [...parts].some(([relationshipsPath, relationships]) => relationshipsPath.endsWith(".rels") && getFirstLevelElements(relationships, "Relationships").some((relationship) => pathOf(sourceOfRelationships(relationshipsPath), relationship) === path22));
135054
+ const removePart = (path22) => {
135055
+ parts.delete(path22);
135056
+ binaryParts.delete(path22);
135057
+ parts.delete(relationshipsPathOf(path22));
134549
135058
  const contentTypes = parts.get(CONTENT_TYPES6);
134550
- if (contentTypes !== void 0) removeContentTypeOverride(contentTypes, `/${path21}`);
135059
+ if (contentTypes !== void 0) removeContentTypeOverride(contentTypes, `/${path22}`);
134551
135060
  };
134552
135061
  return {
134553
135062
  getRelatedPart: (from, relationshipId) => {
134554
135063
  const relationship = findRelationship(from.path, relationshipId);
134555
- const path21 = relationship === void 0 ? void 0 : pathOf(from.path, relationship);
134556
- return path21 === void 0 ? void 0 : {
134557
- path: path21,
134558
- xml: parts.get(path21)
135064
+ const path22 = relationship === void 0 ? void 0 : pathOf(from.path, relationship);
135065
+ return path22 === void 0 ? void 0 : {
135066
+ path: path22,
135067
+ xml: parts.get(path22)
134559
135068
  };
134560
135069
  },
134561
135070
  replaceRelatedPart: (from, relationshipId, part) => {
134562
- const path21 = `word/${file.PackageParts.add(part)}`;
135071
+ const path22 = `word/${file.PackageParts.add(part)}`;
134563
135072
  const { relationshipType } = part.options;
134564
- const target = relativeTarget2(from.path, path21);
135073
+ const target = relativeTarget2(from.path, path22);
134565
135074
  const relationship = relationshipId === void 0 ? void 0 : findRelationship(from.path, relationshipId);
134566
135075
  if (relationship === void 0) {
134567
135076
  var _parts$get;
@@ -134596,16 +135105,16 @@ var patchDrawings = ({ parts, binaryParts, file, patches, delimiters: delimiters
134596
135105
  placeholder: `${delimiters2.start}${key}${delimiters2.end}`,
134597
135106
  patch
134598
135107
  }));
134599
- const found = [...parts].filter(([path21]) => path21.startsWith("word/") && !path21.endsWith(".rels")).flatMap(([path21, xmlPart]) => findDrawings(xmlPart).flatMap((drawing) => {
135108
+ const found = [...parts].filter(([path22]) => path22.startsWith("word/") && !path22.endsWith(".rels")).flatMap(([path22, xmlPart]) => findDrawings(xmlPart).flatMap((drawing) => {
134600
135109
  const altText = altTextOf(drawing.properties);
134601
135110
  const matches = placeholders.filter(({ placeholder }) => altText.some((text7) => text7.includes(placeholder)));
134602
135111
  if (matches.length > 1) {
134603
135112
  var _drawing$properties$a, _drawing$properties$a2;
134604
- throw new Error(`The drawing "${(_drawing$properties$a = (_drawing$properties$a2 = drawing.properties.attributes) === null || _drawing$properties$a2 === void 0 ? void 0 : _drawing$properties$a2.name) !== null && _drawing$properties$a !== void 0 ? _drawing$properties$a : ""}" in ${path21} has the placeholders ${matches.map(({ placeholder }) => placeholder).join(" and ")} in its alt text. A drawing can only be patched once`);
135113
+ throw new Error(`The drawing "${(_drawing$properties$a = (_drawing$properties$a2 = drawing.properties.attributes) === null || _drawing$properties$a2 === void 0 ? void 0 : _drawing$properties$a2.name) !== null && _drawing$properties$a !== void 0 ? _drawing$properties$a : ""}" in ${path22} has the placeholders ${matches.map(({ placeholder }) => placeholder).join(" and ")} in its alt text. A drawing can only be patched once`);
134605
135114
  }
134606
135115
  return matches.map(({ placeholder, patch }) => ({
134607
135116
  drawing: _objectSpread2(_objectSpread2({ placeholder }, drawing), {}, { part: {
134608
- path: path21,
135117
+ path: path22,
134609
135118
  xml: xmlPart
134610
135119
  } }),
134611
135120
  patch
@@ -134685,30 +135194,30 @@ var patchNotesOfKind = (kind, notes, parts, { createContext, addContentTypeOverr
134685
135194
  var _element$attributes3;
134686
135195
  return ((_element$attributes3 = element.attributes) === null || _element$attributes3 === void 0 ? void 0 : _element$attributes3.Type) === kind.relationshipType;
134687
135196
  });
134688
- const path21 = relationship ? resolveTarget(DOCUMENT_PATH$1, String(relationship.attributes.Target)) : kind.path;
134689
- if (!parts.has(path21)) {
134690
- parts.set(path21, {
135197
+ const path22 = relationship ? resolveTarget(DOCUMENT_PATH$1, String(relationship.attributes.Target)) : kind.path;
135198
+ if (!parts.has(path22)) {
135199
+ parts.set(path22, {
134691
135200
  declaration: { attributes: {
134692
135201
  version: "1.0",
134693
135202
  encoding: "UTF-8",
134694
135203
  standalone: "yes"
134695
135204
  } },
134696
- elements: [formatElement$1(kind.create.part(), createContext(path21))]
135205
+ elements: [formatElement$1(kind.create.part(), createContext(path22))]
134697
135206
  });
134698
- addContentTypeOverride(kind.contentType, `/${path21}`);
135207
+ addContentTypeOverride(kind.contentType, `/${path22}`);
134699
135208
  }
134700
- if (!relationship) createContext(DOCUMENT_PATH$1).viewWrapper.Relationships.addRelationship(uniqueId(), kind.relationshipType, relativeTarget2(DOCUMENT_PATH$1, path21));
134701
- return path21;
135209
+ if (!relationship) createContext(DOCUMENT_PATH$1).viewWrapper.Relationships.addRelationship(uniqueId(), kind.relationshipType, relativeTarget2(DOCUMENT_PATH$1, path22));
135210
+ return path22;
134702
135211
  };
134703
135212
  const write = () => {
134704
135213
  if (noteOfId.size === 0) return;
134705
- const path21 = findOrAddPart();
134706
- const context = createContext(path21);
135214
+ const path22 = findOrAddPart();
135215
+ const context = createContext(path22);
134707
135216
  const contentOfNote = new Map([...new Set(noteOfId.values())].map((note) => {
134708
135217
  const mark = formatElement$1(kind.create.mark(), context);
134709
135218
  return [note, useStyles(renumberLists(renumberBookmarks(note.children.map((paragraph2) => formatElement$1(paragraph2, context)).map((paragraph2, index4) => index4 === 0 ? withMark(paragraph2, mark) : paragraph2))))];
134710
135219
  }));
134711
- getFirstLevelElements(parts.get(path21), kind.rootName).push(...[...noteOfId].map(([id, note]) => ({
135220
+ getFirstLevelElements(parts.get(path22), kind.rootName).push(...[...noteOfId].map(([id, note]) => ({
134712
135221
  type: "element",
134713
135222
  name: kind.noteName,
134714
135223
  attributes: { "w:id": String(id) },
@@ -134803,9 +135312,9 @@ var patchNumbering = (numbering, parts, { createContext, addContentTypeOverride
134803
135312
  };
134804
135313
  const findOrAddPart = (written) => {
134805
135314
  const relationship = numberingRelationship();
134806
- const path21 = numberingPath(relationship);
134807
- if (!parts.has(path21)) {
134808
- parts.set(path21, {
135315
+ const path22 = numberingPath(relationship);
135316
+ if (!parts.has(path22)) {
135317
+ parts.set(path22, {
134809
135318
  declaration: { attributes: {
134810
135319
  version: "1.0",
134811
135320
  encoding: "UTF-8",
@@ -134813,10 +135322,10 @@ var patchNumbering = (numbering, parts, { createContext, addContentTypeOverride
134813
135322
  } },
134814
135323
  elements: [_objectSpread2(_objectSpread2({}, written), {}, { elements: [] })]
134815
135324
  });
134816
- addContentTypeOverride(NUMBERING_CONTENT_TYPE, `/${path21}`);
135325
+ addContentTypeOverride(NUMBERING_CONTENT_TYPE, `/${path22}`);
134817
135326
  }
134818
- if (!relationship) createContext(DOCUMENT_PATH).viewWrapper.Relationships.addRelationship(uniqueId(), NUMBERING_RELATIONSHIP, relativeTarget2(DOCUMENT_PATH, path21));
134819
- return path21;
135327
+ if (!relationship) createContext(DOCUMENT_PATH).viewWrapper.Relationships.addRelationship(uniqueId(), NUMBERING_RELATIONSHIP, relativeTarget2(DOCUMENT_PATH, path22));
135328
+ return path22;
134820
135329
  };
134821
135330
  const write = () => {
134822
135331
  var _root$attributes$mcI, _root$attributes;
@@ -134830,10 +135339,10 @@ var patchNumbering = (numbering, parts, { createContext, addContentTypeOverride
134830
135339
  const newId = element.name === "w:abstractNum" ? newAbstractNumIds.get(Number(element.attributes["w:abstractNumId"])) : void 0;
134831
135340
  return newId === void 0 ? [] : [_objectSpread2(_objectSpread2({}, element), {}, { attributes: _objectSpread2(_objectSpread2({}, element.attributes), {}, { "w:abstractNumId": String(newId) }) })];
134832
135341
  });
134833
- const path21 = findOrAddPart(written);
134834
- const root2 = parts.get(path21).elements.find((element) => element.name === "w:numbering");
135342
+ const path22 = findOrAddPart(written);
135343
+ const root2 = parts.get(path22).elements.find((element) => element.name === "w:numbering");
134835
135344
  root2.attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, Object.fromEntries(Object.entries(written.attributes).filter(([name]) => name.startsWith("xmlns:")))), root2.attributes), {}, { "mc:Ignorable": [.../* @__PURE__ */ new Set([...String((_root$attributes$mcI = (_root$attributes = root2.attributes) === null || _root$attributes === void 0 ? void 0 : _root$attributes["mc:Ignorable"]) !== null && _root$attributes$mcI !== void 0 ? _root$attributes$mcI : "").split(" "), ...String(written.attributes["mc:Ignorable"]).split(" ")])].filter((prefix) => prefix !== "").join(" ") });
134836
- const elements = getFirstLevelElements(parts.get(path21), "w:numbering");
135345
+ const elements = getFirstLevelElements(parts.get(path22), "w:numbering");
134837
135346
  const firstIndexOf = (names2) => {
134838
135347
  const index4 = elements.findIndex((element) => names2.includes(element.name));
134839
135348
  return index4 === -1 ? elements.length : index4;
@@ -134896,10 +135405,10 @@ var readPackage = (function() {
134896
135405
  const zip = yield import_jszip_min.default.loadAsync(data);
134897
135406
  const parts = /* @__PURE__ */ new Map();
134898
135407
  const binaryParts = /* @__PURE__ */ new Map();
134899
- for (const [path21, file] of Object.entries(zip.files)) {
135408
+ for (const [path22, file] of Object.entries(zip.files)) {
134900
135409
  if (file.dir) continue;
134901
- if (/\.(xml|rels)$/.test(path21)) parts.set(path21, toJson(yield file.async("text")));
134902
- else binaryParts.set(path21, yield file.async("uint8array"));
135410
+ if (/\.(xml|rels)$/.test(path22)) parts.set(path22, toJson(yield file.async("text")));
135411
+ else binaryParts.set(path22, yield file.async("uint8array"));
134903
135412
  }
134904
135413
  const importedDocuments = yield readImportedDocuments(parts, binaryParts);
134905
135414
  return _objectSpread2({
@@ -134917,11 +135426,11 @@ var readPackage = (function() {
134917
135426
  var readImportedDocuments = (function() {
134918
135427
  var _ref2 = _asyncToGenerator(function* (parts, binaryParts) {
134919
135428
  const imported = /* @__PURE__ */ new Map();
134920
- for (const [path21, relationships] of parts) {
135429
+ for (const [path22, relationships] of parts) {
134921
135430
  var _rootOf$elements, _rootOf;
134922
- if (!path21.endsWith(".rels")) continue;
135431
+ if (!path22.endsWith(".rels")) continue;
134923
135432
  for (const { attributes: attributes2 = {} } of (_rootOf$elements = (_rootOf = rootOf(relationships)) === null || _rootOf === void 0 ? void 0 : _rootOf.elements) !== null && _rootOf$elements !== void 0 ? _rootOf$elements : []) {
134924
- const target = resolveTarget(sourceOfRelationships(path21), String(attributes2.Target));
135433
+ const target = resolveTarget(sourceOfRelationships(path22), String(attributes2.Target));
134925
135434
  const data = binaryParts.get(target);
134926
135435
  const read = attributes2.Type === IMPORT && attributes2.TargetMode !== "External" && data ? yield readPackage(data) : void 0;
134927
135436
  if (read) imported.set(target, read);
@@ -135269,18 +135778,18 @@ var childElementsOf = (element) => {
135269
135778
  var _element$elements;
135270
135779
  return (_element$elements = element.elements) !== null && _element$elements !== void 0 ? _element$elements : [];
135271
135780
  };
135272
- var isInsideElementAtPath = (path21, ancestorPath) => path21.length > ancestorPath.length && ancestorPath.every((index4, i2) => path21[i2] === index4);
135781
+ var isInsideElementAtPath = (path22, ancestorPath) => path22.length > ancestorPath.length && ancestorPath.every((index4, i2) => path22[i2] === index4);
135273
135782
  var withoutNestedParagraphs = (paragraphs) => paragraphs.filter((paragraph2) => !paragraphs.some((other) => isInsideElementAtPath(paragraph2.pathToParagraph, other.pathToParagraph)));
135274
- var goToElementFromPath = (json, path21) => {
135783
+ var goToElementFromPath = (json, path22) => {
135275
135784
  let element = json;
135276
- for (let i2 = 1; i2 < path21.length; i2++) {
135277
- const index4 = path21[i2];
135785
+ for (let i2 = 1; i2 < path22.length; i2++) {
135786
+ const index4 = path22[i2];
135278
135787
  element = element.elements[index4];
135279
135788
  }
135280
135789
  return element;
135281
135790
  };
135282
- var goToParentElementFromPath = (json, path21) => goToElementFromPath(json, path21.slice(0, path21.length - 1));
135283
- var getLastElementIndexFromPath = (path21) => path21[path21.length - 1];
135791
+ var goToParentElementFromPath = (json, path22) => goToElementFromPath(json, path22.slice(0, path22.length - 1));
135792
+ var getLastElementIndexFromPath = (path22) => path22[path22.length - 1];
135284
135793
  var formatter = new Formatter();
135285
135794
  var STYLES_PATH = "word/styles.xml";
135286
135795
  var REFERENCES = /* @__PURE__ */ new Set([
@@ -135415,7 +135924,7 @@ var rowHolding = (json, pathToParagraph) => {
135415
135924
  }
135416
135925
  return row;
135417
135926
  };
135418
- var isInside = (path21, ancestorPath) => path21.length > ancestorPath.length && ancestorPath.every((index4, i2) => path21[i2] === index4);
135927
+ var isInside = (path22, ancestorPath) => path22.length > ancestorPath.length && ancestorPath.every((index4, i2) => path22[i2] === index4);
135419
135928
  var hasRows = (table) => {
135420
135929
  var _table$elements;
135421
135930
  return ((_table$elements = table.elements) !== null && _table$elements !== void 0 ? _table$elements : []).some((e) => e.name === "w:tr" || e.name !== "w:tblPr" && e.name !== "w:tblGrid" && hasRows(e));
@@ -135467,8 +135976,8 @@ var hexValue = (color3) => {
135467
135976
  };
135468
135977
  var isUtf16 = (bytes) => bytes[0] === 255 && bytes[1] === 254 || bytes[0] === 254 && bytes[1] === 255;
135469
135978
  var readPart = (function() {
135470
- var _ref = _asyncToGenerator(function* (zip, path21) {
135471
- const part = zip.file(path21);
135979
+ var _ref = _asyncToGenerator(function* (zip, path22) {
135980
+ const part = zip.file(path22);
135472
135981
  if (part === null) return;
135473
135982
  return isUtf16(yield part.async("uint8array")) ? void 0 : toJson(yield part.async("text"));
135474
135983
  });
@@ -135544,7 +136053,7 @@ var patchDocument = (function() {
135544
136053
  PackageParts: new PackageParts({ addOverride: (contentType, partName) => contentTypeOverrides.push({
135545
136054
  contentType,
135546
136055
  partName
135547
- }) }, new Set(Object.keys(zipContent.files).filter((path21) => path21.startsWith("word/")).map((path21) => path21.slice(5))))
136056
+ }) }, new Set(Object.keys(zipContent.files).filter((path22) => path22.startsWith("word/")).map((path22) => path22.slice(5))))
135548
136057
  };
135549
136058
  const map3 = /* @__PURE__ */ new Map();
135550
136059
  const imageRelationshipAdditions = [];
@@ -135742,7 +136251,7 @@ var patchDocument = (function() {
135742
136251
  }
135743
136252
  for (const [key, value] of binaryContentMap) zip.file(key, value);
135744
136253
  for (const { data: stream, fileName } of file.Media.Array) zip.file(`word/media/${fileName}`, stream);
135745
- for (const { path: path21, data: partData } of packageParts) zip.file(path21, typeof partData === "string" ? encodeUtf8(partData) : partData);
136254
+ for (const { path: path22, data: partData } of packageParts) zip.file(path22, typeof partData === "string" ? encodeUtf8(partData) : partData);
135746
136255
  return zip.generateAsync({
135747
136256
  type: outputType,
135748
136257
  mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
@@ -136208,7 +136717,7 @@ function transformGfmAutolinkLiterals(tree2) {
136208
136717
  { ignore: ["link", "linkReference"] }
136209
136718
  );
136210
136719
  }
136211
- function findUrl(_, protocol, domain2, path21, match) {
136720
+ function findUrl(_, protocol, domain2, path22, match) {
136212
136721
  let prefix = "";
136213
136722
  if (!previous(match)) {
136214
136723
  return false;
@@ -136221,7 +136730,7 @@ function findUrl(_, protocol, domain2, path21, match) {
136221
136730
  if (!isCorrectDomain(domain2)) {
136222
136731
  return false;
136223
136732
  }
136224
- const parts = splitUrl(domain2 + path21);
136733
+ const parts = splitUrl(domain2 + path22);
136225
136734
  if (!parts[0]) return false;
136226
136735
  const result = {
136227
136736
  type: "link",
@@ -145318,27 +145827,27 @@ var sqrtTall = function sqrtTall2(extraVinculum, hLinePad2, viewBoxHeight) {
145318
145827
  };
145319
145828
  var sqrtPath = function sqrtPath2(size, extraVinculum, viewBoxHeight) {
145320
145829
  extraVinculum = 1e3 * extraVinculum;
145321
- var path21 = "";
145830
+ var path22 = "";
145322
145831
  switch (size) {
145323
145832
  case "sqrtMain":
145324
- path21 = sqrtMain(extraVinculum, hLinePad);
145833
+ path22 = sqrtMain(extraVinculum, hLinePad);
145325
145834
  break;
145326
145835
  case "sqrtSize1":
145327
- path21 = sqrtSize1(extraVinculum, hLinePad);
145836
+ path22 = sqrtSize1(extraVinculum, hLinePad);
145328
145837
  break;
145329
145838
  case "sqrtSize2":
145330
- path21 = sqrtSize2(extraVinculum, hLinePad);
145839
+ path22 = sqrtSize2(extraVinculum, hLinePad);
145331
145840
  break;
145332
145841
  case "sqrtSize3":
145333
- path21 = sqrtSize3(extraVinculum, hLinePad);
145842
+ path22 = sqrtSize3(extraVinculum, hLinePad);
145334
145843
  break;
145335
145844
  case "sqrtSize4":
145336
- path21 = sqrtSize4(extraVinculum, hLinePad);
145845
+ path22 = sqrtSize4(extraVinculum, hLinePad);
145337
145846
  break;
145338
145847
  case "sqrtTall":
145339
- path21 = sqrtTall(extraVinculum, hLinePad, viewBoxHeight);
145848
+ path22 = sqrtTall(extraVinculum, hLinePad, viewBoxHeight);
145340
145849
  }
145341
- return path21;
145850
+ return path22;
145342
145851
  };
145343
145852
  var innerPath = function innerPath2(name, height) {
145344
145853
  switch (name) {
@@ -149512,8 +150021,8 @@ var svgData = {
149512
150021
  };
149513
150022
  var staticSvg = function staticSvg2(value, options2) {
149514
150023
  var _svgData$value = svgData[value], pathName = _svgData$value[0], width = _svgData$value[1], height = _svgData$value[2];
149515
- var path21 = new PathNode(pathName);
149516
- var svgNode = new SvgNode([path21], {
150024
+ var path22 = new PathNode(pathName);
150025
+ var svgNode = new SvgNode([path22], {
149517
150026
  "width": makeEm(width),
149518
150027
  "height": makeEm(height),
149519
150028
  // Override CSS rule `.katex svg { width: 100% }`
@@ -150654,8 +151163,8 @@ var stretchySvg = function stretchySvg2(group, options2) {
150654
151163
  pathName = "tilde" + imgIndex;
150655
151164
  }
150656
151165
  }
150657
- var path21 = new PathNode(pathName);
150658
- var svgNode = new SvgNode([path21], {
151166
+ var path22 = new PathNode(pathName);
151167
+ var svgNode = new SvgNode([path22], {
150659
151168
  "width": "100%",
150660
151169
  "height": makeEm(_height),
150661
151170
  "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight,
@@ -151859,8 +152368,8 @@ var makeGlyphSpan = function makeGlyphSpan2(symbol, font, mode) {
151859
152368
  };
151860
152369
  var makeInner = function makeInner2(ch3, height, options2) {
151861
152370
  var width = fontMetricsData["Size4-Regular"][ch3.charCodeAt(0)] ? fontMetricsData["Size4-Regular"][ch3.charCodeAt(0)][4] : fontMetricsData["Size1-Regular"][ch3.charCodeAt(0)][4];
151862
- var path21 = new PathNode("inner", innerPath(ch3, Math.round(1e3 * height)));
151863
- var svgNode = new SvgNode([path21], {
152371
+ var path22 = new PathNode("inner", innerPath(ch3, Math.round(1e3 * height)));
152372
+ var svgNode = new SvgNode([path22], {
151864
152373
  "width": makeEm(width),
151865
152374
  "height": makeEm(height),
151866
152375
  // Override CSS rule `.katex svg { width: 100% }`
@@ -152029,10 +152538,10 @@ var makeStackedDelim = function makeStackedDelim2(delim, heightTotal, center, op
152029
152538
  var midHeight = realHeightTotal - topHeightTotal - bottomHeightTotal;
152030
152539
  var viewBoxHeight = Math.round(realHeightTotal * 1e3);
152031
152540
  var pathStr = tallDelim(svgLabel, Math.round(midHeight * 1e3));
152032
- var path21 = new PathNode(svgLabel, pathStr);
152541
+ var path22 = new PathNode(svgLabel, pathStr);
152033
152542
  var width = makeEm(viewBoxWidth / 1e3);
152034
152543
  var height = makeEm(viewBoxHeight / 1e3);
152035
- var svg = new SvgNode([path21], {
152544
+ var svg = new SvgNode([path22], {
152036
152545
  "width": width,
152037
152546
  "height": height,
152038
152547
  "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight
@@ -152073,8 +152582,8 @@ var makeStackedDelim = function makeStackedDelim2(delim, heightTotal, center, op
152073
152582
  var vbPad = 80;
152074
152583
  var emPad = 0.08;
152075
152584
  var sqrtSvg = function sqrtSvg2(sqrtName, height, viewBoxHeight, extraVinculum, options2) {
152076
- var path21 = sqrtPath(sqrtName, extraVinculum, viewBoxHeight);
152077
- var pathNode = new PathNode(sqrtName, path21);
152585
+ var path22 = sqrtPath(sqrtName, extraVinculum, viewBoxHeight);
152586
+ var pathNode = new PathNode(sqrtName, path22);
152078
152587
  var svg = new SvgNode([pathNode], {
152079
152588
  // Note: 1000:1 ratio of viewBox to document em width.
152080
152589
  "width": "400em",
@@ -152573,8 +153082,8 @@ var htmlBuilder$7 = (group, options2) => {
152573
153082
  var angleHeight = inner2.height + inner2.depth + lineWeight + clearance;
152574
153083
  inner2.style.paddingLeft = makeEm(angleHeight / 2 + lineWeight);
152575
153084
  var viewBoxHeight = Math.floor(1e3 * angleHeight * scale);
152576
- var path21 = phasePath(viewBoxHeight);
152577
- var svgNode = new SvgNode([new PathNode("phase", path21)], {
153085
+ var path22 = phasePath(viewBoxHeight);
153086
+ var svgNode = new SvgNode([new PathNode("phase", path22)], {
152578
153087
  "width": "400em",
152579
153088
  "height": makeEm(viewBoxHeight / 1e3),
152580
153089
  "viewBox": "0 0 400000 " + viewBoxHeight,
@@ -161171,13 +161680,13 @@ var VFile = class {
161171
161680
  * @returns {undefined}
161172
161681
  * Nothing.
161173
161682
  */
161174
- set path(path21) {
161175
- if (isUrl(path21)) {
161176
- path21 = fileURLToPath3(path21);
161683
+ set path(path22) {
161684
+ if (isUrl(path22)) {
161685
+ path22 = fileURLToPath3(path22);
161177
161686
  }
161178
- assertNonEmpty(path21, "path");
161179
- if (this.path !== path21) {
161180
- this.history.push(path21);
161687
+ assertNonEmpty(path22, "path");
161688
+ if (this.path !== path22) {
161689
+ this.history.push(path22);
161181
161690
  }
161182
161691
  }
161183
161692
  /**
@@ -161444,8 +161953,8 @@ function assertNonEmpty(part, name) {
161444
161953
  throw new Error("`" + name + "` cannot be empty");
161445
161954
  }
161446
161955
  }
161447
- function assertPath(path21, name) {
161448
- if (!path21) {
161956
+ function assertPath(path22, name) {
161957
+ if (!path22) {
161449
161958
  throw new Error("Setting `" + name + "` requires `path` to be set too");
161450
161959
  }
161451
161960
  }
@@ -162477,6 +162986,10 @@ function inlineRuns(nodes, refs, marks = {}) {
162477
162986
  out.push(new TextRun({ text: "", break: 1 }));
162478
162987
  break;
162479
162988
  case "image": {
162989
+ if (isDrawioReference(node2.url)) {
162990
+ out.push(new ExternalHyperlink({ children: [runOf(drawioLinkLabel(node2.url, node2.alt), marks)], link: node2.url }));
162991
+ break;
162992
+ }
162480
162993
  const picture = refs.get(node2);
162481
162994
  if (picture === void 0) out.push(runOf(node2.alt ?? node2.url, marks));
162482
162995
  else out.push(pictureRun(picture, node2.alt));
@@ -162561,13 +163074,24 @@ function countDiagrams(text7) {
162561
163074
  walk(parseMarkdown(text7));
162562
163075
  return count;
162563
163076
  }
163077
+ function isDrawioReference(url) {
163078
+ return !/^[a-z][a-z0-9+.-]*:|^\/\//i.test(url) && /\.(drawio|dio)$/i.test(url.split(/[?#]/)[0]);
163079
+ }
163080
+ function drawioLinkLabel(url, alt) {
163081
+ let path22 = url.split(/[?#]/)[0].replace(/^\.\//, "");
163082
+ try {
163083
+ path22 = decodeURIComponent(path22);
163084
+ } catch {
163085
+ }
163086
+ return alt && alt.trim() !== "" ? `${alt.trim()} (draw.io diagram: ${path22})` : `draw.io diagram: ${path22}`;
163087
+ }
162564
163088
  async function loadReferences(root2, source) {
162565
163089
  const refs = /* @__PURE__ */ new Map();
162566
163090
  const { imageKey, loadImage } = source;
162567
163091
  if (imageKey === void 0 || loadImage === void 0) return refs;
162568
163092
  const nodes = [];
162569
163093
  const walk = (node2) => {
162570
- if (node2.type === "image") nodes.push(node2);
163094
+ if (node2.type === "image" && !isDrawioReference(node2.url)) nodes.push(node2);
162571
163095
  for (const child2 of node2.children ?? []) walk(child2);
162572
163096
  };
162573
163097
  walk(root2);
@@ -163613,8 +164137,8 @@ function sectionEnd(headings, heading3, bodyEnd) {
163613
164137
  const next = headings.find((candidate) => candidate.index > heading3.index && candidate.level <= heading3.level);
163614
164138
  return next === void 0 ? bodyEnd : next.index;
163615
164139
  }
163616
- function findSection(path21, headings, bodyEnd) {
163617
- const segments = path21.split(">").map((segment4) => segment4.trim()).filter(Boolean);
164140
+ function findSection(path22, headings, bodyEnd) {
164141
+ const segments = path22.split(">").map((segment4) => segment4.trim()).filter(Boolean);
163618
164142
  if (segments.length === 0) throw new WordTemplateError(`the section path is empty.
163619
164143
  ${outline(headings)}`);
163620
164144
  const matches = (heading3, segment4) => normalise2(heading3.text) === normalise2(segment4) || normalise2(heading3.text) === normalise2(withoutNumber(segment4));
@@ -163631,7 +164155,7 @@ ${outline(headings)}`);
163631
164155
  scope = found;
163632
164156
  }
163633
164157
  if (scope.length > 1) {
163634
- throw new WordTemplateError(`"${path21}" names ${scope.length} sections; add the heading above it, as in "Parent > ${segments[segments.length - 1]}".
164158
+ throw new WordTemplateError(`"${path22}" names ${scope.length} sections; add the heading above it, as in "Parent > ${segments[segments.length - 1]}".
163635
164159
  ${outline(headings)}`);
163636
164160
  }
163637
164161
  return scope[0];
@@ -164677,9 +165201,188 @@ function createDocxRenderToolDefinition(options2) {
164677
165201
  };
164678
165202
  }
164679
165203
 
165204
+ // ../server/src/docxCompare.ts
165205
+ import fs9 from "node:fs/promises";
165206
+ import os2 from "node:os";
165207
+ import path12 from "node:path";
165208
+ var COMPARISON_AUTHOR = "Word comparison";
165209
+ var MANUAL_COMPARISON = "To compare by hand, open the revised document in Word, choose Review \u2192 Compare \u2192 Compare\u2026, save the result, and read it with docx_extract and review: true.";
165210
+ var COMPARE_SCRIPT = [
165211
+ "$ErrorActionPreference = 'Stop'",
165212
+ "[Console]::OutputEncoding = [Text.Encoding]::UTF8",
165213
+ "$app = $null; $original = $null; $revised = $null; $result = $null",
165214
+ "try {",
165215
+ ...startWordLines(),
165216
+ " $missing = [Type]::Missing",
165217
+ " $original = $app.Documents.Open($env:PI_OUTPOST_COMPARE_ORIGINAL, $false, $true, $false, $missing, $missing, $missing, $missing, $missing, 0, $missing, $false)",
165218
+ " $revised = $app.Documents.Open($env:PI_OUTPOST_COMPARE_REVISED, $false, $true, $false, $missing, $missing, $missing, $missing, $missing, 0, $missing, $false)",
165219
+ " $result = $app.CompareDocuments($original, $revised, 2, 1, $false, $true, $true, $true, $true, $true, $true, $true, $true, $true, $env:PI_OUTPOST_COMPARE_AUTHOR, $true)",
165220
+ " $result.SaveAs2($env:PI_OUTPOST_COMPARE_OUTPUT, 16)",
165221
+ "} catch {",
165222
+ " [Console]::Error.WriteLine($_.Exception.Message); exit 1",
165223
+ "} finally {",
165224
+ " foreach ($doc in @($result, $revised, $original)) { if ($doc -ne $null) { try { $doc.Close(0) } catch { } } }",
165225
+ " if ($app -ne $null -and $app.Documents.Count -eq 0) { $app.Quit([ref]0) }",
165226
+ "}"
165227
+ ].join("\n");
165228
+ async function compareWithWord(original, revised, settings2, environment, signal) {
165229
+ if (environment.platform !== "win32") {
165230
+ throw new Error(`Microsoft Word is unavailable: Word automation is only available on Windows. ${MANUAL_COMPARISON}`);
165231
+ }
165232
+ const workDir = await fs9.mkdtemp(path12.join(os2.tmpdir(), "pi-outpost-compare-"));
165233
+ try {
165234
+ const files = {
165235
+ original: path12.join(workDir, "original.docx"),
165236
+ revised: path12.join(workDir, "revised.docx"),
165237
+ output: path12.join(workDir, "compared.docx")
165238
+ };
165239
+ await fs9.writeFile(files.original, original);
165240
+ await fs9.writeFile(files.revised, revised);
165241
+ if (signal?.aborted) throw new Error("The comparison was stopped.");
165242
+ const result = await environment.run(powershellPath(environment), powershellArgs(COMPARE_SCRIPT), {
165243
+ env: {
165244
+ ...environment.env,
165245
+ PI_OUTPOST_COMPARE_ORIGINAL: files.original,
165246
+ PI_OUTPOST_COMPARE_REVISED: files.revised,
165247
+ PI_OUTPOST_COMPARE_OUTPUT: files.output,
165248
+ PI_OUTPOST_COMPARE_AUTHOR: COMPARISON_AUTHOR
165249
+ },
165250
+ timeoutMs: settings2.timeoutMs,
165251
+ signal,
165252
+ holdKillUntil: WORD_STARTED_LINE
165253
+ });
165254
+ stopStartedWord(result, environment, signal);
165255
+ if (signal?.aborted) throw new Error("The comparison was stopped.");
165256
+ const bytes = result.code === 0 ? await fs9.readFile(files.output).catch(() => null) : null;
165257
+ if (bytes !== null && bytes.length > 0) return bytes;
165258
+ if (result.timedOut) {
165259
+ throw new Error(
165260
+ `Word did not finish the comparison within ${Math.round(settings2.timeoutMs / 1e3)} s (office.renderTimeoutMs). ${MANUAL_COMPARISON}`
165261
+ );
165262
+ }
165263
+ throw new Error(`Microsoft Word is unavailable: ${powershellError(result) ?? describeFailure(result, settings2.timeoutMs)}. ${MANUAL_COMPARISON}`);
165264
+ } finally {
165265
+ await fs9.rm(workDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }).catch(() => {
165266
+ });
165267
+ }
165268
+ }
165269
+ function powershellError(result) {
165270
+ const first = result.stderr.split(/\r?\n/).map((line) => line.trim()).find((line) => line !== "");
165271
+ return first?.replace(/\.$/, "");
165272
+ }
165273
+ async function comparisonAnswer(compared, names2, sources = {}) {
165274
+ const opening = `> Compared by Microsoft Word: "${names2.original}" \u2192 "${names2.revised}". The authors and dates on the changes below are the comparison's, not those of whoever edited the document.`;
165275
+ const written = names2.written === void 0 ? [] : [`Saved the compared document, with Word's tracked changes, to \`${names2.written}\`.`];
165276
+ const own4 = sourcesLine(names2, sources);
165277
+ let extraction;
165278
+ let truncated = false;
165279
+ try {
165280
+ try {
165281
+ extraction = await extractDocx(compared, { review: true, full: true });
165282
+ } catch (error) {
165283
+ if (!(error instanceof DocxError) || error.reason !== "too-large") throw error;
165284
+ extraction = await extractDocx(compared, { review: true });
165285
+ truncated = true;
165286
+ }
165287
+ } catch (error) {
165288
+ if (error instanceof DocxError) throw new Error(`Word's compared document could not be read: ${error.message}`);
165289
+ throw error;
165290
+ }
165291
+ if ((extraction.review?.revisions ?? 0) === 0) {
165292
+ return [opening, ...own4, "Word found no difference between the two versions' text (formatting is not compared).", ...written].join("\n\n");
165293
+ }
165294
+ const rest = !truncated ? ["> This is every difference Word found between the two versions. Reading the two versions is not needed to find them."] : names2.written !== void 0 ? [`> Read the rest with docx_extract on \`${names2.written}\` with review: true and the blocks named above.`] : ["> Call docx_compare again with output_path to keep the compared document, then read the rest with docx_extract, review: true and the blocks named above."];
165295
+ return [opening, ...own4, extraction.markdown, ...rest, ...written].join("\n\n");
165296
+ }
165297
+ function sourcesLine(names2, sources) {
165298
+ const { original, revised } = sources;
165299
+ if (original === void 0 || revised === void 0) return [];
165300
+ const holds = (counts) => counts.revisions > 0 || counts.comments > 0;
165301
+ if (!holds(original) && !holds(revised)) return ["> Neither version holds tracked changes or comments of its own."];
165302
+ const described = [
165303
+ [names2.original, original],
165304
+ [names2.revised, revised]
165305
+ ].filter(([, counts]) => holds(counts)).map(([name, counts]) => `"${name}" holds ${countOf(counts)} of its own`);
165306
+ return [`> ${described.join("; ")}, not listed here: read it with docx_extract and review: true to see them.`];
165307
+ }
165308
+ function countOf(counts) {
165309
+ const plural2 = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
165310
+ return [counts.revisions > 0 ? plural2(counts.revisions, "tracked change") : "", counts.comments > 0 ? plural2(counts.comments, "comment") : ""].filter(Boolean).join(" and ");
165311
+ }
165312
+ async function reviewLayerOf(bytes) {
165313
+ try {
165314
+ return (await extractDocx(bytes, { review: true, maxBlocks: 1 })).review;
165315
+ } catch {
165316
+ return void 0;
165317
+ }
165318
+ }
165319
+ function createDocxCompareToolDefinition(options2) {
165320
+ const environment = options2.environment ?? defaultEnvironment();
165321
+ return {
165322
+ name: "docx_compare",
165323
+ label: "Compare Word documents",
165324
+ description: [
165325
+ "Compare two versions of a Word document (.docx) with Microsoft Word, and return what changed in the review reading:",
165326
+ "{++inserted++} and {--deleted--} text, moves marked [mN] at both ends, each change listed at the end with its section.",
165327
+ "Use it whenever you have two versions of a document and need what changed between them, for instance a revision sent without tracked changes.",
165328
+ "Its answer is the complete list of differences, and says whether either version holds tracked changes of its own: do not read the two versions to compare them yourself.",
165329
+ "Formatting is not compared. The authors and dates on the changes are the comparison's, not the editors'. Neither file is modified.",
165330
+ "output_path also saves Word's compared document, for the user to open in Word."
165331
+ ].join(" "),
165332
+ promptSnippet: "Compare two versions of a Word document with Word, to see what changed",
165333
+ parameters: typebox_exports.Object({
165334
+ original: typebox_exports.String({ description: "The earlier version (.docx)." }),
165335
+ revised: typebox_exports.String({ description: "The later version (.docx)." }),
165336
+ output_path: typebox_exports.Optional(typebox_exports.String({ description: "Also save Word's compared document at this workspace path (.docx). The file must not already exist." }))
165337
+ }),
165338
+ executionMode: "sequential",
165339
+ async execute(_toolCallId, params, signal) {
165340
+ const p = params;
165341
+ const original = await readSource(p.original, options2, options2.maxBytes, "Word");
165342
+ const revised = await readSource(p.revised, options2, options2.maxBytes, "Word");
165343
+ let destination;
165344
+ if (p.output_path !== void 0) {
165345
+ if (!/\.docx$/i.test(p.output_path)) throw new Error(`"${p.output_path}" must end in .docx.`);
165346
+ destination = await assertWritableDestination(p.output_path, { cwd: options2.cwd, writableRoot: options2.writableRoot });
165347
+ if (await fs9.lstat(destination).then(() => true, () => false)) {
165348
+ throw new Error(`"${p.output_path}" already exists; choose another path for the compared document.`);
165349
+ }
165350
+ if (!await fs9.stat(path12.dirname(destination)).then((stat) => stat.isDirectory(), () => false)) {
165351
+ throw new Error(`The folder for "${p.output_path}" does not exist.`);
165352
+ }
165353
+ }
165354
+ const compared = await compareWithWord(original.bytes, revised.bytes, options2.render, environment, signal);
165355
+ if (destination !== void 0) {
165356
+ try {
165357
+ await fs9.writeFile(destination, compared, { flag: "wx" });
165358
+ } catch (error) {
165359
+ const code3 = error.code;
165360
+ if (code3 === "EEXIST") throw new Error(`"${p.output_path}" already exists; choose another path for the compared document.`);
165361
+ if (code3 === "ENOENT") throw new Error(`The folder for "${p.output_path}" does not exist.`);
165362
+ throw error;
165363
+ }
165364
+ }
165365
+ const [ownOriginal, ownRevised] = await Promise.all([reviewLayerOf(original.bytes), reviewLayerOf(revised.bytes)]);
165366
+ const text7 = await comparisonAnswer(
165367
+ compared,
165368
+ {
165369
+ original: p.original,
165370
+ revised: p.revised,
165371
+ ...p.output_path === void 0 ? {} : { written: p.output_path }
165372
+ },
165373
+ {
165374
+ ...ownOriginal === void 0 ? {} : { original: ownOriginal },
165375
+ ...ownRevised === void 0 ? {} : { revised: ownRevised }
165376
+ }
165377
+ );
165378
+ return { content: [{ type: "text", text: text7 }], details: void 0 };
165379
+ }
165380
+ };
165381
+ }
165382
+
164680
165383
  // ../server/src/structuredExchangeFigureTool.ts
164681
- import fs10 from "node:fs/promises";
164682
- import path13 from "node:path";
165384
+ import fs11 from "node:fs/promises";
165385
+ import path14 from "node:path";
164683
165386
 
164684
165387
  // ../shared/src/structuredExchangeText.ts
164685
165388
  var CHAR_WIDTH = 6.6;
@@ -165614,32 +166317,32 @@ function findCycle(edges) {
165614
166317
  outgoing.set(edge.from, list3);
165615
166318
  }
165616
166319
  const state2 = /* @__PURE__ */ new Map();
165617
- const path21 = [];
166320
+ const path22 = [];
165618
166321
  for (const root2 of outgoing.keys()) {
165619
166322
  if (state2.has(root2)) continue;
165620
166323
  const stack = [{ id: root2, next: 0 }];
165621
166324
  state2.set(root2, "open");
165622
- path21.push({ id: root2, index: -1 });
166325
+ path22.push({ id: root2, index: -1 });
165623
166326
  while (stack.length > 0) {
165624
166327
  const frame = stack[stack.length - 1];
165625
166328
  const edgesOut = outgoing.get(frame.id) ?? [];
165626
166329
  if (frame.next >= edgesOut.length) {
165627
166330
  state2.set(frame.id, "done");
165628
166331
  stack.pop();
165629
- path21.pop();
166332
+ path22.pop();
165630
166333
  continue;
165631
166334
  }
165632
166335
  const edge = edgesOut[frame.next++];
165633
166336
  const seen = state2.get(edge.to);
165634
166337
  if (seen === "open") {
165635
- const start = path21.findIndex((step) => step.id === edge.to);
165636
- const ids2 = [...path21.slice(start).map((step) => step.id), edge.to];
166338
+ const start = path22.findIndex((step) => step.id === edge.to);
166339
+ const ids2 = [...path22.slice(start).map((step) => step.id), edge.to];
165637
166340
  return { ids: ids2, index: edge.index };
165638
166341
  }
165639
166342
  if (seen === void 0) {
165640
166343
  state2.set(edge.to, "open");
165641
166344
  stack.push({ id: edge.to, next: 0 });
165642
- path21.push({ id: edge.to, index: edge.index });
166345
+ path22.push({ id: edge.to, index: edge.index });
165643
166346
  }
165644
166347
  }
165645
166348
  }
@@ -177218,13 +177921,13 @@ var STRUCTURED_EXCHANGE_RULES_CEILINGS = {
177218
177921
  };
177219
177922
 
177220
177923
  // ../shared/src/structuredExchangeDocumentItems.ts
177221
- function effective(raw, path21) {
177924
+ function effective(raw, path22) {
177222
177925
  const set = raw.set ?? void 0;
177223
177926
  const attributes2 = { ...raw.attributes ?? {} };
177224
177927
  Object.assign(attributes2, set?.attributes ?? {});
177225
177928
  for (const name of set?.removeAttributes ?? []) delete attributes2[name];
177226
177929
  const kind = typeof set?.kind === "string" ? set.kind : typeof raw.kind === "string" ? raw.kind : void 0;
177227
- return { ...typeof raw.id === "string" ? { id: raw.id } : {}, ...kind === void 0 ? {} : { kind }, attributes: attributes2, path: path21 };
177930
+ return { ...typeof raw.id === "string" ? { id: raw.id } : {}, ...kind === void 0 ? {} : { kind }, attributes: attributes2, path: path22 };
177228
177931
  }
177229
177932
  function itemsAndRelationships(envelope) {
177230
177933
  const document4 = envelope;
@@ -177363,8 +178066,8 @@ function evaluateRules(envelope, rules, options2 = {}) {
177363
178066
  });
177364
178067
  }
177365
178068
  }
177366
- const order2 = (path21) => {
177367
- const [, , collection, index4] = path21.split("/");
178069
+ const order2 = (path22) => {
178070
+ const [, , collection, index4] = path22.split("/");
177368
178071
  const rank = { nodes: 0, rows: 0, edges: 1, relations: 1 }[collection] ?? 2;
177369
178072
  return rank * 1e6 + Number(index4);
177370
178073
  };
@@ -177435,12 +178138,12 @@ function checkAgainstProfile(envelope, profile, options2 = {}) {
177435
178138
  if (typeof value === "string") return `the string ${JSON.stringify(value)}`;
177436
178139
  return `the ${typeof value} ${String(value)}`;
177437
178140
  }
177438
- function checkScalar(attribute, kind, value, path21) {
178141
+ function checkScalar(attribute, kind, value, path22) {
177439
178142
  const typed = attribute.type === "string" || attribute.type === "enumeration" ? typeof value === "string" : attribute.type === "number" ? typeof value === "number" : attribute.type === "boolean" ? typeof value === "boolean" : value !== null && typeof value === "object" && typeof value.ref === "string";
177440
178143
  if (!typed) {
177441
178144
  issues.push({
177442
178145
  rule: "profile/attribute-type",
177443
- path: path21,
178146
+ path: path22,
177444
178147
  message: `attribute "${attribute.name}" of kind "${kind}" holds a ${describeType(attribute)}, and this is ${describeValue(value)}`
177445
178148
  });
177446
178149
  return;
@@ -177451,25 +178154,25 @@ function checkAgainstProfile(envelope, profile, options2 = {}) {
177451
178154
  if (attribute.closed) {
177452
178155
  issues.push({
177453
178156
  rule: "profile/closed-enumeration",
177454
- path: path21,
178157
+ path: path22,
177455
178158
  message: `"${value}" is not a value of "${attribute.name}" on kind "${kind}"; profile "${profile.id}" allows ${quoted2(declared)}`
177456
178159
  });
177457
178160
  } else {
177458
178161
  notes.push({
177459
178162
  rule: "profile/open-enumeration-value",
177460
- path: path21,
178163
+ path: path22,
177461
178164
  value,
177462
178165
  declared: [...declared],
177463
178166
  message: `"${value}" is not among the values profile "${profile.id}" lists for "${attribute.name}" on kind "${kind}" (${quoted2(declared)}); accepted, since that enumeration is open`
177464
178167
  });
177465
178168
  }
177466
178169
  }
177467
- function checkValue(attribute, kind, value, path21) {
178170
+ function checkValue(attribute, kind, value, path22) {
177468
178171
  if (value === null) {
177469
178172
  if (attribute.required) {
177470
178173
  issues.push({
177471
178174
  rule: "profile/null-required-attribute",
177472
- path: path21,
178175
+ path: path22,
177473
178176
  message: `attribute "${attribute.name}" is required on kind "${kind}", and null is not a value`
177474
178177
  });
177475
178178
  }
@@ -177478,13 +178181,13 @@ function checkAgainstProfile(envelope, profile, options2 = {}) {
177478
178181
  if (Array.isArray(value) !== (attribute.list === true)) {
177479
178182
  issues.push({
177480
178183
  rule: "profile/attribute-type",
177481
- path: path21,
178184
+ path: path22,
177482
178185
  message: attribute.list ? `attribute "${attribute.name}" of kind "${kind}" holds a list of ${describeType(attribute)}s, not one value` : `attribute "${attribute.name}" of kind "${kind}" holds one ${describeType(attribute)}, not a list`
177483
178186
  });
177484
178187
  return;
177485
178188
  }
177486
- if (Array.isArray(value)) value.forEach((item, index4) => checkScalar(attribute, kind, item, `${path21}/${index4}`));
177487
- else checkScalar(attribute, kind, value, path21);
178189
+ if (Array.isArray(value)) value.forEach((item, index4) => checkScalar(attribute, kind, item, `${path22}/${index4}`));
178190
+ else checkScalar(attribute, kind, value, path22);
177488
178191
  }
177489
178192
  function checkItem(item, at2, vocabulary, noun) {
177490
178193
  const kinds = vocabularies[vocabulary];
@@ -177515,17 +178218,17 @@ function checkAgainstProfile(envelope, profile, options2 = {}) {
177515
178218
  const checkAttributes = (values, base) => {
177516
178219
  if (values === null || typeof values !== "object") return;
177517
178220
  for (const [name, value] of Object.entries(values)) {
177518
- const path21 = `${base}/${segment(name)}`;
178221
+ const path22 = `${base}/${segment(name)}`;
177519
178222
  const attribute = attributes2.get(name);
177520
178223
  if (attribute === void 0) {
177521
178224
  issues.push({
177522
178225
  rule: "profile/undeclared-attribute",
177523
- path: path21,
178226
+ path: path22,
177524
178227
  message: `kind "${kind}" of profile "${profile.id}" has no attribute "${name}"; it declares ${quoted2([...attributes2.keys()])}`
177525
178228
  });
177526
178229
  continue;
177527
178230
  }
177528
- checkValue(attribute, kind, value, path21);
178231
+ checkValue(attribute, kind, value, path22);
177529
178232
  }
177530
178233
  };
177531
178234
  checkAttributes(item.attributes, `${at2}/attributes`);
@@ -177650,8 +178353,8 @@ function holdToProfile(envelope, context, options2 = {}) {
177650
178353
 
177651
178354
  // ../shared/src/structuredExchangeProjectRegistry.ts
177652
178355
  import { createHash as createHash2 } from "node:crypto";
177653
- import fs9 from "node:fs/promises";
177654
- import path12 from "node:path";
178356
+ import fs10 from "node:fs/promises";
178357
+ import path13 from "node:path";
177655
178358
 
177656
178359
  // ../shared/schemas/structured-exchange-profile-1.json
177657
178360
  var structured_exchange_profile_1_default = {
@@ -178168,10 +178871,10 @@ function validateRegistry(value) {
178168
178871
  const registry = value;
178169
178872
  const issues = [];
178170
178873
  const seenPaths = /* @__PURE__ */ new Map();
178171
- (registry.profiles ?? []).forEach((listed, index4) => {
178172
- const first = seenPaths.get(listed);
178173
- if (first === void 0) seenPaths.set(listed, index4);
178174
- else issues.push({ rule: "registry/repeated-profile-path", path: `/profiles/${index4}`, message: `"${listed}" is already listed at /profiles/${first}` });
178874
+ (registry.profiles ?? []).forEach((listed2, index4) => {
178875
+ const first = seenPaths.get(listed2);
178876
+ if (first === void 0) seenPaths.set(listed2, index4);
178877
+ else issues.push({ rule: "registry/repeated-profile-path", path: `/profiles/${index4}`, message: `"${listed2}" is already listed at /profiles/${first}` });
178175
178878
  });
178176
178879
  return issues.length > 0 ? { valid: false, issues } : { valid: true, registry, issues: [] };
178177
178880
  }
@@ -178545,29 +179248,29 @@ async function realResolve2(target) {
178545
179248
  let tail = "";
178546
179249
  for (; ; ) {
178547
179250
  try {
178548
- const real = await fs9.realpath(existing);
178549
- return tail ? path12.join(real, tail) : real;
179251
+ const real = await fs10.realpath(existing);
179252
+ return tail ? path13.join(real, tail) : real;
178550
179253
  } catch {
178551
- const parent = path12.dirname(existing);
179254
+ const parent = path13.dirname(existing);
178552
179255
  if (parent === existing) return target;
178553
- tail = tail ? path12.join(path12.basename(existing), tail) : path12.basename(existing);
179256
+ tail = tail ? path13.join(path13.basename(existing), tail) : path13.basename(existing);
178554
179257
  existing = parent;
178555
179258
  }
178556
179259
  }
178557
179260
  }
178558
- var isWithin2 = (root2, target) => target === root2 || target.startsWith(root2 + path12.sep);
179261
+ var isWithin2 = (root2, target) => target === root2 || target.startsWith(root2 + path13.sep);
178559
179262
  function digestOf(text7) {
178560
179263
  return `sha256:${createHash2("sha256").update(text7, "utf8").digest("hex")}`;
178561
179264
  }
178562
179265
  async function readConfinedJson(root2, relative, maxBytes, namespace) {
178563
- const resolved = await realResolve2(path12.resolve(root2, relative));
178564
- if (path12.isAbsolute(relative) || !isWithin2(root2, resolved)) {
179266
+ const resolved = await realResolve2(path13.resolve(root2, relative));
179267
+ if (path13.isAbsolute(relative) || !isWithin2(root2, resolved)) {
178565
179268
  return {
178566
179269
  ok: false,
178567
179270
  issue: { rule: `${namespace}/outside-project`, path: "", message: `"${relative}" is outside the project directory` }
178568
179271
  };
178569
179272
  }
178570
- const stat = await fs9.stat(resolved).catch(() => null);
179273
+ const stat = await fs10.stat(resolved).catch(() => null);
178571
179274
  if (stat === null) return { ok: "missing" };
178572
179275
  if (!stat.isFile()) {
178573
179276
  return { ok: false, issue: { rule: `${namespace}/not-a-file`, path: "", message: `"${relative}" is not a file` } };
@@ -178587,7 +179290,7 @@ async function readConfinedJson(root2, relative, maxBytes, namespace) {
178587
179290
  }
178588
179291
  let text7;
178589
179292
  try {
178590
- text7 = await fs9.readFile(resolved, "utf8");
179293
+ text7 = await fs10.readFile(resolved, "utf8");
178591
179294
  } catch (error) {
178592
179295
  if (error.code === "ENOENT") return { ok: "missing" };
178593
179296
  return { ok: false, issue: { rule: `${namespace}/unreadable`, path: "", message: `"${relative}" cannot be read: ${error.message}` } };
@@ -178599,7 +179302,7 @@ async function readConfinedJson(root2, relative, maxBytes, namespace) {
178599
179302
  }
178600
179303
  }
178601
179304
  async function readProjectRegistry(projectRoot, registryPath = STRUCTURED_EXCHANGE_PROFILE_REGISTRY_PATH) {
178602
- const root2 = await realResolve2(path12.resolve(projectRoot));
179305
+ const root2 = await realResolve2(path13.resolve(projectRoot));
178603
179306
  const registryFile = registryPath;
178604
179307
  const registryRead = await readConfinedJson(root2, registryFile, STRUCTURED_EXCHANGE_PROFILE_CEILINGS.registryBytes, "registry");
178605
179308
  if (registryRead.ok === "missing") return { state: "none" };
@@ -178612,54 +179315,54 @@ async function readProjectRegistry(projectRoot, registryPath = STRUCTURED_EXCHAN
178612
179315
  const files = [];
178613
179316
  const issues = [];
178614
179317
  const loaded = [];
178615
- for (const [index4, listed] of (registry.profiles ?? []).entries()) {
178616
- const read = await readConfinedJson(root2, listed, STRUCTURED_EXCHANGE_PROFILE_CEILINGS.profileBytes, "profile-format");
179318
+ for (const [index4, listed2] of (registry.profiles ?? []).entries()) {
179319
+ const read = await readConfinedJson(root2, listed2, STRUCTURED_EXCHANGE_PROFILE_CEILINGS.profileBytes, "profile-format");
178617
179320
  if (read.ok === "missing") {
178618
- issues.push({ rule: "registry/missing-profile", path: `/profiles/${index4}`, message: `"${listed}" does not exist`, file: registryFile });
179321
+ issues.push({ rule: "registry/missing-profile", path: `/profiles/${index4}`, message: `"${listed2}" does not exist`, file: registryFile });
178619
179322
  continue;
178620
179323
  }
178621
179324
  if (read.ok === false) {
178622
179325
  issues.push(
178623
- read.issue.rule === "profile-format/outside-project" ? { ...read.issue, rule: "registry/profile-outside-project", path: `/profiles/${index4}`, file: registryFile } : { ...read.issue, file: listed }
179326
+ read.issue.rule === "profile-format/outside-project" ? { ...read.issue, rule: "registry/profile-outside-project", path: `/profiles/${index4}`, file: registryFile } : { ...read.issue, file: listed2 }
178624
179327
  );
178625
179328
  continue;
178626
179329
  }
178627
179330
  const verdict = validateProfile(read.value);
178628
179331
  if (!verdict.valid) {
178629
- issues.push(...verdict.issues.map((issue) => ({ ...issue, file: listed })));
179332
+ issues.push(...verdict.issues.map((issue) => ({ ...issue, file: listed2 })));
178630
179333
  continue;
178631
179334
  }
178632
- loaded.push({ path: listed, profile: verdict.profile });
178633
- files.push({ path: listed, sha256: read.sha256 });
179335
+ loaded.push({ path: listed2, profile: verdict.profile });
179336
+ files.push({ path: listed2, sha256: read.sha256 });
178634
179337
  }
178635
179338
  if (issues.length > 0) return { state: "unusable", issues };
178636
179339
  const consistency = registryConsistencyIssues(registry, loaded);
178637
179340
  if (consistency.length > 0) return { state: "unusable", issues: consistency.map((issue) => ({ ...issue, file: registryFile })) };
178638
179341
  const profiles = new Map(loaded.map((entry) => [entry.profile.id, entry.profile]));
178639
179342
  const loadedRules = [];
178640
- for (const [index4, listed] of (registry.rules ?? []).entries()) {
178641
- const read = await readConfinedJson(root2, listed, STRUCTURED_EXCHANGE_RULES_CEILINGS.rulesBytes, "rules-format");
179343
+ for (const [index4, listed2] of (registry.rules ?? []).entries()) {
179344
+ const read = await readConfinedJson(root2, listed2, STRUCTURED_EXCHANGE_RULES_CEILINGS.rulesBytes, "rules-format");
178642
179345
  if (read.ok === "missing") {
178643
- issues.push({ rule: "registry/missing-rules", path: `/rules/${index4}`, message: `"${listed}" does not exist`, file: registryFile });
179346
+ issues.push({ rule: "registry/missing-rules", path: `/rules/${index4}`, message: `"${listed2}" does not exist`, file: registryFile });
178644
179347
  continue;
178645
179348
  }
178646
179349
  if (read.ok === false) {
178647
179350
  issues.push(
178648
- read.issue.rule === "rules-format/outside-project" ? { ...read.issue, rule: "registry/rules-outside-project", path: `/rules/${index4}`, file: registryFile } : { ...read.issue, file: listed }
179351
+ read.issue.rule === "rules-format/outside-project" ? { ...read.issue, rule: "registry/rules-outside-project", path: `/rules/${index4}`, file: registryFile } : { ...read.issue, file: listed2 }
178649
179352
  );
178650
179353
  continue;
178651
179354
  }
178652
179355
  const verdict = validateRules(read.value);
178653
179356
  if (!verdict.valid) {
178654
- issues.push(...verdict.issues.map((issue) => ({ ...issue, file: listed })));
179357
+ issues.push(...verdict.issues.map((issue) => ({ ...issue, file: listed2 })));
178655
179358
  continue;
178656
179359
  }
178657
179360
  const profile = profiles.get(verdict.rules.profile);
178658
179361
  if (profile !== void 0) {
178659
- issues.push(...rulesAgainstProfile(verdict.rules, profile).map((issue) => ({ ...issue, file: listed })));
179362
+ issues.push(...rulesAgainstProfile(verdict.rules, profile).map((issue) => ({ ...issue, file: listed2 })));
178660
179363
  }
178661
- loadedRules.push({ path: listed, rules: verdict.rules });
178662
- files.push({ path: listed, sha256: read.sha256 });
179364
+ loadedRules.push({ path: listed2, rules: verdict.rules });
179365
+ files.push({ path: listed2, sha256: read.sha256 });
178663
179366
  }
178664
179367
  if (issues.length === 0) {
178665
179368
  issues.push(...registryRulesIssues(loadedRules, profiles).map((issue) => ({ ...issue, file: registryFile })));
@@ -178775,7 +179478,7 @@ function createStructuredExchangeFigureToolDefinition(options2) {
178775
179478
  reference_line: referenceLine,
178776
179479
  comparison
178777
179480
  } = params;
178778
- const resolved = await realResolve(path13.resolve(options2.cwd, target));
179481
+ const resolved = await realResolve(path14.resolve(options2.cwd, target));
178779
179482
  if (!isWithinAny(options2.allowedRoots, resolved)) {
178780
179483
  throw new Error(`Access denied: "${target}" is outside the sandbox (${options2.allowedRoots[0]})`);
178781
179484
  }
@@ -178788,12 +179491,12 @@ function createStructuredExchangeFigureToolDefinition(options2) {
178788
179491
  cwd: options2.cwd,
178789
179492
  writableRoot: options2.writableRoot
178790
179493
  });
178791
- const stat = await fs10.stat(resolved).catch(() => null);
179494
+ const stat = await fs11.stat(resolved).catch(() => null);
178792
179495
  if (stat === null || !stat.isFile()) throw new Error(`No such file: ${target}`);
178793
179496
  if (stat.size > options2.maxBytes) {
178794
179497
  throw new Error(`"${target}" is larger than the ${describeSize6(options2.maxBytes)} document limit`);
178795
179498
  }
178796
- const text7 = await fs10.readFile(resolved, "utf8");
179499
+ const text7 = await fs11.readFile(resolved, "utf8");
178797
179500
  const parsed = parseSerializedStructuredExchange(text7, checkStructuredExchangeSchema, options2.limits);
178798
179501
  let heldTo;
178799
179502
  let appearance;
@@ -178871,9 +179574,9 @@ function createStructuredExchangeFigureToolDefinition(options2) {
178871
179574
  isError: true
178872
179575
  };
178873
179576
  }
178874
- await fs10.mkdir(path13.dirname(writeTo), { recursive: true });
179577
+ await fs11.mkdir(path14.dirname(writeTo), { recursive: true });
178875
179578
  try {
178876
- await fs10.writeFile(writeTo, result.svg, { flag: "wx" });
179579
+ await fs11.writeFile(writeTo, result.svg, { flag: "wx" });
178877
179580
  } catch (error) {
178878
179581
  const code3 = error.code;
178879
179582
  if (code3 === "EEXIST") {
@@ -178892,7 +179595,7 @@ function createStructuredExchangeFigureToolDefinition(options2) {
178892
179595
  result.viewpoint === void 0 ? void 0 : `Drawn for viewpoint \`${result.viewpoint.id}\` (${result.viewpoint.label}), declared by ${result.viewpoint.source === "profile" ? `this project's profile "${result.viewpoint.profile}"` : "the document"}.`,
178893
179596
  result.narrowing === void 0 ? void 0 : `The figure states: "${result.narrowing}"`,
178894
179597
  result.overWidth === true ? `The plan is too long to fit the width asked at a legible scale, so the figure is wider than ${width}; split the range or ask for more width.` : void 0,
178895
- `Reference it from Markdown as a relative path, e.g. \`![${path13.basename(destination, ".svg")}](${destination})\`.`
179598
+ `Reference it from Markdown as a relative path, e.g. \`![${path14.basename(destination, ".svg")}](${destination})\`.`
178896
179599
  ].filter((line) => line !== void 0).join("\n")
178897
179600
  }
178898
179601
  ],
@@ -178903,8 +179606,8 @@ function createStructuredExchangeFigureToolDefinition(options2) {
178903
179606
  }
178904
179607
 
178905
179608
  // ../server/src/timelineComparisonTool.ts
178906
- import fs11 from "node:fs/promises";
178907
- import path14 from "node:path";
179609
+ import fs12 from "node:fs/promises";
179610
+ import path15 from "node:path";
178908
179611
 
178909
179612
  // ../server/src/structuredExchangeTool.ts
178910
179613
  var DESCRIPTION6 = [
@@ -179114,14 +179817,14 @@ var DESCRIPTION7 = [
179114
179817
  "The current plan is not modified. To put the comparison in a report, give `output_path` and draw it with write_structure_figure."
179115
179818
  ].join(" ");
179116
179819
  async function readTimeline(options2, target) {
179117
- const resolved = await realResolve(path14.resolve(options2.cwd, target));
179820
+ const resolved = await realResolve(path15.resolve(options2.cwd, target));
179118
179821
  if (!isWithinAny(options2.allowedRoots, resolved)) {
179119
179822
  throw new Error(`Access denied: "${target}" is outside the sandbox (${options2.allowedRoots[0]})`);
179120
179823
  }
179121
- const stat = await fs11.stat(resolved).catch(() => null);
179824
+ const stat = await fs12.stat(resolved).catch(() => null);
179122
179825
  if (stat === null || !stat.isFile()) throw new Error(`No such file: ${target}`);
179123
179826
  if (stat.size > options2.maxBytes) throw new Error(`"${target}" is larger than the document limit`);
179124
- const verdict = parseSerializedStructuredExchange(await fs11.readFile(resolved, "utf8"), checkStructuredExchangeSchema, options2.limits);
179827
+ const verdict = parseSerializedStructuredExchange(await fs12.readFile(resolved, "utf8"), checkStructuredExchangeSchema, options2.limits);
179125
179828
  if (!verdict.valid) {
179126
179829
  const lines = verdict.issues.map((issue) => `- ${issue.rule} at ${issue.path === "" ? "(document)" : issue.path}: ${issue.message}`);
179127
179830
  return { ok: false, text: [`\`${target}\` does not satisfy the structured-exchange contract:`, ...lines].join("\n") };
@@ -179131,7 +179834,7 @@ async function readTimeline(options2, target) {
179131
179834
  if (data.comparedTo !== void 0) {
179132
179835
  return { ok: false, text: `\`${target}\` is already a comparison (with "${data.comparedTo.label}"); compare the plans themselves.` };
179133
179836
  }
179134
- return { ok: true, data, name: path14.basename(target).replace(/\.json$/i, "") };
179837
+ return { ok: true, data, name: path15.basename(target).replace(/\.json$/i, "") };
179135
179838
  }
179136
179839
  function createTimelineComparisonToolDefinition(options2) {
179137
179840
  return {
@@ -179173,9 +179876,9 @@ function createTimelineComparisonToolDefinition(options2) {
179173
179876
  };
179174
179877
  }
179175
179878
  if (writeTo !== void 0) {
179176
- await fs11.mkdir(path14.dirname(writeTo), { recursive: true });
179879
+ await fs12.mkdir(path15.dirname(writeTo), { recursive: true });
179177
179880
  try {
179178
- await fs11.writeFile(writeTo, `${JSON.stringify(document4, null, 2)}
179881
+ await fs12.writeFile(writeTo, `${JSON.stringify(document4, null, 2)}
179179
179882
  `, { flag: "wx" });
179180
179883
  } catch (error) {
179181
179884
  if (error.code === "EEXIST") {
@@ -179197,8 +179900,8 @@ function createTimelineComparisonToolDefinition(options2) {
179197
179900
  }
179198
179901
 
179199
179902
  // ../server/src/drawioTool.ts
179200
- import fs12 from "node:fs/promises";
179201
- import path15 from "node:path";
179903
+ import fs13 from "node:fs/promises";
179904
+ import path16 from "node:path";
179202
179905
 
179203
179906
  // ../server/src/drawio.ts
179204
179907
  import { inflateRawSync } from "node:zlib";
@@ -179459,19 +180162,19 @@ function checkDrawio(xml) {
179459
180162
  issues
179460
180163
  };
179461
180164
  }
179462
- function describeDrawioReport(path21, report) {
180165
+ function describeDrawioReport(path22, report) {
179463
180166
  const shapes = report.pages.reduce((sum, page) => sum + page.shapes, 0);
179464
180167
  const connectors = report.pages.reduce((sum, page) => sum + page.connectors, 0);
179465
180168
  const errors = report.issues.filter((issue) => issue.severity === "error");
179466
180169
  const warnings = report.issues.filter((issue) => issue.severity === "warning");
179467
180170
  const summary = `${report.pages.length} page${report.pages.length === 1 ? "" : "s"} (${report.pages.map((page) => `"${page.name}"`).join(", ")}), ${shapes} shape${shapes === 1 ? "" : "s"}, ${connectors} connector${connectors === 1 ? "" : "s"}`;
179468
- if (report.issues.length === 0) return `\`${path21}\` is a valid draw.io diagram with no defect found: ${summary}.`;
180171
+ if (report.issues.length === 0) return `\`${path22}\` is a valid draw.io diagram with no defect found: ${summary}.`;
179469
180172
  const lines = [
179470
- errors.length > 0 ? `\`${path21}\` would not open as intended: ${errors.length} error${errors.length === 1 ? "" : "s"} and ${warnings.length} warning${warnings.length === 1 ? "" : "s"}. ${summary}.` : `\`${path21}\` opens, but ${warnings.length} warning${warnings.length === 1 ? "" : "s"} would make it read badly. ${summary}.`
180173
+ errors.length > 0 ? `\`${path22}\` would not open as intended: ${errors.length} error${errors.length === 1 ? "" : "s"} and ${warnings.length} warning${warnings.length === 1 ? "" : "s"}. ${summary}.` : `\`${path22}\` opens, but ${warnings.length} warning${warnings.length === 1 ? "" : "s"} would make it read badly. ${summary}.`
179471
180174
  ];
179472
- const listed = [...errors, ...warnings].slice(0, MAX_LISTED_ISSUES);
179473
- for (const issue of listed) lines.push(`- ${issue.severity} [${issue.page}]: ${issue.message}`);
179474
- if (report.issues.length > listed.length) lines.push(`- \u2026 and ${report.issues.length - listed.length} more`);
180175
+ const listed2 = [...errors, ...warnings].slice(0, MAX_LISTED_ISSUES);
180176
+ for (const issue of listed2) lines.push(`- ${issue.severity} [${issue.page}]: ${issue.message}`);
180177
+ if (report.issues.length > listed2.length) lines.push(`- \u2026 and ${report.issues.length - listed2.length} more`);
179475
180178
  lines.push(errors.length > 0 ? "Fix the errors, then run drawio_check again." : "Move the shapes apart or resize them, then run drawio_check again.");
179476
180179
  return lines.join("\n");
179477
180180
  }
@@ -179496,19 +180199,20 @@ function createDrawioCheckToolDefinition(options2) {
179496
180199
  promptSnippet: "Check a .drawio diagram for errors and layout problems",
179497
180200
  promptGuidelines: [
179498
180201
  "When the user wants a diagram they can open or edit in draw.io, write it as a .drawio file and check it with drawio_check; the interface draws it in the file viewer.",
179499
- "After every write or edit of a .drawio file, run drawio_check and fix what it reports before saying the diagram is done."
180202
+ "After every write or edit of a .drawio file, run drawio_check and fix what it reports before saying the diagram is done.",
180203
+ "Once drawio_check reports no error, show the diagram in your reply as a picture of the file \u2014 ![name](./path/to/file.drawio) \u2014 where the conversation draws it."
179500
180204
  ],
179501
180205
  parameters: parameters8,
179502
180206
  async execute(_toolCallId, params) {
179503
180207
  const { path: target } = params;
179504
- const resolved = await realResolve(path15.resolve(options2.cwd, target));
180208
+ const resolved = await realResolve(path16.resolve(options2.cwd, target));
179505
180209
  if (!isWithinAny(options2.allowedRoots, resolved)) {
179506
180210
  throw new Error(`Access denied: "${target}" is outside the sandbox (${options2.allowedRoots[0]})`);
179507
180211
  }
179508
- const stat = await fs12.stat(resolved).catch(() => null);
180212
+ const stat = await fs13.stat(resolved).catch(() => null);
179509
180213
  if (stat === null || !stat.isFile()) return refused(`No such file: ${target}`);
179510
180214
  if (stat.size > maxBytes) return refused(`"${target}" is larger than the ${Math.round(maxBytes / (1024 * 1024))} MB a diagram may be`);
179511
- const text7 = await fs12.readFile(resolved, "utf8");
180215
+ const text7 = await fs13.readFile(resolved, "utf8");
179512
180216
  try {
179513
180217
  const report = checkDrawio(text7);
179514
180218
  return { content: [{ type: "text", text: describeDrawioReport(target, report) }], details: void 0 };
@@ -179521,8 +180225,8 @@ function createDrawioCheckToolDefinition(options2) {
179521
180225
  }
179522
180226
 
179523
180227
  // ../server/src/structuredExchangeTableTool.ts
179524
- import fs13 from "node:fs/promises";
179525
- import path16 from "node:path";
180228
+ import fs14 from "node:fs/promises";
180229
+ import path17 from "node:path";
179526
180230
 
179527
180231
  // ../shared/src/structuredExchangeTableExport.ts
179528
180232
  var ROLE_COLUMN = "change";
@@ -179601,7 +180305,7 @@ function createStructuredExchangeTableToolDefinition(options2) {
179601
180305
  parameters: parameters9,
179602
180306
  async execute(_toolCallId, params) {
179603
180307
  const { path: target, output_path: destination } = params;
179604
- const resolved = await realResolve(path16.resolve(options2.cwd, target));
180308
+ const resolved = await realResolve(path17.resolve(options2.cwd, target));
179605
180309
  if (!isWithinAny(options2.allowedRoots, resolved)) {
179606
180310
  throw new Error(`Access denied: "${target}" is outside the sandbox (${options2.allowedRoots[0]})`);
179607
180311
  }
@@ -179609,12 +180313,12 @@ function createStructuredExchangeTableToolDefinition(options2) {
179609
180313
  throw new Error(`Cannot write "${destination}": a table is written as Markdown and must be named .md.`);
179610
180314
  }
179611
180315
  const writeTo = await assertWritableDestination(destination, { cwd: options2.cwd, writableRoot: options2.writableRoot });
179612
- const stat = await fs13.stat(resolved).catch(() => null);
180316
+ const stat = await fs14.stat(resolved).catch(() => null);
179613
180317
  if (stat === null || !stat.isFile()) throw new Error(`No such file: ${target}`);
179614
180318
  if (stat.size > options2.maxBytes) {
179615
180319
  throw new Error(`"${target}" is larger than the ${describeSize7(options2.maxBytes)} document limit`);
179616
180320
  }
179617
- const verdict = parseSerializedStructuredExchange(await fs13.readFile(resolved, "utf8"), checkStructuredExchangeSchema, options2.limits);
180321
+ const verdict = parseSerializedStructuredExchange(await fs14.readFile(resolved, "utf8"), checkStructuredExchangeSchema, options2.limits);
179618
180322
  if (!verdict.valid) {
179619
180323
  const lines = verdict.issues.map((issue) => `- ${issue.rule} at ${issue.path === "" ? "(document)" : issue.path}: ${issue.message}`);
179620
180324
  return refused2([`No table was written. \`${target}\` does not satisfy the structured-exchange contract:`, ...lines].join("\n"));
@@ -179647,9 +180351,9 @@ function createStructuredExchangeTableToolDefinition(options2) {
179647
180351
  }
179648
180352
  const data = verdict.envelope.data;
179649
180353
  const markdown = tableMarkdown(data);
179650
- await fs13.mkdir(path16.dirname(writeTo), { recursive: true });
180354
+ await fs14.mkdir(path17.dirname(writeTo), { recursive: true });
179651
180355
  try {
179652
- await fs13.writeFile(writeTo, markdown, { flag: "wx" });
180356
+ await fs14.writeFile(writeTo, markdown, { flag: "wx" });
179653
180357
  } catch (error) {
179654
180358
  if (error.code === "EEXIST") {
179655
180359
  throw new Error(`"${destination}" already exists; a table is written to a new file only. Choose another path.`);
@@ -179664,7 +180368,7 @@ function createStructuredExchangeTableToolDefinition(options2) {
179664
180368
  type: "text",
179665
180369
  text: [
179666
180370
  `Wrote \`${destination}\` (${Buffer.byteLength(markdown, "utf8")} bytes): ${rows} row${rows === 1 ? "" : "s"}${chapters === 0 ? "" : ` in ${chapters} chapter${chapters === 1 ? "" : "s"}`}.`,
179667
- `Include it in a Markdown document by copying its content, or link it as \`[${path16.basename(destination, ".md")}](${destination})\`.`
180371
+ `Include it in a Markdown document by copying its content, or link it as \`[${path17.basename(destination, ".md")}](${destination})\`.`
179668
180372
  ].join("\n")
179669
180373
  }
179670
180374
  ],
@@ -179684,26 +180388,26 @@ async function realResolve(target) {
179684
180388
  let tail = "";
179685
180389
  for (; ; ) {
179686
180390
  try {
179687
- const real = await fs14.realpath(existing);
179688
- return tail ? path17.join(real, tail) : real;
180391
+ const real = await fs15.realpath(existing);
180392
+ return tail ? path18.join(real, tail) : real;
179689
180393
  } catch {
179690
- const parent = path17.dirname(existing);
180394
+ const parent = path18.dirname(existing);
179691
180395
  if (parent === existing) return target;
179692
- tail = tail ? path17.join(path17.basename(existing), tail) : path17.basename(existing);
180396
+ tail = tail ? path18.join(path18.basename(existing), tail) : path18.basename(existing);
179693
180397
  existing = parent;
179694
180398
  }
179695
180399
  }
179696
180400
  }
179697
180401
  function isWithin3(root2, target) {
179698
- return target === root2 || target.startsWith(root2 + path17.sep);
180402
+ return target === root2 || target.startsWith(root2 + path18.sep);
179699
180403
  }
179700
180404
  function isWithinAny(roots, target) {
179701
180405
  return roots.some((root2) => isWithin3(root2, target));
179702
180406
  }
179703
180407
  function piConfigWriteRefusal(writableRoot, resolved, target) {
179704
- const relative = path17.relative(writableRoot, resolved);
179705
- if (relative === "" || relative.startsWith("..") || path17.isAbsolute(relative)) return void 0;
179706
- if (!relative.split(path17.sep).includes(".pi")) return void 0;
180408
+ const relative = path18.relative(writableRoot, resolved);
180409
+ if (relative === "" || relative.startsWith("..") || path18.isAbsolute(relative)) return void 0;
180410
+ if (!relative.split(path18.sep).includes(".pi")) return void 0;
179707
180411
  return `Cannot write "${target}": it is in a .pi directory, which holds the configuration that confines the agent (Pi settings and extensions, sandbox policies). Edit it yourself if it needs to change.`;
179708
180412
  }
179709
180413
 
@@ -179714,7 +180418,7 @@ async function assertWritableDestination(destination, options2) {
179714
180418
  `Cannot write "${destination}": this sandbox is read-only. Ask for the extraction itself instead.`
179715
180419
  );
179716
180420
  }
179717
- const resolved = await realResolve(path18.resolve(options2.cwd, destination));
180421
+ const resolved = await realResolve(path19.resolve(options2.cwd, destination));
179718
180422
  if (!isWithin3(options2.writableRoot, resolved)) {
179719
180423
  throw new Error(
179720
180424
  `Cannot write "${destination}": it is outside the writable zone (${options2.writableRoot}). Ask for the extraction itself, or choose a path inside that zone.`
@@ -179728,7 +180432,7 @@ async function writeExtraction(destination, markdown, options2) {
179728
180432
  const resolved = await assertWritableDestination(destination, options2);
179729
180433
  const bytes = Buffer.byteLength(markdown, "utf8");
179730
180434
  try {
179731
- await fs15.writeFile(resolved, markdown, { flag: "wx" });
180435
+ await fs16.writeFile(resolved, markdown, { flag: "wx" });
179732
180436
  } catch (error) {
179733
180437
  const code3 = error.code;
179734
180438
  if (code3 === "EEXIST") {
@@ -179784,6 +180488,11 @@ var parameters10 = typebox_exports.Object({
179784
180488
  description: "Write the whole extraction to this workspace path and return a summary instead of the content. The file must not already exist."
179785
180489
  })
179786
180490
  ),
180491
+ review: typebox_exports.Optional(
180492
+ typebox_exports.Boolean({
180493
+ description: "Show tracked changes and comments: insertions, deletions and moves marked where they sit, comments on the text they are about, and a closing list with each one's author, date and section. Use it for any question about what changed in a document or what its reviewers said."
180494
+ })
180495
+ ),
179787
180496
  images: imagesParameter
179788
180497
  });
179789
180498
  var DESCRIPTION10 = [
@@ -179791,13 +180500,14 @@ var DESCRIPTION10 = [
179791
180500
  "If the user wants the document saved, converted, or written anywhere, pass output_path: it writes the whole document there in one call and returns a short summary.",
179792
180501
  "Do not return the content and then write it yourself \u2014 that spends the context twice.",
179793
180502
  "Otherwise output is capped per call \u2014 when it is truncated it says so and names the block range to ask for next, or pass full:true to get everything at once.",
179794
- "Tracked changes are resolved to the accepted text: insertions are kept, deletions are not returned.",
180503
+ "By default tracked changes are resolved to the accepted text \u2014 insertions kept, deletions not returned \u2014 and the answer opens with a line saying how many changes and comments the document holds.",
180504
+ "Pass review: true to see them: {++inserted++}, {--deleted--}, a move marked at both ends, {==commented text==}, each with a reference such as [r1] or [c1] listed at the end with its author, date, section and, for a comment, its text, replies and whether it is resolved. Formatting changes are not reported. The document is never modified.",
179795
180505
  "Text the document crosses out is returned as ~~struck through~~ and means the document withdrew it \u2014 do not treat it as current, and say which passages are struck when you transcribe, quote or summarise the document.",
179796
180506
  "Bold and italic runs are returned as markdown emphasis; underline has no markdown equivalent and is not marked.",
179797
180507
  "Only formatting written on the run itself is read, so strikethrough applied through a character style is not detected.",
179798
180508
  'Each picture is named where it sits, as [picture 3: PNG 800\xD7600 \u2014 "its alt text"]; pass images: "all" to get them as images too, or images: ["3"] for one by its number.',
179799
180509
  "A picture whose bytes cannot be shown \u2014 a metafile, a missing part \u2014 is still named, with the reason, so nothing the document holds goes unmentioned.",
179800
- "Headers, footers, footnotes, comments and text boxes are not read. Charts, diagrams and grouped shapes are not pictures and have no bytes to return; call docx_render to see those."
180510
+ "Headers, footers, footnotes and text boxes are not read, nor are comments unless review is true. Charts, diagrams and grouped shapes are not pictures and have no bytes to return; call docx_render to see those."
179801
180511
  ].join(" ");
179802
180512
  var LARGE_ANSWER_CHARS5 = 6e4;
179803
180513
  function describeSize8(bytes) {
@@ -179821,13 +180531,14 @@ function createDocxExtractToolDefinition(options2) {
179821
180531
  mode,
179822
180532
  full,
179823
180533
  output_path: destination,
180534
+ review,
179824
180535
  images = "none"
179825
180536
  } = params;
179826
- const resolved = await realResolve(path19.resolve(options2.cwd, target));
180537
+ const resolved = await realResolve(path20.resolve(options2.cwd, target));
179827
180538
  if (!isWithinAny(options2.allowedRoots, resolved)) {
179828
180539
  throw new Error(`Access denied: "${target}" is outside the sandbox (${options2.allowedRoots[0]})`);
179829
180540
  }
179830
- const stat = await fs16.stat(resolved).catch(() => null);
180541
+ const stat = await fs17.stat(resolved).catch(() => null);
179831
180542
  if (stat === null || !stat.isFile()) throw new Error(`No such file: ${target}`);
179832
180543
  if (stat.size > options2.maxBytes) {
179833
180544
  throw new Error(`"${target}" is larger than the ${describeSize8(options2.maxBytes)} Word limit`);
@@ -179838,10 +180549,11 @@ function createDocxExtractToolDefinition(options2) {
179838
180549
  const wholeDocument = full === true || destination !== void 0;
179839
180550
  let extraction;
179840
180551
  try {
179841
- extraction = await extractDocx(new Uint8Array(await fs16.readFile(resolved)), {
180552
+ extraction = await extractDocx(new Uint8Array(await fs17.readFile(resolved)), {
179842
180553
  ...blocks === void 0 ? {} : { blocks },
179843
180554
  ...mode === void 0 ? {} : { mode },
179844
- ...wholeDocument ? { full: true } : {}
180555
+ ...wholeDocument ? { full: true } : {},
180556
+ ...review === true ? { review: true } : {}
179845
180557
  });
179846
180558
  } catch (error) {
179847
180559
  if (error instanceof DocxError) throw new Error(error.message);
@@ -180438,13 +181150,13 @@ function mutateWorkPlan(current, mutation) {
180438
181150
  }
180439
181151
 
180440
181152
  // ../server/src/workPlanStore.ts
180441
- import fs17 from "node:fs/promises";
180442
- import path20 from "node:path";
181153
+ import fs18 from "node:fs/promises";
181154
+ import path21 from "node:path";
180443
181155
  var workPlanPath = (sessionFile) => `${sessionFile}.work-plan.json`;
180444
181156
  async function loadWorkPlan(sessionFile) {
180445
181157
  if (!sessionFile) return null;
180446
181158
  try {
180447
- return validateWorkPlan(JSON.parse(await fs17.readFile(workPlanPath(sessionFile), "utf8")));
181159
+ return validateWorkPlan(JSON.parse(await fs18.readFile(workPlanPath(sessionFile), "utf8")));
180448
181160
  } catch (error) {
180449
181161
  if (error.code === "ENOENT") return null;
180450
181162
  throw new Error(`Cannot load the Work Plan: ${error instanceof Error ? error.message : String(error)}`);
@@ -180453,18 +181165,18 @@ async function loadWorkPlan(sessionFile) {
180453
181165
  async function persist(sessionFile, plan) {
180454
181166
  const target = workPlanPath(sessionFile);
180455
181167
  if (plan === null) {
180456
- await fs17.unlink(target).catch((error) => {
181168
+ await fs18.unlink(target).catch((error) => {
180457
181169
  if (error.code !== "ENOENT") throw error;
180458
181170
  });
180459
181171
  return;
180460
181172
  }
180461
- const temporary = path20.join(path20.dirname(target), `.${path20.basename(target)}.${process.pid}.${Date.now()}.tmp`);
181173
+ const temporary = path21.join(path21.dirname(target), `.${path21.basename(target)}.${process.pid}.${Date.now()}.tmp`);
180462
181174
  try {
180463
- await fs17.writeFile(temporary, `${JSON.stringify(plan, null, 2)}
181175
+ await fs18.writeFile(temporary, `${JSON.stringify(plan, null, 2)}
180464
181176
  `, { encoding: "utf8", mode: 384, flag: "wx" });
180465
- await fs17.rename(temporary, target);
181177
+ await fs18.rename(temporary, target);
180466
181178
  } catch (error) {
180467
- await fs17.unlink(temporary).catch(() => {
181179
+ await fs18.unlink(temporary).catch(() => {
180468
181180
  });
180469
181181
  throw error;
180470
181182
  }
@@ -180732,7 +181444,7 @@ function parseToolsSettings(raw) {
180732
181444
  }
180733
181445
  async function createPiOutpostTools(settings2) {
180734
181446
  const cwd = settings2.cwd;
180735
- const root2 = await fs18.realpath(cwd);
181447
+ const root2 = await fs19.realpath(cwd);
180736
181448
  const common = { cwd, allowedRoots: [root2], writableRoot: root2 };
180737
181449
  const render3 = settings2.officeRender ?? { renderer: "auto", timeoutMs: DEFAULT_RENDER_TIMEOUT_MS };
180738
181450
  return [
@@ -180750,6 +181462,8 @@ async function createPiOutpostTools(settings2) {
180750
181462
  createDocxUpdateToolDefinition({ ...common, maxBytes: settings2.maxBytes.docx, render: render3 }),
180751
181463
  createDocxRestyleToolDefinition({ ...common, maxBytes: settings2.maxBytes.docx, render: render3 }),
180752
181464
  createDocxRenderToolDefinition({ ...common, maxBytes: settings2.maxBytes.docx, render: render3 }),
181465
+ // Comparing two versions drives Word itself: Windows only.
181466
+ ...process.platform === "win32" ? [createDocxCompareToolDefinition({ ...common, maxBytes: settings2.maxBytes.docx, render: render3 })] : [],
180753
181467
  createStructuredExchangeFigureToolDefinition({ ...common, maxBytes: settings2.maxBytes.structuredExchange, projectRoot: root2 }),
180754
181468
  createStructuredExchangeTableToolDefinition({ ...common, maxBytes: settings2.maxBytes.structuredExchange, projectRoot: root2 }),
180755
181469
  createTimelineComparisonToolDefinition({ ...common, maxBytes: settings2.maxBytes.structuredExchange }),