ryugi-artifacts 1.13.1 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/dist/cli.cjs +22 -4
  2. package/dist/server.cjs +343 -197
  3. package/dist/viewer/{CloudDocument-DROKEMRI.js → CloudDocument-CgM3kbiO.js} +1 -1
  4. package/dist/viewer/CloudLiveDocument-CKVtG8Wd.js +1 -0
  5. package/dist/viewer/{DocumentLayout-9ziWsfNL.js → DocumentLayout-BDQ2bRgn.js} +155 -155
  6. package/dist/viewer/DocumentPage-BBzAFj4H.js +1 -0
  7. package/dist/viewer/{abnfDiagram-VCTEODGH-7Snbrgtb.js → abnfDiagram-VCTEODGH-DXcz0DY8.js} +1 -1
  8. package/dist/viewer/{ar-SA-G6X2FPQ2-C4WXmkki.js → ar-SA-G6X2FPQ2-DaFICdeh.js} +1 -1
  9. package/dist/viewer/{architecture-7GRP2DOG-BvGJ2bde.js → architecture-7GRP2DOG-Bl5CPsMS.js} +1 -1
  10. package/dist/viewer/{architectureDiagram-5GKGNRK7-Dn48oQRa.js → architectureDiagram-5GKGNRK7-7HwBC9Wz.js} +1 -1
  11. package/dist/viewer/{az-AZ-76LH7QW2-D54gwaxj.js → az-AZ-76LH7QW2-ro71YLew.js} +1 -1
  12. package/dist/viewer/{bg-BG-XCXSNQG7-ba6x7ahJ.js → bg-BG-XCXSNQG7-BBql1i2c.js} +1 -1
  13. package/dist/viewer/{blockDiagram-I7D4REHJ-DPLSvrPU.js → blockDiagram-I7D4REHJ-DN6_CCIZ.js} +1 -1
  14. package/dist/viewer/{bn-BD-2XOGV67Q-Dx78lDoy.js → bn-BD-2XOGV67Q-D0nEk_sk.js} +1 -1
  15. package/dist/viewer/{c4Diagram-7LVT6UL2-D4oNLtMS.js → c4Diagram-7LVT6UL2-BiKuFZ_0.js} +1 -1
  16. package/dist/viewer/{ca-ES-6MX7JW3Y-DIzt8Q6T.js → ca-ES-6MX7JW3Y-BzXg8v5p.js} +1 -1
  17. package/dist/viewer/channel-CoY9xRKf.js +1 -0
  18. package/dist/viewer/{chunk-4HAMMTFA-mI_qOrQp.js → chunk-4HAMMTFA-D8wduydj.js} +1 -1
  19. package/dist/viewer/{chunk-75Z2AOVW-CkyZ2k2Y.js → chunk-75Z2AOVW-A-EObLCy.js} +1 -1
  20. package/dist/viewer/{chunk-DU6HZSFF-BWpgeLJJ.js → chunk-DU6HZSFF-CDWc5UBY.js} +1 -1
  21. package/dist/viewer/{chunk-EIO257PC-D3DH6aJS.js → chunk-EIO257PC-KVQLe9-1.js} +1 -1
  22. package/dist/viewer/{chunk-F27PBJKO-Zk52-grf.js → chunk-F27PBJKO-qGDpbSI2.js} +1 -1
  23. package/dist/viewer/{chunk-GMAD6QVW-B8OPXGKD.js → chunk-GMAD6QVW-BPxTHMTi.js} +1 -1
  24. package/dist/viewer/{chunk-GVQU2GXP-BRPsjMGA.js → chunk-GVQU2GXP-C5_2EAAn.js} +1 -1
  25. package/dist/viewer/{chunk-IMKFNOWR-C6TSKNHs.js → chunk-IMKFNOWR-CoST25Zy.js} +1 -1
  26. package/dist/viewer/{chunk-L3NEJ4N5-U5fh1b9J.js → chunk-L3NEJ4N5-DqtaXAcI.js} +1 -1
  27. package/dist/viewer/{chunk-OSK3NFVY-BvbdG-aP.js → chunk-OSK3NFVY-DacvL7tA.js} +1 -1
  28. package/dist/viewer/{chunk-P2QGCYS3-iklY7skC.js → chunk-P2QGCYS3-DJOHCBv0.js} +1 -1
  29. package/dist/viewer/{chunk-POPQ4Y6H-B0smFSPK.js → chunk-POPQ4Y6H-at1Afs_1.js} +1 -1
  30. package/dist/viewer/{chunk-PWAF6VOD-BsgO0tHH.js → chunk-PWAF6VOD-Cxj_hOdt.js} +1 -1
  31. package/dist/viewer/{chunk-SHT3W25Y---6MVIra.js → chunk-SHT3W25Y-D9pKJ6Au.js} +1 -1
  32. package/dist/viewer/{chunk-SVP7TREG-pvbG6ia8.js → chunk-SVP7TREG-svneeNVA.js} +1 -1
  33. package/dist/viewer/{chunk-TICWLB2K-QwIBQ5m0.js → chunk-TICWLB2K-xfr9ROyW.js} +1 -1
  34. package/dist/viewer/classDiagram-ZZMXUADV-lu71gUXJ.js +1 -0
  35. package/dist/viewer/classDiagram-v2-VYDZK3BY-lu71gUXJ.js +1 -0
  36. package/dist/viewer/{cs-CZ-2BRQDIVT-D7YMDD9n.js → cs-CZ-2BRQDIVT-bwZx9UIu.js} +1 -1
  37. package/dist/viewer/{cynefin-OW5HDTMX-BXlWMzIh.js → cynefin-OW5HDTMX-B-FRYmfA.js} +1 -1
  38. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-PY8aYbCu.js → cynefinDiagram-5FMLGOSQ-DlNaJbj_.js} +1 -1
  39. package/dist/viewer/{da-DK-5WZEPLOC-CNfuwT_x.js → da-DK-5WZEPLOC-BApDVcwE.js} +1 -1
  40. package/dist/viewer/{dagre-GXQ25YYZ-BYwPp6cN.js → dagre-GXQ25YYZ-DWu2Ycc5.js} +1 -1
  41. package/dist/viewer/{de-DE-XR44H4JA-BHhzPpeY.js → de-DE-XR44H4JA-COcHc6Zt.js} +1 -1
  42. package/dist/viewer/{diagram-S7CK7UJ4-Hxr5IGEj.js → diagram-S7CK7UJ4-D8VO7YKc.js} +1 -1
  43. package/dist/viewer/{diagram-UQ7AKVKN-qbe2cy8h.js → diagram-UQ7AKVKN-D5OcQNY9.js} +1 -1
  44. package/dist/viewer/{diagram-VSXAHHWV-DiLlG6yw.js → diagram-VSXAHHWV-D8r4mNUW.js} +1 -1
  45. package/dist/viewer/{diagram-VX7I27RA-CO8LquuV.js → diagram-VX7I27RA-DRHmiAWI.js} +1 -1
  46. package/dist/viewer/{diagram-Z3DM3KII-C6FntHFg.js → diagram-Z3DM3KII-ClXzWLem.js} +1 -1
  47. package/dist/viewer/{dist-D1Wa4qrD.js → dist-BKtxxS1a.js} +1 -1
  48. package/dist/viewer/dist-Bgijnk4D.js +1 -0
  49. package/dist/viewer/{dist-BSpv39WM.js → dist-BuKe8NdN.js} +1 -1
  50. package/dist/viewer/dist-C2adJeNZ.js +9 -0
  51. package/dist/viewer/{dist-CfCrut1-.js → dist-CByD4sdq.js} +1 -1
  52. package/dist/viewer/{dist-BJtdl9HO.js → dist-CFkCXjQP.js} +1 -1
  53. package/dist/viewer/{dist-KzZE1cs6.js → dist-CV7QdHTq.js} +1 -1
  54. package/dist/viewer/dist-C_NwF-ep.js +23 -0
  55. package/dist/viewer/{dist-DL_BDhjt.js → dist-D0Emc84u.js} +1 -1
  56. package/dist/viewer/{dist-8fl03Nsj.js → dist-DB3o8dUU.js} +1 -1
  57. package/dist/viewer/{dist-BDSLw9q0.js → dist-DLh5uREE.js} +1 -1
  58. package/dist/viewer/{dist-CubZ-9at.js → dist-DcGUli8O.js} +1 -1
  59. package/dist/viewer/{dist-F3v4_2y_.js → dist-DfWxOyg4.js} +2 -2
  60. package/dist/viewer/{dist-ChDLFu8I.js → dist-DlANbAUX.js} +1 -1
  61. package/dist/viewer/dist-DzBPEHnz.js +11 -0
  62. package/dist/viewer/{dist-2-DBqfQz.js → dist-G2JHMLgK.js} +1 -1
  63. package/dist/viewer/{dist-BFnzZT38.js → dist-M7Lz5R2v.js} +1 -1
  64. package/dist/viewer/{dist-DJly3LNR.js → dist-TX5rYYGW.js} +4 -4
  65. package/dist/viewer/{dist-CY5J2IzE.js → dist-VupXLYv6.js} +1 -1
  66. package/dist/viewer/dist-_3NL_2LS.js +6 -0
  67. package/dist/viewer/{dist-DkBG6KRP.js → dist-a8BuHhYq.js} +1 -1
  68. package/dist/viewer/{dist-RblNtGL7.js → dist-mDWB-P3S.js} +1 -1
  69. package/dist/viewer/{dist-L-7q6M9h.js → dist-q1jFGEbP.js} +1 -1
  70. package/dist/viewer/{dist-sUulK2s9.js → dist-rgdCugHI.js} +1 -1
  71. package/dist/viewer/{ebnfDiagram-PWID7BFC-CRY0N21G.js → ebnfDiagram-PWID7BFC-BOzsyHEk.js} +1 -1
  72. package/dist/viewer/{el-GR-BZB4AONW-DUqgRMTy.js → el-GR-BZB4AONW-h1eLQlP7.js} +1 -1
  73. package/dist/viewer/{en-B4ZKOASM-CLPoEBEZ.js → en-B4ZKOASM-EdleGu9D.js} +1 -1
  74. package/dist/viewer/{erDiagram-RLTQ6QDP-B5ION-eU.js → erDiagram-RLTQ6QDP-BF_tpcM3.js} +1 -1
  75. package/dist/viewer/{es-ES-U4NZUMDT-DDd8Woe3.js → es-ES-U4NZUMDT-DeaeHEK9.js} +1 -1
  76. package/dist/viewer/{eu-ES-A7QVB2H4-BQPiKGQE.js → eu-ES-A7QVB2H4-BzoRNYbw.js} +1 -1
  77. package/dist/viewer/{eventmodeling-NTZA5JFV-CATeUuOQ.js → eventmodeling-NTZA5JFV-CUPY4M1x.js} +1 -1
  78. package/dist/viewer/{fa-IR-HGAKTJCU-Bns8t3Hw.js → fa-IR-HGAKTJCU-fXYoNuWo.js} +1 -1
  79. package/dist/viewer/{fi-FI-Z5N7JZ37-C_twvi10.js → fi-FI-Z5N7JZ37-CTVEZXqM.js} +1 -1
  80. package/dist/viewer/flowDiagram-HODETNUW-DpY3t4b0.js +1 -0
  81. package/dist/viewer/{fr-FR-RHASNOE6-N6G8JzbU.js → fr-FR-RHASNOE6-BizkpgaG.js} +1 -1
  82. package/dist/viewer/ganttDiagram-EL5Y4UJY-DvL8TKGV.js +292 -0
  83. package/dist/viewer/{gitGraph-4MIJSDKK-BYZnsBO9.js → gitGraph-4MIJSDKK-C3CdCDb5.js} +1 -1
  84. package/dist/viewer/{gitGraphDiagram-WWUBYQGX--dMedsqU.js → gitGraphDiagram-WWUBYQGX-Bm0Pyvyn.js} +1 -1
  85. package/dist/viewer/{gl-ES-HMX3MZ6V-oxefKHej.js → gl-ES-HMX3MZ6V-rsfHb2R9.js} +1 -1
  86. package/dist/viewer/{he-IL-6SHJWFNN-GB3sULCk.js → he-IL-6SHJWFNN-BmWEwAWC.js} +1 -1
  87. package/dist/viewer/{hi-IN-IWLTKZ5I-RLz998Fr.js → hi-IN-IWLTKZ5I-gzYZTFIt.js} +1 -1
  88. package/dist/viewer/{hu-HU-A5ZG7DT2-CQSNnwmA.js → hu-HU-A5ZG7DT2-DqXGHJ4g.js} +1 -1
  89. package/dist/viewer/{id-ID-SAP4L64H-JkWndBOF.js → id-ID-SAP4L64H-CVbSVAc3.js} +1 -1
  90. package/dist/viewer/{image-GAAHSSAO-BsOh2Dj5.js → image-GAAHSSAO-B0g7YyLf.js} +1 -1
  91. package/dist/viewer/index.html +1 -1
  92. package/dist/viewer/index.js +8 -8
  93. package/dist/viewer/index2.css +36 -0
  94. package/dist/viewer/{info-A6RAGUB7-w-CNJ77m.js → info-A6RAGUB7-BfTkwG6X.js} +1 -1
  95. package/dist/viewer/{infoDiagram-27XIBGKW-DHAf1ebP.js → infoDiagram-27XIBGKW-DOxIYIRL.js} +1 -1
  96. package/dist/viewer/{ishikawaDiagram-5VMMS53U-BOANZ4my.js → ishikawaDiagram-5VMMS53U-D-U6Fi8F.js} +1 -1
  97. package/dist/viewer/{it-IT-JPQ66NNP-BpUeMeKA.js → it-IT-JPQ66NNP-6PNiI36L.js} +1 -1
  98. package/dist/viewer/{ja-JP-DBVTYXUO-AmyJ9Ehh.js → ja-JP-DBVTYXUO-D3SJtNp5.js} +1 -1
  99. package/dist/viewer/{journeyDiagram-3NMN7TZE-d9tXMN6w.js → journeyDiagram-3NMN7TZE-8Mz0Nae3.js} +1 -1
  100. package/dist/viewer/{kaa-6HZHGXH3-nS9x8k05.js → kaa-6HZHGXH3-Bz3WA5yL.js} +1 -1
  101. package/dist/viewer/{kab-KAB-ZGHBKWFO-CSlBAp4c.js → kab-KAB-ZGHBKWFO-W2PtzMEV.js} +1 -1
  102. package/dist/viewer/{kanban-definition-UXKFOSKX-CN1Z3Ciu.js → kanban-definition-UXKFOSKX-BP8HwPzL.js} +1 -1
  103. package/dist/viewer/{kk-KZ-P5N5QNE5-CttFS7-E.js → kk-KZ-P5N5QNE5-Dc1i0Bup.js} +1 -1
  104. package/dist/viewer/{km-KH-HSX4SM5Z-D719ESMV.js → km-KH-HSX4SM5Z-C88_w0rR.js} +1 -1
  105. package/dist/viewer/{ko-KR-MTYHY66A-BBfeWT-i.js → ko-KR-MTYHY66A-DWOt-6As.js} +1 -1
  106. package/dist/viewer/{ku-TR-6OUDTVRD-CGsGxS1P.js → ku-TR-6OUDTVRD-B7qeFzlo.js} +1 -1
  107. package/dist/viewer/{lt-LT-XHIRWOB4-i3RRm6p_.js → lt-LT-XHIRWOB4-Dc9eguDu.js} +1 -1
  108. package/dist/viewer/{lv-LV-5QDEKY6T-ua5VHQIt.js → lv-LV-5QDEKY6T-D9CzWKMj.js} +1 -1
  109. package/dist/viewer/{mermaid-parser.core-eTBicIMn.js → mermaid-parser.core-Cd74p1Qw.js} +3 -3
  110. package/dist/viewer/{mindmap-definition-YA3MSWOX-DgcPDhCe.js → mindmap-definition-YA3MSWOX-Bikv3SLv.js} +1 -1
  111. package/dist/viewer/{mr-IN-CRQNXWMA-BSJ4z3i6.js → mr-IN-CRQNXWMA-CtlsKIl9.js} +1 -1
  112. package/dist/viewer/{my-MM-5M5IBNSE-BSIuPPdh.js → my-MM-5M5IBNSE-CiyAGqHH.js} +1 -1
  113. package/dist/viewer/{nb-NO-T6EIAALU-CW82jvNd.js → nb-NO-T6EIAALU-l9uMRUdk.js} +1 -1
  114. package/dist/viewer/{nl-NL-IS3SIHDZ-CppHkdms.js → nl-NL-IS3SIHDZ-zja_zaqN.js} +1 -1
  115. package/dist/viewer/{nn-NO-6E72VCQL-CsedjQ-N.js → nn-NO-6E72VCQL-BiP5RLsf.js} +1 -1
  116. package/dist/viewer/{oc-FR-POXYY2M6-BMqr4WHW.js → oc-FR-POXYY2M6-CvKUzwab.js} +1 -1
  117. package/dist/viewer/{pa-IN-N4M65BXN-BWvaUxU-.js → pa-IN-N4M65BXN-DioFchQd.js} +1 -1
  118. package/dist/viewer/{packet-AYTQ26CC-Nm-7d4T7.js → packet-AYTQ26CC-Bu-WAKTD.js} +1 -1
  119. package/dist/viewer/{pegDiagram-XKGWAZYB-Ck2BR5Qb.js → pegDiagram-XKGWAZYB-BSllNtPI.js} +1 -1
  120. package/dist/viewer/percentages-BXMCSKIN-BRZnWvym.js +1 -0
  121. package/dist/viewer/{pie-WAS4IAKB-DUW05HU3.js → pie-WAS4IAKB-DQReqHvw.js} +1 -1
  122. package/dist/viewer/{pieDiagram-E7YTZNPT-D_R0FEOX.js → pieDiagram-E7YTZNPT-b1-BsaA4.js} +3 -3
  123. package/dist/viewer/{pl-PL-T2D74RX3-xZvABOI-.js → pl-PL-T2D74RX3-Ci7dAnI8.js} +1 -1
  124. package/dist/viewer/{prod-CxvgXXgp.js → prod-CPZkgD7t.js} +9 -9
  125. package/dist/viewer/{pt-BR-5N22H2LF-CSj-mVgR.js → pt-BR-5N22H2LF--VT7NYYE.js} +1 -1
  126. package/dist/viewer/{pt-PT-UZXXM6DQ-noHR1ql1.js → pt-PT-UZXXM6DQ-CWdbQilC.js} +1 -1
  127. package/dist/viewer/{quadrantDiagram-AXDQQJYC-CBWQysk9.js → quadrantDiagram-AXDQQJYC-D0pucWR0.js} +1 -1
  128. package/dist/viewer/{radar-RG4KPBEZ-C-qb8AwS.js → radar-RG4KPBEZ-D_r12v0L.js} +1 -1
  129. package/dist/viewer/{railroad-74A4TZTK-CN-vYYIp.js → railroad-74A4TZTK-JLrx94cB.js} +1 -1
  130. package/dist/viewer/{railroad-abnf-HS5TGJTU-CIbwPEoO.js → railroad-abnf-HS5TGJTU-zGEQrPX3.js} +1 -1
  131. package/dist/viewer/{railroad-ebnf-LZEXJU2U-BiGh6OTy.js → railroad-ebnf-LZEXJU2U-CwEVA1VE.js} +1 -1
  132. package/dist/viewer/{railroad-peg-WCYAUIDC-Ch799Qw2.js → railroad-peg-WCYAUIDC-aKEE6HSg.js} +1 -1
  133. package/dist/viewer/{railroadDiagram-O6MQD6OU-Bagb5kRs.js → railroadDiagram-O6MQD6OU-DIPJ2PKr.js} +1 -1
  134. package/dist/viewer/{requirementDiagram-BXWQKSXE-DbDliiGP.js → requirementDiagram-BXWQKSXE-DEGhiwJ9.js} +1 -1
  135. package/dist/viewer/{ro-RO-JPDTUUEW-DeHkNnfy.js → ro-RO-JPDTUUEW-BK4wLUL7.js} +1 -1
  136. package/dist/viewer/{ru-RU-B4JR7IUQ-CHFTZftm.js → ru-RU-B4JR7IUQ-BDPQ8blU.js} +1 -1
  137. package/dist/viewer/{sankeyDiagram-P5KCCOFB-B1FoUvnF.js → sankeyDiagram-P5KCCOFB-DO2JtEMk.js} +1 -1
  138. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-YjNUuoUX.js → sequenceDiagram-WJ2MYXX4-D7sLhGYb.js} +1 -1
  139. package/dist/viewer/{si-LK-N5RQ5JYF-Dp4ARNRJ.js → si-LK-N5RQ5JYF-D5DWsUAA.js} +1 -1
  140. package/dist/viewer/{sk-SK-C5VTKIMK-AKA_erzT.js → sk-SK-C5VTKIMK-Cia9j1Te.js} +1 -1
  141. package/dist/viewer/{sl-SI-NN7IZMDC-BDiZjXA1.js → sl-SI-NN7IZMDC-CV304k5j.js} +1 -1
  142. package/dist/viewer/{stateDiagram-D77RDMKH-ATh-w1b3.js → stateDiagram-D77RDMKH-BMNx9_M8.js} +1 -1
  143. package/dist/viewer/stateDiagram-v2-MP3YSRHH-CPa9DZs4.js +1 -0
  144. package/dist/viewer/subset-shared.chunk-ChUk9bHw.js +1 -0
  145. package/dist/viewer/{subset-worker.chunk-CBUvRfcN.js → subset-worker.chunk-CHQzlaj3.js} +1 -1
  146. package/dist/viewer/{sv-SE-XGPEYMSR-Cj0AcU_6.js → sv-SE-XGPEYMSR-CXdp-XZD.js} +1 -1
  147. package/dist/viewer/{swimlanes-42K2YHIH-C6oPbOc_.js → swimlanes-42K2YHIH-BwUyxwi3.js} +1 -1
  148. package/dist/viewer/swimlanesDiagram-VR7AAH4N-BgxS36EG.js +8 -0
  149. package/dist/viewer/{ta-IN-2NMHFXQM-8VJaxDdr.js → ta-IN-2NMHFXQM-CObY6q-8.js} +1 -1
  150. package/dist/viewer/{th-TH-HPSO5L25-Czv7oKbg.js → th-TH-HPSO5L25-CEOiELZN.js} +1 -1
  151. package/dist/viewer/{timeline-definition-24CTP7MA-DLUP8njF.js → timeline-definition-24CTP7MA-BJ-7Fdfr.js} +1 -1
  152. package/dist/viewer/{tr-TR-DEFEU3FU-cMr0klQe.js → tr-TR-DEFEU3FU-CPj5dFcB.js} +1 -1
  153. package/dist/viewer/{treeView-Q6P3EWNA-BUR1hhrC.js → treeView-Q6P3EWNA-DaAtai94.js} +1 -1
  154. package/dist/viewer/{treemap-WGGIJYW6-DoZbg1PH.js → treemap-WGGIJYW6-BrSC50io.js} +1 -1
  155. package/dist/viewer/{uk-UA-QMV73CPH-DtCG1wYk.js → uk-UA-QMV73CPH-BkZyFeXP.js} +1 -1
  156. package/dist/viewer/{useSandboxFrame-CqqcCy4p.js → useSandboxFrame-BpJ9uM86.js} +1 -1
  157. package/dist/viewer/{vennDiagram-4TSXK5OY-CawO2Qt4.js → vennDiagram-4TSXK5OY-DnFbjWDw.js} +1 -1
  158. package/dist/viewer/{vi-VN-M7AON7JQ-BpNbQd8Q.js → vi-VN-M7AON7JQ-CkKKOpBQ.js} +1 -1
  159. package/dist/viewer/{wardley-WFR3VGLG-QixpmoDn.js → wardley-WFR3VGLG-CtJjyNRB.js} +1 -1
  160. package/dist/viewer/{wardleyDiagram-VM6X3IG4-WPo1rwgF.js → wardleyDiagram-VM6X3IG4-CN_pm__V.js} +1 -1
  161. package/dist/viewer/{xychartDiagram-S5SC5T6Z-DGBqDGeR.js → xychartDiagram-S5SC5T6Z-C7XLywXm.js} +2 -2
  162. package/dist/viewer/{zh-CN-LNUGB5OW-Col_PjC7.js → zh-CN-LNUGB5OW-BQcCqsDg.js} +1 -1
  163. package/dist/viewer/{zh-HK-E62DVLB3-z4YynTvk.js → zh-HK-E62DVLB3-Bp-jK0zw.js} +1 -1
  164. package/dist/viewer/{zh-TW-RAJ6MFWO-DRUQUZWj.js → zh-TW-RAJ6MFWO-KmFL88Bs.js} +1 -1
  165. package/package.json +1 -1
  166. package/dist/viewer/CloudLiveDocument-DVJYvOsu.js +0 -1
  167. package/dist/viewer/DocumentPage-BzZQ4dIA.js +0 -1
  168. package/dist/viewer/channel-DNz5iSBO.js +0 -1
  169. package/dist/viewer/classDiagram-ZZMXUADV-DJCVzIyl.js +0 -1
  170. package/dist/viewer/classDiagram-v2-VYDZK3BY-DJCVzIyl.js +0 -1
  171. package/dist/viewer/dist-CAvp6Xxt.js +0 -6
  172. package/dist/viewer/dist-Dsnv_CF_.js +0 -1
  173. package/dist/viewer/dist-DumDK5j7.js +0 -11
  174. package/dist/viewer/dist-GWGyTSFy.js +0 -23
  175. package/dist/viewer/dist-f2qY_ieJ.js +0 -9
  176. package/dist/viewer/flowDiagram-HODETNUW-DbQx4szb.js +0 -1
  177. package/dist/viewer/ganttDiagram-EL5Y4UJY-DC63ZiWI.js +0 -292
  178. package/dist/viewer/percentages-BXMCSKIN-50X9K3MT.js +0 -1
  179. package/dist/viewer/stateDiagram-v2-MP3YSRHH-wUz1nCet.js +0 -1
  180. package/dist/viewer/subset-shared.chunk-M2Qq5pRR.js +0 -1
  181. package/dist/viewer/swimlanesDiagram-VR7AAH4N-c6uNYsV1.js +0 -8
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_fs22 = __toESM(require("node:fs"), 1);
5174
+ var import_node_fs24 = __toESM(require("node:fs"), 1);
5175
5175
  var import_node_os = __toESM(require("node:os"), 1);
5176
- var import_node_path19 = __toESM(require("node:path"), 1);
5176
+ var import_node_path20 = __toESM(require("node:path"), 1);
5177
5177
 
5178
5178
  // src/server/app.ts
5179
- var import_node_fs20 = __toESM(require("node:fs"), 1);
5179
+ var import_node_fs22 = __toESM(require("node:fs"), 1);
5180
5180
  var import_node_http = __toESM(require("node:http"), 1);
5181
- var import_node_path18 = __toESM(require("node:path"), 1);
5181
+ var import_node_path19 = __toESM(require("node:path"), 1);
5182
5182
 
5183
5183
  // src/shared/types.ts
5184
5184
  var ARTIFACT_TYPES = ["artboard", "document", "html"];
@@ -19250,19 +19250,19 @@ var ElementDOMSlot = class _ElementDOMSlot extends DOMSlot {
19250
19250
  }
19251
19251
  };
19252
19252
  function indexPath(root, child) {
19253
- const path20 = [];
19253
+ const path21 = [];
19254
19254
  let node = child;
19255
19255
  for (; node !== root && node !== null; node = node.parentNode) {
19256
19256
  let i6 = 0;
19257
19257
  for (let sibling = node.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
19258
19258
  i6++;
19259
19259
  }
19260
- path20.push(i6);
19260
+ path21.push(i6);
19261
19261
  }
19262
19262
  if (!(node === root)) {
19263
19263
  formatDevErrorMessage(`indexPath: root is not a parent of child`);
19264
19264
  }
19265
- return path20.reverse();
19265
+ return path21.reverse();
19266
19266
  }
19267
19267
  // @__NO_SIDE_EFFECTS__
19268
19268
  function readLexicalVersion() {
@@ -34042,9 +34042,9 @@ function getActiveElementDeep(root) {
34042
34042
  function getComposedEventTarget(event) {
34043
34043
  const target = event.target;
34044
34044
  if (target !== null && isHTMLElement(target) && target.shadowRoot !== null && typeof event.composedPath === "function") {
34045
- const path20 = event.composedPath();
34046
- if (path20.length > 0) {
34047
- return path20[0];
34045
+ const path21 = event.composedPath();
34046
+ if (path21.length > 0) {
34047
+ return path21[0];
34048
34048
  }
34049
34049
  }
34050
34050
  return target;
@@ -44140,10 +44140,10 @@ function _loadWasmModule(sync, filepath, src, imports2) {
44140
44140
  var buf = null;
44141
44141
  var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
44142
44142
  if (filepath && isNode2) {
44143
- var fs25 = null;
44144
- var path20 = null;
44143
+ var fs27 = null;
44144
+ var path21 = null;
44145
44145
  return new Promise((resolve, reject) => {
44146
- fs25.readFile(path20.resolve(__dirname, filepath), (error, buffer) => {
44146
+ fs27.readFile(path21.resolve(__dirname, filepath), (error, buffer) => {
44147
44147
  if (error != null) {
44148
44148
  reject(error);
44149
44149
  } else {
@@ -45446,10 +45446,10 @@ var LoroDoc = class _LoroDoc {
45446
45446
  * @param {string} path
45447
45447
  * @returns {Value | Container | undefined}
45448
45448
  */
45449
- getByPath(path20) {
45449
+ getByPath(path21) {
45450
45450
  try {
45451
45451
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
45452
- const ptr0 = passStringToWasm0(path20, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
45452
+ const ptr0 = passStringToWasm0(path21, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
45453
45453
  const len0 = WASM_VECTOR_LEN;
45454
45454
  wasm.lorodoc_getByPath(retptr, this.__wbg_ptr, ptr0, len0);
45455
45455
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
@@ -88549,6 +88549,7 @@ var import_node_fs12 = __toESM(require("node:fs"), 1);
88549
88549
  var import_node_path12 = __toESM(require("node:path"), 1);
88550
88550
 
88551
88551
  // src/shared/cloud.ts
88552
+ var ownLink = (url, hostId) => hostId ? `${url}#ryugi-host=${hostId}` : url;
88552
88553
  var isVisibility = (value) => value === "private" || value === "public";
88553
88554
 
88554
88555
  // src/server/config.ts
@@ -88714,7 +88715,7 @@ function createRelayClient(options) {
88714
88715
  ws2.on("open", () => {
88715
88716
  backoff = 1e3;
88716
88717
  announced = idsOf(served).join("\n");
88717
- send2({ t: "hello", version: options.version, ids: idsOf(served) });
88718
+ send2({ t: "hello", version: options.version, ids: idsOf(served), ...options.local ? { local: options.local() } : {} });
88718
88719
  heartbeat = setInterval(() => {
88719
88720
  if (watched.size > 0) options.onActivity();
88720
88721
  ws2.send("ping");
@@ -88782,8 +88783,155 @@ function createRelayClient(options) {
88782
88783
  };
88783
88784
  }
88784
88785
 
88786
+ // src/server/ws.ts
88787
+ var import_node_crypto3 = __toESM(require("node:crypto"), 1);
88788
+ var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
88789
+ var OPCODE_TEXT = 1;
88790
+ var OPCODE_CLOSE = 8;
88791
+ var OPCODE_PING = 9;
88792
+ var OPCODE_PONG = 10;
88793
+ var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
88794
+ function acceptKey(clientKey) {
88795
+ return import_node_crypto3.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
88796
+ }
88797
+ function encodeFrame(opcode, payload) {
88798
+ const len = payload.length;
88799
+ let header;
88800
+ if (len < 126) {
88801
+ header = Buffer.from([128 | opcode, len]);
88802
+ } else if (len < 65536) {
88803
+ header = Buffer.alloc(4);
88804
+ header[0] = 128 | opcode;
88805
+ header[1] = 126;
88806
+ header.writeUInt16BE(len, 2);
88807
+ } else {
88808
+ header = Buffer.alloc(10);
88809
+ header[0] = 128 | opcode;
88810
+ header[1] = 127;
88811
+ header.writeBigUInt64BE(BigInt(len), 2);
88812
+ }
88813
+ return Buffer.concat([header, payload]);
88814
+ }
88815
+ var textFrame = (text2) => encodeFrame(OPCODE_TEXT, Buffer.from(text2));
88816
+ function completeHandshake(socket, clientKey) {
88817
+ socket.write(
88818
+ `HTTP/1.1 101 Switching Protocols\r
88819
+ Upgrade: websocket\r
88820
+ Connection: Upgrade\r
88821
+ Sec-WebSocket-Accept: ${acceptKey(clientKey)}\r
88822
+ \r
88823
+ `
88824
+ );
88825
+ }
88826
+ function rejectUpgrade(socket, status, reason) {
88827
+ socket.end(`HTTP/1.1 ${status} ${reason}\r
88828
+ Connection: close\r
88829
+ Content-Length: 0\r
88830
+ \r
88831
+ `);
88832
+ }
88833
+ function handleClientFrames(socket, onText) {
88834
+ let buffer = Buffer.alloc(0);
88835
+ socket.on("data", (chunk) => {
88836
+ buffer = Buffer.concat([buffer, chunk]);
88837
+ while (buffer.length >= 2) {
88838
+ const fin = (buffer[0] & 128) !== 0;
88839
+ const opcode = buffer[0] & 15;
88840
+ let len = buffer[1] & 127;
88841
+ let offset = 2;
88842
+ if (len === 126) {
88843
+ if (buffer.length < 4) return;
88844
+ len = buffer.readUInt16BE(2);
88845
+ offset = 4;
88846
+ } else if (len === 127) {
88847
+ if (buffer.length < 10) return;
88848
+ const big = buffer.readBigUInt64BE(2);
88849
+ if (big > BigInt(MAX_CLIENT_FRAME)) {
88850
+ socket.destroy();
88851
+ return;
88852
+ }
88853
+ len = Number(big);
88854
+ offset = 10;
88855
+ }
88856
+ const total = offset + 4 + len;
88857
+ if (buffer.length < total) return;
88858
+ const mask = buffer.subarray(offset, offset + 4);
88859
+ const payload = Buffer.from(buffer.subarray(offset + 4, total));
88860
+ for (let i6 = 0; i6 < payload.length; i6++) payload[i6] = payload[i6] ^ mask[i6 % 4];
88861
+ buffer = buffer.subarray(total);
88862
+ if (opcode === OPCODE_CLOSE) {
88863
+ socket.end(encodeFrame(OPCODE_CLOSE, Buffer.alloc(0)));
88864
+ return;
88865
+ }
88866
+ if (opcode === OPCODE_PING) socket.write(encodeFrame(OPCODE_PONG, payload));
88867
+ else if (opcode === OPCODE_TEXT && fin) onText?.(payload.toString("utf8"));
88868
+ }
88869
+ });
88870
+ }
88871
+
88872
+ // src/server/direct-relay.ts
88873
+ function createDirectRelay(options) {
88874
+ const sockets = /* @__PURE__ */ new Map();
88875
+ let opened = 0;
88876
+ const write = (socket, message) => socket.write(textFrame(JSON.stringify(message)));
88877
+ const onText = async (socket, key2, conn, text2) => {
88878
+ let message;
88879
+ try {
88880
+ message = JSON.parse(text2);
88881
+ } catch {
88882
+ return;
88883
+ }
88884
+ if (message.t !== "request" || typeof message.rid !== "number" && typeof message.rid !== "string") return;
88885
+ options.onActivity();
88886
+ try {
88887
+ write(socket, { t: "reply", rid: message.rid, body: { ok: true, data: await options.handle(key2, message.body, conn) } });
88888
+ } catch (err) {
88889
+ write(socket, { t: "reply", rid: message.rid, body: { ok: false, error: err.message } });
88890
+ }
88891
+ };
88892
+ return {
88893
+ accept(socket, clientKey, key2) {
88894
+ completeHandshake(socket, clientKey);
88895
+ const conn = `direct:${++opened}`;
88896
+ sockets.set(socket, { key: key2, conn });
88897
+ write(socket, { t: "presence", online: true, version: options.version });
88898
+ handleClientFrames(socket, (text2) => void onText(socket, key2, conn, text2));
88899
+ const forget = () => {
88900
+ if (sockets.delete(socket)) options.onClose(conn);
88901
+ };
88902
+ socket.on("end", () => {
88903
+ forget();
88904
+ socket.end();
88905
+ });
88906
+ socket.on("close", forget);
88907
+ socket.on("error", forget);
88908
+ options.onActivity();
88909
+ },
88910
+ emit(key2, body) {
88911
+ for (const [socket, entry] of sockets) if (entry.key === key2) write(socket, { t: "event", body });
88912
+ },
88913
+ close() {
88914
+ for (const socket of sockets.keys()) socket.destroy();
88915
+ }
88916
+ };
88917
+ }
88918
+
88919
+ // src/server/host-id.ts
88920
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
88921
+ var import_node_path14 = __toESM(require("node:path"), 1);
88922
+ function hostIdFor(credentialsFile2) {
88923
+ const file = import_node_path14.default.join(import_node_path14.default.dirname(credentialsFile2), "host-id");
88924
+ const saved = readPersisted(file);
88925
+ if (/^[A-Za-z0-9_-]{16,64}$/.test(saved)) return saved;
88926
+ const id2 = randomToken();
88927
+ import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true, mode: 448 });
88928
+ import_node_fs14.default.writeFileSync(file, `${id2}
88929
+ `, { mode: 384 });
88930
+ return id2;
88931
+ }
88932
+
88785
88933
  // src/server/avatars.ts
88786
- var import_node_crypto3 = require("node:crypto");
88934
+ var import_node_crypto4 = require("node:crypto");
88787
88935
  var AVATAR_ROUTE = /^\/api\/avatar\/([a-z]+)\/([^/]+)$/;
88788
88936
  var MAX_BYTES = 512 * 1024;
88789
88937
  var TIMEOUT_MS = 5e3;
@@ -88792,7 +88940,7 @@ var SOURCES = {
88792
88940
  gravatar: { valid: /^[0-9a-f]{64}$/, url: (id2) => `https://gravatar.com/avatar/${id2}?s=64&d=404` }
88793
88941
  };
88794
88942
  var githubAvatar = (login) => `/api/avatar/github/${login}`;
88795
- var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto3.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
88943
+ var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto4.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
88796
88944
  function createAvatars(fetchImpl = fetch) {
88797
88945
  const cache = /* @__PURE__ */ new Map();
88798
88946
  const fetchAvatar = async (url) => {
@@ -88824,7 +88972,7 @@ function createAvatars(fetchImpl = fetch) {
88824
88972
  }
88825
88973
 
88826
88974
  // src/server/cloud.ts
88827
- var import_node_crypto4 = __toESM(require("node:crypto"), 1);
88975
+ var import_node_crypto5 = __toESM(require("node:crypto"), 1);
88828
88976
 
88829
88977
  // src/shared/brand.ts
88830
88978
  var RYUGI_MARK_VIEWBOX = "0 0 512 512";
@@ -88934,8 +89082,8 @@ function callbackPage(result) {
88934
89082
  }
88935
89083
 
88936
89084
  // src/server/pack.ts
88937
- var import_node_fs14 = __toESM(require("node:fs"), 1);
88938
- var import_node_path14 = __toESM(require("node:path"), 1);
89085
+ var import_node_fs15 = __toESM(require("node:fs"), 1);
89086
+ var import_node_path15 = __toESM(require("node:path"), 1);
88939
89087
  var MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
88940
89088
  function formatBytes(bytes) {
88941
89089
  if (bytes < 1024) return `${bytes} B`;
@@ -88944,22 +89092,22 @@ function formatBytes(bytes) {
88944
89092
  }
88945
89093
  var excluded = (type, relative) => type === "document" && relative === "comments.json";
88946
89094
  function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
88947
- const rootReal = import_node_fs14.default.realpathSync(dir);
89095
+ const rootReal = import_node_fs15.default.realpathSync(dir);
88948
89096
  const found = [];
88949
89097
  const visited = /* @__PURE__ */ new Set([rootReal]);
88950
89098
  let total = 0;
88951
89099
  const walk = (current) => {
88952
- for (const entry of import_node_fs14.default.readdirSync(current, { withFileTypes: true })) {
89100
+ for (const entry of import_node_fs15.default.readdirSync(current, { withFileTypes: true })) {
88953
89101
  if (entry.name.startsWith(".")) continue;
88954
- const full = import_node_path14.default.join(current, entry.name);
89102
+ const full = import_node_path15.default.join(current, entry.name);
88955
89103
  let real;
88956
89104
  try {
88957
- real = import_node_fs14.default.realpathSync(full);
89105
+ real = import_node_fs15.default.realpathSync(full);
88958
89106
  } catch {
88959
89107
  continue;
88960
89108
  }
88961
- if (!real.startsWith(rootReal + import_node_path14.default.sep)) continue;
88962
- const stat = import_node_fs14.default.statSync(real);
89109
+ if (!real.startsWith(rootReal + import_node_path15.default.sep)) continue;
89110
+ const stat = import_node_fs15.default.statSync(real);
88963
89111
  if (stat.isDirectory()) {
88964
89112
  if (visited.has(real)) continue;
88965
89113
  visited.add(real);
@@ -88967,7 +89115,7 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
88967
89115
  continue;
88968
89116
  }
88969
89117
  if (!stat.isFile()) continue;
88970
- const relative = import_node_path14.default.relative(dir, full).split(import_node_path14.default.sep).join("/");
89118
+ const relative = import_node_path15.default.relative(dir, full).split(import_node_path15.default.sep).join("/");
88971
89119
  if (excluded(type, relative)) continue;
88972
89120
  total += stat.size;
88973
89121
  found.push({ path: relative, real });
@@ -88977,12 +89125,12 @@ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
88977
89125
  if (total > maxBytes) {
88978
89126
  throw new Error(`artifact is ${formatBytes(total)}; the limit is ${formatBytes(maxBytes)}`);
88979
89127
  }
88980
- return found.map((file) => ({ path: file.path, data: import_node_fs14.default.readFileSync(file.real) }));
89128
+ return found.map((file) => ({ path: file.path, data: import_node_fs15.default.readFileSync(file.real) }));
88981
89129
  }
88982
89130
 
88983
89131
  // src/server/publish-payload.ts
88984
- var import_node_fs15 = __toESM(require("node:fs"), 1);
88985
- var import_node_path15 = __toESM(require("node:path"), 1);
89132
+ var import_node_fs16 = __toESM(require("node:fs"), 1);
89133
+ var import_node_path16 = __toESM(require("node:path"), 1);
88986
89134
  var CLOUD_RUNTIME_URL = "/_ryugi/runtime/ryugi-ui.js";
88987
89135
  function sharedComments(file) {
88988
89136
  return {
@@ -88995,7 +89143,7 @@ function publishPayload(ref, dir, title, payload, comments = emptyComments()) {
88995
89143
  const { canvas, layout, versions } = payload;
88996
89144
  return { canvas, layout, versions };
88997
89145
  }
88998
- if (ref.type === "document") return { title, state: parseDocument2(import_node_fs15.default.readFileSync(import_node_path15.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
89146
+ if (ref.type === "document") return { title, state: parseDocument2(import_node_fs16.default.readFileSync(import_node_path16.default.join(dir, "doc.xml"), "utf8")), comments: sharedComments(comments) };
88999
89147
  return { title };
89000
89148
  }
89001
89149
  var isPage = (type, file) => type === "html" ? file === "index.html" : (type === "document" || type === "artboard") && file.endsWith(".html");
@@ -89006,12 +89154,12 @@ function withCloudRuntime(type, files) {
89006
89154
  }
89007
89155
 
89008
89156
  // src/server/settings.ts
89009
- var import_node_fs16 = __toESM(require("node:fs"), 1);
89010
- var import_node_path16 = __toESM(require("node:path"), 1);
89011
- var settingsFileFor = (credentialsFile2) => import_node_path16.default.join(import_node_path16.default.dirname(credentialsFile2), "config.json");
89157
+ var import_node_fs17 = __toESM(require("node:fs"), 1);
89158
+ var import_node_path17 = __toESM(require("node:path"), 1);
89159
+ var settingsFileFor = (credentialsFile2) => import_node_path17.default.join(import_node_path17.default.dirname(credentialsFile2), "config.json");
89012
89160
  function readSettings(file) {
89013
89161
  try {
89014
- const raw = JSON.parse(import_node_fs16.default.readFileSync(file, "utf8"));
89162
+ const raw = JSON.parse(import_node_fs17.default.readFileSync(file, "utf8"));
89015
89163
  return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : {};
89016
89164
  } catch {
89017
89165
  return {};
@@ -89022,7 +89170,7 @@ function readGlobalAutoPublish(file) {
89022
89170
  return typeof value === "boolean" ? value : void 0;
89023
89171
  }
89024
89172
  function writeGlobalAutoPublish(file, value) {
89025
- import_node_fs16.default.mkdirSync(import_node_path16.default.dirname(file), { recursive: true, mode: 448 });
89173
+ import_node_fs17.default.mkdirSync(import_node_path17.default.dirname(file), { recursive: true, mode: 448 });
89026
89174
  writeJsonAtomic(file, { ...readSettings(file), autoPublish: value });
89027
89175
  }
89028
89176
  function defaultGlobalAutoPublish(file) {
@@ -89037,7 +89185,7 @@ var LOGIN_STATE_TTL_MS = 10 * 60 * 1e3;
89037
89185
  var UPLOAD_CONCURRENCY = 6;
89038
89186
  var MAX_JSON_BODY = 4096;
89039
89187
  var CLOUD_ID = /^[A-Za-z0-9_-]{1,64}$/;
89040
- var ROUTE = /^\/api\/cloud\/(status|login|logout|artifacts|publish|visibility|auto-publish)(?:\/([^/]+)(?:\/([^/]+))?)?$/;
89188
+ var ROUTE = /^\/api\/cloud\/(status|login|logout|artifacts|publish|reserve|visibility|auto-publish)(?:\/([^/]+)(?:\/([^/]+))?)?$/;
89041
89189
  var SignedOut = class extends Error {
89042
89190
  };
89043
89191
  var CloudRefused = class extends Error {
@@ -89094,10 +89242,10 @@ function createCloudRoutes(options) {
89094
89242
  const state = randomToken();
89095
89243
  const verifier = randomToken();
89096
89244
  pendingStates.set(state, { expires: now + LOGIN_STATE_TTL_MS, verifier });
89097
- const challenge = import_node_crypto4.default.createHash("sha256").update(verifier).digest("base64url");
89245
+ const challenge = import_node_crypto5.default.createHash("sha256").update(verifier).digest("base64url");
89098
89246
  return `${origin}/auth/cli?port=${options.port()}&state=${state}&challenge=${challenge}`;
89099
89247
  };
89100
- const cloudFetch = async (method, path20, body) => {
89248
+ const cloudFetch = async (method, path21, body) => {
89101
89249
  const credentials = readCredentials(credentialsFile2, origin);
89102
89250
  if (!credentials) throw new SignedOut();
89103
89251
  const headers = { Authorization: `Bearer ${credentials.token}` };
@@ -89111,7 +89259,7 @@ function createCloudRoutes(options) {
89111
89259
  }
89112
89260
  let res;
89113
89261
  try {
89114
- res = await fetch(`${origin}${path20}`, { method, headers, body: payload });
89262
+ res = await fetch(`${origin}${path21}`, { method, headers, body: payload });
89115
89263
  } catch (err) {
89116
89264
  throw new CloudRefused(502, `could not reach ${origin}: ${err.message}`);
89117
89265
  }
@@ -89134,6 +89282,28 @@ function createCloudRoutes(options) {
89134
89282
  return run2;
89135
89283
  };
89136
89284
  const keyOfCloudId = (cloudId) => Object.entries(readConfig(configFile).config.artifacts).find(([, entry]) => entry.cloud?.id === cloudId)?.[0] ?? `cloud:${cloudId}`;
89285
+ const createRecord2 = async (ref, visibility) => {
89286
+ const res = await cloudFetch("POST", "/api/artifacts", { type: ref.type, visibility, project });
89287
+ if (res.status === 403) throw new CreateRefused(await errorMessage(res));
89288
+ const created = await (await expectOk(res)).json();
89289
+ updateArtifactConfig(configFile, `${ref.type}/${ref.id}`, {
89290
+ visibility: created.visibility,
89291
+ cloud: { id: created.id, url: created.url, publishedAt: null, visibility: created.visibility }
89292
+ });
89293
+ return created.id;
89294
+ };
89295
+ const reserve = async (ref) => {
89296
+ const key2 = `${ref.type}/${ref.id}`;
89297
+ const entry = artifactEntry(key2);
89298
+ if (entry.cloud) return entry.cloud.url;
89299
+ if (entry.autoPublish === false || !autoPublishState().enabled) return null;
89300
+ try {
89301
+ await createRecord2(ref, entry.visibility ?? "private");
89302
+ } catch {
89303
+ return null;
89304
+ }
89305
+ return artifactEntry(key2).cloud?.url ?? null;
89306
+ };
89137
89307
  const publish = async (ref, requested, { recreate = true } = {}) => {
89138
89308
  const inspected = await options.inspect(ref);
89139
89309
  if (!inspected) throw new CloudRefused(404, `${ref.type}/${ref.id} not found`);
@@ -89146,20 +89316,11 @@ function createCloudRoutes(options) {
89146
89316
  }
89147
89317
  const key2 = `${ref.type}/${ref.id}`;
89148
89318
  const entry = artifactEntry(key2);
89149
- const hashed = files.map((file) => ({ ...file, hash: import_node_crypto4.default.createHash("sha256").update(file.data).digest("hex") }));
89319
+ const hashed = files.map((file) => ({ ...file, hash: import_node_crypto5.default.createHash("sha256").update(file.data).digest("hex") }));
89150
89320
  const byHash = new Map(hashed.map((file) => [file.hash, file.data]));
89151
- const manifest = hashed.map(({ path: path20, hash }) => ({ path: path20, hash }));
89321
+ const manifest = hashed.map(({ path: path21, hash }) => ({ path: path21, hash }));
89152
89322
  const version2 = (visibility) => ({ title: inspected.title, payload: inspected.payload, files: manifest, project, ...visibility ? { visibility } : {} });
89153
- const create3 = async () => {
89154
- const res2 = await cloudFetch("POST", "/api/artifacts", { type: ref.type, visibility: requested ?? entry.visibility ?? "private", project });
89155
- if (res2.status === 403) throw new CreateRefused(await errorMessage(res2));
89156
- const created = await (await expectOk(res2)).json();
89157
- updateArtifactConfig(configFile, key2, {
89158
- visibility: created.visibility,
89159
- cloud: { id: created.id, url: created.url, publishedAt: null, visibility: created.visibility }
89160
- });
89161
- return created.id;
89162
- };
89323
+ const create3 = () => createRecord2(ref, requested ?? entry.visibility ?? "private");
89163
89324
  const upload = async (id2, hashes) => {
89164
89325
  for (let i6 = 0; i6 < hashes.length; i6 += UPLOAD_CONCURRENCY) {
89165
89326
  await Promise.all(
@@ -89249,7 +89410,7 @@ function createCloudRoutes(options) {
89249
89410
  if (action === "status" && method === "GET" && !first) {
89250
89411
  const credentials = readCredentials(credentialsFile2, origin);
89251
89412
  const { config, warning } = readConfig(configFile);
89252
- sendJson(res, 200, { signedIn: !!credentials, login: credentials?.login ?? null, origin, artifacts: config.artifacts, autoPublish: autoPublishState(), warning: warning ?? null });
89413
+ sendJson(res, 200, { signedIn: !!credentials, login: credentials?.login ?? null, origin, hostId: hostIdFor(credentialsFile2), artifacts: config.artifacts, autoPublish: autoPublishState(), warning: warning ?? null });
89253
89414
  return;
89254
89415
  }
89255
89416
  if (action === "login" && method === "POST" && !first) {
@@ -89290,6 +89451,10 @@ function createCloudRoutes(options) {
89290
89451
  sendJson(res, result.status, result.body);
89291
89452
  return;
89292
89453
  }
89454
+ if (action === "reserve" && ref && method === "POST") {
89455
+ sendJson(res, 200, { url: await serialized(`${ref.type}/${ref.id}`, () => reserve(ref)) });
89456
+ return;
89457
+ }
89293
89458
  if (action === "publish" && ref && method === "DELETE") {
89294
89459
  const key2 = `${ref.type}/${ref.id}`;
89295
89460
  await serialized(key2, async () => {
@@ -89376,7 +89541,7 @@ function createCloudRoutes(options) {
89376
89541
 
89377
89542
  // src/server/comment-names.ts
89378
89543
  var import_node_child_process = require("node:child_process");
89379
- var import_node_fs17 = __toESM(require("node:fs"), 1);
89544
+ var import_node_fs18 = __toESM(require("node:fs"), 1);
89380
89545
 
89381
89546
  // src/server/agent.ts
89382
89547
  var NAMES = {
@@ -89457,7 +89622,7 @@ function commentNames({ agentFile, projectDir, cloud }) {
89457
89622
  },
89458
89623
  agent: () => {
89459
89624
  try {
89460
- return detectAgent(JSON.parse(import_node_fs17.default.readFileSync(agentFile, "utf8")));
89625
+ return detectAgent(JSON.parse(import_node_fs18.default.readFileSync(agentFile, "utf8")));
89461
89626
  } catch {
89462
89627
  return void 0;
89463
89628
  }
@@ -89485,8 +89650,8 @@ function viewerPage(template, page) {
89485
89650
  }
89486
89651
 
89487
89652
  // src/server/auto-publish.ts
89488
- var import_node_crypto5 = __toESM(require("node:crypto"), 1);
89489
- var import_node_fs18 = __toESM(require("node:fs"), 1);
89653
+ var import_node_crypto6 = __toESM(require("node:crypto"), 1);
89654
+ var import_node_fs19 = __toESM(require("node:fs"), 1);
89490
89655
  var SIGNED_OUT_MESSAGE = "auto-publish paused: the Ryugi Cloud sign-in expired";
89491
89656
  function isNotice(value) {
89492
89657
  if (typeof value !== "object" || value === null) return false;
@@ -89496,7 +89661,7 @@ function isNotice(value) {
89496
89661
  function readAutoPublishState(file) {
89497
89662
  let raw = {};
89498
89663
  try {
89499
- const parsed = JSON.parse(import_node_fs18.default.readFileSync(file, "utf8"));
89664
+ const parsed = JSON.parse(import_node_fs19.default.readFileSync(file, "utf8"));
89500
89665
  if (typeof parsed === "object" && parsed !== null) raw = parsed;
89501
89666
  } catch {
89502
89667
  }
@@ -89516,7 +89681,7 @@ function createAutoPublisher(options) {
89516
89681
  const remarked = /* @__PURE__ */ new Set();
89517
89682
  const save = () => writeJsonAtomic(options.stateFile, { dirty: [...dirty], notice, paused });
89518
89683
  const raise = (kind, message) => {
89519
- if (notice?.kind !== kind) notice = { id: import_node_crypto5.default.randomUUID(), kind, message };
89684
+ if (notice?.kind !== kind) notice = { id: import_node_crypto6.default.randomUUID(), kind, message };
89520
89685
  };
89521
89686
  const run2 = async () => {
89522
89687
  if (!options.enabled() || dirty.size === 0) return;
@@ -89575,26 +89740,45 @@ function createAutoPublisher(options) {
89575
89740
  };
89576
89741
  }
89577
89742
 
89743
+ // src/server/artifact-file.ts
89744
+ var import_node_fs20 = __toESM(require("node:fs"), 1);
89745
+ var RESOLVE = { artboard: resolveBoardFile, document: resolveDocumentAsset, html: resolveHtmlFile };
89746
+ var isArtifactPage = (type, relative) => type === "html" ? relative === "index.html" : relative.endsWith(".html");
89747
+ function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
89748
+ if (!resolveInside(dir, relative)) return null;
89749
+ const target = RESOLVE[type](dir, relative);
89750
+ if (!target) return null;
89751
+ let data;
89752
+ try {
89753
+ data = import_node_fs20.default.readFileSync(target);
89754
+ } catch {
89755
+ return null;
89756
+ }
89757
+ if (!isArtifactPage(type, relative)) return { contentType: mimeOf(target), data };
89758
+ const page = injectRuntime(data.toString("utf8"), { uiRuntimeUrl, embedded: type === "document", inspector: type === "artboard" });
89759
+ return { contentType: "text/html; charset=utf-8", data: Buffer.from(page) };
89760
+ }
89761
+
89578
89762
  // src/server/watch.ts
89579
- var import_node_fs19 = __toESM(require("node:fs"), 1);
89580
- var import_node_path17 = __toESM(require("node:path"), 1);
89581
- var toPosix = (file) => file.split(import_node_path17.default.sep).join("/");
89763
+ var import_node_fs21 = __toESM(require("node:fs"), 1);
89764
+ var import_node_path18 = __toESM(require("node:path"), 1);
89765
+ var toPosix = (file) => file.split(import_node_path18.default.sep).join("/");
89582
89766
  var ignored = (file) => file === ".state" || file.startsWith(".state/");
89583
89767
  function snapshot(root, dir = root, out = /* @__PURE__ */ new Map()) {
89584
89768
  let entries2;
89585
89769
  try {
89586
- entries2 = import_node_fs19.default.readdirSync(dir, { withFileTypes: true });
89770
+ entries2 = import_node_fs21.default.readdirSync(dir, { withFileTypes: true });
89587
89771
  } catch {
89588
89772
  return out;
89589
89773
  }
89590
89774
  for (const entry of entries2) {
89591
- const full = import_node_path17.default.join(dir, entry.name);
89592
- const rel = toPosix(import_node_path17.default.relative(root, full));
89775
+ const full = import_node_path18.default.join(dir, entry.name);
89776
+ const rel = toPosix(import_node_path18.default.relative(root, full));
89593
89777
  if (ignored(rel)) continue;
89594
89778
  if (entry.isDirectory()) snapshot(root, full, out);
89595
89779
  else {
89596
89780
  try {
89597
- out.set(rel, import_node_fs19.default.statSync(full).mtimeMs);
89781
+ out.set(rel, import_node_fs21.default.statSync(full).mtimeMs);
89598
89782
  } catch {
89599
89783
  }
89600
89784
  }
@@ -89627,7 +89811,7 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
89627
89811
  }, debounceMs);
89628
89812
  };
89629
89813
  try {
89630
- const watcher = import_node_fs19.default.watch(root, { recursive: true }, (_event, filename) => {
89814
+ const watcher = import_node_fs21.default.watch(root, { recursive: true }, (_event, filename) => {
89631
89815
  if (filename) queue([toPosix(filename.toString())]);
89632
89816
  });
89633
89817
  watcher.on("error", () => {
@@ -89651,92 +89835,6 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
89651
89835
  }
89652
89836
  }
89653
89837
 
89654
- // src/server/ws.ts
89655
- var import_node_crypto6 = __toESM(require("node:crypto"), 1);
89656
- var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
89657
- var OPCODE_TEXT = 1;
89658
- var OPCODE_CLOSE = 8;
89659
- var OPCODE_PING = 9;
89660
- var OPCODE_PONG = 10;
89661
- var MAX_CLIENT_FRAME = 8 * 1024 * 1024;
89662
- function acceptKey(clientKey) {
89663
- return import_node_crypto6.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
89664
- }
89665
- function encodeFrame(opcode, payload) {
89666
- const len = payload.length;
89667
- let header;
89668
- if (len < 126) {
89669
- header = Buffer.from([128 | opcode, len]);
89670
- } else if (len < 65536) {
89671
- header = Buffer.alloc(4);
89672
- header[0] = 128 | opcode;
89673
- header[1] = 126;
89674
- header.writeUInt16BE(len, 2);
89675
- } else {
89676
- header = Buffer.alloc(10);
89677
- header[0] = 128 | opcode;
89678
- header[1] = 127;
89679
- header.writeBigUInt64BE(BigInt(len), 2);
89680
- }
89681
- return Buffer.concat([header, payload]);
89682
- }
89683
- var textFrame = (text2) => encodeFrame(OPCODE_TEXT, Buffer.from(text2));
89684
- function completeHandshake(socket, clientKey) {
89685
- socket.write(
89686
- `HTTP/1.1 101 Switching Protocols\r
89687
- Upgrade: websocket\r
89688
- Connection: Upgrade\r
89689
- Sec-WebSocket-Accept: ${acceptKey(clientKey)}\r
89690
- \r
89691
- `
89692
- );
89693
- }
89694
- function rejectUpgrade(socket, status, reason) {
89695
- socket.end(`HTTP/1.1 ${status} ${reason}\r
89696
- Connection: close\r
89697
- Content-Length: 0\r
89698
- \r
89699
- `);
89700
- }
89701
- function handleClientFrames(socket, onText) {
89702
- let buffer = Buffer.alloc(0);
89703
- socket.on("data", (chunk) => {
89704
- buffer = Buffer.concat([buffer, chunk]);
89705
- while (buffer.length >= 2) {
89706
- const fin = (buffer[0] & 128) !== 0;
89707
- const opcode = buffer[0] & 15;
89708
- let len = buffer[1] & 127;
89709
- let offset = 2;
89710
- if (len === 126) {
89711
- if (buffer.length < 4) return;
89712
- len = buffer.readUInt16BE(2);
89713
- offset = 4;
89714
- } else if (len === 127) {
89715
- if (buffer.length < 10) return;
89716
- const big = buffer.readBigUInt64BE(2);
89717
- if (big > BigInt(MAX_CLIENT_FRAME)) {
89718
- socket.destroy();
89719
- return;
89720
- }
89721
- len = Number(big);
89722
- offset = 10;
89723
- }
89724
- const total = offset + 4 + len;
89725
- if (buffer.length < total) return;
89726
- const mask = buffer.subarray(offset, offset + 4);
89727
- const payload = Buffer.from(buffer.subarray(offset + 4, total));
89728
- for (let i6 = 0; i6 < payload.length; i6++) payload[i6] = payload[i6] ^ mask[i6 % 4];
89729
- buffer = buffer.subarray(total);
89730
- if (opcode === OPCODE_CLOSE) {
89731
- socket.end(encodeFrame(OPCODE_CLOSE, Buffer.alloc(0)));
89732
- return;
89733
- }
89734
- if (opcode === OPCODE_PING) socket.write(encodeFrame(OPCODE_PONG, payload));
89735
- else if (opcode === OPCODE_TEXT && fin) onText?.(payload.toString("utf8"));
89736
- }
89737
- });
89738
- }
89739
-
89740
89838
  // src/server/app.ts
89741
89839
  var VIEWER_CSP = [
89742
89840
  "default-src 'self'",
@@ -89755,6 +89853,7 @@ var CONTENT_CSP = {
89755
89853
  document: "sandbox; default-src 'none'",
89756
89854
  html: "sandbox allow-scripts allow-modals allow-forms allow-popups allow-downloads"
89757
89855
  };
89856
+ var DIRECT_RELAY_ROUTE = /^\/relay\/a\/([A-Za-z0-9_-]{1,64})$/;
89758
89857
  var SHELL_ROUTE = new RegExp(`^/(?:(${ARTIFACT_TYPES.join("|")})/([^/]+)/?)?$`);
89759
89858
  var API_ARTIFACT_ROUTE = /^\/api\/artifacts\/([^/]+)\/([^/]+)$/;
89760
89859
  var PREVIEW_ROUTE = /^\/preview\/(artboard|document|html)\/([a-z0-9][a-z0-9-]*)\/?$/;
@@ -89763,6 +89862,7 @@ var API_DOCUMENT_ROUTE = /^\/api\/document\/([^/]+)\/(state|update|comments)$/;
89763
89862
  var MAX_COMMENT_OP = 64 * 1024;
89764
89863
  var API_AGENT_COMMENTS_ROUTE = /^\/api\/agent\/document\/([^/]+)\/comments$/;
89765
89864
  var MAX_DOCUMENT_UPDATE = 8 * 1024 * 1024;
89865
+ var MAX_RELAY_FILE = 8 * 1024 * 1024;
89766
89866
  var MAX_RUNTIME_MESSAGE = 2048;
89767
89867
  var MAX_RUNTIME_WARNINGS = 20;
89768
89868
  function readArtifact(dir, ref, runtime = []) {
@@ -89779,17 +89879,17 @@ function titleOf(payload, ref) {
89779
89879
  return payload.canvas?.title || ref.id;
89780
89880
  }
89781
89881
  async function startArtifactsServer(options) {
89782
- const root = import_node_path18.default.resolve(options.root);
89783
- const viewerDir = import_node_path18.default.resolve(options.viewerDir);
89784
- const runtimeDir = options.runtimeDir ? import_node_path18.default.resolve(options.runtimeDir) : null;
89785
- const stateDir = import_node_path18.default.join(root, ".state");
89786
- import_node_fs20.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
89787
- import_node_fs20.default.writeFileSync(import_node_path18.default.join(stateDir, ".gitignore"), "*\n");
89882
+ const root = import_node_path19.default.resolve(options.root);
89883
+ const viewerDir = import_node_path19.default.resolve(options.viewerDir);
89884
+ const runtimeDir = options.runtimeDir ? import_node_path19.default.resolve(options.runtimeDir) : null;
89885
+ const stateDir = import_node_path19.default.join(root, ".state");
89886
+ import_node_fs22.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
89887
+ import_node_fs22.default.writeFileSync(import_node_path19.default.join(stateDir, ".gitignore"), "*\n");
89788
89888
  if (options.configFile) ensureConfig(options.configFile);
89789
- const portFile = import_node_path18.default.join(stateDir, ".last-port");
89790
- const tokenFile = import_node_path18.default.join(stateDir, ".last-token");
89889
+ const portFile = import_node_path19.default.join(stateDir, ".last-port");
89890
+ const tokenFile = import_node_path19.default.join(stateDir, ".last-token");
89791
89891
  const token = readPersisted(tokenFile) || randomToken();
89792
- import_node_fs20.default.writeFileSync(tokenFile, `${token}
89892
+ import_node_fs22.default.writeFileSync(tokenFile, `${token}
89793
89893
  `, { mode: 384 });
89794
89894
  const contentToken = randomToken();
89795
89895
  const runtimeWarnings = /* @__PURE__ */ new Map();
@@ -89806,13 +89906,20 @@ async function startArtifactsServer(options) {
89806
89906
  let port = 0;
89807
89907
  let cookieName = "";
89808
89908
  let relay = null;
89909
+ const direct = createDirectRelay({
89910
+ version: options.relay?.version ?? "",
89911
+ handle: (key2, body, conn) => handleRelay(key2, body, conn, `http://127.0.0.1:${port}`),
89912
+ onActivity: () => touch(),
89913
+ onClose: (conn) => dropRelayViewer(conn)
89914
+ });
89809
89915
  const broadcast = (message) => {
89810
89916
  const frame = textFrame(JSON.stringify(message));
89811
89917
  for (const socket of clients) socket.write(frame);
89812
89918
  relay?.emit(message.artifact, message);
89919
+ direct.emit(message.artifact, message);
89813
89920
  };
89814
89921
  const avatars = createAvatars(options.fetch);
89815
- const names = commentNames({ agentFile: import_node_path18.default.join(stateDir, "agent"), projectDir: import_node_path18.default.resolve(root, "../.."), cloud: options.cloud });
89922
+ const names = commentNames({ agentFile: import_node_path19.default.join(stateDir, "agent"), projectDir: import_node_path19.default.resolve(root, "../.."), cloud: options.cloud });
89816
89923
  const documents = createDocumentRegistry({
89817
89924
  root,
89818
89925
  stateDir,
@@ -89850,8 +89957,8 @@ async function startArtifactsServer(options) {
89850
89957
  }
89851
89958
  return { dir, title, reasons, payload: published };
89852
89959
  };
89853
- const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path18.default.basename(import_node_path18.default.resolve(root, "../..")), port: () => port, inspect }) : null;
89854
- const autoPublisher = cloud ? createAutoPublisher({ stateFile: import_node_path18.default.join(stateDir, "auto-publish.json"), enabled: cloud.autoPublishEnabled, token: cloud.token, publish: cloud.autoPublish }) : null;
89960
+ const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, project: import_node_path19.default.basename(import_node_path19.default.resolve(root, "../..")), port: () => port, inspect }) : null;
89961
+ const autoPublisher = cloud ? createAutoPublisher({ stateFile: import_node_path19.default.join(stateDir, "auto-publish.json"), enabled: cloud.autoPublishEnabled, token: cloud.token, publish: cloud.autoPublish }) : null;
89855
89962
  const sameOrigin = (req) => {
89856
89963
  const origin2 = req.headers.origin;
89857
89964
  const host = req.headers.host ?? "";
@@ -89930,7 +90037,7 @@ async function startArtifactsServer(options) {
89930
90037
  };
89931
90038
  const blockIdsOf = async (id2, dir) => {
89932
90039
  await (await documents.open(id2))?.flush();
89933
- const state = parseDocument2(import_node_fs20.default.readFileSync(import_node_path18.default.join(dir, "doc.xml"), "utf8"));
90040
+ const state = parseDocument2(import_node_fs22.default.readFileSync(import_node_path19.default.join(dir, "doc.xml"), "utf8"));
89934
90041
  return new Set(state.root.children.flatMap((block) => block.$?.blockId ? [block.$.blockId] : []));
89935
90042
  };
89936
90043
  const serveAgentComments = async (req, res, id2) => {
@@ -90010,7 +90117,7 @@ async function startArtifactsServer(options) {
90010
90117
  sendFile(res, target, headers);
90011
90118
  return;
90012
90119
  }
90013
- import_node_fs20.default.readFile(target, "utf8", (err, source) => {
90120
+ import_node_fs22.default.readFile(target, "utf8", (err, source) => {
90014
90121
  if (err) send(res, 404, "Not found");
90015
90122
  else {
90016
90123
  const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
@@ -90018,10 +90125,10 @@ async function startArtifactsServer(options) {
90018
90125
  }
90019
90126
  });
90020
90127
  };
90021
- const artifactMeta = (ref, dir) => ({
90128
+ const artifactMeta = (ref, dir, contentOrigin = "") => ({
90022
90129
  ...readArtifact(dir, ref, runtimeOf(ref, dir)),
90023
90130
  ...ref.type !== "html" ? { agent: names.agent() } : {},
90024
- contentBase: `${contentPrefix}${ref.type}/${ref.id}/`
90131
+ contentBase: `${contentOrigin}${contentPrefix}${ref.type}/${ref.id}/`
90025
90132
  });
90026
90133
  const serveArtifactApi = (res, type, id2) => {
90027
90134
  const dir = resolveArtifactDir(root, type, id2);
@@ -90039,7 +90146,7 @@ async function startArtifactsServer(options) {
90039
90146
  title: titleOf(readArtifact(entry.dir, entry), entry),
90040
90147
  updatedAt: latestMtime(entry.dir)
90041
90148
  }));
90042
- sendJson(res, 200, { project: import_node_path18.default.basename(import_node_path18.default.dirname(import_node_path18.default.dirname(root))), artifacts: summaries, warnings });
90149
+ sendJson(res, 200, { project: import_node_path19.default.basename(import_node_path19.default.dirname(import_node_path19.default.dirname(root))), artifacts: summaries, warnings });
90043
90150
  };
90044
90151
  function onClientText(socket, text2) {
90045
90152
  let message;
@@ -90053,7 +90160,9 @@ async function startArtifactsServer(options) {
90053
90160
  selections.accept(socket, message);
90054
90161
  return;
90055
90162
  }
90056
- const { type, artifact, message: detail, version: version2, file } = message;
90163
+ acceptReport(message);
90164
+ }
90165
+ function acceptReport({ type, artifact, message: detail, version: version2, file }) {
90057
90166
  if (typeof artifact !== "string") return;
90058
90167
  const ref = artifactKeyOf(artifact);
90059
90168
  if (!ref || ref.type === "artboard" || artifact !== `${ref.type}/${ref.id}`) return;
@@ -90085,7 +90194,7 @@ async function startArtifactsServer(options) {
90085
90194
  runtimeWarnings.set(artifact, [...list2, detail]);
90086
90195
  writeState(ref, dir);
90087
90196
  const frame = textFrame(JSON.stringify({ type: "change", artifact, files: [] }));
90088
- for (const socket2 of clients) socket2.write(frame);
90197
+ for (const socket of clients) socket.write(frame);
90089
90198
  }
90090
90199
  const handleRequest = (req, res) => {
90091
90200
  touch();
@@ -90099,7 +90208,7 @@ async function startArtifactsServer(options) {
90099
90208
  return;
90100
90209
  }
90101
90210
  if (pathname === "/robots.txt") {
90102
- sendFile(res, import_node_path18.default.join(viewerDir, "robots.txt"));
90211
+ sendFile(res, import_node_path19.default.join(viewerDir, "robots.txt"));
90103
90212
  return;
90104
90213
  }
90105
90214
  if (pathname.startsWith("/c/")) {
@@ -90196,7 +90305,7 @@ async function startArtifactsServer(options) {
90196
90305
  if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
90197
90306
  const ref = artifactKeyOf(pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""));
90198
90307
  const dir = ref && resolveArtifactDir(root, ref.type, ref.id);
90199
- const project = import_node_path18.default.basename(import_node_path18.default.dirname(import_node_path18.default.dirname(root)));
90308
+ const project = import_node_path19.default.basename(import_node_path19.default.dirname(import_node_path19.default.dirname(root)));
90200
90309
  const title = ref ? dir ? titleOf(readArtifact(dir, ref), ref) : ref.id : `${project} \xB7 Artifacts`;
90201
90310
  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`;
90202
90311
  const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}/${ref ? `${ref.type}/${ref.id}` : ""}`;
@@ -90205,7 +90314,7 @@ async function startArtifactsServer(options) {
90205
90314
  "Content-Security-Policy": PREVIEW_ROUTE.test(pathname) ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP
90206
90315
  };
90207
90316
  if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
90208
- void import_node_fs20.default.promises.readFile(import_node_path18.default.join(viewerDir, "index.html"), "utf8").then((template) => send(res, 200, viewerPage(template, { title, description, url: canonical }), headers)).catch((err) => send(res, err.code === "ENOENT" ? 404 : 500, "Viewer unavailable"));
90317
+ void import_node_fs22.default.promises.readFile(import_node_path19.default.join(viewerDir, "index.html"), "utf8").then((template) => send(res, 200, viewerPage(template, { title, description, url: canonical }), headers)).catch((err) => send(res, err.code === "ENOENT" ? 404 : 500, "Viewer unavailable"));
90209
90318
  return;
90210
90319
  }
90211
90320
  const target = resolveInside(viewerDir, pathname.slice(1));
@@ -90222,6 +90331,18 @@ async function startArtifactsServer(options) {
90222
90331
  server.on("upgrade", (req, socket) => {
90223
90332
  const url2 = new URL(req.url ?? "/", "http://artifacts.local");
90224
90333
  const clientKey = req.headers["sec-websocket-key"];
90334
+ const directMatch = DIRECT_RELAY_ROUTE.exec(url2.pathname);
90335
+ if (directMatch && typeof clientKey === "string") {
90336
+ const fromCloud = options.cloud !== void 0 && req.headers.origin === options.cloud.origin;
90337
+ if (!safeEqual(url2.searchParams.get("key") ?? "", token) || !(fromCloud || sameOrigin(req))) {
90338
+ rejectUpgrade(socket, 403, "Forbidden");
90339
+ return;
90340
+ }
90341
+ const key2 = servedArtifacts().get(directMatch[1]);
90342
+ if (!key2) rejectUpgrade(socket, 404, "Not Found");
90343
+ else direct.accept(socket, clientKey, key2);
90344
+ return;
90345
+ }
90225
90346
  if (url2.pathname !== "/ws" || typeof clientKey !== "string") {
90226
90347
  rejectUpgrade(socket, 400, "Bad Request");
90227
90348
  return;
@@ -90252,7 +90373,7 @@ async function startArtifactsServer(options) {
90252
90373
  port = await listen(server, options.host, 0);
90253
90374
  }
90254
90375
  cookieName = `ryugi_artifacts_${port}`;
90255
- import_node_fs20.default.writeFileSync(portFile, `${port}
90376
+ import_node_fs22.default.writeFileSync(portFile, `${port}
90256
90377
  `, { mode: 384 });
90257
90378
  const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
90258
90379
  const url = `${origin}/?key=${token}`;
@@ -90278,23 +90399,40 @@ async function startArtifactsServer(options) {
90278
90399
  initialChanges.push({ ref: entry, payload, files: [] });
90279
90400
  if (entry.type === "document") void documents.open(entry.id);
90280
90401
  }
90281
- writeJsonAtomic(import_node_path18.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
90402
+ writeJsonAtomic(import_node_path19.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
90282
90403
  const relayViewers = /* @__PURE__ */ new Map();
90283
- const servedDocuments = () => {
90404
+ const servedArtifacts = () => {
90284
90405
  const served = /* @__PURE__ */ new Map();
90285
90406
  if (!options.configFile) return served;
90286
90407
  for (const [key2, entry] of Object.entries(readConfig(options.configFile).config.artifacts)) {
90287
90408
  const ref = artifactKeyOf(key2);
90288
- if (entry.cloud && ref?.type === "document" && resolveArtifactDir(root, "document", ref.id)) served.set(entry.cloud.id, key2);
90409
+ if (entry.cloud && ref && resolveArtifactDir(root, ref.type, ref.id)) served.set(entry.cloud.id, key2);
90289
90410
  }
90290
90411
  return served;
90291
90412
  };
90292
- const handleRelay = async (key2, body, conn) => {
90413
+ const dropRelayViewer = (conn) => {
90414
+ const viewer = relayViewers.get(conn);
90415
+ if (!viewer) return;
90416
+ selections.drop(viewer.tab);
90417
+ relayViewers.delete(conn);
90418
+ };
90419
+ const handleRelay = async (key2, body, conn, contentOrigin = "") => {
90293
90420
  const ref = artifactKeyOf(key2);
90294
90421
  const dir = resolveArtifactDir(root, ref.type, ref.id);
90295
90422
  if (!dir) throw new Error(`${key2} not found`);
90296
90423
  const request = typeof body === "object" && body !== null ? body : {};
90297
- if (request.op === "meta") return artifactMeta(ref, dir);
90424
+ if (request.op === "meta") return artifactMeta(ref, dir, contentOrigin);
90425
+ if (request.op === "file") {
90426
+ const file = typeof request.path === "string" ? readArtifactFile(dir, ref.type, request.path, CLOUD_RUNTIME_URL) : null;
90427
+ if (!file) throw new Error("not found");
90428
+ if (file.data.length > MAX_RELAY_FILE) throw new Error("too large");
90429
+ return { contentType: file.contentType, data: file.data.toString("base64") };
90430
+ }
90431
+ if (request.op === "client") {
90432
+ if (typeof request.message === "object" && request.message !== null) acceptReport({ ...request.message, artifact: key2 });
90433
+ return null;
90434
+ }
90435
+ if ((request.op === "state" || request.op === "update" || request.op === "comment") && ref.type !== "document") throw new Error(`${key2} is not a document`);
90298
90436
  if (request.op === "state" || request.op === "update") {
90299
90437
  const session = await documents.open(ref.id);
90300
90438
  if (!session) throw new Error(`${key2} has no doc.xml`);
@@ -90322,12 +90460,13 @@ async function startArtifactsServer(options) {
90322
90460
  relay = options.relay && options.cloud ? createRelayClient({
90323
90461
  ...options.relay,
90324
90462
  token: () => readCredentials(options.cloud.credentialsFile, options.cloud.origin)?.token ?? null,
90325
- served: servedDocuments,
90463
+ served: servedArtifacts,
90464
+ local: () => ({ hostId: hostIdFor(options.cloud.credentialsFile), port, key: token }),
90326
90465
  handle: handleRelay,
90327
90466
  onActivity: touch,
90328
90467
  onWatch: (keys2) => {
90329
90468
  for (const [conn, viewer] of relayViewers) {
90330
- if (keys2.has(viewer.key)) continue;
90469
+ if (keys2.has(viewer.key) || conn.startsWith("direct:")) continue;
90331
90470
  selections.drop(viewer.tab);
90332
90471
  relayViewers.delete(conn);
90333
90472
  }
@@ -90364,6 +90503,7 @@ async function startArtifactsServer(options) {
90364
90503
  const frame = textFrame(JSON.stringify({ type: "change", artifact: key2, files: changed }));
90365
90504
  for (const socket of clients) socket.write(frame);
90366
90505
  relay?.emit(key2, { type: "change", artifact: key2, files: changed });
90506
+ direct.emit(key2, { type: "change", artifact: key2, files: changed });
90367
90507
  changeListeners.forEach((listener) => listener(ref, payload, changed));
90368
90508
  }
90369
90509
  touch();
@@ -90376,6 +90516,11 @@ async function startArtifactsServer(options) {
90376
90516
  contentToken,
90377
90517
  url,
90378
90518
  linkFor,
90519
+ cloudLinkFor: (type, id2) => {
90520
+ if (!options.cloud || !options.configFile || !readCredentials(options.cloud.credentialsFile, options.cloud.origin)) return null;
90521
+ const url2 = readConfig(options.configFile).config.artifacts[`${type}/${id2}`]?.cloud?.url;
90522
+ return url2 ? ownLink(url2, hostIdFor(options.cloud.credentialsFile)) : null;
90523
+ },
90379
90524
  clientCount: () => clients.size,
90380
90525
  onArtifactChange: (listener) => {
90381
90526
  changeListeners.push(listener);
@@ -90385,6 +90530,7 @@ async function startArtifactsServer(options) {
90385
90530
  close: () => new Promise((resolve) => {
90386
90531
  watcher.close();
90387
90532
  relay?.close();
90533
+ direct.close();
90388
90534
  selections.clearAll();
90389
90535
  for (const socket of clients) socket.destroy();
90390
90536
  server.close(() => resolve());
@@ -90394,7 +90540,7 @@ async function startArtifactsServer(options) {
90394
90540
  }
90395
90541
 
90396
90542
  // src/server/lifecycle.ts
90397
- var import_node_fs21 = __toESM(require("node:fs"), 1);
90543
+ var import_node_fs23 = __toESM(require("node:fs"), 1);
90398
90544
  var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
90399
90545
  var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
90400
90546
  var SERVER_ID_ARG = "--artifacts-server-id=";
@@ -90426,7 +90572,7 @@ function parseEnv(env, argv = []) {
90426
90572
  function readOwners(file) {
90427
90573
  let text2;
90428
90574
  try {
90429
- text2 = import_node_fs21.default.readFileSync(file, "utf8");
90575
+ text2 = import_node_fs23.default.readFileSync(file, "utf8");
90430
90576
  } catch {
90431
90577
  return [];
90432
90578
  }
@@ -90489,20 +90635,20 @@ function openReady(payload) {
90489
90635
  }
90490
90636
 
90491
90637
  // package.json
90492
- var version = "1.13.1";
90638
+ var version = "1.15.0";
90493
90639
 
90494
90640
  // src/server/main.ts
90495
90641
  async function main() {
90496
90642
  const config = parseEnv(process.env, process.argv.slice(2));
90497
- const root = import_node_path19.default.resolve(config.root);
90498
- const stateDir = import_node_path19.default.join(root, ".state");
90643
+ const root = import_node_path20.default.resolve(config.root);
90644
+ const stateDir = import_node_path20.default.join(root, ".state");
90499
90645
  const server = await startArtifactsServer({
90500
90646
  root,
90501
- viewerDir: import_node_path19.default.join(__dirname, "viewer"),
90502
- runtimeDir: import_node_path19.default.join(__dirname, "runtime"),
90647
+ viewerDir: import_node_path20.default.join(__dirname, "viewer"),
90648
+ runtimeDir: import_node_path20.default.join(__dirname, "runtime"),
90503
90649
  host: config.host,
90504
90650
  urlHost: config.urlHost,
90505
- configFile: import_node_path19.default.join(import_node_path19.default.dirname(root), "config.json"),
90651
+ configFile: import_node_path20.default.join(import_node_path20.default.dirname(root), "config.json"),
90506
90652
  cloud: { origin: config.cloudOrigin, credentialsFile: credentialsFile(process.env, process.platform, import_node_os.default.homedir()) },
90507
90653
  relay: { url: `${config.cloudOrigin.replace(/^http/, "ws")}/api/relay/host`, version }
90508
90654
  });
@@ -90517,7 +90663,7 @@ async function main() {
90517
90663
  if ("canvas" in payload ? !openReady(payload) : payload.warnings.length > 0) return;
90518
90664
  browserOpened = true;
90519
90665
  if (server.clientCount() > 0) return;
90520
- const link = server.linkFor(ref.type, ref.id);
90666
+ const link = server.cloudLinkFor(ref.type, ref.id) ?? server.linkFor(ref.type, ref.id);
90521
90667
  if (config.openCmd) {
90522
90668
  (0, import_node_child_process2.exec)(`${config.openCmd} ${JSON.stringify(link)}`, () => {
90523
90669
  });
@@ -90532,12 +90678,12 @@ async function main() {
90532
90678
  if (stopping) return;
90533
90679
  stopping = true;
90534
90680
  console.log(JSON.stringify({ type: "server-stopped", reason }));
90535
- import_node_fs22.default.rmSync(import_node_path19.default.join(stateDir, "server-info"), { force: true });
90536
- writeJsonAtomic(import_node_path19.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
90681
+ import_node_fs24.default.rmSync(import_node_path20.default.join(stateDir, "server-info"), { force: true });
90682
+ writeJsonAtomic(import_node_path20.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
90537
90683
  await server.close();
90538
90684
  process.exit(0);
90539
90685
  };
90540
- const ownersFile = import_node_path19.default.join(stateDir, "owners");
90686
+ const ownersFile = import_node_path20.default.join(stateDir, "owners");
90541
90687
  const timer = setInterval(() => {
90542
90688
  const owners = readOwners(ownersFile);
90543
90689
  const reason = shutdownReason({
@@ -90551,7 +90697,7 @@ async function main() {
90551
90697
  timer.unref();
90552
90698
  process.on("SIGTERM", () => void shutdown("SIGTERM"));
90553
90699
  process.on("SIGINT", () => void shutdown("SIGINT"));
90554
- import_node_fs22.default.rmSync(import_node_path19.default.join(stateDir, "server-stopped"), { force: true });
90700
+ import_node_fs24.default.rmSync(import_node_path20.default.join(stateDir, "server-stopped"), { force: true });
90555
90701
  console.log(JSON.stringify({ type: "server-started", url: server.url, port: server.port, root }));
90556
90702
  }
90557
90703
  main().catch((err) => {