ryugi-artifacts 1.31.4 → 1.31.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/dist/cli.cjs +79 -29
  2. package/dist/server.cjs +287 -247
  3. package/dist/viewer/CloudDocument--a8-nXso.js +1 -0
  4. package/dist/viewer/CloudLiveDocument-Dn7hsd9J.js +1 -0
  5. package/dist/viewer/{DocumentLayout-CoaWyJ8o.js → DocumentLayout-CyTmvIv_.js} +12 -12
  6. package/dist/viewer/DocumentPage-BjkBiEX-.css +1 -0
  7. package/dist/viewer/DocumentPage-CNXMmV9l.js +1 -0
  8. package/dist/viewer/{useSandboxFrame-DiOdLOg3.js → RailSwitch-D4FON4Vr.js} +8 -8
  9. package/dist/viewer/{abnfDiagram-VCTEODGH-V-HUdHOR.js → abnfDiagram-VCTEODGH-BU-Q5nRu.js} +1 -1
  10. package/dist/viewer/{ar-SA-G6X2FPQ2-DQ0iM0EN.js → ar-SA-G6X2FPQ2-Bym-z3Gy.js} +1 -1
  11. package/dist/viewer/{architectureDiagram-5GKGNRK7-BR7YqPnS.js → architectureDiagram-5GKGNRK7-hBXFocSt.js} +1 -1
  12. package/dist/viewer/{az-AZ-76LH7QW2-BZhhIHTR.js → az-AZ-76LH7QW2-DptPViJZ.js} +1 -1
  13. package/dist/viewer/{bg-BG-XCXSNQG7-CQon9Ha7.js → bg-BG-XCXSNQG7-BCAH5UjV.js} +1 -1
  14. package/dist/viewer/{blockDiagram-I7D4REHJ-2rr9DBaj.js → blockDiagram-I7D4REHJ-CQMZg8Nz.js} +1 -1
  15. package/dist/viewer/{bn-BD-2XOGV67Q-oMzz5AyV.js → bn-BD-2XOGV67Q-CQ103rTG.js} +1 -1
  16. package/dist/viewer/{c4Diagram-7LVT6UL2-BLeiPlMV.js → c4Diagram-7LVT6UL2-Wmb5uWym.js} +1 -1
  17. package/dist/viewer/{ca-ES-6MX7JW3Y-Cna6kdsT.js → ca-ES-6MX7JW3Y-QZjpbZoN.js} +1 -1
  18. package/dist/viewer/{chunk-4HAMMTFA-CjyXxW0j.js → chunk-4HAMMTFA-DApjFb3D.js} +1 -1
  19. package/dist/viewer/{chunk-EIO257PC-BLuvNuM3.js → chunk-EIO257PC-CWVuL_0r.js} +1 -1
  20. package/dist/viewer/{chunk-GMAD6QVW-B73OQhVp.js → chunk-GMAD6QVW-CsJibQuL.js} +1 -1
  21. package/dist/viewer/{chunk-GVQU2GXP-DKQ5qiuo.js → chunk-GVQU2GXP-DYTi7tYA.js} +1 -1
  22. package/dist/viewer/{chunk-IMKFNOWR-Cezt1GsL.js → chunk-IMKFNOWR-CWeDJlP4.js} +1 -1
  23. package/dist/viewer/{chunk-L3NEJ4N5-C-84XODC.js → chunk-L3NEJ4N5-TdTMGSnz.js} +1 -1
  24. package/dist/viewer/{chunk-OSK3NFVY-BAIU7jCA.js → chunk-OSK3NFVY-DmS4WZvt.js} +1 -1
  25. package/dist/viewer/{chunk-PWAF6VOD-n-gQe1QG.js → chunk-PWAF6VOD-CgqqcZ7Z.js} +1 -1
  26. package/dist/viewer/{chunk-SHT3W25Y-GBpOdXrL.js → chunk-SHT3W25Y-CO2CRBJI.js} +1 -1
  27. package/dist/viewer/{chunk-SVP7TREG-sSvXNpK2.js → chunk-SVP7TREG-CdURcuTQ.js} +1 -1
  28. package/dist/viewer/{chunk-TICWLB2K-CsBBxqeq.js → chunk-TICWLB2K--5oOkN7m.js} +1 -1
  29. package/dist/viewer/{classDiagram-ZZMXUADV-x8Bacm1h.js → classDiagram-ZZMXUADV-DeIP4NkP.js} +1 -1
  30. package/dist/viewer/{classDiagram-v2-VYDZK3BY-x8Bacm1h.js → classDiagram-v2-VYDZK3BY-DeIP4NkP.js} +1 -1
  31. package/dist/viewer/{cs-CZ-2BRQDIVT-DTbO_wNP.js → cs-CZ-2BRQDIVT-N2YztnjI.js} +1 -1
  32. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-BAxRDxAh.js → cynefinDiagram-5FMLGOSQ-BqdKqwqw.js} +1 -1
  33. package/dist/viewer/{da-DK-5WZEPLOC-gh43GvJ3.js → da-DK-5WZEPLOC-CClTezxe.js} +1 -1
  34. package/dist/viewer/{dagre-GXQ25YYZ-B5Z9Ox26.js → dagre-GXQ25YYZ-DhmSGUk2.js} +1 -1
  35. package/dist/viewer/{de-DE-XR44H4JA-Dtwy2_La.js → de-DE-XR44H4JA-CLPa1jFU.js} +1 -1
  36. package/dist/viewer/{diagram-S7CK7UJ4-DF5PCIpV.js → diagram-S7CK7UJ4-rnc6tcUb.js} +1 -1
  37. package/dist/viewer/{diagram-UQ7AKVKN-Ce5zDPFC.js → diagram-UQ7AKVKN-CZG1zSha.js} +1 -1
  38. package/dist/viewer/{diagram-VX7I27RA-RUhzpCJg.js → diagram-VX7I27RA-esJGj2aD.js} +1 -1
  39. package/dist/viewer/{diagram-Z3DM3KII-C-TBa6Fl.js → diagram-Z3DM3KII-rMa1oT-N.js} +1 -1
  40. package/dist/viewer/{dist-C9jaXMxM.js → dist-0R8oZhgF.js} +1 -1
  41. package/dist/viewer/{dist-pIluIDrQ.js → dist-1wqDUqVM.js} +1 -1
  42. package/dist/viewer/{dist-D-k2wLgF.js → dist-B13oEVXf.js} +1 -1
  43. package/dist/viewer/{dist-7PnLKlq_.js → dist-B40UUbgw.js} +1 -1
  44. package/dist/viewer/{dist-Cyy67cae.js → dist-BMEAkBHE.js} +1 -1
  45. package/dist/viewer/{dist-CbJw7Hmx.js → dist-BQp88HM1.js} +1 -1
  46. package/dist/viewer/{dist-DlPv2tBz.js → dist-Bew_q9_H.js} +1 -1
  47. package/dist/viewer/{dist-CQCY9lrr.js → dist-C55eUDGb.js} +1 -1
  48. package/dist/viewer/{dist-DDAAPJmv.js → dist-C6czRr4c.js} +1 -1
  49. package/dist/viewer/{dist-DpWG9pfC.js → dist-CC9VKgjG.js} +4 -4
  50. package/dist/viewer/{dist-By5kxfOe.js → dist-CJ7QItR6.js} +1 -1
  51. package/dist/viewer/{dist-B84AnNmg.js → dist-CY2TkmE9.js} +1 -1
  52. package/dist/viewer/{dist-DqoaTJ1R.js → dist-CvCVEZHM.js} +1 -1
  53. package/dist/viewer/{dist-DN2KzIr5.js → dist-D-6apRFO.js} +1 -1
  54. package/dist/viewer/{dist-BjTvkeHe.js → dist-D6BaZXlD.js} +1 -1
  55. package/dist/viewer/{dist-dQ0_FCjz.js → dist-D78xEVNA.js} +1 -1
  56. package/dist/viewer/{dist-M2XMA2Pz.js → dist-DHALLG2c.js} +1 -1
  57. package/dist/viewer/{dist-CwTOAwWG.js → dist-DabEZ184.js} +1 -1
  58. package/dist/viewer/{dist-B7NVPGeP.js → dist-Dd3TTld7.js} +1 -1
  59. package/dist/viewer/{dist-dxkbB17f.js → dist-Ded9oFKo.js} +1 -1
  60. package/dist/viewer/{dist-AkIqU1Dz.js → dist-Wtk9y4QC.js} +1 -1
  61. package/dist/viewer/{dist-BWfLj92W.js → dist-cf3dK6JU.js} +1 -1
  62. package/dist/viewer/{dist-D19U_UOY.js → dist-txabnobd.js} +1 -1
  63. package/dist/viewer/{dist-E6DtvB3t.js → dist-vfTnUsvv.js} +1 -1
  64. package/dist/viewer/{ebnfDiagram-PWID7BFC-W6W8wGx4.js → ebnfDiagram-PWID7BFC-9giBRT9V.js} +1 -1
  65. package/dist/viewer/{el-GR-BZB4AONW-Dv4Rs_Df.js → el-GR-BZB4AONW-DiytE3HK.js} +1 -1
  66. package/dist/viewer/{en-B4ZKOASM-BHmDnV1n.js → en-B4ZKOASM-BnlX_3m1.js} +1 -1
  67. package/dist/viewer/{erDiagram-RLTQ6QDP-k_44u2lM.js → erDiagram-RLTQ6QDP-BFc3pr17.js} +1 -1
  68. package/dist/viewer/{es-ES-U4NZUMDT-D-vQ062d.js → es-ES-U4NZUMDT-BLZs9ryR.js} +1 -1
  69. package/dist/viewer/{eu-ES-A7QVB2H4-DYJjnf7k.js → eu-ES-A7QVB2H4-Do47CF4f.js} +1 -1
  70. package/dist/viewer/{fa-IR-HGAKTJCU-CeG9eVdo.js → fa-IR-HGAKTJCU-BZbWTobm.js} +1 -1
  71. package/dist/viewer/{fi-FI-Z5N7JZ37-BYhHYWe_.js → fi-FI-Z5N7JZ37-Bj1DZkcY.js} +1 -1
  72. package/dist/viewer/flowDiagram-HODETNUW-DJKmbPSM.js +1 -0
  73. package/dist/viewer/{fr-FR-RHASNOE6-HTwRpYPq.js → fr-FR-RHASNOE6-BwL6w642.js} +1 -1
  74. package/dist/viewer/{ganttDiagram-EL5Y4UJY-BaG9O0Mo.js → ganttDiagram-EL5Y4UJY-tkthcHqs.js} +1 -1
  75. package/dist/viewer/{gl-ES-HMX3MZ6V--twqMfjm.js → gl-ES-HMX3MZ6V-ConDt0TV.js} +1 -1
  76. package/dist/viewer/{he-IL-6SHJWFNN-DjEE_S2c.js → he-IL-6SHJWFNN-BlAXOFv0.js} +1 -1
  77. package/dist/viewer/{hi-IN-IWLTKZ5I-P609s9r1.js → hi-IN-IWLTKZ5I-D3eaYVhg.js} +1 -1
  78. package/dist/viewer/{hu-HU-A5ZG7DT2-DnDDq-09.js → hu-HU-A5ZG7DT2-DZRZmO8U.js} +1 -1
  79. package/dist/viewer/{id-ID-SAP4L64H-wXuUsbid.js → id-ID-SAP4L64H-CpfVDf1D.js} +1 -1
  80. package/dist/viewer/{image-GAAHSSAO-Z7fqDf9l.js → image-GAAHSSAO-CTiY9gHI.js} +1 -1
  81. package/dist/viewer/index.html +1 -1
  82. package/dist/viewer/index.js +9 -9
  83. package/dist/viewer/index2.css +16 -4
  84. package/dist/viewer/{infoDiagram-27XIBGKW-Dc7UJxEe.js → infoDiagram-27XIBGKW-nrTZd6ja.js} +1 -1
  85. package/dist/viewer/{ishikawaDiagram-5VMMS53U-HVSpaNcP.js → ishikawaDiagram-5VMMS53U-Qt3RnGXG.js} +1 -1
  86. package/dist/viewer/{it-IT-JPQ66NNP-Dz_ldq9W.js → it-IT-JPQ66NNP-D-9al1qd.js} +1 -1
  87. package/dist/viewer/{ja-JP-DBVTYXUO-D_Y3Qx6n.js → ja-JP-DBVTYXUO--8rpiAjQ.js} +1 -1
  88. package/dist/viewer/{journeyDiagram-3NMN7TZE-CZA_wgT3.js → journeyDiagram-3NMN7TZE-gleUhig1.js} +1 -1
  89. package/dist/viewer/{kaa-6HZHGXH3-Bg28G59N.js → kaa-6HZHGXH3-BISHy72m.js} +1 -1
  90. package/dist/viewer/{kab-KAB-ZGHBKWFO-CjKTOitL.js → kab-KAB-ZGHBKWFO-rqflrdnE.js} +1 -1
  91. package/dist/viewer/{kanban-definition-UXKFOSKX-DOrdOxZf.js → kanban-definition-UXKFOSKX-DHYX9Sne.js} +1 -1
  92. package/dist/viewer/{kk-KZ-P5N5QNE5-DDt5JOBa.js → kk-KZ-P5N5QNE5-CxsofODM.js} +1 -1
  93. package/dist/viewer/{km-KH-HSX4SM5Z-1GGv3vFQ.js → km-KH-HSX4SM5Z-CY7KPsg8.js} +1 -1
  94. package/dist/viewer/{ko-KR-MTYHY66A-DBC6a0Fk.js → ko-KR-MTYHY66A-Mo8X-aCW.js} +1 -1
  95. package/dist/viewer/{ku-TR-6OUDTVRD-D5PzWCFN.js → ku-TR-6OUDTVRD-XdGOo6AM.js} +1 -1
  96. package/dist/viewer/{lt-LT-XHIRWOB4-BMt-7WWM.js → lt-LT-XHIRWOB4-BTJg8sWT.js} +1 -1
  97. package/dist/viewer/{lv-LV-5QDEKY6T-Dzce_YpG.js → lv-LV-5QDEKY6T-BKlFEfuS.js} +1 -1
  98. package/dist/viewer/{mindmap-definition-YA3MSWOX-Bd2YON6d.js → mindmap-definition-YA3MSWOX-BmwdHmpO.js} +1 -1
  99. package/dist/viewer/{mr-IN-CRQNXWMA-UoxyeJGh.js → mr-IN-CRQNXWMA-D0AQrCA2.js} +1 -1
  100. package/dist/viewer/{my-MM-5M5IBNSE-DuhFAvGA.js → my-MM-5M5IBNSE-NjpzYQsO.js} +1 -1
  101. package/dist/viewer/{nb-NO-T6EIAALU-D2HesCV7.js → nb-NO-T6EIAALU-BzWm7B-O.js} +1 -1
  102. package/dist/viewer/{nl-NL-IS3SIHDZ-D-7LDwui.js → nl-NL-IS3SIHDZ-T8_DslA8.js} +1 -1
  103. package/dist/viewer/{nn-NO-6E72VCQL-CSp296dk.js → nn-NO-6E72VCQL-BTszDvP-.js} +1 -1
  104. package/dist/viewer/{oc-FR-POXYY2M6-07HaLB9l.js → oc-FR-POXYY2M6-hpKPsf_6.js} +1 -1
  105. package/dist/viewer/{pa-IN-N4M65BXN-CwctqD6c.js → pa-IN-N4M65BXN-DFhI5C_f.js} +1 -1
  106. package/dist/viewer/{pegDiagram-XKGWAZYB-CRD0uqB1.js → pegDiagram-XKGWAZYB-DqketQBQ.js} +1 -1
  107. package/dist/viewer/percentages-BXMCSKIN-BE-dJ5Ph.js +1 -0
  108. package/dist/viewer/{pieDiagram-E7YTZNPT-Cw74ebj0.js → pieDiagram-E7YTZNPT-CswNjFwQ.js} +1 -1
  109. package/dist/viewer/{pl-PL-T2D74RX3-BxJKeX_1.js → pl-PL-T2D74RX3-D558twE2.js} +1 -1
  110. package/dist/viewer/{prod-C-6zSFxv.js → prod-QHcKCKFc.js} +8 -8
  111. package/dist/viewer/{pt-BR-5N22H2LF-C4_Reldi.js → pt-BR-5N22H2LF-DSx6pGlq.js} +1 -1
  112. package/dist/viewer/{pt-PT-UZXXM6DQ-CQ3gFzQH.js → pt-PT-UZXXM6DQ-DmOAYnAV.js} +1 -1
  113. package/dist/viewer/{quadrantDiagram-AXDQQJYC-DwieeaHN.js → quadrantDiagram-AXDQQJYC-Du4WujoN.js} +1 -1
  114. package/dist/viewer/{railroadDiagram-O6MQD6OU-DuQ49o4K.js → railroadDiagram-O6MQD6OU-DtPojk0V.js} +1 -1
  115. package/dist/viewer/{requirementDiagram-BXWQKSXE-Dlq9-j8c.js → requirementDiagram-BXWQKSXE-DPfOYGEZ.js} +1 -1
  116. package/dist/viewer/{ro-RO-JPDTUUEW-BVKmnDvM.js → ro-RO-JPDTUUEW-CqQXLoRW.js} +1 -1
  117. package/dist/viewer/{ru-RU-B4JR7IUQ-CCxHHLrA.js → ru-RU-B4JR7IUQ-J649-Rol.js} +1 -1
  118. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-DBhcNj5A.js → sequenceDiagram-WJ2MYXX4-BCzPC46m.js} +1 -1
  119. package/dist/viewer/{si-LK-N5RQ5JYF-DkOlkhdA.js → si-LK-N5RQ5JYF-BtnJyPI4.js} +1 -1
  120. package/dist/viewer/{sk-SK-C5VTKIMK-Bi4Uprlv.js → sk-SK-C5VTKIMK-Dd4ukPQm.js} +1 -1
  121. package/dist/viewer/{sl-SI-NN7IZMDC-BGuRxttK.js → sl-SI-NN7IZMDC-CfLEfkKK.js} +1 -1
  122. package/dist/viewer/{stateDiagram-D77RDMKH-DXKpxIuA.js → stateDiagram-D77RDMKH-rJOQf35n.js} +1 -1
  123. package/dist/viewer/{stateDiagram-v2-MP3YSRHH-CBJWpsr9.js → stateDiagram-v2-MP3YSRHH-2Xy4p5Ky.js} +1 -1
  124. package/dist/viewer/subset-shared.chunk-D9kegQAo.js +1 -0
  125. package/dist/viewer/{subset-worker.chunk-Cz-rQHpj.js → subset-worker.chunk-VHwqqTOg.js} +1 -1
  126. package/dist/viewer/{sv-SE-XGPEYMSR-Del5jLMP.js → sv-SE-XGPEYMSR-6aSxoBco.js} +1 -1
  127. package/dist/viewer/{swimlanes-42K2YHIH-tHu8NwKc.js → swimlanes-42K2YHIH-v4Asr9Gq.js} +1 -1
  128. package/dist/viewer/{swimlanesDiagram-VR7AAH4N-QGW4zvRm.js → swimlanesDiagram-VR7AAH4N-ELa654QB.js} +1 -1
  129. package/dist/viewer/{ta-IN-2NMHFXQM-BPvWkb6U.js → ta-IN-2NMHFXQM-CFXGYN1q.js} +1 -1
  130. package/dist/viewer/{th-TH-HPSO5L25-CLDQIXWf.js → th-TH-HPSO5L25-DE3snqCF.js} +1 -1
  131. package/dist/viewer/{timeline-definition-24CTP7MA-Deed7SMe.js → timeline-definition-24CTP7MA-BAcffnfw.js} +1 -1
  132. package/dist/viewer/{tr-TR-DEFEU3FU-CKhIwM-a.js → tr-TR-DEFEU3FU-B4xo5NFF.js} +1 -1
  133. package/dist/viewer/{uk-UA-QMV73CPH-ArQZWzCO.js → uk-UA-QMV73CPH-6G-hcLK9.js} +1 -1
  134. package/dist/viewer/{vennDiagram-4TSXK5OY-DTsTOAD0.js → vennDiagram-4TSXK5OY-X6DsLJAg.js} +1 -1
  135. package/dist/viewer/{vi-VN-M7AON7JQ-BlPxrRvf.js → vi-VN-M7AON7JQ-1UrXvj_c.js} +1 -1
  136. package/dist/viewer/{wardleyDiagram-VM6X3IG4-fftHN4D7.js → wardleyDiagram-VM6X3IG4-C6d-EQap.js} +1 -1
  137. package/dist/viewer/{xychartDiagram-S5SC5T6Z-DVVUiHF6.js → xychartDiagram-S5SC5T6Z-CsXmXjQH.js} +1 -1
  138. package/dist/viewer/{zh-CN-LNUGB5OW-DpNT6DDj.js → zh-CN-LNUGB5OW-t5_YfMiv.js} +1 -1
  139. package/dist/viewer/{zh-HK-E62DVLB3-BlLwOVyy.js → zh-HK-E62DVLB3-DJLNgDSD.js} +1 -1
  140. package/dist/viewer/{zh-TW-RAJ6MFWO-CV_K9CZh.js → zh-TW-RAJ6MFWO-CxK5BbTi.js} +1 -1
  141. package/package.json +1 -1
  142. package/dist/viewer/CloudDocument-DI8rTqBL.js +0 -1
  143. package/dist/viewer/CloudLiveDocument-DAfaRpMU.js +0 -1
  144. package/dist/viewer/DocumentPage-B5t36jZf.js +0 -1
  145. package/dist/viewer/DocumentPage-RHTp39ah.css +0 -1
  146. package/dist/viewer/flowDiagram-HODETNUW-C3rwBhGN.js +0 -1
  147. package/dist/viewer/percentages-BXMCSKIN-9jDDhvw6.js +0 -1
  148. package/dist/viewer/subset-shared.chunk-ek8LNSV8.js +0 -1
package/dist/server.cjs CHANGED
@@ -5171,14 +5171,14 @@ var require_websocket_server = __commonJS({
5171
5171
 
5172
5172
  // src/server/main.ts
5173
5173
  var import_node_child_process2 = require("node:child_process");
5174
- var import_node_fs25 = __toESM(require("node:fs"), 1);
5174
+ var import_node_fs26 = __toESM(require("node:fs"), 1);
5175
5175
  var import_node_os = __toESM(require("node:os"), 1);
5176
- var import_node_path21 = __toESM(require("node:path"), 1);
5176
+ var import_node_path22 = __toESM(require("node:path"), 1);
5177
5177
 
5178
5178
  // src/server/app.ts
5179
- var import_node_fs23 = __toESM(require("node:fs"), 1);
5179
+ var import_node_fs24 = __toESM(require("node:fs"), 1);
5180
5180
  var import_node_http = __toESM(require("node:http"), 1);
5181
- var import_node_path20 = __toESM(require("node:path"), 1);
5181
+ var import_node_path21 = __toESM(require("node:path"), 1);
5182
5182
 
5183
5183
  // src/shared/types.ts
5184
5184
  var ARTIFACT_TYPES = ["artboard", "document", "html"];
@@ -5264,27 +5264,62 @@ function artifactSignature(dir, type) {
5264
5264
  return `${names.length}:${size}:${latest}:${hash}`;
5265
5265
  }
5266
5266
 
5267
+ // src/server/artifact-address.ts
5268
+ var import_node_crypto2 = __toESM(require("node:crypto"), 1);
5269
+ var import_node_fs2 = __toESM(require("node:fs"), 1);
5270
+ var import_node_path2 = __toESM(require("node:path"), 1);
5271
+ function artifactId(dir) {
5272
+ const file = import_node_path2.default.join(dir, ".artifact-id");
5273
+ let id2;
5274
+ try {
5275
+ id2 = import_node_fs2.default.readFileSync(file, "utf8").trim();
5276
+ } catch (err) {
5277
+ if (err.code !== "ENOENT") throw err;
5278
+ id2 = import_node_crypto2.default.randomBytes(16).toString("hex");
5279
+ try {
5280
+ import_node_fs2.default.writeFileSync(file, `${id2}
5281
+ `, { flag: "wx" });
5282
+ } catch (writeError) {
5283
+ if (writeError.code !== "EEXIST") throw writeError;
5284
+ return artifactId(dir);
5285
+ }
5286
+ }
5287
+ if (!/^[a-f0-9]{32}$/.test(id2)) throw new Error(`Invalid artifact ID in ${file}`);
5288
+ return id2;
5289
+ }
5290
+ function artifactPath(root, type, slug) {
5291
+ if (!isArtifactType(type) || !isArtifactId(slug)) throw new Error("Invalid artifact locator");
5292
+ const dir = import_node_path2.default.join(root, type, slug);
5293
+ import_node_fs2.default.mkdirSync(dir, { recursive: true });
5294
+ return `/${type}/${artifactId(dir)}`;
5295
+ }
5296
+ function resolveArtifactAddress(root, type, address) {
5297
+ const matches2 = listArtifacts(root).artifacts.filter((entry) => entry.type === type && artifactId(entry.dir) === address);
5298
+ if (matches2.length > 1) throw new Error(`Duplicate artifact ID: ${type}/${address} (${matches2.map((entry) => entry.id).join(", ")})`);
5299
+ return matches2[0] ?? (resolveArtifactDir(root, type, address) ? { type, id: address, dir: import_node_path2.default.join(root, type, address) } : null);
5300
+ }
5301
+
5267
5302
  // src/server/document.ts
5268
- var import_node_fs3 = __toESM(require("node:fs"), 1);
5269
- var import_node_path3 = __toESM(require("node:path"), 1);
5303
+ var import_node_fs4 = __toESM(require("node:fs"), 1);
5304
+ var import_node_path4 = __toESM(require("node:path"), 1);
5270
5305
 
5271
5306
  // src/server/html.ts
5272
- var import_node_fs2 = __toESM(require("node:fs"), 1);
5273
- var import_node_path2 = __toESM(require("node:path"), 1);
5307
+ var import_node_fs3 = __toESM(require("node:fs"), 1);
5308
+ var import_node_path3 = __toESM(require("node:path"), 1);
5274
5309
  var TITLE = /<title[^>]*>([\s\S]*?)<\/title>/i;
5275
5310
  function latestMtime(dir) {
5276
5311
  let latest = 0;
5277
5312
  let entries2;
5278
5313
  try {
5279
- entries2 = import_node_fs2.default.readdirSync(dir, { withFileTypes: true });
5314
+ entries2 = import_node_fs3.default.readdirSync(dir, { withFileTypes: true });
5280
5315
  } catch {
5281
5316
  return latest;
5282
5317
  }
5283
5318
  for (const entry of entries2) {
5284
5319
  if (entry.name.startsWith(".")) continue;
5285
- const full = import_node_path2.default.join(dir, entry.name);
5320
+ const full = import_node_path3.default.join(dir, entry.name);
5286
5321
  try {
5287
- latest = Math.max(latest, entry.isDirectory() ? latestMtime(full) : import_node_fs2.default.statSync(full).mtimeMs);
5322
+ latest = Math.max(latest, entry.isDirectory() ? latestMtime(full) : import_node_fs3.default.statSync(full).mtimeMs);
5288
5323
  } catch {
5289
5324
  continue;
5290
5325
  }
@@ -5294,7 +5329,7 @@ function latestMtime(dir) {
5294
5329
  function readHtml(dir, id2) {
5295
5330
  let source;
5296
5331
  try {
5297
- source = import_node_fs2.default.readFileSync(import_node_path2.default.join(dir, "index.html"), "utf8");
5332
+ source = import_node_fs3.default.readFileSync(import_node_path3.default.join(dir, "index.html"), "utf8");
5298
5333
  } catch {
5299
5334
  return { title: id2, warnings: ["index.html not found"], version: latestMtime(dir) };
5300
5335
  }
@@ -5307,7 +5342,7 @@ var FIRST_HEADING = /<h[1-6]\b[^>]*>([\s\S]*?)<\/h[1-6]>/i;
5307
5342
  function readDocument(dir, id2) {
5308
5343
  let source;
5309
5344
  try {
5310
- source = import_node_fs3.default.readFileSync(import_node_path3.default.join(dir, "doc.xml"), "utf8");
5345
+ source = import_node_fs4.default.readFileSync(import_node_path4.default.join(dir, "doc.xml"), "utf8");
5311
5346
  } catch {
5312
5347
  return { title: id2, warnings: ["doc.xml not found"], version: latestMtime(dir) };
5313
5348
  }
@@ -17576,7 +17611,7 @@ setPrototypeOf(Document4, Document2).prototype = Document2.prototype;
17576
17611
  registerParseHTML((html) => parseHTML2(html).document);
17577
17612
 
17578
17613
  // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
17579
- var import_node_crypto2 = require("node:crypto");
17614
+ var import_node_crypto3 = require("node:crypto");
17580
17615
 
17581
17616
  // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
17582
17617
  var urlAlphabet2 = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
@@ -17590,10 +17625,10 @@ function fillPool(bytes) {
17590
17625
  try {
17591
17626
  if (!pool || pool.length < bytes) {
17592
17627
  pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
17593
- import_node_crypto2.webcrypto.getRandomValues(pool);
17628
+ import_node_crypto3.webcrypto.getRandomValues(pool);
17594
17629
  poolOffset = 0;
17595
17630
  } else if (poolOffset + bytes > pool.length) {
17596
- import_node_crypto2.webcrypto.getRandomValues(pool);
17631
+ import_node_crypto3.webcrypto.getRandomValues(pool);
17597
17632
  poolOffset = 0;
17598
17633
  }
17599
17634
  } catch (e5) {
@@ -17803,9 +17838,9 @@ function boxDrawingDiagrams(state) {
17803
17838
  }
17804
17839
 
17805
17840
  // src/server/board-comments.ts
17806
- var import_node_crypto3 = __toESM(require("node:crypto"), 1);
17807
- var import_node_fs8 = __toESM(require("node:fs"), 1);
17808
- var import_node_path7 = __toESM(require("node:path"), 1);
17841
+ var import_node_crypto4 = __toESM(require("node:crypto"), 1);
17842
+ var import_node_fs9 = __toESM(require("node:fs"), 1);
17843
+ var import_node_path8 = __toESM(require("node:path"), 1);
17809
17844
 
17810
17845
  // src/shared/comments.ts
17811
17846
  var emptyComments = () => ({ version: 1, threads: [] });
@@ -18101,12 +18136,12 @@ function groupVerdict(threads, group, stale) {
18101
18136
  }
18102
18137
 
18103
18138
  // src/server/comment-cursors.ts
18104
- var import_node_fs6 = __toESM(require("node:fs"), 1);
18105
- var import_node_path6 = __toESM(require("node:path"), 1);
18139
+ var import_node_fs7 = __toESM(require("node:fs"), 1);
18140
+ var import_node_path7 = __toESM(require("node:path"), 1);
18106
18141
 
18107
18142
  // src/server/state.ts
18108
- var import_node_fs5 = __toESM(require("node:fs"), 1);
18109
- var import_node_path5 = __toESM(require("node:path"), 1);
18143
+ var import_node_fs6 = __toESM(require("node:fs"), 1);
18144
+ var import_node_path6 = __toESM(require("node:path"), 1);
18110
18145
 
18111
18146
  // src/shared/geometry.ts
18112
18147
  var GROUP_PAD = 48;
@@ -18351,38 +18386,38 @@ function validateCanvas(raw, fileExists, options = {}) {
18351
18386
  }
18352
18387
 
18353
18388
  // src/server/paths.ts
18354
- var import_node_fs4 = __toESM(require("node:fs"), 1);
18355
- var import_node_path4 = __toESM(require("node:path"), 1);
18389
+ var import_node_fs5 = __toESM(require("node:fs"), 1);
18390
+ var import_node_path5 = __toESM(require("node:path"), 1);
18356
18391
  function resolveInside(root, relative) {
18357
- const target = import_node_path4.default.resolve(root, `.${import_node_path4.default.sep}${relative}`);
18358
- if (!target.startsWith(root + import_node_path4.default.sep)) return null;
18359
- if (import_node_path4.default.relative(root, target).split(import_node_path4.default.sep).some((segment) => segment.startsWith("."))) return null;
18392
+ const target = import_node_path5.default.resolve(root, `.${import_node_path5.default.sep}${relative}`);
18393
+ if (!target.startsWith(root + import_node_path5.default.sep)) return null;
18394
+ if (import_node_path5.default.relative(root, target).split(import_node_path5.default.sep).some((segment) => segment.startsWith("."))) return null;
18360
18395
  return target;
18361
18396
  }
18362
- var isWithin = (child, parent) => child.toLowerCase().startsWith(`${parent.toLowerCase()}${import_node_path4.default.sep}`);
18397
+ var isWithin = (child, parent) => child.toLowerCase().startsWith(`${parent.toLowerCase()}${import_node_path5.default.sep}`);
18363
18398
  function resolveFileWithin(root, relative, allowedDir) {
18364
18399
  const target = resolveInside(root, relative);
18365
18400
  if (!target) return null;
18366
18401
  let real;
18367
18402
  let allowedReal;
18368
18403
  try {
18369
- real = import_node_fs4.default.realpathSync(target);
18370
- allowedReal = import_node_fs4.default.realpathSync(allowedDir);
18404
+ real = import_node_fs5.default.realpathSync(target);
18405
+ allowedReal = import_node_fs5.default.realpathSync(allowedDir);
18371
18406
  } catch {
18372
18407
  return null;
18373
18408
  }
18374
18409
  if (!isWithin(real, allowedReal)) return null;
18375
- return import_node_fs4.default.statSync(real).isFile() ? real : null;
18410
+ return import_node_fs5.default.statSync(real).isFile() ? real : null;
18376
18411
  }
18377
- var resolveBoardFile = (boardDir, relative) => resolveFileWithin(boardDir, relative, import_node_path4.default.join(boardDir, "pages"));
18378
- var resolveDocumentAsset = (artifactDir, relative) => resolveFileWithin(artifactDir, relative, import_node_path4.default.join(artifactDir, "assets"));
18412
+ var resolveBoardFile = (boardDir, relative) => resolveFileWithin(boardDir, relative, import_node_path5.default.join(boardDir, "pages"));
18413
+ var resolveDocumentAsset = (artifactDir, relative) => resolveFileWithin(artifactDir, relative, import_node_path5.default.join(artifactDir, "assets"));
18379
18414
  var resolveHtmlFile = (artifactDir, relative) => resolveFileWithin(artifactDir, relative, artifactDir);
18380
18415
 
18381
18416
  // src/server/state.ts
18382
18417
  function readRaw(boardDir) {
18383
18418
  let text2;
18384
18419
  try {
18385
- text2 = import_node_fs5.default.readFileSync(import_node_path5.default.join(boardDir, "canvas.json"), "utf8");
18420
+ text2 = import_node_fs6.default.readFileSync(import_node_path6.default.join(boardDir, "canvas.json"), "utf8");
18386
18421
  } catch {
18387
18422
  return { warning: "canvas.json not found" };
18388
18423
  }
@@ -18403,12 +18438,12 @@ function boardVersions(boardDir, canvas) {
18403
18438
  continue;
18404
18439
  }
18405
18440
  try {
18406
- const stat = import_node_fs5.default.statSync(target);
18441
+ const stat = import_node_fs6.default.statSync(target);
18407
18442
  if (isMediaBoard(board)) {
18408
18443
  versions[board.file] = stat.size > 0 ? stat.mtimeMs : 0;
18409
18444
  continue;
18410
18445
  }
18411
- const html = import_node_fs5.default.readFileSync(target, "utf8");
18446
+ const html = import_node_fs6.default.readFileSync(target, "utf8");
18412
18447
  const document2 = /<(?:!doctype|html)\b/i.test(html);
18413
18448
  const ready = html.trim().length > 0 && (!document2 || /<\/html>\s*(?:<!--[\s\S]*?-->\s*)*$/i.test(html));
18414
18449
  versions[board.file] = ready ? stat.mtimeMs : 0;
@@ -18454,19 +18489,19 @@ function readCanvas(boardDir) {
18454
18489
  }
18455
18490
  }
18456
18491
  function writeJsonAtomic(file, value) {
18457
- import_node_fs5.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true });
18492
+ import_node_fs6.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true });
18458
18493
  const tmp = `${file}.${process.pid}.tmp`;
18459
- import_node_fs5.default.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}
18494
+ import_node_fs6.default.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}
18460
18495
  `, { mode: 384 });
18461
- import_node_fs5.default.renameSync(tmp, file);
18496
+ import_node_fs6.default.renameSync(tmp, file);
18462
18497
  }
18463
18498
  function writeArtifactState(stateDir, ref, payload, extra = {}) {
18464
18499
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
18465
- const dir = import_node_path5.default.join(stateDir, ref.type, ref.id);
18500
+ const dir = import_node_path6.default.join(stateDir, ref.type, ref.id);
18466
18501
  if (ref.type === "artboard") {
18467
- writeJsonAtomic(import_node_path5.default.join(dir, "layout.json"), { checkedAt, ...payload.layout ?? { pages: {} } });
18502
+ writeJsonAtomic(import_node_path6.default.join(dir, "layout.json"), { checkedAt, ...payload.layout ?? { pages: {} } });
18468
18503
  }
18469
- writeJsonAtomic(import_node_path5.default.join(dir, "warnings.json"), {
18504
+ writeJsonAtomic(import_node_path6.default.join(dir, "warnings.json"), {
18470
18505
  checkedAt,
18471
18506
  warnings: payload.warnings,
18472
18507
  ...payload.pending ? { pending: payload.pending } : {},
@@ -18475,10 +18510,10 @@ function writeArtifactState(stateDir, ref, payload, extra = {}) {
18475
18510
  }
18476
18511
 
18477
18512
  // src/server/comment-cursors.ts
18478
- var cursorsFile = (stateDir, id2, type = "document") => import_node_path6.default.join(stateDir, type, id2, "comment-cursors.json");
18513
+ var cursorsFile = (stateDir, id2, type = "document") => import_node_path7.default.join(stateDir, type, id2, "comment-cursors.json");
18479
18514
  function read(file) {
18480
18515
  try {
18481
- const value = JSON.parse(import_node_fs6.default.readFileSync(file, "utf8"));
18516
+ const value = JSON.parse(import_node_fs7.default.readFileSync(file, "utf8"));
18482
18517
  if (typeof value !== "object" || value === null || Array.isArray(value)) return {};
18483
18518
  return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
18484
18519
  } catch {
@@ -18498,7 +18533,7 @@ function createCommentCursors(stateDir, type = "document") {
18498
18533
  }
18499
18534
 
18500
18535
  // src/server/document-comments.ts
18501
- var import_node_fs7 = __toESM(require("node:fs"), 1);
18536
+ var import_node_fs8 = __toESM(require("node:fs"), 1);
18502
18537
  var MAX_TEXT = 2e4;
18503
18538
  var isText3 = (value, max = MAX_TEXT) => typeof value === "string" && value.length <= max;
18504
18539
  var isId = (value) => isText3(value, 100) && value.length > 0;
@@ -18553,12 +18588,12 @@ function createStore(file, rules, names = noNames, now = () => (/* @__PURE__ */
18553
18588
  let loaded = false;
18554
18589
  const write = () => {
18555
18590
  writeJsonAtomic(file, current);
18556
- lastSeen = import_node_fs7.default.readFileSync(file, "utf8");
18591
+ lastSeen = import_node_fs8.default.readFileSync(file, "utf8");
18557
18592
  };
18558
18593
  const sync = () => {
18559
18594
  let text2;
18560
18595
  try {
18561
- text2 = import_node_fs7.default.readFileSync(file, "utf8");
18596
+ text2 = import_node_fs8.default.readFileSync(file, "utf8");
18562
18597
  } catch {
18563
18598
  return false;
18564
18599
  }
@@ -18632,7 +18667,7 @@ function asBoardAgentOp(value) {
18632
18667
  }
18633
18668
  function readCanvasJson(dir) {
18634
18669
  try {
18635
- return JSON.parse(import_node_fs8.default.readFileSync(import_node_path7.default.join(dir, "canvas.json"), "utf8"));
18670
+ return JSON.parse(import_node_fs9.default.readFileSync(import_node_path8.default.join(dir, "canvas.json"), "utf8"));
18636
18671
  } catch {
18637
18672
  return {};
18638
18673
  }
@@ -18662,11 +18697,11 @@ function fileHash(dir, relative) {
18662
18697
  const file = resolveBoardFile(dir, relative);
18663
18698
  if (!file) return null;
18664
18699
  try {
18665
- const stat = import_node_fs8.default.statSync(file);
18700
+ const stat = import_node_fs9.default.statSync(file);
18666
18701
  const stamp2 = `${stat.size}:${stat.mtimeMs}`;
18667
18702
  const cached = hashCache.get(file);
18668
18703
  if (cached?.stamp === stamp2) return cached.hash;
18669
- const hash = import_node_crypto3.default.createHash("sha1").update(import_node_fs8.default.readFileSync(file)).digest("hex").slice(0, 12);
18704
+ const hash = import_node_crypto4.default.createHash("sha1").update(import_node_fs9.default.readFileSync(file)).digest("hex").slice(0, 12);
18670
18705
  hashCache.set(file, { stamp: stamp2, hash });
18671
18706
  return hash;
18672
18707
  } catch {
@@ -18698,11 +18733,11 @@ function createBoardCommentRegistry(options) {
18698
18733
  const hashes = /* @__PURE__ */ new Map();
18699
18734
  const lastStale = /* @__PURE__ */ new Map();
18700
18735
  const cursors = createCommentCursors(options.stateDir, "artboard");
18701
- const dirOf = (id2) => import_node_path7.default.join(options.root, "artboard", id2);
18736
+ const dirOf = (id2) => import_node_path8.default.join(options.root, "artboard", id2);
18702
18737
  const store = (id2) => {
18703
18738
  let found = stores.get(id2);
18704
18739
  if (!found) {
18705
- found = createStore(import_node_path7.default.join(dirOf(id2), "comments.json"), boardRules, options.names);
18740
+ found = createStore(import_node_path8.default.join(dirOf(id2), "comments.json"), boardRules, options.names);
18706
18741
  stores.set(id2, found);
18707
18742
  }
18708
18743
  return found;
@@ -18783,19 +18818,19 @@ function createBoardCommentRegistry(options) {
18783
18818
  },
18784
18819
  boardsChanged: (id2) => {
18785
18820
  fresh(id2);
18786
- if (!stores.has(id2) && !import_node_fs8.default.existsSync(import_node_path7.default.join(dirOf(id2), "comments.json"))) return;
18821
+ if (!stores.has(id2) && !import_node_fs9.default.existsSync(import_node_path8.default.join(dirOf(id2), "comments.json"))) return;
18787
18822
  if (JSON.stringify(stale(id2)) !== (lastStale.get(id2) ?? "[]")) push2(id2);
18788
18823
  }
18789
18824
  };
18790
18825
  }
18791
18826
 
18792
18827
  // src/server/documents.ts
18793
- var import_node_fs9 = __toESM(require("node:fs"), 1);
18794
- var import_node_path9 = __toESM(require("node:path"), 1);
18828
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
18829
+ var import_node_path10 = __toESM(require("node:path"), 1);
18795
18830
 
18796
18831
  // src/server/document-session.ts
18797
18832
  var import_promises = __toESM(require("node:fs/promises"), 1);
18798
- var import_node_path8 = __toESM(require("node:path"), 1);
18833
+ var import_node_path9 = __toESM(require("node:path"), 1);
18799
18834
 
18800
18835
  // node_modules/.pnpm/lexical@0.52.0_typescript@5.9.3/node_modules/lexical/dist/Lexical.dev.js
18801
18836
  var Lexical_dev_exports = {};
@@ -19653,19 +19688,19 @@ var ElementDOMSlot = class _ElementDOMSlot extends DOMSlot {
19653
19688
  }
19654
19689
  };
19655
19690
  function indexPath(root, child) {
19656
- const path22 = [];
19691
+ const path23 = [];
19657
19692
  let node = child;
19658
19693
  for (; node !== root && node !== null; node = node.parentNode) {
19659
19694
  let i6 = 0;
19660
19695
  for (let sibling = node.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
19661
19696
  i6++;
19662
19697
  }
19663
- path22.push(i6);
19698
+ path23.push(i6);
19664
19699
  }
19665
19700
  if (!(node === root)) {
19666
19701
  formatDevErrorMessage(`indexPath: root is not a parent of child`);
19667
19702
  }
19668
- return path22.reverse();
19703
+ return path23.reverse();
19669
19704
  }
19670
19705
  // @__NO_SIDE_EFFECTS__
19671
19706
  function readLexicalVersion() {
@@ -34445,9 +34480,9 @@ function getActiveElementDeep(root) {
34445
34480
  function getComposedEventTarget(event) {
34446
34481
  const target = event.target;
34447
34482
  if (target !== null && isHTMLElement(target) && target.shadowRoot !== null && typeof event.composedPath === "function") {
34448
- const path22 = event.composedPath();
34449
- if (path22.length > 0) {
34450
- return path22[0];
34483
+ const path23 = event.composedPath();
34484
+ if (path23.length > 0) {
34485
+ return path23[0];
34451
34486
  }
34452
34487
  }
34453
34488
  return target;
@@ -36358,7 +36393,7 @@ __export(Lexical_prod_exports, {
36358
36393
  $getNodeFromDOMNode: () => Qc,
36359
36394
  $getPreviousSelection: () => ds,
36360
36395
  $getRoot: () => ra,
36361
- $getSelection: () => fs9,
36396
+ $getSelection: () => fs10,
36362
36397
  $getSelectionSlotFrame: () => Df,
36363
36398
  $getSiblingCaret: () => ad,
36364
36399
  $getSlot: () => Lf,
@@ -37098,9 +37133,9 @@ function Ct(t7, e5, n7) {
37098
37133
  const o8 = performance.now() - _t > 100;
37099
37134
  try {
37100
37135
  al(t7, () => {
37101
- const r7 = fs9() || (function(t8) {
37136
+ const r7 = fs10() || (function(t8) {
37102
37137
  return t8.read("latest", () => {
37103
- const t9 = fs9();
37138
+ const t9 = fs10();
37104
37139
  return null !== t9 ? t9.clone() : null;
37105
37140
  });
37106
37141
  })(t7), i6 = /* @__PURE__ */ new Map(), s7 = t7._editorState, l8 = t7._blockCursorElement;
@@ -38380,7 +38415,7 @@ function Yo(t7, n7, o8) {
38380
38415
  al(n7, () => {
38381
38416
  if (!o8) return void sa(null);
38382
38417
  if (!Dc(n7, r7, s7)) return;
38383
- let a5 = fs9();
38418
+ let a5 = fs10();
38384
38419
  if (c10.postDeleteSelectionToRestore && zi(a5) && a5.isCollapsed()) {
38385
38420
  const t8 = a5.anchor, e5 = c10.postDeleteSelectionToRestore.anchor;
38386
38421
  (t8.key === e5.key && t8.offset === e5.offset + 1 || 1 === t8.offset && e5.getNode().is(t8.getNode().getPreviousSibling())) && (a5 = c10.postDeleteSelectionToRestore.clone(), sa(a5));
@@ -38422,7 +38457,7 @@ function Xo(t7, e5) {
38422
38457
  }
38423
38458
  function Qo(t7, e5) {
38424
38459
  al(e5, () => {
38425
- const n7 = fs9(), o8 = Qa(Wa(e5)), r7 = ds();
38460
+ const n7 = fs10(), o8 = Qa(Wa(e5)), r7 = ds();
38426
38461
  if (o8) {
38427
38462
  if (zi(n7)) {
38428
38463
  const t8 = n7.anchor, e6 = t8.getNode();
@@ -38471,7 +38506,7 @@ function er(t7) {
38471
38506
  if (null == t7 || t7.length <= 1 || null == e5) return;
38472
38507
  const n7 = 1 === e5.length ? e5 : "Enter" === e5 ? "\n" : "Tab" === e5 ? " " : null;
38473
38508
  if (!n7) return;
38474
- const o8 = fs9();
38509
+ const o8 = fs10();
38475
38510
  if (!zi(o8) || !o8.isCollapsed()) return;
38476
38511
  const r7 = o8.anchor.getNode();
38477
38512
  if (!ki(r7)) return;
@@ -38503,7 +38538,7 @@ function rr(t7, e5) {
38503
38538
  return null !== r7 && o8.contains(r7) && Ju(r7, e5);
38504
38539
  }
38505
38540
  function ir(t7) {
38506
- const n7 = t7.inputType, o8 = tr(t7), r7 = Vs(), i6 = r7._inputState, s7 = fs9();
38541
+ const n7 = t7.inputType, o8 = tr(t7), r7 = Vs(), i6 = r7._inputState, s7 = fs10();
38507
38542
  if ("insertText" === n7 && t7.data && i6.isInsertTextAfterHandledSelectionCommand) {
38508
38543
  if (nr(i6), t7.preventDefault(), zi(s7) && !s7.isCollapsed()) {
38509
38544
  const t8 = s7.isBackward() ? s7.anchor : s7.focus;
@@ -38537,7 +38572,7 @@ function ir(t7) {
38537
38572
  let u9 = m && n8 && !a6 && c11;
38538
38573
  if (u9 && s7.isCollapsed() && (u9 = !Sl(Ea(s7.anchor, true))), !u9) {
38539
38574
  Ma(r7, jn, true);
38540
- const t8 = fs9();
38575
+ const t8 = fs10();
38541
38576
  m && zi(t8) && t8.isCollapsed() && (i6.postDeleteSelectionToRestore = t8, setTimeout(() => i6.postDeleteSelectionToRestore = null));
38542
38577
  }
38543
38578
  }
@@ -38637,7 +38672,7 @@ function sr(t7, e5) {
38637
38672
  }, { event: t7 }), n7.unprocessedBeforeInputData = null;
38638
38673
  }
38639
38674
  function lr(t7) {
38640
- const e5 = Vs(), n7 = e5._inputState, o8 = fs9(), r7 = t7.data, i6 = tr(t7);
38675
+ const e5 = Vs(), n7 = e5._inputState, o8 = fs10(), r7 = t7.data, i6 = tr(t7);
38641
38676
  let s7 = false;
38642
38677
  if (null != r7 && zi(o8)) {
38643
38678
  const l8 = Qa(Wa(e5)), c10 = null !== l8 ? cu(l8, e5._rootElement) : null, a5 = "insertCompositionText" === t7.inputType && "ending-firefox" !== n7.compositionPhase && !e5.isComposing();
@@ -38662,13 +38697,13 @@ function cr(t7, e5) {
38662
38697
  Ma(e5, Wn, t7);
38663
38698
  }
38664
38699
  function ar(t7) {
38665
- const e5 = Vs(), n7 = e5._inputState, o8 = fs9();
38700
+ const e5 = Vs(), n7 = e5._inputState, o8 = fs10();
38666
38701
  if (zi(o8) && !e5.isComposing()) {
38667
38702
  n7.compositionPhase = "composing", n7.hadOrphanedCompositionEvents = false;
38668
38703
  const r7 = o8.anchor, i6 = o8.anchor.getNode();
38669
38704
  if (Yc(r7.key), za(Ur), t7.timeStamp < n7.lastKeyDownTimeStamp + 30 || "element" === r7.type || !o8.isCollapsed() || !m && (i6.getFormat() !== o8.format || ki(i6) && i6.getStyle() !== o8.style) || ki(i6) && (Bc(i6) || 0 === r7.offset && !i6.canInsertTextBefore() || r7.offset === i6.getTextContentSize() && !i6.canInsertTextAfter())) {
38670
38705
  Ma(e5, Jn, F);
38671
- const t8 = fs9();
38706
+ const t8 = fs10();
38672
38707
  zi(t8) && Yc(t8.anchor.key);
38673
38708
  }
38674
38709
  }
@@ -38682,7 +38717,7 @@ function fr(t7) {
38682
38717
  if (null === t7) return;
38683
38718
  const e5 = Xc(t7);
38684
38719
  if (!ki(e5) || "text" === e5.getType() || Bc(e5) || !e5.isAttached()) return;
38685
- const n7 = fs9(), o8 = zi(n7) && n7.anchor.key === t7 ? n7.anchor.offset : null, r7 = vi(e5.getTextContent());
38720
+ const n7 = fs10(), o8 = zi(n7) && n7.anchor.key === t7 ? n7.anchor.offset : null, r7 = vi(e5.getTextContent());
38686
38721
  if (r7.setFormat(e5.getFormat()), r7.setStyle(e5.getStyle()), e5.replace(r7), null !== o8) {
38687
38722
  const t8 = Math.min(o8, r7.getTextContentSize());
38688
38723
  r7.select(t8, t8);
@@ -38701,7 +38736,7 @@ function dr(t7, e5) {
38701
38736
  return fr(n7), false;
38702
38737
  }
38703
38738
  if ("\n" === e5[e5.length - 1]) {
38704
- const e6 = fs9();
38739
+ const e6 = fs10();
38705
38740
  if (zi(e6) || Bi(e6)) {
38706
38741
  if (zi(e6)) {
38707
38742
  const t8 = e6.focus;
@@ -38713,7 +38748,7 @@ function dr(t7, e5) {
38713
38748
  const o8 = Xc(n7);
38714
38749
  if (null !== o8 && ki(o8) && Bc(o8)) {
38715
38750
  o8.markDirty();
38716
- const t8 = fs9(), r7 = o8.getTextContentSize(), i6 = zi(t8) && t8.anchor.key === n7 ? t8.anchor.offset : r7;
38751
+ const t8 = fs10(), r7 = o8.getTextContentSize(), i6 = zi(t8) && t8.anchor.key === n7 ? t8.anchor.offset : r7;
38717
38752
  return o8.select(i6, i6).insertText(e5), true;
38718
38753
  }
38719
38754
  }
@@ -38840,7 +38875,7 @@ function wr(t7, n7, o8) {
38840
38875
  const r7 = t7.__key, i6 = t7.getParent();
38841
38876
  if (null === i6) return void (null !== Of(t7) && e(367, r7, String(Of(t7))));
38842
38877
  const s7 = (function(t8) {
38843
- const e5 = fs9();
38878
+ const e5 = fs10();
38844
38879
  if (!zi(e5) || !yl(t8)) return e5;
38845
38880
  const { anchor: n8, focus: o9 } = e5, r8 = n8.getNode(), i7 = o9.getNode();
38846
38881
  return Ba(r8, t8) && n8.set(t8.__key, 0, "element"), Ba(i7, t8) && o9.set(t8.__key, 0, "element"), e5;
@@ -38912,7 +38947,7 @@ var Fr = class {
38912
38947
  return false;
38913
38948
  }
38914
38949
  isSelected(t7) {
38915
- const e5 = t7 || fs9();
38950
+ const e5 = t7 || fs10();
38916
38951
  if (null == e5) return false;
38917
38952
  const n7 = e5.getNodes().some((t8) => t8.__key === this.__key);
38918
38953
  if (ki(this)) return n7;
@@ -39102,7 +39137,7 @@ var Fr = class {
39102
39137
  }
39103
39138
  replace(t7, n7) {
39104
39139
  Ws();
39105
- let o8 = fs9();
39140
+ let o8 = fs10();
39106
39141
  null !== o8 && (o8 = o8.clone()), qa(this, t7);
39107
39142
  const r7 = this.getLatest(), i6 = this.__key, s7 = Mf(r7);
39108
39143
  null !== s7 && e(400, i6, r7.getType(), s7.getKey(), s7.getType());
@@ -39122,7 +39157,7 @@ var Fr = class {
39122
39157
  Ws(), qa(this, t7);
39123
39158
  const n7 = this.getWritable(), o8 = t7.getWritable();
39124
39159
  this.getParentOrThrow();
39125
- const r7 = o8.getParent(), i6 = fs9();
39160
+ const r7 = o8.getParent(), i6 = fs10();
39126
39161
  let s7 = false, l8 = false, c10 = -1;
39127
39162
  if (null !== r7 && e5 && zi(i6) && hs(i6, r7)) {
39128
39163
  const e6 = r7.__key, n8 = i6.anchor, o9 = i6.focus;
@@ -39143,7 +39178,7 @@ var Fr = class {
39143
39178
  Ws(), qa(this, t7);
39144
39179
  const n7 = this.getWritable(), o8 = t7.getWritable();
39145
39180
  this.getParentOrThrow();
39146
- const r7 = o8.__key, i6 = fs9(), s7 = o8.getParent(), l8 = null !== s7 && e5 && zi(i6) && hs(i6, s7), c10 = l8 ? o8.getIndexWithinParent() : -1;
39181
+ const r7 = o8.__key, i6 = fs10(), s7 = o8.getParent(), l8 = null !== s7 && e5 && zi(i6) && hs(i6, s7), c10 = l8 ? o8.getIndexWithinParent() : -1;
39147
39182
  Jc(o8), l8 && null !== s7 && zi(i6) && gs(i6, s7, c10, -1);
39148
39183
  const a5 = this.getPreviousSibling(), u8 = this.getParentOrThrow().getWritable(), f6 = n7.__prev, d9 = e5 && zi(i6) && hs(i6, u8), h9 = d9 ? this.getIndexWithinParent() : -1;
39149
39184
  return null === a5 ? u8.__first = r7 : a5.getWritable().__next = r7, u8.__size++, n7.__prev = r7, o8.__prev = f6, o8.__next = n7.__key, o8.__parent = n7.__parent, d9 && zi(i6) && gs(i6, u8, h9), t7;
@@ -39541,7 +39576,7 @@ var hi = class extends Fr {
39541
39576
  select(t7, e5) {
39542
39577
  Ws();
39543
39578
  let n7 = t7, o8 = e5;
39544
- const r7 = fs9(), i6 = this.getTextContent(), s7 = this.__key;
39579
+ const r7 = fs10(), i6 = this.getTextContent(), s7 = this.__key;
39545
39580
  if ("string" == typeof i6) {
39546
39581
  const t8 = i6.length;
39547
39582
  void 0 === n7 && (n7 = t8), void 0 === o8 && (o8 = t8);
@@ -39564,7 +39599,7 @@ var hi = class extends Fr {
39564
39599
  const r7 = this.getWritable(), i6 = r7.__text, s7 = n7.length;
39565
39600
  let l8 = t7;
39566
39601
  l8 < 0 && (l8 = s7 + l8, l8 < 0 && (l8 = 0));
39567
- const c10 = fs9();
39602
+ const c10 = fs10();
39568
39603
  if (o8 && zi(c10)) {
39569
39604
  const e6 = t7 + s7;
39570
39605
  c10.setTextNodeRange(r7, e6, r7, e6);
@@ -39595,7 +39630,7 @@ var hi = class extends Fr {
39595
39630
  let f6;
39596
39631
  const d9 = e5.getFormat(), h9 = e5.getStyle(), g8 = e5.__detail;
39597
39632
  let _5 = false, p7 = null, y5 = null;
39598
- const m11 = fs9();
39633
+ const m11 = fs10();
39599
39634
  if (zi(m11)) {
39600
39635
  const [t8, e6] = m11.isBackward() ? [m11.focus, m11.anchor] : [m11.anchor, m11.focus];
39601
39636
  "text" === t8.type && t8.key === o8 && (p7 = t8), "text" === e6.type && e6.key === o8 && (y5 = e6);
@@ -39634,7 +39669,7 @@ var hi = class extends Fr {
39634
39669
  n7 || t7 === this.getNextSibling() || e(50);
39635
39670
  const o8 = this.__key, r7 = t7.__key, i6 = this.__text, s7 = i6.length;
39636
39671
  Gc() === r7 && Yc(o8);
39637
- const l8 = fs9();
39672
+ const l8 = fs10();
39638
39673
  if (zi(l8)) {
39639
39674
  const e5 = l8.anchor, i7 = l8.focus;
39640
39675
  null !== e5 && e5.key === r7 && ys(e5, n7, o8, t7, s7), null !== i7 && i7.key === r7 && ys(i7, n7, o8, t7, s7);
@@ -39921,7 +39956,7 @@ var Ii = class _Ii {
39921
39956
  }
39922
39957
  deleteNodes() {
39923
39958
  const t7 = this.getNodes().filter((t8) => null === Of(t8));
39924
- if ((fs9() || ds()) === this && t7[0]) {
39959
+ if ((fs10() || ds()) === this && t7[0]) {
39925
39960
  const e5 = ad(t7[0], "next");
39926
39961
  Kl(vd(e5, e5));
39927
39962
  }
@@ -39931,7 +39966,7 @@ var Ii = class _Ii {
39931
39966
  };
39932
39967
  function Li() {
39933
39968
  const t7 = ra();
39934
- if (0 === t7.getChildrenSize() && null === Df(fs9())) {
39969
+ if (0 === t7.getChildrenSize() && null === Df(fs10())) {
39935
39970
  const e5 = oc();
39936
39971
  t7.append(e5), e5.select();
39937
39972
  }
@@ -40058,8 +40093,8 @@ var Ki = class _Ki {
40058
40093
  else {
40059
40094
  const t8 = vi(r7.getTextContent());
40060
40095
  t8.setFormat(n7), t8.setStyle(o8);
40061
- const e6 = fs9() === this;
40062
- r7.replace(t8), this.setTextNodeRange(t8, i6, t8, i6), e6 && fs9() !== this && sa(this);
40096
+ const e6 = fs10() === this;
40097
+ r7.replace(t8), this.setTextNodeRange(t8, i6, t8, i6), e6 && fs10() !== this && sa(this);
40063
40098
  }
40064
40099
  return void ("" !== t7 && this.insertText(t7));
40065
40100
  }
@@ -40094,14 +40129,14 @@ var Ki = class _Ki {
40094
40129
  r7.spliceText(i6, 0, t7, true), r7.isComposing() && "text" === this.anchor.type && this.anchor.set(this.anchor.key, this.anchor.offset - t7.length, this.anchor.type);
40095
40130
  }
40096
40131
  removeText() {
40097
- const t7 = fs9() === this, e5 = this.anchor.key;
40132
+ const t7 = fs10() === this, e5 = this.anchor.key;
40098
40133
  Bl(this, Ul(Rl(this))), this.isCollapsed() && (function(t8, e6) {
40099
40134
  const n7 = t8.anchor;
40100
40135
  if (n7.key === e6) return;
40101
40136
  const o8 = n7.getNode();
40102
40137
  let r7 = 0, i6 = "";
40103
40138
  ki(o8) ? (r7 = o8.getFormat(), i6 = o8.getStyle()) : yl(o8) && (r7 = o8.getTextFormat(), i6 = o8.getTextStyle()), t8.format === r7 && t8.style === i6 || (t8.format = r7, t8.style = i6, t8.dirty = true);
40104
- })(this, e5), t7 && fs9() !== this && sa(this);
40139
+ })(this, e5), t7 && fs10() !== this && sa(this);
40105
40140
  }
40106
40141
  formatText(t7, e5 = null) {
40107
40142
  $i(this, t7, e5);
@@ -40118,7 +40153,7 @@ var Ki = class _Ki {
40118
40153
  }
40119
40154
  if (null !== o9) {
40120
40155
  o9.selectStart();
40121
- const n8 = fs9();
40156
+ const n8 = fs10();
40122
40157
  return zi(n8) || e(369), n8.insertNodes(t7);
40123
40158
  }
40124
40159
  }
@@ -40712,7 +40747,7 @@ function us(t7, e5, n7, o8) {
40712
40747
  const x9 = new Ki(g8, _5, y5, m11);
40713
40748
  return p7 && (x9.dirty = true), x9;
40714
40749
  }
40715
- function fs9() {
40750
+ function fs10() {
40716
40751
  return js()._selection;
40717
40752
  }
40718
40753
  function ds() {
@@ -40882,7 +40917,7 @@ function Ss(t7, e5, n7, o8, r7, i6) {
40882
40917
  }
40883
40918
  }
40884
40919
  function Cs(t7) {
40885
- let e5 = fs9() || ds();
40920
+ let e5 = fs10() || ds();
40886
40921
  null === e5 && (e5 = ra().selectEnd()), e5.insertNodes(t7);
40887
40922
  }
40888
40923
  function vs(t7, e5) {
@@ -40893,7 +40928,7 @@ function ks(t7) {
40893
40928
  return vs(t7, { linebreak: () => e5.push(Al()), tab: () => e5.push(wi()), text: (t8) => e5.push(vi(t8)) }), e5;
40894
40929
  }
40895
40930
  function bs() {
40896
- const t7 = fs9();
40931
+ const t7 = fs10();
40897
40932
  return null === t7 ? "" : t7.getTextContent();
40898
40933
  }
40899
40934
  function Ts(t7) {
@@ -40904,7 +40939,7 @@ function Ts(t7) {
40904
40939
  function Ns(t7, n7 = false) {
40905
40940
  let o8 = t7;
40906
40941
  t7.isCollapsed() || o8.removeText();
40907
- const r7 = fs9();
40942
+ const r7 = fs10();
40908
40943
  zi(r7) && (o8 = r7), zi(o8) || e(161);
40909
40944
  const i6 = o8.anchor;
40910
40945
  let s7 = i6.getNode(), l8 = i6.offset;
@@ -41587,7 +41622,7 @@ var pl = class extends Fr {
41587
41622
  }
41588
41623
  select(t7, e5) {
41589
41624
  Ws();
41590
- const n7 = fs9();
41625
+ const n7 = fs10();
41591
41626
  let o8 = t7, r7 = e5;
41592
41627
  const i6 = this.getChildrenSize();
41593
41628
  if (!this.canBeEmpty()) {
@@ -41684,7 +41719,7 @@ var pl = class extends Fr {
41684
41719
  } else t8.__prev = null;
41685
41720
  }
41686
41721
  if (i6.__size = f6, c10.length) {
41687
- const t8 = fs9();
41722
+ const t8 = fs10();
41688
41723
  if (zi(t8)) {
41689
41724
  const e5 = new Set(c10), n8 = new Set(l8), { anchor: o9, focus: r8 } = t8;
41690
41725
  ml(o9, e5, n8) && ps(o9, o9.getNode(), this, u8, a5), ml(r8, e5, n8) && ps(r8, r8.getNode(), this, u8, a5), 0 !== f6 || this.canBeEmpty() || Va(this) || this.remove();
@@ -41967,7 +42002,7 @@ function zl(t7, n7) {
41967
42002
  nd(n7) ? t7.set(o8.getKey(), n7.offset, "text") : rd(n7) ? ki(o8) ? t7.set(o8.getKey(), fd(o8, r7), "text") : t7.set(o8.getParentOrThrow().getKey(), o8.getIndexWithinParent() + (i6 ? 1 : 0), "element") : (id(n7) && yl(o8) || e(268), t7.set(o8.getKey(), i6 ? 0 : o8.getChildrenSize(), "element"));
41968
42003
  }
41969
42004
  function Kl(t7) {
41970
- const e5 = fs9(), n7 = zi(e5) ? e5 : ls();
42005
+ const e5 = fs10(), n7 = zi(e5) ? e5 : ls();
41971
42006
  return Bl(n7, t7), sa(n7), n7;
41972
42007
  }
41973
42008
  function Bl(t7, e5) {
@@ -42587,7 +42622,7 @@ var vc = class {
42587
42622
  focus(t7, e5 = {}) {
42588
42623
  const n7 = this._rootElement;
42589
42624
  null !== n7 && (n7.setAttribute("autocapitalize", "off"), al(this, () => {
42590
- const o8 = fs9(), r7 = ra();
42625
+ const o8 = fs10(), r7 = ra();
42591
42626
  null !== o8 ? o8.dirty || sa(o8.clone()) : 0 !== r7.getChildrenSize() && ("rootStart" === e5.defaultSelection ? r7.selectStart() : r7.selectEnd()), za("focus"), Ka(() => {
42592
42627
  n7.removeAttribute("autocapitalize"), t7 && t7();
42593
42628
  });
@@ -42849,7 +42884,7 @@ function ga(t7, e5, n7, o8, r7) {
42849
42884
  }
42850
42885
  const c10 = i6.getTextContent();
42851
42886
  if (r7 || l8 !== c10) {
42852
- const e6 = fs9();
42887
+ const e6 = fs10();
42853
42888
  if ("" === l8) {
42854
42889
  if (Yc(null), p || g || x) i6.remove();
42855
42890
  else {
@@ -44543,10 +44578,10 @@ function _loadWasmModule(sync, filepath, src, imports2) {
44543
44578
  var buf = null;
44544
44579
  var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
44545
44580
  if (filepath && isNode2) {
44546
- var fs28 = null;
44547
- var path22 = null;
44581
+ var fs29 = null;
44582
+ var path23 = null;
44548
44583
  return new Promise((resolve, reject) => {
44549
- fs28.readFile(path22.resolve(__dirname, filepath), (error, buffer) => {
44584
+ fs29.readFile(path23.resolve(__dirname, filepath), (error, buffer) => {
44550
44585
  if (error != null) {
44551
44586
  reject(error);
44552
44587
  } else {
@@ -45849,10 +45884,10 @@ var LoroDoc = class _LoroDoc {
45849
45884
  * @param {string} path
45850
45885
  * @returns {Value | Container | undefined}
45851
45886
  */
45852
- getByPath(path22) {
45887
+ getByPath(path23) {
45853
45888
  try {
45854
45889
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
45855
- const ptr0 = passStringToWasm0(path22, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
45890
+ const ptr0 = passStringToWasm0(path23, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
45856
45891
  const len0 = WASM_VECTOR_LEN;
45857
45892
  wasm.lorodoc_getByPath(retptr, this.__wbg_ptr, ptr0, len0);
45858
45893
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
@@ -87933,7 +87968,7 @@ async function readText(file) {
87933
87968
  }
87934
87969
  }
87935
87970
  async function writeAtomic(file, data) {
87936
- await import_promises.default.mkdir(import_node_path8.default.dirname(file), { recursive: true });
87971
+ await import_promises.default.mkdir(import_node_path9.default.dirname(file), { recursive: true });
87937
87972
  const tmp = `${file}.${process.pid}.tmp`;
87938
87973
  await import_promises.default.writeFile(tmp, data);
87939
87974
  await import_promises.default.rename(tmp, file);
@@ -87969,7 +88004,7 @@ async function createDocumentSession(options) {
87969
88004
  let lastGoodText = null;
87970
88005
  let lastAgentText = null;
87971
88006
  let lastFileText = await readText(file) ?? "";
87972
- const activityFile = import_node_path8.default.join(import_node_path8.default.dirname(snapshotFile), "agent-active");
88007
+ const activityFile = import_node_path9.default.join(import_node_path9.default.dirname(snapshotFile), "agent-active");
87973
88008
  let agentActiveAt = await lastAgentWrite(activityFile, file);
87974
88009
  let activitySaved = Promise.resolve();
87975
88010
  const emitStatus = () => emit({ type: "status", outcome, streaming: streaming > 0, agentActiveAt });
@@ -88162,13 +88197,13 @@ function outcomeWarnings(outcome) {
88162
88197
  function createDocumentRegistry(options) {
88163
88198
  const sessions = /* @__PURE__ */ new Map();
88164
88199
  const warnings = /* @__PURE__ */ new Map();
88165
- const docFile = (id2) => import_node_path9.default.join(options.root, "document", id2, "doc.xml");
88200
+ const docFile = (id2) => import_node_path10.default.join(options.root, "document", id2, "doc.xml");
88166
88201
  const commentStores = /* @__PURE__ */ new Map();
88167
88202
  const cursors = createCommentCursors(options.stateDir);
88168
88203
  const commentStore = (id2) => {
88169
88204
  let store = commentStores.get(id2);
88170
88205
  if (!store) {
88171
- store = createCommentStore(import_node_path9.default.join(options.root, "document", id2, "comments.json"), options.names);
88206
+ store = createCommentStore(import_node_path10.default.join(options.root, "document", id2, "comments.json"), options.names);
88172
88207
  commentStores.set(id2, store);
88173
88208
  }
88174
88209
  return store;
@@ -88182,10 +88217,10 @@ function createDocumentRegistry(options) {
88182
88217
  if (JSON.stringify(store.warnings()) !== before2) options.onWarningsChange(id2);
88183
88218
  };
88184
88219
  const create3 = async (id2) => {
88185
- if (!import_node_fs9.default.existsSync(docFile(id2))) return null;
88220
+ if (!import_node_fs10.default.existsSync(docFile(id2))) return null;
88186
88221
  const session = await createDocumentSession({
88187
88222
  file: docFile(id2),
88188
- snapshotFile: import_node_path9.default.join(options.stateDir, "document", id2, "doc.loro"),
88223
+ snapshotFile: import_node_path10.default.join(options.stateDir, "document", id2, "doc.loro"),
88189
88224
  ...options.timing,
88190
88225
  log: options.log
88191
88226
  });
@@ -88235,7 +88270,7 @@ function createDocumentRegistry(options) {
88235
88270
  const known = sessions.has(id2);
88236
88271
  void open(id2).then((session) => {
88237
88272
  if (!session || !known) return;
88238
- import_node_fs9.default.readFile(docFile(id2), "utf8", (err, text2) => {
88273
+ import_node_fs10.default.readFile(docFile(id2), "utf8", (err, text2) => {
88239
88274
  if (!err) session.onFileText(text2);
88240
88275
  });
88241
88276
  });
@@ -88959,9 +88994,9 @@ function injectRuntime(html, options = {}) {
88959
88994
  }
88960
88995
 
88961
88996
  // src/server/http.ts
88962
- var import_node_crypto4 = __toESM(require("node:crypto"), 1);
88963
- var import_node_fs10 = __toESM(require("node:fs"), 1);
88964
- var import_node_path10 = __toESM(require("node:path"), 1);
88997
+ var import_node_crypto5 = __toESM(require("node:crypto"), 1);
88998
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
88999
+ var import_node_path11 = __toESM(require("node:path"), 1);
88965
89000
  var MIME2 = {
88966
89001
  ".html": "text/html; charset=utf-8",
88967
89002
  ".js": "text/javascript; charset=utf-8",
@@ -88984,12 +89019,12 @@ var MIME2 = {
88984
89019
  ".mp4": "video/mp4",
88985
89020
  ".webm": "video/webm"
88986
89021
  };
88987
- var mimeOf = (file) => MIME2[import_node_path10.default.extname(file).toLowerCase()] ?? "application/octet-stream";
88988
- var randomToken = () => import_node_crypto4.default.randomBytes(24).toString("base64url");
89022
+ var mimeOf = (file) => MIME2[import_node_path11.default.extname(file).toLowerCase()] ?? "application/octet-stream";
89023
+ var randomToken = () => import_node_crypto5.default.randomBytes(24).toString("base64url");
88989
89024
  function safeEqual(a5, b6) {
88990
89025
  const ab = Buffer.from(a5);
88991
89026
  const bb = Buffer.from(b6);
88992
- return ab.length === bb.length && import_node_crypto4.default.timingSafeEqual(ab, bb);
89027
+ return ab.length === bb.length && import_node_crypto5.default.timingSafeEqual(ab, bb);
88993
89028
  }
88994
89029
  function parseCookies(header) {
88995
89030
  const cookies = {};
@@ -89001,7 +89036,7 @@ function parseCookies(header) {
89001
89036
  }
89002
89037
  function readPersisted(file) {
89003
89038
  try {
89004
- return import_node_fs10.default.readFileSync(file, "utf8").trim();
89039
+ return import_node_fs11.default.readFileSync(file, "utf8").trim();
89005
89040
  } catch {
89006
89041
  return "";
89007
89042
  }
@@ -89037,7 +89072,7 @@ function byteRange(range, size) {
89037
89072
  return start > end || start >= size ? "unsatisfiable" : { start, end };
89038
89073
  }
89039
89074
  function sendFile(res, file, headers = {}, range) {
89040
- import_node_fs10.default.stat(file, (err, stat) => {
89075
+ import_node_fs11.default.stat(file, (err, stat) => {
89041
89076
  if (err || !stat.isFile()) {
89042
89077
  send(res, 404, "Not found");
89043
89078
  return;
@@ -89051,13 +89086,13 @@ function sendFile(res, file, headers = {}, range) {
89051
89086
  }
89052
89087
  if (part) res.writeHead(206, { ...base, "Content-Range": `bytes ${part.start}-${part.end}/${stat.size}`, "Content-Length": String(part.end - part.start + 1) });
89053
89088
  else res.writeHead(200, { ...base, "Content-Length": String(stat.size) });
89054
- import_node_fs10.default.createReadStream(file, part ?? {}).on("error", () => res.destroy()).pipe(res);
89089
+ import_node_fs11.default.createReadStream(file, part ?? {}).on("error", () => res.destroy()).pipe(res);
89055
89090
  });
89056
89091
  }
89057
89092
 
89058
89093
  // src/server/dynamic-blocks.ts
89059
- var import_node_fs11 = __toESM(require("node:fs"), 1);
89060
- var import_node_path11 = __toESM(require("node:path"), 1);
89094
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
89095
+ var import_node_path12 = __toESM(require("node:path"), 1);
89061
89096
  function dynamicUrls(xml) {
89062
89097
  const urls = /* @__PURE__ */ new Set();
89063
89098
  for (const match of stripOpaque(xml).matchAll(TAG)) {
@@ -89070,7 +89105,7 @@ function dynamicUrls(xml) {
89070
89105
  }
89071
89106
  var mtimeOf = (file) => {
89072
89107
  try {
89073
- return import_node_fs11.default.statSync(file).mtimeMs;
89108
+ return import_node_fs12.default.statSync(file).mtimeMs;
89074
89109
  } catch {
89075
89110
  return -1;
89076
89111
  }
@@ -89087,7 +89122,7 @@ function createDynamicBlocks(limits) {
89087
89122
  };
89088
89123
  const entry = (id2, dir, file) => {
89089
89124
  const map = files(id2);
89090
- const mtime = mtimeOf(import_node_path11.default.join(dir, file));
89125
+ const mtime = mtimeOf(import_node_path12.default.join(dir, file));
89091
89126
  let state = map.get(file);
89092
89127
  if (!state || state.mtime !== mtime) {
89093
89128
  state = { mtime, errors: [], ran: false };
@@ -89112,19 +89147,19 @@ function createDynamicBlocks(limits) {
89112
89147
  state(id2, dir) {
89113
89148
  let xml = "";
89114
89149
  try {
89115
- xml = import_node_fs11.default.readFileSync(import_node_path11.default.join(dir, "doc.xml"), "utf8");
89150
+ xml = import_node_fs12.default.readFileSync(import_node_path12.default.join(dir, "doc.xml"), "utf8");
89116
89151
  } catch {
89117
89152
  return { warnings: [], dynamic: {} };
89118
89153
  }
89119
89154
  const urls = dynamicUrls(xml);
89120
89155
  const map = files(id2);
89121
89156
  for (const [file, state] of map) {
89122
- if (!urls.includes(file) || state.mtime !== mtimeOf(import_node_path11.default.join(dir, file))) map.delete(file);
89157
+ if (!urls.includes(file) || state.mtime !== mtimeOf(import_node_path12.default.join(dir, file))) map.delete(file);
89123
89158
  }
89124
89159
  const warnings = [];
89125
89160
  const dynamic = {};
89126
89161
  for (const url of urls) {
89127
- if (!import_node_fs11.default.existsSync(import_node_path11.default.join(dir, url))) warnings.push(`${url} not found`);
89162
+ if (!import_node_fs12.default.existsSync(import_node_path12.default.join(dir, url))) warnings.push(`${url} not found`);
89128
89163
  const state = map.get(url);
89129
89164
  for (const error of state?.errors ?? []) warnings.push(`runtime: ${url}: ${error}`);
89130
89165
  dynamic[url] = { ran: state?.ran ?? false };
@@ -89135,8 +89170,8 @@ function createDynamicBlocks(limits) {
89135
89170
  }
89136
89171
 
89137
89172
  // src/server/selection.ts
89138
- var import_node_fs12 = __toESM(require("node:fs"), 1);
89139
- var import_node_path12 = __toESM(require("node:path"), 1);
89173
+ var import_node_fs13 = __toESM(require("node:fs"), 1);
89174
+ var import_node_path13 = __toESM(require("node:path"), 1);
89140
89175
 
89141
89176
  // src/shared/selection.ts
89142
89177
  var SELECTION_FULL_NODES = 20;
@@ -89211,14 +89246,14 @@ function readAnySelection(value) {
89211
89246
  function createSelectionStore(stateDir, exists) {
89212
89247
  const tabs = /* @__PURE__ */ new Map();
89213
89248
  let clock = 0;
89214
- const fileOf2 = (kind, id2) => import_node_path12.default.join(stateDir, kind, id2, "selection.json");
89249
+ const fileOf2 = (kind, id2) => import_node_path13.default.join(stateDir, kind, id2, "selection.json");
89215
89250
  const write = (kind, id2) => {
89216
89251
  let winner;
89217
89252
  for (const tab of tabs.values()) {
89218
89253
  if (tab.kind !== kind || tab.id !== id2) continue;
89219
89254
  if (!winner || tab.humanAt > winner.humanAt || tab.humanAt === winner.humanAt && tab.seenAt > winner.seenAt) winner = tab;
89220
89255
  }
89221
- if (!winner?.state) import_node_fs12.default.rmSync(fileOf2(kind, id2), { force: true });
89256
+ if (!winner?.state) import_node_fs13.default.rmSync(fileOf2(kind, id2), { force: true });
89222
89257
  else writeJsonAtomic(fileOf2(kind, id2), { artifact: `${kind}/${id2}`, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...winner.state });
89223
89258
  };
89224
89259
  return {
@@ -89249,19 +89284,19 @@ function createSelectionStore(stateDir, exists) {
89249
89284
  for (const kind of ["artboard", "document"]) {
89250
89285
  let ids = [];
89251
89286
  try {
89252
- ids = import_node_fs12.default.readdirSync(import_node_path12.default.join(stateDir, kind));
89287
+ ids = import_node_fs13.default.readdirSync(import_node_path13.default.join(stateDir, kind));
89253
89288
  } catch {
89254
89289
  continue;
89255
89290
  }
89256
- for (const id2 of ids) import_node_fs12.default.rmSync(fileOf2(kind, id2), { force: true });
89291
+ for (const id2 of ids) import_node_fs13.default.rmSync(fileOf2(kind, id2), { force: true });
89257
89292
  }
89258
89293
  }
89259
89294
  };
89260
89295
  }
89261
89296
 
89262
89297
  // src/server/config.ts
89263
- var import_node_fs13 = __toESM(require("node:fs"), 1);
89264
- var import_node_path13 = __toESM(require("node:path"), 1);
89298
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
89299
+ var import_node_path14 = __toESM(require("node:path"), 1);
89265
89300
 
89266
89301
  // src/shared/cloud.ts
89267
89302
  var ownLink = (url, hostId) => hostId ? `${url}#ryugi-host=${hostId}` : url;
@@ -89299,7 +89334,7 @@ function normalize(raw) {
89299
89334
  function readConfig(file) {
89300
89335
  let text2;
89301
89336
  try {
89302
- text2 = import_node_fs13.default.readFileSync(file, "utf8");
89337
+ text2 = import_node_fs14.default.readFileSync(file, "utf8");
89303
89338
  } catch {
89304
89339
  return { config: defaults() };
89305
89340
  }
@@ -89310,22 +89345,22 @@ function readConfig(file) {
89310
89345
  }
89311
89346
  }
89312
89347
  function ensureGitignore(dir) {
89313
- const file = import_node_path13.default.join(dir, ".gitignore");
89348
+ const file = import_node_path14.default.join(dir, ".gitignore");
89314
89349
  let current = "";
89315
89350
  try {
89316
- current = import_node_fs13.default.readFileSync(file, "utf8");
89351
+ current = import_node_fs14.default.readFileSync(file, "utf8");
89317
89352
  } catch {
89318
- import_node_fs13.default.writeFileSync(file, "config.json\n");
89353
+ import_node_fs14.default.writeFileSync(file, "config.json\n");
89319
89354
  return;
89320
89355
  }
89321
89356
  if (current.split(/\r?\n/).some((line) => line.trim() === "config.json")) return;
89322
- import_node_fs13.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}config.json
89357
+ import_node_fs14.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}config.json
89323
89358
  `);
89324
89359
  }
89325
89360
  function ensureConfig(file) {
89326
- import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
89327
- ensureGitignore(import_node_path13.default.dirname(file));
89328
- if (!import_node_fs13.default.existsSync(file)) writeJsonAtomic(file, defaults());
89361
+ import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true });
89362
+ ensureGitignore(import_node_path14.default.dirname(file));
89363
+ if (!import_node_fs14.default.existsSync(file)) writeJsonAtomic(file, defaults());
89329
89364
  }
89330
89365
  function updateArtifactConfig(file, key2, patch) {
89331
89366
  const { config, warning } = readConfig(file);
@@ -89345,21 +89380,21 @@ function setProjectAutoPublish(file, value) {
89345
89380
  if (warning) throw new Error(warning);
89346
89381
  if (value === null) delete config.autoPublish;
89347
89382
  else config.autoPublish = value;
89348
- import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(file), { recursive: true });
89383
+ import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true });
89349
89384
  writeJsonAtomic(file, config);
89350
89385
  }
89351
89386
 
89352
89387
  // src/server/credentials.ts
89353
- var import_node_fs14 = __toESM(require("node:fs"), 1);
89354
- var import_node_path14 = __toESM(require("node:path"), 1);
89388
+ var import_node_fs15 = __toESM(require("node:fs"), 1);
89389
+ var import_node_path15 = __toESM(require("node:path"), 1);
89355
89390
  function credentialsFile(env, platform, home) {
89356
- if (platform === "win32" && env.APPDATA) return import_node_path14.default.join(env.APPDATA, "ryugi", "credentials.json");
89357
- return import_node_path14.default.join(env.XDG_CONFIG_HOME || import_node_path14.default.join(home, ".config"), "ryugi", "credentials.json");
89391
+ if (platform === "win32" && env.APPDATA) return import_node_path15.default.join(env.APPDATA, "ryugi", "credentials.json");
89392
+ return import_node_path15.default.join(env.XDG_CONFIG_HOME || import_node_path15.default.join(home, ".config"), "ryugi", "credentials.json");
89358
89393
  }
89359
89394
  function readCredentials(file, origin) {
89360
89395
  let raw;
89361
89396
  try {
89362
- raw = JSON.parse(import_node_fs14.default.readFileSync(file, "utf8"));
89397
+ raw = JSON.parse(import_node_fs15.default.readFileSync(file, "utf8"));
89363
89398
  } catch {
89364
89399
  return null;
89365
89400
  }
@@ -89370,11 +89405,11 @@ function readCredentials(file, origin) {
89370
89405
  return { origin: savedOrigin, token, login };
89371
89406
  }
89372
89407
  function writeCredentials(file, credentials) {
89373
- import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true, mode: 448 });
89408
+ import_node_fs15.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true, mode: 448 });
89374
89409
  writeJsonAtomic(file, credentials);
89375
89410
  }
89376
89411
  function clearCredentials(file) {
89377
- import_node_fs14.default.rmSync(file, { force: true });
89412
+ import_node_fs15.default.rmSync(file, { force: true });
89378
89413
  }
89379
89414
 
89380
89415
  // node_modules/.pnpm/ws@8.18.3/node_modules/ws/wrapper.mjs
@@ -89502,7 +89537,7 @@ function createRelayClient(options) {
89502
89537
  }
89503
89538
 
89504
89539
  // src/server/ws.ts
89505
- var import_node_crypto5 = __toESM(require("node:crypto"), 1);
89540
+ var import_node_crypto6 = __toESM(require("node:crypto"), 1);
89506
89541
  var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
89507
89542
  var OPCODE_TEXT = 1;
89508
89543
  var OPCODE_CLOSE = 8;
@@ -89510,7 +89545,7 @@ var OPCODE_PING = 9;
89510
89545
  var OPCODE_PONG = 10;
89511
89546
  var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
89512
89547
  function acceptKey(clientKey) {
89513
- return import_node_crypto5.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
89548
+ return import_node_crypto6.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
89514
89549
  }
89515
89550
  function encodeFrame(opcode, payload) {
89516
89551
  const len = payload.length;
@@ -89635,21 +89670,21 @@ function createDirectRelay(options) {
89635
89670
  }
89636
89671
 
89637
89672
  // src/server/host-id.ts
89638
- var import_node_fs15 = __toESM(require("node:fs"), 1);
89639
- var import_node_path15 = __toESM(require("node:path"), 1);
89673
+ var import_node_fs16 = __toESM(require("node:fs"), 1);
89674
+ var import_node_path16 = __toESM(require("node:path"), 1);
89640
89675
  function hostIdFor(credentialsFile2) {
89641
- const file = import_node_path15.default.join(import_node_path15.default.dirname(credentialsFile2), "host-id");
89676
+ const file = import_node_path16.default.join(import_node_path16.default.dirname(credentialsFile2), "host-id");
89642
89677
  const saved = readPersisted(file);
89643
89678
  if (/^[A-Za-z0-9_-]{16,64}$/.test(saved)) return saved;
89644
89679
  const id2 = randomToken();
89645
- import_node_fs15.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true, mode: 448 });
89646
- import_node_fs15.default.writeFileSync(file, `${id2}
89680
+ import_node_fs16.default.mkdirSync(import_node_path16.default.dirname(file), { recursive: true, mode: 448 });
89681
+ import_node_fs16.default.writeFileSync(file, `${id2}
89647
89682
  `, { mode: 384 });
89648
89683
  return id2;
89649
89684
  }
89650
89685
 
89651
89686
  // src/server/avatars.ts
89652
- var import_node_crypto6 = require("node:crypto");
89687
+ var import_node_crypto7 = require("node:crypto");
89653
89688
  var AVATAR_ROUTE = /^\/api\/avatar\/([a-z]+)\/([^/]+)$/;
89654
89689
  var MAX_BYTES = 512 * 1024;
89655
89690
  var TIMEOUT_MS = 5e3;
@@ -89658,7 +89693,7 @@ var SOURCES = {
89658
89693
  gravatar: { valid: /^[0-9a-f]{64}$/, url: (id2) => `https://gravatar.com/avatar/${id2}?s=64&d=404` }
89659
89694
  };
89660
89695
  var githubAvatar = (login) => `/api/avatar/github/${login}`;
89661
- var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto6.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
89696
+ var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto7.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
89662
89697
  function createAvatars(fetchImpl = fetch) {
89663
89698
  const cache = /* @__PURE__ */ new Map();
89664
89699
  const fetchAvatar = async (url) => {
@@ -89690,7 +89725,7 @@ function createAvatars(fetchImpl = fetch) {
89690
89725
  }
89691
89726
 
89692
89727
  // src/server/cloud.ts
89693
- var import_node_crypto7 = __toESM(require("node:crypto"), 1);
89728
+ var import_node_crypto8 = __toESM(require("node:crypto"), 1);
89694
89729
 
89695
89730
  // src/shared/brand.ts
89696
89731
  var RYUGI_MARK_VIEWBOX = "0 0 512 512";
@@ -89818,8 +89853,8 @@ function cloudErrorDetails(value) {
89818
89853
  }
89819
89854
 
89820
89855
  // src/server/pack.ts
89821
- var import_node_fs16 = __toESM(require("node:fs"), 1);
89822
- var import_node_path16 = __toESM(require("node:path"), 1);
89856
+ var import_node_fs17 = __toESM(require("node:fs"), 1);
89857
+ var import_node_path17 = __toESM(require("node:path"), 1);
89823
89858
  var MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
89824
89859
  function formatBytes(bytes) {
89825
89860
  if (bytes < 1024) return `${bytes} B`;
@@ -89828,22 +89863,22 @@ function formatBytes(bytes) {
89828
89863
  }
89829
89864
  var excluded = (type, relative) => (type === "document" || type === "artboard") && relative === "comments.json";
89830
89865
  function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
89831
- const rootReal = import_node_fs16.default.realpathSync(dir);
89866
+ const rootReal = import_node_fs17.default.realpathSync(dir);
89832
89867
  const found = [];
89833
89868
  const visited = /* @__PURE__ */ new Set([rootReal]);
89834
89869
  let total = 0;
89835
89870
  const walk = (current) => {
89836
- for (const entry of import_node_fs16.default.readdirSync(current, { withFileTypes: true })) {
89871
+ for (const entry of import_node_fs17.default.readdirSync(current, { withFileTypes: true })) {
89837
89872
  if (entry.name.startsWith(".")) continue;
89838
- const full = import_node_path16.default.join(current, entry.name);
89873
+ const full = import_node_path17.default.join(current, entry.name);
89839
89874
  let real;
89840
89875
  try {
89841
- real = import_node_fs16.default.realpathSync(full);
89876
+ real = import_node_fs17.default.realpathSync(full);
89842
89877
  } catch {
89843
89878
  continue;
89844
89879
  }
89845
- if (!real.startsWith(rootReal + import_node_path16.default.sep)) continue;
89846
- const stat = import_node_fs16.default.statSync(real);
89880
+ if (!real.startsWith(rootReal + import_node_path17.default.sep)) continue;
89881
+ const stat = import_node_fs17.default.statSync(real);
89847
89882
  if (stat.isDirectory()) {
89848
89883
  if (visited.has(real)) continue;
89849
89884
  visited.add(real);
@@ -89851,7 +89886,7 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
89851
89886
  continue;
89852
89887
  }
89853
89888
  if (!stat.isFile()) continue;
89854
- const relative = import_node_path16.default.relative(dir, full).split(import_node_path16.default.sep).join("/");
89889
+ const relative = import_node_path17.default.relative(dir, full).split(import_node_path17.default.sep).join("/");
89855
89890
  if (excluded(type, relative)) continue;
89856
89891
  total += stat.size;
89857
89892
  found.push({ path: relative, real });
@@ -89861,12 +89896,12 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
89861
89896
  if (total > maxBytes) {
89862
89897
  throw new Error(`artifact is ${formatBytes(total)}; the limit is ${formatBytes(maxBytes)}`);
89863
89898
  }
89864
- return found.map((file) => ({ path: file.path, data: import_node_fs16.default.readFileSync(file.real) }));
89899
+ return found.map((file) => ({ path: file.path, data: import_node_fs17.default.readFileSync(file.real) }));
89865
89900
  }
89866
89901
 
89867
89902
  // src/server/publish-payload.ts
89868
- var import_node_fs17 = __toESM(require("node:fs"), 1);
89869
- var import_node_path17 = __toESM(require("node:path"), 1);
89903
+ var import_node_fs18 = __toESM(require("node:fs"), 1);
89904
+ var import_node_path18 = __toESM(require("node:path"), 1);
89870
89905
  var CLOUD_RUNTIME_URL = "/_ryugi/runtime/ryugi-ui.js";
89871
89906
  function sharedComments(file) {
89872
89907
  return {
@@ -89879,7 +89914,7 @@ function publishPayload(ref, dir, title, payload, comments = emptyComments()) {
89879
89914
  const { canvas, layout, versions } = payload;
89880
89915
  return { canvas, layout, versions };
89881
89916
  }
89882
- if (ref.type === "document") return { title, state: parseDocument2(import_node_fs17.default.readFileSync(import_node_path17.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
89917
+ if (ref.type === "document") return { title, state: parseDocument2(import_node_fs18.default.readFileSync(import_node_path18.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
89883
89918
  return { title };
89884
89919
  }
89885
89920
  var isPage = (type, file) => type === "html" ? file === "index.html" : (type === "document" || type === "artboard") && file.endsWith(".html");
@@ -89890,12 +89925,12 @@ function withCloudRuntime(type, files) {
89890
89925
  }
89891
89926
 
89892
89927
  // src/server/settings.ts
89893
- var import_node_fs18 = __toESM(require("node:fs"), 1);
89894
- var import_node_path18 = __toESM(require("node:path"), 1);
89895
- var settingsFileFor = (credentialsFile2) => import_node_path18.default.join(import_node_path18.default.dirname(credentialsFile2), "config.json");
89928
+ var import_node_fs19 = __toESM(require("node:fs"), 1);
89929
+ var import_node_path19 = __toESM(require("node:path"), 1);
89930
+ var settingsFileFor = (credentialsFile2) => import_node_path19.default.join(import_node_path19.default.dirname(credentialsFile2), "config.json");
89896
89931
  function readSettings(file) {
89897
89932
  try {
89898
- const raw = JSON.parse(import_node_fs18.default.readFileSync(file, "utf8"));
89933
+ const raw = JSON.parse(import_node_fs19.default.readFileSync(file, "utf8"));
89899
89934
  return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
89900
89935
  } catch {
89901
89936
  return {};
@@ -89906,7 +89941,7 @@ function readGlobalAutoPublish(file) {
89906
89941
  return typeof value === "boolean" ? value : void 0;
89907
89942
  }
89908
89943
  function writeGlobalAutoPublish(file, value) {
89909
- import_node_fs18.default.mkdirSync(import_node_path18.default.dirname(file), { recursive: true, mode: 448 });
89944
+ import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true, mode: 448 });
89910
89945
  writeJsonAtomic(file, { ...readSettings(file), autoPublish: value });
89911
89946
  }
89912
89947
  function defaultGlobalAutoPublish(file) {
@@ -90005,10 +90040,10 @@ function createCloudRoutes(options) {
90005
90040
  const state = randomToken();
90006
90041
  const verifier = randomToken();
90007
90042
  pendingStates.set(state, { expires: now + LOGIN_STATE_TTL_MS, verifier });
90008
- const challenge = import_node_crypto7.default.createHash("sha256").update(verifier).digest("base64url");
90043
+ const challenge = import_node_crypto8.default.createHash("sha256").update(verifier).digest("base64url");
90009
90044
  return `${origin}/auth/cli?port=${options.port()}&state=${state}&challenge=${challenge}`;
90010
90045
  };
90011
- const cloudFetch = async (method, path22, body) => {
90046
+ const cloudFetch = async (method, path23, body) => {
90012
90047
  const credentials = readCredentials(credentialsFile2, origin);
90013
90048
  if (!credentials) throw new SignedOut();
90014
90049
  const headers = { Authorization: `Bearer ${credentials.token}` };
@@ -90022,7 +90057,7 @@ function createCloudRoutes(options) {
90022
90057
  }
90023
90058
  let res;
90024
90059
  try {
90025
- res = await fetch(`${origin}${path22}`, { method, headers, body: payload });
90060
+ res = await fetch(`${origin}${path23}`, { method, headers, body: payload });
90026
90061
  } catch (err) {
90027
90062
  throw new CloudRefused(502, `could not reach ${origin}: ${err.message}`);
90028
90063
  }
@@ -90077,9 +90112,9 @@ function createCloudRoutes(options) {
90077
90112
  } catch (err) {
90078
90113
  throw new CloudRefused(413, err.message);
90079
90114
  }
90080
- const sha = (data) => import_node_crypto7.default.createHash("sha256").update(data).digest("hex");
90115
+ const sha = (data) => import_node_crypto8.default.createHash("sha256").update(data).digest("hex");
90081
90116
  const hashed = withCloudRuntime(ref.type, packed).map((file) => ({ ...file, hash: sha(file.data) }));
90082
- const content = { title: inspected.title, payload: inspected.payload, files: hashed.map(({ path: path22, hash }) => ({ path: path22, hash })) };
90117
+ const content = { title: inspected.title, payload: inspected.payload, files: hashed.map(({ path: path23, hash }) => ({ path: path23, hash })) };
90083
90118
  const fingerprint = sha(JSON.stringify({ title: inspected.title, payload: fingerprintPayload(inspected.payload), files: packed.map((file) => ({ path: file.path, hash: sha(file.data) })) }));
90084
90119
  return { ready: true, hashed, content, fingerprint };
90085
90120
  };
@@ -90361,7 +90396,7 @@ function typeFaviconHref(type) {
90361
90396
 
90362
90397
  // src/server/comment-names.ts
90363
90398
  var import_node_child_process = require("node:child_process");
90364
- var import_node_fs19 = __toESM(require("node:fs"), 1);
90399
+ var import_node_fs20 = __toESM(require("node:fs"), 1);
90365
90400
 
90366
90401
  // src/server/agent.ts
90367
90402
  var NAMES = {
@@ -90448,7 +90483,7 @@ function commentNames({ agentFile, projectDir, cloud }) {
90448
90483
  },
90449
90484
  agent: () => {
90450
90485
  try {
90451
- return detectAgent(JSON.parse(import_node_fs19.default.readFileSync(agentFile, "utf8")));
90486
+ return detectAgent(JSON.parse(import_node_fs20.default.readFileSync(agentFile, "utf8")));
90452
90487
  } catch {
90453
90488
  return void 0;
90454
90489
  }
@@ -90457,7 +90492,7 @@ function commentNames({ agentFile, projectDir, cloud }) {
90457
90492
  }
90458
90493
 
90459
90494
  // src/server/viewer-page.ts
90460
- var import_node_crypto8 = require("node:crypto");
90495
+ var import_node_crypto9 = require("node:crypto");
90461
90496
  var escapeHtml2 = (value) => value.replace(/[&<>"']/g, (ch) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[ch]);
90462
90497
  function viewerPage(template, page) {
90463
90498
  const values = {
@@ -90468,7 +90503,7 @@ function viewerPage(template, page) {
90468
90503
  "twitter:title": page.title,
90469
90504
  "twitter:description": page.description
90470
90505
  };
90471
- return template.replace(/<title\b[^>]*>[\s\S]*?<\/title>/i, () => `<title>${escapeHtml2(page.title)}</title>`).replace(/(<link\b[^>]*\brel="icon"[^>]*\bhref=")[^"]*(")/i, (tag, prefix, suffix) => page.icon ? `${prefix}${escapeHtml2(page.icon)}${suffix}` : tag).replace(/(<meta\b[^>]*\b(?:name|property)="([^"]+)"[^>]*\bcontent=")([^"]*)("[^>]*>)/gi, (tag, prefix, name, value, suffix) => {
90506
+ return template.replace(/<html\b/i, (tag) => page.artifactId ? `${tag} data-ryugi-artifact-id="${escapeHtml2(page.artifactId)}"` : tag).replace(/<title\b[^>]*>[\s\S]*?<\/title>/i, () => `<title>${escapeHtml2(page.title)}</title>`).replace(/(<link\b[^>]*\brel="icon"[^>]*\bhref=")[^"]*(")/i, (tag, prefix, suffix) => page.icon ? `${prefix}${escapeHtml2(page.icon)}${suffix}` : tag).replace(/(<meta\b[^>]*\b(?:name|property)="([^"]+)"[^>]*\bcontent=")([^"]*)("[^>]*>)/gi, (tag, prefix, name, value, suffix) => {
90472
90507
  const content = values[name] ?? (name === "og:image" || name === "twitter:image" ? new URL(value, page.url).href : void 0);
90473
90508
  return content === void 0 ? tag : `${prefix}${escapeHtml2(content)}${suffix}`;
90474
90509
  }).replace(/<\/head>/i, () => `<link rel="canonical" href="${escapeHtml2(page.url)}">
@@ -90477,13 +90512,13 @@ function viewerPage(template, page) {
90477
90512
  }
90478
90513
  var INLINE_SCRIPT = /<script\b(?![^>]*\bsrc=)[^>]*>([\s\S]*?)<\/script>/gi;
90479
90514
  function allowInlineScripts(csp, html) {
90480
- const hashes = [...html.matchAll(INLINE_SCRIPT)].map(([, body]) => `'sha256-${(0, import_node_crypto8.createHash)("sha256").update(body).digest("base64")}'`);
90515
+ const hashes = [...html.matchAll(INLINE_SCRIPT)].map(([, body]) => `'sha256-${(0, import_node_crypto9.createHash)("sha256").update(body).digest("base64")}'`);
90481
90516
  return hashes.length ? csp.replace(/script-src [^;]*/, (directive) => `${directive} ${hashes.join(" ")}`) : csp;
90482
90517
  }
90483
90518
 
90484
90519
  // src/server/auto-publish.ts
90485
- var import_node_crypto9 = __toESM(require("node:crypto"), 1);
90486
- var import_node_fs20 = __toESM(require("node:fs"), 1);
90520
+ var import_node_crypto10 = __toESM(require("node:crypto"), 1);
90521
+ var import_node_fs21 = __toESM(require("node:fs"), 1);
90487
90522
  var IDLE_MS = 5 * 60 * 1e3;
90488
90523
  var MAX_WAIT_MS = 15 * 60 * 1e3;
90489
90524
  var SIGNED_OUT_MESSAGE = "auto-publish paused: the Ryugi Cloud sign-in expired";
@@ -90496,7 +90531,7 @@ function isNotice(value) {
90496
90531
  function readAutoPublishState(file) {
90497
90532
  let raw = {};
90498
90533
  try {
90499
- const parsed = JSON.parse(import_node_fs20.default.readFileSync(file, "utf8"));
90534
+ const parsed = JSON.parse(import_node_fs21.default.readFileSync(file, "utf8"));
90500
90535
  if (typeof parsed === "object" && parsed !== null) raw = parsed;
90501
90536
  } catch {
90502
90537
  }
@@ -90517,7 +90552,7 @@ function createAutoPublisher(options) {
90517
90552
  const failures = /* @__PURE__ */ new Map();
90518
90553
  const save = () => writeJsonAtomic(options.stateFile, { dirty: [...dirty], notice, paused });
90519
90554
  const raise = (kind, message, upgradeUrl) => {
90520
- if (notice?.kind !== kind) notice = { id: import_node_crypto9.default.randomUUID(), kind, message, ...upgradeUrl ? { upgradeUrl } : {} };
90555
+ if (notice?.kind !== kind) notice = { id: import_node_crypto10.default.randomUUID(), kind, message, ...upgradeUrl ? { upgradeUrl } : {} };
90521
90556
  };
90522
90557
  let idleTimer = null;
90523
90558
  let maxTimer = null;
@@ -90607,7 +90642,7 @@ function createAutoPublisher(options) {
90607
90642
  }
90608
90643
 
90609
90644
  // src/server/artifact-file.ts
90610
- var import_node_fs21 = __toESM(require("node:fs"), 1);
90645
+ var import_node_fs22 = __toESM(require("node:fs"), 1);
90611
90646
  var RESOLVE = { artboard: resolveBoardFile, document: resolveDocumentAsset, html: resolveHtmlFile };
90612
90647
  var isArtifactPage = (type, relative) => type === "html" ? relative === "index.html" : relative.endsWith(".html");
90613
90648
  function readArtifactFile(dir, type, relative, uiRuntimeUrl, maxBytes = Infinity) {
@@ -90616,8 +90651,8 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl, maxBytes = Infinity
90616
90651
  if (!target) return null;
90617
90652
  let data;
90618
90653
  try {
90619
- if (import_node_fs21.default.statSync(target).size > maxBytes) throw new RangeError("too large");
90620
- data = import_node_fs21.default.readFileSync(target);
90654
+ if (import_node_fs22.default.statSync(target).size > maxBytes) throw new RangeError("too large");
90655
+ data = import_node_fs22.default.readFileSync(target);
90621
90656
  } catch (err) {
90622
90657
  if (err instanceof RangeError) throw err;
90623
90658
  return null;
@@ -90628,25 +90663,25 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl, maxBytes = Infinity
90628
90663
  }
90629
90664
 
90630
90665
  // src/server/watch.ts
90631
- var import_node_fs22 = __toESM(require("node:fs"), 1);
90632
- var import_node_path19 = __toESM(require("node:path"), 1);
90633
- var toPosix = (file) => file.split(import_node_path19.default.sep).join("/");
90666
+ var import_node_fs23 = __toESM(require("node:fs"), 1);
90667
+ var import_node_path20 = __toESM(require("node:path"), 1);
90668
+ var toPosix = (file) => file.split(import_node_path20.default.sep).join("/");
90634
90669
  var ignored = (file) => file === ".state" || file.startsWith(".state/");
90635
90670
  function snapshot(root, dir = root, out = /* @__PURE__ */ new Map()) {
90636
90671
  let entries2;
90637
90672
  try {
90638
- entries2 = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
90673
+ entries2 = import_node_fs23.default.readdirSync(dir, { withFileTypes: true });
90639
90674
  } catch {
90640
90675
  return out;
90641
90676
  }
90642
90677
  for (const entry of entries2) {
90643
- const full = import_node_path19.default.join(dir, entry.name);
90644
- const rel = toPosix(import_node_path19.default.relative(root, full));
90678
+ const full = import_node_path20.default.join(dir, entry.name);
90679
+ const rel = toPosix(import_node_path20.default.relative(root, full));
90645
90680
  if (ignored(rel)) continue;
90646
90681
  if (entry.isDirectory()) snapshot(root, full, out);
90647
90682
  else {
90648
90683
  try {
90649
- out.set(rel, import_node_fs22.default.statSync(full).mtimeMs);
90684
+ out.set(rel, import_node_fs23.default.statSync(full).mtimeMs);
90650
90685
  } catch {
90651
90686
  }
90652
90687
  }
@@ -90679,7 +90714,7 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
90679
90714
  }, debounceMs);
90680
90715
  };
90681
90716
  try {
90682
- const watcher = import_node_fs22.default.watch(root, { recursive: true }, (_event, filename) => {
90717
+ const watcher = import_node_fs23.default.watch(root, { recursive: true }, (_event, filename) => {
90683
90718
  if (filename) queue([toPosix(filename.toString())]);
90684
90719
  });
90685
90720
  watcher.on("error", () => {
@@ -90753,17 +90788,17 @@ function titleOf(payload, ref) {
90753
90788
  return payload.canvas?.title || ref.id;
90754
90789
  }
90755
90790
  async function startArtifactsServer(options) {
90756
- const root = import_node_path20.default.resolve(options.root);
90757
- const viewerDir = import_node_path20.default.resolve(options.viewerDir);
90758
- const runtimeDir = options.runtimeDir ? import_node_path20.default.resolve(options.runtimeDir) : null;
90759
- const stateDir = import_node_path20.default.join(root, ".state");
90760
- import_node_fs23.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
90761
- import_node_fs23.default.writeFileSync(import_node_path20.default.join(stateDir, ".gitignore"), "*\n");
90791
+ const root = import_node_path21.default.resolve(options.root);
90792
+ const viewerDir = import_node_path21.default.resolve(options.viewerDir);
90793
+ const runtimeDir = options.runtimeDir ? import_node_path21.default.resolve(options.runtimeDir) : null;
90794
+ const stateDir = import_node_path21.default.join(root, ".state");
90795
+ import_node_fs24.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
90796
+ import_node_fs24.default.writeFileSync(import_node_path21.default.join(stateDir, ".gitignore"), "*\n");
90762
90797
  if (options.configFile) ensureConfig(options.configFile);
90763
- const portFile = import_node_path20.default.join(stateDir, ".last-port");
90764
- const tokenFile = import_node_path20.default.join(stateDir, ".last-token");
90798
+ const portFile = import_node_path21.default.join(stateDir, ".last-port");
90799
+ const tokenFile = import_node_path21.default.join(stateDir, ".last-token");
90765
90800
  const token = readPersisted(tokenFile) || randomToken();
90766
- import_node_fs23.default.writeFileSync(tokenFile, `${token}
90801
+ import_node_fs24.default.writeFileSync(tokenFile, `${token}
90767
90802
  `, { mode: 384 });
90768
90803
  const contentToken = randomToken();
90769
90804
  const runtimeWarnings = /* @__PURE__ */ new Map();
@@ -90793,7 +90828,7 @@ async function startArtifactsServer(options) {
90793
90828
  direct.emit(message.artifact, message);
90794
90829
  };
90795
90830
  const avatars = createAvatars(options.fetch);
90796
- const names = commentNames({ agentFile: import_node_path20.default.join(stateDir, "agent"), projectDir: import_node_path20.default.resolve(root, "../.."), cloud: options.cloud });
90831
+ const names = commentNames({ agentFile: import_node_path21.default.join(stateDir, "agent"), projectDir: import_node_path21.default.resolve(root, "../.."), cloud: options.cloud });
90797
90832
  const boardComments = createBoardCommentRegistry({ root, stateDir, broadcast, names });
90798
90833
  const documents = createDocumentRegistry({
90799
90834
  root,
@@ -90832,9 +90867,9 @@ async function startArtifactsServer(options) {
90832
90867
  }
90833
90868
  return { dir, title, reasons, payload: published };
90834
90869
  };
90835
- const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path20.default.basename(import_node_path20.default.resolve(root, "../..")), port: () => port, inspect }) : null;
90870
+ const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path21.default.basename(import_node_path21.default.resolve(root, "../..")), port: () => port, inspect }) : null;
90836
90871
  const autoPublisher = cloud ? createAutoPublisher({
90837
- stateFile: import_node_path20.default.join(stateDir, "auto-publish.json"),
90872
+ stateFile: import_node_path21.default.join(stateDir, "auto-publish.json"),
90838
90873
  enabled: cloud.autoPublishEnabled,
90839
90874
  token: cloud.token,
90840
90875
  publish: async (key2) => {
@@ -90928,7 +90963,7 @@ async function startArtifactsServer(options) {
90928
90963
  };
90929
90964
  const blockIdsOf = async (id2, dir) => {
90930
90965
  await (await documents.open(id2))?.flush();
90931
- const state = parseDocument2(import_node_fs23.default.readFileSync(import_node_path20.default.join(dir, "doc.xml"), "utf8"));
90966
+ const state = parseDocument2(import_node_fs24.default.readFileSync(import_node_path21.default.join(dir, "doc.xml"), "utf8"));
90932
90967
  return new Set(state.root.children.flatMap((block) => block.$?.blockId ? [block.$.blockId] : []));
90933
90968
  };
90934
90969
  const serveAgentComments = async (req, res, id2) => {
@@ -91062,7 +91097,7 @@ async function startArtifactsServer(options) {
91062
91097
  sendFile(res, target, headers, range);
91063
91098
  return;
91064
91099
  }
91065
- import_node_fs23.default.readFile(target, "utf8", (err, source) => {
91100
+ import_node_fs24.default.readFile(target, "utf8", (err, source) => {
91066
91101
  if (err) send(res, 404, "Not found");
91067
91102
  else {
91068
91103
  const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
@@ -91089,10 +91124,11 @@ async function startArtifactsServer(options) {
91089
91124
  const summaries = artifacts.map((entry) => ({
91090
91125
  type: entry.type,
91091
91126
  id: entry.id,
91127
+ url: artifactPath(root, entry.type, entry.id),
91092
91128
  title: titleOf(readArtifact(entry.dir, entry), entry),
91093
91129
  updatedAt: latestMtime(entry.dir)
91094
91130
  }));
91095
- sendJson(res, 200, { project: import_node_path20.default.basename(import_node_path20.default.dirname(import_node_path20.default.dirname(root))), artifacts: summaries, warnings });
91131
+ sendJson(res, 200, { project: import_node_path21.default.basename(import_node_path21.default.dirname(import_node_path21.default.dirname(root))), artifacts: summaries, warnings });
91096
91132
  };
91097
91133
  function onClientText(socket, text2) {
91098
91134
  let message;
@@ -91154,7 +91190,7 @@ async function startArtifactsServer(options) {
91154
91190
  return;
91155
91191
  }
91156
91192
  if (pathname === "/robots.txt") {
91157
- sendFile(res, import_node_path20.default.join(viewerDir, "robots.txt"));
91193
+ sendFile(res, import_node_path21.default.join(viewerDir, "robots.txt"));
91158
91194
  return;
91159
91195
  }
91160
91196
  if (pathname.startsWith("/c/")) {
@@ -91278,17 +91314,21 @@ async function startArtifactsServer(options) {
91278
91314
  return;
91279
91315
  }
91280
91316
  if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
91281
- const ref = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
91282
- const dir = ref && resolveArtifactDir(root, ref.type, ref.id);
91283
- const project = import_node_path20.default.basename(import_node_path20.default.dirname(import_node_path20.default.dirname(root)));
91317
+ const requested = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
91318
+ const resolved = requested && resolveArtifactAddress(root, requested.type, requested.id);
91319
+ const ref = resolved ?? requested;
91320
+ const dir = resolved?.dir;
91321
+ const project = import_node_path21.default.basename(import_node_path21.default.dirname(import_node_path21.default.dirname(root)));
91284
91322
  const title = ref ? dir ? titleOf(readArtifact(dir, ref), ref) : ref.id : `${project} \xB7 Artifacts`;
91285
91323
  const description = ref ? `\u5728 ${project} \u9879\u76EE\u4E2D\u67E5\u770B ${title}\uFF0C\u8FD9\u662F\u4E00\u4E2A ${ref.type === "artboard" ? "Artboard" : ref.type === "document" ? "Document" : "HTML"} Artifact\u3002` : `\u6D4F\u89C8 ${project} \u9879\u76EE\u7684\u5168\u90E8 Artboard\u3001Document \u548C HTML Artifact\uFF0C\u9884\u89C8\u771F\u5B9E\u5185\u5BB9\uFF0C\u6309\u7C7B\u578B\u3001\u540D\u79F0\u548C\u66F4\u65B0\u65F6\u95F4\u67E5\u627E\u4F5C\u54C1\u3002`;
91286
- const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}/${ref ? `${ref.type}/${ref.id}` : ""}`;
91287
- const csp = PREVIEW_ROUTE.test(pathname) ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP;
91324
+ const preview = PREVIEW_ROUTE.test(pathname);
91325
+ const canonicalPath = ref ? dir ? artifactPath(root, ref.type, ref.id) : `/${ref.type}/${ref.id}` : "/";
91326
+ const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}${preview ? "/preview" : ""}${canonicalPath}`;
91327
+ const csp = preview ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP;
91288
91328
  const headers = { "Content-Type": "text/html; charset=utf-8" };
91289
91329
  if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
91290
- void import_node_fs23.default.promises.readFile(import_node_path20.default.join(viewerDir, "index.html"), "utf8").then((template) => {
91291
- const html = viewerPage(template, { title, description, url: canonical, icon: ref ? typeFaviconHref(ref.type) : void 0 });
91330
+ void import_node_fs24.default.promises.readFile(import_node_path21.default.join(viewerDir, "index.html"), "utf8").then((template) => {
91331
+ const html = viewerPage(template, { title, description, url: canonical, icon: ref ? typeFaviconHref(ref.type) : void 0, artifactId: resolved?.id });
91292
91332
  send(res, 200, html, { ...headers, "Content-Security-Policy": allowInlineScripts(csp, html) });
91293
91333
  }).catch((err) => send(res, err.code === "ENOENT" ? 404 : 500, "Viewer unavailable"));
91294
91334
  return;
@@ -91349,11 +91389,11 @@ async function startArtifactsServer(options) {
91349
91389
  port = await listen(server, options.host, 0);
91350
91390
  }
91351
91391
  cookieName = `ryugi_artifacts_${port}`;
91352
- import_node_fs23.default.writeFileSync(portFile, `${port}
91392
+ import_node_fs24.default.writeFileSync(portFile, `${port}
91353
91393
  `, { mode: 384 });
91354
91394
  const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
91355
91395
  const url = `${origin}/?key=${token}`;
91356
- const linkFor = (type, id2) => `${origin}/${type}/${id2}?key=${token}`;
91396
+ const linkFor = (type, id2) => `${origin}${artifactPath(root, type, id2)}?key=${token}`;
91357
91397
  const signatures = /* @__PURE__ */ new Map();
91358
91398
  const writeState = (ref, dir) => {
91359
91399
  const payload = readArtifact(dir, ref, runtimeOf(ref, dir));
@@ -91375,7 +91415,7 @@ async function startArtifactsServer(options) {
91375
91415
  initialChanges.push({ ref: entry, payload, files: [] });
91376
91416
  if (entry.type === "document") void documents.open(entry.id);
91377
91417
  }
91378
- writeJsonAtomic(import_node_path20.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
91418
+ writeJsonAtomic(import_node_path21.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
91379
91419
  const relayViewers = /* @__PURE__ */ new Map();
91380
91420
  const servedArtifacts = () => {
91381
91421
  const served = /* @__PURE__ */ new Map();
@@ -91468,7 +91508,7 @@ async function startArtifactsServer(options) {
91468
91508
  let merging = false;
91469
91509
  if (ref.type === "document") {
91470
91510
  const session = await documents.open(ref.id);
91471
- const text2 = await import_node_fs23.default.promises.readFile(import_node_path20.default.join(dir, "doc.xml"), "utf8").catch(() => null);
91511
+ const text2 = await import_node_fs24.default.promises.readFile(import_node_path21.default.join(dir, "doc.xml"), "utf8").catch(() => null);
91472
91512
  if (session && text2 !== null) {
91473
91513
  session.onFileText(text2);
91474
91514
  const timeout = new Promise((resolve) => setTimeout(() => resolve("timeout"), CHECK_MERGE_WAIT_MS).unref());
@@ -91476,7 +91516,7 @@ async function startArtifactsServer(options) {
91476
91516
  }
91477
91517
  }
91478
91518
  writeState(ref, dir);
91479
- const state = JSON.parse(await import_node_fs23.default.promises.readFile(import_node_path20.default.join(stateDir, ref.type, ref.id, "warnings.json"), "utf8"));
91519
+ const state = JSON.parse(await import_node_fs24.default.promises.readFile(import_node_path21.default.join(stateDir, ref.type, ref.id, "warnings.json"), "utf8"));
91480
91520
  sendJson(res, 200, merging ? { ...state, merging: true } : state);
91481
91521
  };
91482
91522
  const watcher = watchTree(
@@ -91554,7 +91594,7 @@ async function startArtifactsServer(options) {
91554
91594
  }
91555
91595
 
91556
91596
  // src/server/lifecycle.ts
91557
- var import_node_fs24 = __toESM(require("node:fs"), 1);
91597
+ var import_node_fs25 = __toESM(require("node:fs"), 1);
91558
91598
  var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
91559
91599
  var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
91560
91600
  var SERVER_ID_ARG = "--artifacts-server-id=";
@@ -91586,7 +91626,7 @@ function parseEnv(env, argv = []) {
91586
91626
  function readOwners(file) {
91587
91627
  let text2;
91588
91628
  try {
91589
- text2 = import_node_fs24.default.readFileSync(file, "utf8");
91629
+ text2 = import_node_fs25.default.readFileSync(file, "utf8");
91590
91630
  } catch {
91591
91631
  return [];
91592
91632
  }
@@ -91649,20 +91689,20 @@ function openReady(payload) {
91649
91689
  }
91650
91690
 
91651
91691
  // package.json
91652
- var version = "1.31.4";
91692
+ var version = "1.31.6";
91653
91693
 
91654
91694
  // src/server/main.ts
91655
91695
  async function main() {
91656
91696
  const config = parseEnv(process.env, process.argv.slice(2));
91657
- const root = import_node_path21.default.resolve(config.root);
91658
- const stateDir = import_node_path21.default.join(root, ".state");
91697
+ const root = import_node_path22.default.resolve(config.root);
91698
+ const stateDir = import_node_path22.default.join(root, ".state");
91659
91699
  const server = await startArtifactsServer({
91660
91700
  root,
91661
- viewerDir: import_node_path21.default.join(__dirname, "viewer"),
91662
- runtimeDir: import_node_path21.default.join(__dirname, "runtime"),
91701
+ viewerDir: import_node_path22.default.join(__dirname, "viewer"),
91702
+ runtimeDir: import_node_path22.default.join(__dirname, "runtime"),
91663
91703
  host: config.host,
91664
91704
  urlHost: config.urlHost,
91665
- configFile: import_node_path21.default.join(import_node_path21.default.dirname(root), "config.json"),
91705
+ configFile: import_node_path22.default.join(import_node_path22.default.dirname(root), "config.json"),
91666
91706
  cloud: { origin: config.cloudOrigin, credentialsFile: credentialsFile(process.env, process.platform, import_node_os.default.homedir()) },
91667
91707
  relay: { url: `${config.cloudOrigin.replace(/^http/, "ws")}/api/relay/host`, version }
91668
91708
  });
@@ -91692,12 +91732,12 @@ async function main() {
91692
91732
  if (stopping) return;
91693
91733
  stopping = true;
91694
91734
  console.log(JSON.stringify({ type: "server-stopped", reason }));
91695
- import_node_fs25.default.rmSync(import_node_path21.default.join(stateDir, "server-info"), { force: true });
91696
- writeJsonAtomic(import_node_path21.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
91735
+ import_node_fs26.default.rmSync(import_node_path22.default.join(stateDir, "server-info"), { force: true });
91736
+ writeJsonAtomic(import_node_path22.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
91697
91737
  await server.close();
91698
91738
  process.exit(0);
91699
91739
  };
91700
- const ownersFile = import_node_path21.default.join(stateDir, "owners");
91740
+ const ownersFile = import_node_path22.default.join(stateDir, "owners");
91701
91741
  const timer = setInterval(() => {
91702
91742
  const owners = readOwners(ownersFile);
91703
91743
  const reason = shutdownReason({
@@ -91711,7 +91751,7 @@ async function main() {
91711
91751
  timer.unref();
91712
91752
  process.on("SIGTERM", () => void shutdown("SIGTERM"));
91713
91753
  process.on("SIGINT", () => void shutdown("SIGINT"));
91714
- import_node_fs25.default.rmSync(import_node_path21.default.join(stateDir, "server-stopped"), { force: true });
91754
+ import_node_fs26.default.rmSync(import_node_path22.default.join(stateDir, "server-stopped"), { force: true });
91715
91755
  console.log(JSON.stringify({ type: "server-started", url: server.url, port: server.port, root }));
91716
91756
  }
91717
91757
  main().catch((err) => {