ryugi-artifacts 1.5.2 → 1.6.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 (202) hide show
  1. package/dist/server.cjs +1078 -77
  2. package/dist/viewer/CloudDocument-Cmt0f5LX.js +1 -0
  3. package/dist/viewer/{DocumentPage-DdNmWoh_.js → DocumentEditor-RfVa-8pR.js} +169 -169
  4. package/dist/viewer/DocumentPage-Cg4Y7n8Z.js +1 -0
  5. package/dist/viewer/{abnfDiagram-VCTEODGH-DUjnpkq-.js → abnfDiagram-VCTEODGH-Ch1PrcW_.js} +1 -1
  6. package/dist/viewer/{ar-SA-G6X2FPQ2-mI8eD7-e.js → ar-SA-G6X2FPQ2-BZLJnXPp.js} +1 -1
  7. package/dist/viewer/{architecture-7GRP2DOG-BklKKRgi.js → architecture-7GRP2DOG-BTLY6ygE.js} +1 -1
  8. package/dist/viewer/{architectureDiagram-5GKGNRK7-ComXlUxJ.js → architectureDiagram-5GKGNRK7-Crf3vLUm.js} +1 -1
  9. package/dist/viewer/{az-AZ-76LH7QW2-CfrUcbev.js → az-AZ-76LH7QW2-CJCCtBBF.js} +1 -1
  10. package/dist/viewer/{bg-BG-XCXSNQG7-Dg5RyqcI.js → bg-BG-XCXSNQG7-A9uZROfi.js} +1 -1
  11. package/dist/viewer/{blockDiagram-I7D4REHJ-B4Mufofe.js → blockDiagram-I7D4REHJ-kmyfDg5y.js} +1 -1
  12. package/dist/viewer/{bn-BD-2XOGV67Q-D13ElBZK.js → bn-BD-2XOGV67Q-CMY785z7.js} +1 -1
  13. package/dist/viewer/{c4Diagram-7LVT6UL2-DNVvBVlj.js → c4Diagram-7LVT6UL2-DtRUOCrL.js} +1 -1
  14. package/dist/viewer/{ca-ES-6MX7JW3Y-BAw29ydH.js → ca-ES-6MX7JW3Y-BYYBxQ2h.js} +1 -1
  15. package/dist/viewer/channel-C7FdHgA5.js +1 -0
  16. package/dist/viewer/{chunk-4HAMMTFA-B6UXPokb.js → chunk-4HAMMTFA-D7lBPl2E.js} +1 -1
  17. package/dist/viewer/{chunk-75Z2AOVW-xTyaS-ou.js → chunk-75Z2AOVW-Dmt3SQH3.js} +1 -1
  18. package/dist/viewer/{chunk-DU6HZSFF-BnNI-hjm.js → chunk-DU6HZSFF-C0GRIO4w.js} +1 -1
  19. package/dist/viewer/{chunk-EIO257PC-Dsdwxebf.js → chunk-EIO257PC-BvW_EZuD.js} +1 -1
  20. package/dist/viewer/{chunk-F27PBJKO-PNrLZNah.js → chunk-F27PBJKO-cC_G0fXX.js} +1 -1
  21. package/dist/viewer/{chunk-GMAD6QVW-BWIKiLlp.js → chunk-GMAD6QVW-B0KZ3k-s.js} +1 -1
  22. package/dist/viewer/{chunk-GVQU2GXP-hJKBOJPC.js → chunk-GVQU2GXP-vAqsTjwW.js} +1 -1
  23. package/dist/viewer/{chunk-IMKFNOWR-C3ncrHH1.js → chunk-IMKFNOWR-CVmDn72x.js} +1 -1
  24. package/dist/viewer/{chunk-L3NEJ4N5-B5l5Mej0.js → chunk-L3NEJ4N5-DhAe4WGx.js} +1 -1
  25. package/dist/viewer/chunk-OSK3NFVY-CD-0X77m.js +10 -0
  26. package/dist/viewer/{chunk-P2QGCYS3-BM06KU7a.js → chunk-P2QGCYS3-BVqK-Rk9.js} +1 -1
  27. package/dist/viewer/{chunk-POPQ4Y6H-ap38DGDn.js → chunk-POPQ4Y6H-4s63FXj5.js} +1 -1
  28. package/dist/viewer/chunk-PWAF6VOD-Cku_5L2L.js +1 -0
  29. package/dist/viewer/{chunk-SHT3W25Y-B0cF1jqj.js → chunk-SHT3W25Y-DhRf-pGm.js} +1 -1
  30. package/dist/viewer/{chunk-SVP7TREG-DqK5Zrva.js → chunk-SVP7TREG-DmQ8yYT7.js} +1 -1
  31. package/dist/viewer/{chunk-TICWLB2K-CfU63rGI.js → chunk-TICWLB2K-ptqkK9g5.js} +1 -1
  32. package/dist/viewer/classDiagram-ZZMXUADV-D5iY4ZXd.js +1 -0
  33. package/dist/viewer/classDiagram-v2-VYDZK3BY-D5iY4ZXd.js +1 -0
  34. package/dist/viewer/{cs-CZ-2BRQDIVT-aRT5y-UA.js → cs-CZ-2BRQDIVT-Dzf23tSv.js} +1 -1
  35. package/dist/viewer/{cynefin-OW5HDTMX-DkcNTZzB.js → cynefin-OW5HDTMX-Bn02xX14.js} +1 -1
  36. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-DL79KeHN.js → cynefinDiagram-5FMLGOSQ-CPkt5HTK.js} +1 -1
  37. package/dist/viewer/{da-DK-5WZEPLOC-UCzc43UR.js → da-DK-5WZEPLOC-kk5u8oeh.js} +1 -1
  38. package/dist/viewer/{dagre-GXQ25YYZ-1IhuF6dR.js → dagre-GXQ25YYZ-Bhb-6j9p.js} +1 -1
  39. package/dist/viewer/{de-DE-XR44H4JA-ChbdOPiO.js → de-DE-XR44H4JA-SMlX6klW.js} +1 -1
  40. package/dist/viewer/{diagram-S7CK7UJ4-DpWKuIWt.js → diagram-S7CK7UJ4-CvFeOngn.js} +1 -1
  41. package/dist/viewer/{diagram-UQ7AKVKN-Fd5dc17c.js → diagram-UQ7AKVKN-YhpPzvtc.js} +1 -1
  42. package/dist/viewer/{diagram-VSXAHHWV-CQKqNVdK.js → diagram-VSXAHHWV-HxtxJg2X.js} +1 -1
  43. package/dist/viewer/diagram-VX7I27RA-CHXupSCr.js +24 -0
  44. package/dist/viewer/{diagram-Z3DM3KII-W7k7bYij.js → diagram-Z3DM3KII-Q_9dAatE.js} +1 -1
  45. package/dist/viewer/dist-B5smEokn.js +1 -0
  46. package/dist/viewer/dist-B9MlS-yc.js +1 -0
  47. package/dist/viewer/{dist-D3QQcwrD.js → dist-B9dFSb2w.js} +4 -4
  48. package/dist/viewer/dist-B9l6xPFH.js +1 -0
  49. package/dist/viewer/dist-BUQddJyY.js +1 -0
  50. package/dist/viewer/dist-BYFhByvm.js +1 -0
  51. package/dist/viewer/dist-BiSGJruV.js +1 -0
  52. package/dist/viewer/dist-BuhqQu7t.js +9 -0
  53. package/dist/viewer/dist-CQLwSz5A.js +1 -0
  54. package/dist/viewer/dist-Caiv-ahd.js +2 -0
  55. package/dist/viewer/dist-CpeuWhgo.js +1 -0
  56. package/dist/viewer/dist-Cyyn2QnM.js +1 -0
  57. package/dist/viewer/dist-D54iKVBK.js +1 -0
  58. package/dist/viewer/dist-DCGRsZVI.js +1 -0
  59. package/dist/viewer/dist-DPsEN2aY.js +1 -0
  60. package/dist/viewer/dist-DUsSVxcw.js +1 -0
  61. package/dist/viewer/dist-DuN7MgQk.js +1 -0
  62. package/dist/viewer/dist-HBBjtVCs.js +23 -0
  63. package/dist/viewer/dist-HEpf722E.js +1 -0
  64. package/dist/viewer/dist-KarY-eub.js +1 -0
  65. package/dist/viewer/dist-f0EzsI-T.js +11 -0
  66. package/dist/viewer/dist-nBKLr6IT.js +1 -0
  67. package/dist/viewer/dist-paIVcwaQ.js +6 -0
  68. package/dist/viewer/dist-rV_cA3xa.js +1 -0
  69. package/dist/viewer/{ebnfDiagram-PWID7BFC-Be1xMnXN.js → ebnfDiagram-PWID7BFC-Hv9B-3hk.js} +1 -1
  70. package/dist/viewer/{el-GR-BZB4AONW-D7ypohOV.js → el-GR-BZB4AONW-DaH9owXi.js} +1 -1
  71. package/dist/viewer/{en-B4ZKOASM-BwQHpV0g.js → en-B4ZKOASM-YnGAFBsU.js} +1 -1
  72. package/dist/viewer/{erDiagram-RLTQ6QDP-bsW0qw8n.js → erDiagram-RLTQ6QDP-BTUs0BT2.js} +1 -1
  73. package/dist/viewer/{es-ES-U4NZUMDT-DfRye-0D.js → es-ES-U4NZUMDT-BuoQIO3M.js} +1 -1
  74. package/dist/viewer/{eu-ES-A7QVB2H4-BWCZjoDI.js → eu-ES-A7QVB2H4-DUhHVlZe.js} +1 -1
  75. package/dist/viewer/{eventmodeling-NTZA5JFV-BxSIs5tc.js → eventmodeling-NTZA5JFV-BCi8CKiX.js} +1 -1
  76. package/dist/viewer/{fa-IR-HGAKTJCU-CyRIVaan.js → fa-IR-HGAKTJCU-CjJKc0am.js} +1 -1
  77. package/dist/viewer/{fi-FI-Z5N7JZ37-BTOW9Wm8.js → fi-FI-Z5N7JZ37-CMFLRD0_.js} +1 -1
  78. package/dist/viewer/flowDiagram-HODETNUW-CNs3HB63.js +1 -0
  79. package/dist/viewer/{fr-FR-RHASNOE6-Cm51rPOH.js → fr-FR-RHASNOE6-BHoSntIq.js} +1 -1
  80. package/dist/viewer/ganttDiagram-EL5Y4UJY-CeEQLTco.js +292 -0
  81. package/dist/viewer/{gitGraph-4MIJSDKK-z7Gw08nk.js → gitGraph-4MIJSDKK-DfE6dNnv.js} +1 -1
  82. package/dist/viewer/{gitGraphDiagram-WWUBYQGX-WHGfcYN_.js → gitGraphDiagram-WWUBYQGX-CZxp-Wm4.js} +1 -1
  83. package/dist/viewer/{gl-ES-HMX3MZ6V-D5UecBmh.js → gl-ES-HMX3MZ6V-DICoY99I.js} +1 -1
  84. package/dist/viewer/{he-IL-6SHJWFNN-Oz-jJZDy.js → he-IL-6SHJWFNN-CEe7bLWa.js} +1 -1
  85. package/dist/viewer/{hi-IN-IWLTKZ5I-N5zzENnU.js → hi-IN-IWLTKZ5I-Dh_vRgBn.js} +1 -1
  86. package/dist/viewer/{hu-HU-A5ZG7DT2-DAwuPvi7.js → hu-HU-A5ZG7DT2-Bidop9I6.js} +1 -1
  87. package/dist/viewer/{id-ID-SAP4L64H-D_GNMEv3.js → id-ID-SAP4L64H-D183pYjJ.js} +1 -1
  88. package/dist/viewer/{image-GAAHSSAO-Ar9sm1AS.js → image-GAAHSSAO-DGMqto4h.js} +1 -1
  89. package/dist/viewer/index.css +1 -1062
  90. package/dist/viewer/index.html +1 -1
  91. package/dist/viewer/index.js +13 -12
  92. package/dist/viewer/index2.css +1082 -0
  93. package/dist/viewer/{info-A6RAGUB7-Cf5to2ar.js → info-A6RAGUB7-CYSfmlLx.js} +1 -1
  94. package/dist/viewer/{infoDiagram-27XIBGKW-DtnCMWLn.js → infoDiagram-27XIBGKW-BWBppJ8S.js} +1 -1
  95. package/dist/viewer/{ishikawaDiagram-5VMMS53U-DJITL75z.js → ishikawaDiagram-5VMMS53U-DwcqlxrU.js} +1 -1
  96. package/dist/viewer/{it-IT-JPQ66NNP-DPpOxig5.js → it-IT-JPQ66NNP-BmsXfM8K.js} +1 -1
  97. package/dist/viewer/{ja-JP-DBVTYXUO-czDcO5hY.js → ja-JP-DBVTYXUO-DyW8qb-0.js} +1 -1
  98. package/dist/viewer/{journeyDiagram-3NMN7TZE-C8QHQm2P.js → journeyDiagram-3NMN7TZE-DcgpwdKu.js} +7 -7
  99. package/dist/viewer/{kaa-6HZHGXH3-10EO2C3t.js → kaa-6HZHGXH3-DJYup-gx.js} +1 -1
  100. package/dist/viewer/{kab-KAB-ZGHBKWFO-jN9hQes5.js → kab-KAB-ZGHBKWFO-D1TTkU3Z.js} +1 -1
  101. package/dist/viewer/{kanban-definition-UXKFOSKX-BPwnRmy-.js → kanban-definition-UXKFOSKX-DY7wxWTD.js} +1 -1
  102. package/dist/viewer/{kk-KZ-P5N5QNE5-BXiW-6pN.js → kk-KZ-P5N5QNE5-Bi6KJaJ_.js} +1 -1
  103. package/dist/viewer/{km-KH-HSX4SM5Z-eJZcjbVY.js → km-KH-HSX4SM5Z-DUgQIxqu.js} +1 -1
  104. package/dist/viewer/{ko-KR-MTYHY66A-DJQ5t55Q.js → ko-KR-MTYHY66A-DBjXJgtG.js} +1 -1
  105. package/dist/viewer/{ku-TR-6OUDTVRD-SslXbW7I.js → ku-TR-6OUDTVRD-DZ7-3E8v.js} +1 -1
  106. package/dist/viewer/{lt-LT-XHIRWOB4-BQQH3p63.js → lt-LT-XHIRWOB4-CZq0sHVB.js} +1 -1
  107. package/dist/viewer/{lv-LV-5QDEKY6T-Clu0u2XA.js → lv-LV-5QDEKY6T-CSnpouGk.js} +1 -1
  108. package/dist/viewer/{mermaid-parser.core-BdSSxVU7.js → mermaid-parser.core-HxZZO7kh.js} +3 -3
  109. package/dist/viewer/{mindmap-definition-YA3MSWOX-DrF6TBI_.js → mindmap-definition-YA3MSWOX-B8Pb-wf1.js} +1 -1
  110. package/dist/viewer/{mr-IN-CRQNXWMA-CQxb20NT.js → mr-IN-CRQNXWMA-COt7YzBU.js} +1 -1
  111. package/dist/viewer/{my-MM-5M5IBNSE-DWucYt2w.js → my-MM-5M5IBNSE-D0Y1Da5n.js} +1 -1
  112. package/dist/viewer/{nb-NO-T6EIAALU-COGWygzu.js → nb-NO-T6EIAALU-oWyfOUMc.js} +1 -1
  113. package/dist/viewer/{nl-NL-IS3SIHDZ-BeHSFsZU.js → nl-NL-IS3SIHDZ-DmHiL8bF.js} +1 -1
  114. package/dist/viewer/{nn-NO-6E72VCQL-DpyrfPpI.js → nn-NO-6E72VCQL-aPmsjnhV.js} +1 -1
  115. package/dist/viewer/{oc-FR-POXYY2M6-Cs74HNSe.js → oc-FR-POXYY2M6-IX-_Z2L9.js} +1 -1
  116. package/dist/viewer/{pa-IN-N4M65BXN-BmXzYjy2.js → pa-IN-N4M65BXN-Bs_eqV6D.js} +1 -1
  117. package/dist/viewer/{packet-AYTQ26CC-usauJtTa.js → packet-AYTQ26CC-DszQqrn-.js} +1 -1
  118. package/dist/viewer/{pegDiagram-XKGWAZYB-BnXj64Ei.js → pegDiagram-XKGWAZYB-CUKB72zB.js} +1 -1
  119. package/dist/viewer/percentages-BXMCSKIN-B0uUmwNv.js +1 -0
  120. package/dist/viewer/{pie-WAS4IAKB-DknaY_2m.js → pie-WAS4IAKB-_7Cjr2yX.js} +1 -1
  121. package/dist/viewer/pieDiagram-E7YTZNPT-PGM-bC7i.js +39 -0
  122. package/dist/viewer/{pl-PL-T2D74RX3-T6Fe9mdT.js → pl-PL-T2D74RX3-B62vM7Wd.js} +1 -1
  123. package/dist/viewer/{prod-AmqxNzpE.js → prod-CXChZPSF.js} +12 -12
  124. package/dist/viewer/{pt-BR-5N22H2LF-CePhWINQ.js → pt-BR-5N22H2LF-DeO8w0-j.js} +1 -1
  125. package/dist/viewer/{pt-PT-UZXXM6DQ-DsHfrYs5.js → pt-PT-UZXXM6DQ-DHRKu_nC.js} +1 -1
  126. package/dist/viewer/{quadrantDiagram-AXDQQJYC-BANg6Bk_.js → quadrantDiagram-AXDQQJYC-BHGqqzJO.js} +6 -6
  127. package/dist/viewer/{radar-RG4KPBEZ-Dbo2ldml.js → radar-RG4KPBEZ-DUB0C2uH.js} +1 -1
  128. package/dist/viewer/{railroad-74A4TZTK-C5ptSrdP.js → railroad-74A4TZTK-BWFq_Uxa.js} +1 -1
  129. package/dist/viewer/{railroad-abnf-HS5TGJTU-B5-w1gmO.js → railroad-abnf-HS5TGJTU-CXi8H5jA.js} +1 -1
  130. package/dist/viewer/{railroad-ebnf-LZEXJU2U-DgzWo47b.js → railroad-ebnf-LZEXJU2U-BF6QoeOc.js} +1 -1
  131. package/dist/viewer/{railroad-peg-WCYAUIDC-Rohr0jWN.js → railroad-peg-WCYAUIDC-DZk9vECQ.js} +1 -1
  132. package/dist/viewer/{railroadDiagram-O6MQD6OU-BM43IHqe.js → railroadDiagram-O6MQD6OU-xkx7KBZh.js} +1 -1
  133. package/dist/viewer/{requirementDiagram-BXWQKSXE-BpfN-tyX.js → requirementDiagram-BXWQKSXE-YoHOz35u.js} +1 -1
  134. package/dist/viewer/{ro-RO-JPDTUUEW-8ghwmIee.js → ro-RO-JPDTUUEW-CZ7CkjNI.js} +1 -1
  135. package/dist/viewer/{ru-RU-B4JR7IUQ-HQRhTM2R.js → ru-RU-B4JR7IUQ-sQ2YRlyV.js} +1 -1
  136. package/dist/viewer/{sankeyDiagram-P5KCCOFB-wkQgztcK.js → sankeyDiagram-P5KCCOFB-D0ehFMRa.js} +1 -1
  137. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-CgGiuRe0.js → sequenceDiagram-WJ2MYXX4-DdADoY-J.js} +1 -1
  138. package/dist/viewer/{si-LK-N5RQ5JYF-D67JK97H.js → si-LK-N5RQ5JYF-DLuQj109.js} +1 -1
  139. package/dist/viewer/{sk-SK-C5VTKIMK-B2W6Cezg.js → sk-SK-C5VTKIMK-CMe_YVPU.js} +1 -1
  140. package/dist/viewer/{sl-SI-NN7IZMDC-CXYpfWDT.js → sl-SI-NN7IZMDC-BPakRJTF.js} +1 -1
  141. package/dist/viewer/stateDiagram-D77RDMKH-DDcsZcrC.js +1 -0
  142. package/dist/viewer/stateDiagram-v2-MP3YSRHH-BEL5Pgsi.js +1 -0
  143. package/dist/viewer/subset-shared.chunk-CT_Q-SQa.js +1 -0
  144. package/dist/viewer/{subset-worker.chunk-Bp_PHA4h.js → subset-worker.chunk-CAdHeyaa.js} +1 -1
  145. package/dist/viewer/{sv-SE-XGPEYMSR-DEdFY4ZO.js → sv-SE-XGPEYMSR-qERuvZ6s.js} +1 -1
  146. package/dist/viewer/{swimlanes-42K2YHIH-Co-B4prm.js → swimlanes-42K2YHIH-C1_2L18N.js} +1 -1
  147. package/dist/viewer/swimlanesDiagram-VR7AAH4N-ZxKOyUwv.js +8 -0
  148. package/dist/viewer/{ta-IN-2NMHFXQM-EAJkqvlH.js → ta-IN-2NMHFXQM-CtrwjuD9.js} +1 -1
  149. package/dist/viewer/{th-TH-HPSO5L25-iFl_gUpg.js → th-TH-HPSO5L25-D2ykN4P-.js} +1 -1
  150. package/dist/viewer/{timeline-definition-24CTP7MA-CY4kJUpV.js → timeline-definition-24CTP7MA-Bw3z4a18.js} +7 -7
  151. package/dist/viewer/{tr-TR-DEFEU3FU-BY4Qxw4z.js → tr-TR-DEFEU3FU-DG1l6URL.js} +1 -1
  152. package/dist/viewer/{treeView-Q6P3EWNA-CZswEJX-.js → treeView-Q6P3EWNA-DEPHUB4h.js} +1 -1
  153. package/dist/viewer/{treemap-WGGIJYW6-Bxu2ANKb.js → treemap-WGGIJYW6-fyrd1JXW.js} +1 -1
  154. package/dist/viewer/{uk-UA-QMV73CPH-B0Pj5ITY.js → uk-UA-QMV73CPH-BOWgVI7Y.js} +1 -1
  155. package/dist/viewer/{vennDiagram-4TSXK5OY-R2fJVmFw.js → vennDiagram-4TSXK5OY-ba8MnyJG.js} +1 -1
  156. package/dist/viewer/{vi-VN-M7AON7JQ-DW-lWcLk.js → vi-VN-M7AON7JQ-uVRFZJH3.js} +1 -1
  157. package/dist/viewer/{wardley-WFR3VGLG-B5ClAPZx.js → wardley-WFR3VGLG-w1K3t7u7.js} +1 -1
  158. package/dist/viewer/{wardleyDiagram-VM6X3IG4-DSbOqXHD.js → wardleyDiagram-VM6X3IG4-BXqHV7Of.js} +1 -1
  159. package/dist/viewer/{xychartDiagram-S5SC5T6Z-B8TvP47z.js → xychartDiagram-S5SC5T6Z-DDAwmSA_.js} +6 -6
  160. package/dist/viewer/{zh-CN-LNUGB5OW-DoQdr1Gr.js → zh-CN-LNUGB5OW-CG6LZlkW.js} +1 -1
  161. package/dist/viewer/{zh-HK-E62DVLB3-CL8mO9m4.js → zh-HK-E62DVLB3-B1k0qvGq.js} +1 -1
  162. package/dist/viewer/{zh-TW-RAJ6MFWO-Bn2UsB-h.js → zh-TW-RAJ6MFWO-DnRoij4Q.js} +1 -1
  163. package/package.json +14 -14
  164. package/dist/viewer/DocumentPage-CWIKqaxW.css +0 -1
  165. package/dist/viewer/bundle-full-wBDeuAI3.js +0 -1
  166. package/dist/viewer/channel-9zFn1XUZ.js +0 -1
  167. package/dist/viewer/chunk-OSK3NFVY-BaVrPSZ1.js +0 -10
  168. package/dist/viewer/chunk-PWAF6VOD-Btkhupbq.js +0 -1
  169. package/dist/viewer/classDiagram-ZZMXUADV-BbfPk5VI.js +0 -1
  170. package/dist/viewer/classDiagram-v2-VYDZK3BY-BbfPk5VI.js +0 -1
  171. package/dist/viewer/diagram-VX7I27RA-CXEsN_TH.js +0 -24
  172. package/dist/viewer/dist-3_W2uhz9.js +0 -1
  173. package/dist/viewer/dist-6YtIYN9U.js +0 -11
  174. package/dist/viewer/dist-B1Uj0j6_.js +0 -1
  175. package/dist/viewer/dist-BH2W2_kH.js +0 -23
  176. package/dist/viewer/dist-BP31qiHB.js +0 -2
  177. package/dist/viewer/dist-BZMiS25s.js +0 -1
  178. package/dist/viewer/dist-BgEiCwCY.js +0 -1
  179. package/dist/viewer/dist-BqYTu_K0.js +0 -1
  180. package/dist/viewer/dist-CAA5JL-H.js +0 -1
  181. package/dist/viewer/dist-CQMhsU7V.js +0 -1
  182. package/dist/viewer/dist-CcnKrk8J.js +0 -1
  183. package/dist/viewer/dist-CvV1imaV.js +0 -1
  184. package/dist/viewer/dist-D5HYlhLP.js +0 -1
  185. package/dist/viewer/dist-DNc6xRYL.js +0 -6
  186. package/dist/viewer/dist-DOix3dB5.js +0 -1
  187. package/dist/viewer/dist-DPawvC3r.js +0 -1
  188. package/dist/viewer/dist-DV2vWKxQ.js +0 -9
  189. package/dist/viewer/dist-D_N9ry31.js +0 -1
  190. package/dist/viewer/dist-DmNyJ7xQ.js +0 -1
  191. package/dist/viewer/dist-DvsfYDhh.js +0 -1
  192. package/dist/viewer/dist-F63P6t_j.js +0 -1
  193. package/dist/viewer/dist-GfcCd8dY.js +0 -1
  194. package/dist/viewer/dist-xklV_v9R.js +0 -1
  195. package/dist/viewer/flowDiagram-HODETNUW-rE0pM-Yy.js +0 -1
  196. package/dist/viewer/ganttDiagram-EL5Y4UJY-DSUaNw2e.js +0 -292
  197. package/dist/viewer/percentages-BXMCSKIN-MiUOXNm2.js +0 -1
  198. package/dist/viewer/pieDiagram-E7YTZNPT-7IT3IkfR.js +0 -39
  199. package/dist/viewer/stateDiagram-D77RDMKH-CHn4O4ho.js +0 -1
  200. package/dist/viewer/stateDiagram-v2-MP3YSRHH-27y2SulA.js +0 -1
  201. package/dist/viewer/subset-shared.chunk-Re1K60kh.js +0 -1
  202. package/dist/viewer/swimlanesDiagram-VR7AAH4N--fzHsdcJ.js +0 -8
package/dist/server.cjs CHANGED
@@ -1563,13 +1563,14 @@ var require_canvas = __commonJS({
1563
1563
 
1564
1564
  // src/server/main.ts
1565
1565
  var import_node_child_process = require("node:child_process");
1566
- var import_node_fs13 = __toESM(require("node:fs"), 1);
1567
- var import_node_path12 = __toESM(require("node:path"), 1);
1566
+ var import_node_fs17 = __toESM(require("node:fs"), 1);
1567
+ var import_node_os = __toESM(require("node:os"), 1);
1568
+ var import_node_path16 = __toESM(require("node:path"), 1);
1568
1569
 
1569
1570
  // src/server/app.ts
1570
- var import_node_fs11 = __toESM(require("node:fs"), 1);
1571
+ var import_node_fs15 = __toESM(require("node:fs"), 1);
1571
1572
  var import_node_http = __toESM(require("node:http"), 1);
1572
- var import_node_path11 = __toESM(require("node:path"), 1);
1573
+ var import_node_path15 = __toESM(require("node:path"), 1);
1573
1574
 
1574
1575
  // src/shared/types.ts
1575
1576
  var ARTIFACT_TYPES = ["artboard", "document", "html"];
@@ -3113,19 +3114,19 @@ var ElementDOMSlot = class _ElementDOMSlot extends DOMSlot {
3113
3114
  }
3114
3115
  };
3115
3116
  function indexPath(root, child) {
3116
- const path13 = [];
3117
+ const path17 = [];
3117
3118
  let node = child;
3118
3119
  for (; node !== root && node !== null; node = node.parentNode) {
3119
3120
  let i6 = 0;
3120
3121
  for (let sibling = node.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
3121
3122
  i6++;
3122
3123
  }
3123
- path13.push(i6);
3124
+ path17.push(i6);
3124
3125
  }
3125
3126
  if (!(node === root)) {
3126
3127
  formatDevErrorMessage(`indexPath: root is not a parent of child`);
3127
3128
  }
3128
- return path13.reverse();
3129
+ return path17.reverse();
3129
3130
  }
3130
3131
  // @__NO_SIDE_EFFECTS__
3131
3132
  function readLexicalVersion() {
@@ -17905,9 +17906,9 @@ function getActiveElementDeep(root) {
17905
17906
  function getComposedEventTarget(event) {
17906
17907
  const target = event.target;
17907
17908
  if (target !== null && isHTMLElement(target) && target.shadowRoot !== null && typeof event.composedPath === "function") {
17908
- const path13 = event.composedPath();
17909
- if (path13.length > 0) {
17910
- return path13[0];
17909
+ const path17 = event.composedPath();
17910
+ if (path17.length > 0) {
17911
+ return path17[0];
17911
17912
  }
17912
17913
  }
17913
17914
  return target;
@@ -28003,10 +28004,10 @@ function _loadWasmModule(sync, filepath, src, imports2) {
28003
28004
  var buf = null;
28004
28005
  var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
28005
28006
  if (filepath && isNode2) {
28006
- var fs16 = null;
28007
- var path13 = null;
28007
+ var fs20 = null;
28008
+ var path17 = null;
28008
28009
  return new Promise((resolve, reject) => {
28009
- fs16.readFile(path13.resolve(__dirname, filepath), (error, buffer) => {
28010
+ fs20.readFile(path17.resolve(__dirname, filepath), (error, buffer) => {
28010
28011
  if (error != null) {
28011
28012
  reject(error);
28012
28013
  } else {
@@ -29309,10 +29310,10 @@ var LoroDoc = class _LoroDoc {
29309
29310
  * @param {string} path
29310
29311
  * @returns {Value | Container | undefined}
29311
29312
  */
29312
- getByPath(path13) {
29313
+ getByPath(path17) {
29313
29314
  try {
29314
29315
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
29315
- const ptr0 = passStringToWasm0(path13, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
29316
+ const ptr0 = passStringToWasm0(path17, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
29316
29317
  const len0 = WASM_VECTOR_LEN;
29317
29318
  wasm.lorodoc_getByPath(retptr, this.__wbg_ptr, ptr0, len0);
29318
29319
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
@@ -36491,7 +36492,7 @@ decorateMethods(EphemeralStoreWasm.prototype, [
36491
36492
  ]);
36492
36493
  decorateMethods(UndoManager.prototype, ["undo", "redo"]);
36493
36494
 
36494
- // node_modules/.pnpm/@haklex+rich-collab-loro@0.50.1_lexical@0.52.0_typescript@5.9.3__loro-crdt@1.16.4/node_modules/@haklex/rich-collab-loro/dist/index.mjs
36495
+ // node_modules/.pnpm/@haklex+rich-collab-loro@0.51.0_lexical@0.52.0_typescript@5.9.3__loro-crdt@1.16.4/node_modules/@haklex/rich-collab-loro/dist/index.mjs
36495
36496
  function transformOffset(previous, next, offset) {
36496
36497
  const limit = Math.min(previous.length, next.length);
36497
36498
  let prefix = 0;
@@ -37472,11 +37473,11 @@ var LexicalExtensionNamedSignals_dev_exports = {};
37472
37473
  __export(LexicalExtensionNamedSignals_dev_exports, {
37473
37474
  namedSignals: () => namedSignals
37474
37475
  });
37475
- function namedSignals(defaults, opts = {}) {
37476
+ function namedSignals(defaults2, opts = {}) {
37476
37477
  const initial = {};
37477
- for (const k5 in defaults) {
37478
+ for (const k5 in defaults2) {
37478
37479
  const v6 = opts[k5];
37479
- const store = signal(v6 === void 0 ? defaults[k5] : v6);
37480
+ const store = signal(v6 === void 0 ? defaults2[k5] : v6);
37480
37481
  initial[k5] = store;
37481
37482
  }
37482
37483
  return initial;
@@ -42282,8 +42283,8 @@ function sequence4($acc, $getOverride) {
42282
42283
  }
42283
42284
  };
42284
42285
  }
42285
- function compilePrerenderKey(prerender, k5, defaults, mergeFunction, ignoreNextFunction) {
42286
- let acc = defaults[k5];
42286
+ function compilePrerenderKey(prerender, k5, defaults2, mergeFunction, ignoreNextFunction) {
42287
+ let acc = defaults2[k5];
42287
42288
  for (const pair of prerender[k5]) {
42288
42289
  if (typeof pair[0] === "function") {
42289
42290
  const [$predicate, $override] = pair;
@@ -42303,7 +42304,7 @@ function compilePrerenderKey(prerender, k5, defaults, mergeFunction, ignoreNextF
42303
42304
  });
42304
42305
  }
42305
42306
  }
42306
- defaults[k5] = acc;
42307
+ defaults2[k5] = acc;
42307
42308
  }
42308
42309
  function addOverride(prerender, k5, predicateOrTypes, override) {
42309
42310
  if (!override) {
@@ -43182,13 +43183,13 @@ function readElementFormatStyle(el2) {
43182
43183
  verticalAlign: el2.style.verticalAlign
43183
43184
  };
43184
43185
  }
43185
- function mergeStyles(defaults, override) {
43186
+ function mergeStyles(defaults2, override) {
43186
43187
  return {
43187
- fontStyle: override.fontStyle || defaults.fontStyle,
43188
- fontWeight: override.fontWeight || defaults.fontWeight,
43189
- textDecoration: override.textDecoration || defaults.textDecoration,
43190
- textTransform: override.textTransform || defaults.textTransform,
43191
- verticalAlign: override.verticalAlign || defaults.verticalAlign
43188
+ fontStyle: override.fontStyle || defaults2.fontStyle,
43189
+ fontWeight: override.fontWeight || defaults2.fontWeight,
43190
+ textDecoration: override.textDecoration || defaults2.textDecoration,
43191
+ textTransform: override.textTransform || defaults2.textTransform,
43192
+ verticalAlign: override.verticalAlign || defaults2.verticalAlign
43192
43193
  };
43193
43194
  }
43194
43195
  var FORMAT_BIT_STYLE_PROPS = /* @__PURE__ */ new Set(["font-weight", "font-style", "text-decoration", "text-transform", "vertical-align"]);
@@ -43726,11 +43727,11 @@ var DefaultHoistRule = {
43726
43727
  var DOMImportExtension = {
43727
43728
  build(editor, config) {
43728
43729
  const dispatch2 = compileImportRules(flattenRuleEntries(config.rules));
43729
- const defaults = contextFromPairs(config.contextDefaults, void 0);
43730
+ const defaults2 = contextFromPairs(config.contextDefaults, void 0);
43730
43731
  const configPreprocess = config.preprocess;
43731
43732
  return {
43732
43733
  $generateNodesFromDOM: (dom, options) => {
43733
- const parentRecord = getContextRecord(DOMImportContextSymbol, editor) || defaults;
43734
+ const parentRecord = getContextRecord(DOMImportContextSymbol, editor) || defaults2;
43734
43735
  const fromOpts = options && options.context ? contextFromPairs(options.context, parentRecord) : parentRecord;
43735
43736
  const sessionRecord = fromOpts !== void 0 && fromOpts !== parentRecord ? fromOpts : Object.create(parentRecord || null);
43736
43737
  const session = new ImportSessionImpl(sessionRecord);
@@ -43741,7 +43742,7 @@ var DOMImportExtension = {
43741
43742
  $runPreprocessStack(stack, dom, preprocessCtx);
43742
43743
  return /* @__PURE__ */ $withFullContext(DOMImportContextSymbol, sessionRecord, () => $runImport(dispatch2, editor, dom, session), editor);
43743
43744
  },
43744
- defaults
43745
+ defaults: defaults2
43745
43746
  };
43746
43747
  },
43747
43748
  config: {
@@ -67902,7 +67903,7 @@ var UNORDERED_LIST2 = mod28.UNORDERED_LIST;
67902
67903
  var isTableRowDivider2 = mod28.isTableRowDivider;
67903
67904
  var registerMarkdownShortcuts2 = mod28.registerMarkdownShortcuts;
67904
67905
 
67905
- // node_modules/.pnpm/@haklex+rich-headless@0.50.1_lexical@0.52.0_typescript@5.9.3__typescript@5.9.3/node_modules/@haklex/rich-headless/dist/transformers.mjs
67906
+ // node_modules/.pnpm/@haklex+rich-headless@0.51.0_lexical@0.52.0_typescript@5.9.3__typescript@5.9.3/node_modules/@haklex/rich-headless/dist/transformers.mjs
67906
67907
  var NEVER = /a^/;
67907
67908
  var NOOP = () => {
67908
67909
  };
@@ -70559,7 +70560,7 @@ var signal2 = mod43.signal;
70559
70560
  var untracked2 = mod43.untracked;
70560
70561
  var watchedSignal3 = mod43.watchedSignal;
70561
70562
 
70562
- // node_modules/.pnpm/@haklex+rich-headless@0.50.1_lexical@0.52.0_typescript@5.9.3__typescript@5.9.3/node_modules/@haklex/rich-headless/dist/index.mjs
70563
+ // node_modules/.pnpm/@haklex+rich-headless@0.51.0_lexical@0.52.0_typescript@5.9.3__typescript@5.9.3/node_modules/@haklex/rich-headless/dist/index.mjs
70563
70564
  var builtinNodes = [
70564
70565
  HeadingNode2,
70565
70566
  QuoteNode2,
@@ -70725,11 +70726,11 @@ var RichQuoteNode = class RichQuoteNode2 extends QuoteNode2 {
70725
70726
  return false;
70726
70727
  }
70727
70728
  };
70728
- function headlessDecorator(type, propKeys, defaults, inline = false) {
70729
+ function headlessDecorator(type, propKeys, defaults2, inline = false) {
70729
70730
  class Node5 extends DecoratorNode2 {
70730
70731
  constructor(key2) {
70731
70732
  super(key2);
70732
- for (const k5 of propKeys) this[`__${k5}`] = defaults[k5];
70733
+ for (const k5 of propKeys) this[`__${k5}`] = defaults2[k5];
70733
70734
  }
70734
70735
  static getType() {
70735
70736
  return type;
@@ -70742,7 +70743,7 @@ function headlessDecorator(type, propKeys, defaults, inline = false) {
70742
70743
  static importJSON(_json) {
70743
70744
  const json = _json;
70744
70745
  const node = new Node5();
70745
- for (const k5 of propKeys) node[`__${k5}`] = json[k5] ?? defaults[k5];
70746
+ for (const k5 of propKeys) node[`__${k5}`] = json[k5] ?? defaults2[k5];
70746
70747
  return node.updateFromJSON(json);
70747
70748
  }
70748
70749
  exportJSON() {
@@ -71352,7 +71353,7 @@ function customAlphabet(alphabet, defaultSize = 21) {
71352
71353
  }
71353
71354
  var nanoid2 = customAlphabet(urlAlphabet2);
71354
71355
 
71355
- // node_modules/.pnpm/@haklex+rich-litexml@0.50.1_typescript@5.9.3/node_modules/@haklex/rich-litexml/dist/src-COIhAhyB.js
71356
+ // node_modules/.pnpm/@haklex+rich-litexml@0.51.0_typescript@5.9.3/node_modules/@haklex/rich-litexml/dist/src-COIhAhyB.js
71356
71357
  var impl = null;
71357
71358
  function registerParseHTML(fn5) {
71358
71359
  impl = fn5;
@@ -83456,7 +83457,7 @@ function Document4() {
83456
83457
  }
83457
83458
  setPrototypeOf(Document4, Document2).prototype = Document2.prototype;
83458
83459
 
83459
- // node_modules/.pnpm/@haklex+rich-litexml@0.50.1_typescript@5.9.3/node_modules/@haklex/rich-litexml/dist/node.mjs
83460
+ // node_modules/.pnpm/@haklex+rich-litexml@0.51.0_typescript@5.9.3/node_modules/@haklex/rich-litexml/dist/node.mjs
83460
83461
  registerParseHTML((html) => parseHTML2(html).document);
83461
83462
 
83462
83463
  // src/shared/dynamic.ts
@@ -83954,6 +83955,384 @@ function createDocumentRegistry(options) {
83954
83955
  };
83955
83956
  }
83956
83957
 
83958
+ // src/inspector/runtime.ts
83959
+ function installInspector(win, properties) {
83960
+ const doc = win.document;
83961
+ const session = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
83962
+ const ids = /* @__PURE__ */ new WeakMap();
83963
+ const elements = /* @__PURE__ */ new Map();
83964
+ const originals = /* @__PURE__ */ new Map();
83965
+ const ignored2 = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "META", "LINK", "NOSCRIPT", "HEAD"]);
83966
+ let nextId = 0;
83967
+ let enabled = false;
83968
+ let connection = "";
83969
+ let selected = null;
83970
+ let treeTimer = 0;
83971
+ let geometryFrame = 0;
83972
+ let hovered = null;
83973
+ let selectedRect = null;
83974
+ let hoverRect = null;
83975
+ let dragging = null;
83976
+ let marquee = null;
83977
+ let suppressClick = false;
83978
+ const tracked = /* @__PURE__ */ new Map();
83979
+ const post = (type, data) => win.parent.postMessage({ type: `ryugi:inspect:${type}`, session, connection, ...data }, "*");
83980
+ const idOf = (el2) => {
83981
+ let id2 = ids.get(el2);
83982
+ if (!id2) {
83983
+ id2 = ++nextId;
83984
+ ids.set(el2, id2);
83985
+ }
83986
+ elements.set(id2, el2);
83987
+ return id2;
83988
+ };
83989
+ const label = (el2) => (el2.getAttribute("data-layer-name") || el2.getAttribute("aria-label") || el2.id || (!el2.childElementCount ? el2.textContent?.trim() : "") || "").slice(0, 100);
83990
+ const selector = (el2) => (el2.id ? `#${el2.id}` : el2.tagName.toLowerCase() + Array.from(el2.classList).slice(0, 2).map((name) => `.${name}`).join("")).slice(0, 200);
83991
+ const kind = (el2, style) => {
83992
+ if (/^H[1-6]$/.test(el2.tagName)) return "Title";
83993
+ if (["IMG", "SVG", "CANVAS", "VIDEO"].includes(el2.tagName.toUpperCase())) return "Image";
83994
+ if (["BUTTON", "A", "INPUT", "SELECT", "TEXTAREA"].includes(el2.tagName)) return "Button";
83995
+ if (!el2.childElementCount) return "Text";
83996
+ if (style.display.includes("flex")) return style.flexDirection.startsWith("row") ? "Row" : "Column";
83997
+ return style.display.includes("grid") ? "Grid" : "Frame";
83998
+ };
83999
+ const rectOf = (el2) => {
84000
+ const rect = el2.getBoundingClientRect();
84001
+ return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
84002
+ };
84003
+ const selection = (reason, toggle = false) => {
84004
+ if (!selected?.isConnected) {
84005
+ selected = null;
84006
+ post("selection", { selection: null, reason });
84007
+ return;
84008
+ }
84009
+ const el2 = selected;
84010
+ const style = win.getComputedStyle(el2);
84011
+ const inline = el2.style;
84012
+ const info = {
84013
+ id: idOf(el2),
84014
+ name: label(el2),
84015
+ tag: el2.tagName.toLowerCase(),
84016
+ selector: selector(el2),
84017
+ rect: selectedRect = rectOf(el2),
84018
+ css: Object.fromEntries(properties.map((property) => [property, style.getPropertyValue(property)])),
84019
+ html: el2.outerHTML.slice(0, 2e4),
84020
+ widthMode: inline?.width === "100%" ? "fill" : inline?.width === "max-content" ? "hug" : "fixed",
84021
+ heightMode: inline?.height && inline.height !== "auto" ? "fixed" : "hug"
84022
+ };
84023
+ post("selection", { selection: info, reason, toggle });
84024
+ };
84025
+ const tweaks = () => {
84026
+ const list = [];
84027
+ for (const [el2, changes] of originals) {
84028
+ if (!el2.isConnected) {
84029
+ originals.delete(el2);
84030
+ continue;
84031
+ }
84032
+ for (const [property, saved] of changes) list.push({ id: idOf(el2), name: label(el2) || selector(el2), property, value: saved.applied });
84033
+ }
84034
+ post("tweaks", { tweaks: list });
84035
+ };
84036
+ const tree = () => {
84037
+ if (!enabled || !doc.body) return;
84038
+ elements.clear();
84039
+ const nodes = [];
84040
+ let truncated = false;
84041
+ const visit = (el2, parentId, depth) => {
84042
+ if (ignored2.has(el2.tagName) || el2.hasAttribute("data-ryugi-inspector")) return null;
84043
+ if (nodes.length >= 2500 || depth >= 50) {
84044
+ truncated = true;
84045
+ return null;
84046
+ }
84047
+ const id2 = idOf(el2);
84048
+ const node = { id: id2, parentId, name: label(el2), tag: el2.tagName.toLowerCase(), selector: selector(el2), kind: kind(el2, win.getComputedStyle(el2)), children: [] };
84049
+ nodes.push(node);
84050
+ for (const child of el2.children) {
84051
+ if (nodes.length >= 2500) {
84052
+ truncated = true;
84053
+ break;
84054
+ }
84055
+ const childId = visit(child, id2, depth + 1);
84056
+ if (childId !== null) node.children.push(childId);
84057
+ }
84058
+ return id2;
84059
+ };
84060
+ visit(doc.body, null, 0);
84061
+ post("tree", { nodes, truncated });
84062
+ };
84063
+ const refresh = () => {
84064
+ treeTimer = 0;
84065
+ if (!enabled) return;
84066
+ tree();
84067
+ selection("update");
84068
+ tweaks();
84069
+ };
84070
+ const schedule = () => {
84071
+ if (enabled && !treeTimer) treeTimer = win.setTimeout(refresh, 100);
84072
+ };
84073
+ const observer = new win.MutationObserver(schedule);
84074
+ const sameRect = (a5, b6) => a5 && a5.x === b6.x && a5.y === b6.y && a5.width === b6.width && a5.height === b6.height;
84075
+ const geometry = () => {
84076
+ if (!enabled) return;
84077
+ if (selected?.isConnected) {
84078
+ const rect = rectOf(selected);
84079
+ if (!sameRect(selectedRect, rect)) {
84080
+ selectedRect = rect;
84081
+ post("rect", { id: idOf(selected), rect });
84082
+ }
84083
+ }
84084
+ for (const [id2, previous] of tracked) {
84085
+ const el2 = elements.get(id2);
84086
+ if (!el2?.isConnected) {
84087
+ tracked.delete(id2);
84088
+ continue;
84089
+ }
84090
+ const rect = rectOf(el2);
84091
+ if (!sameRect(previous, rect)) {
84092
+ tracked.set(id2, rect);
84093
+ post("rect", { id: id2, rect });
84094
+ }
84095
+ }
84096
+ if (hovered?.isConnected) {
84097
+ const rect = rectOf(hovered);
84098
+ if (!sameRect(hoverRect, rect)) {
84099
+ hoverRect = rect;
84100
+ post("hover", { rect });
84101
+ }
84102
+ } else if (hoverRect) {
84103
+ hoverRect = null;
84104
+ post("hover", { rect: null });
84105
+ }
84106
+ geometryFrame = win.requestAnimationFrame(geometry);
84107
+ };
84108
+ const ignoredTarget = (el2) => !!el2.closest("[data-ryugi-inspector], script, style, link");
84109
+ const onClick2 = (event) => {
84110
+ if (!enabled || event.button !== 0 || !(event.target instanceof win.Element) || ignoredTarget(event.target)) return;
84111
+ event.preventDefault();
84112
+ event.stopImmediatePropagation();
84113
+ if (suppressClick) {
84114
+ suppressClick = false;
84115
+ return;
84116
+ }
84117
+ selected = event.target.closest("svg") || event.target;
84118
+ selection("user", event.shiftKey || event.metaKey || event.ctrlKey);
84119
+ };
84120
+ const onPointerDown2 = (event) => {
84121
+ if (!enabled) return;
84122
+ if (event.button === 1) {
84123
+ event.preventDefault();
84124
+ event.stopImmediatePropagation();
84125
+ dragging = { x: event.screenX, y: event.screenY, pointer: event.pointerId };
84126
+ doc.documentElement.setPointerCapture?.(event.pointerId);
84127
+ } else if (event.button === 0 && event.target instanceof win.Element) {
84128
+ event.preventDefault();
84129
+ event.stopImmediatePropagation();
84130
+ suppressClick = false;
84131
+ marquee = { x: event.clientX, y: event.clientY, screenX: event.screenX, screenY: event.screenY, pointer: event.pointerId, append: event.shiftKey || event.metaKey || event.ctrlKey, moved: false };
84132
+ event.target.setPointerCapture?.(event.pointerId);
84133
+ post("drag", { phase: "start", x: event.clientX, y: event.clientY, append: marquee.append, id: idOf(event.target.closest("svg") || event.target) });
84134
+ }
84135
+ };
84136
+ const onPointerMove = (event) => {
84137
+ if (!enabled) return;
84138
+ if (dragging) {
84139
+ post("pan", { deltaX: event.screenX - dragging.x, deltaY: event.screenY - dragging.y });
84140
+ dragging.x = event.screenX;
84141
+ dragging.y = event.screenY;
84142
+ return;
84143
+ }
84144
+ if (marquee && event.pointerId === marquee.pointer) {
84145
+ if (Math.hypot(event.screenX - marquee.screenX, event.screenY - marquee.screenY) >= 3) marquee.moved = true;
84146
+ if (marquee.moved) post("drag", { phase: "move", x: event.clientX, y: event.clientY, append: marquee.append });
84147
+ return;
84148
+ }
84149
+ if (!(event.target instanceof win.Element)) return;
84150
+ hovered = ignoredTarget(event.target) ? null : event.target.closest("svg") || event.target;
84151
+ };
84152
+ const endDrag = (event) => {
84153
+ if (marquee) {
84154
+ const pointer = event;
84155
+ post("drag", { phase: event.type === "pointerup" && marquee.moved ? "end" : "cancel", x: pointer.clientX ?? marquee.x, y: pointer.clientY ?? marquee.y, append: marquee.append });
84156
+ suppressClick = marquee.moved;
84157
+ }
84158
+ dragging = null;
84159
+ marquee = null;
84160
+ };
84161
+ const leave = () => {
84162
+ hovered = null;
84163
+ hoverRect = null;
84164
+ if (enabled) post("hover", { rect: null });
84165
+ };
84166
+ const wheel = (event) => {
84167
+ if (!enabled) return;
84168
+ event.preventDefault();
84169
+ event.stopImmediatePropagation();
84170
+ const factor = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? win.innerHeight : 1;
84171
+ post("wheel", { deltaX: event.deltaX * factor, deltaY: event.deltaY * factor, x: event.clientX, y: event.clientY, zoom: event.ctrlKey || event.metaKey });
84172
+ };
84173
+ const key2 = (event) => {
84174
+ if (!enabled || event.composedPath().some((target) => target instanceof win.Element && target.matches("input,textarea,select,[contenteditable]"))) return;
84175
+ if (!["Space", "KeyH", "KeyV", "Escape", "Equal", "Minus", "Digit0", "Digit1"].includes(event.code)) return;
84176
+ event.preventDefault();
84177
+ event.stopImmediatePropagation();
84178
+ post("key", { key: event.key, code: event.code, down: event.type === "keydown", ctrlKey: event.ctrlKey, metaKey: event.metaKey, shiftKey: event.shiftKey, altKey: event.altKey });
84179
+ };
84180
+ const scroll = () => {
84181
+ if (enabled && selected) selection("update");
84182
+ };
84183
+ const disable = () => {
84184
+ endDrag(new win.Event("pointercancel"));
84185
+ enabled = false;
84186
+ observer.disconnect();
84187
+ win.clearTimeout(treeTimer);
84188
+ win.cancelAnimationFrame(geometryFrame);
84189
+ treeTimer = 0;
84190
+ geometryFrame = 0;
84191
+ hovered = null;
84192
+ hoverRect = null;
84193
+ post("hover", { rect: null });
84194
+ };
84195
+ const onMessage = (event) => {
84196
+ if (event.source !== win.parent || event.data?.type !== "ryugi:inspect") return;
84197
+ const data = event.data;
84198
+ if (data.action === "enable") {
84199
+ if (typeof data.connection !== "string" || !data.connection || data.connection.length > 128) return;
84200
+ connection = data.connection;
84201
+ enabled = true;
84202
+ observer.observe(doc.documentElement, { subtree: true, childList: true, characterData: true, attributes: true });
84203
+ win.cancelAnimationFrame(geometryFrame);
84204
+ geometryFrame = win.requestAnimationFrame(geometry);
84205
+ tree();
84206
+ tweaks();
84207
+ if (selected) selection("update");
84208
+ return;
84209
+ }
84210
+ if (data.connection !== connection) return;
84211
+ if (data.action === "disable") {
84212
+ disable();
84213
+ return;
84214
+ }
84215
+ if (!enabled && data.action !== "reset") return;
84216
+ if (data.session !== session) return;
84217
+ if (data.action === "cancel-drag") {
84218
+ endDrag(new win.Event("pointercancel"));
84219
+ return;
84220
+ }
84221
+ if (data.action === "select" && Number.isSafeInteger(data.id)) {
84222
+ const el2 = elements.get(data.id);
84223
+ if (el2?.isConnected) {
84224
+ selected = el2;
84225
+ selection(data.primary === true ? "primary" : "command", data.toggle === true);
84226
+ }
84227
+ } else if (data.action === "track" && Array.isArray(data.ids) && data.ids.length <= 2500 && data.ids.every((id2) => Number.isSafeInteger(id2) && id2 > 0)) {
84228
+ tracked.clear();
84229
+ for (const id2 of data.ids) {
84230
+ const el2 = elements.get(id2);
84231
+ if (el2?.isConnected) tracked.set(id2, rectOf(el2));
84232
+ }
84233
+ } else if (data.action === "marquee" && Number.isSafeInteger(data.request) && data.request > 0) {
84234
+ const r7 = data.rect;
84235
+ if (!r7 || !["x", "y", "width", "height"].every((key3) => typeof r7[key3] === "number" && Number.isFinite(r7[key3]) && Math.abs(r7[key3]) <= 1e8) || r7.width < 0 || r7.height < 0) return;
84236
+ const contained = /* @__PURE__ */ new Set();
84237
+ const targets = [];
84238
+ for (const [id2, el2] of elements) {
84239
+ if (el2 === doc.body || !el2.isConnected) continue;
84240
+ const rect = rectOf(el2);
84241
+ if (rect.width <= 0 || rect.height <= 0 || rect.x < r7.x || rect.y < r7.y || rect.x + rect.width > r7.x + r7.width || rect.y + rect.height > r7.y + r7.height) continue;
84242
+ let parent = el2.parentElement;
84243
+ while (parent && !contained.has(parent)) parent = parent.parentElement;
84244
+ if (parent) continue;
84245
+ contained.add(el2);
84246
+ targets.push({ id: id2, name: label(el2) || selector(el2), rect });
84247
+ }
84248
+ post("targets", { request: data.request, targets });
84249
+ } else if (data.action === "hover") {
84250
+ const el2 = elements.get(data.id);
84251
+ hovered = el2?.isConnected ? el2 : null;
84252
+ hoverRect = hovered ? rectOf(hovered) : null;
84253
+ post("hover", { rect: hoverRect });
84254
+ } else if (data.action === "style" && data.session === session && selected && ids.get(selected) === data.id && properties.includes(data.property) && typeof data.value === "string" && data.value.length <= 300) {
84255
+ const el2 = selected;
84256
+ if (!el2.style || !el2.isConnected) return;
84257
+ const property = data.property;
84258
+ const probe = doc.createElement("div").style;
84259
+ probe.setProperty(property, data.value);
84260
+ const value = probe.getPropertyValue(property);
84261
+ if (!value) return;
84262
+ if (!originals.has(el2)) originals.set(el2, /* @__PURE__ */ new Map());
84263
+ const changes = originals.get(el2);
84264
+ if (!changes.has(property)) {
84265
+ const affected = /* @__PURE__ */ new Set([...Array.from(probe), ...Array.from(el2.style).filter((name) => probe.getPropertyValue(name))]);
84266
+ changes.set(property, { applied: "", declarations: new Map(Array.from(affected, (name) => [name, { value: el2.style.getPropertyValue(name), priority: el2.style.getPropertyPriority(name), applied: "" }])) });
84267
+ }
84268
+ el2.style.setProperty(property, value);
84269
+ const saved = changes.get(property);
84270
+ saved.applied = el2.style.getPropertyValue(property);
84271
+ for (const [name, declaration] of saved.declarations) declaration.applied = el2.style.getPropertyValue(name);
84272
+ selection("update");
84273
+ tweaks();
84274
+ } else if (data.action === "reset") {
84275
+ for (const [el2, changes] of originals) for (const saved of changes.values()) {
84276
+ const owned = Array.from(saved.declarations).filter(([name, declaration]) => el2.style.getPropertyValue(name) === declaration.applied && !el2.style.getPropertyPriority(name));
84277
+ for (const [name, declaration] of owned) {
84278
+ if (declaration.value) el2.style.setProperty(name, declaration.value, declaration.priority);
84279
+ else el2.style.removeProperty(name);
84280
+ }
84281
+ }
84282
+ originals.clear();
84283
+ selection("update");
84284
+ tweaks();
84285
+ }
84286
+ };
84287
+ win.addEventListener("message", onMessage);
84288
+ doc.addEventListener("click", onClick2, true);
84289
+ doc.addEventListener("pointerdown", onPointerDown2, true);
84290
+ doc.addEventListener("pointermove", onPointerMove, true);
84291
+ doc.addEventListener("pointerup", endDrag, true);
84292
+ doc.addEventListener("pointercancel", endDrag, true);
84293
+ doc.addEventListener("pointerleave", leave);
84294
+ doc.addEventListener("wheel", wheel, { passive: false, capture: true });
84295
+ doc.addEventListener("keydown", key2, true);
84296
+ doc.addEventListener("keyup", key2, true);
84297
+ win.addEventListener("scroll", scroll, true);
84298
+ win.addEventListener("blur", endDrag);
84299
+ return () => {
84300
+ disable();
84301
+ win.removeEventListener("message", onMessage);
84302
+ doc.removeEventListener("click", onClick2, true);
84303
+ doc.removeEventListener("pointerdown", onPointerDown2, true);
84304
+ doc.removeEventListener("pointermove", onPointerMove, true);
84305
+ doc.removeEventListener("pointerup", endDrag, true);
84306
+ doc.removeEventListener("pointercancel", endDrag, true);
84307
+ doc.removeEventListener("pointerleave", leave);
84308
+ doc.removeEventListener("wheel", wheel, true);
84309
+ doc.removeEventListener("keydown", key2, true);
84310
+ doc.removeEventListener("keyup", key2, true);
84311
+ win.removeEventListener("scroll", scroll, true);
84312
+ win.removeEventListener("blur", endDrag);
84313
+ };
84314
+ }
84315
+
84316
+ // src/shared/inspector.ts
84317
+ var INSPECTOR_PROPERTIES = [
84318
+ "width",
84319
+ "height",
84320
+ "position",
84321
+ "flex-grow",
84322
+ "display",
84323
+ "flex-direction",
84324
+ "align-items",
84325
+ "gap",
84326
+ "padding",
84327
+ "background-color",
84328
+ "opacity",
84329
+ "border-radius",
84330
+ "border-style",
84331
+ "font-size",
84332
+ "color",
84333
+ "box-shadow"
84334
+ ];
84335
+
83957
84336
  // src/server/inject.ts
83958
84337
  var RUNTIME = `(() => {
83959
84338
  const post = (message) => parent.postMessage(message, '*');
@@ -84063,8 +84442,9 @@ var EMBEDDED_STYLE = "<style>:root{color-scheme:light dark;background:transparen
84063
84442
  var UI_MARKER = /<ryugi-[a-z0-9-]+(?:\s|>)/i;
84064
84443
  var UI_META = /<meta[^>]+name=["']ryugi-ui["'][^>]*>/i;
84065
84444
  function injectRuntime(html, options = {}) {
84066
- const tag = `${options.embedded ? EMBEDDED_STYLE : ""}<script>${RUNTIME_LINE}</script>`;
84067
- const ui2 = options.uiRuntimeUrl && (UI_MARKER.test(html) || UI_META.test(html)) ? `<script defer src="${options.uiRuntimeUrl.replace(/"/g, "&quot;")}"></script>` : "";
84445
+ const inspect = options.inspector ? `;(${installInspector.toString().replace(/\n/g, " ")})(window,${JSON.stringify(INSPECTOR_PROPERTIES)});` : "";
84446
+ const tag = `${options.embedded ? EMBEDDED_STYLE : ""}<script>${inspect || RUNTIME_LINE}</script>`;
84447
+ const ui2 = options.uiRuntimeUrl && !options.inspector && (UI_MARKER.test(html) || UI_META.test(html)) ? `<script defer src="${options.uiRuntimeUrl.replace(/"/g, "&quot;")}"></script>` : "";
84068
84448
  const head = HEAD.exec(html);
84069
84449
  const at7 = head ? head.index + head[0].length : PROLOGUE.exec(html)?.[0].length ?? 0;
84070
84450
  return html.slice(0, at7) + tag + ui2 + html.slice(at7);
@@ -84227,26 +84607,606 @@ function createDynamicBlocks(limits) {
84227
84607
  };
84228
84608
  }
84229
84609
 
84230
- // src/server/watch.ts
84610
+ // src/server/config.ts
84231
84611
  var import_node_fs10 = __toESM(require("node:fs"), 1);
84232
84612
  var import_node_path10 = __toESM(require("node:path"), 1);
84233
- var toPosix = (file) => file.split(import_node_path10.default.sep).join("/");
84613
+
84614
+ // src/shared/cloud.ts
84615
+ var isVisibility = (value) => value === "private" || value === "public";
84616
+
84617
+ // src/server/config.ts
84618
+ var defaults = () => ({ version: 1, artifacts: {} });
84619
+ function isCloudRecord(value) {
84620
+ if (typeof value !== "object" || value === null) return false;
84621
+ const { id: id2, url, publishedAt, visibility } = value;
84622
+ return typeof id2 === "string" && typeof url === "string" && typeof publishedAt === "string" && isVisibility(visibility);
84623
+ }
84624
+ function normalize(raw) {
84625
+ const config = defaults();
84626
+ if (typeof raw !== "object" || raw === null) return config;
84627
+ const artifacts = raw.artifacts;
84628
+ if (typeof artifacts !== "object" || artifacts === null) return config;
84629
+ for (const [key2, value] of Object.entries(artifacts)) {
84630
+ if (typeof value !== "object" || value === null) continue;
84631
+ const { visibility, cloud } = value;
84632
+ if (visibility !== void 0 && !isVisibility(visibility)) continue;
84633
+ const entry = {};
84634
+ if (visibility) entry.visibility = visibility;
84635
+ if (isCloudRecord(cloud)) entry.cloud = { id: cloud.id, url: cloud.url, publishedAt: cloud.publishedAt, visibility: cloud.visibility };
84636
+ config.artifacts[key2] = entry;
84637
+ }
84638
+ return config;
84639
+ }
84640
+ function readConfig(file) {
84641
+ let text;
84642
+ try {
84643
+ text = import_node_fs10.default.readFileSync(file, "utf8");
84644
+ } catch {
84645
+ return { config: defaults() };
84646
+ }
84647
+ try {
84648
+ return { config: normalize(JSON.parse(text)) };
84649
+ } catch (err) {
84650
+ return { config: defaults(), warning: `config.json is not valid JSON: ${err.message}` };
84651
+ }
84652
+ }
84653
+ function ensureGitignore(dir) {
84654
+ const file = import_node_path10.default.join(dir, ".gitignore");
84655
+ let current = "";
84656
+ try {
84657
+ current = import_node_fs10.default.readFileSync(file, "utf8");
84658
+ } catch {
84659
+ import_node_fs10.default.writeFileSync(file, "config.json\n");
84660
+ return;
84661
+ }
84662
+ if (current.split(/\r?\n/).some((line) => line.trim() === "config.json")) return;
84663
+ import_node_fs10.default.writeFileSync(file, `${current}${current === "" || current.endsWith("\n") ? "" : "\n"}config.json
84664
+ `);
84665
+ }
84666
+ function ensureConfig(file) {
84667
+ import_node_fs10.default.mkdirSync(import_node_path10.default.dirname(file), { recursive: true });
84668
+ ensureGitignore(import_node_path10.default.dirname(file));
84669
+ if (!import_node_fs10.default.existsSync(file)) writeJsonAtomic(file, defaults());
84670
+ }
84671
+ function updateArtifactConfig(file, key2, patch) {
84672
+ const { config, warning } = readConfig(file);
84673
+ if (warning) throw new Error(warning);
84674
+ const entry = { ...config.artifacts[key2] };
84675
+ if (patch.visibility) entry.visibility = patch.visibility;
84676
+ if (patch.cloud === null) delete entry.cloud;
84677
+ else if (patch.cloud) entry.cloud = patch.cloud;
84678
+ config.artifacts[key2] = entry;
84679
+ writeJsonAtomic(file, config);
84680
+ return entry;
84681
+ }
84682
+
84683
+ // src/server/cloud.ts
84684
+ var import_node_crypto3 = __toESM(require("node:crypto"), 1);
84685
+
84686
+ // src/server/callback-page.ts
84687
+ var CALLBACK_PAGE_CSP = "default-src 'none'; style-src 'unsafe-inline'; img-src data:; script-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'";
84688
+ var escapeHtml = (value) => value.replace(/[&<>"']/g, (ch) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[ch]);
84689
+ var GRAIN = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>";
84690
+ var STYLE2 = `
84691
+ :root {
84692
+ color-scheme: light dark;
84693
+ --paper: #f3ede1;
84694
+ --paper-deep: #e8dfcd;
84695
+ --ink: #1d1a16;
84696
+ --ink-soft: #6b6152;
84697
+ --rule: #cfc3ab;
84698
+ --moon-hi: #fffaf0;
84699
+ --moon-mid: #f1e4c6;
84700
+ --moon-lo: #d6c19b;
84701
+ --halo: rgba(214, 178, 110, 0.35);
84702
+ --accent: #9b3d2a;
84703
+ --serif: "Iowan Old Style", "Songti SC", "STSong", "Noto Serif CJK SC", "Source Han Serif SC", Georgia, serif;
84704
+ --sans: "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", system-ui, sans-serif;
84705
+ --mono: ui-monospace, "SF Mono", Menlo, monospace;
84706
+ }
84707
+ @media (prefers-color-scheme: dark) {
84708
+ :root {
84709
+ --paper: #0e1222;
84710
+ --paper-deep: #070912;
84711
+ --ink: #ece6d8;
84712
+ --ink-soft: #9a96a8;
84713
+ --rule: #2a3050;
84714
+ --moon-hi: #fffdf6;
84715
+ --moon-mid: #e9dfc6;
84716
+ --moon-lo: #b9a985;
84717
+ --halo: rgba(233, 214, 160, 0.28);
84718
+ --accent: #e08a6d;
84719
+ }
84720
+ }
84721
+ * { box-sizing: border-box; }
84722
+ html, body { height: 100%; margin: 0; }
84723
+ body {
84724
+ display: grid;
84725
+ place-items: center;
84726
+ padding: 32px 20px;
84727
+ background: radial-gradient(120% 90% at 18% 20%, var(--paper) 0%, var(--paper-deep) 100%);
84728
+ color: var(--ink);
84729
+ font-family: var(--sans);
84730
+ -webkit-font-smoothing: antialiased;
84731
+ overflow: hidden;
84732
+ }
84733
+ body::before {
84734
+ content: "";
84735
+ position: fixed;
84736
+ inset: 0;
84737
+ background-image: url("${GRAIN}");
84738
+ opacity: 0.07;
84739
+ mix-blend-mode: multiply;
84740
+ pointer-events: none;
84741
+ }
84742
+ main {
84743
+ position: relative;
84744
+ display: grid;
84745
+ grid-template-columns: auto minmax(0, 360px);
84746
+ align-items: center;
84747
+ gap: 56px;
84748
+ max-width: 760px;
84749
+ }
84750
+ .sky { position: relative; width: 220px; height: 220px; }
84751
+ .moon {
84752
+ position: absolute;
84753
+ inset: 0;
84754
+ border-radius: 50%;
84755
+ background:
84756
+ radial-gradient(circle at 64% 30%, rgba(0, 0, 0, 0.06) 0 9%, transparent 10%),
84757
+ radial-gradient(circle at 34% 62%, rgba(0, 0, 0, 0.05) 0 13%, transparent 14%),
84758
+ radial-gradient(circle at 70% 70%, rgba(0, 0, 0, 0.04) 0 6%, transparent 7%),
84759
+ radial-gradient(circle at 35% 32%, var(--moon-hi) 0%, var(--moon-mid) 55%, var(--moon-lo) 100%);
84760
+ box-shadow: 0 0 0 1px var(--halo), 0 0 80px 18px var(--halo);
84761
+ animation: rise 1.1s cubic-bezier(0.2, 0.7, 0.1, 1) both;
84762
+ }
84763
+ .failed .moon {
84764
+ background: transparent;
84765
+ box-shadow: inset 34px -14px 0 0 var(--moon-lo), 0 0 0 1px var(--rule);
84766
+ opacity: 0.85;
84767
+ }
84768
+ .vertical {
84769
+ position: absolute;
84770
+ right: -34px;
84771
+ top: 6px;
84772
+ writing-mode: vertical-rl;
84773
+ font-family: var(--serif);
84774
+ font-size: 15px;
84775
+ letter-spacing: 0.5em;
84776
+ color: var(--ink-soft);
84777
+ animation: fade 1s 0.5s both;
84778
+ }
84779
+ .label {
84780
+ display: flex;
84781
+ align-items: center;
84782
+ gap: 10px;
84783
+ margin: 0 0 18px;
84784
+ font-family: var(--mono);
84785
+ font-size: 11px;
84786
+ letter-spacing: 0.18em;
84787
+ text-transform: uppercase;
84788
+ color: var(--ink-soft);
84789
+ animation: fade 0.8s 0.35s both;
84790
+ }
84791
+ .label::before { content: ""; width: 28px; height: 1px; background: var(--rule); }
84792
+ .failed .label { color: var(--accent); }
84793
+ h1 {
84794
+ margin: 0;
84795
+ font-family: var(--serif);
84796
+ font-weight: 600;
84797
+ font-size: clamp(34px, 6vw, 46px);
84798
+ line-height: 1.15;
84799
+ letter-spacing: 0.01em;
84800
+ animation: fade 0.9s 0.45s both;
84801
+ }
84802
+ h1 em {
84803
+ display: block;
84804
+ font-style: italic;
84805
+ font-weight: 400;
84806
+ color: var(--ink-soft);
84807
+ }
84808
+ p {
84809
+ margin: 22px 0 0;
84810
+ font-size: 15px;
84811
+ line-height: 1.85;
84812
+ color: var(--ink-soft);
84813
+ animation: fade 0.9s 0.6s both;
84814
+ }
84815
+ p strong { color: var(--ink); font-weight: 500; }
84816
+ footer {
84817
+ margin-top: 34px;
84818
+ padding-top: 16px;
84819
+ border-top: 1px solid var(--rule);
84820
+ display: flex;
84821
+ justify-content: space-between;
84822
+ gap: 16px;
84823
+ font-family: var(--mono);
84824
+ font-size: 11px;
84825
+ color: var(--ink-soft);
84826
+ animation: fade 0.9s 0.75s both;
84827
+ }
84828
+ @keyframes rise { from { opacity: 0; transform: translateY(28px) scale(0.96); } to { opacity: 1; transform: none; } }
84829
+ @keyframes fade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
84830
+ @media (max-width: 640px) {
84831
+ main { grid-template-columns: 1fr; gap: 40px; justify-items: start; }
84832
+ .sky { width: 132px; height: 132px; }
84833
+ .vertical { display: none; }
84834
+ }
84835
+ @media (prefers-reduced-motion: reduce) {
84836
+ *, *::before, *::after { animation: none !important; }
84837
+ }
84838
+ `;
84839
+ function callbackPage(result) {
84840
+ const host = escapeHtml(new URL(result.origin).host);
84841
+ const title = result.ok ? "\u5DF2\u767B\u5F55 Ryugi Cloud" : "\u767B\u5F55\u6CA1\u6709\u5B8C\u6210";
84842
+ const body = result.ok ? `<p class="label">Ryugi Cloud \xB7 \u5DF2\u8FDE\u63A5</p>
84843
+ <h1>\u5DF2\u767B\u5F55<em>${escapeHtml(result.login)}</em></h1>
84844
+ <p>\u8FD9\u53F0\u7535\u8111\u4E0A\u7684 Ryugi \u73B0\u5728\u53EF\u4EE5\u53D1\u5E03 artifact \u4E86\u3002<strong>\u56DE\u5230 Ryugi</strong>\uFF0C\u5206\u4EAB\u9762\u677F\u4F1A\u81EA\u52A8\u5237\u65B0\uFF1B\u5982\u679C\u662F\u8BA9 agent \u53D1\u5E03\u7684\uFF0C\u8BA9\u5B83\u518D\u8FD0\u884C\u4E00\u6B21\u53D1\u5E03\u547D\u4EE4\u3002</p>` : `<p class="label">Ryugi Cloud \xB7 \u672A\u8FDE\u63A5</p>
84845
+ <h1>\u767B\u5F55\u6CA1\u6709\u5B8C\u6210</h1>
84846
+ <p>${escapeHtml(result.detail)}</p>`;
84847
+ return `<!doctype html>
84848
+ <html lang="zh-CN">
84849
+ <head>
84850
+ <meta charset="utf-8">
84851
+ <meta name="viewport" content="width=device-width, initial-scale=1">
84852
+ <meta name="referrer" content="no-referrer">
84853
+ <title>${title}</title>
84854
+ <style>${STYLE2}</style>
84855
+ </head>
84856
+ <body>
84857
+ <main class="${result.ok ? "signed-in" : "failed"}">
84858
+ <div class="sky" aria-hidden="true"><div class="moon"></div><span class="vertical">\u6D41\u5100</span></div>
84859
+ <section>
84860
+ ${body}
84861
+ <footer><span>${result.ok ? "\u53EF\u4EE5\u5173\u95ED\u8FD9\u4E2A\u9875\u9762" : "\u53EF\u4EE5\u5173\u95ED\u8FD9\u4E2A\u9875\u9762\u540E\u91CD\u8BD5"}</span><span>${host}</span></footer>
84862
+ </section>
84863
+ </main>
84864
+ </body>
84865
+ </html>
84866
+ `;
84867
+ }
84868
+
84869
+ // src/server/credentials.ts
84870
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
84871
+ var import_node_path11 = __toESM(require("node:path"), 1);
84872
+ function credentialsFile(env, platform, home) {
84873
+ if (platform === "win32" && env.APPDATA) return import_node_path11.default.join(env.APPDATA, "ryugi", "credentials.json");
84874
+ return import_node_path11.default.join(env.XDG_CONFIG_HOME || import_node_path11.default.join(home, ".config"), "ryugi", "credentials.json");
84875
+ }
84876
+ function readCredentials(file, origin) {
84877
+ let raw;
84878
+ try {
84879
+ raw = JSON.parse(import_node_fs11.default.readFileSync(file, "utf8"));
84880
+ } catch {
84881
+ return null;
84882
+ }
84883
+ if (typeof raw !== "object" || raw === null) return null;
84884
+ const { origin: savedOrigin, token, login } = raw;
84885
+ if (typeof savedOrigin !== "string" || typeof token !== "string" || typeof login !== "string") return null;
84886
+ if (savedOrigin !== origin) return null;
84887
+ return { origin: savedOrigin, token, login };
84888
+ }
84889
+ function writeCredentials(file, credentials) {
84890
+ import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(file), { recursive: true, mode: 448 });
84891
+ writeJsonAtomic(file, credentials);
84892
+ }
84893
+ function clearCredentials(file) {
84894
+ import_node_fs11.default.rmSync(file, { force: true });
84895
+ }
84896
+
84897
+ // src/server/pack.ts
84898
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
84899
+ var import_node_path12 = __toESM(require("node:path"), 1);
84900
+ var MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
84901
+ function formatBytes(bytes) {
84902
+ if (bytes < 1024) return `${bytes} B`;
84903
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
84904
+ return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
84905
+ }
84906
+ var excluded = (type, relative) => type === "document" && relative === "comments.json";
84907
+ function packArtifact(dir, type, { maxBytes = MAX_ARTIFACT_BYTES } = {}) {
84908
+ const rootReal = import_node_fs12.default.realpathSync(dir);
84909
+ const found = [];
84910
+ const visited = /* @__PURE__ */ new Set([rootReal]);
84911
+ let total = 0;
84912
+ const walk = (current) => {
84913
+ for (const entry of import_node_fs12.default.readdirSync(current, { withFileTypes: true })) {
84914
+ if (entry.name.startsWith(".")) continue;
84915
+ const full = import_node_path12.default.join(current, entry.name);
84916
+ let real;
84917
+ try {
84918
+ real = import_node_fs12.default.realpathSync(full);
84919
+ } catch {
84920
+ continue;
84921
+ }
84922
+ if (!real.startsWith(rootReal + import_node_path12.default.sep)) continue;
84923
+ const stat = import_node_fs12.default.statSync(real);
84924
+ if (stat.isDirectory()) {
84925
+ if (visited.has(real)) continue;
84926
+ visited.add(real);
84927
+ walk(full);
84928
+ continue;
84929
+ }
84930
+ if (!stat.isFile()) continue;
84931
+ const relative = import_node_path12.default.relative(dir, full).split(import_node_path12.default.sep).join("/");
84932
+ if (excluded(type, relative)) continue;
84933
+ total += stat.size;
84934
+ found.push({ path: relative, real });
84935
+ }
84936
+ };
84937
+ walk(dir);
84938
+ if (total > maxBytes) {
84939
+ throw new Error(`artifact is ${formatBytes(total)}; the limit is ${formatBytes(maxBytes)}`);
84940
+ }
84941
+ return found.map((file) => ({ path: file.path, data: import_node_fs12.default.readFileSync(file.real) }));
84942
+ }
84943
+
84944
+ // src/server/publish-payload.ts
84945
+ var import_node_fs13 = __toESM(require("node:fs"), 1);
84946
+ var import_node_path13 = __toESM(require("node:path"), 1);
84947
+ var CLOUD_RUNTIME_URL = "/_ryugi/runtime/ryugi-ui.js";
84948
+ function publishPayload(ref, dir, title, payload) {
84949
+ if (ref.type === "artboard") {
84950
+ const { canvas, layout, versions } = payload;
84951
+ return { canvas, layout, versions };
84952
+ }
84953
+ if (ref.type === "document") return { title, state: parseDocument2(import_node_fs13.default.readFileSync(import_node_path13.default.join(dir, "doc.xml"), "utf8")) };
84954
+ return { title };
84955
+ }
84956
+ var isPage = (type, file) => type === "html" ? file === "index.html" : (type === "document" || type === "artboard") && file.endsWith(".html");
84957
+ function withCloudRuntime(type, files) {
84958
+ return files.map(
84959
+ (file) => isPage(type, file.path) ? { path: file.path, data: Buffer.from(injectRuntime(file.data.toString("utf8"), { uiRuntimeUrl: CLOUD_RUNTIME_URL, embedded: type === "document", inspector: type === "artboard" })) } : file
84960
+ );
84961
+ }
84962
+
84963
+ // src/server/cloud.ts
84964
+ var LOGIN_STATE_TTL_MS = 10 * 60 * 1e3;
84965
+ var MAX_JSON_BODY = 4096;
84966
+ var CLOUD_ID = /^[A-Za-z0-9_-]{1,64}$/;
84967
+ var ROUTE = /^\/api\/cloud\/(status|login|logout|artifacts|publish|visibility)(?:\/([^/]+)(?:\/([^/]+))?)?$/;
84968
+ var SignedOut = class extends Error {
84969
+ };
84970
+ var CloudRefused = class extends Error {
84971
+ constructor(status, message) {
84972
+ super(message);
84973
+ this.status = status;
84974
+ }
84975
+ status;
84976
+ };
84977
+ async function readJsonBody(req) {
84978
+ const chunks = [];
84979
+ let size = 0;
84980
+ for await (const chunk of req) {
84981
+ size += chunk.length;
84982
+ if (size > MAX_JSON_BODY) throw new CloudRefused(413, "request body too large");
84983
+ chunks.push(chunk);
84984
+ }
84985
+ try {
84986
+ return JSON.parse(Buffer.concat(chunks).toString("utf8") || "null");
84987
+ } catch {
84988
+ return null;
84989
+ }
84990
+ }
84991
+ async function errorMessage(res) {
84992
+ const text = await res.text().catch(() => "");
84993
+ try {
84994
+ const parsed = JSON.parse(text);
84995
+ return typeof parsed.error === "string" ? parsed.error : text;
84996
+ } catch {
84997
+ return text || res.statusText;
84998
+ }
84999
+ }
85000
+ function createCloudRoutes(options) {
85001
+ const { origin, credentialsFile: credentialsFile2, configFile } = options;
85002
+ const pendingStates = /* @__PURE__ */ new Map();
85003
+ const loginUrl = () => {
85004
+ const now = Date.now();
85005
+ for (const [state2, pending] of pendingStates) if (pending.expires < now) pendingStates.delete(state2);
85006
+ const state = randomToken();
85007
+ const verifier = randomToken();
85008
+ pendingStates.set(state, { expires: now + LOGIN_STATE_TTL_MS, verifier });
85009
+ const challenge = import_node_crypto3.default.createHash("sha256").update(verifier).digest("base64url");
85010
+ return `${origin}/auth/cli?port=${options.port()}&state=${state}&challenge=${challenge}`;
85011
+ };
85012
+ const cloudFetch = async (method, path17, body) => {
85013
+ const credentials = readCredentials(credentialsFile2, origin);
85014
+ if (!credentials) throw new SignedOut();
85015
+ const headers = { Authorization: `Bearer ${credentials.token}` };
85016
+ let payload;
85017
+ if (body instanceof FormData) payload = body;
85018
+ else if (body) {
85019
+ headers["Content-Type"] = "application/json";
85020
+ payload = JSON.stringify(body);
85021
+ }
85022
+ let res;
85023
+ try {
85024
+ res = await fetch(`${origin}${path17}`, { method, headers, body: payload });
85025
+ } catch (err) {
85026
+ throw new CloudRefused(502, `could not reach ${origin}: ${err.message}`);
85027
+ }
85028
+ if (res.status === 401) throw new SignedOut();
85029
+ return res;
85030
+ };
85031
+ const expectOk = async (res) => {
85032
+ if (!res.ok) throw new CloudRefused(502, `cloud refused (${res.status}): ${await errorMessage(res)}`);
85033
+ return res;
85034
+ };
85035
+ const artifactEntry = (key2) => readConfig(configFile).config.artifacts[key2] ?? {};
85036
+ const publish = async (ref, requested) => {
85037
+ const inspected = await options.inspect(ref);
85038
+ if (!inspected) throw new CloudRefused(404, `${ref.type}/${ref.id} not found`);
85039
+ if (inspected.reasons.length > 0 || !inspected.payload) return { status: 409, body: { error: "fix these before publishing", reasons: inspected.reasons } };
85040
+ let files;
85041
+ try {
85042
+ files = withCloudRuntime(ref.type, packArtifact(inspected.dir, ref.type));
85043
+ } catch (err) {
85044
+ throw new CloudRefused(413, err.message);
85045
+ }
85046
+ const key2 = `${ref.type}/${ref.id}`;
85047
+ const entry = artifactEntry(key2);
85048
+ const visibility = requested ?? entry.visibility ?? "private";
85049
+ const form = new FormData();
85050
+ form.set("meta", JSON.stringify({ type: ref.type, title: inspected.title, visibility }));
85051
+ form.set("payload", JSON.stringify(inspected.payload));
85052
+ for (const file of files) form.set(`file:${file.path}`, new Blob([new Uint8Array(file.data)]), file.path);
85053
+ let res = entry.cloud ? await cloudFetch("PUT", `/api/artifacts/${entry.cloud.id}`, form) : null;
85054
+ if (!res || res.status === 404) res = await cloudFetch("POST", "/api/artifacts", form);
85055
+ const published = await (await expectOk(res)).json();
85056
+ updateArtifactConfig(configFile, key2, {
85057
+ visibility,
85058
+ cloud: { id: published.id, url: published.url, publishedAt: published.updatedAt, visibility: published.visibility }
85059
+ });
85060
+ return { status: 200, body: { id: published.id, url: published.url, visibility, publishedAt: published.updatedAt } };
85061
+ };
85062
+ const setVisibility = async (ref, visibility) => {
85063
+ if (!await options.inspect(ref)) throw new CloudRefused(404, `${ref.type}/${ref.id} not found`);
85064
+ const key2 = `${ref.type}/${ref.id}`;
85065
+ const entry = artifactEntry(key2);
85066
+ if (entry.cloud) {
85067
+ const res = await cloudFetch("PATCH", `/api/artifacts/${entry.cloud.id}`, { visibility });
85068
+ if (res.status === 404) updateArtifactConfig(configFile, key2, { cloud: null });
85069
+ else {
85070
+ const updated = await (await expectOk(res)).json();
85071
+ updateArtifactConfig(configFile, key2, { cloud: { ...entry.cloud, visibility: updated.visibility } });
85072
+ }
85073
+ }
85074
+ return updateArtifactConfig(configFile, key2, { visibility });
85075
+ };
85076
+ const deleteCloud = async (cloudId) => {
85077
+ const res = await cloudFetch("DELETE", `/api/artifacts/${cloudId}`);
85078
+ if (res.status !== 404) await expectOk(res);
85079
+ for (const [key2, entry] of Object.entries(readConfig(configFile).config.artifacts)) {
85080
+ if (entry.cloud?.id === cloudId) updateArtifactConfig(configFile, key2, { cloud: null });
85081
+ }
85082
+ };
85083
+ const route = async (req, res, match) => {
85084
+ const [, action, first, second] = match;
85085
+ const method = req.method ?? "GET";
85086
+ const ref = first && second ? artifactKeyOf(`${first}/${second}`) : null;
85087
+ if (action === "status" && method === "GET" && !first) {
85088
+ const credentials = readCredentials(credentialsFile2, origin);
85089
+ const { config, warning } = readConfig(configFile);
85090
+ sendJson(res, 200, { signedIn: !!credentials, login: credentials?.login ?? null, origin, artifacts: config.artifacts, warning: warning ?? null });
85091
+ return;
85092
+ }
85093
+ if (action === "login" && method === "POST" && !first) {
85094
+ sendJson(res, 200, { url: loginUrl() });
85095
+ return;
85096
+ }
85097
+ if (action === "logout" && method === "POST" && !first) {
85098
+ const credentials = readCredentials(credentialsFile2, origin);
85099
+ if (credentials) {
85100
+ await fetch(`${origin}/api/logout`, { method: "POST", headers: { Authorization: `Bearer ${credentials.token}` } }).catch(() => void 0);
85101
+ }
85102
+ clearCredentials(credentialsFile2);
85103
+ sendJson(res, 200, { signedIn: false });
85104
+ return;
85105
+ }
85106
+ if (action === "artifacts" && method === "GET" && !first) {
85107
+ sendJson(res, 200, await (await expectOk(await cloudFetch("GET", "/api/artifacts"))).json());
85108
+ return;
85109
+ }
85110
+ if (action === "artifacts" && method === "DELETE" && first && !second) {
85111
+ if (!CLOUD_ID.test(first)) throw new CloudRefused(400, "not a cloud artifact id");
85112
+ await deleteCloud(first);
85113
+ sendJson(res, 200, { deleted: first });
85114
+ return;
85115
+ }
85116
+ if (action === "publish" && ref && method === "POST") {
85117
+ const body = await readJsonBody(req);
85118
+ if (body?.visibility !== void 0 && !isVisibility(body.visibility)) throw new CloudRefused(400, 'visibility must be "public" or "private"');
85119
+ const result = await publish(ref, body?.visibility);
85120
+ sendJson(res, result.status, result.body);
85121
+ return;
85122
+ }
85123
+ if (action === "publish" && ref && method === "DELETE") {
85124
+ const entry = artifactEntry(`${ref.type}/${ref.id}`);
85125
+ if (entry.cloud) await deleteCloud(entry.cloud.id);
85126
+ sendJson(res, 200, { unpublished: `${ref.type}/${ref.id}` });
85127
+ return;
85128
+ }
85129
+ if (action === "visibility" && ref && method === "POST") {
85130
+ const body = await readJsonBody(req);
85131
+ const visibility = body?.visibility;
85132
+ if (!isVisibility(visibility)) throw new CloudRefused(400, 'visibility must be "public" or "private"');
85133
+ sendJson(res, 200, await setVisibility(ref, visibility));
85134
+ return;
85135
+ }
85136
+ send(res, 404, "Not found");
85137
+ };
85138
+ return {
85139
+ async handleCallback(url, res) {
85140
+ const page = (status, result) => send(res, status, callbackPage({ ...result, origin }), {
85141
+ "Content-Type": "text/html; charset=utf-8",
85142
+ "Content-Security-Policy": CALLBACK_PAGE_CSP
85143
+ });
85144
+ const state = url.searchParams.get("state") ?? "";
85145
+ const pending = pendingStates.get(state);
85146
+ pendingStates.delete(state);
85147
+ const code = url.searchParams.get("code");
85148
+ if (!pending || pending.expires < Date.now() || !code) {
85149
+ page(400, { ok: false, detail: "\u8FD9\u4E2A\u767B\u5F55\u94FE\u63A5\u5DF2\u8FC7\u671F\u6216\u5DF2\u7ECF\u7528\u8FC7\u3002\u56DE\u5230 Ryugi \u91CD\u65B0\u53D1\u8D77\u4E00\u6B21\u767B\u5F55\u3002" });
85150
+ return;
85151
+ }
85152
+ let swap;
85153
+ try {
85154
+ swap = await fetch(`${origin}/auth/cli/token`, {
85155
+ method: "POST",
85156
+ headers: { "Content-Type": "application/json" },
85157
+ body: JSON.stringify({ code, verifier: pending.verifier })
85158
+ });
85159
+ } catch (err) {
85160
+ page(502, { ok: false, detail: `\u8FDE\u4E0D\u4E0A ${origin}\uFF08${err.message}\uFF09\u3002\u68C0\u67E5\u7F51\u7EDC\u540E\u56DE\u5230 Ryugi \u91CD\u65B0\u53D1\u8D77\u767B\u5F55\u3002` });
85161
+ return;
85162
+ }
85163
+ const issued = await swap.json().catch(() => ({}));
85164
+ if (!swap.ok || typeof issued.token !== "string" || typeof issued.login !== "string") {
85165
+ const reason = typeof issued.error === "string" ? issued.error : `HTTP ${swap.status}`;
85166
+ page(400, { ok: false, detail: `Ryugi Cloud \u6CA1\u6709\u63A5\u53D7\u8FD9\u6B21\u767B\u5F55\uFF08${reason}\uFF09\u3002\u56DE\u5230 Ryugi \u91CD\u65B0\u53D1\u8D77\u767B\u5F55\u3002` });
85167
+ return;
85168
+ }
85169
+ writeCredentials(credentialsFile2, { origin, token: issued.token, login: issued.login });
85170
+ page(200, { ok: true, login: issued.login });
85171
+ },
85172
+ match: (pathname) => ROUTE.exec(pathname),
85173
+ async handle(req, res, match) {
85174
+ try {
85175
+ await route(req, res, match);
85176
+ } catch (err) {
85177
+ if (res.headersSent) return;
85178
+ if (err instanceof SignedOut) {
85179
+ sendJson(res, 401, { error: "not signed in to the Ryugi cloud", loginUrl: loginUrl() });
85180
+ } else if (err instanceof CloudRefused) {
85181
+ sendJson(res, err.status, { error: err.message });
85182
+ } else {
85183
+ sendJson(res, 500, { error: err.message });
85184
+ }
85185
+ }
85186
+ }
85187
+ };
85188
+ }
85189
+
85190
+ // src/server/watch.ts
85191
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
85192
+ var import_node_path14 = __toESM(require("node:path"), 1);
85193
+ var toPosix = (file) => file.split(import_node_path14.default.sep).join("/");
84234
85194
  var ignored = (file) => file === ".state" || file.startsWith(".state/");
84235
85195
  function snapshot(root, dir = root, out = /* @__PURE__ */ new Map()) {
84236
85196
  let entries2;
84237
85197
  try {
84238
- entries2 = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
85198
+ entries2 = import_node_fs14.default.readdirSync(dir, { withFileTypes: true });
84239
85199
  } catch {
84240
85200
  return out;
84241
85201
  }
84242
85202
  for (const entry of entries2) {
84243
- const full = import_node_path10.default.join(dir, entry.name);
84244
- const rel = toPosix(import_node_path10.default.relative(root, full));
85203
+ const full = import_node_path14.default.join(dir, entry.name);
85204
+ const rel = toPosix(import_node_path14.default.relative(root, full));
84245
85205
  if (ignored(rel)) continue;
84246
85206
  if (entry.isDirectory()) snapshot(root, full, out);
84247
85207
  else {
84248
85208
  try {
84249
- out.set(rel, import_node_fs10.default.statSync(full).mtimeMs);
85209
+ out.set(rel, import_node_fs14.default.statSync(full).mtimeMs);
84250
85210
  } catch {
84251
85211
  }
84252
85212
  }
@@ -84279,7 +85239,7 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
84279
85239
  }, debounceMs);
84280
85240
  };
84281
85241
  try {
84282
- const watcher = import_node_fs10.default.watch(root, { recursive: true }, (_event, filename) => {
85242
+ const watcher = import_node_fs14.default.watch(root, { recursive: true }, (_event, filename) => {
84283
85243
  if (filename) queue([toPosix(filename.toString())]);
84284
85244
  });
84285
85245
  watcher.on("error", () => {
@@ -84304,14 +85264,14 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
84304
85264
  }
84305
85265
 
84306
85266
  // src/server/ws.ts
84307
- var import_node_crypto3 = __toESM(require("node:crypto"), 1);
85267
+ var import_node_crypto4 = __toESM(require("node:crypto"), 1);
84308
85268
  var WS_MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
84309
85269
  var OPCODE_TEXT = 1;
84310
85270
  var OPCODE_CLOSE = 8;
84311
85271
  var OPCODE_PING = 9;
84312
85272
  var OPCODE_PONG = 10;
84313
85273
  function acceptKey(clientKey) {
84314
- return import_node_crypto3.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
85274
+ return import_node_crypto4.default.createHash("sha1").update(clientKey + WS_MAGIC).digest("base64");
84315
85275
  }
84316
85276
  function encodeFrame(opcode, payload) {
84317
85277
  const len = payload.length;
@@ -84421,16 +85381,17 @@ function titleOf(payload, ref) {
84421
85381
  return payload.canvas?.title || ref.id;
84422
85382
  }
84423
85383
  async function startArtifactsServer(options) {
84424
- const root = import_node_path11.default.resolve(options.root);
84425
- const viewerDir = import_node_path11.default.resolve(options.viewerDir);
84426
- const runtimeDir = options.runtimeDir ? import_node_path11.default.resolve(options.runtimeDir) : null;
84427
- const stateDir = import_node_path11.default.join(root, ".state");
84428
- import_node_fs11.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
84429
- import_node_fs11.default.writeFileSync(import_node_path11.default.join(stateDir, ".gitignore"), "*\n");
84430
- const portFile = import_node_path11.default.join(stateDir, ".last-port");
84431
- const tokenFile = import_node_path11.default.join(stateDir, ".last-token");
85384
+ const root = import_node_path15.default.resolve(options.root);
85385
+ const viewerDir = import_node_path15.default.resolve(options.viewerDir);
85386
+ const runtimeDir = options.runtimeDir ? import_node_path15.default.resolve(options.runtimeDir) : null;
85387
+ const stateDir = import_node_path15.default.join(root, ".state");
85388
+ import_node_fs15.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
85389
+ import_node_fs15.default.writeFileSync(import_node_path15.default.join(stateDir, ".gitignore"), "*\n");
85390
+ if (options.configFile) ensureConfig(options.configFile);
85391
+ const portFile = import_node_path15.default.join(stateDir, ".last-port");
85392
+ const tokenFile = import_node_path15.default.join(stateDir, ".last-token");
84432
85393
  const token = readPersisted(tokenFile) || randomToken();
84433
- import_node_fs11.default.writeFileSync(tokenFile, `${token}
85394
+ import_node_fs15.default.writeFileSync(tokenFile, `${token}
84434
85395
  `, { mode: 384 });
84435
85396
  const contentToken = randomToken();
84436
85397
  const runtimeWarnings = /* @__PURE__ */ new Map();
@@ -84461,6 +85422,27 @@ async function startArtifactsServer(options) {
84461
85422
  },
84462
85423
  log: (line) => console.log(JSON.stringify({ type: "document-log", line }))
84463
85424
  });
85425
+ const inspect = async (ref) => {
85426
+ const dir = resolveArtifactDir(root, ref.type, ref.id);
85427
+ if (!dir) return null;
85428
+ const session = ref.type === "document" ? await documents.open(ref.id) : null;
85429
+ await session?.flush();
85430
+ const payload = readArtifact(dir, ref, runtimeOf(ref, dir));
85431
+ const reasons = [...payload.warnings];
85432
+ if ("pending" in payload) reasons.push(...payload.pending.map((board) => `board ${board} is still being written`));
85433
+ if (session?.streaming()) reasons.push("the document is still being written");
85434
+ const title = titleOf(payload, ref);
85435
+ let published = null;
85436
+ if (reasons.length === 0) {
85437
+ try {
85438
+ published = publishPayload(ref, dir, title, payload);
85439
+ } catch (err) {
85440
+ reasons.push(err.message);
85441
+ }
85442
+ }
85443
+ return { dir, title, reasons, payload: published };
85444
+ };
85445
+ const cloud = options.cloud && options.configFile ? createCloudRoutes({ ...options.cloud, configFile: options.configFile, port: () => port, inspect }) : null;
84464
85446
  const sameOrigin = (req) => {
84465
85447
  const origin2 = req.headers.origin;
84466
85448
  const host = req.headers.host ?? "";
@@ -84568,17 +85550,17 @@ async function startArtifactsServer(options) {
84568
85550
  send(res, 404, "Not found");
84569
85551
  return;
84570
85552
  }
84571
- const page = ref.type === "html" ? relative === "index.html" : ref.type === "document" && relative.endsWith(".html");
84572
- const headers = { "Content-Security-Policy": CONTENT_CSP[page ? "html" : ref.type], "Access-Control-Allow-Origin": "*" };
85553
+ const page = ref.type === "html" ? relative === "index.html" : relative.endsWith(".html");
85554
+ const headers = { "Content-Security-Policy": CONTENT_CSP[page && ref.type === "document" ? "html" : ref.type], "Access-Control-Allow-Origin": "*" };
84573
85555
  if (!page) {
84574
85556
  sendFile(res, target, headers);
84575
85557
  return;
84576
85558
  }
84577
- import_node_fs11.default.readFile(target, "utf8", (err, source) => {
85559
+ import_node_fs15.default.readFile(target, "utf8", (err, source) => {
84578
85560
  if (err) send(res, 404, "Not found");
84579
85561
  else {
84580
85562
  const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
84581
- send(res, 200, injectRuntime(source, { uiRuntimeUrl, embedded: ref.type === "document" }), { "Content-Type": "text/html; charset=utf-8", ...headers });
85563
+ send(res, 200, injectRuntime(source, { uiRuntimeUrl, embedded: ref.type === "document", inspector: ref.type === "artboard" }), { "Content-Type": "text/html; charset=utf-8", ...headers });
84582
85564
  }
84583
85565
  });
84584
85566
  };
@@ -84657,6 +85639,12 @@ async function startArtifactsServer(options) {
84657
85639
  else serveContent(res, pathname.slice(contentPrefix.length));
84658
85640
  return;
84659
85641
  }
85642
+ if (cloud && pathname === "/api/cloud/callback") {
85643
+ void cloud.handleCallback(url2, res).catch((err) => {
85644
+ if (!res.headersSent) send(res, 500, `Artifacts error: ${err.message}`);
85645
+ });
85646
+ return;
85647
+ }
84660
85648
  const key2 = url2.searchParams.get("key");
84661
85649
  if (!isAuthorized(req, key2)) {
84662
85650
  send(res, 403, "Forbidden: open the full artifact link including ?key=");
@@ -84666,6 +85654,15 @@ async function startArtifactsServer(options) {
84666
85654
  serveList(res);
84667
85655
  return;
84668
85656
  }
85657
+ const cloudMatch = cloud?.match(pathname);
85658
+ if (cloud && cloudMatch) {
85659
+ if (req.method !== "GET" && !(key2 !== null && safeEqual(key2, token)) && !sameOrigin(req)) {
85660
+ send(res, 403, "Forbidden");
85661
+ return;
85662
+ }
85663
+ void cloud.handle(req, res, cloudMatch);
85664
+ return;
85665
+ }
84669
85666
  const documentMatch = API_DOCUMENT_ROUTE.exec(pathname);
84670
85667
  if (documentMatch) {
84671
85668
  void serveDocumentApi(req, res, documentMatch[1], documentMatch[2]).catch((err) => {
@@ -84681,7 +85678,7 @@ async function startArtifactsServer(options) {
84681
85678
  if (SHELL_ROUTE.test(pathname) || pathname === "/index.html") {
84682
85679
  const headers = { "Content-Security-Policy": VIEWER_CSP };
84683
85680
  if (key2 !== null) headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
84684
- sendFile(res, import_node_path11.default.join(viewerDir, "index.html"), headers);
85681
+ sendFile(res, import_node_path15.default.join(viewerDir, "index.html"), headers);
84685
85682
  return;
84686
85683
  }
84687
85684
  const target = resolveInside(viewerDir, pathname.slice(1));
@@ -84720,7 +85717,7 @@ async function startArtifactsServer(options) {
84720
85717
  port = await listen(server, options.host, 0);
84721
85718
  }
84722
85719
  cookieName = `ryugi_artifacts_${port}`;
84723
- import_node_fs11.default.writeFileSync(portFile, `${port}
85720
+ import_node_fs15.default.writeFileSync(portFile, `${port}
84724
85721
  `, { mode: 384 });
84725
85722
  const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
84726
85723
  const url = `${origin}/?key=${token}`;
@@ -84746,7 +85743,7 @@ async function startArtifactsServer(options) {
84746
85743
  initialChanges.push({ ref: entry, payload, files: [] });
84747
85744
  if (entry.type === "document") void documents.open(entry.id);
84748
85745
  }
84749
- writeJsonAtomic(import_node_path11.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
85746
+ writeJsonAtomic(import_node_path15.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
84750
85747
  const watcher = watchTree(
84751
85748
  root,
84752
85749
  (files) => {
@@ -84801,10 +85798,11 @@ async function startArtifactsServer(options) {
84801
85798
  }
84802
85799
 
84803
85800
  // src/server/lifecycle.ts
84804
- var import_node_fs12 = __toESM(require("node:fs"), 1);
85801
+ var import_node_fs16 = __toESM(require("node:fs"), 1);
84805
85802
  var DEFAULT_IDLE_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
84806
85803
  var DEFAULT_LIFECYCLE_CHECK_MS = 60 * 1e3;
84807
85804
  var SERVER_ID_ARG = "--artifacts-server-id=";
85805
+ var DEFAULT_CLOUD_ORIGIN = "https://ryugi.innei.dev";
84808
85806
  var positive = (value, fallback) => {
84809
85807
  const n7 = Number(value);
84810
85808
  return Number.isFinite(n7) && n7 > 0 ? n7 : fallback;
@@ -84825,13 +85823,14 @@ function parseEnv(env, argv = []) {
84825
85823
  open: env.ARTIFACTS_OPEN !== "0",
84826
85824
  openCmd: env.ARTIFACTS_OPEN_CMD || null,
84827
85825
  openArtifact: env.ARTIFACTS_OPEN_ARTIFACT || null,
84828
- serverId: serverIdArg ? serverIdArg.slice(SERVER_ID_ARG.length) : null
85826
+ serverId: serverIdArg ? serverIdArg.slice(SERVER_ID_ARG.length) : null,
85827
+ cloudOrigin: (env.RYUGI_CLOUD_ORIGIN || DEFAULT_CLOUD_ORIGIN).replace(/\/+$/, "")
84829
85828
  };
84830
85829
  }
84831
85830
  function readOwners(file) {
84832
85831
  let text;
84833
85832
  try {
84834
- text = import_node_fs12.default.readFileSync(file, "utf8");
85833
+ text = import_node_fs16.default.readFileSync(file, "utf8");
84835
85834
  } catch {
84836
85835
  return [];
84837
85836
  }
@@ -84895,14 +85894,16 @@ function openReady(payload) {
84895
85894
  // src/server/main.ts
84896
85895
  async function main() {
84897
85896
  const config = parseEnv(process.env, process.argv.slice(2));
84898
- const root = import_node_path12.default.resolve(config.root);
84899
- const stateDir = import_node_path12.default.join(root, ".state");
85897
+ const root = import_node_path16.default.resolve(config.root);
85898
+ const stateDir = import_node_path16.default.join(root, ".state");
84900
85899
  const server = await startArtifactsServer({
84901
85900
  root,
84902
- viewerDir: import_node_path12.default.join(__dirname, "viewer"),
84903
- runtimeDir: import_node_path12.default.join(__dirname, "runtime"),
85901
+ viewerDir: import_node_path16.default.join(__dirname, "viewer"),
85902
+ runtimeDir: import_node_path16.default.join(__dirname, "runtime"),
84904
85903
  host: config.host,
84905
- urlHost: config.urlHost
85904
+ urlHost: config.urlHost,
85905
+ configFile: import_node_path16.default.join(import_node_path16.default.dirname(root), "config.json"),
85906
+ cloud: { origin: config.cloudOrigin, credentialsFile: credentialsFile(process.env, process.platform, import_node_os.default.homedir()) }
84906
85907
  });
84907
85908
  let lastActivity = Date.now();
84908
85909
  server.onActivity(() => {
@@ -84927,12 +85928,12 @@ async function main() {
84927
85928
  });
84928
85929
  const shutdown = async (reason) => {
84929
85930
  console.log(JSON.stringify({ type: "server-stopped", reason }));
84930
- import_node_fs13.default.rmSync(import_node_path12.default.join(stateDir, "server-info"), { force: true });
84931
- writeJsonAtomic(import_node_path12.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
85931
+ import_node_fs17.default.rmSync(import_node_path16.default.join(stateDir, "server-info"), { force: true });
85932
+ writeJsonAtomic(import_node_path16.default.join(stateDir, "server-stopped"), { reason, timestamp: Date.now() });
84932
85933
  await server.close();
84933
85934
  process.exit(0);
84934
85935
  };
84935
- const ownersFile = import_node_path12.default.join(stateDir, "owners");
85936
+ const ownersFile = import_node_path16.default.join(stateDir, "owners");
84936
85937
  const timer = setInterval(() => {
84937
85938
  const owners = readOwners(ownersFile);
84938
85939
  const reason = shutdownReason({
@@ -84946,7 +85947,7 @@ async function main() {
84946
85947
  timer.unref();
84947
85948
  process.on("SIGTERM", () => void shutdown("SIGTERM"));
84948
85949
  process.on("SIGINT", () => void shutdown("SIGINT"));
84949
- import_node_fs13.default.rmSync(import_node_path12.default.join(stateDir, "server-stopped"), { force: true });
85950
+ import_node_fs17.default.rmSync(import_node_path16.default.join(stateDir, "server-stopped"), { force: true });
84950
85951
  console.log(JSON.stringify({ type: "server-started", url: server.url, port: server.port, root }));
84951
85952
  }
84952
85953
  main().catch((err) => {