collabmd 0.1.18

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 (430) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +453 -0
  3. package/bin/collabmd.js +241 -0
  4. package/docker-compose.yml +43 -0
  5. package/package.json +93 -0
  6. package/public/assets/css/base.css +1 -0
  7. package/public/assets/css/style.css +1 -0
  8. package/public/assets/js/assets/Assistant-Bold-ZDZZ6JHA.woff2 +0 -0
  9. package/public/assets/js/assets/Assistant-Medium-DZ25RZU3.woff2 +0 -0
  10. package/public/assets/js/assets/Assistant-Regular-PLF2XOGW.woff2 +0 -0
  11. package/public/assets/js/assets/Assistant-SemiBold-CZ5MX6FK.woff2 +0 -0
  12. package/public/assets/js/chunks/CodeMirrorEditor-UCMRAMCV-MAKZFDBE.js +12 -0
  13. package/public/assets/js/chunks/apl-C5P5JBDI.js +1 -0
  14. package/public/assets/js/chunks/ar-SA-NXDWD63E-MF6HMEA4.js +8 -0
  15. package/public/assets/js/chunks/architecture-PBZL5I3N-55LDZ5WS.js +1 -0
  16. package/public/assets/js/chunks/architectureDiagram-2XIMDMQ5-2VP562X7.js +36 -0
  17. package/public/assets/js/chunks/asciiarmor-3NCLLELT.js +1 -0
  18. package/public/assets/js/chunks/asn1-KF4WXU3M.js +1 -0
  19. package/public/assets/js/chunks/asterisk-EA3VIN65.js +1 -0
  20. package/public/assets/js/chunks/az-AZ-MXSORGZV-AIGO4TNU.js +1 -0
  21. package/public/assets/js/chunks/bg-BG-O6MV2KSF-X6AVO2AF.js +5 -0
  22. package/public/assets/js/chunks/blockDiagram-WCTKOSBZ-KM56WWDE.js +132 -0
  23. package/public/assets/js/chunks/bn-BD-T2VJNT7N-7OMHRIGC.js +3 -0
  24. package/public/assets/js/chunks/bn-IN-MMW2ORAC-EPKMNKG7.js +3 -0
  25. package/public/assets/js/chunks/brainfuck-A3CTQVFD.js +1 -0
  26. package/public/assets/js/chunks/c4Diagram-IC4MRINW-KX6UEGQZ.js +10 -0
  27. package/public/assets/js/chunks/ca-ES-MKBCGNOG-U44SUUTN.js +8 -0
  28. package/public/assets/js/chunks/chunk-2NTQWLZD.js +25 -0
  29. package/public/assets/js/chunks/chunk-2YRP2AWD.js +1 -0
  30. package/public/assets/js/chunks/chunk-3BUCGSSJ.js +1 -0
  31. package/public/assets/js/chunks/chunk-47L7JGE3.js +1 -0
  32. package/public/assets/js/chunks/chunk-4BCHPULB.js +1 -0
  33. package/public/assets/js/chunks/chunk-4NKM6YFO.js +161 -0
  34. package/public/assets/js/chunks/chunk-4WGMPBK5.js +1 -0
  35. package/public/assets/js/chunks/chunk-55WF6Y2Q.js +1 -0
  36. package/public/assets/js/chunks/chunk-775E65SU.js +1 -0
  37. package/public/assets/js/chunks/chunk-AJRGTECU.js +70 -0
  38. package/public/assets/js/chunks/chunk-B2J3PHGY.js +1 -0
  39. package/public/assets/js/chunks/chunk-B4JKB3BC.js +1 -0
  40. package/public/assets/js/chunks/chunk-BBHPYU2R.js +1 -0
  41. package/public/assets/js/chunks/chunk-CGVY4PKT.js +13 -0
  42. package/public/assets/js/chunks/chunk-CVTRX3TE.js +220 -0
  43. package/public/assets/js/chunks/chunk-DW6KK6VF.js +1 -0
  44. package/public/assets/js/chunks/chunk-E2HMNOQL.js +189 -0
  45. package/public/assets/js/chunks/chunk-EPTJZP5H.js +7 -0
  46. package/public/assets/js/chunks/chunk-G7NUGGE7.js +13 -0
  47. package/public/assets/js/chunks/chunk-GI7LBIBP.js +1 -0
  48. package/public/assets/js/chunks/chunk-GXRL27M7.js +1 -0
  49. package/public/assets/js/chunks/chunk-H6EYDHRW.js +1 -0
  50. package/public/assets/js/chunks/chunk-HOCBCDA5.js +1 -0
  51. package/public/assets/js/chunks/chunk-HS2CUOC6.js +1 -0
  52. package/public/assets/js/chunks/chunk-HUAS4BYI.js +12 -0
  53. package/public/assets/js/chunks/chunk-HVNNEPP5.js +2 -0
  54. package/public/assets/js/chunks/chunk-I2GVZI7W.js +38 -0
  55. package/public/assets/js/chunks/chunk-I6PVWGBN.js +14 -0
  56. package/public/assets/js/chunks/chunk-IR2DOYV4.js +7 -0
  57. package/public/assets/js/chunks/chunk-IZ3V3F2A.js +1 -0
  58. package/public/assets/js/chunks/chunk-KPAQHIOI.js +1 -0
  59. package/public/assets/js/chunks/chunk-M3EW4V74.js +1 -0
  60. package/public/assets/js/chunks/chunk-MK3AFU3C.js +90 -0
  61. package/public/assets/js/chunks/chunk-NM6J3ND7.js +1 -0
  62. package/public/assets/js/chunks/chunk-NO7UPWTU.js +1 -0
  63. package/public/assets/js/chunks/chunk-OG2TNZEU.js +9 -0
  64. package/public/assets/js/chunks/chunk-OHGDMMWM.js +1 -0
  65. package/public/assets/js/chunks/chunk-OOT2HALX.js +1 -0
  66. package/public/assets/js/chunks/chunk-OQLLZFFN.js +1 -0
  67. package/public/assets/js/chunks/chunk-PF6TP4EI.js +1 -0
  68. package/public/assets/js/chunks/chunk-PMOZMECZ.js +85 -0
  69. package/public/assets/js/chunks/chunk-QBGS6DJR.js +1 -0
  70. package/public/assets/js/chunks/chunk-QF3ZQ6UQ.js +1 -0
  71. package/public/assets/js/chunks/chunk-QFXMAUW4.js +1 -0
  72. package/public/assets/js/chunks/chunk-QSTBGTWJ.js +1 -0
  73. package/public/assets/js/chunks/chunk-QYKIT2IH.js +41 -0
  74. package/public/assets/js/chunks/chunk-S75BI2UQ.js +1 -0
  75. package/public/assets/js/chunks/chunk-SKEZZ3H6.js +1 -0
  76. package/public/assets/js/chunks/chunk-SO6QBCB6.js +1 -0
  77. package/public/assets/js/chunks/chunk-SR3U53EQ.js +1 -0
  78. package/public/assets/js/chunks/chunk-TFP6LRYJ.js +53 -0
  79. package/public/assets/js/chunks/chunk-U6APNHAF.js +15 -0
  80. package/public/assets/js/chunks/chunk-VOODXHXA.js +1 -0
  81. package/public/assets/js/chunks/chunk-W7WJUTSA.js +3 -0
  82. package/public/assets/js/chunks/chunk-WNXFO2F2.js +1 -0
  83. package/public/assets/js/chunks/chunk-X6EEYWV4.js +6 -0
  84. package/public/assets/js/chunks/chunk-YVW3ZETS.js +1 -0
  85. package/public/assets/js/chunks/chunk-ZR2QRTBG.js +339 -0
  86. package/public/assets/js/chunks/chunk-ZZJX4LQ2.js +1 -0
  87. package/public/assets/js/chunks/classDiagram-VBA2DB6C-IYW4O2RM.js +1 -0
  88. package/public/assets/js/chunks/classDiagram-v2-RAHNMMFH-DNKVN2WD.js +1 -0
  89. package/public/assets/js/chunks/clike-RTBH33GE.js +1 -0
  90. package/public/assets/js/chunks/clojure-BR2VJ2JI.js +1 -0
  91. package/public/assets/js/chunks/cmake-2HEWVFEE.js +1 -0
  92. package/public/assets/js/chunks/cobol-V6EIK6DN.js +1 -0
  93. package/public/assets/js/chunks/coffeescript-JW3ZOGMD.js +1 -0
  94. package/public/assets/js/chunks/commonlisp-UCWSIHYK.js +1 -0
  95. package/public/assets/js/chunks/cose-bilkent-S5V4N54A-QVYRFFNC.js +1 -0
  96. package/public/assets/js/chunks/crystal-GR4VLC3M.js +1 -0
  97. package/public/assets/js/chunks/cs-CZ-V77HGUP7-OLBAKFG5.js +7 -0
  98. package/public/assets/js/chunks/css-C5DVWGB4.js +1 -0
  99. package/public/assets/js/chunks/cypher-K7FZM5GC.js +1 -0
  100. package/public/assets/js/chunks/d-CF3QNNH5.js +1 -0
  101. package/public/assets/js/chunks/da-DK-I5RFNTM4-QJIG2SEZ.js +2 -0
  102. package/public/assets/js/chunks/dagre-KLK3FWXG-KVNBUDOY.js +4 -0
  103. package/public/assets/js/chunks/de-CH-WLRDEVBV-4MMJDMVD.js +7 -0
  104. package/public/assets/js/chunks/de-DE-DTI4WUSC-ML7C46TT.js +7 -0
  105. package/public/assets/js/chunks/diagram-E7M64L7V-ZP33VRUC.js +24 -0
  106. package/public/assets/js/chunks/diagram-IFDJBPK2-ZG35YWOD.js +43 -0
  107. package/public/assets/js/chunks/diagram-P4PSJMXO-ZGIGM7D2.js +24 -0
  108. package/public/assets/js/chunks/diff-KOMSZU7O.js +1 -0
  109. package/public/assets/js/chunks/dist-7RQKSOUX.js +7 -0
  110. package/public/assets/js/chunks/dist-ARWGZ6MN.js +1 -0
  111. package/public/assets/js/chunks/dist-DPBSGC3Y.js +2 -0
  112. package/public/assets/js/chunks/dist-E36PJE5M.js +1 -0
  113. package/public/assets/js/chunks/dist-E5NM7OBW.js +1 -0
  114. package/public/assets/js/chunks/dist-ERADYPEK.js +1 -0
  115. package/public/assets/js/chunks/dist-F43RIHBZ.js +1 -0
  116. package/public/assets/js/chunks/dist-HAB5NIXI.js +1 -0
  117. package/public/assets/js/chunks/dist-HG23OLRA.js +1 -0
  118. package/public/assets/js/chunks/dist-IEJXBSDJ.js +1 -0
  119. package/public/assets/js/chunks/dist-IQA4KVJK.js +1 -0
  120. package/public/assets/js/chunks/dist-OIQTNVT2.js +3 -0
  121. package/public/assets/js/chunks/dist-PMZJ734S.js +1 -0
  122. package/public/assets/js/chunks/dist-RCQFQRLD.js +1 -0
  123. package/public/assets/js/chunks/dist-RQLC4GVI.js +1 -0
  124. package/public/assets/js/chunks/dist-RSJGLSKC.js +1 -0
  125. package/public/assets/js/chunks/dist-SGNQZVVX.js +1 -0
  126. package/public/assets/js/chunks/dist-VCFTF7Z6.js +1 -0
  127. package/public/assets/js/chunks/dist-VTO23SHH.js +1 -0
  128. package/public/assets/js/chunks/dist-XOODBV4L.js +1 -0
  129. package/public/assets/js/chunks/dist-ZFZNCRZY.js +1 -0
  130. package/public/assets/js/chunks/dockerfile-XCIKYOSI.js +1 -0
  131. package/public/assets/js/chunks/dtd-3XFH7W6Z.js +1 -0
  132. package/public/assets/js/chunks/dylan-3UWPKVOR.js +1 -0
  133. package/public/assets/js/chunks/ebnf-OLHTL3VN.js +1 -0
  134. package/public/assets/js/chunks/ecl-43LZ3ZRM.js +1 -0
  135. package/public/assets/js/chunks/editor-session-IHFTYG5D.js +22 -0
  136. package/public/assets/js/chunks/eiffel-ISPO2UJF.js +1 -0
  137. package/public/assets/js/chunks/el-GR-ZXDJ2OS4-WSCEIO6J.js +7 -0
  138. package/public/assets/js/chunks/elm-CLK576PK.js +1 -0
  139. package/public/assets/js/chunks/en-CTDJDZ6K-IC3QAUOI.js +1 -0
  140. package/public/assets/js/chunks/erDiagram-INFDFZHY-ZMS6H2TH.js +70 -0
  141. package/public/assets/js/chunks/erlang-AVQXQFOT.js +1 -0
  142. package/public/assets/js/chunks/es-ES-DYQHAD43-XGB5X5IM.js +7 -0
  143. package/public/assets/js/chunks/eu-ES-QDSYU5Y3-LA3JTIJ2.js +7 -0
  144. package/public/assets/js/chunks/excalidraw-mermaid-stub-NYXTOJ4H.js +1 -0
  145. package/public/assets/js/chunks/fa-IR-26LZG4PM-PFALMEDX.js +9 -0
  146. package/public/assets/js/chunks/factor-CRTVBD6Q.js +1 -0
  147. package/public/assets/js/chunks/fcl-FX24LKTH.js +1 -0
  148. package/public/assets/js/chunks/fi-FI-6YS4KDE4-ES5MV6P4.js +6 -0
  149. package/public/assets/js/chunks/flowDiagram-PKNHOUZH-QD4L5IE5.js +162 -0
  150. package/public/assets/js/chunks/forth-YKDKCTVS.js +1 -0
  151. package/public/assets/js/chunks/fortran-UJWC6SLU.js +1 -0
  152. package/public/assets/js/chunks/fr-FR-BRLLPTZC-VMFE22YV.js +12 -0
  153. package/public/assets/js/chunks/ganttDiagram-A5KZAMGK-VTMTQESP.js +292 -0
  154. package/public/assets/js/chunks/gas-MYEMWGRE.js +1 -0
  155. package/public/assets/js/chunks/gherkin-JWHAU2YG.js +1 -0
  156. package/public/assets/js/chunks/gitGraph-HDMCJU4V-YPHS74XX.js +1 -0
  157. package/public/assets/js/chunks/gitGraphDiagram-K3NZZRJ6-Z3EZ634T.js +65 -0
  158. package/public/assets/js/chunks/gl-ES-OKUZTLYG-GPT42ZHV.js +6 -0
  159. package/public/assets/js/chunks/groovy-QZIZQIAK.js +1 -0
  160. package/public/assets/js/chunks/haskell-JR3G7YNW.js +1 -0
  161. package/public/assets/js/chunks/haxe-TVLAIYEN.js +1 -0
  162. package/public/assets/js/chunks/he-IL-26MGYIU7-VQ5XQYYY.js +8 -0
  163. package/public/assets/js/chunks/hi-IN-Q4ZOGTP2-2Z766MXA.js +3 -0
  164. package/public/assets/js/chunks/http-YXQRE77G.js +1 -0
  165. package/public/assets/js/chunks/hu-HU-P2OXPSN5-6XDVPGTE.js +3 -0
  166. package/public/assets/js/chunks/id-ID-2EIKXYN6-J5GWSY2S.js +8 -0
  167. package/public/assets/js/chunks/idl-RAQGJ6LJ.js +1 -0
  168. package/public/assets/js/chunks/image-32MOCVDX-JN2EUMQG.js +1 -0
  169. package/public/assets/js/chunks/image-blob-reduce.esm-K5OWL55S.js +13 -0
  170. package/public/assets/js/chunks/info-3K5VOQVL-CXJSPNNP.js +1 -0
  171. package/public/assets/js/chunks/infoDiagram-LFFYTUFH-WQ34MUJA.js +2 -0
  172. package/public/assets/js/chunks/ishikawaDiagram-PHBUUO56-4IARWKJK.js +70 -0
  173. package/public/assets/js/chunks/it-IT-4CFKVXI2-NMBWUWFF.js +12 -0
  174. package/public/assets/js/chunks/ja-JP-MAND2Z4V-GQZYXXOC.js +7 -0
  175. package/public/assets/js/chunks/javascript-NM7KDJUE.js +1 -0
  176. package/public/assets/js/chunks/journeyDiagram-4ABVD52K-FJ4LF4SX.js +139 -0
  177. package/public/assets/js/chunks/julia-LG3BH25B.js +1 -0
  178. package/public/assets/js/chunks/kaa-HQRTCXTJ-7D6PAKDJ.js +1 -0
  179. package/public/assets/js/chunks/kab-KAB-JKIKKTGH-TNKFXNAX.js +4 -0
  180. package/public/assets/js/chunks/kanban-definition-K7BYSVSG-TY4EVYI3.js +89 -0
  181. package/public/assets/js/chunks/katex-5YJCUCFD.js +261 -0
  182. package/public/assets/js/chunks/kk-KZ-HXQ63ZFC-T4HCMWED.js +1 -0
  183. package/public/assets/js/chunks/km-KH-PKL3LSGX-HTLHEJV6.js +7 -0
  184. package/public/assets/js/chunks/ko-KR-KXLREZX3-QMR52QVI.js +5 -0
  185. package/public/assets/js/chunks/ku-TR-MJ4IER3X-K5CNY4UO.js +6 -0
  186. package/public/assets/js/chunks/livescript-4CVWVI4M.js +1 -0
  187. package/public/assets/js/chunks/lt-LT-H6WFQ6FJ-IW25FAGX.js +3 -0
  188. package/public/assets/js/chunks/lua-VWGE7DQ7.js +1 -0
  189. package/public/assets/js/chunks/lv-LV-GOCK6SJW-KTDFW5OH.js +4 -0
  190. package/public/assets/js/chunks/mathematica-D7APQSEU.js +1 -0
  191. package/public/assets/js/chunks/mbox-BN3XQBYX.js +1 -0
  192. package/public/assets/js/chunks/mermaid-runtime-BIFNJ2CT.js +18 -0
  193. package/public/assets/js/chunks/mindmap-definition-YRQLILUH-5B565RNP.js +68 -0
  194. package/public/assets/js/chunks/mirc-565WBI76.js +1 -0
  195. package/public/assets/js/chunks/mllike-VV3KS46B.js +1 -0
  196. package/public/assets/js/chunks/modelica-EGX44FZV.js +1 -0
  197. package/public/assets/js/chunks/mr-IN-IXVLDMEQ-PHM5DT7Q.js +9 -0
  198. package/public/assets/js/chunks/mscgen-GFGTHENT.js +1 -0
  199. package/public/assets/js/chunks/mumps-POZYWSMI.js +1 -0
  200. package/public/assets/js/chunks/my-MM-YG6MYTTD-ZHLCMEVA.js +1 -0
  201. package/public/assets/js/chunks/nb-NO-XGWJISD2-KSDFG6YU.js +8 -0
  202. package/public/assets/js/chunks/nginx-JUBX55EU.js +1 -0
  203. package/public/assets/js/chunks/nl-NL-XVDVCPNC-KVF3ZO2R.js +13 -0
  204. package/public/assets/js/chunks/nn-NO-EMX5MJX5-34QKSHNR.js +4 -0
  205. package/public/assets/js/chunks/nsis-RC4CREGM.js +1 -0
  206. package/public/assets/js/chunks/ntriples-4WK6CNVE.js +1 -0
  207. package/public/assets/js/chunks/oc-FR-ROEINTVO-5GP4AOYO.js +4 -0
  208. package/public/assets/js/chunks/octave-GOKFN2V7.js +1 -0
  209. package/public/assets/js/chunks/oz-OQUMNC63.js +1 -0
  210. package/public/assets/js/chunks/pa-IN-ZYN6SUDY-MVL7O44W.js +4 -0
  211. package/public/assets/js/chunks/packet-RMMSAZCW-D7XTR5TT.js +1 -0
  212. package/public/assets/js/chunks/pascal-BBWQWWWD.js +1 -0
  213. package/public/assets/js/chunks/percentages-5DKR754L-DG7W23CV.js +1 -0
  214. package/public/assets/js/chunks/perl-KTPJTTAM.js +1 -0
  215. package/public/assets/js/chunks/pica-6G3NROWT.js +17 -0
  216. package/public/assets/js/chunks/pie-UPGHQEXC-KGC3O6LN.js +1 -0
  217. package/public/assets/js/chunks/pieDiagram-SKSYHLDU-KWKRDEZS.js +30 -0
  218. package/public/assets/js/chunks/pig-IJMBS4FZ.js +1 -0
  219. package/public/assets/js/chunks/pl-PL-6VTG7PHC-VADRWSX4.js +12 -0
  220. package/public/assets/js/chunks/powershell-6YGCBHDP.js +1 -0
  221. package/public/assets/js/chunks/preview-render-compiler-WD3A76I6.js +25 -0
  222. package/public/assets/js/chunks/properties-5QTD3364.js +1 -0
  223. package/public/assets/js/chunks/protobuf-LTRWBIK3.js +1 -0
  224. package/public/assets/js/chunks/pt-BR-5YFKRR5G-HHF4UPO4.js +6 -0
  225. package/public/assets/js/chunks/pt-PT-GEIXXZ67-TUTAUZJK.js +8 -0
  226. package/public/assets/js/chunks/pug-U4PV3WLG.js +1 -0
  227. package/public/assets/js/chunks/puppet-WGYJPR3Y.js +1 -0
  228. package/public/assets/js/chunks/python-6YGH4S47.js +1 -0
  229. package/public/assets/js/chunks/q-VIG4IJLI.js +1 -0
  230. package/public/assets/js/chunks/quadrantDiagram-337W2JSQ-GWQRUFHQ.js +7 -0
  231. package/public/assets/js/chunks/quick-switcher-controller-JYDIJVAJ.js +5 -0
  232. package/public/assets/js/chunks/r-NVPCXGTR.js +1 -0
  233. package/public/assets/js/chunks/radar-KQ55EAFF-OPO64DRI.js +1 -0
  234. package/public/assets/js/chunks/requirementDiagram-Z7DCOOCP-ASW7IPJL.js +73 -0
  235. package/public/assets/js/chunks/ro-RO-E2P6TFZI-RJFCULYF.js +12 -0
  236. package/public/assets/js/chunks/roundRect-Z3DX3W5S.js +1 -0
  237. package/public/assets/js/chunks/rpm-UEA257HD.js +1 -0
  238. package/public/assets/js/chunks/ru-RU-YBIIY43T-BF27TNVK.js +10 -0
  239. package/public/assets/js/chunks/ruby-KPQRAJGE.js +1 -0
  240. package/public/assets/js/chunks/sankeyDiagram-WA2Y5GQK-W6BBWCLW.js +10 -0
  241. package/public/assets/js/chunks/sas-L7VATVH5.js +1 -0
  242. package/public/assets/js/chunks/scheme-T2NOWR3P.js +1 -0
  243. package/public/assets/js/chunks/sequenceDiagram-2WXFIKYE-H4G3ISLN.js +145 -0
  244. package/public/assets/js/chunks/shell-DLVDUNFA.js +1 -0
  245. package/public/assets/js/chunks/si-LK-673C2CI2-IOFGU4U2.js +1 -0
  246. package/public/assets/js/chunks/sieve-BKBZYDBU.js +1 -0
  247. package/public/assets/js/chunks/sk-SK-CKZHQ4AP-6O5JGN26.js +7 -0
  248. package/public/assets/js/chunks/sl-SI-557H2GWM-2NEHLV7W.js +6 -0
  249. package/public/assets/js/chunks/smalltalk-WRJQKJSD.js +1 -0
  250. package/public/assets/js/chunks/solr-66B3BIDL.js +1 -0
  251. package/public/assets/js/chunks/sparql-S25Z47JG.js +1 -0
  252. package/public/assets/js/chunks/spreadsheet-B272EF7Y.js +1 -0
  253. package/public/assets/js/chunks/sql-BPLIIUYC.js +1 -0
  254. package/public/assets/js/chunks/stateDiagram-RAJIS63D-OF5XXRUS.js +1 -0
  255. package/public/assets/js/chunks/stateDiagram-v2-FVOUBMTO-IV2CSQSQ.js +1 -0
  256. package/public/assets/js/chunks/stex-4IJY64QX.js +1 -0
  257. package/public/assets/js/chunks/stylus-PJUHLGPT.js +1 -0
  258. package/public/assets/js/chunks/subset-shared.chunk-4NMWHS4D.js +1 -0
  259. package/public/assets/js/chunks/subset-worker.chunk-NTLP7Y66.js +1 -0
  260. package/public/assets/js/chunks/sv-SE-XOPKKDWS-Q2L6KGFV.js +8 -0
  261. package/public/assets/js/chunks/swift-UYHTO4SX.js +1 -0
  262. package/public/assets/js/chunks/ta-IN-XBH7DQI3-ISSUGZAK.js +6 -0
  263. package/public/assets/js/chunks/tcl-OQ5J3VO2.js +1 -0
  264. package/public/assets/js/chunks/textile-NOGVBEYF.js +1 -0
  265. package/public/assets/js/chunks/th-TH-TOCWH3R4-TABEAMJA.js +1 -0
  266. package/public/assets/js/chunks/tiddlywiki-SYTK4QUE.js +1 -0
  267. package/public/assets/js/chunks/tiki-P7K4ZLOM.js +1 -0
  268. package/public/assets/js/chunks/timeline-definition-YZTLITO2-HBCANIUC.js +61 -0
  269. package/public/assets/js/chunks/toml-AUZYRP36.js +1 -0
  270. package/public/assets/js/chunks/tr-TR-GXW6CYY5-5NQRN52Y.js +4 -0
  271. package/public/assets/js/chunks/treemap-KZPCXAKY-WYMCT5F7.js +1 -0
  272. package/public/assets/js/chunks/troff-XFYJNQOJ.js +1 -0
  273. package/public/assets/js/chunks/ttcn-AK2IXWU6.js +1 -0
  274. package/public/assets/js/chunks/ttcn-cfg-3IDPIYPU.js +1 -0
  275. package/public/assets/js/chunks/turtle-OIDMF46P.js +1 -0
  276. package/public/assets/js/chunks/uk-UA-IJKTNUDG-2IIL3TO5.js +6 -0
  277. package/public/assets/js/chunks/uz-UZ-TBZZEA4V-X22KVKBP.js +1 -0
  278. package/public/assets/js/chunks/vb-J6K4XVA2.js +1 -0
  279. package/public/assets/js/chunks/vbscript-FM7DDZZE.js +1 -0
  280. package/public/assets/js/chunks/velocity-6KZFEOFD.js +1 -0
  281. package/public/assets/js/chunks/vennDiagram-LZ73GAT5-EBRF3MZR.js +34 -0
  282. package/public/assets/js/chunks/verilog-EWWQPMNN.js +1 -0
  283. package/public/assets/js/chunks/vhdl-CJ3M4IHI.js +1 -0
  284. package/public/assets/js/chunks/vi-VN-MULSGNVB-TENM65C7.js +7 -0
  285. package/public/assets/js/chunks/webidl-XVBHXCRV.js +1 -0
  286. package/public/assets/js/chunks/xquery-7WZOZ4UK.js +1 -0
  287. package/public/assets/js/chunks/xychartDiagram-JWTSCODW-WIFVRQPR.js +7 -0
  288. package/public/assets/js/chunks/yacas-MZ2ZZPF3.js +1 -0
  289. package/public/assets/js/chunks/z80-I447CBF7.js +1 -0
  290. package/public/assets/js/chunks/zh-CN-MVX3E32U-S5VA2BA5.js +11 -0
  291. package/public/assets/js/chunks/zh-HK-JNU5RLIE-A4VUKZFV.js +1 -0
  292. package/public/assets/js/chunks/zh-TW-LENVCA6T-KFB6KHMM.js +9 -0
  293. package/public/assets/js/excalidraw-editor-7ORML5YA.css +1 -0
  294. package/public/assets/js/excalidraw-editor-LKW2AZBU.js +347 -0
  295. package/public/assets/js/excalidraw-editor.css +1 -0
  296. package/public/assets/js/excalidraw-editor.js +1 -0
  297. package/public/assets/js/main.js +354 -0
  298. package/public/assets/js/preview-render-worker.js +30 -0
  299. package/public/assets/vendor/highlight/github-dark.min.css +10 -0
  300. package/public/assets/vendor/highlight/github.min.css +10 -0
  301. package/public/excalidraw-editor.html +31 -0
  302. package/public/index.html +549 -0
  303. package/scripts/cloudflare-tunnel.mjs +145 -0
  304. package/scripts/local-plantuml-compose.mjs +92 -0
  305. package/server.js +1 -0
  306. package/src/client/application/app-shell/chat-feature.js +363 -0
  307. package/src/client/application/app-shell/comments-feature.js +33 -0
  308. package/src/client/application/app-shell/git-feature.js +394 -0
  309. package/src/client/application/app-shell/presence-feature.js +229 -0
  310. package/src/client/application/app-shell/ui-feature.js +535 -0
  311. package/src/client/application/app-shell/workspace-feature.js +132 -0
  312. package/src/client/application/app-shell-elements.js +78 -0
  313. package/src/client/application/diagram-preview-hydrator.js +382 -0
  314. package/src/client/application/file-open-lifecycle.js +26 -0
  315. package/src/client/application/mermaid-preview-hydrator.js +570 -0
  316. package/src/client/application/plantuml-preview-hydrator.js +563 -0
  317. package/src/client/application/preview-diagram-utils.js +223 -0
  318. package/src/client/application/preview-render-compiler.js +426 -0
  319. package/src/client/application/preview-render-executor.js +153 -0
  320. package/src/client/application/preview-render-profile.js +63 -0
  321. package/src/client/application/preview-render-scheduler.js +73 -0
  322. package/src/client/application/preview-render-worker.js +19 -0
  323. package/src/client/application/preview-renderer.js +452 -0
  324. package/src/client/application/wiki-link-file-controller.js +58 -0
  325. package/src/client/application/workspace-chrome-controller.js +84 -0
  326. package/src/client/application/workspace-coordinator.js +238 -0
  327. package/src/client/application/workspace-preview-controller.js +237 -0
  328. package/src/client/application/workspace-route-controller.js +170 -0
  329. package/src/client/application/workspace-state-store.js +46 -0
  330. package/src/client/bootstrap/collabmd-app-shell.js +479 -0
  331. package/src/client/domain/diagram-action-icons.js +41 -0
  332. package/src/client/domain/excalidraw-collaboration.js +153 -0
  333. package/src/client/domain/excalidraw-scene.js +87 -0
  334. package/src/client/domain/markdown-formatting.js +370 -0
  335. package/src/client/domain/plantuml-language.js +226 -0
  336. package/src/client/domain/room.js +49 -0
  337. package/src/client/domain/runtime-paths.js +136 -0
  338. package/src/client/domain/vault-api-client.js +1 -0
  339. package/src/client/domain/vault-paths.js +80 -0
  340. package/src/client/domain/vault-utils.js +49 -0
  341. package/src/client/domain/wiki-link-completions.js +78 -0
  342. package/src/client/excalidraw-editor.js +630 -0
  343. package/src/client/excalidraw-mermaid-stub.js +7 -0
  344. package/src/client/infrastructure/auth-client.js +383 -0
  345. package/src/client/infrastructure/browser-navigation-port.js +19 -0
  346. package/src/client/infrastructure/browser-notification-port.js +40 -0
  347. package/src/client/infrastructure/browser-preferences-port.js +79 -0
  348. package/src/client/infrastructure/comment-thread-store.js +293 -0
  349. package/src/client/infrastructure/editor-collaboration-client.js +240 -0
  350. package/src/client/infrastructure/editor-session.js +255 -0
  351. package/src/client/infrastructure/editor-view-adapter.js +578 -0
  352. package/src/client/infrastructure/excalidraw-room-client.js +651 -0
  353. package/src/client/infrastructure/lobby-presence.js +304 -0
  354. package/src/client/infrastructure/runtime-config.js +65 -0
  355. package/src/client/infrastructure/tab-activity-lock.js +193 -0
  356. package/src/client/infrastructure/vault-api-client.js +61 -0
  357. package/src/client/infrastructure/yjs-provider-reset-guard.js +19 -0
  358. package/src/client/main.js +16 -0
  359. package/src/client/mermaid-runtime.js +3 -0
  360. package/src/client/presentation/backlinks-panel.js +188 -0
  361. package/src/client/presentation/comment-ui-controller.js +1235 -0
  362. package/src/client/presentation/comments-panel.js +531 -0
  363. package/src/client/presentation/excalidraw-embed-controller.js +968 -0
  364. package/src/client/presentation/excalidraw-embed-reconciler.js +37 -0
  365. package/src/client/presentation/file-action-controller.js +596 -0
  366. package/src/client/presentation/file-explorer-controller.js +81 -0
  367. package/src/client/presentation/file-explorer-view.js +256 -0
  368. package/src/client/presentation/file-tree-state.js +77 -0
  369. package/src/client/presentation/git-diff-view-controller.js +656 -0
  370. package/src/client/presentation/git-panel-controller.js +516 -0
  371. package/src/client/presentation/layout-controller.js +222 -0
  372. package/src/client/presentation/outline-controller.js +239 -0
  373. package/src/client/presentation/quick-switcher-controller.js +300 -0
  374. package/src/client/presentation/scroll-sync-controller.js +500 -0
  375. package/src/client/presentation/theme-controller.js +64 -0
  376. package/src/client/presentation/toast-controller.js +21 -0
  377. package/src/client/presentation/video-embed-controller.js +264 -0
  378. package/src/client/styles/base.css +58 -0
  379. package/src/client/styles/style.css +4245 -0
  380. package/src/domain/comment-threads.js +233 -0
  381. package/src/domain/excalidraw-room-codec.js +427 -0
  382. package/src/domain/file-kind.js +104 -0
  383. package/src/domain/wiki-link-resolver.js +75 -0
  384. package/src/server/auth/create-auth-service.js +272 -0
  385. package/src/server/auth/session-cookie.js +125 -0
  386. package/src/server/config/env.js +186 -0
  387. package/src/server/create-app-server.js +143 -0
  388. package/src/server/domain/backlink-index.js +291 -0
  389. package/src/server/domain/collaboration/collaboration-document-store.js +155 -0
  390. package/src/server/domain/collaboration/collaboration-room.js +603 -0
  391. package/src/server/domain/collaboration/protocol.js +2 -0
  392. package/src/server/domain/collaboration/room-client-state-store.js +28 -0
  393. package/src/server/domain/collaboration/room-persistence-controller.js +80 -0
  394. package/src/server/domain/collaboration/room-registry.js +94 -0
  395. package/src/server/domain/git-service.js +1 -0
  396. package/src/server/domain/plantuml-encoder.js +49 -0
  397. package/src/server/domain/plantuml-renderer.js +1 -0
  398. package/src/server/index.js +72 -0
  399. package/src/server/infrastructure/git/command-runner.js +48 -0
  400. package/src/server/infrastructure/git/concurrency.js +19 -0
  401. package/src/server/infrastructure/git/diff-service.js +389 -0
  402. package/src/server/infrastructure/git/errors.js +5 -0
  403. package/src/server/infrastructure/git/git-service.js +216 -0
  404. package/src/server/infrastructure/git/parsers.js +401 -0
  405. package/src/server/infrastructure/git/path-utils.js +65 -0
  406. package/src/server/infrastructure/git/responses.js +108 -0
  407. package/src/server/infrastructure/git/status-service.js +99 -0
  408. package/src/server/infrastructure/git/untracked-files.js +101 -0
  409. package/src/server/infrastructure/http/create-auth-api-handler.js +48 -0
  410. package/src/server/infrastructure/http/create-esm-proxy-handler.js +130 -0
  411. package/src/server/infrastructure/http/create-git-api-command-handler.js +170 -0
  412. package/src/server/infrastructure/http/create-git-api-handler.js +40 -0
  413. package/src/server/infrastructure/http/create-git-api-query-handler.js +62 -0
  414. package/src/server/infrastructure/http/create-plantuml-api-handler.js +43 -0
  415. package/src/server/infrastructure/http/create-request-handler.js +138 -0
  416. package/src/server/infrastructure/http/create-static-handler.js +167 -0
  417. package/src/server/infrastructure/http/create-vault-api-command-handler.js +161 -0
  418. package/src/server/infrastructure/http/create-vault-api-handler.js +43 -0
  419. package/src/server/infrastructure/http/create-vault-api-query-handler.js +82 -0
  420. package/src/server/infrastructure/http/http-errors.js +13 -0
  421. package/src/server/infrastructure/http/http-response.js +167 -0
  422. package/src/server/infrastructure/http/request-body.js +56 -0
  423. package/src/server/infrastructure/persistence/path-utils.js +90 -0
  424. package/src/server/infrastructure/persistence/sidecar-store.js +150 -0
  425. package/src/server/infrastructure/persistence/vault-content-adapter.js +49 -0
  426. package/src/server/infrastructure/persistence/vault-file-store.js +435 -0
  427. package/src/server/infrastructure/plantuml/plantuml-renderer.js +56 -0
  428. package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +194 -0
  429. package/src/server/infrastructure/websocket/client-socket-session.js +151 -0
  430. package/src/server/startup/git-remote-bootstrap.js +435 -0
@@ -0,0 +1,968 @@
1
+ import { setDiagramActionButtonIcon } from '../domain/diagram-action-icons.js';
2
+ import { reconcileEmbedEntries } from './excalidraw-embed-reconciler.js';
3
+ import { resolveAppUrl } from '../domain/runtime-paths.js';
4
+
5
+ const DEFAULT_HEIGHT = 420;
6
+ const HYDRATE_TIMEOUT_MS = 500;
7
+ const IFRAME_BOOT_TIMEOUT_MS = 15000;
8
+ const MAX_HEIGHT = 800;
9
+ const MAX_IFRAME_BOOT_ATTEMPTS = 3;
10
+ const MIN_HEIGHT = 200;
11
+ const EDITOR_IFRAME_PATH = '/excalidraw-editor.html';
12
+
13
+ function requestIdleRender(callback, timeout) {
14
+ if (typeof window.requestIdleCallback === 'function') {
15
+ return window.requestIdleCallback(callback, { timeout });
16
+ }
17
+
18
+ return window.setTimeout(() => {
19
+ callback({
20
+ didTimeout: false,
21
+ timeRemaining: () => 0,
22
+ });
23
+ }, 1);
24
+ }
25
+
26
+ function cancelIdleRender(id) {
27
+ if (id === null) {
28
+ return;
29
+ }
30
+
31
+ if (typeof window.cancelIdleCallback === 'function') {
32
+ window.cancelIdleCallback(id);
33
+ return;
34
+ }
35
+
36
+ window.clearTimeout(id);
37
+ }
38
+
39
+ function isNearViewport(element, root, marginPx) {
40
+ if (!element || !root) {
41
+ return false;
42
+ }
43
+
44
+ const rootRect = root.getBoundingClientRect();
45
+ const elementRect = element.getBoundingClientRect();
46
+
47
+ return (
48
+ elementRect.bottom >= (rootRect.top - marginPx)
49
+ && elementRect.top <= (rootRect.bottom + marginPx)
50
+ );
51
+ }
52
+
53
+ export class ExcalidrawEmbedController {
54
+ constructor({
55
+ getTheme,
56
+ getLocalUser,
57
+ onOpenFile = null,
58
+ previewContainer,
59
+ previewElement,
60
+ toastController,
61
+ }) {
62
+ this.getTheme = getTheme;
63
+ this.getLocalUser = getLocalUser;
64
+ this.onOpenFile = onOpenFile;
65
+ this.previewContainer = previewContainer;
66
+ this.previewElement = previewElement;
67
+ this.toastController = toastController;
68
+ this.embedEntries = new Map();
69
+ this.hydrationQueue = [];
70
+ this.hydrationIdleId = null;
71
+ this.hydrationPaused = false;
72
+ this.hydrationInProgress = false;
73
+ this.instanceCounter = 0;
74
+ this.isLargeDocument = false;
75
+ this.maximizedEmbed = null;
76
+ this.overlayRoot = null;
77
+ this.maximizedRoot = null;
78
+ this.placeholderObserver = null;
79
+ this.followedPeerIdsByFilePath = new Map();
80
+
81
+ this._onMessage = this._onMessage.bind(this);
82
+ this._onKeyDown = this._onKeyDown.bind(this);
83
+ this._onPreviewClick = this._onPreviewClick.bind(this);
84
+
85
+ window.addEventListener('message', this._onMessage);
86
+ window.addEventListener('keydown', this._onKeyDown);
87
+ this.previewElement?.addEventListener('click', this._onPreviewClick);
88
+ }
89
+
90
+ destroy() {
91
+ window.removeEventListener('message', this._onMessage);
92
+ window.removeEventListener('keydown', this._onKeyDown);
93
+ this.previewElement?.removeEventListener('click', this._onPreviewClick);
94
+ this._disconnectPlaceholderObserver();
95
+ cancelIdleRender(this.hydrationIdleId);
96
+ this.hydrationIdleId = null;
97
+ this.hydrationQueue = [];
98
+ this._exitMaximizedEmbed();
99
+ document.body.classList.remove('excalidraw-maximized-open');
100
+
101
+ this.embedEntries.forEach((entry) => {
102
+ this._clearEntryBootTimeout(entry);
103
+ entry.wrapper?.remove();
104
+ entry.placeholder = null;
105
+ });
106
+ this.embedEntries.clear();
107
+ this.followedPeerIdsByFilePath.clear();
108
+ this.overlayRoot?.remove();
109
+ this.overlayRoot = null;
110
+ this.maximizedRoot?.remove();
111
+ this.maximizedRoot = null;
112
+ }
113
+
114
+ async setFollowedUser(filePath, peerId = null) {
115
+ if (!filePath) {
116
+ return false;
117
+ }
118
+
119
+ this.followedPeerIdsByFilePath.set(filePath, peerId || null);
120
+
121
+ const entry = this._findEntryByFilePath(filePath);
122
+ if (!entry) {
123
+ return true;
124
+ }
125
+
126
+ if (!entry.wrapper) {
127
+ await this._hydrateEntry(entry);
128
+ }
129
+
130
+ entry.followedPeerId = this.followedPeerIdsByFilePath.get(filePath) ?? null;
131
+ this._syncEntryFollowState(entry);
132
+ return true;
133
+ }
134
+
135
+ detachForCommit() {
136
+ this._disconnectPlaceholderObserver();
137
+ cancelIdleRender(this.hydrationIdleId);
138
+ this.hydrationIdleId = null;
139
+ this.hydrationQueue = [];
140
+ this.hydrationInProgress = false;
141
+ if (this.overlayRoot) {
142
+ this.overlayRoot.hidden = true;
143
+ }
144
+ if (this.maximizedRoot) {
145
+ this.maximizedRoot.hidden = true;
146
+ }
147
+
148
+ this.embedEntries.forEach((entry) => {
149
+ entry.queued = false;
150
+ entry.placeholder = null;
151
+ });
152
+ }
153
+
154
+ setHydrationPaused(paused) {
155
+ this.hydrationPaused = Boolean(paused);
156
+
157
+ if (this.hydrationPaused) {
158
+ cancelIdleRender(this.hydrationIdleId);
159
+ this.hydrationIdleId = null;
160
+ return;
161
+ }
162
+
163
+ this.hydrateVisibleEmbeds();
164
+ this._scheduleHydration();
165
+ }
166
+
167
+ reconcileEmbeds(previewElement, { isLargeDocument = false } = {}) {
168
+ this.isLargeDocument = Boolean(isLargeDocument);
169
+ this._disconnectPlaceholderObserver();
170
+ cancelIdleRender(this.hydrationIdleId);
171
+ this.hydrationIdleId = null;
172
+ this.hydrationQueue = [];
173
+ this.hydrationInProgress = false;
174
+
175
+ const descriptors = Array.from(previewElement.querySelectorAll('.excalidraw-embed-placeholder[data-embed-key]')).map((placeholder) => ({
176
+ filePath: placeholder.dataset.embedTarget,
177
+ key: placeholder.dataset.embedKey,
178
+ label: placeholder.dataset.embedLabel || placeholder.dataset.embedTarget,
179
+ placeholder,
180
+ }));
181
+
182
+ const { nextEntries, removedEntries } = reconcileEmbedEntries(this.embedEntries, descriptors);
183
+ this._adoptReusableEntries(nextEntries, removedEntries);
184
+ removedEntries.forEach((entry) => this._destroyEntry(entry));
185
+ this.embedEntries = nextEntries;
186
+
187
+ this._ensurePlaceholderObserver();
188
+
189
+ this.embedEntries.forEach((entry) => {
190
+ entry.queued = false;
191
+ entry.followedPeerId = this.followedPeerIdsByFilePath.get(entry.filePath);
192
+ if (entry.wrapper) {
193
+ this._updateEmbedLabel(entry);
194
+ this._attachWrapper(entry);
195
+ return;
196
+ }
197
+
198
+ if (!entry.placeholder) {
199
+ return;
200
+ }
201
+
202
+ this.placeholderObserver?.observe(entry.placeholder);
203
+ });
204
+
205
+ if (!this.hydrationPaused) {
206
+ this.hydrateVisibleEmbeds();
207
+ }
208
+
209
+ this.syncLayout();
210
+ }
211
+
212
+ hydrateVisibleEmbeds() {
213
+ if (this.hydrationPaused) {
214
+ return;
215
+ }
216
+
217
+ const margin = this.isLargeDocument ? 180 : 420;
218
+ this.embedEntries.forEach((entry) => {
219
+ if (entry.wrapper || !entry.placeholder?.isConnected) {
220
+ return;
221
+ }
222
+
223
+ if (isNearViewport(entry.placeholder, this.previewContainer, margin)) {
224
+ this._enqueueHydration(entry, { prioritize: true });
225
+ }
226
+ });
227
+ }
228
+
229
+ updateTheme(theme) {
230
+ this.embedEntries.forEach((entry) => {
231
+ this._postMessageToEntry(entry, {
232
+ source: 'collabmd-host',
233
+ type: 'set-theme',
234
+ theme,
235
+ });
236
+ });
237
+ }
238
+
239
+ updateLocalUser(user) {
240
+ this.embedEntries.forEach((entry) => {
241
+ this._syncEntryUser(entry, user);
242
+ });
243
+ }
244
+
245
+ _ensurePlaceholderObserver() {
246
+ if (!this.previewContainer) {
247
+ return;
248
+ }
249
+
250
+ this.placeholderObserver = new IntersectionObserver((entries) => {
251
+ entries.forEach((entry) => {
252
+ if (!entry.isIntersecting) {
253
+ return;
254
+ }
255
+
256
+ const embedEntry = this.embedEntries.get(entry.target.dataset.embedKey);
257
+ if (embedEntry) {
258
+ this._enqueueHydration(embedEntry);
259
+ }
260
+ });
261
+ }, {
262
+ root: this.previewContainer,
263
+ rootMargin: this.isLargeDocument ? '180px 0px' : '420px 0px',
264
+ });
265
+ }
266
+
267
+ _disconnectPlaceholderObserver() {
268
+ if (!this.placeholderObserver) {
269
+ return;
270
+ }
271
+
272
+ this.placeholderObserver.disconnect();
273
+ this.placeholderObserver = null;
274
+ }
275
+
276
+ _enqueueHydration(entry, { prioritize = false } = {}) {
277
+ if (!entry || entry.wrapper || entry.queued) {
278
+ return;
279
+ }
280
+
281
+ entry.queued = true;
282
+ if (prioritize) {
283
+ this.hydrationQueue.unshift(entry.key);
284
+ } else {
285
+ this.hydrationQueue.push(entry.key);
286
+ }
287
+
288
+ if (this.hydrationPaused) {
289
+ return;
290
+ }
291
+
292
+ if (prioritize && !this.hydrationInProgress && this.hydrationIdleId === null) {
293
+ void this._flushHydrationQueue();
294
+ return;
295
+ }
296
+
297
+ this._scheduleHydration();
298
+ }
299
+
300
+ _scheduleHydration() {
301
+ if (this.hydrationPaused || this.hydrationInProgress || this.hydrationIdleId !== null) {
302
+ return;
303
+ }
304
+
305
+ this.hydrationIdleId = requestIdleRender(() => {
306
+ this.hydrationIdleId = null;
307
+ void this._flushHydrationQueue();
308
+ }, HYDRATE_TIMEOUT_MS);
309
+ }
310
+
311
+ async _flushHydrationQueue() {
312
+ if (this.hydrationPaused || this.hydrationInProgress) {
313
+ return;
314
+ }
315
+
316
+ let nextEntry = null;
317
+ while (this.hydrationQueue.length > 0 && !nextEntry) {
318
+ const key = this.hydrationQueue.shift();
319
+ const entry = this.embedEntries.get(key);
320
+ if (!entry || entry.wrapper || !entry.placeholder?.isConnected) {
321
+ if (entry) {
322
+ entry.queued = false;
323
+ }
324
+ continue;
325
+ }
326
+
327
+ nextEntry = entry;
328
+ }
329
+
330
+ if (!nextEntry) {
331
+ return;
332
+ }
333
+
334
+ this.hydrationInProgress = true;
335
+ nextEntry.queued = false;
336
+
337
+ await this._hydrateEntry(nextEntry);
338
+
339
+ this.hydrationInProgress = false;
340
+ if (this.hydrationQueue.length > 0) {
341
+ this._scheduleHydration();
342
+ }
343
+ }
344
+
345
+ async _hydrateEntry(entry) {
346
+ if (!entry.placeholder?.isConnected && !entry.wrapper) {
347
+ return;
348
+ }
349
+
350
+ if (!entry.wrapper) {
351
+ const mount = this._createEmbedContainer(entry);
352
+ entry.wrapper = mount.wrapper;
353
+ entry.iframe = mount.iframe;
354
+ entry.labelElement = mount.labelElement;
355
+ entry.instanceId = mount.instanceId;
356
+ entry.isReady = false;
357
+ entry.bootAttempts = (entry.bootAttempts ?? 0) + 1;
358
+ this._armEntryBootTimeout(entry);
359
+ }
360
+
361
+ entry.followedPeerId = this.followedPeerIdsByFilePath.get(entry.filePath);
362
+ this._updateEmbedLabel(entry);
363
+ this._attachWrapper(entry);
364
+ }
365
+
366
+ _attachWrapper(entry) {
367
+ const placeholder = entry.placeholder?.isConnected
368
+ ? entry.placeholder
369
+ : this.previewElement?.querySelector(`.excalidraw-embed-placeholder[data-embed-key="${entry.key}"]`);
370
+
371
+ if (!placeholder) {
372
+ return;
373
+ }
374
+
375
+ entry.placeholder = placeholder;
376
+ this._syncMountedEntryMetadata(entry);
377
+ if (this._shouldInlineFilePreview(entry)) {
378
+ entry.wrapper.style.position = '';
379
+ entry.wrapper.style.top = '';
380
+ entry.wrapper.style.left = '';
381
+ entry.wrapper.style.width = '';
382
+ entry.wrapper.style.margin = '';
383
+ entry.wrapper.style.pointerEvents = 'auto';
384
+ placeholder.replaceWith(entry.wrapper);
385
+ entry.placeholder = null;
386
+ return;
387
+ }
388
+
389
+ const overlayRoot = this._ensureOverlayRoot();
390
+ overlayRoot.hidden = false;
391
+ if (entry.wrapper?.parentElement !== overlayRoot) {
392
+ overlayRoot.appendChild(entry.wrapper);
393
+ }
394
+
395
+ this._syncEntryLayout(entry);
396
+ }
397
+
398
+ _adoptReusableEntries(nextEntries, removedEntries) {
399
+ nextEntries.forEach((nextEntry, key) => {
400
+ if (nextEntry.wrapper || nextEntry.iframe) {
401
+ return;
402
+ }
403
+
404
+ const removedIndex = removedEntries.findIndex((entry) => (
405
+ entry.filePath === nextEntry.filePath
406
+ && this._getEntryMode(entry) === this._getEntryMode(nextEntry)
407
+ && (entry.wrapper || entry.iframe)
408
+ ));
409
+ if (removedIndex < 0) {
410
+ return;
411
+ }
412
+
413
+ const [reusedEntry] = removedEntries.splice(removedIndex, 1);
414
+ reusedEntry.filePath = nextEntry.filePath;
415
+ reusedEntry.key = nextEntry.key;
416
+ reusedEntry.label = nextEntry.label;
417
+ reusedEntry.placeholder = nextEntry.placeholder;
418
+ reusedEntry.queued = false;
419
+ reusedEntry.reusedFromEmbed = this._isFilePreviewEntry(nextEntry);
420
+ nextEntries.set(key, reusedEntry);
421
+ });
422
+ }
423
+
424
+ _destroyEntry(entry) {
425
+ if (this.maximizedEmbed?.wrapper === entry.wrapper) {
426
+ this._exitMaximizedEmbed();
427
+ }
428
+
429
+ this._clearEntryBootTimeout(entry);
430
+ this._resetPlaceholderLayout(entry);
431
+ entry.wrapper?.remove();
432
+ entry.placeholder = null;
433
+ }
434
+
435
+ _armEntryBootTimeout(entry) {
436
+ this._clearEntryBootTimeout(entry);
437
+ entry.bootTimerId = window.setTimeout(() => {
438
+ void this._handleEntryBootTimeout(entry);
439
+ }, IFRAME_BOOT_TIMEOUT_MS);
440
+ }
441
+
442
+ _clearEntryBootTimeout(entry) {
443
+ if (!entry?.bootTimerId) {
444
+ return;
445
+ }
446
+
447
+ window.clearTimeout(entry.bootTimerId);
448
+ entry.bootTimerId = null;
449
+ }
450
+
451
+ async _handleEntryBootTimeout(entry) {
452
+ if (!entry?.iframe?.isConnected) {
453
+ return;
454
+ }
455
+
456
+ if ((entry.bootAttempts ?? 0) >= MAX_IFRAME_BOOT_ATTEMPTS) {
457
+ this._clearEntryBootTimeout(entry);
458
+ this.toastController?.show(`Excalidraw embed timed out: ${entry.label}`);
459
+ return;
460
+ }
461
+
462
+ await this._retryEntryBootstrap(entry);
463
+ }
464
+
465
+ async _retryEntryBootstrap(entry) {
466
+ if (!entry) {
467
+ return;
468
+ }
469
+
470
+ this._clearEntryBootTimeout(entry);
471
+ this._resetPlaceholderLayout(entry);
472
+
473
+ if (this.maximizedEmbed?.wrapper === entry.wrapper) {
474
+ this._exitMaximizedEmbed();
475
+ }
476
+
477
+ entry.wrapper?.remove();
478
+ entry.wrapper = null;
479
+ entry.iframe = null;
480
+ entry.labelElement = null;
481
+ entry.instanceId = null;
482
+ entry.isReady = false;
483
+
484
+ await this._hydrateEntry(entry);
485
+ }
486
+
487
+ _findEntryByContentWindow(contentWindow) {
488
+ if (!contentWindow) {
489
+ return null;
490
+ }
491
+
492
+ for (const entry of this.embedEntries.values()) {
493
+ if (entry.iframe?.contentWindow === contentWindow) {
494
+ return entry;
495
+ }
496
+ }
497
+
498
+ return null;
499
+ }
500
+
501
+ _findEntryByFilePath(filePath) {
502
+ if (!filePath) {
503
+ return null;
504
+ }
505
+
506
+ for (const entry of this.embedEntries.values()) {
507
+ if (entry.filePath === filePath) {
508
+ return entry;
509
+ }
510
+ }
511
+
512
+ return null;
513
+ }
514
+
515
+ _updateEmbedLabel(entry) {
516
+ if (entry.labelElement) {
517
+ entry.labelElement.textContent = entry.label.replace(/\.excalidraw$/i, '');
518
+ }
519
+ }
520
+
521
+ _syncMountedEntryMetadata(entry) {
522
+ if (entry.wrapper) {
523
+ entry.wrapper.dataset.embedKey = entry.key;
524
+ entry.wrapper.dataset.file = entry.filePath;
525
+ }
526
+
527
+ if (entry.iframe) {
528
+ entry.iframe.title = `Excalidraw: ${entry.filePath}`;
529
+ }
530
+ }
531
+
532
+ _buildIframeUrl(entry) {
533
+ const iframeUrl = new URL(resolveAppUrl(EDITOR_IFRAME_PATH));
534
+ const theme = this.getTheme?.() || 'dark';
535
+
536
+ iframeUrl.searchParams.set('file', entry.filePath);
537
+ iframeUrl.searchParams.set('theme', theme);
538
+ iframeUrl.searchParams.set('boot', entry.instanceId || '');
539
+ if (!this._isFilePreviewEntry(entry)) {
540
+ iframeUrl.searchParams.set('mode', 'preview');
541
+ }
542
+
543
+ const localUser = this.getLocalUser?.();
544
+ if (localUser?.name) {
545
+ iframeUrl.searchParams.set('userName', localUser.name);
546
+ }
547
+ if (localUser?.color) {
548
+ iframeUrl.searchParams.set('userColor', localUser.color);
549
+ }
550
+ if (localUser?.colorLight) {
551
+ iframeUrl.searchParams.set('userColorLight', localUser.colorLight);
552
+ }
553
+ if (localUser?.peerId) {
554
+ iframeUrl.searchParams.set('userPeerId', localUser.peerId);
555
+ }
556
+
557
+ const hostSearchParams = new URLSearchParams(window.location.search);
558
+ const serverOverride = hostSearchParams.get('server');
559
+ if (serverOverride) {
560
+ iframeUrl.searchParams.set('server', serverOverride);
561
+ }
562
+ if (hostSearchParams.get('test') === '1') {
563
+ iframeUrl.searchParams.set('test', '1');
564
+ }
565
+ if (hostSearchParams.has('syncTimeoutMs')) {
566
+ iframeUrl.searchParams.set('syncTimeoutMs', hostSearchParams.get('syncTimeoutMs'));
567
+ }
568
+
569
+ return iframeUrl;
570
+ }
571
+
572
+ _createEmbedContainer(entry) {
573
+ const wrapper = document.createElement('div');
574
+ wrapper.className = 'excalidraw-embed diagram-preview-shell';
575
+ wrapper.dataset.embedKey = entry.key;
576
+ wrapper.dataset.file = entry.filePath;
577
+
578
+ const header = document.createElement('div');
579
+ header.className = 'excalidraw-embed-header diagram-preview-toolbar';
580
+
581
+ const icon = document.createElement('span');
582
+ icon.className = 'excalidraw-embed-icon';
583
+ icon.innerHTML = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/></svg>`;
584
+
585
+ const label = document.createElement('span');
586
+ label.className = 'excalidraw-embed-label';
587
+ label.textContent = entry.label.replace(/\.excalidraw$/i, '');
588
+
589
+ const openBtn = document.createElement('button');
590
+ openBtn.type = 'button';
591
+ openBtn.className = 'excalidraw-embed-btn diagram-preview-action-btn';
592
+ openBtn.title = 'Edit in Excalidraw';
593
+ openBtn.setAttribute('aria-label', 'Edit in Excalidraw');
594
+ setDiagramActionButtonIcon(openBtn, 'edit');
595
+
596
+ const maxBtn = document.createElement('button');
597
+ maxBtn.type = 'button';
598
+ maxBtn.className = 'excalidraw-embed-btn diagram-preview-action-btn';
599
+ maxBtn.title = 'Maximize diagram';
600
+ maxBtn.setAttribute('aria-label', 'Maximize diagram');
601
+ setDiagramActionButtonIcon(maxBtn, 'maximize');
602
+
603
+ header.append(icon, label);
604
+ if (!this._isFilePreviewEntry(entry)) {
605
+ header.append(openBtn);
606
+ }
607
+ header.append(maxBtn);
608
+
609
+ const iframe = document.createElement('iframe');
610
+ iframe.className = 'excalidraw-embed-iframe';
611
+ iframe.dataset.instanceId = String(++this.instanceCounter);
612
+ entry.instanceId = iframe.dataset.instanceId;
613
+ iframe.src = this._buildIframeUrl(entry).toString();
614
+ // The controller already lazy-hydrates embeds near the viewport, so the
615
+ // iframe should start loading immediately once it has been mounted.
616
+ iframe.setAttribute('loading', 'eager');
617
+ iframe.title = `Excalidraw: ${entry.filePath}`;
618
+ iframe.style.height = `${DEFAULT_HEIGHT}px`;
619
+
620
+ const resizer = document.createElement('div');
621
+ resizer.className = 'excalidraw-embed-resizer';
622
+ resizer.title = 'Drag to resize';
623
+ this._setupResizer(resizer, iframe, () => this._syncEntryLayout(entry));
624
+
625
+ wrapper.append(header, iframe, resizer);
626
+
627
+ let isMaximized = false;
628
+ let restoreHeight = `${DEFAULT_HEIGHT}px`;
629
+
630
+ const syncMaximizeButtonState = () => {
631
+ setDiagramActionButtonIcon(maxBtn, isMaximized ? 'restore' : 'maximize');
632
+ maxBtn.title = isMaximized ? 'Restore diagram size' : 'Maximize diagram';
633
+ maxBtn.setAttribute('aria-label', isMaximized ? 'Restore diagram size' : 'Maximize diagram');
634
+ };
635
+
636
+ const exitMaximize = () => {
637
+ if (!isMaximized) return;
638
+ isMaximized = false;
639
+ wrapper.classList.remove('is-maximized');
640
+ syncMaximizeButtonState();
641
+ document.body.classList.remove('excalidraw-maximized-open');
642
+ this._restoreWrapperMount(entry);
643
+ iframe.style.height = restoreHeight;
644
+ if (this.maximizedEmbed?.wrapper === wrapper) {
645
+ this.maximizedEmbed = null;
646
+ }
647
+ this._syncEntryLayout(entry);
648
+ };
649
+
650
+ const enterMaximize = () => {
651
+ if (isMaximized) return;
652
+ this._exitMaximizedEmbed();
653
+ isMaximized = true;
654
+ restoreHeight = iframe.style.height || `${DEFAULT_HEIGHT}px`;
655
+ this._mountWrapperInMaximizedRoot(entry);
656
+ wrapper.classList.add('is-maximized');
657
+ syncMaximizeButtonState();
658
+ document.body.classList.add('excalidraw-maximized-open');
659
+ this.maximizedEmbed = { wrapper, exit: exitMaximize };
660
+ this._syncEntryLayout(entry);
661
+ };
662
+
663
+ maxBtn.addEventListener('click', () => {
664
+ if (isMaximized) {
665
+ exitMaximize();
666
+ } else {
667
+ enterMaximize();
668
+ }
669
+ });
670
+ openBtn.addEventListener('click', () => {
671
+ this.onOpenFile?.(entry.filePath);
672
+ });
673
+
674
+ syncMaximizeButtonState();
675
+
676
+ return {
677
+ iframe,
678
+ instanceId: iframe.dataset.instanceId,
679
+ labelElement: label,
680
+ wrapper,
681
+ };
682
+ }
683
+
684
+ _setupResizer(resizer, iframe, onResizeEnd = null) {
685
+ let startY = 0;
686
+ let startHeight = 0;
687
+
688
+ const onPointerMove = (event) => {
689
+ const delta = event.clientY - startY;
690
+ const newHeight = Math.min(Math.max(startHeight + delta, MIN_HEIGHT), MAX_HEIGHT);
691
+ iframe.style.height = `${newHeight}px`;
692
+ iframe.style.pointerEvents = 'none';
693
+ };
694
+
695
+ const onPointerUp = () => {
696
+ iframe.style.pointerEvents = '';
697
+ document.removeEventListener('pointermove', onPointerMove);
698
+ document.removeEventListener('pointerup', onPointerUp);
699
+ onResizeEnd?.();
700
+ };
701
+
702
+ resizer.addEventListener('pointerdown', (event) => {
703
+ event.preventDefault();
704
+ startY = event.clientY;
705
+ startHeight = iframe.offsetHeight;
706
+ document.addEventListener('pointermove', onPointerMove);
707
+ document.addEventListener('pointerup', onPointerUp);
708
+ });
709
+ }
710
+
711
+ _ensureOverlayRoot() {
712
+ if (this.overlayRoot?.isConnected && this.overlayRoot.parentElement === this.previewElement) {
713
+ return this.overlayRoot;
714
+ }
715
+
716
+ let overlayRoot = this.previewElement?.querySelector('[data-excalidraw-overlay-root="true"]');
717
+ if (!overlayRoot) {
718
+ overlayRoot = document.createElement('div');
719
+ overlayRoot.dataset.excalidrawOverlayRoot = 'true';
720
+ overlayRoot.className = 'excalidraw-embed-overlay-root';
721
+ this.previewElement?.appendChild(overlayRoot);
722
+ }
723
+
724
+ this.overlayRoot = overlayRoot;
725
+ return overlayRoot;
726
+ }
727
+
728
+ _ensureMaximizedRoot() {
729
+ if (this.maximizedRoot?.isConnected && this.maximizedRoot.parentElement === document.body) {
730
+ return this.maximizedRoot;
731
+ }
732
+
733
+ let maximizedRoot = document.body.querySelector('[data-excalidraw-maximized-root="true"]');
734
+ if (!maximizedRoot) {
735
+ maximizedRoot = document.createElement('div');
736
+ maximizedRoot.dataset.excalidrawMaximizedRoot = 'true';
737
+ maximizedRoot.className = 'excalidraw-maximized-root';
738
+ document.body.appendChild(maximizedRoot);
739
+ }
740
+
741
+ this.maximizedRoot = maximizedRoot;
742
+ return maximizedRoot;
743
+ }
744
+
745
+ _isFilePreviewEntry(entry) {
746
+ return entry?.key === `${entry?.filePath}#file-preview`;
747
+ }
748
+
749
+ _getEntryMode(entry) {
750
+ return this._isFilePreviewEntry(entry) ? 'edit' : 'preview';
751
+ }
752
+
753
+ _shouldInlineFilePreview(entry) {
754
+ return this._isFilePreviewEntry(entry) && !entry?.reusedFromEmbed;
755
+ }
756
+
757
+ _resetPlaceholderLayout(entry) {
758
+ if (!entry?.placeholder?.isConnected || this._shouldInlineFilePreview(entry)) {
759
+ return;
760
+ }
761
+
762
+ entry.placeholder.classList.remove('is-hydrated');
763
+ entry.placeholder.removeAttribute('data-embed-hydrated');
764
+ entry.placeholder.style.height = '';
765
+ entry.placeholder.style.pointerEvents = '';
766
+ }
767
+
768
+ _mountWrapperInMaximizedRoot(entry) {
769
+ if (!entry?.wrapper) {
770
+ return;
771
+ }
772
+
773
+ const maximizedRoot = this._ensureMaximizedRoot();
774
+ maximizedRoot.hidden = false;
775
+ entry.restoreParent = entry.wrapper.parentElement || null;
776
+ entry.restoreNextSibling = entry.wrapper.nextSibling || null;
777
+ entry.wrapper.style.position = '';
778
+ entry.wrapper.style.top = '';
779
+ entry.wrapper.style.left = '';
780
+ entry.wrapper.style.width = '';
781
+ entry.wrapper.style.margin = '';
782
+ if (entry.wrapper.parentElement !== maximizedRoot) {
783
+ maximizedRoot.appendChild(entry.wrapper);
784
+ }
785
+ }
786
+
787
+ _restoreWrapperMount(entry) {
788
+ if (!entry?.wrapper) {
789
+ return;
790
+ }
791
+
792
+ if (this._shouldInlineFilePreview(entry)) {
793
+ const { restoreParent, restoreNextSibling } = entry;
794
+ if (restoreParent?.isConnected) {
795
+ if (restoreNextSibling?.parentElement === restoreParent) {
796
+ restoreParent.insertBefore(entry.wrapper, restoreNextSibling);
797
+ } else {
798
+ restoreParent.appendChild(entry.wrapper);
799
+ }
800
+ }
801
+ } else {
802
+ const overlayRoot = this._ensureOverlayRoot();
803
+ overlayRoot.hidden = false;
804
+ if (entry.wrapper.parentElement !== overlayRoot) {
805
+ overlayRoot.appendChild(entry.wrapper);
806
+ }
807
+ }
808
+
809
+ entry.restoreParent = null;
810
+ entry.restoreNextSibling = null;
811
+
812
+ if (this.maximizedRoot && this.maximizedRoot.childElementCount === 0) {
813
+ this.maximizedRoot.hidden = true;
814
+ }
815
+ }
816
+
817
+ _syncEntryLayout(entry) {
818
+ if (!entry?.wrapper || this._shouldInlineFilePreview(entry)) {
819
+ return;
820
+ }
821
+
822
+ const placeholder = entry.placeholder?.isConnected
823
+ ? entry.placeholder
824
+ : this.previewElement?.querySelector(`.excalidraw-embed-placeholder[data-embed-key="${entry.key}"]`);
825
+
826
+ if (!placeholder) {
827
+ return;
828
+ }
829
+
830
+ entry.placeholder = placeholder;
831
+ placeholder.classList.add('is-hydrated');
832
+ placeholder.dataset.embedHydrated = 'true';
833
+ placeholder.style.pointerEvents = 'none';
834
+ if (this._isFilePreviewEntry(entry) && placeholder.childElementCount > 0) {
835
+ placeholder.replaceChildren();
836
+ }
837
+
838
+ const isMaximized = entry.wrapper.classList.contains('is-maximized');
839
+ const headerHeight = entry.wrapper.querySelector('.excalidraw-embed-header')?.offsetHeight || 0;
840
+ const iframeHeight = entry.iframe?.offsetHeight
841
+ || Number.parseFloat(entry.iframe?.style.height || '')
842
+ || DEFAULT_HEIGHT;
843
+ const resizerHeight = isMaximized
844
+ ? 0
845
+ : (entry.wrapper.querySelector('.excalidraw-embed-resizer')?.offsetHeight || 0);
846
+ const inlineHeight = Math.ceil(headerHeight + iframeHeight + resizerHeight);
847
+
848
+ if (!isMaximized) {
849
+ entry.inlineHeightPx = inlineHeight;
850
+ }
851
+
852
+ placeholder.style.height = `${Math.ceil(entry.inlineHeightPx || inlineHeight || DEFAULT_HEIGHT)}px`;
853
+ entry.wrapper.style.pointerEvents = 'auto';
854
+
855
+ if (isMaximized) {
856
+ entry.wrapper.style.position = '';
857
+ entry.wrapper.style.top = '';
858
+ entry.wrapper.style.left = '';
859
+ entry.wrapper.style.width = '';
860
+ entry.wrapper.style.margin = '';
861
+ return;
862
+ }
863
+
864
+ entry.wrapper.style.position = 'absolute';
865
+ entry.wrapper.style.top = `${placeholder.offsetTop}px`;
866
+ entry.wrapper.style.left = `${placeholder.offsetLeft}px`;
867
+ entry.wrapper.style.width = `${placeholder.offsetWidth}px`;
868
+ entry.wrapper.style.margin = '0';
869
+ }
870
+
871
+ syncLayout() {
872
+ this.embedEntries.forEach((entry) => {
873
+ if (entry.wrapper && !this._shouldInlineFilePreview(entry)) {
874
+ this._syncEntryLayout(entry);
875
+ }
876
+ });
877
+ }
878
+
879
+ _onPreviewClick(event) {
880
+ const loadButton = event.target.closest('.excalidraw-embed-placeholder-btn');
881
+ if (!loadButton) {
882
+ return;
883
+ }
884
+
885
+ event.preventDefault();
886
+ const entry = this.embedEntries.get(loadButton.dataset.embedKey);
887
+ if (entry) {
888
+ void this._hydrateEntry(entry);
889
+ }
890
+ }
891
+
892
+ _onMessage(event) {
893
+ if (event.origin !== window.location.origin) return;
894
+ const msg = event.data;
895
+ if (!msg || msg.source !== 'excalidraw-editor') return;
896
+
897
+ const entry = this._findEntryByContentWindow(event.source);
898
+ if (!entry) {
899
+ return;
900
+ }
901
+
902
+ if (msg.type === 'ready') {
903
+ entry.isReady = true;
904
+ this._clearEntryBootTimeout(entry);
905
+ this._syncEntryUser(entry);
906
+ this._postMessageToEntry(entry, {
907
+ source: 'collabmd-host',
908
+ type: 'set-theme',
909
+ theme: this.getTheme?.() || 'dark',
910
+ });
911
+ this._syncEntryFollowState(entry);
912
+ return;
913
+ }
914
+
915
+ if (msg.type === 'error') {
916
+ entry.isReady = false;
917
+ void this._handleEntryBootTimeout(entry);
918
+ }
919
+ }
920
+
921
+ _onKeyDown(event) {
922
+ if (event.key === 'Escape') {
923
+ this._exitMaximizedEmbed();
924
+ }
925
+ }
926
+
927
+ _exitMaximizedEmbed() {
928
+ if (this.maximizedEmbed?.exit) {
929
+ this.maximizedEmbed.exit();
930
+ }
931
+ this.maximizedEmbed = null;
932
+ document.body.classList.remove('excalidraw-maximized-open');
933
+ }
934
+
935
+ _postMessageToEntry(entry, payload) {
936
+ entry?.iframe?.contentWindow?.postMessage(payload, window.location.origin);
937
+ }
938
+
939
+ _syncEntryUser(entry, overrideUser = null) {
940
+ const localUser = overrideUser || this.getLocalUser?.();
941
+ if (!localUser) {
942
+ return;
943
+ }
944
+
945
+ this._postMessageToEntry(entry, {
946
+ source: 'collabmd-host',
947
+ type: 'set-user',
948
+ user: {
949
+ color: localUser.color || '',
950
+ colorLight: localUser.colorLight || '',
951
+ name: localUser.name || '',
952
+ peerId: localUser.peerId || '',
953
+ },
954
+ });
955
+ }
956
+
957
+ _syncEntryFollowState(entry) {
958
+ if (!entry?.isReady || entry.followedPeerId === undefined) {
959
+ return;
960
+ }
961
+
962
+ this._postMessageToEntry(entry, {
963
+ source: 'collabmd-host',
964
+ type: 'follow-user',
965
+ peerId: entry.followedPeerId,
966
+ });
967
+ }
968
+ }