ryugi-artifacts 1.47.0 → 1.48.1

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 (242) hide show
  1. package/dist/cli.cjs +34 -83
  2. package/dist/server.cjs +277 -134
  3. package/dist/viewer/ArtboardLayout-KQmamERB.js +12 -0
  4. package/dist/viewer/ArtifactList-BX7uyG0a.js +1 -0
  5. package/dist/viewer/{AutoPublishPrompt-DMbPBIa7.js → AutoPublishPrompt-hLdShrr1.js} +1 -1
  6. package/dist/viewer/{Avatar-sJ6BwmM4.js → Avatar-dVuGXaGv.js} +1 -1
  7. package/dist/viewer/{Canvas-BRcbK9Oh.js → Canvas-DR9g_0g-.js} +1 -1
  8. package/dist/viewer/DocumentLayout-BGmMGPWu.js +2 -0
  9. package/dist/viewer/{DocumentPage-tHCa_QBi.js → DocumentPage-C7pveaCL.js} +3 -3
  10. package/dist/viewer/{HtmlLayout-zDyQayIW.js → HtmlLayout-DN_RC8ER.js} +1 -1
  11. package/dist/viewer/{MenuSubmenuTrigger-DbKKTh4p.js → MenuSubmenuTrigger-COtUZ7rK.js} +1 -1
  12. package/dist/viewer/{PopoverPopup-DCSCUVit.js → PopoverPopup-DbicV8QT.js} +1 -1
  13. package/dist/viewer/PreviewLayout-bKeGBF-n.js +2 -0
  14. package/dist/viewer/{Select-s1rLjxSD.js → Select-CyQRjxXp.js} +1 -1
  15. package/dist/viewer/{SelectScrollUpArrow-Bf8GSGJi.js → SelectScrollUpArrow-BquMl3kO.js} +1 -1
  16. package/dist/viewer/{SettingsDialog-CtG16kqq.js → SettingsDialog-DALEpAnA.js} +1 -1
  17. package/dist/viewer/{SnapshotDocument-C6M98-Xm.js → SnapshotDocument-B4d-X_r-.js} +1 -1
  18. package/dist/viewer/{Switch-CiQE6IIA.js → Switch-C9DrBYMm.js} +1 -1
  19. package/dist/viewer/{TooltipPopup-3z_XuZz6.js → TooltipPopup-BRiHjngV.js} +1 -1
  20. package/dist/viewer/{VirtualizedEditor-D9Ivycdp-C2midg2t.js → VirtualizedEditor-D9Ivycdp-D5vZigul.js} +1 -1
  21. package/dist/viewer/{VirtualizedRenderer-C_d95FXi-CjilBxHD.js → VirtualizedRenderer-C_d95FXi-jDSvsO_S.js} +1 -1
  22. package/dist/viewer/{WarningsBadge-CwTzz_8O.js → WarningsBadge-Dq9MCOka.js} +1 -1
  23. package/dist/viewer/{abnfDiagram-VCTEODGH-B8FH4uyq.js → abnfDiagram-VCTEODGH-DvH3n-ag.js} +1 -1
  24. package/dist/viewer/{ar-SA-G6X2FPQ2-G-dKeKsf.js → ar-SA-G6X2FPQ2-D11wBsfI.js} +1 -1
  25. package/dist/viewer/{architecture-7GRP2DOG-BDHw3fSb.js → architecture-7GRP2DOG-getNBIXu.js} +1 -1
  26. package/dist/viewer/{architectureDiagram-5GKGNRK7-CaMlHVkz.js → architectureDiagram-5GKGNRK7-DacvQVV0.js} +1 -1
  27. package/dist/viewer/{atoms-C-iIWE8G.js → atoms-DfNSS4CQ.js} +2 -2
  28. package/dist/viewer/{az-AZ-76LH7QW2-DksynjeT.js → az-AZ-76LH7QW2-DmjLQk0z.js} +1 -1
  29. package/dist/viewer/{bg-BG-XCXSNQG7-3bPdXQKI.js → bg-BG-XCXSNQG7-Dq5qUQzr.js} +1 -1
  30. package/dist/viewer/{blockDiagram-I7D4REHJ-DBEfOaV6.js → blockDiagram-I7D4REHJ-DYFZvVtR.js} +1 -1
  31. package/dist/viewer/{bn-BD-2XOGV67Q-DBOxHyif.js → bn-BD-2XOGV67Q-CB5ihzW3.js} +1 -1
  32. package/dist/viewer/{c4Diagram-7LVT6UL2-DypJ8XID.js → c4Diagram-7LVT6UL2-CItIeFst.js} +1 -1
  33. package/dist/viewer/{ca-ES-6MX7JW3Y-eQQJVA5S.js → ca-ES-6MX7JW3Y-B1vvpFRz.js} +1 -1
  34. package/dist/viewer/{channel-Ci7EBqIH.js → channel-NSE57aBD.js} +9 -9
  35. package/dist/viewer/channel-tQ-5o9x1.js +1 -0
  36. package/dist/viewer/{chunk-4HAMMTFA-CPW78UTT.js → chunk-4HAMMTFA-BXjvEkTf.js} +1 -1
  37. package/dist/viewer/{chunk-75Z2AOVW-Eg087bVQ.js → chunk-75Z2AOVW-Cp5QYgru.js} +1 -1
  38. package/dist/viewer/{chunk-DU6HZSFF-CfZf-GY2.js → chunk-DU6HZSFF-Co37jFu9.js} +1 -1
  39. package/dist/viewer/{chunk-EIO257PC-CH0xWeCX.js → chunk-EIO257PC-BzoJi82T.js} +1 -1
  40. package/dist/viewer/{chunk-F27PBJKO-BgYz98-j.js → chunk-F27PBJKO-SOAeS3VX.js} +1 -1
  41. package/dist/viewer/{chunk-GMAD6QVW--aiwO7Dy.js → chunk-GMAD6QVW-Ozh-1h9J.js} +1 -1
  42. package/dist/viewer/{chunk-GVQU2GXP-8IoaKmow.js → chunk-GVQU2GXP-DPXdyMxy.js} +1 -1
  43. package/dist/viewer/{chunk-IMKFNOWR-B8zIyzHy.js → chunk-IMKFNOWR-D3-fYgRw.js} +1 -1
  44. package/dist/viewer/{chunk-L3NEJ4N5-BG153wzp.js → chunk-L3NEJ4N5-CsXfjxgF.js} +1 -1
  45. package/dist/viewer/{chunk-OSK3NFVY-kL1QnHSt.js → chunk-OSK3NFVY-33dYvZp0.js} +1 -1
  46. package/dist/viewer/{chunk-P2QGCYS3-DaSq0O1p.js → chunk-P2QGCYS3-3KdzOSkK.js} +1 -1
  47. package/dist/viewer/{chunk-POPQ4Y6H-DoMhff9f.js → chunk-POPQ4Y6H-DLxpEPms.js} +1 -1
  48. package/dist/viewer/{chunk-PWAF6VOD-DPNah1Nl.js → chunk-PWAF6VOD-JePqG5w3.js} +1 -1
  49. package/dist/viewer/{chunk-SHT3W25Y-D4Ix0weD.js → chunk-SHT3W25Y-D83tEMVR.js} +1 -1
  50. package/dist/viewer/{chunk-SVP7TREG-CFsWFQLo.js → chunk-SVP7TREG-B1VK1C1g.js} +1 -1
  51. package/dist/viewer/{chunk-TICWLB2K-DUDaM3ko.js → chunk-TICWLB2K-Cn0lQFgz.js} +1 -1
  52. package/dist/viewer/classDiagram-ZZMXUADV-CbZZST1l.js +1 -0
  53. package/dist/viewer/classDiagram-v2-VYDZK3BY-CbZZST1l.js +1 -0
  54. package/dist/viewer/{cs-CZ-2BRQDIVT-BKYK1gJC.js → cs-CZ-2BRQDIVT-CMWJYUvu.js} +1 -1
  55. package/dist/viewer/{cynefin-OW5HDTMX-DKQm7set.js → cynefin-OW5HDTMX-Cg5yzGfm.js} +1 -1
  56. package/dist/viewer/{cynefinDiagram-5FMLGOSQ-BTLYyESY.js → cynefinDiagram-5FMLGOSQ-DosdMrh6.js} +1 -1
  57. package/dist/viewer/{da-DK-5WZEPLOC-BDQOs5QW.js → da-DK-5WZEPLOC-D64URQaK.js} +1 -1
  58. package/dist/viewer/{dagre-GXQ25YYZ-BReLfRXY.js → dagre-GXQ25YYZ-CTCCaVFG.js} +1 -1
  59. package/dist/viewer/{de-DE-XR44H4JA-DnO-n72L.js → de-DE-XR44H4JA-41XC-cAS.js} +1 -1
  60. package/dist/viewer/{diagram-S7CK7UJ4-CIpJgK0W.js → diagram-S7CK7UJ4-CxwnLwpO.js} +1 -1
  61. package/dist/viewer/{diagram-UQ7AKVKN-BAmnr00y.js → diagram-UQ7AKVKN-AcI8HsSg.js} +1 -1
  62. package/dist/viewer/{diagram-VSXAHHWV-yXfFdEzV.js → diagram-VSXAHHWV-DlvGSQbP.js} +1 -1
  63. package/dist/viewer/{diagram-VX7I27RA-DK6fKObi.js → diagram-VX7I27RA-BbKISGj6.js} +1 -1
  64. package/dist/viewer/{diagram-Z3DM3KII-CcjaP-Wb.js → diagram-Z3DM3KII-DNwxN4s8.js} +1 -1
  65. package/dist/viewer/{dist-Bq1g2ZBY.js → dist-BAhKEC7v.js} +1 -1
  66. package/dist/viewer/{dist-34Z5y-sW.js → dist-BPuOQwgt.js} +1 -1
  67. package/dist/viewer/{dist-CMOQFuRH.js → dist-BR3etSjd.js} +1 -1
  68. package/dist/viewer/{dist-DcHSVaY8.js → dist-BtMYPQ-R.js} +4 -4
  69. package/dist/viewer/{dist-Cao1XXjH.js → dist-Bxn9izx8.js} +1 -1
  70. package/dist/viewer/{dist-CvYwMJzs.js → dist-C89I1Syb.js} +1 -1
  71. package/dist/viewer/{dist-vA7Qcthq.js → dist-C8gjGXlt.js} +1 -1
  72. package/dist/viewer/{dist-krnWQQrk.js → dist-CCpihLKc.js} +1 -1
  73. package/dist/viewer/{dist-CJTFllzN.js → dist-CaHvwSHf.js} +1 -1
  74. package/dist/viewer/{dist-C6kyd9D5.js → dist-Cd5E_SnD.js} +1 -1
  75. package/dist/viewer/{dist-DEGw8J87.js → dist-ChkKwRhM.js} +1 -1
  76. package/dist/viewer/{dist-DPhrPdn7.js → dist-CjRmmbjs.js} +1 -1
  77. package/dist/viewer/{dist-DucsqYIQ.js → dist-Cl-9gKYC.js} +1 -1
  78. package/dist/viewer/{dist-Hq0lXHyb.js → dist-CsaZKHv_.js} +1 -1
  79. package/dist/viewer/{dist-DeA2ZVNf.js → dist-D5nVsU3q.js} +1 -1
  80. package/dist/viewer/{dist-C89SuqnV.js → dist-D8In6BWy.js} +1 -1
  81. package/dist/viewer/{dist-kKmy1XoA.js → dist-DHiNxYl_.js} +1 -1
  82. package/dist/viewer/{dist-yJb9Vu52.js → dist-DY-Y4Me7.js} +1 -1
  83. package/dist/viewer/{dist-BIRjT5Cm.js → dist-DfgStcdq.js} +1 -1
  84. package/dist/viewer/{dist-DNgj5LJI.js → dist-Do_avVXy.js} +1 -1
  85. package/dist/viewer/{dist-DU1DaNRm.js → dist-DznxxRh9.js} +1 -1
  86. package/dist/viewer/{dist-DT-JP7sR.js → dist-WPS0bgUa.js} +1 -1
  87. package/dist/viewer/{dist-CJ_Cksaa.js → dist-u7oPbGhJ.js} +1 -1
  88. package/dist/viewer/{dist-NMoHUAGb.js → dist-wui1iR0t.js} +1 -1
  89. package/dist/viewer/{ebnfDiagram-PWID7BFC-BMm9lHLY.js → ebnfDiagram-PWID7BFC-LIQ-mL74.js} +1 -1
  90. package/dist/viewer/{el-GR-BZB4AONW-D7unzbhC.js → el-GR-BZB4AONW-nf4SIDWy.js} +1 -1
  91. package/dist/viewer/{en-B4ZKOASM-CWe-bLtn.js → en-B4ZKOASM-C3uSsrzN.js} +1 -1
  92. package/dist/viewer/{erDiagram-RLTQ6QDP-DN9VJJci.js → erDiagram-RLTQ6QDP-CtP4cA8a.js} +1 -1
  93. package/dist/viewer/{es-ES-U4NZUMDT-Bvlm0b7z.js → es-ES-U4NZUMDT-D83QBRdb.js} +1 -1
  94. package/dist/viewer/{eu-ES-A7QVB2H4-B5LYsQUM.js → eu-ES-A7QVB2H4-C1SzxCFV.js} +1 -1
  95. package/dist/viewer/{eventmodeling-NTZA5JFV-3zELSLwV.js → eventmodeling-NTZA5JFV-Dzz8QjX3.js} +1 -1
  96. package/dist/viewer/{fa-IR-HGAKTJCU-ByVwwvt0.js → fa-IR-HGAKTJCU-DJ75mace.js} +1 -1
  97. package/dist/viewer/{fi-FI-Z5N7JZ37-B02R6zbK.js → fi-FI-Z5N7JZ37-D0oIoDPa.js} +1 -1
  98. package/dist/viewer/flowDiagram-HODETNUW-Z8rwwmKe.js +1 -0
  99. package/dist/viewer/{fr-FR-RHASNOE6-DU5uEvk0.js → fr-FR-RHASNOE6-CxrYpwSQ.js} +1 -1
  100. package/dist/viewer/{ganttDiagram-EL5Y4UJY-B6Swc8hj.js → ganttDiagram-EL5Y4UJY-Dm_GsqHo.js} +1 -1
  101. package/dist/viewer/{gitGraph-4MIJSDKK-DzPv0N39.js → gitGraph-4MIJSDKK-Cmsi3QFW.js} +1 -1
  102. package/dist/viewer/{gitGraphDiagram-WWUBYQGX-BfB2YcQN.js → gitGraphDiagram-WWUBYQGX-pE4QOFt6.js} +1 -1
  103. package/dist/viewer/{gl-ES-HMX3MZ6V-Bknu-aK_.js → gl-ES-HMX3MZ6V-W_AoCFMi.js} +1 -1
  104. package/dist/viewer/{he-IL-6SHJWFNN-DvF-jE5l.js → he-IL-6SHJWFNN-iVqaubIb.js} +1 -1
  105. package/dist/viewer/{hi-IN-IWLTKZ5I-BwE5Vdy-.js → hi-IN-IWLTKZ5I-BCJYxdcu.js} +1 -1
  106. package/dist/viewer/{hu-HU-A5ZG7DT2-DC5IoPMr.js → hu-HU-A5ZG7DT2-D_ufjwGq.js} +1 -1
  107. package/dist/viewer/{id-ID-SAP4L64H-BQQOVK8S.js → id-ID-SAP4L64H-ByGvK2Qg.js} +1 -1
  108. package/dist/viewer/{image-GAAHSSAO-B5FAAqHd.js → image-GAAHSSAO-DIF9SQU_.js} +1 -1
  109. package/dist/viewer/{imperative-BnxnQwIX.js → imperative-ChsionQQ.js} +1 -1
  110. package/dist/viewer/index.html +6 -6
  111. package/dist/viewer/index.js +2 -2
  112. package/dist/viewer/{info-A6RAGUB7-DObaDBqg.js → info-A6RAGUB7-CNgClLVH.js} +1 -1
  113. package/dist/viewer/{infoDiagram-27XIBGKW-Ci1G0del.js → infoDiagram-27XIBGKW-BZqe2QYh.js} +1 -1
  114. package/dist/viewer/{isElementDisabled-DPhqCAQ0.js → isElementDisabled-f0m04fH6.js} +1 -1
  115. package/dist/viewer/{ishikawaDiagram-5VMMS53U-B-_DVyWy.js → ishikawaDiagram-5VMMS53U-DVh4zNCI.js} +1 -1
  116. package/dist/viewer/{it-IT-JPQ66NNP-CIRzYaKh.js → it-IT-JPQ66NNP-Dv6_nr0a.js} +1 -1
  117. package/dist/viewer/{ja-JP-DBVTYXUO-DNw7FEG3.js → ja-JP-DBVTYXUO-KZ9e7KAQ.js} +1 -1
  118. package/dist/viewer/{journeyDiagram-3NMN7TZE-BmXpZge8.js → journeyDiagram-3NMN7TZE-Hrs-56h0.js} +1 -1
  119. package/dist/viewer/{kaa-6HZHGXH3-BYMal1K6.js → kaa-6HZHGXH3-D811ofJi.js} +1 -1
  120. package/dist/viewer/{kab-KAB-ZGHBKWFO-DD1uWHLa.js → kab-KAB-ZGHBKWFO-8_E4WiNI.js} +1 -1
  121. package/dist/viewer/{kanban-definition-UXKFOSKX-qtW-l6On.js → kanban-definition-UXKFOSKX-DDV_2Nle.js} +1 -1
  122. package/dist/viewer/{kk-KZ-P5N5QNE5-BP7tR0-R.js → kk-KZ-P5N5QNE5-XH-ncBcx.js} +1 -1
  123. package/dist/viewer/{km-KH-HSX4SM5Z-BocR_B80.js → km-KH-HSX4SM5Z-DfuMBSsH.js} +1 -1
  124. package/dist/viewer/{ko-KR-MTYHY66A-DDzKDqBI.js → ko-KR-MTYHY66A-UTuAQHeO.js} +1 -1
  125. package/dist/viewer/{ku-TR-6OUDTVRD-Df99BvvZ.js → ku-TR-6OUDTVRD-B6cXUJdZ.js} +1 -1
  126. package/dist/viewer/{lt-LT-XHIRWOB4-BRTkJx8W.js → lt-LT-XHIRWOB4-osfVDYh4.js} +1 -1
  127. package/dist/viewer/{lv-LV-5QDEKY6T-D2FIwSIq.js → lv-LV-5QDEKY6T-owEwthaJ.js} +1 -1
  128. package/dist/viewer/{mermaid-parser.core-Bn4VLJH2.js → mermaid-parser.core-D7qGh1wC.js} +3 -3
  129. package/dist/viewer/{mindmap-definition-YA3MSWOX-Ns9W_dM6.js → mindmap-definition-YA3MSWOX-CEjQFlyO.js} +1 -1
  130. package/dist/viewer/{motion-BjbNPUCa.js → motion-i-14Q28p.js} +1 -1
  131. package/dist/viewer/{mr-IN-CRQNXWMA-pFSqGIla.js → mr-IN-CRQNXWMA-Ble9F94R.js} +1 -1
  132. package/dist/viewer/{my-MM-5M5IBNSE-BJkXPRLV.js → my-MM-5M5IBNSE-CaN6NJFL.js} +1 -1
  133. package/dist/viewer/{nb-NO-T6EIAALU-8CumXBsx.js → nb-NO-T6EIAALU-BDiEiYiE.js} +1 -1
  134. package/dist/viewer/{nl-NL-IS3SIHDZ-z2dABa5l.js → nl-NL-IS3SIHDZ-C0QmOZo_.js} +1 -1
  135. package/dist/viewer/{nn-NO-6E72VCQL-Cv6FIS7h.js → nn-NO-6E72VCQL-CQAbAV7N.js} +1 -1
  136. package/dist/viewer/{oc-FR-POXYY2M6-Bn4Vpssx.js → oc-FR-POXYY2M6-00g3KTwj.js} +1 -1
  137. package/dist/viewer/{pa-IN-N4M65BXN-C0ml9H6B.js → pa-IN-N4M65BXN-zKA1yqPY.js} +1 -1
  138. package/dist/viewer/{packet-AYTQ26CC-Bgc4xsy7.js → packet-AYTQ26CC-Bbo7YLwV.js} +1 -1
  139. package/dist/viewer/{pegDiagram-XKGWAZYB-CNEuS3Em.js → pegDiagram-XKGWAZYB-Bva2VVTO.js} +1 -1
  140. package/dist/viewer/percentages-BXMCSKIN-B9m0MHwS.js +1 -0
  141. package/dist/viewer/{pie-WAS4IAKB-CfkFfG-Z.js → pie-WAS4IAKB-DR-1NEAB.js} +1 -1
  142. package/dist/viewer/{pieDiagram-E7YTZNPT-CjuArQr5.js → pieDiagram-E7YTZNPT-DHxiq9Xw.js} +1 -1
  143. package/dist/viewer/{pl-PL-T2D74RX3-CPNtMC-7.js → pl-PL-T2D74RX3-Ds5hI1PP.js} +1 -1
  144. package/dist/viewer/preview.html +4 -4
  145. package/dist/viewer/preview.js +1 -1
  146. package/dist/viewer/{prod-DkgTkPT0.js → prod-Bxq8Vdzv.js} +12 -12
  147. package/dist/viewer/{pt-BR-5N22H2LF-Df-iaFJF.js → pt-BR-5N22H2LF-D7XJA5jJ.js} +1 -1
  148. package/dist/viewer/{pt-PT-UZXXM6DQ-Dkn6lidV.js → pt-PT-UZXXM6DQ-uJtX9Kj1.js} +1 -1
  149. package/dist/viewer/{quadrantDiagram-AXDQQJYC-iw0683GO.js → quadrantDiagram-AXDQQJYC-C8X4P0Un.js} +1 -1
  150. package/dist/viewer/{radar-RG4KPBEZ-DlyWbVXF.js → radar-RG4KPBEZ-B2Nkysmm.js} +1 -1
  151. package/dist/viewer/{railroad-74A4TZTK-COQW-__X.js → railroad-74A4TZTK-CqyegNhY.js} +1 -1
  152. package/dist/viewer/{railroad-abnf-HS5TGJTU-k4rmb6Ba.js → railroad-abnf-HS5TGJTU-D437JbRt.js} +1 -1
  153. package/dist/viewer/{railroad-ebnf-LZEXJU2U-6xlClmJB.js → railroad-ebnf-LZEXJU2U-Cfjp24wu.js} +1 -1
  154. package/dist/viewer/{railroad-peg-WCYAUIDC-CbchexCP.js → railroad-peg-WCYAUIDC-DFKq1m4V.js} +1 -1
  155. package/dist/viewer/{railroadDiagram-O6MQD6OU-DS-Bm6d_.js → railroadDiagram-O6MQD6OU-Bi0WDKNl.js} +1 -1
  156. package/dist/viewer/{requirementDiagram-BXWQKSXE-BINydeED.js → requirementDiagram-BXWQKSXE-CPxbWN0o.js} +1 -1
  157. package/dist/viewer/{ro-RO-JPDTUUEW-DdRvNm-I.js → ro-RO-JPDTUUEW-CahCeDzl.js} +1 -1
  158. package/dist/viewer/{route-B5bzKpud.js → route-w3PXrIFf.js} +1 -1
  159. package/dist/viewer/{ru-RU-B4JR7IUQ-CjNIRk4D.js → ru-RU-B4JR7IUQ-CqoxmaXz.js} +1 -1
  160. package/dist/viewer/{sankeyDiagram-P5KCCOFB-Df0U_V9p.js → sankeyDiagram-P5KCCOFB-DZw6r51H.js} +1 -1
  161. package/dist/viewer/{selection-Bv5ssed6.js → selection-BWAAa3tl.js} +1 -1
  162. package/dist/viewer/{sequenceDiagram-WJ2MYXX4-CwZzTbw6.js → sequenceDiagram-WJ2MYXX4-Thge-udC.js} +1 -1
  163. package/dist/viewer/{settings-dialog-oqRBz3HH.js → settings-dialog-CsUVMGkR.js} +1 -1
  164. package/dist/viewer/{si-LK-N5RQ5JYF-Bn2cq5Ok.js → si-LK-N5RQ5JYF-LdkAa2Ul.js} +1 -1
  165. package/dist/viewer/{sk-SK-C5VTKIMK-DkQagVs8.js → sk-SK-C5VTKIMK-CKX2GUNt.js} +1 -1
  166. package/dist/viewer/{sl-SI-NN7IZMDC-DWUkw9Es.js → sl-SI-NN7IZMDC-CzFyYKkG.js} +1 -1
  167. package/dist/viewer/{stateDiagram-D77RDMKH-DVyBdMso.js → stateDiagram-D77RDMKH-BIRU_cq9.js} +1 -1
  168. package/dist/viewer/stateDiagram-v2-MP3YSRHH-W6GM4mdH.js +1 -0
  169. package/dist/viewer/subset-shared.chunk-e43yvG81.js +1 -0
  170. package/dist/viewer/{subset-worker.chunk-B8oo_rFu.js → subset-worker.chunk-DnTcanba.js} +1 -1
  171. package/dist/viewer/{sv-SE-XGPEYMSR-Bwrn5pou.js → sv-SE-XGPEYMSR-DNC_mUSl.js} +1 -1
  172. package/dist/viewer/{swimlanes-42K2YHIH-DeoVqdEH.js → swimlanes-42K2YHIH-CjgoNxpA.js} +1 -1
  173. package/dist/viewer/swimlanesDiagram-VR7AAH4N-D5-PU8Pf.js +8 -0
  174. package/dist/viewer/{ta-IN-2NMHFXQM-oEgUCuIa.js → ta-IN-2NMHFXQM-CYr9ZGr1.js} +1 -1
  175. package/dist/viewer/{th-TH-HPSO5L25-CxPlzxKw.js → th-TH-HPSO5L25-C6bnXArK.js} +1 -1
  176. package/dist/viewer/{timeline-definition-24CTP7MA-mwiqh6_R.js → timeline-definition-24CTP7MA-B9JpbwqJ.js} +1 -1
  177. package/dist/viewer/{tr-TR-DEFEU3FU-7uH4wvY7.js → tr-TR-DEFEU3FU-BYGOia6c.js} +1 -1
  178. package/dist/viewer/{treeView-Q6P3EWNA-C2ArJ2Q4.js → treeView-Q6P3EWNA-Ak-ne88N.js} +1 -1
  179. package/dist/viewer/{treemap-WGGIJYW6-Vy7-EYOO.js → treemap-WGGIJYW6-DXjq0Uxk.js} +1 -1
  180. package/dist/viewer/{type-icons-BmaAIhru.js → type-icons-DfzR1Nvz.js} +1 -1
  181. package/dist/viewer/{uk-UA-QMV73CPH-SGNVkCzl.js → uk-UA-QMV73CPH-Dqls9x9N.js} +1 -1
  182. package/dist/viewer/{useOpenInteractionType-BS_27F88.js → useOpenInteractionType-DVZ9bVwU.js} +1 -1
  183. package/dist/viewer/{useTranslation-BaBmKQ5R.js → useTranslation-D91FrcSE.js} +1 -1
  184. package/dist/viewer/{useTypeFavicon-DVTP7TWI.js → useTypeFavicon-DV0oFcwK.js} +1 -1
  185. package/dist/viewer/{vennDiagram-4TSXK5OY-DCAXQgUU.js → vennDiagram-4TSXK5OY-CaR9-X17.js} +1 -1
  186. package/dist/viewer/{vi-VN-M7AON7JQ-ilE0ydgZ.js → vi-VN-M7AON7JQ-Hm3jAJrG.js} +1 -1
  187. package/dist/viewer/view-Dzqqcsok.js +1 -0
  188. package/dist/viewer/{viewport-CFJHn_Y6-CZ2u5hxC.js → viewport-CFJHn_Y6-CyNXuhKV.js} +1 -1
  189. package/dist/viewer/{wardley-WFR3VGLG-B5mJzBH-.js → wardley-WFR3VGLG-B8O3gzU6.js} +1 -1
  190. package/dist/viewer/{wardleyDiagram-VM6X3IG4-Bb0cqjgf.js → wardleyDiagram-VM6X3IG4-CkGcY15o.js} +1 -1
  191. package/dist/viewer/{xychartDiagram-S5SC5T6Z-D0eoP4oC.js → xychartDiagram-S5SC5T6Z-NfDIUsFv.js} +1 -1
  192. package/dist/viewer/{zh-CN-LNUGB5OW-BtfqsQSW.js → zh-CN-LNUGB5OW-DfOZAHSW.js} +1 -1
  193. package/dist/viewer/{zh-HK-E62DVLB3-4UGVsAFf.js → zh-HK-E62DVLB3-BGA8Pz-Y.js} +1 -1
  194. package/dist/viewer/{zh-TW-RAJ6MFWO-ChXgRlLr.js → zh-TW-RAJ6MFWO-p--eir4S.js} +1 -1
  195. package/dist/viewer-lib/{Canvas-CsAyNFlN.js → Canvas-aHZz21RV.js} +223 -188
  196. package/dist/viewer-lib/{PreviewView-DrA6Vyn8.js → PreviewView-Dhif0ukY.js} +63 -104
  197. package/dist/viewer-lib/core.js +3 -3
  198. package/dist/viewer-lib/ids.js +40 -0
  199. package/dist/viewer-lib/index.js +2322 -2536
  200. package/dist/viewer-lib/types/src/shared/ids.d.ts +2 -0
  201. package/dist/viewer-lib/types/src/shared/relay.d.ts +2 -1
  202. package/dist/viewer-lib/types/src/viewer/components/Canvas.d.ts +17 -9
  203. package/dist/viewer-lib/types/src/viewer/components/DebugHud.d.ts +12 -4
  204. package/dist/viewer-lib/types/src/viewer/components/EmbeddedCanvas.d.ts +6 -0
  205. package/dist/viewer-lib/types/src/viewer/components/ExpandedBoard.d.ts +2 -1
  206. package/dist/viewer-lib/types/src/viewer/components/PhoneBoard.d.ts +2 -1
  207. package/dist/viewer-lib/types/src/viewer/hooks/useBoardLifecycle.d.ts +28 -0
  208. package/dist/viewer-lib/types/src/viewer/hooks/useBoardOrigin.d.ts +8 -0
  209. package/dist/viewer-lib/types/src/viewer/hooks/useCanvasData.d.ts +2 -0
  210. package/dist/viewer-lib/types/src/viewer/hooks/useCulledBoards.d.ts +6 -0
  211. package/dist/viewer-lib/types/src/viewer/hooks/usePanZoom.d.ts +4 -1
  212. package/dist/viewer-lib/types/src/viewer/layouts/ArtboardView.d.ts +0 -1
  213. package/dist/viewer-lib/types/src/viewer/layouts/PhoneArtboard.d.ts +4 -3
  214. package/dist/viewer-lib/types/src/viewer/lib/board-lifecycle.d.ts +46 -0
  215. package/dist/viewer-lib/types/src/viewer/lib/board-origin.d.ts +21 -0
  216. package/dist/viewer-lib/types/src/viewer/lib/cull.d.ts +14 -0
  217. package/dist/viewer-lib/types/src/viewer/lib/embed-bridge.d.ts +27 -0
  218. package/dist/viewer-lib/types/src/viewer/lib/payload.d.ts +2 -0
  219. package/dist/viewer-lib/types/src/viewer/library/index.d.ts +1 -0
  220. package/package.json +7 -2
  221. package/dist/viewer/ArtboardLayout-BSA9WeVj.js +0 -14
  222. package/dist/viewer/ArtifactList-Bavpjuy4.js +0 -1
  223. package/dist/viewer/DocumentLayout-lHxaL5sP.js +0 -2
  224. package/dist/viewer/PreviewLayout-EAHAJn22.js +0 -2
  225. package/dist/viewer/channel-auni3Ry1.js +0 -1
  226. package/dist/viewer/classDiagram-ZZMXUADV-cNNncaUU.js +0 -1
  227. package/dist/viewer/classDiagram-v2-VYDZK3BY-cNNncaUU.js +0 -1
  228. package/dist/viewer/flowDiagram-HODETNUW--TvHHSmf.js +0 -1
  229. package/dist/viewer/percentages-BXMCSKIN-CZKcCCkO.js +0 -1
  230. package/dist/viewer/stateDiagram-v2-MP3YSRHH-BpgW6a_T.js +0 -1
  231. package/dist/viewer/subset-shared.chunk-CScPtGlu.js +0 -1
  232. package/dist/viewer/swimlanesDiagram-VR7AAH4N-BJ7X1Jzf.js +0 -8
  233. package/dist/viewer/view-DsLeNJwB.js +0 -1
  234. package/dist/viewer-lib/types/src/viewer/hooks/useBoardTiers.d.ts +0 -27
  235. package/dist/viewer-lib/types/src/viewer/hooks/useHoverDwell.d.ts +0 -20
  236. package/dist/viewer-lib/types/src/viewer/hooks/useKeptBoards.d.ts +0 -2
  237. package/dist/viewer-lib/types/src/viewer/lib/board-tiers.d.ts +0 -40
  238. package/dist/viewer-lib/types/src/viewer/lib/hover-dwell.d.ts +0 -18
  239. package/dist/viewer-lib/types/src/viewer/lib/kept-boards.d.ts +0 -7
  240. package/dist/viewer-lib/types/src/viewer/lib/live-limit.d.ts +0 -33
  241. package/dist/viewer-lib/types/src/viewer/lib/snapshot-store.d.ts +0 -41
  242. package/dist/viewer-lib/types/src/viewer/lib/tier-controller.d.ts +0 -28
package/dist/server.cjs CHANGED
@@ -8798,7 +8798,7 @@ var import_node_os2 = __toESM(require("node:os"), 1);
8798
8798
  var import_node_path25 = __toESM(require("node:path"), 1);
8799
8799
 
8800
8800
  // package.json
8801
- var version = "1.47.0";
8801
+ var version = "1.48.1";
8802
8802
 
8803
8803
  // src/server/app.ts
8804
8804
  var import_node_fs26 = __toESM(require("node:fs"), 1);
@@ -8825,6 +8825,24 @@ var ADDRESS_SOURCE = "(?:[\\w-]{21}|[a-f0-9]{32})";
8825
8825
  var ARTIFACT_LOCATOR_SOURCE = `(?:${SLUG_SOURCE}|${ADDRESS_SOURCE})`;
8826
8826
  var ID_PATTERN = new RegExp(`^${SLUG_SOURCE}$`);
8827
8827
  var ADDRESS_PATTERN = new RegExp(`^${ADDRESS_SOURCE}$`);
8828
+ var MINT_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
8829
+ var MINT_LENGTH = 21;
8830
+ var MINTED_PATTERN = new RegExp(`^[a-z0-9]{${MINT_LENGTH}}$`, "i");
8831
+ var MINT_BYTE_LIMIT = 248;
8832
+ function mintArtifactId() {
8833
+ let id2 = "";
8834
+ const bytes = new Uint8Array(MINT_LENGTH * 2);
8835
+ while (id2.length < MINT_LENGTH) {
8836
+ crypto.getRandomValues(bytes);
8837
+ for (const byte of bytes) {
8838
+ if (byte >= MINT_BYTE_LIMIT) continue;
8839
+ id2 += MINT_ALPHABET[byte % MINT_ALPHABET.length];
8840
+ if (id2.length === MINT_LENGTH) break;
8841
+ }
8842
+ }
8843
+ return id2;
8844
+ }
8845
+ var isMintedArtifactId = (id2) => MINTED_PATTERN.test(id2);
8828
8846
  var isArtifactId = (id2) => ID_PATTERN.test(id2);
8829
8847
  var isArtifactAddress = (id2) => ADDRESS_PATTERN.test(id2);
8830
8848
  var isArtifactLocator = (id2) => ID_PATTERN.test(id2) || ADDRESS_PATTERN.test(id2);
@@ -9120,88 +9138,36 @@ function typeFaviconHref(type) {
9120
9138
  return `data:image/svg+xml,${encodeURIComponent(svg)}`;
9121
9139
  }
9122
9140
 
9141
+ // src/server/access.ts
9142
+ var LOOPBACK = /* @__PURE__ */ new Set(["localhost", "::1", "[::1]"]);
9143
+ var isLoopbackHost = (host) => LOOPBACK.has(host) || /^127\.\d+\.\d+\.\d+$/.test(host);
9144
+ var bracket = (host) => host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
9145
+ function accessPolicy({
9146
+ host,
9147
+ urlHost,
9148
+ ports,
9149
+ cloudOrigin
9150
+ }) {
9151
+ const names = [
9152
+ ...new Set(
9153
+ ["localhost", "127.0.0.1", bracket(host), bracket(urlHost)].map((name) => name.toLowerCase())
9154
+ )
9155
+ ];
9156
+ const hosts = new Set(ports.flatMap((port) => names.map((name) => `${name}:${port}`)));
9157
+ const viewerPort = ports[0];
9158
+ const origins = new Set(names.map((name) => `http://${name}:${viewerPort}`));
9159
+ return { loopback: isLoopbackHost(host), hosts, origins, cloudOrigin };
9160
+ }
9161
+ var hostAllowed = (policy, host) => !policy.loopback || host !== void 0 && policy.hosts.has(host.toLowerCase());
9162
+ var originAllowed = (policy, origin, { cloud = false } = {}) => origin === void 0 || policy.origins.has(origin) || cloud && policy.cloudOrigin !== void 0 && origin === policy.cloudOrigin;
9163
+ var navigationAllowed = (secFetchSite) => secFetchSite === void 0 || secFetchSite === "none" || secFetchSite === "same-origin";
9164
+
9123
9165
  // src/server/artifact-address.ts
9124
9166
  var import_node_fs2 = __toESM(require("node:fs"), 1);
9125
9167
  var import_node_path2 = __toESM(require("node:path"), 1);
9126
9168
 
9127
- // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
9128
- var import_node_crypto = require("node:crypto");
9129
-
9130
- // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
9131
- var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
9132
-
9133
- // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
9134
- var POOL_SIZE_MULTIPLIER = 128;
9135
- var pool;
9136
- var poolOffset;
9137
- function fillPool(bytes) {
9138
- if (bytes < 0) throw new RangeError("Wrong ID size");
9139
- try {
9140
- if (!pool || pool.length < bytes) {
9141
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
9142
- import_node_crypto.webcrypto.getRandomValues(pool);
9143
- poolOffset = 0;
9144
- } else if (poolOffset + bytes > pool.length) {
9145
- import_node_crypto.webcrypto.getRandomValues(pool);
9146
- poolOffset = 0;
9147
- }
9148
- } catch (e5) {
9149
- pool = void 0;
9150
- throw e5;
9151
- }
9152
- poolOffset += bytes;
9153
- }
9154
- function random(bytes) {
9155
- fillPool(bytes |= 0);
9156
- return pool.subarray(poolOffset - bytes, poolOffset);
9157
- }
9158
- function customRandom(alphabet, defaultSize, getRandom) {
9159
- let safeByteCutoff = 256 - 256 % alphabet.length;
9160
- if (safeByteCutoff === 256) {
9161
- let mask = alphabet.length - 1;
9162
- return (size = defaultSize) => {
9163
- if (!size) return "";
9164
- let id2 = "";
9165
- while (true) {
9166
- let bytes = getRandom(size);
9167
- let i6 = size;
9168
- while (i6--) {
9169
- id2 += alphabet[bytes[i6] & mask];
9170
- if (id2.length >= size) return id2;
9171
- }
9172
- }
9173
- };
9174
- }
9175
- let step = Math.ceil(1.6 * 256 * defaultSize / safeByteCutoff);
9176
- return (size = defaultSize) => {
9177
- if (!size) return "";
9178
- let id2 = "";
9179
- while (true) {
9180
- let bytes = getRandom(step);
9181
- let i6 = step;
9182
- while (i6--) {
9183
- if (bytes[i6] < safeByteCutoff) {
9184
- id2 += alphabet[bytes[i6] % alphabet.length];
9185
- if (id2.length >= size) return id2;
9186
- }
9187
- }
9188
- }
9189
- };
9190
- }
9191
- function customAlphabet(alphabet, size = 21) {
9192
- return customRandom(alphabet, size, random);
9193
- }
9194
- function nanoid(size = 21) {
9195
- fillPool(size |= 0);
9196
- let id2 = "";
9197
- for (let i6 = poolOffset - size; i6 < poolOffset; i6++) {
9198
- id2 += urlAlphabet[pool[i6] & 63];
9199
- }
9200
- return id2;
9201
- }
9202
-
9203
9169
  // src/server/artifacts.ts
9204
- var import_node_crypto2 = __toESM(require("node:crypto"), 1);
9170
+ var import_node_crypto = __toESM(require("node:crypto"), 1);
9205
9171
  var import_node_fs = __toESM(require("node:fs"), 1);
9206
9172
  var import_node_path = __toESM(require("node:path"), 1);
9207
9173
  function subdirectories(dir) {
@@ -9273,15 +9239,11 @@ function artifactSignature(dir, type) {
9273
9239
  }
9274
9240
  };
9275
9241
  walk(dir);
9276
- const hash = import_node_crypto2.default.createHash("sha1").update(names.sort().join("\0")).digest("hex").slice(0, 12);
9242
+ const hash = import_node_crypto.default.createHash("sha1").update(names.sort().join("\0")).digest("hex").slice(0, 12);
9277
9243
  return `${names.length}:${size}:${latest}:${hash}`;
9278
9244
  }
9279
9245
 
9280
9246
  // src/server/artifact-address.ts
9281
- var newArtifactId = customAlphabet(
9282
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
9283
- 21
9284
- );
9285
9247
  function artifactId(dir) {
9286
9248
  const file = import_node_path2.default.join(dir, ".artifact-id");
9287
9249
  let id2;
@@ -9289,7 +9251,7 @@ function artifactId(dir) {
9289
9251
  id2 = import_node_fs2.default.readFileSync(file, "utf8").trim();
9290
9252
  } catch (err) {
9291
9253
  if (err.code !== "ENOENT") throw err;
9292
- id2 = newArtifactId();
9254
+ id2 = mintArtifactId();
9293
9255
  try {
9294
9256
  import_node_fs2.default.writeFileSync(file, `${id2}
9295
9257
  `, { flag: "wx" });
@@ -9322,7 +9284,7 @@ function resolveArtifactAddress(root, type, address) {
9322
9284
  var import_node_fs5 = __toESM(require("node:fs"), 1);
9323
9285
 
9324
9286
  // src/server/http.ts
9325
- var import_node_crypto3 = __toESM(require("node:crypto"), 1);
9287
+ var import_node_crypto2 = __toESM(require("node:crypto"), 1);
9326
9288
  var import_node_fs3 = __toESM(require("node:fs"), 1);
9327
9289
  var import_node_path3 = __toESM(require("node:path"), 1);
9328
9290
  var MIME = {
@@ -9348,11 +9310,11 @@ var MIME = {
9348
9310
  ".webm": "video/webm"
9349
9311
  };
9350
9312
  var mimeOf = (file) => MIME[import_node_path3.default.extname(file).toLowerCase()] ?? "application/octet-stream";
9351
- var randomToken = () => import_node_crypto3.default.randomBytes(24).toString("base64url");
9313
+ var randomToken = () => import_node_crypto2.default.randomBytes(24).toString("base64url");
9352
9314
  function safeEqual(a5, b6) {
9353
9315
  const ab = Buffer.from(a5);
9354
9316
  const bb = Buffer.from(b6);
9355
- return ab.length === bb.length && import_node_crypto3.default.timingSafeEqual(ab, bb);
9317
+ return ab.length === bb.length && import_node_crypto2.default.timingSafeEqual(ab, bb);
9356
9318
  }
9357
9319
  function parseCookies(header) {
9358
9320
  const cookies = {};
@@ -10559,7 +10521,7 @@ function readArtifactFile(dir, type, relative, uiRuntimeUrl, maxBytes = Infinity
10559
10521
  }
10560
10522
 
10561
10523
  // src/server/auto-publish.ts
10562
- var import_node_crypto4 = __toESM(require("node:crypto"), 1);
10524
+ var import_node_crypto3 = __toESM(require("node:crypto"), 1);
10563
10525
  var import_node_fs7 = __toESM(require("node:fs"), 1);
10564
10526
 
10565
10527
  // src/server/state.ts
@@ -10979,7 +10941,7 @@ function createAutoPublisher(options) {
10979
10941
  });
10980
10942
  const raise = (kind, message, upgradeUrl) => {
10981
10943
  if (notice?.kind !== kind)
10982
- notice = { id: import_node_crypto4.default.randomUUID(), kind, message, ...upgradeUrl ? { upgradeUrl } : {} };
10944
+ notice = { id: import_node_crypto3.default.randomUUID(), kind, message, ...upgradeUrl ? { upgradeUrl } : {} };
10983
10945
  };
10984
10946
  let idleTimer = null;
10985
10947
  let maxTimer = null;
@@ -11082,7 +11044,7 @@ function createAutoPublisher(options) {
11082
11044
  }
11083
11045
 
11084
11046
  // src/server/avatars.ts
11085
- var import_node_crypto5 = require("node:crypto");
11047
+ var import_node_crypto4 = require("node:crypto");
11086
11048
  var AVATAR_ROUTE = /^\/api\/avatar\/([a-z]+)\/([^/]+)$/;
11087
11049
  var MAX_BYTES = 512 * 1024;
11088
11050
  var TIMEOUT_MS = 5e3;
@@ -11097,7 +11059,7 @@ var SOURCES = {
11097
11059
  }
11098
11060
  };
11099
11061
  var githubAvatar = (login) => `/api/avatar/github/${login}`;
11100
- var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto5.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
11062
+ var gravatarAvatar = (email) => `/api/avatar/gravatar/${(0, import_node_crypto4.createHash)("sha256").update(email.trim().toLowerCase()).digest("hex")}`;
11101
11063
  function createAvatars(fetchImpl = fetch) {
11102
11064
  const cache = /* @__PURE__ */ new Map();
11103
11065
  const fetchAvatar = async (url) => {
@@ -11608,6 +11570,44 @@ function createCommentCursors(stateDir, type = "document") {
11608
11570
 
11609
11571
  // src/server/document-comments.ts
11610
11572
  var import_node_fs9 = __toESM(require("node:fs"), 1);
11573
+
11574
+ // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
11575
+ var import_node_crypto5 = require("node:crypto");
11576
+
11577
+ // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
11578
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
11579
+
11580
+ // node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
11581
+ var POOL_SIZE_MULTIPLIER = 128;
11582
+ var pool;
11583
+ var poolOffset;
11584
+ function fillPool(bytes) {
11585
+ if (bytes < 0) throw new RangeError("Wrong ID size");
11586
+ try {
11587
+ if (!pool || pool.length < bytes) {
11588
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
11589
+ import_node_crypto5.webcrypto.getRandomValues(pool);
11590
+ poolOffset = 0;
11591
+ } else if (poolOffset + bytes > pool.length) {
11592
+ import_node_crypto5.webcrypto.getRandomValues(pool);
11593
+ poolOffset = 0;
11594
+ }
11595
+ } catch (e5) {
11596
+ pool = void 0;
11597
+ throw e5;
11598
+ }
11599
+ poolOffset += bytes;
11600
+ }
11601
+ function nanoid(size = 21) {
11602
+ fillPool(size |= 0);
11603
+ let id2 = "";
11604
+ for (let i6 = poolOffset - size; i6 < poolOffset; i6++) {
11605
+ id2 += urlAlphabet[pool[i6] & 63];
11606
+ }
11607
+ return id2;
11608
+ }
11609
+
11610
+ // src/server/document-comments.ts
11611
11611
  var MAX_TEXT = 2e4;
11612
11612
  var isText = (value, max = MAX_TEXT) => typeof value === "string" && value.length <= max;
11613
11613
  var isId = (value) => isText(value, 100) && value.length > 0;
@@ -11982,6 +11982,29 @@ function createBoardCommentRegistry(options) {
11982
11982
  };
11983
11983
  }
11984
11984
 
11985
+ // src/server/board-port.ts
11986
+ var BOARD_PORT_FILE = ".last-board-port";
11987
+ var BOARD_ROUTE = /^\/c\/artboard\/([^/]+)\/(.+)$/;
11988
+ var RUNTIME_ROUTE = /^\/c\/runtime\/(.+)$/;
11989
+ var loopbackHosts = (urlHost) => [
11990
+ .../* @__PURE__ */ new Set(["localhost", "127.0.0.1", urlHost.includes(":") ? `[${urlHost}]` : urlHost])
11991
+ ];
11992
+ var originsFor = (urlHost, port) => loopbackHosts(urlHost).map((host) => `http://${host}:${port}`);
11993
+ function boardCsp(urlHost, viewerPort, cloudOrigin) {
11994
+ const ancestors = [...originsFor(urlHost, viewerPort), ...cloudOrigin ? [cloudOrigin] : []];
11995
+ return `worker-src 'none'; frame-ancestors ${ancestors.join(" ")}`;
11996
+ }
11997
+ function routeBoardRequest(req, pathname) {
11998
+ if (req.method !== "GET" && req.method !== "HEAD") return { kind: "none" };
11999
+ if (pathname === "/robots.txt") return { kind: "robots" };
12000
+ const runtime = RUNTIME_ROUTE.exec(pathname);
12001
+ if (runtime) return { kind: "runtime", rest: `runtime/${runtime[1]}` };
12002
+ const board = BOARD_ROUTE.exec(pathname);
12003
+ if (board && isArtifactAddress(board[1]))
12004
+ return { kind: "board", address: board[1], rest: board[2] };
12005
+ return { kind: "none" };
12006
+ }
12007
+
11985
12008
  // src/server/cloud.ts
11986
12009
  var import_node_crypto7 = __toESM(require("node:crypto"), 1);
11987
12010
 
@@ -12448,14 +12471,14 @@ function fillRandom(buffer) {
12448
12471
  from = to3;
12449
12472
  }
12450
12473
  }
12451
- function random2(bytes) {
12474
+ function random(bytes) {
12452
12475
  bytes |= 0;
12453
12476
  if (bytes < 0) throw new RangeError("Wrong ID size");
12454
12477
  let buffer = Buffer.allocUnsafe(bytes);
12455
12478
  fillRandom(buffer);
12456
12479
  return buffer;
12457
12480
  }
12458
- function customRandom2(alphabet, defaultSize, getRandom) {
12481
+ function customRandom(alphabet, defaultSize, getRandom) {
12459
12482
  let safeByteCutoff = 256 - 256 % alphabet.length;
12460
12483
  if (safeByteCutoff === 256) {
12461
12484
  let mask = alphabet.length - 1;
@@ -12489,13 +12512,13 @@ function customRandom2(alphabet, defaultSize, getRandom) {
12489
12512
  };
12490
12513
  }
12491
12514
  var POOL_MAX = GET_RANDOM_LIMIT / 2;
12492
- function customAlphabet2(alphabet, defaultSize = 21) {
12515
+ function customAlphabet(alphabet, defaultSize = 21) {
12493
12516
  if (typeof alphabet !== "string" || !alphabet || alphabet.length > 256) {
12494
- return customRandom2(alphabet, defaultSize, random2);
12517
+ return customRandom(alphabet, defaultSize, random);
12495
12518
  }
12496
12519
  for (let i6 = 0; i6 < alphabet.length; i6++) {
12497
12520
  if (alphabet.charCodeAt(i6) > 255) {
12498
- return customRandom2(alphabet, defaultSize, random2);
12521
+ return customRandom(alphabet, defaultSize, random);
12499
12522
  }
12500
12523
  }
12501
12524
  let charCodes = Uint8Array.from(alphabet, (str) => {
@@ -12542,7 +12565,7 @@ function customAlphabet2(alphabet, defaultSize = 21) {
12542
12565
  return pool2.substring(poolOffset2 - size, poolOffset2);
12543
12566
  };
12544
12567
  }
12545
- var nanoid2 = customAlphabet2(urlAlphabet2);
12568
+ var nanoid2 = customAlphabet(urlAlphabet2);
12546
12569
 
12547
12570
  // node_modules/.pnpm/@haklex+rich-litexml@0.61.1_typescript@5.9.3/node_modules/@haklex/rich-litexml/dist/src-CwO17cE7.js
12548
12571
  var impl = null;
@@ -12688,11 +12711,11 @@ function registerBuiltinReaders(registry2) {
12688
12711
  }));
12689
12712
  }
12690
12713
  var idAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
12691
- var makePollIdSuffix = customAlphabet2(idAlphabet, 10);
12692
- var makeOptionIdSuffix = customAlphabet2(idAlphabet, 6);
12693
- var makeChatParticipantId = customAlphabet2(idAlphabet, 6);
12694
- var makeChatMessageId = customAlphabet2(idAlphabet, 8);
12695
- var makeStepId = customAlphabet2(idAlphabet, 8);
12714
+ var makePollIdSuffix = customAlphabet(idAlphabet, 10);
12715
+ var makeOptionIdSuffix = customAlphabet(idAlphabet, 6);
12716
+ var makeChatParticipantId = customAlphabet(idAlphabet, 6);
12717
+ var makeChatMessageId = customAlphabet(idAlphabet, 8);
12718
+ var makeStepId = customAlphabet(idAlphabet, 8);
12696
12719
  function extractBlockId(el2) {
12697
12720
  const id2 = el2.getAttribute("id");
12698
12721
  return id2 ? { $: { blockId: id2 } } : {};
@@ -24929,7 +24952,7 @@ function sharedComments(file) {
24929
24952
  function publishPayload(ref, dir, title, payload, comments = emptyComments()) {
24930
24953
  if (ref.type === "artboard") {
24931
24954
  const { canvas, layout, versions } = payload;
24932
- return { canvas, layout, versions, snapshots: true };
24955
+ return { canvas, layout, versions };
24933
24956
  }
24934
24957
  if (ref.type === "document")
24935
24958
  return {
@@ -25170,7 +25193,14 @@ function createCloudRoutes(options) {
25170
25193
  ([, entry]) => entry.cloud?.id === cloudId
25171
25194
  )?.[0] ?? `cloud:${cloudId}`;
25172
25195
  const createRecord2 = async (ref, visibility) => {
25173
- const res = await cloudFetch("POST", "/api/artifacts", { type: ref.type, visibility, project });
25196
+ const body = { type: ref.type, visibility, project };
25197
+ const id2 = options.address?.(ref);
25198
+ let res = await cloudFetch(
25199
+ "POST",
25200
+ "/api/artifacts",
25201
+ id2 && isMintedArtifactId(id2) ? { ...body, id: id2 } : body
25202
+ );
25203
+ if (res.status === 409) res = await cloudFetch("POST", "/api/artifacts", body);
25174
25204
  if (res.status === 403) throw new CreateRefused(await errorMessage(res));
25175
25205
  const created = await (await expectOk(res)).json();
25176
25206
  updateArtifactConfig(configFile, `${ref.type}/${ref.id}`, {
@@ -95268,11 +95298,11 @@ function $assignBlockIds(editor, runtime, candidates) {
95268
95298
  }
95269
95299
  }
95270
95300
  }
95271
- let random3 = needFresh;
95301
+ let random2 = needFresh;
95272
95302
  if (isLoad && needFresh.length > 0) {
95273
95303
  const fresh = new Set(needFresh.map((node) => node.getKey()));
95274
95304
  const placed = $placeBlocks(runtime, (node) => fresh.has(node.getKey()));
95275
- random3 = [];
95305
+ random2 = [];
95276
95306
  for (const node of needFresh) {
95277
95307
  const key2 = node.getKey();
95278
95308
  const id2 = placed.get(key2);
@@ -95280,11 +95310,11 @@ function $assignBlockIds(editor, runtime, candidates) {
95280
95310
  used.add(id2);
95281
95311
  $setState2(node, blockIdState, id2);
95282
95312
  } else {
95283
- random3.push(node);
95313
+ random2.push(node);
95284
95314
  }
95285
95315
  }
95286
95316
  }
95287
- for (const node of random3.sort(compareKeys)) {
95317
+ for (const node of random2.sort(compareKeys)) {
95288
95318
  const id2 = $makeFreshId(runtime, used);
95289
95319
  $setState2(node, blockIdState, id2);
95290
95320
  if (!prevNodeMap.has(node.getKey())) {
@@ -100170,7 +100200,7 @@ function viewerPage(template, page) {
100170
100200
  };
100171
100201
  return template.replace(
100172
100202
  /<html\b([^>]*)>/i,
100173
- (_tag, attributes) => `<html${attributes.replace(/\slang="[^"]*"/i, "")} lang="${HTML_LANG[locale]}"${page.artifactId ? ` data-ryugi-artifact-id="${escapeHtml2(page.artifactId)}"` : ""}>`
100203
+ (_tag, attributes) => `<html${attributes.replace(/\slang="[^"]*"/i, "")} lang="${HTML_LANG[locale]}"${page.artifactId ? ` data-ryugi-artifact-id="${escapeHtml2(page.artifactId)}"` : ""}${page.embedParent ? ` data-ryugi-embed-parent="${escapeHtml2(page.embedParent)}"` : ""}>`
100174
100204
  ).replace(/<title\b[^>]*>[\s\S]*?<\/title>/i, () => `<title>${escapeHtml2(page.title)}</title>`).replace(
100175
100205
  /(<link\b[^>]+\brel="icon"[^>]*\bhref=")[^"]*(")/i,
100176
100206
  (tag, prefix, suffix) => page.icon ? `${prefix}${escapeHtml2(page.icon)}${suffix}` : tag
@@ -100272,14 +100302,14 @@ function watchTree(root, onChange, debounceMs = 120, backupPollMs = 1e3) {
100272
100302
  }
100273
100303
 
100274
100304
  // src/server/app.ts
100275
- var VIEWER_CSP = [
100305
+ var viewerCsp = (boardOrigins) => [
100276
100306
  "default-src 'self'",
100277
100307
  "script-src 'self' 'wasm-unsafe-eval'",
100278
100308
  "style-src 'self' 'unsafe-inline'",
100279
100309
  "img-src 'self' data: blob:",
100280
100310
  "font-src 'self' data:",
100281
- "connect-src 'self'",
100282
- "frame-src 'self'",
100311
+ `connect-src 'self' ${boardOrigins.join(" ")}`,
100312
+ `frame-src 'self' ${boardOrigins.join(" ")}`,
100283
100313
  "base-uri 'self'",
100284
100314
  "form-action 'none'",
100285
100315
  "frame-ancestors 'none'"
@@ -100297,6 +100327,7 @@ var PREVIEW_ROUTE = new RegExp(
100297
100327
  `^/preview/(artboard|document|html)/${ARTIFACT_LOCATOR_SOURCE}/?$`
100298
100328
  );
100299
100329
  var API_PREVIEW_ROUTE = /^\/api\/preview\/([^/]+)\/([^/]+)$/;
100330
+ var EMBED_ROUTE = /^\/embed\/artboard\/([\w-]{1,64})\/?$/;
100300
100331
  var API_THUMBNAIL_ROUTE = /^\/api\/thumbnail\/([^/]+)\/([^/]+)\.svg$/;
100301
100332
  var API_DOCUMENT_ROUTE = /^\/api\/document\/([^/]+)\/(state|update|comments)$/;
100302
100333
  var MAX_COMMENT_OP = 64 * 1024;
@@ -100345,6 +100376,15 @@ async function startArtifactsServer(options) {
100345
100376
  import_node_fs26.default.writeFileSync(tokenFile, `${token}
100346
100377
  `, { mode: 384 });
100347
100378
  const contentToken = randomToken();
100379
+ const loopback = isLoopbackHost(options.host);
100380
+ const keyOk = (key2) => loopback || key2 !== null && safeEqual(key2, token);
100381
+ const agentOk = (req, key2) => loopback ? req.headers.origin === void 0 : key2 !== null && safeEqual(key2, token);
100382
+ let policy = accessPolicy({
100383
+ host: options.host,
100384
+ urlHost: options.urlHost,
100385
+ ports: [],
100386
+ cloudOrigin: options.cloud?.origin
100387
+ });
100348
100388
  const runtimeWarnings = /* @__PURE__ */ new Map();
100349
100389
  const ranVersions = /* @__PURE__ */ new Map();
100350
100390
  const dynamicBlocks = createDynamicBlocks({ maxErrors: MAX_RUNTIME_WARNINGS });
@@ -100365,6 +100405,8 @@ async function startArtifactsServer(options) {
100365
100405
  activityListeners.forEach((listener) => listener());
100366
100406
  };
100367
100407
  let port = 0;
100408
+ let boardPort = 0;
100409
+ const boardOrigins = () => boardPort ? originsFor(options.urlHost, boardPort) : [];
100368
100410
  let cookieName = "";
100369
100411
  let relay = null;
100370
100412
  const direct = createDirectRelay({
@@ -100465,6 +100507,7 @@ async function startArtifactsServer(options) {
100465
100507
  ...options.cloud,
100466
100508
  configFile: options.configFile,
100467
100509
  project: import_node_path23.default.basename(import_node_path23.default.resolve(root, "../..")),
100510
+ address: (ref) => artifactPath(root, ref.type, ref.id).split("/").pop(),
100468
100511
  port: () => port,
100469
100512
  inspect,
100470
100513
  onPublication: (key2, publication) => {
@@ -100692,8 +100735,8 @@ async function startArtifactsServer(options) {
100692
100735
  sendJson(res, 400, { error: err.message });
100693
100736
  }
100694
100737
  };
100695
- const isAuthorized = (req, keyFromQuery) => keyFromQuery !== null && safeEqual(keyFromQuery, token) || safeEqual(parseCookies(req.headers.cookie)[cookieName] ?? "", token);
100696
- const serveContent = (res, rest, range) => {
100738
+ const isAuthorized = (req, keyFromQuery) => loopback || keyFromQuery !== null && safeEqual(keyFromQuery, token) || safeEqual(parseCookies(req.headers.cookie)[cookieName] ?? "", token);
100739
+ const serveContent = (res, rest, range, mode = "main") => {
100697
100740
  if (rest.startsWith("runtime/")) {
100698
100741
  if (!runtimeDir) {
100699
100742
  send(res, 404, "Not found");
@@ -100735,8 +100778,8 @@ async function startArtifactsServer(options) {
100735
100778
  }
100736
100779
  const page = ref.type === "html" ? relative === "index.html" : relative.endsWith(".html");
100737
100780
  const headers = {
100738
- "Content-Security-Policy": CONTENT_CSP[page && ref.type === "document" ? "html" : ref.type],
100739
- "Access-Control-Allow-Origin": "*"
100781
+ "Content-Security-Policy": mode === "board" ? boardCsp(options.urlHost, port, options.cloud?.origin) : CONTENT_CSP[page && ref.type === "document" ? "html" : ref.type],
100782
+ ...mode === "board" ? {} : { "Access-Control-Allow-Origin": "*" }
100740
100783
  };
100741
100784
  if (!page) {
100742
100785
  sendFile(res, target, headers, range);
@@ -100745,7 +100788,7 @@ async function startArtifactsServer(options) {
100745
100788
  import_node_fs26.default.readFile(target, "utf8", (err, source) => {
100746
100789
  if (err) send(res, 404, "Not found");
100747
100790
  else {
100748
- const uiRuntimeUrl = runtimeDir ? `${contentPrefix}runtime/ryugi-ui.js` : void 0;
100791
+ const uiRuntimeUrl = runtimeDir ? `${mode === "board" ? "/c/" : contentPrefix}runtime/ryugi-ui.js` : void 0;
100749
100792
  send(
100750
100793
  res,
100751
100794
  200,
@@ -100771,7 +100814,11 @@ async function startArtifactsServer(options) {
100771
100814
  sendJson(res, 404, { warnings: [`artifact ${type}/${id2} not found`] });
100772
100815
  return;
100773
100816
  }
100774
- sendJson(res, 200, artifactMeta(artifactKeyOf(`${type}/${id2}`), dir));
100817
+ const ref = artifactKeyOf(`${type}/${id2}`);
100818
+ sendJson(res, 200, {
100819
+ ...artifactMeta(ref, dir),
100820
+ ...ref.type === "artboard" && boardPort ? { boardPort, boardPath: `/c${artifactPath(root, "artboard", ref.id)}/` } : {}
100821
+ });
100775
100822
  };
100776
100823
  const serveList = (res) => {
100777
100824
  const { artifacts, warnings } = listArtifacts(root);
@@ -100846,6 +100893,10 @@ async function startArtifactsServer(options) {
100846
100893
  }
100847
100894
  const handleRequest = (req, res) => {
100848
100895
  res.setHeader("X-Robots-Tag", "noindex, nofollow");
100896
+ if (!hostAllowed(policy, req.headers.host)) {
100897
+ send(res, 403, "Forbidden host");
100898
+ return;
100899
+ }
100849
100900
  const url2 = new URL(req.url ?? "/", "http://artifacts.local");
100850
100901
  if (url2.pathname === "/api/status") {
100851
100902
  if (!isAuthorized(req, url2.searchParams.get("key")))
@@ -100890,6 +100941,10 @@ async function startArtifactsServer(options) {
100890
100941
  });
100891
100942
  return;
100892
100943
  }
100944
+ if (loopback && !originAllowed(policy, req.headers.origin)) {
100945
+ send(res, 403, "Forbidden origin");
100946
+ return;
100947
+ }
100893
100948
  const key2 = url2.searchParams.get("key");
100894
100949
  if (!isAuthorized(req, key2)) {
100895
100950
  send(res, 403, "Forbidden: open the full artifact link including ?key=");
@@ -100971,7 +101026,7 @@ async function startArtifactsServer(options) {
100971
101026
  return;
100972
101027
  }
100973
101028
  if (pathname === "/api/cloud/flush") {
100974
- if (req.method !== "POST" || key2 === null || !safeEqual(key2, token)) {
101029
+ if (req.method !== "POST" || !agentOk(req, key2)) {
100975
101030
  send(res, 403, "Forbidden: agent calls need ?key=");
100976
101031
  return;
100977
101032
  }
@@ -100986,7 +101041,7 @@ async function startArtifactsServer(options) {
100986
101041
  }
100987
101042
  const cloudMatch = cloud?.match(pathname);
100988
101043
  if (cloud && cloudMatch) {
100989
- if (req.method !== "GET" && !(key2 !== null && safeEqual(key2, token)) && !sameOrigin(req)) {
101044
+ if (req.method !== "GET" && !keyOk(key2) && !sameOrigin(req)) {
100990
101045
  send(res, 403, "Forbidden");
100991
101046
  return;
100992
101047
  }
@@ -100995,7 +101050,7 @@ async function startArtifactsServer(options) {
100995
101050
  }
100996
101051
  const agentCommentsMatch = API_AGENT_COMMENTS_ROUTE.exec(pathname);
100997
101052
  if (agentCommentsMatch) {
100998
- if (req.method !== "POST" || key2 === null || !safeEqual(key2, token)) {
101053
+ if (req.method !== "POST" || !agentOk(req, key2)) {
100999
101054
  send(res, 403, "Forbidden: agent calls need ?key=");
101000
101055
  return;
101001
101056
  }
@@ -101006,7 +101061,7 @@ async function startArtifactsServer(options) {
101006
101061
  }
101007
101062
  const agentBoardMatch = API_AGENT_BOARD_COMMENTS_ROUTE.exec(pathname);
101008
101063
  if (agentBoardMatch) {
101009
- if (req.method !== "POST" || key2 === null || !safeEqual(key2, token)) {
101064
+ if (req.method !== "POST" || !agentOk(req, key2)) {
101010
101065
  send(res, 403, "Forbidden: agent calls need ?key=");
101011
101066
  return;
101012
101067
  }
@@ -101017,7 +101072,7 @@ async function startArtifactsServer(options) {
101017
101072
  }
101018
101073
  const agentCheckMatch = API_AGENT_CHECK_ROUTE.exec(pathname);
101019
101074
  if (agentCheckMatch) {
101020
- if (req.method !== "POST" || key2 === null || !safeEqual(key2, token)) {
101075
+ if (req.method !== "POST" || !agentOk(req, key2)) {
101021
101076
  send(res, 403, "Forbidden: agent calls need ?key=");
101022
101077
  return;
101023
101078
  }
@@ -101045,8 +101100,19 @@ async function startArtifactsServer(options) {
101045
101100
  serveArtifactApi(res, apiMatch[1], apiMatch[2]);
101046
101101
  return;
101047
101102
  }
101048
- if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || pathname === "/index.html") {
101049
- const requested = artifactKeyOf(
101103
+ const embedMatch = EMBED_ROUTE.exec(pathname);
101104
+ const embed = !!embedMatch;
101105
+ const embedded = embedMatch && embedTarget(embedMatch[1]);
101106
+ if (pathname.startsWith("/embed/") && (!embedded || !options.cloud)) {
101107
+ send(res, 404, "Not found");
101108
+ return;
101109
+ }
101110
+ if (SHELL_ROUTE.test(pathname) || PREVIEW_ROUTE.test(pathname) || embed || pathname === "/index.html") {
101111
+ if (loopback && (pathname === "/" || pathname === "/index.html") && !navigationAllowed(req.headers["sec-fetch-site"])) {
101112
+ send(res, 403, "Forbidden");
101113
+ return;
101114
+ }
101115
+ const requested = embedded || artifactKeyOf(
101050
101116
  pathname.replace(/^\/(?:preview\/)?/, "").replace(/\/$/, ""),
101051
101117
  isArtifactLocator
101052
101118
  );
@@ -101065,9 +101131,12 @@ async function startArtifactsServer(options) {
101065
101131
  const preview = PREVIEW_ROUTE.test(pathname);
101066
101132
  const canonicalPath = ref ? dir ? artifactPath(root, ref.type, ref.id) : `/${ref.type}/${ref.id}` : "/";
101067
101133
  const canonical = `http://${urlHostForHttp(options.urlHost)}:${port}${preview ? "/preview" : ""}${canonicalPath}`;
101068
- const csp = preview ? VIEWER_CSP.replace("frame-ancestors 'none'", "frame-ancestors 'self'") : VIEWER_CSP;
101134
+ const csp = embed ? viewerCsp(boardOrigins()).replace(
101135
+ "frame-ancestors 'none'",
101136
+ `frame-ancestors ${options.cloud.origin}`
101137
+ ) : preview ? viewerCsp(boardOrigins()).replace("frame-ancestors 'none'", "frame-ancestors 'self'") : viewerCsp(boardOrigins());
101069
101138
  const headers = { "Content-Type": "text/html; charset=utf-8" };
101070
- if (key2 !== null)
101139
+ if (key2 !== null && !loopback)
101071
101140
  headers["Set-Cookie"] = `${cookieName}=${token}; HttpOnly; SameSite=Strict; Path=/`;
101072
101141
  const entry = preview && import_node_fs26.default.existsSync(import_node_path23.default.join(viewerDir, "preview.html")) ? "preview.html" : "index.html";
101073
101142
  void import_node_fs26.default.promises.readFile(import_node_path23.default.join(viewerDir, entry), "utf8").then((template) => {
@@ -101077,7 +101146,8 @@ async function startArtifactsServer(options) {
101077
101146
  locale,
101078
101147
  url: canonical,
101079
101148
  icon: ref ? typeFaviconHref(ref.type) : void 0,
101080
- artifactId: resolved?.id
101149
+ artifactId: resolved?.id,
101150
+ embedParent: embed ? options.cloud.origin : void 0
101081
101151
  });
101082
101152
  send(res, 200, html, {
101083
101153
  ...headers,
@@ -101090,7 +101160,10 @@ async function startArtifactsServer(options) {
101090
101160
  }
101091
101161
  const target = resolveInside(viewerDir, pathname.slice(1));
101092
101162
  if (!target) send(res, 404, "Not found");
101093
- else sendFile(res, target, { "Content-Security-Policy": VIEWER_CSP });
101163
+ else
101164
+ sendFile(res, target, {
101165
+ "Content-Security-Policy": viewerCsp(boardOrigins())
101166
+ });
101094
101167
  };
101095
101168
  const server = import_node_http.default.createServer((req, res) => {
101096
101169
  try {
@@ -101100,12 +101173,16 @@ async function startArtifactsServer(options) {
101100
101173
  }
101101
101174
  });
101102
101175
  server.on("upgrade", (req, socket) => {
101176
+ if (!hostAllowed(policy, req.headers.host)) {
101177
+ rejectUpgrade(socket, 403, "Forbidden");
101178
+ return;
101179
+ }
101103
101180
  const url2 = new URL(req.url ?? "/", "http://artifacts.local");
101104
101181
  const clientKey = req.headers["sec-websocket-key"];
101105
101182
  const directMatch = DIRECT_RELAY_ROUTE.exec(url2.pathname);
101106
101183
  if (directMatch && typeof clientKey === "string") {
101107
101184
  const fromCloud = options.cloud !== void 0 && req.headers.origin === options.cloud.origin;
101108
- if (!safeEqual(url2.searchParams.get("key") ?? "", token) || !(fromCloud || sameOrigin(req))) {
101185
+ if (!keyOk(url2.searchParams.get("key")) || !(fromCloud || sameOrigin(req))) {
101109
101186
  rejectUpgrade(socket, 403, "Forbidden");
101110
101187
  return;
101111
101188
  }
@@ -101150,9 +101227,56 @@ async function startArtifactsServer(options) {
101150
101227
  cookieName = `ryugi_artifacts_${port}`;
101151
101228
  import_node_fs26.default.writeFileSync(portFile, `${port}
101152
101229
  `, { mode: 384 });
101230
+ const boardServer = import_node_http.default.createServer((req, res) => {
101231
+ if (!hostAllowed(policy, req.headers.host)) {
101232
+ send(res, 403, "Forbidden host");
101233
+ return;
101234
+ }
101235
+ let pathname;
101236
+ try {
101237
+ pathname = decodeURIComponent(new URL(req.url ?? "/", "http://board.local").pathname);
101238
+ } catch {
101239
+ send(res, 400, "Bad request");
101240
+ return;
101241
+ }
101242
+ try {
101243
+ const route = routeBoardRequest(req, pathname);
101244
+ if (route.kind === "robots") send(res, 200, "User-agent: *\nDisallow: /\n");
101245
+ else if (route.kind === "runtime") serveContent(res, route.rest, req.headers.range, "board");
101246
+ else if (route.kind === "board") {
101247
+ const resolved = resolveArtifactAddress(root, "artboard", route.address);
101248
+ if (!resolved || resolved.id === route.address) send(res, 404, "Not found");
101249
+ else serveContent(res, `artboard/${resolved.id}/${route.rest}`, req.headers.range, "board");
101250
+ } else send(res, 404, "Not found");
101251
+ } catch (err) {
101252
+ if (!res.headersSent) send(res, 500, err.message);
101253
+ else res.destroy();
101254
+ }
101255
+ });
101256
+ if (loopback) {
101257
+ const boardPortFile = import_node_path23.default.join(stateDir, BOARD_PORT_FILE);
101258
+ const previousBoardPort = Number(readPersisted(boardPortFile));
101259
+ try {
101260
+ boardPort = await listen(
101261
+ boardServer,
101262
+ options.host,
101263
+ Number.isInteger(previousBoardPort) && previousBoardPort > 0 && previousBoardPort !== port ? previousBoardPort : 0
101264
+ );
101265
+ } catch {
101266
+ boardPort = await listen(boardServer, options.host, 0);
101267
+ }
101268
+ import_node_fs26.default.writeFileSync(boardPortFile, `${boardPort}
101269
+ `, { mode: 384 });
101270
+ }
101271
+ policy = accessPolicy({
101272
+ host: options.host,
101273
+ urlHost: options.urlHost,
101274
+ ports: boardPort ? [port, boardPort] : [port],
101275
+ cloudOrigin: options.cloud?.origin
101276
+ });
101153
101277
  const origin = `http://${urlHostForHttp(options.urlHost)}:${port}`;
101154
- const url = `${origin}/?key=${token}`;
101155
- const linkFor = (type, id2) => `${origin}${artifactPath(root, type, id2)}?key=${token}`;
101278
+ const url = loopback ? `${origin}/` : `${origin}/?key=${token}`;
101279
+ const linkFor = (type, id2) => `${origin}${artifactPath(root, type, id2)}${loopback ? "" : `?key=${token}`}`;
101156
101280
  const signatures = /* @__PURE__ */ new Map();
101157
101281
  const writeState = (ref, dir) => {
101158
101282
  const payload = readArtifact(dir, ref, runtimeOf(ref, dir));
@@ -101174,8 +101298,20 @@ async function startArtifactsServer(options) {
101174
101298
  initialChanges.push({ ref: entry, payload, files: [] });
101175
101299
  if (entry.type === "document") void documents.open(entry.id);
101176
101300
  }
101177
- writeJsonAtomic(import_node_path23.default.join(stateDir, "server-info"), { type: "server-started", url, port, root });
101301
+ writeJsonAtomic(import_node_path23.default.join(stateDir, "server-info"), {
101302
+ type: "server-started",
101303
+ url,
101304
+ port,
101305
+ boardPort,
101306
+ root
101307
+ });
101178
101308
  const relayViewers = /* @__PURE__ */ new Map();
101309
+ const embedTarget = (id2) => {
101310
+ if (isArtifactLocator(id2) && resolveArtifactAddress(root, "artboard", id2))
101311
+ return { type: "artboard", id: id2 };
101312
+ const served = artifactKeyOf(servedArtifacts().get(id2) ?? "");
101313
+ return served?.type === "artboard" ? served : null;
101314
+ };
101179
101315
  const servedArtifacts = () => {
101180
101316
  const served = /* @__PURE__ */ new Map();
101181
101317
  if (!options.configFile) return served;
@@ -101257,7 +101393,11 @@ async function startArtifactsServer(options) {
101257
101393
  ...options.relay,
101258
101394
  token: () => readCredentials(options.cloud.credentialsFile, options.cloud.origin)?.token ?? null,
101259
101395
  served: servedArtifacts,
101260
- local: () => ({ hostId: hostIdFor(options.cloud.credentialsFile), port, key: token }),
101396
+ local: () => ({
101397
+ hostId: hostIdFor(options.cloud.credentialsFile),
101398
+ port,
101399
+ ...loopback ? { embed: true } : { key: token }
101400
+ }),
101261
101401
  handle: handleRelay,
101262
101402
  onActivity: touch,
101263
101403
  onWatch: (keys2) => {
@@ -101352,6 +101492,7 @@ async function startArtifactsServer(options) {
101352
101492
  );
101353
101493
  return {
101354
101494
  port,
101495
+ boardPort,
101355
101496
  token,
101356
101497
  contentToken,
101357
101498
  url,
@@ -101380,6 +101521,8 @@ async function startArtifactsServer(options) {
101380
101521
  direct.close();
101381
101522
  selections.clearAll();
101382
101523
  for (const socket of clients) socket.destroy();
101524
+ boardServer.close();
101525
+ boardServer.closeAllConnections();
101383
101526
  server.close(() => resolve());
101384
101527
  server.closeAllConnections();
101385
101528
  });