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.
- package/LICENSE +21 -0
- package/README.md +453 -0
- package/bin/collabmd.js +241 -0
- package/docker-compose.yml +43 -0
- package/package.json +93 -0
- package/public/assets/css/base.css +1 -0
- package/public/assets/css/style.css +1 -0
- package/public/assets/js/assets/Assistant-Bold-ZDZZ6JHA.woff2 +0 -0
- package/public/assets/js/assets/Assistant-Medium-DZ25RZU3.woff2 +0 -0
- package/public/assets/js/assets/Assistant-Regular-PLF2XOGW.woff2 +0 -0
- package/public/assets/js/assets/Assistant-SemiBold-CZ5MX6FK.woff2 +0 -0
- package/public/assets/js/chunks/CodeMirrorEditor-UCMRAMCV-MAKZFDBE.js +12 -0
- package/public/assets/js/chunks/apl-C5P5JBDI.js +1 -0
- package/public/assets/js/chunks/ar-SA-NXDWD63E-MF6HMEA4.js +8 -0
- package/public/assets/js/chunks/architecture-PBZL5I3N-55LDZ5WS.js +1 -0
- package/public/assets/js/chunks/architectureDiagram-2XIMDMQ5-2VP562X7.js +36 -0
- package/public/assets/js/chunks/asciiarmor-3NCLLELT.js +1 -0
- package/public/assets/js/chunks/asn1-KF4WXU3M.js +1 -0
- package/public/assets/js/chunks/asterisk-EA3VIN65.js +1 -0
- package/public/assets/js/chunks/az-AZ-MXSORGZV-AIGO4TNU.js +1 -0
- package/public/assets/js/chunks/bg-BG-O6MV2KSF-X6AVO2AF.js +5 -0
- package/public/assets/js/chunks/blockDiagram-WCTKOSBZ-KM56WWDE.js +132 -0
- package/public/assets/js/chunks/bn-BD-T2VJNT7N-7OMHRIGC.js +3 -0
- package/public/assets/js/chunks/bn-IN-MMW2ORAC-EPKMNKG7.js +3 -0
- package/public/assets/js/chunks/brainfuck-A3CTQVFD.js +1 -0
- package/public/assets/js/chunks/c4Diagram-IC4MRINW-KX6UEGQZ.js +10 -0
- package/public/assets/js/chunks/ca-ES-MKBCGNOG-U44SUUTN.js +8 -0
- package/public/assets/js/chunks/chunk-2NTQWLZD.js +25 -0
- package/public/assets/js/chunks/chunk-2YRP2AWD.js +1 -0
- package/public/assets/js/chunks/chunk-3BUCGSSJ.js +1 -0
- package/public/assets/js/chunks/chunk-47L7JGE3.js +1 -0
- package/public/assets/js/chunks/chunk-4BCHPULB.js +1 -0
- package/public/assets/js/chunks/chunk-4NKM6YFO.js +161 -0
- package/public/assets/js/chunks/chunk-4WGMPBK5.js +1 -0
- package/public/assets/js/chunks/chunk-55WF6Y2Q.js +1 -0
- package/public/assets/js/chunks/chunk-775E65SU.js +1 -0
- package/public/assets/js/chunks/chunk-AJRGTECU.js +70 -0
- package/public/assets/js/chunks/chunk-B2J3PHGY.js +1 -0
- package/public/assets/js/chunks/chunk-B4JKB3BC.js +1 -0
- package/public/assets/js/chunks/chunk-BBHPYU2R.js +1 -0
- package/public/assets/js/chunks/chunk-CGVY4PKT.js +13 -0
- package/public/assets/js/chunks/chunk-CVTRX3TE.js +220 -0
- package/public/assets/js/chunks/chunk-DW6KK6VF.js +1 -0
- package/public/assets/js/chunks/chunk-E2HMNOQL.js +189 -0
- package/public/assets/js/chunks/chunk-EPTJZP5H.js +7 -0
- package/public/assets/js/chunks/chunk-G7NUGGE7.js +13 -0
- package/public/assets/js/chunks/chunk-GI7LBIBP.js +1 -0
- package/public/assets/js/chunks/chunk-GXRL27M7.js +1 -0
- package/public/assets/js/chunks/chunk-H6EYDHRW.js +1 -0
- package/public/assets/js/chunks/chunk-HOCBCDA5.js +1 -0
- package/public/assets/js/chunks/chunk-HS2CUOC6.js +1 -0
- package/public/assets/js/chunks/chunk-HUAS4BYI.js +12 -0
- package/public/assets/js/chunks/chunk-HVNNEPP5.js +2 -0
- package/public/assets/js/chunks/chunk-I2GVZI7W.js +38 -0
- package/public/assets/js/chunks/chunk-I6PVWGBN.js +14 -0
- package/public/assets/js/chunks/chunk-IR2DOYV4.js +7 -0
- package/public/assets/js/chunks/chunk-IZ3V3F2A.js +1 -0
- package/public/assets/js/chunks/chunk-KPAQHIOI.js +1 -0
- package/public/assets/js/chunks/chunk-M3EW4V74.js +1 -0
- package/public/assets/js/chunks/chunk-MK3AFU3C.js +90 -0
- package/public/assets/js/chunks/chunk-NM6J3ND7.js +1 -0
- package/public/assets/js/chunks/chunk-NO7UPWTU.js +1 -0
- package/public/assets/js/chunks/chunk-OG2TNZEU.js +9 -0
- package/public/assets/js/chunks/chunk-OHGDMMWM.js +1 -0
- package/public/assets/js/chunks/chunk-OOT2HALX.js +1 -0
- package/public/assets/js/chunks/chunk-OQLLZFFN.js +1 -0
- package/public/assets/js/chunks/chunk-PF6TP4EI.js +1 -0
- package/public/assets/js/chunks/chunk-PMOZMECZ.js +85 -0
- package/public/assets/js/chunks/chunk-QBGS6DJR.js +1 -0
- package/public/assets/js/chunks/chunk-QF3ZQ6UQ.js +1 -0
- package/public/assets/js/chunks/chunk-QFXMAUW4.js +1 -0
- package/public/assets/js/chunks/chunk-QSTBGTWJ.js +1 -0
- package/public/assets/js/chunks/chunk-QYKIT2IH.js +41 -0
- package/public/assets/js/chunks/chunk-S75BI2UQ.js +1 -0
- package/public/assets/js/chunks/chunk-SKEZZ3H6.js +1 -0
- package/public/assets/js/chunks/chunk-SO6QBCB6.js +1 -0
- package/public/assets/js/chunks/chunk-SR3U53EQ.js +1 -0
- package/public/assets/js/chunks/chunk-TFP6LRYJ.js +53 -0
- package/public/assets/js/chunks/chunk-U6APNHAF.js +15 -0
- package/public/assets/js/chunks/chunk-VOODXHXA.js +1 -0
- package/public/assets/js/chunks/chunk-W7WJUTSA.js +3 -0
- package/public/assets/js/chunks/chunk-WNXFO2F2.js +1 -0
- package/public/assets/js/chunks/chunk-X6EEYWV4.js +6 -0
- package/public/assets/js/chunks/chunk-YVW3ZETS.js +1 -0
- package/public/assets/js/chunks/chunk-ZR2QRTBG.js +339 -0
- package/public/assets/js/chunks/chunk-ZZJX4LQ2.js +1 -0
- package/public/assets/js/chunks/classDiagram-VBA2DB6C-IYW4O2RM.js +1 -0
- package/public/assets/js/chunks/classDiagram-v2-RAHNMMFH-DNKVN2WD.js +1 -0
- package/public/assets/js/chunks/clike-RTBH33GE.js +1 -0
- package/public/assets/js/chunks/clojure-BR2VJ2JI.js +1 -0
- package/public/assets/js/chunks/cmake-2HEWVFEE.js +1 -0
- package/public/assets/js/chunks/cobol-V6EIK6DN.js +1 -0
- package/public/assets/js/chunks/coffeescript-JW3ZOGMD.js +1 -0
- package/public/assets/js/chunks/commonlisp-UCWSIHYK.js +1 -0
- package/public/assets/js/chunks/cose-bilkent-S5V4N54A-QVYRFFNC.js +1 -0
- package/public/assets/js/chunks/crystal-GR4VLC3M.js +1 -0
- package/public/assets/js/chunks/cs-CZ-V77HGUP7-OLBAKFG5.js +7 -0
- package/public/assets/js/chunks/css-C5DVWGB4.js +1 -0
- package/public/assets/js/chunks/cypher-K7FZM5GC.js +1 -0
- package/public/assets/js/chunks/d-CF3QNNH5.js +1 -0
- package/public/assets/js/chunks/da-DK-I5RFNTM4-QJIG2SEZ.js +2 -0
- package/public/assets/js/chunks/dagre-KLK3FWXG-KVNBUDOY.js +4 -0
- package/public/assets/js/chunks/de-CH-WLRDEVBV-4MMJDMVD.js +7 -0
- package/public/assets/js/chunks/de-DE-DTI4WUSC-ML7C46TT.js +7 -0
- package/public/assets/js/chunks/diagram-E7M64L7V-ZP33VRUC.js +24 -0
- package/public/assets/js/chunks/diagram-IFDJBPK2-ZG35YWOD.js +43 -0
- package/public/assets/js/chunks/diagram-P4PSJMXO-ZGIGM7D2.js +24 -0
- package/public/assets/js/chunks/diff-KOMSZU7O.js +1 -0
- package/public/assets/js/chunks/dist-7RQKSOUX.js +7 -0
- package/public/assets/js/chunks/dist-ARWGZ6MN.js +1 -0
- package/public/assets/js/chunks/dist-DPBSGC3Y.js +2 -0
- package/public/assets/js/chunks/dist-E36PJE5M.js +1 -0
- package/public/assets/js/chunks/dist-E5NM7OBW.js +1 -0
- package/public/assets/js/chunks/dist-ERADYPEK.js +1 -0
- package/public/assets/js/chunks/dist-F43RIHBZ.js +1 -0
- package/public/assets/js/chunks/dist-HAB5NIXI.js +1 -0
- package/public/assets/js/chunks/dist-HG23OLRA.js +1 -0
- package/public/assets/js/chunks/dist-IEJXBSDJ.js +1 -0
- package/public/assets/js/chunks/dist-IQA4KVJK.js +1 -0
- package/public/assets/js/chunks/dist-OIQTNVT2.js +3 -0
- package/public/assets/js/chunks/dist-PMZJ734S.js +1 -0
- package/public/assets/js/chunks/dist-RCQFQRLD.js +1 -0
- package/public/assets/js/chunks/dist-RQLC4GVI.js +1 -0
- package/public/assets/js/chunks/dist-RSJGLSKC.js +1 -0
- package/public/assets/js/chunks/dist-SGNQZVVX.js +1 -0
- package/public/assets/js/chunks/dist-VCFTF7Z6.js +1 -0
- package/public/assets/js/chunks/dist-VTO23SHH.js +1 -0
- package/public/assets/js/chunks/dist-XOODBV4L.js +1 -0
- package/public/assets/js/chunks/dist-ZFZNCRZY.js +1 -0
- package/public/assets/js/chunks/dockerfile-XCIKYOSI.js +1 -0
- package/public/assets/js/chunks/dtd-3XFH7W6Z.js +1 -0
- package/public/assets/js/chunks/dylan-3UWPKVOR.js +1 -0
- package/public/assets/js/chunks/ebnf-OLHTL3VN.js +1 -0
- package/public/assets/js/chunks/ecl-43LZ3ZRM.js +1 -0
- package/public/assets/js/chunks/editor-session-IHFTYG5D.js +22 -0
- package/public/assets/js/chunks/eiffel-ISPO2UJF.js +1 -0
- package/public/assets/js/chunks/el-GR-ZXDJ2OS4-WSCEIO6J.js +7 -0
- package/public/assets/js/chunks/elm-CLK576PK.js +1 -0
- package/public/assets/js/chunks/en-CTDJDZ6K-IC3QAUOI.js +1 -0
- package/public/assets/js/chunks/erDiagram-INFDFZHY-ZMS6H2TH.js +70 -0
- package/public/assets/js/chunks/erlang-AVQXQFOT.js +1 -0
- package/public/assets/js/chunks/es-ES-DYQHAD43-XGB5X5IM.js +7 -0
- package/public/assets/js/chunks/eu-ES-QDSYU5Y3-LA3JTIJ2.js +7 -0
- package/public/assets/js/chunks/excalidraw-mermaid-stub-NYXTOJ4H.js +1 -0
- package/public/assets/js/chunks/fa-IR-26LZG4PM-PFALMEDX.js +9 -0
- package/public/assets/js/chunks/factor-CRTVBD6Q.js +1 -0
- package/public/assets/js/chunks/fcl-FX24LKTH.js +1 -0
- package/public/assets/js/chunks/fi-FI-6YS4KDE4-ES5MV6P4.js +6 -0
- package/public/assets/js/chunks/flowDiagram-PKNHOUZH-QD4L5IE5.js +162 -0
- package/public/assets/js/chunks/forth-YKDKCTVS.js +1 -0
- package/public/assets/js/chunks/fortran-UJWC6SLU.js +1 -0
- package/public/assets/js/chunks/fr-FR-BRLLPTZC-VMFE22YV.js +12 -0
- package/public/assets/js/chunks/ganttDiagram-A5KZAMGK-VTMTQESP.js +292 -0
- package/public/assets/js/chunks/gas-MYEMWGRE.js +1 -0
- package/public/assets/js/chunks/gherkin-JWHAU2YG.js +1 -0
- package/public/assets/js/chunks/gitGraph-HDMCJU4V-YPHS74XX.js +1 -0
- package/public/assets/js/chunks/gitGraphDiagram-K3NZZRJ6-Z3EZ634T.js +65 -0
- package/public/assets/js/chunks/gl-ES-OKUZTLYG-GPT42ZHV.js +6 -0
- package/public/assets/js/chunks/groovy-QZIZQIAK.js +1 -0
- package/public/assets/js/chunks/haskell-JR3G7YNW.js +1 -0
- package/public/assets/js/chunks/haxe-TVLAIYEN.js +1 -0
- package/public/assets/js/chunks/he-IL-26MGYIU7-VQ5XQYYY.js +8 -0
- package/public/assets/js/chunks/hi-IN-Q4ZOGTP2-2Z766MXA.js +3 -0
- package/public/assets/js/chunks/http-YXQRE77G.js +1 -0
- package/public/assets/js/chunks/hu-HU-P2OXPSN5-6XDVPGTE.js +3 -0
- package/public/assets/js/chunks/id-ID-2EIKXYN6-J5GWSY2S.js +8 -0
- package/public/assets/js/chunks/idl-RAQGJ6LJ.js +1 -0
- package/public/assets/js/chunks/image-32MOCVDX-JN2EUMQG.js +1 -0
- package/public/assets/js/chunks/image-blob-reduce.esm-K5OWL55S.js +13 -0
- package/public/assets/js/chunks/info-3K5VOQVL-CXJSPNNP.js +1 -0
- package/public/assets/js/chunks/infoDiagram-LFFYTUFH-WQ34MUJA.js +2 -0
- package/public/assets/js/chunks/ishikawaDiagram-PHBUUO56-4IARWKJK.js +70 -0
- package/public/assets/js/chunks/it-IT-4CFKVXI2-NMBWUWFF.js +12 -0
- package/public/assets/js/chunks/ja-JP-MAND2Z4V-GQZYXXOC.js +7 -0
- package/public/assets/js/chunks/javascript-NM7KDJUE.js +1 -0
- package/public/assets/js/chunks/journeyDiagram-4ABVD52K-FJ4LF4SX.js +139 -0
- package/public/assets/js/chunks/julia-LG3BH25B.js +1 -0
- package/public/assets/js/chunks/kaa-HQRTCXTJ-7D6PAKDJ.js +1 -0
- package/public/assets/js/chunks/kab-KAB-JKIKKTGH-TNKFXNAX.js +4 -0
- package/public/assets/js/chunks/kanban-definition-K7BYSVSG-TY4EVYI3.js +89 -0
- package/public/assets/js/chunks/katex-5YJCUCFD.js +261 -0
- package/public/assets/js/chunks/kk-KZ-HXQ63ZFC-T4HCMWED.js +1 -0
- package/public/assets/js/chunks/km-KH-PKL3LSGX-HTLHEJV6.js +7 -0
- package/public/assets/js/chunks/ko-KR-KXLREZX3-QMR52QVI.js +5 -0
- package/public/assets/js/chunks/ku-TR-MJ4IER3X-K5CNY4UO.js +6 -0
- package/public/assets/js/chunks/livescript-4CVWVI4M.js +1 -0
- package/public/assets/js/chunks/lt-LT-H6WFQ6FJ-IW25FAGX.js +3 -0
- package/public/assets/js/chunks/lua-VWGE7DQ7.js +1 -0
- package/public/assets/js/chunks/lv-LV-GOCK6SJW-KTDFW5OH.js +4 -0
- package/public/assets/js/chunks/mathematica-D7APQSEU.js +1 -0
- package/public/assets/js/chunks/mbox-BN3XQBYX.js +1 -0
- package/public/assets/js/chunks/mermaid-runtime-BIFNJ2CT.js +18 -0
- package/public/assets/js/chunks/mindmap-definition-YRQLILUH-5B565RNP.js +68 -0
- package/public/assets/js/chunks/mirc-565WBI76.js +1 -0
- package/public/assets/js/chunks/mllike-VV3KS46B.js +1 -0
- package/public/assets/js/chunks/modelica-EGX44FZV.js +1 -0
- package/public/assets/js/chunks/mr-IN-IXVLDMEQ-PHM5DT7Q.js +9 -0
- package/public/assets/js/chunks/mscgen-GFGTHENT.js +1 -0
- package/public/assets/js/chunks/mumps-POZYWSMI.js +1 -0
- package/public/assets/js/chunks/my-MM-YG6MYTTD-ZHLCMEVA.js +1 -0
- package/public/assets/js/chunks/nb-NO-XGWJISD2-KSDFG6YU.js +8 -0
- package/public/assets/js/chunks/nginx-JUBX55EU.js +1 -0
- package/public/assets/js/chunks/nl-NL-XVDVCPNC-KVF3ZO2R.js +13 -0
- package/public/assets/js/chunks/nn-NO-EMX5MJX5-34QKSHNR.js +4 -0
- package/public/assets/js/chunks/nsis-RC4CREGM.js +1 -0
- package/public/assets/js/chunks/ntriples-4WK6CNVE.js +1 -0
- package/public/assets/js/chunks/oc-FR-ROEINTVO-5GP4AOYO.js +4 -0
- package/public/assets/js/chunks/octave-GOKFN2V7.js +1 -0
- package/public/assets/js/chunks/oz-OQUMNC63.js +1 -0
- package/public/assets/js/chunks/pa-IN-ZYN6SUDY-MVL7O44W.js +4 -0
- package/public/assets/js/chunks/packet-RMMSAZCW-D7XTR5TT.js +1 -0
- package/public/assets/js/chunks/pascal-BBWQWWWD.js +1 -0
- package/public/assets/js/chunks/percentages-5DKR754L-DG7W23CV.js +1 -0
- package/public/assets/js/chunks/perl-KTPJTTAM.js +1 -0
- package/public/assets/js/chunks/pica-6G3NROWT.js +17 -0
- package/public/assets/js/chunks/pie-UPGHQEXC-KGC3O6LN.js +1 -0
- package/public/assets/js/chunks/pieDiagram-SKSYHLDU-KWKRDEZS.js +30 -0
- package/public/assets/js/chunks/pig-IJMBS4FZ.js +1 -0
- package/public/assets/js/chunks/pl-PL-6VTG7PHC-VADRWSX4.js +12 -0
- package/public/assets/js/chunks/powershell-6YGCBHDP.js +1 -0
- package/public/assets/js/chunks/preview-render-compiler-WD3A76I6.js +25 -0
- package/public/assets/js/chunks/properties-5QTD3364.js +1 -0
- package/public/assets/js/chunks/protobuf-LTRWBIK3.js +1 -0
- package/public/assets/js/chunks/pt-BR-5YFKRR5G-HHF4UPO4.js +6 -0
- package/public/assets/js/chunks/pt-PT-GEIXXZ67-TUTAUZJK.js +8 -0
- package/public/assets/js/chunks/pug-U4PV3WLG.js +1 -0
- package/public/assets/js/chunks/puppet-WGYJPR3Y.js +1 -0
- package/public/assets/js/chunks/python-6YGH4S47.js +1 -0
- package/public/assets/js/chunks/q-VIG4IJLI.js +1 -0
- package/public/assets/js/chunks/quadrantDiagram-337W2JSQ-GWQRUFHQ.js +7 -0
- package/public/assets/js/chunks/quick-switcher-controller-JYDIJVAJ.js +5 -0
- package/public/assets/js/chunks/r-NVPCXGTR.js +1 -0
- package/public/assets/js/chunks/radar-KQ55EAFF-OPO64DRI.js +1 -0
- package/public/assets/js/chunks/requirementDiagram-Z7DCOOCP-ASW7IPJL.js +73 -0
- package/public/assets/js/chunks/ro-RO-E2P6TFZI-RJFCULYF.js +12 -0
- package/public/assets/js/chunks/roundRect-Z3DX3W5S.js +1 -0
- package/public/assets/js/chunks/rpm-UEA257HD.js +1 -0
- package/public/assets/js/chunks/ru-RU-YBIIY43T-BF27TNVK.js +10 -0
- package/public/assets/js/chunks/ruby-KPQRAJGE.js +1 -0
- package/public/assets/js/chunks/sankeyDiagram-WA2Y5GQK-W6BBWCLW.js +10 -0
- package/public/assets/js/chunks/sas-L7VATVH5.js +1 -0
- package/public/assets/js/chunks/scheme-T2NOWR3P.js +1 -0
- package/public/assets/js/chunks/sequenceDiagram-2WXFIKYE-H4G3ISLN.js +145 -0
- package/public/assets/js/chunks/shell-DLVDUNFA.js +1 -0
- package/public/assets/js/chunks/si-LK-673C2CI2-IOFGU4U2.js +1 -0
- package/public/assets/js/chunks/sieve-BKBZYDBU.js +1 -0
- package/public/assets/js/chunks/sk-SK-CKZHQ4AP-6O5JGN26.js +7 -0
- package/public/assets/js/chunks/sl-SI-557H2GWM-2NEHLV7W.js +6 -0
- package/public/assets/js/chunks/smalltalk-WRJQKJSD.js +1 -0
- package/public/assets/js/chunks/solr-66B3BIDL.js +1 -0
- package/public/assets/js/chunks/sparql-S25Z47JG.js +1 -0
- package/public/assets/js/chunks/spreadsheet-B272EF7Y.js +1 -0
- package/public/assets/js/chunks/sql-BPLIIUYC.js +1 -0
- package/public/assets/js/chunks/stateDiagram-RAJIS63D-OF5XXRUS.js +1 -0
- package/public/assets/js/chunks/stateDiagram-v2-FVOUBMTO-IV2CSQSQ.js +1 -0
- package/public/assets/js/chunks/stex-4IJY64QX.js +1 -0
- package/public/assets/js/chunks/stylus-PJUHLGPT.js +1 -0
- package/public/assets/js/chunks/subset-shared.chunk-4NMWHS4D.js +1 -0
- package/public/assets/js/chunks/subset-worker.chunk-NTLP7Y66.js +1 -0
- package/public/assets/js/chunks/sv-SE-XOPKKDWS-Q2L6KGFV.js +8 -0
- package/public/assets/js/chunks/swift-UYHTO4SX.js +1 -0
- package/public/assets/js/chunks/ta-IN-XBH7DQI3-ISSUGZAK.js +6 -0
- package/public/assets/js/chunks/tcl-OQ5J3VO2.js +1 -0
- package/public/assets/js/chunks/textile-NOGVBEYF.js +1 -0
- package/public/assets/js/chunks/th-TH-TOCWH3R4-TABEAMJA.js +1 -0
- package/public/assets/js/chunks/tiddlywiki-SYTK4QUE.js +1 -0
- package/public/assets/js/chunks/tiki-P7K4ZLOM.js +1 -0
- package/public/assets/js/chunks/timeline-definition-YZTLITO2-HBCANIUC.js +61 -0
- package/public/assets/js/chunks/toml-AUZYRP36.js +1 -0
- package/public/assets/js/chunks/tr-TR-GXW6CYY5-5NQRN52Y.js +4 -0
- package/public/assets/js/chunks/treemap-KZPCXAKY-WYMCT5F7.js +1 -0
- package/public/assets/js/chunks/troff-XFYJNQOJ.js +1 -0
- package/public/assets/js/chunks/ttcn-AK2IXWU6.js +1 -0
- package/public/assets/js/chunks/ttcn-cfg-3IDPIYPU.js +1 -0
- package/public/assets/js/chunks/turtle-OIDMF46P.js +1 -0
- package/public/assets/js/chunks/uk-UA-IJKTNUDG-2IIL3TO5.js +6 -0
- package/public/assets/js/chunks/uz-UZ-TBZZEA4V-X22KVKBP.js +1 -0
- package/public/assets/js/chunks/vb-J6K4XVA2.js +1 -0
- package/public/assets/js/chunks/vbscript-FM7DDZZE.js +1 -0
- package/public/assets/js/chunks/velocity-6KZFEOFD.js +1 -0
- package/public/assets/js/chunks/vennDiagram-LZ73GAT5-EBRF3MZR.js +34 -0
- package/public/assets/js/chunks/verilog-EWWQPMNN.js +1 -0
- package/public/assets/js/chunks/vhdl-CJ3M4IHI.js +1 -0
- package/public/assets/js/chunks/vi-VN-MULSGNVB-TENM65C7.js +7 -0
- package/public/assets/js/chunks/webidl-XVBHXCRV.js +1 -0
- package/public/assets/js/chunks/xquery-7WZOZ4UK.js +1 -0
- package/public/assets/js/chunks/xychartDiagram-JWTSCODW-WIFVRQPR.js +7 -0
- package/public/assets/js/chunks/yacas-MZ2ZZPF3.js +1 -0
- package/public/assets/js/chunks/z80-I447CBF7.js +1 -0
- package/public/assets/js/chunks/zh-CN-MVX3E32U-S5VA2BA5.js +11 -0
- package/public/assets/js/chunks/zh-HK-JNU5RLIE-A4VUKZFV.js +1 -0
- package/public/assets/js/chunks/zh-TW-LENVCA6T-KFB6KHMM.js +9 -0
- package/public/assets/js/excalidraw-editor-7ORML5YA.css +1 -0
- package/public/assets/js/excalidraw-editor-LKW2AZBU.js +347 -0
- package/public/assets/js/excalidraw-editor.css +1 -0
- package/public/assets/js/excalidraw-editor.js +1 -0
- package/public/assets/js/main.js +354 -0
- package/public/assets/js/preview-render-worker.js +30 -0
- package/public/assets/vendor/highlight/github-dark.min.css +10 -0
- package/public/assets/vendor/highlight/github.min.css +10 -0
- package/public/excalidraw-editor.html +31 -0
- package/public/index.html +549 -0
- package/scripts/cloudflare-tunnel.mjs +145 -0
- package/scripts/local-plantuml-compose.mjs +92 -0
- package/server.js +1 -0
- package/src/client/application/app-shell/chat-feature.js +363 -0
- package/src/client/application/app-shell/comments-feature.js +33 -0
- package/src/client/application/app-shell/git-feature.js +394 -0
- package/src/client/application/app-shell/presence-feature.js +229 -0
- package/src/client/application/app-shell/ui-feature.js +535 -0
- package/src/client/application/app-shell/workspace-feature.js +132 -0
- package/src/client/application/app-shell-elements.js +78 -0
- package/src/client/application/diagram-preview-hydrator.js +382 -0
- package/src/client/application/file-open-lifecycle.js +26 -0
- package/src/client/application/mermaid-preview-hydrator.js +570 -0
- package/src/client/application/plantuml-preview-hydrator.js +563 -0
- package/src/client/application/preview-diagram-utils.js +223 -0
- package/src/client/application/preview-render-compiler.js +426 -0
- package/src/client/application/preview-render-executor.js +153 -0
- package/src/client/application/preview-render-profile.js +63 -0
- package/src/client/application/preview-render-scheduler.js +73 -0
- package/src/client/application/preview-render-worker.js +19 -0
- package/src/client/application/preview-renderer.js +452 -0
- package/src/client/application/wiki-link-file-controller.js +58 -0
- package/src/client/application/workspace-chrome-controller.js +84 -0
- package/src/client/application/workspace-coordinator.js +238 -0
- package/src/client/application/workspace-preview-controller.js +237 -0
- package/src/client/application/workspace-route-controller.js +170 -0
- package/src/client/application/workspace-state-store.js +46 -0
- package/src/client/bootstrap/collabmd-app-shell.js +479 -0
- package/src/client/domain/diagram-action-icons.js +41 -0
- package/src/client/domain/excalidraw-collaboration.js +153 -0
- package/src/client/domain/excalidraw-scene.js +87 -0
- package/src/client/domain/markdown-formatting.js +370 -0
- package/src/client/domain/plantuml-language.js +226 -0
- package/src/client/domain/room.js +49 -0
- package/src/client/domain/runtime-paths.js +136 -0
- package/src/client/domain/vault-api-client.js +1 -0
- package/src/client/domain/vault-paths.js +80 -0
- package/src/client/domain/vault-utils.js +49 -0
- package/src/client/domain/wiki-link-completions.js +78 -0
- package/src/client/excalidraw-editor.js +630 -0
- package/src/client/excalidraw-mermaid-stub.js +7 -0
- package/src/client/infrastructure/auth-client.js +383 -0
- package/src/client/infrastructure/browser-navigation-port.js +19 -0
- package/src/client/infrastructure/browser-notification-port.js +40 -0
- package/src/client/infrastructure/browser-preferences-port.js +79 -0
- package/src/client/infrastructure/comment-thread-store.js +293 -0
- package/src/client/infrastructure/editor-collaboration-client.js +240 -0
- package/src/client/infrastructure/editor-session.js +255 -0
- package/src/client/infrastructure/editor-view-adapter.js +578 -0
- package/src/client/infrastructure/excalidraw-room-client.js +651 -0
- package/src/client/infrastructure/lobby-presence.js +304 -0
- package/src/client/infrastructure/runtime-config.js +65 -0
- package/src/client/infrastructure/tab-activity-lock.js +193 -0
- package/src/client/infrastructure/vault-api-client.js +61 -0
- package/src/client/infrastructure/yjs-provider-reset-guard.js +19 -0
- package/src/client/main.js +16 -0
- package/src/client/mermaid-runtime.js +3 -0
- package/src/client/presentation/backlinks-panel.js +188 -0
- package/src/client/presentation/comment-ui-controller.js +1235 -0
- package/src/client/presentation/comments-panel.js +531 -0
- package/src/client/presentation/excalidraw-embed-controller.js +968 -0
- package/src/client/presentation/excalidraw-embed-reconciler.js +37 -0
- package/src/client/presentation/file-action-controller.js +596 -0
- package/src/client/presentation/file-explorer-controller.js +81 -0
- package/src/client/presentation/file-explorer-view.js +256 -0
- package/src/client/presentation/file-tree-state.js +77 -0
- package/src/client/presentation/git-diff-view-controller.js +656 -0
- package/src/client/presentation/git-panel-controller.js +516 -0
- package/src/client/presentation/layout-controller.js +222 -0
- package/src/client/presentation/outline-controller.js +239 -0
- package/src/client/presentation/quick-switcher-controller.js +300 -0
- package/src/client/presentation/scroll-sync-controller.js +500 -0
- package/src/client/presentation/theme-controller.js +64 -0
- package/src/client/presentation/toast-controller.js +21 -0
- package/src/client/presentation/video-embed-controller.js +264 -0
- package/src/client/styles/base.css +58 -0
- package/src/client/styles/style.css +4245 -0
- package/src/domain/comment-threads.js +233 -0
- package/src/domain/excalidraw-room-codec.js +427 -0
- package/src/domain/file-kind.js +104 -0
- package/src/domain/wiki-link-resolver.js +75 -0
- package/src/server/auth/create-auth-service.js +272 -0
- package/src/server/auth/session-cookie.js +125 -0
- package/src/server/config/env.js +186 -0
- package/src/server/create-app-server.js +143 -0
- package/src/server/domain/backlink-index.js +291 -0
- package/src/server/domain/collaboration/collaboration-document-store.js +155 -0
- package/src/server/domain/collaboration/collaboration-room.js +603 -0
- package/src/server/domain/collaboration/protocol.js +2 -0
- package/src/server/domain/collaboration/room-client-state-store.js +28 -0
- package/src/server/domain/collaboration/room-persistence-controller.js +80 -0
- package/src/server/domain/collaboration/room-registry.js +94 -0
- package/src/server/domain/git-service.js +1 -0
- package/src/server/domain/plantuml-encoder.js +49 -0
- package/src/server/domain/plantuml-renderer.js +1 -0
- package/src/server/index.js +72 -0
- package/src/server/infrastructure/git/command-runner.js +48 -0
- package/src/server/infrastructure/git/concurrency.js +19 -0
- package/src/server/infrastructure/git/diff-service.js +389 -0
- package/src/server/infrastructure/git/errors.js +5 -0
- package/src/server/infrastructure/git/git-service.js +216 -0
- package/src/server/infrastructure/git/parsers.js +401 -0
- package/src/server/infrastructure/git/path-utils.js +65 -0
- package/src/server/infrastructure/git/responses.js +108 -0
- package/src/server/infrastructure/git/status-service.js +99 -0
- package/src/server/infrastructure/git/untracked-files.js +101 -0
- package/src/server/infrastructure/http/create-auth-api-handler.js +48 -0
- package/src/server/infrastructure/http/create-esm-proxy-handler.js +130 -0
- package/src/server/infrastructure/http/create-git-api-command-handler.js +170 -0
- package/src/server/infrastructure/http/create-git-api-handler.js +40 -0
- package/src/server/infrastructure/http/create-git-api-query-handler.js +62 -0
- package/src/server/infrastructure/http/create-plantuml-api-handler.js +43 -0
- package/src/server/infrastructure/http/create-request-handler.js +138 -0
- package/src/server/infrastructure/http/create-static-handler.js +167 -0
- package/src/server/infrastructure/http/create-vault-api-command-handler.js +161 -0
- package/src/server/infrastructure/http/create-vault-api-handler.js +43 -0
- package/src/server/infrastructure/http/create-vault-api-query-handler.js +82 -0
- package/src/server/infrastructure/http/http-errors.js +13 -0
- package/src/server/infrastructure/http/http-response.js +167 -0
- package/src/server/infrastructure/http/request-body.js +56 -0
- package/src/server/infrastructure/persistence/path-utils.js +90 -0
- package/src/server/infrastructure/persistence/sidecar-store.js +150 -0
- package/src/server/infrastructure/persistence/vault-content-adapter.js +49 -0
- package/src/server/infrastructure/persistence/vault-file-store.js +435 -0
- package/src/server/infrastructure/plantuml/plantuml-renderer.js +56 -0
- package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +194 -0
- package/src/server/infrastructure/websocket/client-socket-session.js +151 -0
- package/src/server/startup/git-remote-bootstrap.js +435 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import{C as Dt,a as bt,b,c as Ct,d as Tt,e as Pt,k as At,t as Mt,u as ye,v as Rt,w as Bt,x as Nt,y as Ht,z as ct}from"./chunks/chunk-OG2TNZEU.js";import{a as St,b as xt,c as Lt,d as Y,e as kt,f as fe,g as ge,h as Ft,i as It,j as we,k as q}from"./chunks/chunk-QSTBGTWJ.js";import{b as Et,c as pe}from"./chunks/chunk-SR3U53EQ.js";import{a as m,b as vt,c as F}from"./chunks/chunk-BBHPYU2R.js";import"./chunks/chunk-775E65SU.js";var Ti={edit:`
|
|
2
|
+
<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
3
|
+
<path d="M11.8 1.8a1.5 1.5 0 0 1 2.1 2.1l-7.2 7.2-3.2.9.9-3.2z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
4
|
+
<path d="M10.7 2.9l2.4 2.4" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
5
|
+
</svg>
|
|
6
|
+
`,maximize:`
|
|
7
|
+
<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
8
|
+
<path d="M6 2H2v4M10 2h4v4M14 10v4h-4M2 10v4h4" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
9
|
+
</svg>
|
|
10
|
+
`,refresh:`
|
|
11
|
+
<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
12
|
+
<path d="M13 4.5V1.8M13 1.8h-2.7M13 11.5v2.7M13 14.2h-2.7" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
13
|
+
<path d="M12.3 4.2A5.3 5.3 0 1 0 13 11.8" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
14
|
+
</svg>
|
|
15
|
+
`,restore:`
|
|
16
|
+
<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
17
|
+
<path d="M6 5V2H2M10 5V2h4M10 11v3h4M6 11v3H2" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
18
|
+
<path d="M4.5 4.5h7v7h-7z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.4"/>
|
|
19
|
+
</svg>
|
|
20
|
+
`};function T(n,e){if(!(n instanceof HTMLElement))return;let t=Ti[e];if(!t){n.classList.remove("is-icon-only");return}n.classList.add("is-icon-only"),n.dataset.icon=e,n.innerHTML=t.trim()}var x={default:1,animationDurationMs:160,max:3,min:.5,step:.1},L={default:1,animationDurationMs:160,max:3,min:.1,step:.1},W=500,Ut=2,_t=2;function X(n,e){return typeof window.requestIdleCallback=="function"?window.requestIdleCallback(n,{timeout:e}):window.setTimeout(()=>{n({didTimeout:!1,timeRemaining:()=>0})},1)}function ee(n){if(n!==null){if(typeof window.cancelIdleCallback=="function"){window.cancelIdleCallback(n);return}window.clearTimeout(n)}}function J(n,e,t){let i=e.getAttribute(t);if(i===null){n.removeAttribute(t);return}n.setAttribute(t,i)}function ce(n){let e=n.viewBox?.baseVal,t=Number.parseFloat(n.getAttribute("width")||""),i=Number.parseFloat(n.getAttribute("height")||""),s=n.getBoundingClientRect(),r=typeof n.getBBox=="function"?n.getBBox():null;return{height:e?.height||r?.height||i||s.height||480,width:e?.width||r?.width||t||s.width||640}}function zt(n){if(!n||typeof n.getBBox!="function")return ce(n);try{let e=n.getBBox();if(!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)return ce(n);let t=16,i=e.x-t,s=e.y-t,r=e.width+t*2,a=e.height+t*2;return n.setAttribute("viewBox",`${i} ${s} ${r} ${a}`),n.setAttribute("width",String(r)),n.setAttribute("height",String(a)),n.setAttribute("preserveAspectRatio","xMinYMin meet"),{width:r,height:a}}catch{return ce(n)}}function j(n){let e=window.getComputedStyle(n),t=Number.parseFloat(e.paddingLeft||"0")+Number.parseFloat(e.paddingRight||"0"),i=Number.parseFloat(e.paddingTop||"0")+Number.parseFloat(e.paddingBottom||"0");return{height:Math.max(n.clientHeight-i,0),width:Math.max(n.clientWidth-t,0)}}function ve(n){return 1-(1-n)**3}function $t(n){return dt(n,{label:"Mermaid diagram",message:"Loads when visible"})}function dt(n,{label:e="Mermaid diagram",message:t="Loads when visible"}={}){let i=document.createElement("div");i.className="mermaid-placeholder-card";let s=document.createElement("div");s.className="mermaid-placeholder-copy";let r=document.createElement("strong");r.textContent=e;let a=document.createElement("span");a.textContent=t;let o=document.createElement("button");return o.type="button",o.className="mermaid-placeholder-btn",o.dataset.mermaidKey=n,o.textContent="Render",s.append(r,a),i.append(s,o),i}function ht(n,e="Renders server-side when visible"){let t=document.createElement("div");t.className="plantuml-placeholder-card";let i=document.createElement("div");i.className="plantuml-placeholder-copy";let s=document.createElement("strong");s.textContent="PlantUML diagram";let r=document.createElement("span");r.textContent=e;let a=document.createElement("button");return a.type="button",a.className="plantuml-placeholder-btn",a.dataset.plantumlKey=n,a.textContent="Render",i.append(s,r),t.append(i,a),t}function Ot(n){let t=new DOMParser().parseFromString(n,"image/svg+xml"),i=t.documentElement;if(!i||i.nodeName.toLowerCase()!=="svg")throw new Error("Renderer returned invalid SVG");return t.querySelectorAll("script, foreignObject").forEach(s=>{s.remove()}),Array.from(t.querySelectorAll("*")).forEach(s=>{Array.from(s.attributes).forEach(r=>{let a=r.name.toLowerCase(),o=r.value||"";if(a.startsWith("on")){s.removeAttribute(r.name);return}(a==="href"||a==="xlink:href")&&/^\s*javascript:/i.test(o)&&s.removeAttribute(r.name)})}),i.outerHTML}function qt({nextSource:n="",nextTarget:e="",preservedSource:t="",preservedTarget:i=""}={}){return n?n===t:e?e===i:!1}function Wt(n,e,t){if(!n||!e)return!1;let i=e.getBoundingClientRect(),s=n.getBoundingClientRect();return s.bottom>=i.top-t&&s.top<=i.bottom+t}function Pi(n){return`data-${n.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}`}var te=class{constructor(e,{batchSize:t,datasetKeys:i,fetchFn:s=(...h)=>fetch(...h),filePathLabel:r,requestIdleRenderFn:a=X,cancelIdleRenderFn:o=ee,intersectionObserverFactory:l=(h,v)=>new IntersectionObserver(h,v),isNearViewportFn:d=Wt,requestAnimationFrameFn:c=h=>requestAnimationFrame(h),shellClassName:p,sourceClassName:f}){this.renderer=e,this.batchSize=t,this.datasetKeys=i,this.fetchFn=s,this.filePathLabel=r,this.requestIdleRenderFn=a,this.cancelIdleRenderFn=o,this.intersectionObserverFactory=l,this.isNearViewportFn=d,this.requestAnimationFrameFn=c,this.shellClassName=p,this.sourceClassName=f,this.shellSelector=`.${p}`,this.sourceSelector=`.${f}`,this.attributeNames=Object.fromEntries(Object.entries(i).map(([h,v])=>[h,Pi(v)])),this.observer=null,this.idleId=null,this.pendingShells=[],this.hydrationInProgress=!1,this.instanceCounter=0,this.preservedShells=new Map,this.fileInflightRequests=new Map}destroy(){this.cancelHydration(),this.preservedShells.clear()}cancelHydration(){this.observer&&(this.observer.disconnect(),this.observer=null),this.cancelIdleRenderFn(this.idleId),this.idleId=null,this.pendingShells=[],this.hydrationInProgress=!1}cancelPendingIdleWork(){this.cancelIdleRenderFn(this.idleId),this.idleId=null}clearPreservedShells(){this.preservedShells.clear()}hasPendingWork(){return this.hydrationInProgress||this.pendingShells.length>0}preserveHydratedShellsForCommit(){this.preservedShells.clear();let e=this.renderer.previewElement;e&&Array.from(e.querySelectorAll(`${this.shellSelector}[${this.attributeNames.hydrated}="true"][${this.attributeNames.key}]`)).forEach(t=>{let i=t.dataset[this.datasetKeys.key],s=t.querySelector(this.sourceSelector)?.textContent??"",r=t.dataset[this.datasetKeys.target]??"";!i||!s&&!r||(t.isConnected&&t.remove(),this.preservedShells.set(i,{key:i,shell:t,source:s,target:r}))})}reconcileHydratedShells(){let e=this.renderer.previewElement;if(!e||this.preservedShells.size===0){this.preservedShells.clear();return}let t=!1;Array.from(e.querySelectorAll(`${this.shellSelector}[${this.attributeNames.key}]`)).forEach(i=>{let s=i.dataset[this.datasetKeys.key],r=s?this.preservedShells.get(s):null;if(!r)return;let a=i.querySelector(this.sourceSelector)?.textContent??"",o=i.dataset[this.datasetKeys.target]??"";qt({nextSource:a,nextTarget:o,preservedSource:r.source,preservedTarget:r.target})&&(this.syncPreservedShell(r.shell,i),i.replaceWith(r.shell),t=t||r.shell.classList.contains("is-maximized"),this.preservedShells.delete(s))}),this.preservedShells.clear(),this.handleReconcile({restoredMaximizedShell:t})}handleReconcile(){}syncPreservedShell(e,t){J(e,t,this.attributeNames.sourceLine),J(e,t,this.attributeNames.sourceLineEnd),J(e,t,this.attributeNames.key),J(e,t,this.attributeNames.target),J(e,t,this.attributeNames.label),J(e,t,this.attributeNames.sourceHash),e.classList.add(this.shellClassName),e.dataset[this.datasetKeys.hydrated]="true",this.removeDatasetValue(e,"queued");let i=t.querySelector(this.sourceSelector),s=e.querySelector(this.sourceSelector);if(!s&&i&&(s=i.cloneNode(!0),e.prepend(s)),s&&i){let r=i.textContent??"";(r||!t.dataset[this.datasetKeys.target])&&(s.textContent=r),s.hidden=!0}}setupHydration(e){let t=this.renderer.previewElement,i=this.renderer.previewContainer;if(!t||!i)return 0;let s=Array.from(t.querySelectorAll(this.shellSelector));return s.length===0?0:(this.observer=this.intersectionObserverFactory(r=>{r.forEach(a=>{a.isIntersecting&&this.enqueueShell(a.target)})},{root:i,rootMargin:this.renderer.isLargeDocument?"180px 0px":"420px 0px"}),s.forEach(r=>this.observer.observe(r)),this.requestAnimationFrameFn(()=>{e===this.renderer.activeRenderVersion&&(this.hydrateVisibleShells(),this.renderer.updateHydrationPhase())}),s.length)}hydrateVisibleShells(){let e=this.renderer.previewElement,t=this.renderer.previewContainer;if(this.renderer.hydrationPaused||!e||!t)return;let i=this.renderer.isLargeDocument?180:420;Array.from(e.querySelectorAll(this.shellSelector)).forEach(s=>{this.isNearViewportFn(s,t,i)&&this.enqueueShell(s,{prioritize:!0})})}enqueueShell(e,{prioritize:t=!1}={}){!e?.isConnected||this.isShellHydrated(e)||this.isShellQueued(e)||(e.dataset[this.datasetKeys.queued]="true",t?this.pendingShells.unshift(e):this.pendingShells.push(e),!this.renderer.hydrationPaused&&(this.renderer.updateHydrationPhase(),this.scheduleHydration()))}scheduleHydration(){this.renderer.hydrationPaused||this.hydrationInProgress||this.idleId!==null||(this.idleId=this.requestIdleRenderFn(()=>{this.idleId=null,this.flushHydrationQueue()},W))}async flushHydrationQueue(){if(this.renderer.hydrationPaused||this.hydrationInProgress)return;let e=[];for(;this.pendingShells.length>0&&e.length<this.batchSize;){let i=this.pendingShells.shift();!i?.isConnected||this.isShellHydrated(i)||(this.removeDatasetValue(i,"queued"),e.push(i))}if(e.length===0){this.renderer.updateHydrationPhase();return}this.hydrationInProgress=!0,this.renderer.setPhase("hydrating");let t=null;try{t=await this.prepareHydrationBatch(e)}catch(i){this.handlePrepareHydrationBatchError(e,i),this.hydrationInProgress=!1,this.renderer.updateHydrationPhase();return}for(let i of e)await this.hydrateShell(i,t);this.hydrationInProgress=!1,this.pendingShells.length>0&&this.scheduleHydration(),this.renderer.updateHydrationPhase()}async prepareHydrationBatch(){return null}handlePrepareHydrationBatchError(e,t){}async hydrateShell(){throw new Error("hydrateShell must be implemented by subclasses")}markShellHydrated(e){e.dataset[this.datasetKeys.hydrated]="true",e.dataset[this.datasetKeys.instanceId]=String(++this.instanceCounter)}isShellHydrated(e){return e?.dataset?.[this.datasetKeys.hydrated]==="true"}removeDatasetValue(e,t){let i=this.datasetKeys[t];!i||!e||(e.removeAttribute?.(this.attributeNames[t]),e.dataset&&delete e.dataset[i])}isShellQueued(e){return e?.dataset?.[this.datasetKeys.queued]==="true"}async fetchSource(e){let t=String(e??"").trim();if(!t)throw new Error(`Missing ${this.filePathLabel} file path`);if(this.fileInflightRequests.has(t))return this.fileInflightRequests.get(t);let i=this.fetchFn(b(`/file?path=${encodeURIComponent(t)}`),{headers:{Accept:"application/json"}}).then(async s=>{let r=await s.json().catch(()=>null);if(!s.ok||typeof r?.content!="string")throw new Error(r?.error||`Failed to load ${t}`);return r.content}).finally(()=>{this.fileInflightRequests.delete(t)});return this.fileInflightRequests.set(t,i),i}};var be=class extends te{constructor(e){super(e,{batchSize:Ut,datasetKeys:{hydrated:"mermaidHydrated",instanceId:"mermaidInstanceId",key:"mermaidKey",label:"mermaidLabel",queued:"mermaidQueued",sourceHash:"mermaidSourceHash",sourceLine:"sourceLine",sourceLineEnd:"sourceLineEnd",target:"mermaidTarget"},filePathLabel:"Mermaid",shellClassName:"mermaid-shell",sourceClassName:"mermaid-source"}),this.renderer=e,this.currentTheme=document.documentElement?.dataset.theme==="light"?"light":"dark",this.loader=null,this.runtime=null,this.shellRefits=new WeakMap}applyTheme(e){this.currentTheme=e;let t=this.runtime;t&&(this.configureMermaid(t),this.resetHydratedShells())}configureMermaid(e){e.initialize({startOnLoad:!1,flowchart:{defaultRenderer:"dagre-wrapper",useMaxWidth:!0},class:{defaultRenderer:"dagre-wrapper",useMaxWidth:!0},theme:this.currentTheme==="dark"?"dark":"default",themeVariables:this.currentTheme==="dark"?{background:"#161822",clusterBkg:"#1a1c28",edgeLabelBackground:"#161822",lineColor:"#8b8ba0",mainBkg:"#1c1e2c",nodeBorder:"#383a50",primaryBorderColor:"#383a50",primaryColor:"#818cf8",primaryTextColor:"#e2e2ea",secondaryColor:"#1c1e2c",tertiaryColor:"#161822",titleColor:"#e2e2ea"}:{}})}ensureMermaid(){return this.runtime?(this.configureMermaid(this.runtime),Promise.resolve(this.runtime)):this.loader?this.loader:(this.loader=import("./chunks/mermaid-runtime-BIFNJ2CT.js").then(e=>{let t=e?.default;if(!t)throw new Error("Mermaid runtime failed to initialize");return this.runtime=t,this.configureMermaid(t),t}).catch(e=>{throw this.loader=null,this.runtime=null,new Error(e instanceof Error?e.message:"Failed to load Mermaid runtime")}),this.loader)}handleReconcile({restoredMaximizedShell:e}){e&&document.body.classList.add("mermaid-maximized-open")}async prepareHydrationBatch(){return this.ensureMermaid()}handlePrepareHydrationBatchError(e,t){console.warn("[preview] Mermaid runtime failed to load:",t)}async hydrateShell(e,t){if(!t||!e?.isConnected||this.isShellHydrated(e))return;let i=e.querySelector(".mermaid-source");i||(i=document.createElement("span"),i.className="mermaid-source",i.hidden=!0,e.appendChild(i));let s=i.textContent??"";try{if(!s.trim()&&e.dataset.mermaidTarget){if(s=await this.fetchSource(e.dataset.mermaidTarget),!e.isConnected)return;i.textContent=s}if(!s.trim())throw new Error(e.dataset.mermaidTarget?"Mermaid file is empty":"Mermaid source is empty");s=this.prepareSource(s),e.querySelector(".mermaid-placeholder-card")?.remove();let r=document.createElement("div");r.className="mermaid mermaid-render-node",r.id=e.dataset.mermaidKey||`mermaid-${Date.now()}`;let a=e.getAttribute("data-source-line"),o=e.getAttribute("data-source-line-end");if(a&&r.setAttribute("data-source-line",a),o&&r.setAttribute("data-source-line-end",o),r.textContent=s,e.appendChild(r),await t.run({nodes:[r]}),!r.isConnected||e!==r.parentElement)return;this.enhanceDiagram(e,r),this.markShellHydrated(e)}catch(r){console.warn("[preview] Mermaid render failed:",r),e.querySelector(":scope > .mermaid-toolbar")?.remove(),e.querySelector(":scope > .mermaid-frame")?.remove(),e.querySelector(":scope > .mermaid-render-node")?.remove(),e.querySelector(".mermaid-placeholder-card")||i?.after(dt(e.dataset.mermaidKey||"mermaid",{label:e.dataset.mermaidLabel||"Mermaid diagram",message:r instanceof Error?r.message:"Render failed"}))}}prepareSource(e){let t=String(e??"");if(!/%%\{[\s\S]*?\binit\s*:/m.test(t)){let r=this.getPreviewInitConfig(t);r&&(t=`%%{init: ${JSON.stringify(r)}}%%
|
|
21
|
+
${t}`)}if(!/^\s*gantt\b/m.test(t)||/\btodayMarker\b/.test(t))return t;let i=t.split(`
|
|
22
|
+
`),s=i.findIndex(r=>/^\s*gantt\b/.test(r));return s===-1?t:(i.splice(s+1,0," todayMarker off"),i.join(`
|
|
23
|
+
`))}getPreviewInitConfig(e){return/^\s*stateDiagram(?:-v2)?\b/m.test(e)?{htmlLabels:!1}:/^\s*classDiagram\b/m.test(e)?{htmlLabels:!1}:/^\s*gantt\b/m.test(e)?{htmlLabels:!1}:null}resetHydratedShells(){let e=this.renderer.previewElement;if(!e)return;let t=Array.from(e.querySelectorAll('.mermaid-shell[data-mermaid-hydrated="true"]'));t.length!==0&&t.forEach(i=>{this.shellRefits.delete(i),i.removeAttribute("data-mermaid-hydrated"),i.querySelector(":scope > .mermaid-toolbar")?.remove(),i.querySelector(":scope > .mermaid-frame")?.remove(),i.querySelector(":scope > .mermaid-render-node")?.remove(),i.querySelector(".mermaid-placeholder-card")||i.querySelector(".mermaid-source")?.after($t(i.dataset.mermaidKey||"mermaid")),this.enqueueShell(i,{prioritize:!0})})}enhanceDiagram(e,t){let i=t.querySelector("svg");if(!i){t.remove();return}let s=document.createElement("div");s.className="mermaid-toolbar diagram-preview-toolbar";let r=this.createZoomButton("\u2212","Zoom out"),a=this.createZoomButton("+","Zoom in"),o=this.createZoomButton("Reset","Reset zoom"),l=this.createZoomButton("Max","Maximize diagram");l.classList.add("mermaid-maximize-btn"),T(l,"maximize");let d=document.createElement("span");d.className="mermaid-zoom-label diagram-preview-zoom-label",d.setAttribute("aria-live","polite"),s.append(r,d,o,a,l);let c=document.createElement("div");c.className="mermaid-frame diagram-preview-frame";let{width:p,height:f}=zt(i),h=x.default,v=1,y=null,E=null,C=!1,P=0,I=!1,A=null,z=0,M=0,R=0,$=0;i.style.display="block",i.style.margin="0 auto",i.style.maxWidth="none";let B=()=>{let u=j(c);if(!Number.isFinite(p)||p<=0||u.width<=0)return x.default;let g=u.width/p;return!Number.isFinite(g)||g<=0?x.default:F(g,x.min,x.max)},N=u=>{h=F(u,x.min,x.max),i.style.width=`${p*h}px`,i.style.height=`${f*h}px`,d.textContent=`${Math.round(h*100)}%`,r.disabled=h<=x.min,a.disabled=h>=x.max;let g=j(c),w=p*h>g.width||f*h>g.height;c.classList.toggle("is-pannable",w),i.style.margin=w?"0":"0 auto"},Z=()=>({x:c.scrollLeft+c.clientWidth/2,y:c.scrollTop+c.clientHeight/2}),V=(u,g,w)=>{if(u===0)return;let S=g/u;c.scrollLeft=w.x*S-c.clientWidth/2,c.scrollTop=w.y*S-c.clientHeight/2},K=u=>{let g=F(u,x.min,x.max),w=h;if(g===w)return;let S=Z(),at=performance.now();y&&cancelAnimationFrame(y);let ae=ot=>{let oe=F((ot-at)/x.animationDurationMs,0,1),lt=ve(oe),le=w+(g-w)*lt;if(N(le),V(w,le,S),oe<1){y=requestAnimationFrame(ae);return}y=null,N(g),V(w,g,S)};y=requestAnimationFrame(ae)},G=u=>{C=!0,K(h+u)},H=({animate:u=!1}={})=>{if(v=B(),C=!1,P=j(c).width,u&&Math.abs(v-h)>.001){K(v);return}y&&(cancelAnimationFrame(y),y=null),N(v),c.scrollLeft=0,c.scrollTop=0},D=({force:u=!1}={})=>{E&&cancelAnimationFrame(E),E=requestAnimationFrame(()=>{if(E=null,!e.isConnected)return;let g=j(c).width,w=Math.abs(g-P)>1;!u&&C||!u&&P>0&&!w||H()})};this.shellRefits.set(e,D),r.addEventListener("click",()=>G(-x.step)),a.addEventListener("click",()=>G(x.step)),o.addEventListener("click",()=>{H({animate:!0})});let U=()=>{let u=e.classList.contains("is-maximized");T(l,u?"restore":"maximize");let g=u?"Restore diagram size":"Maximize diagram";l.setAttribute("aria-label",g),l.title=g},re=u=>{let g=this.renderer.previewElement;if(u){let w=g.querySelector(".mermaid-shell.is-maximized");if(w&&w!==e){w.classList.remove("is-maximized"),this.shellRefits.get(w)?.();let S=w.querySelector(".mermaid-maximize-btn");S&&(T(S,"maximize"),S.setAttribute("aria-label","Maximize diagram"),S.title="Maximize diagram")}e.classList.add("is-maximized"),document.body.classList.add("mermaid-maximized-open"),U(),D({force:!0});return}e.classList.remove("is-maximized"),g.querySelector(".mermaid-shell.is-maximized")||document.body.classList.remove("mermaid-maximized-open"),U(),D({force:!0})};U(),l.addEventListener("click",()=>{re(!e.classList.contains("is-maximized"))});let O=()=>{if(I){if(I=!1,c.classList.remove("is-dragging"),A!==null&&typeof c.releasePointerCapture=="function")try{c.releasePointerCapture(A)}catch{}A=null}};c.addEventListener("pointerdown",u=>{u.button!==0||!c.classList.contains("is-pannable")||(y&&(cancelAnimationFrame(y),y=null),I=!0,A=u.pointerId,z=u.clientX,M=u.clientY,R=c.scrollLeft,$=c.scrollTop,c.classList.add("is-dragging"),c.setPointerCapture?.(u.pointerId),u.preventDefault())}),c.addEventListener("pointermove",u=>{I&&(c.scrollLeft=R-(u.clientX-z),c.scrollTop=$-(u.clientY-M))}),c.addEventListener("pointerup",O),c.addEventListener("pointercancel",O),c.addEventListener("lostpointercapture",O),c.appendChild(i);let _=e.querySelector(".mermaid-source");t.remove(),e.replaceChildren(),_&&(_.hidden=!0,e.appendChild(_)),e.append(s,c),D({force:!0})}scheduleActiveRefit(){let e=this.renderer.previewElement;e&&Array.from(e.querySelectorAll('.mermaid-shell[data-mermaid-hydrated="true"]')).forEach(t=>{this.shellRefits.get(t)?.()})}createZoomButton(e,t){let i=document.createElement("button");return i.type="button",i.className="mermaid-zoom-btn diagram-preview-action-btn",i.setAttribute("aria-label",t),i.title=t,i.textContent=e,i}};var Ce=class extends te{constructor(e){super(e,{batchSize:_t,datasetKeys:{hydrated:"plantumlHydrated",instanceId:"plantumlInstanceId",key:"plantumlKey",label:"plantumlLabel",queued:"plantumlQueued",sourceHash:"plantumlSourceHash",sourceLine:"sourceLine",sourceLineEnd:"sourceLineEnd",target:"plantumlTarget"},filePathLabel:"PlantUML",shellClassName:"plantuml-shell",sourceClassName:"plantuml-source"}),this.renderer=e,this.svgCache=new Map,this.svgInflightRequests=new Map,this.shellRefits=new WeakMap,this.activeMaximizedShell=null,this.maximizedRoot=null,this.resizeFrameId=null}destroy(){this.cancelHydration(),this.preservedShells.clear(),this.clearActiveShell(),this.resizeFrameId&&(cancelAnimationFrame(this.resizeFrameId),this.resizeFrameId=null),this.maximizedRoot?.remove(),this.maximizedRoot=null}clearActiveShell(){this.activeMaximizedShell=null,this.maximizedRoot&&this.maximizedRoot.childElementCount===0&&(this.maximizedRoot.hidden=!0)}syncActiveShell(){return this.activeMaximizedShell?.isConnected&&this.activeMaximizedShell.classList.contains("is-maximized")?this.activeMaximizedShell:(this.clearActiveShell(),null)}scheduleActiveRefit(){this.resizeFrameId&&cancelAnimationFrame(this.resizeFrameId),this.resizeFrameId=requestAnimationFrame(()=>{this.resizeFrameId=null;let e=this.syncActiveShell();e&&this.shellRefits.get(e)?.()})}handleReconcile({restoredMaximizedShell:e}){e&&document.body.classList.add("plantuml-maximized-open"),this.syncActiveShell()}ensureMaximizedRoot(){if(this.maximizedRoot?.isConnected&&this.maximizedRoot.parentElement===document.body)return this.maximizedRoot;let e=document.body.querySelector('[data-plantuml-maximized-root="true"]');return e||(e=document.createElement("div"),e.dataset.plantumlMaximizedRoot="true",e.className="plantuml-maximized-root",document.body.appendChild(e)),this.maximizedRoot=e,e}mountShellInMaximizedRoot(e){if(!e)return;let t=this.ensureMaximizedRoot();t.hidden=!1,e._plantumlRestoreParent=e.parentElement||null,e._plantumlRestoreNextSibling=e.nextSibling||null,t.appendChild(e)}restoreShellMount(e){if(!e)return;let t=e._plantumlRestoreParent,i=e._plantumlRestoreNextSibling;t?.isConnected&&(i?.parentElement===t?t.insertBefore(e,i):t.appendChild(e)),e._plantumlRestoreParent=null,e._plantumlRestoreNextSibling=null,this.maximizedRoot&&this.maximizedRoot.childElementCount===0&&(this.maximizedRoot.hidden=!0)}async hydrateShell(e){if(!e?.isConnected||this.isShellHydrated(e))return;let t=e.querySelector(".plantuml-source");t||(t=document.createElement("span"),t.className="plantuml-source",t.hidden=!0,e.appendChild(t)),e.querySelector(".plantuml-placeholder-card")?.remove();try{let i=t.textContent??"";if(!i.trim()&&e.dataset.plantumlTarget){if(i=await this.fetchSource(e.dataset.plantumlTarget),!e.isConnected)return;t.textContent=i}if(!i.trim())throw new Error(e.dataset.plantumlTarget?"PlantUML file is empty":"PlantUML source is empty");let s=await this.fetchSvg(i);if(!e.isConnected)return;this.enhanceDiagram(e,s),this.markShellHydrated(e)}catch(i){console.warn("[preview] PlantUML render failed:",i),e.querySelector(":scope > .plantuml-toolbar")?.remove(),e.querySelector(":scope > .plantuml-frame")?.remove(),e.querySelector(".plantuml-placeholder-card")||t?.after(ht(e.dataset.plantumlKey||"plantuml",i instanceof Error?i.message:"Render failed"))}}async fetchSvg(e){let t=e;if(this.svgCache.has(t))return this.svgCache.get(t);if(this.svgInflightRequests.has(t))return this.svgInflightRequests.get(t);let i=fetch(b("/plantuml/render"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source:e})}).then(async s=>{let r=await s.json().catch(()=>null);if(!s.ok||!r?.ok||typeof r.svg!="string")throw new Error(r?.error||"Failed to render PlantUML");let a=Ot(r.svg);return this.svgCache.set(t,a),a}).finally(()=>{this.svgInflightRequests.delete(t)});return this.svgInflightRequests.set(t,i),i}resetShell(e,{clearCache:t=!1,message:i="Renders server-side when visible"}={}){let s=e.querySelector(".plantuml-source")?.textContent??"";t&&s&&(this.svgCache.delete(s),this.svgInflightRequests.delete(s)),this.shellRefits.delete(e),this.activeMaximizedShell===e&&(this.restoreShellMount(e),this.clearActiveShell()),e.removeAttribute("data-plantuml-hydrated"),e.removeAttribute("data-plantuml-instance-id"),e.removeAttribute("data-plantuml-queued"),e.classList.remove("is-maximized"),this.syncActiveShell()||document.body.classList.remove("plantuml-maximized-open"),e.querySelector(":scope > .plantuml-toolbar")?.remove(),e.querySelector(":scope > .plantuml-frame")?.remove(),e.querySelector(".plantuml-placeholder-card")||e.querySelector(".plantuml-source")?.after(ht(e.dataset.plantumlKey||"plantuml",i))}enhanceDiagram(e,t){let i=document.createElement("div");i.innerHTML=t;let s=i.querySelector("svg");if(!s)throw new Error("Renderer returned invalid SVG");let r=document.createElement("div");r.className="plantuml-toolbar diagram-preview-toolbar";let a=document.createElement("div");a.className="plantuml-frame diagram-preview-frame";let o=this.createToolButton("\u2212","Zoom out"),l=this.createToolButton("+","Zoom in"),d=this.createToolButton("Reset","Reset zoom"),c=this.createToolButton("Reload","Reload diagram"),p=this.createToolButton("Max","Maximize diagram");p.classList.add("plantuml-maximize-btn"),T(c,"refresh"),T(p,"maximize");let f=document.createElement("span");f.className="plantuml-zoom-label diagram-preview-zoom-label",f.setAttribute("aria-live","polite"),r.append(o,f,d,l,c,p);let{width:h,height:v}=ce(s),y=L.default,E=1,C=null,P=!1,I=null,A=0,z=0,M=0,R=0;s.style.display="block",s.style.margin="0 auto",s.style.maxWidth="none";let $=()=>{let u=j(a);return!Number.isFinite(h)||h<=0||u.width<=0?L.default:F(Math.min(L.default,u.width/h),L.min,L.max)},B=u=>{y=F(u,L.min,L.max),s.style.width=`${h*y}px`,s.style.height=`${v*y}px`,f.textContent=`${Math.round(y*100)}%`,o.disabled=y<=L.min,l.disabled=y>=L.max;let g=j(a),w=h*y>g.width||v*y>g.height;a.classList.toggle("is-pannable",w)},N=()=>({x:a.scrollLeft+a.clientWidth/2,y:a.scrollTop+a.clientHeight/2}),Z=(u,g,w)=>{if(u===0)return;let S=g/u;a.scrollLeft=w.x*S-a.clientWidth/2,a.scrollTop=w.y*S-a.clientHeight/2},V=u=>{let g=F(u,L.min,L.max),w=y;if(g===w)return;let S=N(),at=performance.now();C&&cancelAnimationFrame(C);let ae=ot=>{let oe=F((ot-at)/L.animationDurationMs,0,1),lt=ve(oe),le=w+(g-w)*lt;if(B(le),Z(w,le,S),oe<1){C=requestAnimationFrame(ae);return}C=null,B(g),Z(w,g,S)};C=requestAnimationFrame(ae)},K=u=>{V(y+u)},G=({animate:u=!1}={})=>{if(E=$(),u&&Math.abs(E-y)>.001){V(E);return}C&&(cancelAnimationFrame(C),C=null),B(E),a.scrollLeft=0,a.scrollTop=0},H=null,D=()=>{H&&cancelAnimationFrame(H),H=requestAnimationFrame(()=>{H=null,e.isConnected&&G()})};this.shellRefits.set(e,D),o.addEventListener("click",()=>K(-L.step)),l.addEventListener("click",()=>K(L.step)),d.addEventListener("click",()=>{G({animate:!0})});let U=()=>{let u=e.classList.contains("is-maximized");T(p,u?"restore":"maximize");let g=u?"Restore diagram size":"Maximize diagram";p.setAttribute("aria-label",g),p.title=g},re=u=>{if(u){let g=this.syncActiveShell();if(g&&g!==e){this.restoreShellMount(g),g.classList.remove("is-maximized"),this.activeMaximizedShell===g&&this.clearActiveShell(),this.shellRefits.get(g)?.();let w=g.querySelector(".plantuml-maximize-btn");w&&(T(w,"maximize"),w.setAttribute("aria-label","Maximize diagram"),w.title="Maximize diagram")}this.mountShellInMaximizedRoot(e),e.classList.add("is-maximized"),this.activeMaximizedShell=e,document.body.classList.add("plantuml-maximized-open"),U(),D();return}this.restoreShellMount(e),e.classList.remove("is-maximized"),this.activeMaximizedShell===e&&this.clearActiveShell(),this.syncActiveShell()||document.body.classList.remove("plantuml-maximized-open"),U(),D()};c.addEventListener("click",()=>{this.resetShell(e,{clearCache:!0,message:"Refreshing\u2026"}),this.enqueueShell(e,{prioritize:!0})}),U(),p.addEventListener("click",()=>{re(!e.classList.contains("is-maximized"))});let O=()=>{if(P){if(P=!1,a.classList.remove("is-dragging"),I!==null&&typeof a.releasePointerCapture=="function")try{a.releasePointerCapture(I)}catch{}I=null}};a.addEventListener("pointerdown",u=>{u.button!==0||!a.classList.contains("is-pannable")||(C&&(cancelAnimationFrame(C),C=null),P=!0,I=u.pointerId,A=u.clientX,z=u.clientY,M=a.scrollLeft,R=a.scrollTop,a.classList.add("is-dragging"),a.setPointerCapture?.(u.pointerId),u.preventDefault())}),a.addEventListener("pointermove",u=>{P&&(a.scrollLeft=M-(u.clientX-A),a.scrollTop=R-(u.clientY-z))}),a.addEventListener("pointerup",O),a.addEventListener("pointercancel",O),a.addEventListener("lostpointercapture",O),a.appendChild(s);let _=e.querySelector(".plantuml-source");e.replaceChildren(),_&&(_.hidden=!0,e.appendChild(_)),e.append(r,a),E=$(),B(E)}createToolButton(e,t){let i=document.createElement("button");return i.type="button",i.className="plantuml-tool-btn diagram-preview-action-btn",i.setAttribute("aria-label",t),i.title=t,i.textContent=e,i}};function Ai(){return new Worker(new URL("./preview-render-worker.js",import.meta.url),{type:"module"})}var Ee=class{constructor({cancelIdleRenderFn:e=ee,compilePreviewDocumentLoader:t=()=>import("./chunks/preview-render-compiler-WD3A76I6.js"),createWorkerFn:i=Ai,getFileList:s,idleTimeoutMs:r=W,requestIdleRenderFn:a=X}={}){this.cancelIdleRenderFn=e,this.compilePreviewDocumentLoader=t,this.createWorkerFn=i,this.getFileList=s,this.idleTimeoutMs=r,this.requestIdleRenderFn=a,this.worker=null,this.workerDisabled=!1,this.workerJob=null,this.workerPrewarmId=null,this.handleWorkerMessage=o=>{if(!this.workerJob||o.data?.renderVersion!==this.workerJob.renderVersion)return;let l=this.workerJob;if(this.workerJob=null,o.data?.error){l.reject(new Error(o.data.error));return}l.resolve({html:o.data.html,stats:o.data.stats})},this.handleWorkerError=o=>{let l=new Error(o.message||"Preview worker failed");this.workerJob&&(this.workerJob.reject(l),this.workerJob=null),this.reset("Preview worker failed",{disable:!0})}}hasPendingJob(){return this.workerJob!==null}schedulePrewarm({timeout:e=this.idleTimeoutMs}={}){this.workerDisabled||this.worker||this.workerPrewarmId!==null||(this.workerPrewarmId=this.requestIdleRenderFn(()=>{this.workerPrewarmId=null,this.ensureWorker()},e))}ensureWorker(){if(this.workerDisabled)return null;if(this.worker)return this.worker;try{return this.worker=this.createWorkerFn(),this.worker.addEventListener("message",this.handleWorkerMessage),this.worker.addEventListener("error",this.handleWorkerError),this.worker}catch{return this.workerDisabled=!0,null}}async compile(e,t){if(this.ensureWorker()){this.workerJob&&this.reset("Superseded preview render");let r=this.ensureWorker();return new Promise((a,o)=>{this.workerJob={reject:o,renderVersion:t,resolve:a},r.postMessage({fileList:this.getFileList?.()??[],markdownText:e,renderVersion:t})})}let{compilePreviewDocument:s}=await this.compilePreviewDocumentLoader();return s({fileList:this.getFileList?.()??[],markdownText:e})}cancelWorkerJob(e){this.workerJob&&(this.workerJob.reject(new Error(e)),this.workerJob=null)}reset(e,{disable:t=!1}={}){this.cancelWorkerJob(e),this.worker&&(this.worker.removeEventListener("message",this.handleWorkerMessage),this.worker.removeEventListener("error",this.handleWorkerError),this.worker.terminate(),this.worker=null),t&&(this.workerDisabled=!0)}destroy(e="Preview renderer destroyed"){this.workerPrewarmId!==null&&this.cancelIdleRenderFn(this.workerPrewarmId),this.workerPrewarmId=null,this.reset(e)}};var Se=class{constructor({cancelAnimationFrameFn:e=d=>cancelAnimationFrame(d),cancelIdleRenderFn:t=ee,clearTimeoutFn:i=d=>clearTimeout(d),getRenderProfileFn:s=pe,idleTimeoutMs:r=W,requestAnimationFrameFn:a=d=>requestAnimationFrame(d),requestIdleRenderFn:o=X,setTimeoutFn:l=(d,c)=>setTimeout(d,c)}={}){this.cancelAnimationFrameFn=e,this.cancelIdleRenderFn=t,this.clearTimeoutFn=i,this.getRenderProfileFn=s,this.idleTimeoutMs=r,this.requestAnimationFrameFn=a,this.requestIdleRenderFn=o,this.setTimeoutFn=l,this.frameId=null,this.idleId=null,this.timeoutId=null}queue({markdownText:e,onRenderRequested:t,renderVersion:i}){let s=this.getRenderProfileFn(e);this.cancel();let r=()=>{this.frameId=this.requestAnimationFrameFn(()=>{this.frameId=null,this.timeoutId=null,t?.(e,i)})},a=()=>{if(s.deferUntilIdle){this.idleId=this.requestIdleRenderFn(()=>{this.idleId=null,r()},this.idleTimeoutMs);return}r()};this.timeoutId=this.setTimeoutFn(a,s.debounceMs)}cancel(){this.clearTimeoutFn(this.timeoutId),this.frameId&&this.cancelAnimationFrameFn(this.frameId),this.cancelIdleRenderFn(this.idleId),this.frameId=null,this.idleId=null,this.timeoutId=null}destroy(){this.cancel()}};var xe=class{constructor({getContent:e,getFileList:t,onAfterRenderCommit:i,onBeforeRenderCommit:s,onRenderComplete:r,outlineController:a,previewContainer:o,previewElement:l}){this.getContent=e,this.getFileList=t,this.onAfterRenderCommit=i,this.onBeforeRenderCommit=s,this.onRenderComplete=r,this.outlineController=a,this.previewContainer=o,this.previewElement=l,this.renderHost=null,this.pendingRenderVersion=0,this.activeRenderVersion=0,this.readyRenderVersion=0,this.currentStats=null,this.isLargeDocument=!1,this.hydrationPaused=!1,this.handlePreviewClick=d=>{let c=d.target.closest(".mermaid-placeholder-btn");if(c){let f=c.closest(".mermaid-shell");if(!f)return;d.preventDefault(),this.enqueueMermaidShell(f,{prioritize:!0});return}let p=d.target.closest(".plantuml-placeholder-btn");if(p){let f=p.closest(".plantuml-shell");if(!f)return;d.preventDefault(),this.enqueuePlantUmlShell(f,{prioritize:!0})}},this.handleWindowResize=()=>{this.mermaidHydrator.scheduleActiveRefit(),this.plantUmlHydrator.scheduleActiveRefit()},this.mermaidHydrator=new be(this),this.plantUmlHydrator=new Ce(this),this.renderScheduler=new Se({getRenderProfileFn:pe}),this.renderExecutor=new Ee({getFileList:()=>this.getFileList?.()??[],idleTimeoutMs:W}),this.previewElement?.addEventListener("click",this.handlePreviewClick),window.addEventListener("resize",this.handleWindowResize),this.setPhase("ready")}ensureRenderHost(){if(!this.previewElement)return null;if(this.renderHost?.isConnected&&this.renderHost.parentElement===this.previewElement)return this.renderHost;let e=this.previewElement.querySelector('[data-preview-render-host="true"]');return e||(e=document.createElement("div"),e.dataset.previewRenderHost="true",this.previewElement.appendChild(e)),this.renderHost=e,this.renderHost}normalizePreviewChildren(e=this.renderHost){this.previewElement&&Array.from(this.previewElement.children).forEach(t=>{t===e||t.dataset.excalidrawOverlayRoot==="true"||t.dataset.videoOverlayRoot==="true"||t.remove()})}getReservedPreviewHeight(){let e=this.renderHost?.getBoundingClientRect?.().height??0,t=this.previewContainer?.clientHeight??0;return Math.max(Math.round(e),Math.round(t),320)}beginDocumentLoad(){this.cancelScheduledRender(),this.cancelMermaidHydration(),this.cancelPlantUmlHydration(),this.mermaidHydrator.clearPreservedShells(),this.plantUmlHydrator.clearPreservedShells(),this.clearActivePlantUmlShell(),this.onBeforeRenderCommit?.(this.previewElement),this.pendingRenderVersion+=1,this.activeRenderVersion=this.pendingRenderVersion,this.readyRenderVersion=0,this.currentStats=null,this.isLargeDocument=!1,this.renderExecutor.hasPendingJob()&&this.resetWorker("Document changed");let e=this.ensureRenderHost();this.normalizePreviewChildren(e);let t=this.getReservedPreviewHeight();e&&(e.replaceChildren(),e.style.minHeight=`${t}px`);let i=document.createElement("div");i.className="preview-shell",i.style.minHeight=`${t}px`,i.textContent="Rendering preview\u2026",e?.append(i),this.setPhase("shell")}applyTheme(e){let t=document.getElementById("hljs-theme");if(t){let{darkHref:i,lightHref:s}=t.dataset;t.href=e==="dark"?i:s}this.mermaidHydrator.applyTheme(e)}configureMermaid(e){this.mermaidHydrator.configureMermaid(e)}ensureMermaid(){return this.mermaidHydrator.ensureMermaid()}queueRender(){let e=this.getContent();this.cancelScheduledRender(),this.pendingRenderVersion+=1;let t=this.pendingRenderVersion;this.renderScheduler.queue({markdownText:e,onRenderRequested:(i,s)=>{this.render(i,s)},renderVersion:t})}async render(e=this.getContent(),t=this.pendingRenderVersion){if(this.previewElement)try{let i=await this.compilePreview(e,t);if(t!==this.pendingRenderVersion)return;this.commitBaseRender(i,t)}catch(i){if(t!==this.pendingRenderVersion)return;console.warn("[preview] Failed to render preview:",i)}}destroy(){this.renderScheduler.destroy(),this.mermaidHydrator.destroy(),this.plantUmlHydrator.destroy(),this.renderExecutor.destroy(),this.previewElement?.removeEventListener("click",this.handlePreviewClick),window.removeEventListener("resize",this.handleWindowResize)}setPhase(e){this.previewElement&&(this.previewElement.dataset.renderPhase=e)}cancelScheduledRender(){this.renderScheduler.cancel()}cancelMermaidHydration(){this.mermaidHydrator.cancelHydration()}cancelPlantUmlHydration(){this.plantUmlHydrator.cancelHydration()}clearActivePlantUmlShell(){this.plantUmlHydrator.clearActiveShell()}scheduleActiveMermaidRefit(){this.mermaidHydrator.scheduleActiveRefit()}syncActivePlantUmlShell(){return this.plantUmlHydrator.syncActiveShell()}scheduleActivePlantUmlRefit(){this.plantUmlHydrator.scheduleActiveRefit()}setHydrationPaused(e){if(this.hydrationPaused=!!e,this.hydrationPaused){this.mermaidHydrator.cancelPendingIdleWork(),this.plantUmlHydrator.cancelPendingIdleWork();return}this.mermaidHydrator.hydrateVisibleShells(),this.mermaidHydrator.scheduleHydration(),this.plantUmlHydrator.hydrateVisibleShells(),this.plantUmlHydrator.scheduleHydration(),this.updateHydrationPhase()}resetWorker(e,{disable:t=!1}={}){this.renderExecutor.reset(e,{disable:t})}scheduleWorkerPrewarm({timeout:e=W}={}){this.renderExecutor.schedulePrewarm({timeout:e})}async compilePreview(e,t){return this.renderExecutor.compile(e,t)}commitBaseRender({html:e,stats:t},i){this.activeRenderVersion=i,this.readyRenderVersion=0,this.currentStats=t,this.isLargeDocument=Et(t),this.cancelMermaidHydration(),this.cancelPlantUmlHydration(),document.body.classList.remove("mermaid-maximized-open"),document.body.classList.remove("plantuml-maximized-open"),this.preserveHydratedMermaidsForCommit(),this.preserveHydratedPlantUmlsForCommit(),this.onBeforeRenderCommit?.(this.previewElement);let s=this.ensureRenderHost();this.normalizePreviewChildren(s),s&&(s.innerHTML=e),this.reconcileHydratedMermaids(),this.reconcileHydratedPlantUmls(),this.setPhase("base"),this.outlineController.refresh(),this.onAfterRenderCommit?.(this.previewElement,{...t,isLargeDocument:this.isLargeDocument,renderVersion:i});let r=this.setupMermaidHydration(i),a=this.setupPlantUmlHydration(i);r===0&&a===0&&this.notifyReady()}preserveHydratedMermaidsForCommit(){this.mermaidHydrator.preserveHydratedShellsForCommit()}preserveHydratedPlantUmlsForCommit(){this.plantUmlHydrator.preserveHydratedShellsForCommit()}reconcileHydratedMermaids(){this.mermaidHydrator.reconcileHydratedShells()}reconcileHydratedPlantUmls(){this.plantUmlHydrator.reconcileHydratedShells()}syncPreservedMermaidShell(e,t){this.mermaidHydrator.syncPreservedShell(e,t)}syncPreservedPlantUmlShell(e,t){this.plantUmlHydrator.syncPreservedShell(e,t)}setupMermaidHydration(e){return this.mermaidHydrator.setupHydration(e)}hydrateVisibleMermaids(){this.mermaidHydrator.hydrateVisibleShells()}enqueueMermaidShell(e,{prioritize:t=!1}={}){this.mermaidHydrator.enqueueShell(e,{prioritize:t})}scheduleMermaidHydration(){this.mermaidHydrator.scheduleHydration()}async flushMermaidHydrationQueue(){await this.mermaidHydrator.flushHydrationQueue()}async hydrateMermaidShell(e,t){await this.mermaidHydrator.hydrateShell(e,t)}resetHydratedMermaids(){this.mermaidHydrator.resetHydratedShells()}setupPlantUmlHydration(e){return this.plantUmlHydrator.setupHydration(e)}hydrateVisiblePlantUmls(){this.plantUmlHydrator.hydrateVisibleShells()}enqueuePlantUmlShell(e,{prioritize:t=!1}={}){this.plantUmlHydrator.enqueueShell(e,{prioritize:t})}schedulePlantUmlHydration(){this.plantUmlHydrator.scheduleHydration()}async flushPlantUmlHydrationQueue(){await this.plantUmlHydrator.flushHydrationQueue()}async hydratePlantUmlShell(e){await this.plantUmlHydrator.hydrateShell(e)}updateHydrationPhase(){if(this.hydrationPaused&&(this.mermaidHydrator.hasPendingWork()||this.plantUmlHydrator.hasPendingWork())){this.setPhase("base");return}if(this.mermaidHydrator.hasPendingWork()||this.plantUmlHydrator.hasPendingWork()){this.setPhase("hydrating");return}this.notifyReady()}notifyReady(){this.renderHost&&(this.renderHost.style.minHeight=""),this.setPhase("ready"),this.readyRenderVersion!==this.activeRenderVersion&&(this.readyRenderVersion=this.activeRenderVersion,this.onRenderComplete?.({isLargeDocument:this.isLargeDocument,stats:this.currentStats}))}async fetchPlantUmlSvg(e){return this.plantUmlHydrator.fetchSvg(e)}async fetchPlantUmlSource(e){return this.plantUmlHydrator.fetchSource(e)}async fetchMermaidSource(e){return this.mermaidHydrator.fetchSource(e)}resetPlantUmlShell(e,{clearCache:t=!1,message:i="Renders server-side when visible"}={}){this.plantUmlHydrator.resetShell(e,{clearCache:t,message:i})}enhancePlantUmlDiagram(e,t){this.plantUmlHydrator.enhanceDiagram(e,t)}enhanceMermaidDiagram(e,t){this.mermaidHydrator.enhanceDiagram(e,t)}createMermaidZoomButton(e,t){return this.mermaidHydrator.createZoomButton(e,t)}createPlantUmlToolButton(e,t){return this.plantUmlHydrator.createToolButton(e,t)}};var Le=class{constructor({backlinksPanel:e,clearInitialFileBootstrap:t,closeSidebarOnMobile:i,elements:s,excalidrawEmbed:r,fileExplorer:a,getIsTabActive:o,getSessionLoadToken:l,gitDiffView:d,gitPanel:c,lobby:p,navigation:f,previewRenderer:h,renderAvatars:v,renderPresence:y,resetPreviewMode:E,scrollSyncController:C,setSession:P,setSessionLoadToken:I,setSidebarTab:A,setCurrentFilePath:z,showGitDiff:M,syncMainChrome:R,videoEmbed:$,workspaceCoordinator:B,layoutController:N}){this.backlinksPanel=e,this.clearInitialFileBootstrap=t,this.closeSidebarOnMobile=i,this.elements=s,this.excalidrawEmbed=r,this.fileExplorer=a,this.getIsTabActive=o,this.getSessionLoadToken=l,this.gitDiffView=d,this.gitPanel=c,this.lobby=p,this.navigation=f,this.previewRenderer=h,this.renderAvatars=v,this.renderPresence=y,this.resetPreviewMode=E,this.scrollSyncController=C,this.setSession=P,this.setSessionLoadToken=I,this.setSidebarTab=A,this.setCurrentFilePath=z,this.showGitDiff=M,this.syncMainChrome=R,this.videoEmbed=$,this.workspaceCoordinator=B,this.layoutController=N}async handleHashChange(){if(!this.getIsTabActive())return;let e=this.navigation.getHashRoute();if(e.type==="empty"){this.gitPanel.setSelection(),this.showEmptyState(),this.syncMainChrome({mode:"empty",title:"CollabMD"});return}if(e.type==="git-diff"){this.setSidebarTab("git"),await this.showGitDiff(e);return}this.setSidebarTab("files"),await this.openFile(e.filePath)}showEmptyState(){this.gitDiffView.hide(),this.workspaceCoordinator.cleanupSession(),this.setSession(null),this.setSessionLoadToken(this.getSessionLoadToken()+1),this.clearInitialFileBootstrap(),this.resetPreviewMode(),this.elements.outlineToggle?.classList.remove("hidden"),this.elements.markdownToolbar?.classList.add("hidden"),this.setCurrentFilePath(null),this.lobby.setCurrentFile(null),this.fileExplorer.setActiveFile(null),this.elements.emptyState?.classList.remove("hidden"),this.elements.editorPage?.classList.add("hidden"),this.elements.diffPage?.classList.add("hidden"),this.elements.previewContent&&(this.elements.previewContent.innerHTML="",this.elements.previewContent.dataset.renderPhase="ready"),this.videoEmbed?.reconcileEmbeds(this.elements.previewContent),this.resetPreviewSurface(),this.renderAvatars(),this.renderPresence(),this.backlinksPanel.clear(),this.elements.activeFileName&&(this.elements.activeFileName.textContent="CollabMD")}showDiffState(){this.setSessionLoadToken(this.getSessionLoadToken()+1),this.clearInitialFileBootstrap(),this.workspaceCoordinator.cleanupSession(),this.setSession(null),this.resetPreviewMode(),this.layoutController.reset(),this.setCurrentFilePath(null),this.lobby.setCurrentFile(null),this.fileExplorer.setActiveFile(null),this.elements.emptyState?.classList.add("hidden"),this.elements.editorPage?.classList.add("hidden"),this.elements.diffPage?.classList.remove("hidden"),this.elements.previewContent&&(this.elements.previewContent.innerHTML="",this.elements.previewContent.dataset.renderPhase="ready"),this.videoEmbed?.reconcileEmbeds(this.elements.previewContent),this.resetPreviewSurface(),this.elements.outlineToggle?.classList.add("hidden"),this.elements.markdownToolbar?.classList.add("hidden"),this.renderAvatars(),this.renderPresence(),this.backlinksPanel.clear()}async openFile(e){this.gitPanel.setSelection(),this.gitDiffView.hide(),this.syncMainChrome({mode:"editor"}),await this.workspaceCoordinator.openFile(e),this.setSession(this.workspaceCoordinator.getSession())}cleanupSession(){this.workspaceCoordinator.cleanupSession(),this.setSession(this.workspaceCoordinator.getSession())}handleFileSelection(e,{closeSidebarOnMobile:t=!1}={}){t&&this.closeSidebarOnMobile(),this.navigation.navigateToFile(e)}resetPreviewSurface(){this.previewRenderer.setHydrationPaused(!1),this.excalidrawEmbed.setHydrationPaused(!1),this.videoEmbed?.detachForCommit(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks()}};function k(n){let e=String(n??"").trim().replace(/\\/g,"/").replace(/^\/+/u,"").split("/").map(t=>t.trim()).filter(Boolean);return e.some(t=>t==="."||t==="..")?"":e.join("/")}function ie(n,e){let t=k(n),i=k(e);return t?i?`${t}/${i}`:t:i}function Vt(n,e){return n.toLowerCase().endsWith(e.toLowerCase())?n:`${n}${e}`}function ke(n){return`# ${q(String(n??"").split("/").pop()||"")||"Untitled"}
|
|
24
|
+
|
|
25
|
+
`}function Kt(n){let e=k(n),t=fe(e)?e:`${e}.mmd`;return{content:["flowchart TD"," A[Start] --> B{Decide}"," B -->|Yes| C[Ship it]"," B -->|No| D[Revise]",""].join(`
|
|
26
|
+
`),path:t}}function Gt(n){let e=k(n),t=ge(e)?e:`${e}.puml`;return{content:["@startuml","Alice -> Bob: Hello","@enduml",""].join(`
|
|
27
|
+
`),path:t}}var Fe=class{constructor({getFileList:e,navigation:t,refreshExplorer:i,toastController:s,vaultApiClient:r}){this.getFileList=e,this.navigation=t,this.refreshExplorer=i,this.toastController=s,this.vaultApiClient=r}handleWikiLinkClick(e){let t=vt(e,this.getFileList());if(t){this.navigation.navigateToFile(t);return}let i=this.normalizeNewWikiFilePath(e);if(!i){this.toastController.show("Cannot create an empty wiki-link target");return}this.createAndOpenFile(i,e)}normalizeNewWikiFilePath(e){let t=k(e);return t?t.endsWith(".md")?t:`${t}.md`:null}async createAndOpenFile(e,t){try{await this.vaultApiClient.createFile({content:ke(t||e),path:e}),await this.refreshExplorer(),this.navigation.navigateToFile(e)}catch(i){this.toastController.show(`Failed to create file: ${i.message}`)}}};var Ie=class{constructor({backlinksPanel:e,elements:t,excalidrawEmbed:i,getDisplayName:s,getSession:r,isExcalidrawFile:a,isMermaidFile:o,isPlantUmlFile:l,layoutController:d,outlineController:c,previewRenderer:p,schedulePreviewLayoutSync:f,scrollSyncController:h,videoEmbed:v}){this.backlinksPanel=e,this.elements=t,this.excalidrawEmbed=i,this.getDisplayName=s,this.getSession=r,this.isExcalidrawFile=a,this.isMermaidFile=o,this.isPlantUmlFile=l,this.layoutController=d,this.outlineController=c,this.previewRenderer=p,this.schedulePreviewLayoutSyncCallback=f,this.scrollSyncController=h,this.videoEmbed=v}createDiagramPreviewDocument(e,t=""){let i=String(t??""),s=Math.max(...i.match(/`+/g)?.map(a=>a.length)??[0]),r="`".repeat(Math.max(3,s+1));return`${r}${e}
|
|
28
|
+
${i}
|
|
29
|
+
${r}`}getPreviewSource(e){let t=this.getSession()?.getText()??"";return this.isMermaidFile(e)?this.createDiagramPreviewDocument("mermaid",t):this.isPlantUmlFile(e)?this.createDiagramPreviewDocument("plantuml",t):t}resetPreviewMode(){this.elements.previewContent?.classList.remove("is-excalidraw-file-preview"),this.elements.previewContent?.classList.remove("is-mermaid-file-preview"),this.elements.previewContent?.classList.remove("is-plantuml-file-preview")}syncFileChrome(e){let t=this.isExcalidrawFile(e),i=Y(e),s=this.isMermaidFile(e),r=this.isPlantUmlFile(e),a=Ft(e);if(this.elements.markdownToolbar?.classList.toggle("hidden",!i),this.elements.outlineToggle?.classList.toggle("hidden",a),this.elements.previewContent?.classList.toggle("is-mermaid-file-preview",s),this.elements.previewContent?.classList.toggle("is-plantuml-file-preview",r),t){this.layoutController.setView("preview",{persist:!1}),this.outlineController.close(),this.backlinksPanel.clear();return}(s||r)&&(this.outlineController.close(),this.backlinksPanel.clear())}renderExcalidrawFilePreview(e){let t=this.elements.previewContent;if(!t)return;this.videoEmbed?.detachForCommit(),this.excalidrawEmbed.detachForCommit(),this.resetPreviewMode(),t.classList.add("is-excalidraw-file-preview");let i=this.previewRenderer.ensureRenderHost();this.previewRenderer.normalizePreviewChildren(i);let s=document.createElement("div");s.className="excalidraw-embed-placeholder",s.dataset.embedKey=`${e}#file-preview`,s.dataset.embedLabel=this.getDisplayName(e),s.dataset.embedTarget=e;let r=document.createElement("div");r.className="preview-shell",r.textContent="Loading Excalidraw preview\u2026",s.appendChild(r),i&&(i.replaceChildren(s),i.style.minHeight=""),t.dataset.renderPhase="ready",this.outlineController.refresh(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(t),this.excalidrawEmbed.reconcileEmbeds(t,{isLargeDocument:!1}),this.excalidrawEmbed.hydrateVisibleEmbeds(),this.schedulePreviewLayoutSyncCallback({delayMs:0})}createResizeHandler(e){let t=null;return()=>{clearTimeout(t),t=setTimeout(()=>{e?.(),this.schedulePreviewLayoutSyncCallback({delayMs:0})},100)}}initializePreviewLayoutObserver(e=()=>{}){if(typeof ResizeObserver!="function"||!this.elements.previewContent)return null;let t=new ResizeObserver(()=>{e()});return t.observe(this.elements.previewContent),t}schedulePreviewLayoutSync({hydrationPaused:e,previewLayoutSyncTimer:t,setPendingPreviewLayoutSync:i,setPreviewLayoutSyncTimer:s,delayMs:r=120}){if(e){i(!0);return}clearTimeout(t);let a=setTimeout(()=>{s(null);let o=!!this.getSession(),l=this.elements.previewContent?.classList?.contains?.("is-excalidraw-file-preview")??!1;if(!(!o&&!l||!this.elements.previewContent)&&this.elements.previewContent.dataset.renderPhase!=="shell"){if(e){i(!0);return}this.previewRenderer.scheduleActiveMermaidRefit(),this.previewRenderer.scheduleActivePlantUmlRefit(),this.videoEmbed?.syncLayout(),this.excalidrawEmbed.syncLayout(),!(l&&!o)&&(this.scrollSyncController.invalidatePreviewBlocks(),this.scrollSyncController.warmPreviewBlocks({onReady:()=>{this.getSession()&&(this.scrollSyncController.realignAfterLayoutChange(),this.outlineController.scheduleActiveHeadingUpdate())}}))}},r);s(a)}handleEditorScrollActivityChange({isActive:e,pendingPreviewLayoutSync:t,previewLayoutSyncTimer:i,setHydrationPaused:s,setPendingPreviewLayoutSync:r,setPreviewLayoutSyncTimer:a}){let o=!!e;if(s(o),this.previewRenderer.setHydrationPaused(o),this.excalidrawEmbed.setHydrationPaused(o),o){clearTimeout(i),a(null),r(!0);return}t&&(r(!1),this.schedulePreviewLayoutSync({delayMs:0,hydrationPaused:!1,previewLayoutSyncTimer:null,setPendingPreviewLayoutSync:r,setPreviewLayoutSyncTimer:a}))}};var Te=class{constructor({attachEditorScroller:e,createEditorSession:t,loadEditorSessionClass:i,scrollContainerForSession:s}){this.attachEditorScroller=e,this.createEditorSession=t,this.loadEditorSessionClass=i,this.scrollContainerForSession=s}async createSession(e){let t=await this.loadEditorSessionClass();return this.createEditorSession(t,e)}attachSessionScroller(e){this.attachEditorScroller(this.scrollContainerForSession(e))}clearSessionScroller(){this.attachEditorScroller(null)}};var Pe=class{constructor({beginDocumentLoad:e,getDisplayName:t,loadBacklinks:i,onBeforeFileOpen:s,onFileOpenError:r,onFileOpenReady:a,onRenderExcalidrawPreview:o,onSyncWrapToggle:l,onUpdateActiveFile:d,onUpdateCurrentFile:c,onUpdateLobbyCurrentFile:p,onUpdateVisibleChrome:f,onViewModeReset:h,renderPresence:v,showEditorLoading:y,stateStore:E}){this.beginDocumentLoad=e,this.getDisplayName=t,this.loadBacklinks=i,this.onBeforeFileOpen=s,this.onFileOpenError=r,this.onFileOpenReady=a,this.onRenderExcalidrawPreview=o,this.onSyncWrapToggle=l,this.onUpdateActiveFile=d,this.onUpdateCurrentFile=c,this.onUpdateLobbyCurrentFile=p,this.onUpdateVisibleChrome=f,this.onViewModeReset=h,this.renderPresence=v,this.showEditorLoading=y,this.stateStore=E}prepareForFileOpen(e,{resetConnectionState:t=!0}={}){return this.onViewModeReset(),this.onBeforeFileOpen(),this.stateStore.set("connectionHelpShown",!1),t&&this.stateStore.set("connectionState",{status:"connecting",unreachable:!1}),this.stateStore.set("currentFilePath",e),this.onUpdateCurrentFile(e),this.onUpdateLobbyCurrentFile(e),this.onUpdateActiveFile(e),this.onUpdateVisibleChrome(e,{displayName:this.getDisplayName(e),isMarkdown:Y(e)}),this.showEditorLoading(),this.beginDocumentLoad(),this.renderPresence(),{supportsBacklinks:we(e)}}markFileOpenReady(e){this.onFileOpenReady(e)}finalizeFileOpen({filePath:e,isExcalidraw:t,session:i=null,supportsBacklinks:s}){t&&this.onRenderExcalidrawPreview(e),this.onSyncWrapToggle(),s&&i&&this.loadBacklinks(e)}handleFileOpenError(){this.onFileOpenError()}};var Ae=class{constructor({attachEditorScroller:e,beginDocumentLoad:t,cleanupAfterSessionDestroy:i,createEditorSession:s,getDisplayName:r,getFileList:a,getLineWrappingEnabled:o,getLocalUser:l,getStoredUserName:d,getTheme:c,isExcalidrawFile:p,isMermaidFile:f,isPlantUmlFile:h,isTabActive:v,loadEditorSessionClass:y,loadBacklinks:E,onBeforeFileOpen:C,onConnectionChange:P,onContentChange:I,onCommentsChange:A,onFileAwarenessChange:z,onFileOpenError:M,onFileOpenReady:R,onSelectionChange:$,onSessionAssigned:B=null,onRenderExcalidrawPreview:N,onSyncWrapToggle:Z,onUpdateActiveFile:V,onUpdateCurrentFile:K,onUpdateLobbyCurrentFile:G,onUpdateVisibleChrome:H,onViewModeReset:D,renderPresence:U,scrollContainerForSession:re,showEditorLoading:O,stateStore:_}){this.attachEditorScroller=e,this.beginDocumentLoad=t,this.cleanupAfterSessionDestroy=i,this.createEditorSession=s,this.getDisplayName=r,this.getFileList=a,this.getLineWrappingEnabled=o,this.getLocalUser=l,this.getStoredUserName=d,this.getTheme=c,this.isExcalidrawFile=p,this.isMermaidFile=f,this.isPlantUmlFile=h,this.isTabActive=v,this.loadEditorSessionClassPort=y,this.loadBacklinks=E,this.onBeforeFileOpen=C,this.onConnectionChange=P,this.onContentChange=I,this.onCommentsChange=A,this.onFileAwarenessChange=z,this.onFileOpenError=M,this.onFileOpenReady=R,this.onSelectionChange=$,this.onSessionAssigned=B,this.onRenderExcalidrawPreview=N,this.onSyncWrapToggle=Z,this.onUpdateActiveFile=V,this.onUpdateCurrentFile=K,this.onUpdateLobbyCurrentFile=G,this.onUpdateVisibleChrome=H,this.renderPresence=U,this.stateStore=_,this.session=null,this.lifecycle=new Te({attachEditorScroller:e,createEditorSession:s,loadEditorSessionClass:()=>this.loadEditorSessionClassPort(),scrollContainerForSession:re}),this.chromeController=new Pe({beginDocumentLoad:t,getDisplayName:r,loadBacklinks:E,onBeforeFileOpen:C,onFileOpenError:M,onFileOpenReady:R,onRenderExcalidrawPreview:N,onSyncWrapToggle:Z,onUpdateActiveFile:V,onUpdateCurrentFile:K,onUpdateLobbyCurrentFile:G,onUpdateVisibleChrome:H,onViewModeReset:D,renderPresence:U,showEditorLoading:O,stateStore:_})}getSession(){return this.session}loadEditorSessionClass(){return this.loadEditorSessionClassPort()}waitForNextPaint(){return new Promise(e=>{requestAnimationFrame(()=>{requestAnimationFrame(e)})})}cleanupSession(){this.session?.destroy(),this.session=null,this.lifecycle.clearSessionScroller(),this.cleanupAfterSessionDestroy()}async openFile(e){if(!this.isTabActive())return;let t=this.isExcalidrawFile(e),i=this.isMermaidFile(e),s=this.isPlantUmlFile(e);if(e===this.stateStore.get("currentFilePath")&&(this.session||t)){this.onUpdateActiveFile(e),this.onUpdateLobbyCurrentFile(e);return}let r=this.stateStore.nextSessionLoadToken();this.cleanupSession();let a=this.chromeController.prepareForFileOpen(e,{resetConnectionState:!t});if(t){if(this.onSessionAssigned?.(null),r!==this.stateStore.get("sessionLoadToken"))return;this.chromeController.markFileOpenReady(null),this.chromeController.finalizeFileOpen({filePath:e,isExcalidraw:!0,session:null,supportsBacklinks:a.supportsBacklinks});return}let o=await this.lifecycle.createSession({filePath:e,getFileList:this.getFileList,lineWrappingEnabled:this.getLineWrappingEnabled(),localUser:this.getLocalUser(),onAwarenessChange:l=>this.onFileAwarenessChange(l),onConnectionChange:l=>this.onConnectionChange(l),onCommentsChange:l=>this.onCommentsChange?.(l),onContentChange:()=>{t||this.onContentChange({isMermaid:i,isPlantUml:s})},preferredUserName:this.getStoredUserName(),onSelectionChange:l=>this.onSelectionChange?.(l),theme:this.getTheme()});this.session=o,this.onSessionAssigned?.(o);try{if(await o.initialize(e),r!==this.stateStore.get("sessionLoadToken")){o.destroy();return}if(this.lifecycle.attachSessionScroller(o),o.applyTheme(this.getTheme()),await o.waitForInitialSync(),o.ensureInitialContent?.(),r!==this.stateStore.get("sessionLoadToken")){o.destroy();return}if(this.chromeController.markFileOpenReady(o),o.requestMeasure(),await this.waitForNextPaint(),r!==this.stateStore.get("sessionLoadToken")){o.destroy();return}this.chromeController.finalizeFileOpen({filePath:e,isExcalidraw:t,session:o,supportsBacklinks:a.supportsBacklinks})}catch(l){if(console.error("[app] Failed to initialize editor:",l),o.destroy(),this.lifecycle.clearSessionScroller(),this.session===o&&(this.session=null),r!==this.stateStore.get("sessionLoadToken"))return;this.chromeController.handleFileOpenError()}}};var Me=class{constructor(e={}){this.state={activeSidebarTab:"files",chatInitialSyncComplete:!1,chatIsOpen:!1,chatMessageIds:new Set,chatMessages:[],chatUnreadCount:0,connectionHelpShown:!1,connectionState:{status:"disconnected",unreachable:!1},currentFilePath:null,fileExplorerReady:!1,followedCursorSignature:"",followedUserClientId:null,gitRepoAvailable:!1,globalUsers:[],isTabActive:!1,sessionLoadToken:0,...e}}get(e){return this.state[e]}set(e,t){return this.state[e]=t,t}nextSessionLoadToken(){let e=Number(this.state.sessionLoadToken||0)+1;return this.state.sessionLoadToken=e,e}replaceChatState({initialSyncComplete:e,isOpen:t,messageIds:i,messages:s,unreadCount:r}){this.state.chatMessages=Array.isArray(s)?s:[],this.state.chatMessageIds=i instanceof Set?i:new Set,this.state.chatUnreadCount=Number.isFinite(r)?r:0,this.state.chatIsOpen=!!t,this.state.chatInitialSyncComplete=!!e}};function jt(n=document){return{currentUserName:n.getElementById("currentUserName"),chatContainer:n.getElementById("chatContainer"),chatEmptyState:n.getElementById("chatEmptyState"),chatForm:n.getElementById("chatForm"),chatInput:n.getElementById("chatInput"),chatMessages:n.getElementById("chatMessages"),chatNotificationButton:n.getElementById("chatNotificationBtn"),chatPanel:n.getElementById("chatPanel"),chatStatus:n.getElementById("chatStatus"),chatToastContainer:n.getElementById("chatToastContainer"),chatToggleBadge:n.getElementById("chatToggleBadge"),chatToggleButton:n.getElementById("chatToggleBtn"),gitCommitCancel:n.getElementById("gitCommitCancel"),gitCommitCopy:n.getElementById("gitCommitCopy"),gitCommitDialog:n.getElementById("gitCommitDialog"),gitCommitForm:n.getElementById("gitCommitForm"),gitCommitInput:n.getElementById("gitCommitInput"),gitCommitSubmit:n.getElementById("gitCommitSubmit"),gitCommitTitle:n.getElementById("gitCommitTitle"),gitResetCancel:n.getElementById("gitResetCancel"),gitResetCopy:n.getElementById("gitResetCopy"),gitResetDialog:n.getElementById("gitResetDialog"),gitResetFileName:n.getElementById("gitResetFileName"),gitResetSubmit:n.getElementById("gitResetSubmit"),gitResetTitle:n.getElementById("gitResetTitle"),displayNameCancel:n.getElementById("displayNameCancel"),displayNameCopy:n.getElementById("displayNameCopy"),displayNameDialog:n.getElementById("displayNameDialog"),displayNameForm:n.getElementById("displayNameForm"),displayNameInput:n.getElementById("displayNameInput"),displayNameSubmit:n.getElementById("displayNameSubmit"),displayNameTitle:n.getElementById("displayNameTitle"),editNameButton:n.getElementById("editNameBtn"),editorContainer:n.getElementById("editorContainer"),markdownToolbar:n.getElementById("markdownToolbar"),editorPage:n.getElementById("editor-page"),diffPage:n.getElementById("diff-page"),fileSearch:n.getElementById("fileSearch"),filesSidebarTab:n.getElementById("filesSidebarTab"),gitSearch:n.getElementById("gitSearch"),gitSearchInput:n.getElementById("gitSearchInput"),gitSidebarTab:n.getElementById("gitSidebarTab"),gitOperationStatus:n.getElementById("gitOperationStatus"),lineInfo:n.getElementById("lineInfo"),mobileViewToggle:n.getElementById("mobileViewToggle"),previewContent:n.getElementById("previewContent"),previewContainer:n.getElementById("previewContainer"),shareButton:n.getElementById("shareBtn"),toastContainer:n.getElementById("toastContainer"),toggleWrapButton:n.getElementById("toggleWrapBtn"),userAvatars:n.getElementById("userAvatars"),userCount:n.getElementById("userCount"),wrapToggleLabel:n.getElementById("wrapToggleLabel"),activeFileName:n.getElementById("activeFileName"),sidebarToggle:n.getElementById("sidebarToggle"),sidebarClose:n.getElementById("sidebarClose"),sidebar:n.getElementById("sidebar"),emptyState:n.getElementById("emptyState"),emptyStateNewFileBtn:n.getElementById("emptyStateNewFileBtn"),emptyStateSearchBtn:n.getElementById("emptyStateSearchBtn"),backlinksPanel:n.getElementById("backlinksPanel"),commentSelectionButton:n.getElementById("commentSelectionBtn"),commentsDrawer:n.getElementById("commentsDrawer"),commentsDrawerEmpty:n.getElementById("commentsDrawerEmpty"),commentsDrawerList:n.getElementById("commentsDrawerList"),commentsToggleButton:n.getElementById("commentsToggle"),outlineToggle:n.getElementById("outlineToggle"),tabLockCopy:n.getElementById("tabLockCopy"),tabLockOverlay:n.getElementById("tabLockOverlay"),tabLockTakeoverButton:n.getElementById("tabLockTakeoverBtn"),tabLockTitle:n.getElementById("tabLockTitle"),toolbarCenter:n.getElementById("toolbarCenter"),toolbarDiffBadge:n.getElementById("toolbarDiffBadge"),sidebarTabs:n.getElementById("sidebarTabs")}}var Qt={updateChatMessages(n,{initial:e=!1}={}){let t=new Set(this.chatMessageIds),i=this.lobby.getLocalUser()?.peerId??null;if(this.chatMessages=n,this.chatMessageIds=new Set(n.map(r=>r.id)),!this.chatInitialSyncComplete){e&&(this.chatInitialSyncComplete=!0),this.renderChat();return}let s=n.filter(r=>!t.has(r.id)&&r.peerId&&r.peerId!==i);this.chatIsOpen?this.chatUnreadCount=0:s.length>0&&(this.chatUnreadCount+=s.length);for(let r of s)this.maybeNotifyChatMessage(r);this.renderChat()},toggleChatPanel(){if(this.chatIsOpen){this.closeChatPanel();return}this.openChatPanel()},openChatPanel(){this.chatIsOpen=!0,this.chatUnreadCount=0,this.renderChat(),requestAnimationFrame(()=>{this.elements.chatInput?.focus(),this.scrollChatToBottom()})},closeChatPanel(){this.chatIsOpen&&(this.chatIsOpen=!1,this.renderChat())},handleChatSubmit(){if(!this.isTabActive)return;let n=this.elements.chatInput;if(!n)return;if(!this.lobby.sendChatMessage(n.value)){n.focus();return}if(n.value="",!this.chatIsOpen){this.openChatPanel();return}this.renderChat()},renderChat(){this.elements.chatContainer?.classList.toggle("is-open",this.chatIsOpen),this.elements.chatPanel?.classList.toggle("hidden",!this.chatIsOpen),this.syncChatToggleButton(),this.syncChatNotificationButton();let n=this.elements.chatMessages,e=this.elements.chatEmptyState;if(this.elements.chatStatus&&(this.elements.chatStatus.textContent=this.chatInitialSyncComplete?`${this.globalUsers.length} online`:"Syncing..."),!n)return;if(n.replaceChildren(),this.chatMessages.length===0){e?.classList.remove("hidden"),n.classList.add("hidden");return}e?.classList.add("hidden"),n.classList.remove("hidden");let t=document.createDocumentFragment();this.chatMessages.forEach(i=>{t.appendChild(this.createChatMessageElement(i))}),n.appendChild(t),this.chatIsOpen&&this.scrollChatToBottom()},createChatMessageElement(n){let e=document.createElement("article"),t=n.peerId===this.lobby.getLocalUser()?.peerId;e.className="chat-message",e.classList.toggle("is-local",t);let i=document.createElement("div");i.className="chat-message-avatar",i.style.backgroundColor=n.userColor||"var(--color-primary)",i.textContent=(n.userName||"?").charAt(0).toUpperCase(),i.setAttribute("aria-hidden","true");let s=document.createElement("div");s.className="chat-message-body";let r=document.createElement("div");r.className="chat-message-meta";let a=document.createElement("span");a.className="chat-message-author",a.textContent=t?`${n.userName} (you)`:n.userName;let o=document.createElement("span");o.className="chat-message-time",o.textContent=this.formatChatTimestamp(n.createdAt),r.append(a,o);let l=this.getChatMessageFileLabel(n.filePath);if(l){let c=document.createElement("span");c.className="chat-message-file",c.textContent=l,r.append(c)}let d=document.createElement("p");return d.className="chat-message-text",d.textContent=n.text,s.append(r,d),e.append(i,s),e},scrollChatToBottom(){let n=this.elements.chatMessages;n&&requestAnimationFrame(()=>{n.scrollTop=n.scrollHeight})},formatChatTimestamp(n){if(!Number.isFinite(n))return"";try{return this.chatTimeFormatter.format(new Date(n))}catch{return""}},getChatMessageFileLabel(n){return n?this.getDisplayName(n):""},formatChatToastMessage(n){let e=n?.userName||"Someone",t=String(n?.text??"").replace(/\s+/g," ").trim(),i=t.length>88?`${t.slice(0,85).trimEnd()}...`:t;return`${e}: ${i}`},syncChatToggleButton(){let n=this.elements.chatToggleButton,e=this.elements.chatToggleBadge;if(!n)return;let t=this.chatUnreadCount>0,i=t&&!this.chatIsOpen;n.classList.toggle("is-active",this.chatIsOpen),n.classList.toggle("is-unread",i),n.setAttribute("aria-expanded",String(this.chatIsOpen)),n.setAttribute("aria-label",t?`Open team chat, ${this.chatUnreadCount} unread`:"Open team chat"),n.title=this.chatUnreadCount>0?`Team chat (${this.chatUnreadCount} unread)`:"Team chat",e&&(e.classList.toggle("hidden",!t),e.textContent=this.chatUnreadCount>9?"9+":String(this.chatUnreadCount))},syncChatNotificationButton(){let n=this.elements.chatNotificationButton;if(!n)return;let e=this.notifications.getPermission();this.chatNotificationPermission=e;let t="Enable alerts",i="Enable browser notifications for new chat messages",s=!1;e==="unsupported"?(t="No alerts",i="Browser notifications are unavailable here"):e==="denied"?(t="Alerts blocked",i="Browser notifications are blocked for this site"):e==="granted"&&(s=this.chatNotificationsEnabled,t=s?"Alerts on":"Alerts off",i=s?"Disable browser notifications for chat":"Enable browser notifications for chat"),n.textContent=t,n.title=i,n.setAttribute("aria-pressed",String(s)),n.classList.toggle("is-enabled",s),n.classList.toggle("is-blocked",e==="denied")},async handleChatNotificationToggle(){let n=this.notifications.getPermission();if(this.chatNotificationPermission=n,n==="unsupported"){this.toastController.show("Browser notifications are unavailable here"),this.syncChatNotificationButton();return}if(n==="denied"){this.chatNotificationsEnabled=!1,this.preferences.setChatNotificationsEnabled(!1),this.toastController.show("Browser notifications are blocked for this site"),this.syncChatNotificationButton();return}if(n==="default"){let e=await this.notifications.requestPermission();if(this.chatNotificationPermission=e,e!=="granted"){this.chatNotificationsEnabled=!1,this.preferences.setChatNotificationsEnabled(!1),e==="denied"&&this.toastController.show("Browser notifications were blocked"),this.syncChatNotificationButton();return}this.chatNotificationsEnabled=!0,this.preferences.setChatNotificationsEnabled(!0),this.syncChatNotificationButton();return}this.chatNotificationsEnabled=!this.chatNotificationsEnabled,this.preferences.setChatNotificationsEnabled(this.chatNotificationsEnabled),this.syncChatNotificationButton()},maybeNotifyChatMessage(n){if(this.chatInitialSyncComplete){if(document.hidden){this.maybeShowBrowserChatNotification(n);return}!this.isTabActive||this.chatIsOpen||(this.chatToastController??this.toastController).show(this.formatChatToastMessage(n),4e3)}},maybeShowBrowserChatNotification(n){if(!this.chatNotificationsEnabled||this.notifications.getPermission()!=="granted")return;let e=`CollabMD chat \u2022 ${n.userName}`,t=this.getChatMessageFileLabel(n.filePath),i=t?`${t}: ${n.text}`:n.text,s=this.notifications.createNotification({body:i,onClick:()=>{n.filePath&&this.navigation.navigateToFile(n.filePath)},tag:`collabmd-chat-${n.id}`,title:e});s&&setTimeout(()=>{s.close?.()},6e3)}};var Zt={getCommentFileKind(n=this.currentFilePath){return St(n)||"markdown"},syncCommentChrome(n=this.currentFilePath){let e=It(n)&&!this.isExcalidrawFile(n);this.commentUi.setCurrentFile(n,{fileKind:this.getCommentFileKind(n),supported:e}),this.handleCommentThreadsChange(this.session?.getCommentThreads?.()??[]),this.handleCommentSelectionChange(this.session?.getCurrentSelectionCommentAnchor?.()??null)},handleCommentSelectionChange(n){this.commentUi.setSelectionAnchor(n)},handleCommentThreadsChange(n=[]){this.commentUi.setThreads(n)},handleCommentEditorContentChange(){this.commentUi.handleEditorContentChange()},refreshCommentUiLayout(){this.commentUi.refreshLayout()}};function Jt(n={}){return{changedPaths:Array.isArray(n.changedPaths)?n.changedPaths.filter(Boolean):[],deletedPaths:Array.isArray(n.deletedPaths)?n.deletedPaths.filter(Boolean):[],refreshExplorer:n.refreshExplorer!==!1,renamedPaths:Array.isArray(n.renamedPaths)?n.renamedPaths.filter(e=>e?.oldPath&&e?.newPath):[]}}var Yt={setGitOperationStatus(n=""){let e=this.elements.gitOperationStatus;if(!e)return;let t=String(n??"").trim();e.textContent=t,e.classList.toggle("hidden",!t)},async runGitActionWithStatus(n,e){this.setGitOperationStatus(n);try{return await e()}finally{this.setGitOperationStatus("")}},handleGitDiffSelection(n,{closeSidebarOnMobile:e=!1,scope:t="working-tree"}={}){e&&this.closeSidebarOnMobile(),this.navigation.navigateToGitDiff({filePath:n,scope:t})},handleGitRepoChange(n,e=null){this.gitRepoAvailable=!!n,this.elements.sidebarTabs?.classList.toggle("hidden",!this.gitRepoAvailable),this.elements.gitSidebarTab?.classList.toggle("hidden",!this.gitRepoAvailable);let t=n&&e?.summary?.changedFiles>0;if(this.elements.gitSidebarTab?.classList.toggle("has-changes",t),this.gitDiffView.setRepoStatus(this.gitRepoAvailable?e:null),!this.gitRepoAvailable&&this.activeSidebarTab==="git"){this.setSidebarTab("files");return}this.gitRepoAvailable&&this.navigation.getHashRoute().type==="git-diff"&&this.activeSidebarTab!=="git"&&this.setSidebarTab("git")},syncMainChrome({mode:n,title:e=null}={}){let t=n==="diff";this.elements.toolbarCenter?.classList.toggle("hidden",t),this.elements.mobileViewToggle?.classList.toggle("hidden",t),this.elements.userCount?.classList.toggle("hidden",t),this.elements.toolbarDiffBadge?.classList.toggle("hidden",!t),e&&this.elements.activeFileName&&(this.elements.activeFileName.textContent=e)},async showGitDiff({filePath:n=null,scope:e="all"}={}){this.gitPanel.setSelection(n?{path:n,scope:e}:{}),this.showDiffState(),this.syncMainChrome({mode:"diff",title:this.gitDiffView.getToolbarTitle({filePath:n,scope:e})}),await this.gitDiffView.open({filePath:n,scope:e})},async postGitAction(n,e){let t=await fetch(n,{body:JSON.stringify(e),headers:{"Content-Type":"application/json"},method:"POST"}),i=await t.json();if(!t.ok)throw new Error(i.error||"Git action failed");return i},async refreshWorkspaceAfterGitAction({filePath:n=null,preferredScope:e=null}={}){await this.fileExplorer.refresh(),await this.refreshGitAfterAction({filePath:n,preferredScope:e})},async refreshGitAfterAction({filePath:n=null,preferredScope:e=null}={}){await this.gitPanel.refresh({force:!0});let t=this.navigation.getHashRoute();if(t.type!=="git-diff")return;let i=n??t.filePath,s=e??t.scope;if(s!==t.scope||i!==t.filePath){this.navigation.navigateToGitDiff({filePath:i,scope:s});return}await this.showGitDiff({filePath:t.filePath,scope:t.scope})},async finalizeGitAction({action:n,filePath:e=null,preferredScope:t=null,result:i={},showLocalFileToast:s=!1}={}){let r=Jt(i.workspaceChange);return await this.refreshWorkspaceAfterGitAction({filePath:e,preferredScope:t}),this.handleWorkspaceChangeForCurrentFile(r,{action:n,local:!0,showToast:s}),this.lobby.sendWorkspaceEvent({action:n,sourceRef:i.sourceRef??null,workspaceChange:r}),r},handleWorkspaceChangeForCurrentFile(n,{action:e="git",local:t=!1,showToast:i=!0}={}){let s=this.currentFilePath;if(!s)return!1;let r=n.deletedPaths.includes(s),a=n.renamedPaths.find(l=>l.oldPath===s);if(!r&&!a)return!1;if(this.navigation.navigateToFile(null),!i)return!0;let o=this.getDisplayName(s);return a?(this.toastController.show(t?`${o} was reset away from this branch path`:`${o} moved after a ${e} operation`),!0):(this.toastController.show(t?`${o} was removed by ${e}`:`${o} was removed after a ${e} operation`),!0)},async handleIncomingWorkspaceEvent(n){if(!this.isTabActive||!n)return;let e=Jt(n.workspaceChange);await this.refreshWorkspaceAfterGitAction(),this.handleWorkspaceChangeForCurrentFile(e,{action:n.action||"git",local:!1,showToast:!0})},async stageGitFile(n,{scope:e="working-tree"}={}){n&&await this.runGitActionWithStatus("Staging changes...",async()=>{let t=await this.postGitAction(b("/git/stage"),{path:n});await this.finalizeGitAction({action:"stage",filePath:n,preferredScope:e==="all"?"all":"staged",result:t})})},async unstageGitFile(n,{scope:e="staged"}={}){n&&await this.runGitActionWithStatus("Unstaging changes...",async()=>{let t=await this.postGitAction(b("/git/unstage"),{path:n});await this.finalizeGitAction({action:"unstage",filePath:n,preferredScope:e==="all"?"all":"working-tree",result:t})})},async pushGitBranch(){await this.runGitActionWithStatus("Pushing branch...",async()=>{try{let n=await this.postGitAction(b("/git/push"),{});await this.finalizeGitAction({action:"push",result:n})}catch(n){this.toastController.show(n.message||"Failed to push branch")}})},async pullGitBranch(){await this.runGitActionWithStatus("Pulling branch...",async()=>{try{let n=await this.postGitAction(b("/git/pull"),{});await this.finalizeGitAction({action:"pull",result:n,showLocalFileToast:!0})}catch(n){this.toastController.show(n.message||"Failed to pull branch")}})},openGitResetDialog(n){if(!this.isTabActive||!n)return;let e=this.elements.gitResetDialog;!e||!this.elements.gitResetFileName||(this.pendingGitResetPath=n,this.elements.gitResetTitle&&(this.elements.gitResetTitle.textContent="Reset file to current branch"),this.elements.gitResetCopy&&(this.elements.gitResetCopy.textContent="Restore this file from the current checked-out branch. If this branch does not contain the file, the file will be deleted locally."),this.elements.gitResetFileName.value=n,this.elements.gitResetSubmit&&(this.elements.gitResetSubmit.textContent="Reset File"),this.elements.gitResetSubmit?.toggleAttribute("disabled",!1),!e.open&&(typeof e.showModal=="function"?e.showModal():e.setAttribute("open","true")))},async handleGitResetSubmit(){let n=this.pendingGitResetPath,e=this.elements.gitResetDialog,t=this.elements.gitResetSubmit;if(!(!n||!e)){t?.toggleAttribute("disabled",!0),t&&(t.textContent="Resetting...");try{await this.runGitActionWithStatus("Resetting file...",async()=>{let i=await this.postGitAction(b("/git/reset-file"),{path:n});await this.finalizeGitAction({action:"reset",filePath:n,result:i,showLocalFileToast:!0})}),e.close()}catch(i){this.toastController.show(i.message||"Failed to reset file")}finally{t&&(t.textContent="Reset File"),t?.toggleAttribute("disabled",!1)}}},openGitCommitDialog(){if(!this.isTabActive)return;let n=this.elements.gitCommitDialog,e=this.elements.gitCommitInput;if(!(!n||!e)){if(this.elements.gitCommitTitle&&(this.elements.gitCommitTitle.textContent="Commit staged changes"),this.elements.gitCommitCopy){let t=Number(this.gitPanel.status?.summary?.staged||0);this.elements.gitCommitCopy.textContent=t>0?`${t} staged file${t===1?"":"s"} will be included.`:"All staged changes will be included."}this.elements.gitCommitSubmit&&(this.elements.gitCommitSubmit.textContent="Commit staged changes"),e.value="",!n.open&&(typeof n.showModal=="function"?n.showModal():n.setAttribute("open","true"),requestAnimationFrame(()=>{e.focus(),e.select()}))}},async handleGitCommitSubmit(){let n=this.elements.gitCommitDialog,e=this.elements.gitCommitInput,t=this.elements.gitCommitSubmit,i=String(e?.value??"").trim();if(!(!n||!e)){if(!i){e.focus(),this.toastController.show("Commit message cannot be empty");return}t?.toggleAttribute("disabled",!0),t&&(t.textContent="Committing...");try{await this.runGitActionWithStatus("Committing changes...",async()=>{let s=await this.postGitAction(b("/git/commit"),{message:i});await this.finalizeGitAction({action:"commit",result:s})}),n.close()}catch(s){this.toastController.show(s.message||"Failed to commit staged changes")}finally{t&&(t.textContent="Commit staged changes"),t?.toggleAttribute("disabled",!1)}}}};var Xt={updateGlobalUsers(n){this.globalUsers=n,this.syncFollowedUser(),this.renderAvatars(),this.renderChat(),this.renderPresence(),this.syncCurrentUserName()},updateFileAwareness(n){this.syncFollowedUser()},renderPresence(){let n=this.elements.userCount;if(!n)return;let e=!!this.session,t=!!(this.currentFilePath&&this.isExcalidrawFile?.(this.currentFilePath)),s=!e&&(!this.currentFilePath||t)?this.lobby?.getConnectionState?.()??this.connectionState:this.connectionState;if(s.status==="connected"){n.textContent=`${this.globalUsers.length} online`,n.style.opacity="1";return}if(s.status==="connecting"){n.textContent=s.unreachable?"Unreachable":"Connecting...",n.style.opacity="0.6";return}n.textContent="Offline",n.style.opacity="0.6"},renderAvatars(){let n=this.elements.userAvatars;if(!n)return;n.innerHTML="";let e=[...this.globalUsers],t=e.findIndex(r=>r.isLocal);if(t>0){let[r]=e.splice(t,1);e.unshift(r)}let i=e.findIndex(r=>!r.isLocal&&r.clientId===this.followedUserClientId),s=e[0]?.isLocal?1:0;if(i>s){let[r]=e.splice(i,1);e.splice(s,0,r)}if(e.slice(0,5).forEach(r=>{let a=document.createElement(r.isLocal?"div":"button");a.className="user-avatar",a.classList.toggle("is-local",r.isLocal),a.style.backgroundColor=r.color,a.classList.toggle("is-following",r.clientId===this.followedUserClientId);let o=document.createElement("span");o.className="user-avatar-initial",o.textContent=r.name.charAt(0).toUpperCase(),a.appendChild(o);let l=r.currentFile&&r.currentFile===this.currentFilePath,d=r.currentFile?this.getDisplayName(r.currentFile):"No file";if(r.isLocal){let c=document.createElement("span");c.className="user-avatar-self-label",c.textContent="You",a.appendChild(c),a.title=`${r.name} (you) \u2014 ${d}`,a.setAttribute("role","img"),a.setAttribute("aria-label",`${r.name} (you) \u2014 ${d}`)}else{a.type="button",a.classList.add("user-avatar-button"),l||a.classList.add("different-file");let c=r.clientId===this.followedUserClientId?`Stop following ${r.name}`:l?`Follow ${r.name}`:`Follow ${r.name} \u2014 ${d}`;a.title=c,a.setAttribute("aria-label",c),a.addEventListener("click",()=>this.toggleFollowUser(r.clientId))}n.appendChild(a)}),e.length>5){let r=document.createElement("div");r.className="user-avatar",r.style.backgroundColor="var(--color-surface-dynamic)",r.style.color="var(--color-text-muted)";let a=document.createElement("span");a.className="user-avatar-initial",a.textContent=`+${e.length-5}`,r.appendChild(a),n.appendChild(r)}},toggleFollowUser(n){if(!n)return;if(this.followedUserClientId===n){this.stopFollowingUser();return}let e=this.globalUsers.find(t=>t.clientId===n&&!t.isLocal);if(e){if(this.followedUserClientId=n,this.followedCursorSignature="",this.renderAvatars(),e.currentFile&&e.currentFile!==this.currentFilePath){this.navigation.navigateToFile(e.currentFile);return}requestAnimationFrame(()=>{this.followedUserClientId===n&&this.followUserCursor(e,{force:!0})})}},stopFollowingUser(){this.followedUserClientId&&(this.currentFilePath&&this.isExcalidrawFile?.(this.currentFilePath)&&this.excalidrawEmbed?.setFollowedUser(this.currentFilePath,null),this.followedUserClientId=null,this.followedCursorSignature="",this.renderAvatars())},syncFollowedUser(){if(!this.followedUserClientId)return;let n=this.globalUsers.find(e=>e.clientId===this.followedUserClientId);if(!n||n.isLocal){this.stopFollowingUser();return}if(n.currentFile&&n.currentFile!==this.currentFilePath){this.navigation.navigateToFile(n.currentFile);return}this.followUserCursor(n)},followUserCursor(n,{force:e=!1}={}){if(this.currentFilePath&&this.isExcalidrawFile?.(this.currentFilePath)){this.followExcalidrawUser(n,{force:e});return}let t=this.resolveFileClientId(n.peerId),i=t!=null?this.session?.getUserViewport(t):null,s=t!=null?this.session?.getUserCursor(t):null,r=s?.cursorHead??null,a=s?.cursorLine??null,o=s?.cursorAnchor??null,l=i?.topLine??null,d=i?.viewportRatio??.35;if(!n||l==null&&(r==null||a==null)){this.followedCursorSignature="";return}let c=`${n.clientId}:${l??"no-viewport"}:${o??"no-anchor"}:${r??"no-head"}`;if(!e&&c===this.followedCursorSignature)return;(t!=null&&this.session?.scrollToUserViewport(t)||t!=null&&this.session?.scrollToUserCursor(t,"center")||r!=null&&this.session?.scrollToPosition(r,"center")||a!=null&&this.session?.scrollToLine(a,d))&&(this.followedCursorSignature=c)},followExcalidrawUser(n,{force:e=!1}={}){if(!n?.peerId||!this.currentFilePath){this.followedCursorSignature="";return}let t=`excalidraw:${this.currentFilePath}:${n.peerId}`;!e&&t===this.followedCursorSignature||Promise.resolve(this.excalidrawEmbed?.setFollowedUser(this.currentFilePath,n.peerId)).then(i=>{i===!1||this.followedUserClientId!==n.clientId||(this.followedCursorSignature=t)}).catch(()=>{})},resolveFileClientId(n){if(!n||!this.session?.awareness)return null;for(let[e,t]of this.session.awareness.getStates())if(t.user?.peerId===n)return e;return null}};var ei={initialize(){this.themeController.initialize(),this.previewRenderer.applyTheme(this.themeController.getTheme()),this.previewRenderer.scheduleWorkerPrewarm(),this.scheduleEditorSessionPrewarm?.(),this.outlineController.initialize(),this.layoutController.initialize(),this.scrollSyncController.initialize(),this.fileExplorer.initialize(),this.gitPanel.initialize(),this.gitDiffView.initialize(),this.initializePreviewLayoutObserver(),this.syncCurrentUserName(),this.syncWrapToggle(),this.syncChatNotificationButton(),this.renderChat(),this.gitPanel.refresh({force:!0}),this.elements.chatInput?.setAttribute("maxlength",String(this.lobbyChatMessageMaxLength)),this.bindEvents(),this.restoreSidebarState(),this.tabActivityLock.initialize(),this.tabActivityLock.tryActivate(),window.addEventListener("hashchange",()=>this.handleHashChange()),window.addEventListener("resize",this.createResizeHandler()),this.fileExplorerReadyPromise=this.fileExplorer.refresh().then(()=>{if(this.fileExplorerReady=!0,this.isTabActive)return this.handleHashChange()})},bindEvents(){this.elements.emptyStateNewFileBtn?.addEventListener("click",()=>{this.fileExplorer.actionController.handleNewFile()}),this.elements.emptyStateSearchBtn?.addEventListener("click",()=>{this.toggleQuickSwitcher()}),this.elements.chatToggleButton?.addEventListener("click",()=>{this.toggleChatPanel()}),this.elements.chatForm?.addEventListener("submit",n=>{n.preventDefault(),this.handleChatSubmit()}),this.elements.chatNotificationButton?.addEventListener("click",()=>{this.handleChatNotificationToggle()}),this.elements.shareButton?.addEventListener("click",()=>{this.copyCurrentLink()}),this.elements.editNameButton?.addEventListener("click",()=>{this.openDisplayNameDialog()}),this.elements.displayNameCancel?.addEventListener("click",()=>{this.elements.displayNameDialog?.close()}),this.elements.gitCommitCancel?.addEventListener("click",()=>{this.elements.gitCommitDialog?.close()}),this.elements.gitResetCancel?.addEventListener("click",()=>{this.elements.gitResetDialog?.close()}),this.elements.gitResetSubmit?.addEventListener("click",()=>{this.handleGitResetSubmit()}),this.elements.gitCommitDialog?.addEventListener("close",()=>{this.elements.gitCommitInput&&(this.elements.gitCommitInput.value=""),this.elements.gitCommitSubmit&&(this.elements.gitCommitSubmit.textContent="Commit staged changes")}),this.elements.gitResetDialog?.addEventListener("close",()=>{this.pendingGitResetPath=null,this.elements.gitResetFileName&&(this.elements.gitResetFileName.value=""),this.elements.gitResetSubmit&&(this.elements.gitResetSubmit.textContent="Reset File")}),this.elements.markdownToolbar?.addEventListener("click",n=>{let t=(n.target instanceof Element?n.target.closest("[data-markdown-action]"):null)?.getAttribute("data-markdown-action");t&&this.applyMarkdownToolbarAction(t)}),this.elements.displayNameForm?.addEventListener("submit",n=>{n.preventDefault(),this.handleDisplayNameSubmit()}),this.elements.gitCommitForm?.addEventListener("submit",n=>{n.preventDefault(),this.handleGitCommitSubmit()}),this.elements.tabLockTakeoverButton?.addEventListener("click",()=>{this.handleTabTakeover()}),this.elements.toggleWrapButton?.addEventListener("click",()=>{this.toggleLineWrapping()}),this.elements.previewContent?.addEventListener("click",n=>{let e=n.target.closest("a.wiki-link[data-wiki-target]");e&&(n.preventDefault(),this.handleWikiLinkClick(e.dataset.wikiTarget))}),this.elements.sidebarToggle?.addEventListener("click",()=>{this.toggleSidebar()}),this.elements.sidebarClose?.addEventListener("click",()=>{this.closeSidebarOnMobile()}),this.elements.filesSidebarTab?.addEventListener("click",()=>{this.setSidebarTab("files")}),this.elements.gitSidebarTab?.addEventListener("click",()=>{this.gitRepoAvailable&&this.setSidebarTab("git")}),document.addEventListener("pointerdown",n=>{this.chatIsOpen&&(this.elements.chatContainer?.contains(n.target)||this.closeChatPanel())}),document.addEventListener("keydown",n=>{if(n.key==="Escape"&&this.chatIsOpen){this.closeChatPanel();return}(n.metaKey||n.ctrlKey)&&n.key==="k"&&(n.preventDefault(),this.toggleQuickSwitcher())})},isMobileViewport(){return this.mobileBreakpointQuery.matches},closeSidebarOnMobile(){let n=this.elements.sidebar;!n||!this.isMobileViewport()||n.classList.contains("collapsed")||this.setSidebarVisibility(!1)},toggleSidebar(){let n=this.elements.sidebar;if(!n)return;let e=n.classList.contains("collapsed");this.setSidebarVisibility(e)},restoreSidebarState(){if(!this.elements.sidebar)return;let e=this.isMobileViewport(),t=this.preferences.getSidebarVisible(),i=!0;t==="true"?i=!0:(t==="false"||e)&&(i=!1),this.applySidebarVisibility(i)},setSidebarVisibility(n){this.applySidebarVisibility(n),this.preferences.setSidebarVisible(n)},applySidebarVisibility(n){let e=this.elements.sidebar;if(!e)return;let t=!n,i=t&&this.isMobileViewport();e.classList.toggle("collapsed",t),e.toggleAttribute("hidden",i),e.setAttribute("aria-hidden",i?"true":"false"),e.inert=t},setSidebarTab(n){let e=n==="git"&&this.gitRepoAvailable?"git":"files";this.activeSidebarTab=e,this.elements.filesSidebarTab?.classList.toggle("active",e==="files"),this.elements.gitSidebarTab?.classList.toggle("active",e==="git"),document.getElementById("fileTree")?.classList.toggle("hidden",e!=="files"),this.elements.fileSearch?.classList.toggle("hidden",e!=="files"),this.elements.gitSearch?.classList.toggle("hidden",e!=="git"),document.getElementById("gitPanel")?.classList.toggle("active",e==="git"),document.getElementById("gitPanel")?.classList.toggle("hidden",e!=="git"),this.gitPanel.setActive(e==="git")},applyMarkdownToolbarAction(n){if(!this.session||!Y(this.currentFilePath))return;this.session.applyMarkdownToolbarAction(n)||this.toastController.show("Formatting action is unavailable")},handleThemeChange(n){this.previewRenderer.applyTheme(n),this.isExcalidrawFile(this.currentFilePath)||this.previewRenderer.queueRender(),this.session?.applyTheme(n),this.excalidrawEmbed.updateTheme(n)},handleConnectionChange(n){this.connectionState=n,this.renderPresence(),n.unreachable&&!this.connectionHelpShown&&(this.connectionHelpShown=!0,this.toastController.show(`Cannot reach server at ${n.wsBaseUrl}`,6e3))},openDisplayNameDialog({mode:n="edit"}={}){if(!this.isTabActive)return;let e=this.elements.displayNameDialog,t=this.elements.displayNameInput,i=this.elements.displayNameTitle,s=this.elements.displayNameCopy,r=this.elements.displayNameCancel,a=this.elements.displayNameSubmit;if(!e||!t)return;let o=n==="onboarding";i&&(i.textContent=o?"Choose your display name":"Update display name"),s&&(s.textContent=o?"Pick a name collaborators will see. You can skip for now and continue as a guest.":"Your name will be visible to everyone editing this vault."),r&&(r.textContent=o?"Skip for now":"Cancel"),a&&(a.textContent=o?"Continue":"Save name"),t.value=o?"":this.getCurrentUserName(),!e.open&&(typeof e.showModal=="function"?e.showModal():e.setAttribute("open","true"),requestAnimationFrame(()=>{t.focus(),t.select()}))},promptForDisplayNameIfNeeded(){!this.isTabActive||this._hasPromptedForDisplayName||this.getStoredUserName()||(this._hasPromptedForDisplayName=!0,requestAnimationFrame(()=>{this.openDisplayNameDialog({mode:"onboarding"})}))},handleDisplayNameSubmit(){let n=this.elements.displayNameInput,e=this.elements.displayNameDialog;if(!n||!e)return;let t=this.session?this.session.setUserName(n.value):Tt(n.value);if(!t){n.focus(),this.toastController.show(`Name must be 1-${24} characters`);return}this.preferences.setUserName(t),this.lobby.setUserName(t),this.excalidrawEmbed.updateLocalUser(this.lobby.getLocalUser()),this.syncCurrentUserName(),this.renderChat(),e.close()},async copyCurrentLink(){try{await navigator.clipboard.writeText(window.location.href),this.toastController.show("Link copied")}catch{this.toastController.show("Failed to copy link")}},getCurrentUser(){return this.globalUsers.find(n=>n.isLocal)??this.session?.getLocalUser()??this.lobby?.getLocalUser()??null},getCurrentUserName(){return this.getCurrentUser()?.name??this.getStoredUserName()??""},getStoredUserName(){return this.preferences.getUserName()},syncCurrentUserName(){let n=this.elements.currentUserName;if(!n)return;let e=this.getCurrentUserName();n.textContent=e||"Set name",n.classList.toggle("has-name",!!e),this.elements.editNameButton?.setAttribute("aria-label",`${e||"Set name"}. Change display name`)},toggleLineWrapping(){let e=!(this.session?.isLineWrappingEnabled()??this.getStoredLineWrapping());this.session?.setLineWrapping(e),this.preferences.setLineWrappingEnabled(e),this.syncWrapToggle(e),this.session?.requestMeasure(),this.scrollSyncController.syncPreviewToEditor()},getStoredLineWrapping(){return this.preferences.getLineWrappingEnabled()},handleTabTakeover(){this.tabActivityLock.tryActivate({takeover:!0})},handleTabActivated({takeover:n=!1}={}){let e=!this.isTabActive;this.isTabActive=!0,this.hideTabLockOverlay(),this.lobby.provider||this.lobby.connect(),e&&(this.fileExplorerReady&&this.handleHashChange(),this.promptForDisplayNameIfNeeded()),n&&this.toastController.show("This tab is now active")},handleTabBlocked({reason:n}={}){let e=this.isTabActive;this.isTabActive=!1,this.elements.displayNameDialog?.open&&this.elements.displayNameDialog.close(),this.lobby.disconnect(),this.globalUsers=[],this.chatMessages=[],this.chatMessageIds.clear(),this.chatUnreadCount=0,this.chatInitialSyncComplete=!1,this.followedUserClientId=null,this.followedCursorSignature="",this.connectionState={status:"disconnected",unreachable:!1},this.showEmptyState(),this.renderChat(),this.showTabLockOverlay({reason:n}),e&&n==="taken-over"&&this.toastController.show("Another tab took over this session")},showTabLockOverlay({reason:n}={}){let e=this.elements.tabLockOverlay,t=this.elements.tabLockTitle,i=this.elements.tabLockCopy;e&&(t&&(t.textContent=n==="taken-over"?"This tab is no longer active":"This vault is active in another tab"),i&&(i.textContent=n==="taken-over"?"Another tab took over the live session. This tab is now disconnected until you explicitly take over here again.":"To avoid duplicate presence and chat, only one tab can stay connected at a time. Use the other tab, or take over the session here."),e.classList.remove("hidden"))},hideTabLockOverlay(){this.elements.tabLockOverlay?.classList.add("hidden")},syncWrapToggle(n){let e=n??this.session?.isLineWrappingEnabled()??this.getStoredLineWrapping(),t=this.elements.wrapToggleLabel,i=this.elements.toggleWrapButton,s=e?"Wrap on":"Wrap off";t&&(t.textContent=s),i&&i.setAttribute("aria-label",`${s}. ${e?"Disable line wrap":"Enable line wrap"}`)},scheduleBacklinkRefresh(){clearTimeout(this._backlinkRefreshTimer),this._backlinkRefreshTimer=setTimeout(()=>{we(this.currentFilePath)&&this.backlinksPanel.load(this.currentFilePath)},2e3)},showEditorLoading(){this.elements.editorContainer&&(this.elements.editorContainer.classList.add("is-loading-editor"),this.elements.editorContainer.innerHTML=`
|
|
30
|
+
<div class="editor-loading" id="editorLoading">
|
|
31
|
+
<div class="loading-spinner"></div>
|
|
32
|
+
<span class="loading-text">Loading file...</span>
|
|
33
|
+
</div>`)},hideEditorLoading(){this.elements.editorContainer&&(this.elements.editorContainer.classList.remove("is-loading-editor"),this.elements.editorContainer.querySelector("#editorLoading")?.remove())},showEditorLoadError(){this.elements.editorContainer&&(this.elements.editorContainer.classList.remove("is-loading-editor"),this.elements.editorContainer.innerHTML=`
|
|
34
|
+
<div class="editor-loading" id="editorLoading">
|
|
35
|
+
<span class="loading-text">Failed to load file</span>
|
|
36
|
+
</div>`)},clearInitialFileBootstrap(){document.documentElement.removeAttribute("data-initial-file-requested")}};var ti={isExcalidrawFile(n){return kt(n)},isMermaidFile(n){return fe(n)},isPlantUmlFile(n){return ge(n)},createDiagramPreviewDocument(n,e=""){return this.workspacePreviewController.createDiagramPreviewDocument(n,e)},getPreviewSource(){return this.workspacePreviewController.getPreviewSource(this.currentFilePath)},getDisplayName(n){return q(String(n??"").split("/").pop())},resetPreviewMode(){this.workspacePreviewController.resetPreviewMode()},syncFileChrome(n){this.workspacePreviewController.syncFileChrome(n)},renderExcalidrawFilePreview(n){this.workspacePreviewController.renderExcalidrawFilePreview(n)},createResizeHandler(){return this.workspacePreviewController.createResizeHandler(()=>this.restoreSidebarState())},initializePreviewLayoutObserver(){this._previewLayoutResizeObserver?.disconnect(),this._previewLayoutResizeObserver=this.workspacePreviewController.initializePreviewLayoutObserver(()=>this.schedulePreviewLayoutSync())},schedulePreviewLayoutSync({delayMs:n=120}={}){this.workspacePreviewController.schedulePreviewLayoutSync({delayMs:n,hydrationPaused:this._previewHydrationPaused,previewLayoutSyncTimer:this._previewLayoutSyncTimer,setPendingPreviewLayoutSync:e=>{this._pendingPreviewLayoutSync=e},setPreviewLayoutSyncTimer:e=>{this._previewLayoutSyncTimer=e}})},handleEditorScrollActivityChange(n){this.workspacePreviewController.handleEditorScrollActivityChange({isActive:n,pendingPreviewLayoutSync:this._pendingPreviewLayoutSync,previewLayoutSyncTimer:this._previewLayoutSyncTimer,setHydrationPaused:e=>{this._previewHydrationPaused=e},setPendingPreviewLayoutSync:e=>{this._pendingPreviewLayoutSync=e},setPreviewLayoutSyncTimer:e=>{this._previewLayoutSyncTimer=e}})},async handleHashChange(){await this.workspaceRouteController.handleHashChange()},showEmptyState(){clearTimeout(this._previewLayoutSyncTimer),this._previewLayoutSyncTimer=null,this._pendingPreviewLayoutSync=!1,this._previewHydrationPaused=!1,this.workspaceRouteController.showEmptyState()},showDiffState(){clearTimeout(this._previewLayoutSyncTimer),this._previewLayoutSyncTimer=null,this._pendingPreviewLayoutSync=!1,this._previewHydrationPaused=!1,this.workspaceRouteController.showDiffState()},async openFile(n){await this.workspaceRouteController.openFile(n)},cleanupSession(){this.workspaceRouteController.cleanupSession()},handleWikiLinkClick(n){this.wikiLinkFileController.handleWikiLinkClick(n)},normalizeNewWikiFilePath(n){return this.wikiLinkFileController.normalizeNewWikiFilePath(n)},async createAndOpenFile(n,e){await this.wikiLinkFileController.createAndOpenFile(n,e)},handleFileSelection(n,{closeSidebarOnMobile:e=!1}={}){this.workspaceRouteController.handleFileSelection(n,{closeSidebarOnMobile:e})}};var Ri="__lobby__",mt=280,ii=40;function Bi(n){return String(n??"").replace(/\s+/g," ").trim().slice(0,mt)||null}function ni(n){return globalThis.crypto?.randomUUID?globalThis.crypto.randomUUID():`${n||"user"}-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function ut(n){if(!n||typeof n!="object"||typeof n.id!="string")return null;let e=n.workspaceChange&&typeof n.workspaceChange=="object"?n.workspaceChange:{};return{action:typeof n.action=="string"?n.action:"git",createdAt:Number.isFinite(n.createdAt)?n.createdAt:Date.now(),id:n.id,peerId:typeof n.peerId=="string"?n.peerId:null,sourceRef:typeof n.sourceRef=="string"?n.sourceRef:null,workspaceChange:{changedPaths:Array.isArray(e.changedPaths)?e.changedPaths.filter(Boolean):[],deletedPaths:Array.isArray(e.deletedPaths)?e.deletedPaths.filter(Boolean):[],refreshExplorer:e.refreshExplorer!==!1,renamedPaths:Array.isArray(e.renamedPaths)?e.renamedPaths.filter(t=>t?.oldPath&&t?.newPath):[]}}}var Re=class{constructor({preferredUserName:e,onChange:t,onChatChange:i,onWorkspaceEvent:s}){this.onChange=t,this.onChatChange=i,this.onWorkspaceEvent=s,this.wsBaseUrl=Ct(),this.ydoc=new At,this.chatMessages=this.ydoc.getArray("chat-messages"),this.workspaceEvents=this.ydoc.getArray("workspace-events"),this.provider=null,this.awareness=null,this.localUser=Pt(e),this.currentFile=null,this._connected=!1,this._didInitialSync=!1,this.seenWorkspaceEventIds=new Set,this.handleAwarenessChange=()=>{this._emitChange()},this.handleChatMessagesChange=()=>{this._emitChatChange()},this.handleWorkspaceEventsChange=()=>{this._emitWorkspaceEvents()}}connect(){this.provider||(this._didInitialSync=!1,this.provider=new Mt(this.wsBaseUrl,Ri,this.ydoc,{disableBc:!0,maxBackoffTime:5e3}),Ht(this.provider),this.awareness=this.provider.awareness,this.awareness.setLocalStateField("user",this.localUser),this.awareness.setLocalStateField("currentFile",this.currentFile),this.awareness.on("change",this.handleAwarenessChange),this.chatMessages.observe(this.handleChatMessagesChange),this.workspaceEvents.observe(this.handleWorkspaceEventsChange),this.provider.on("status",({status:e})=>{this._connected=e==="connected"}),this.provider.on("sync",e=>{!e||this._didInitialSync||(this._didInitialSync=!0,this._primeWorkspaceEventCache(),this._emitChange(),this._emitChatChange({initial:!0}))}))}setCurrentFile(e){this.currentFile=e,this.awareness&&this.awareness.setLocalStateField("currentFile",e)}setUserName(e){e&&(this.localUser={...this.localUser,name:e},this.awareness&&this.awareness.setLocalStateField("user",this.localUser))}getLocalUser(){return this.localUser}sendChatMessage(e){let t=Bi(e);if(!t)return null;let i={createdAt:Date.now(),filePath:this.currentFile??null,id:ni(this.localUser.peerId),peerId:this.localUser.peerId,text:t,userColor:this.localUser.color,userName:this.localUser.name};return this.ydoc.transact(()=>{this.chatMessages.push([i]);let s=this.chatMessages.length-ii;s>0&&this.chatMessages.delete(0,s)},"lobby-chat-message"),i}sendWorkspaceEvent({action:e="git",sourceRef:t=null,workspaceChange:i={}}={}){let s=ut({action:e,createdAt:Date.now(),id:ni(this.localUser.peerId),peerId:this.localUser.peerId,sourceRef:t,workspaceChange:i});return s?(this.ydoc.transact(()=>{this.workspaceEvents.push([s]);let r=this.workspaceEvents.length-ii;r>0&&this.workspaceEvents.delete(0,r)},"lobby-workspace-event"),this.seenWorkspaceEventIds.add(s.id),s):null}getMessages(){return this.chatMessages.toArray().filter(e=>e&&typeof e.id=="string"&&typeof e.peerId=="string"&&typeof e.text=="string"&&typeof e.userName=="string")}getUsers(){if(!this.awareness)return[];let e=[];return this.awareness.getStates().forEach((t,i)=>{t.user&&e.push({...t.user,clientId:i,currentFile:t.currentFile??null,isLocal:i===this.awareness.clientID})}),e}getConnectionState(){return this._connected?{status:"connected",unreachable:!1}:this.provider?{status:"connecting",unreachable:!1}:{status:"disconnected",unreachable:!1}}disconnect(){this.provider&&(this.awareness?.off("change",this.handleAwarenessChange),this.chatMessages?.unobserve(this.handleChatMessagesChange),this.workspaceEvents?.unobserve(this.handleWorkspaceEventsChange)),this.provider?.disconnect(),this.provider?.destroy(),this.provider=null,this.awareness=null,this._connected=!1,this._didInitialSync=!1,this.seenWorkspaceEventIds.clear()}destroy(){this.disconnect(),this.ydoc?.destroy(),this.ydoc=null}_emitChange(){this.onChange?.(this.getUsers())}_emitChatChange(e={}){this.onChatChange?.(this.getMessages(),e)}_primeWorkspaceEventCache(){this.workspaceEvents.toArray().forEach(e=>{let t=ut(e);t&&this.seenWorkspaceEventIds.add(t.id)})}_emitWorkspaceEvents(){if(!this._didInitialSync){this._primeWorkspaceEventCache();return}this.workspaceEvents.toArray().forEach(e=>{let t=ut(e);!t||this.seenWorkspaceEventIds.has(t.id)||(this.seenWorkspaceEventIds.add(t.id),t.peerId!==this.localUser.peerId&&this.onWorkspaceEvent?.(t))})}};var Be=class{getHashRoute(){return Rt()}navigateToFile(e){Bt(e)}navigateToGitDiff(e){Nt(e)}};var Ne=class{constructor({NotificationImpl:e=globalThis.Notification,focusWindow:t=()=>globalThis.window?.focus?.()}={}){this.NotificationImpl=e,this.focusWindow=t}getPermission(){return typeof this.NotificationImpl!="function"?"unsupported":this.NotificationImpl.permission}async requestPermission(){return typeof this.NotificationImpl!="function"?"unsupported":this.NotificationImpl.requestPermission()}createNotification({body:e,onClick:t,tag:i,title:s}){if(typeof this.NotificationImpl!="function")return null;let r=new this.NotificationImpl(s,{body:e,tag:i});return typeof t=="function"&&r.addEventListener("click",()=>{this.focusWindow(),t()}),r}};var He=class{constructor({chatNotificationsKey:e,lineWrappingKey:t,sidebarVisibleKey:i,userNameKey:s,storage:r=globalThis.localStorage}){this.chatNotificationsKey=e,this.lineWrappingKey=t,this.sidebarVisibleKey=i,this.storage=r,this.userNameKey=s}getUserName(){try{return this.storage.getItem(this.userNameKey)||""}catch{return""}}setUserName(e){try{this.storage.setItem(this.userNameKey,e)}catch{}}getLineWrappingEnabled(){try{return this.storage.getItem(this.lineWrappingKey)!=="false"}catch{return!0}}setLineWrappingEnabled(e){try{this.storage.setItem(this.lineWrappingKey,String(e))}catch{}}getSidebarVisible(){try{return this.storage.getItem(this.sidebarVisibleKey)}catch{return null}}setSidebarVisible(e){try{this.storage.setItem(this.sidebarVisibleKey,e?"true":"false")}catch{}}getChatNotificationsEnabled(){try{return this.storage.getItem(this.chatNotificationsKey)==="true"}catch{return!1}}setChatNotificationsEnabled(e){try{this.storage.setItem(this.chatNotificationsKey,String(e))}catch{}}};var De="collabmd-active-tab-lock",si="collabmd-tab-id",Ni="collabmd-tab-lock";function pt(){return Date.now()}function ri(){return globalThis.crypto?.randomUUID?globalThis.crypto.randomUUID():`tab-${pt()}-${Math.random().toString(36).slice(2,10)}`}function ai(n){if(!n)return null;try{return JSON.parse(n)}catch{return null}}var Ue=class{constructor({heartbeatIntervalMs:e=4e3,onBlocked:t,onActivated:i,onStolen:s}={}){this.heartbeatIntervalMs=e,this.staleAfterMs=e*3,this.onBlocked=t,this.onActivated=i,this.onStolen=s,this.tabId=this.getOrCreateTabId(),this.channel=null,this.heartbeatTimer=null,this.isOwner=!1,this.handleStorageEvent=this.handleStorageEvent.bind(this),this.handlePageHide=this.handlePageHide.bind(this)}initialize(){window.addEventListener("storage",this.handleStorageEvent),window.addEventListener("pagehide",this.handlePageHide),"BroadcastChannel"in globalThis&&(this.channel=new BroadcastChannel(Ni),this.channel.addEventListener("message",e=>{this.handleChannelMessage(e.data)}))}destroy(){this.release(),window.removeEventListener("storage",this.handleStorageEvent),window.removeEventListener("pagehide",this.handlePageHide),this.channel?.close(),this.channel=null}tryActivate({takeover:e=!1}={}){let t=this.readLock();return this.isFreshLock(t)&&t.tabId!==this.tabId&&!e?(this.isOwner=!1,this.stopHeartbeat(),this.onBlocked?.({reason:"active-elsewhere",ownerTabId:t.tabId}),!1):(this.writeLock(),this.startHeartbeat(),this.isOwner=!0,this.channel?.postMessage({type:"claimed",takeover:e,tabId:this.tabId}),this.onActivated?.({takeover:e}),!0)}release(){this.readLock()?.tabId===this.tabId&&(localStorage.removeItem(De),this.channel?.postMessage({type:"released",tabId:this.tabId})),this.isOwner=!1,this.stopHeartbeat()}getOrCreateTabId(){try{let e=window.sessionStorage.getItem(si);if(e)return e;let t=ri();return window.sessionStorage.setItem(si,t),t}catch{return ri()}}readLock(){try{return ai(window.localStorage.getItem(De))}catch{return null}}isFreshLock(e){return!!(e&&typeof e.tabId=="string"&&Number.isFinite(e.updatedAt)&&pt()-e.updatedAt<this.staleAfterMs)}writeLock(){try{window.localStorage.setItem(De,JSON.stringify({tabId:this.tabId,updatedAt:pt()}))}catch{}}startHeartbeat(){this.stopHeartbeat(),this.writeLock(),this.heartbeatTimer=window.setInterval(()=>{if(!this.isOwner){this.stopHeartbeat();return}this.writeLock()},this.heartbeatIntervalMs)}stopHeartbeat(){this.heartbeatTimer&&(window.clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}handleStorageEvent(e){if(e.key!==De)return;let t=ai(e.newValue);this.handleExternalLockChange(t)}handleChannelMessage(e){!e||typeof e!="object"||e.tabId===this.tabId||e.type==="claimed"&&this.handleExternalLockChange(this.readLock())}handleExternalLockChange(e){this.isOwner&&this.isFreshLock(e)&&e.tabId!==this.tabId&&(this.isOwner=!1,this.stopHeartbeat(),this.onStolen?.({ownerTabId:e.tabId}))}handlePageHide(){this.release()}};async function ne(n,e){let t=await n.json().catch(()=>({}));if(!n.ok||t.ok===!1){let i=new Error(t.error||e);throw i.status=n.status,i.body=t,i}return t}var _e=class{async readTree(){let e=await fetch(b("/files"));return ne(e,"Failed to load file tree")}async readFile(e){let t=await fetch(b(`/file?path=${encodeURIComponent(e)}`));return ne(t,"Failed to read file")}async createFile({content:e,path:t}){let i=await fetch(b("/file"),{body:JSON.stringify({content:e,path:t}),headers:{"Content-Type":"application/json"},method:"POST"});return ne(i,"Failed to create file")}async renameFile({oldPath:e,newPath:t}){let i=await fetch(b("/file"),{body:JSON.stringify({newPath:t,oldPath:e}),headers:{"Content-Type":"application/json"},method:"PATCH"});return ne(i,"Failed to rename file")}async deleteFile(e){let t=await fetch(b(`/file?path=${encodeURIComponent(e)}`),{method:"DELETE"});return ne(t,"Failed to delete file")}async createDirectory(e){let t=await fetch(b("/directory"),{body:JSON.stringify({path:e}),headers:{"Content-Type":"application/json"},method:"POST"});return ne(t,"Failed to create folder")}},de=new _e;var ze=class{constructor({panelElement:e,onFileSelect:t}){this.panel=e,this.onFileSelect=t,this.header=this.panel?.querySelector(".backlinks-header"),this.toggle=this.panel?.querySelector(".backlinks-toggle"),this.countBadge=this.panel?.querySelector(".backlinks-count"),this.body=this.panel?.querySelector(".backlinks-body"),this.list=this.panel?.querySelector(".backlinks-list"),this._expanded=!1,this._currentFile=null,this._fetchController=null,this._backlinks=[],this.bindEvents()}bindEvents(){this.header?.addEventListener("click",()=>{this._backlinks.length!==0&&(this._expanded=!this._expanded,this._applyExpandState())}),this.header?.addEventListener("keydown",e=>{e.key!=="Enter"&&e.key!==" "||(e.preventDefault(),this.header.click())})}async load(e){if(this._currentFile=e,!e){this._backlinks=[],this._render();return}this._fetchController?.abort(),this._fetchController=new AbortController;try{let i=await(await fetch(b(`/backlinks?file=${encodeURIComponent(e)}`),{signal:this._fetchController.signal})).json();if(this._currentFile!==e)return;this._backlinks=i.backlinks??[]}catch(t){if(t.name==="AbortError")return;console.warn("[backlinks] Failed to load:",t.message),this._backlinks=[]}this._render()}clear(){this._currentFile=null,this._backlinks=[],this._expanded=!1,this._render()}_render(){if(!this.panel)return;let e=this._backlinks.length,t=e===1?"1 Linked Mention":`${e} Linked Mentions`;if(this.countBadge&&(this.countBadge.textContent=e>0?String(e):""),this.toggle&&(this.toggle.textContent=t),this.panel.classList.toggle("hidden",!this._currentFile),this.header?.classList.toggle("backlinks-header-empty",e===0),e===0){this._expanded=!1,this._applyExpandState(),this.list&&(this.list.innerHTML="");return}this._renderList(),this._applyExpandState()}_renderList(){if(!this.list)return;this.list.innerHTML="";let e=document.createDocumentFragment();for(let t of this._backlinks){let i=t.file.replace(/\.md$/i,"").split("/").pop(),s=t.file.includes("/")?t.file.substring(0,t.file.lastIndexOf("/")):"",r=document.createElement("button");r.type="button",r.className="backlink-item",r.addEventListener("click",()=>{this.onFileSelect?.(t.file)});let a=document.createElement("div");a.className="backlink-file-name",a.innerHTML=`
|
|
37
|
+
<svg class="backlink-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
38
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
39
|
+
<polyline points="14 2 14 8 20 8"/>
|
|
40
|
+
</svg>
|
|
41
|
+
<span>${m(i)}</span>
|
|
42
|
+
${s?`<span class="backlink-dir">${m(s)}</span>`:""}
|
|
43
|
+
`,r.appendChild(a);for(let o of t.contexts.slice(0,3)){let l=document.createElement("div");l.className="backlink-context",l.textContent=o,r.appendChild(l)}if(t.contexts.length>3){let o=document.createElement("div");o.className="backlink-context backlink-more",o.textContent=`+${t.contexts.length-3} more`,r.appendChild(o)}e.appendChild(r)}this.list.appendChild(e)}_applyExpandState(){this.panel?.classList.toggle("expanded",this._expanded),this.header?.setAttribute("aria-expanded",String(this._expanded)),this.header?.setAttribute("aria-disabled",String(this._backlinks.length===0)),this.body?.setAttribute("aria-hidden",String(!this._expanded)),this.body&&this.body.toggleAttribute("inert",!this._expanded)}};var oi=14,li=360,Hi=150,Di=12,$e=36;function se(n,e,t){return Math.min(Math.max(n,e),t)}function Ui(n=[]){return[...n].sort((e,t)=>(e.anchor?.startLine??0)-(t.anchor?.startLine??0)||e.createdAt-t.createdAt)}function gt(n){return n?.anchorKind||n?.kind||"line"}function ft(n){return gt(n)==="text"&&Number.isFinite(n?.startIndex)&&Number.isFinite(n?.endIndex)&&n.endIndex>n.startIndex}function ci(n,e){return n===e?!0:!n||!e?!1:gt(n)===gt(e)&&(n.startIndex??null)===(e.startIndex??null)&&(n.endIndex??null)===(e.endIndex??null)&&(n.startLine??null)===(e.startLine??null)&&(n.endLine??null)===(e.endLine??null)&&(n.anchorQuote??n.quote??"")===(e.anchorQuote??e.quote??"")}function di(n){return n?(n.kind||n.anchorKind)==="text"&&n.quote?n.startLine===n.endLine?`Line ${n.startLine}`:`Lines ${n.startLine}-${n.endLine}`:n.startLine===n.endLine?`Line ${n.startLine}`:`Lines ${n.startLine}-${n.endLine}`:"No source anchor"}function _i(n={}){return[n.kind||n.anchorKind||"line",n.startLine??0,n.endLine??0,n.quote||""].join("::")}function zi(n){return n&&!n.querySelector("[data-source-line]")}function hi(n){let e=Number.parseInt(n||"",10);return Number.isFinite(e)?e:null}function ui(n,e){let t=hi(n?.getAttribute?.("data-source-line")),i=hi(n?.getAttribute?.("data-source-line-end"))??t;return!t||!i||!e?!1:e.startLine<=i&&e.endLine>=t}function $i(n){let e=document.createTreeWalker(n,NodeFilter.SHOW_TEXT),t="",i=[],s=!0;for(;e.nextNode();){let r=e.currentNode,a=r.textContent||"";for(let o=0;o<a.length;o+=1){let l=a[o];if(/\s/.test(l)){if(s)continue;t+=" ",i.push({node:r,offset:o}),s=!0;continue}t+=l,i.push({node:r,offset:o}),s=!1}}for(;t.endsWith(" ");)t=t.slice(0,-1),i.pop();return{map:i,normalized:t}}function Oi(n,e){let t=Dt(e);if(!n||!t)return null;let i=$i(n);if(!i.normalized)return null;let s=i.normalized.indexOf(t);if(s<0||i.normalized.indexOf(t,s+1)>=0)return null;let r=i.map[s],a=i.map[s+t.length-1];if(!r||!a)return null;let o=document.createRange();return o.setStart(r.node,r.offset),o.setEnd(a.node,a.offset+1),o}function mi(n,e){return{bottom:n.bottom-e.top,height:n.height,left:n.left-e.left,right:n.right-e.left,top:n.top-e.top,width:n.width}}function qi(n=[]){if(!Array.isArray(n)||n.length===0)return null;let e=Math.min(...n.map(r=>r.left)),t=Math.min(...n.map(r=>r.top)),i=Math.max(...n.map(r=>r.right)),s=Math.max(...n.map(r=>r.bottom));return{bottom:s,height:s-t,left:e,right:i,top:t,width:i-e}}function pi(n){let e=document.createDocumentFragment(),t=document.createElement("span");if(t.className="comment-marker-icon",t.setAttribute("aria-hidden","true"),t.innerHTML=`
|
|
44
|
+
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
45
|
+
<path d="M3 4.75A1.75 1.75 0 0 1 4.75 3h6.5A1.75 1.75 0 0 1 13 4.75v4.5A1.75 1.75 0 0 1 11.25 11H8.9L6.5 13v-2H4.75A1.75 1.75 0 0 1 3 9.25v-4.5Z" stroke="currentColor" stroke-width="1.35" stroke-linejoin="round"/>
|
|
46
|
+
</svg>
|
|
47
|
+
`,e.appendChild(t),n>1){let i=document.createElement("span");i.className="comment-marker-count",i.textContent=String(n),e.appendChild(i)}return e}var Oe=class{constructor({commentSelectionButton:e,commentsDrawer:t,commentsDrawerEmpty:i,commentsDrawerList:s,commentsToggleButton:r,editorContainer:a,onCreateThread:o,onNavigateToLine:l,onReplyToThread:d,onResolveThread:c,previewContainer:p,previewElement:f}){this.commentSelectionButton=e,this.commentsDrawer=t,this.commentsDrawerEmpty=i,this.commentsDrawerList=s,this.commentsToggleButton=r,this.editorContainer=a,this.onCreateThread=o,this.onNavigateToLine=l,this.onReplyToThread=d,this.onResolveThread=c,this.previewContainer=p,this.previewElement=f,this.currentFile=null,this.fileKind="markdown",this.supported=!1,this.drawerOpen=!1,this.threads=[],this.selectionAnchor=null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.selectionRevealTimer=0,this.pointerSelecting=!1,this.session=null,this.activeCard=null,this.editorLayer=null,this.previewLayer=null,this.previewHighlightLayer=null,this.cardRoot=null,this.pendingCardFocusElement=null,this.layoutFrame=0,this.timeFormatter=new Intl.DateTimeFormat(void 0,{day:"numeric",hour:"numeric",minute:"2-digit",month:"short"}),this.handleEditorScroll=()=>this.scheduleLayoutRefresh(),this.handlePreviewScroll=()=>this.scheduleLayoutRefresh(),this.handleWindowResize=()=>this.scheduleLayoutRefresh(),this.handleEditorPointerDown=h=>{h.button!==0||!this.supported||!this.session||!h.target?.closest?.(".cm-editor")||h.target?.closest?.(".comment-editor-layer")||(this.pointerSelecting=!0,this.clearSelectionRevealTimer(),this.committedSelectionAnchor&&(this.committedSelectionAnchor=null,this.scheduleLayoutRefresh()))},this.handleDocumentPointerUp=()=>{this.pointerSelecting&&requestAnimationFrame(()=>{let h=this.supported?this.session?.getCurrentSelectionCommentAnchor?.()??null:null;this.pointerSelecting=!1,this.selectionAnchor=h,this.renderToolbar(),this.pendingSelectionAnchor=ft(h)?h:null,this.clearSelectionRevealTimer(),this.committedSelectionAnchor=ft(h)&&this.activeCard?.mode!=="create"?h:null,this.scheduleLayoutRefresh()})},this.handleEditorFocusOut=h=>{let v=h.relatedTarget;v instanceof Node&&(this.editorContainer?.contains(v)||this.cardRoot?.contains(v)||this.commentSelectionButton?.contains(v))||(this.clearSelectionRevealTimer(),this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.scheduleLayoutRefresh())},this.handleDocumentPointerDown=h=>{!this.activeCard||!this.cardRoot||this.cardRoot.contains(h.target)||this.closeCard()},this.handleDocumentKeyDown=h=>{h.key==="Escape"&&this.activeCard&&this.closeCard(),h.key==="Escape"&&this.committedSelectionAnchor&&(this.clearSelectionRevealTimer(),this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.scheduleLayoutRefresh())},this.commentSelectionButton?.addEventListener("click",()=>{this.openComposerForSelection("toolbar")}),this.commentsToggleButton?.addEventListener("click",()=>{this.drawerOpen=!this.drawerOpen,this.render()}),this.previewContainer?.addEventListener("scroll",this.handlePreviewScroll,{passive:!0}),this.editorContainer?.addEventListener("pointerdown",this.handleEditorPointerDown),this.editorContainer?.addEventListener("focusout",this.handleEditorFocusOut),window.addEventListener("resize",this.handleWindowResize),document.addEventListener("pointerup",this.handleDocumentPointerUp),document.addEventListener("pointercancel",this.handleDocumentPointerUp),document.addEventListener("pointerdown",this.handleDocumentPointerDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}destroy(){this.layoutFrame&&(cancelAnimationFrame(this.layoutFrame),this.layoutFrame=0),this.attachSession(null),this.previewContainer?.removeEventListener("scroll",this.handlePreviewScroll),this.editorContainer?.removeEventListener("pointerdown",this.handleEditorPointerDown),this.editorContainer?.removeEventListener("focusout",this.handleEditorFocusOut),window.removeEventListener("resize",this.handleWindowResize),document.removeEventListener("pointerup",this.handleDocumentPointerUp),document.removeEventListener("pointercancel",this.handleDocumentPointerUp),document.removeEventListener("pointerdown",this.handleDocumentPointerDown),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.cardRoot?.remove(),this.editorLayer?.remove(),this.previewLayer?.remove(),this.pendingCardFocusElement=null}attachSession(e){this.session?.getScrollContainer?.()?.removeEventListener("scroll",this.handleEditorScroll),this.session=e,this.selectionAnchor=e?.getCurrentSelectionCommentAnchor?.()??null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.pointerSelecting=!1,e?.getScrollContainer?.()?.addEventListener("scroll",this.handleEditorScroll,{passive:!0}),this.render()}setCurrentFile(e,{fileKind:t="markdown",supported:i=!1}={}){let s=this.currentFile!==e;this.currentFile=e,this.fileKind=t,this.supported=!!(e&&i),s&&(this.drawerOpen=!1,this.threads=[],this.selectionAnchor=null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.pointerSelecting=!1,this.activeCard=null),this.supported||(this.drawerOpen=!1,this.activeCard=null,this.threads=[],this.selectionAnchor=null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.pointerSelecting=!1),this.render()}setSelectionAnchor(e){if(this.selectionAnchor=this.supported?e:null,!this.supported||!this.selectionAnchor){this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.renderToolbar(),this.scheduleLayoutRefresh();return}if(!ft(this.selectionAnchor)){this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.renderToolbar(),this.scheduleLayoutRefresh();return}if(this.pendingSelectionAnchor=this.selectionAnchor,this.activeCard?.mode==="create"){this.clearSelectionRevealTimer(),this.renderToolbar(),this.scheduleLayoutRefresh();return}if(this.pointerSelecting){this.clearSelectionRevealTimer(),this.committedSelectionAnchor=null,this.renderToolbar(),this.scheduleLayoutRefresh();return}if(ci(this.committedSelectionAnchor,this.selectionAnchor)){this.renderToolbar(),this.scheduleLayoutRefresh();return}this.scheduleSelectionReveal(this.selectionAnchor),this.renderToolbar(),this.scheduleLayoutRefresh()}handleEditorContentChange(){this.activeCard?.mode!=="create"&&(this.clearSelectionRevealTimer(),this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.scheduleLayoutRefresh())}setThreads(e=[]){this.threads=Ui(e),this.activeCard?.mode==="group"&&!this.getThreadGroups().some(t=>t.key===this.activeCard.groupKey)&&(this.activeCard=null),this.render()}refreshLayout(){this.renderEditorLayer(),this.renderPreviewLayer(),this.repositionActiveCard()}scheduleLayoutRefresh(){this.layoutFrame||(this.layoutFrame=requestAnimationFrame(()=>{this.layoutFrame=0,this.refreshLayout()}))}render(){this.renderToolbar(),this.renderDrawer(),this.renderCard(),this.scheduleLayoutRefresh()}renderToolbar(){let e=this.threads.length,t=this.supported&&!!this.session;if(this.commentSelectionButton?.classList.toggle("hidden",!t),this.commentsToggleButton?.classList.toggle("hidden",!this.supported),this.commentSelectionButton&&(this.commentSelectionButton.disabled=!this.selectionAnchor),this.commentsToggleButton){this.commentsToggleButton.classList.toggle("active",this.drawerOpen),this.commentsToggleButton.setAttribute("aria-expanded",String(this.drawerOpen));let i=e>0?`Comments ${e}`:"Comments",s=this.commentsToggleButton.querySelector(".pane-header-btn-label");s?s.textContent=i:this.commentsToggleButton.textContent=i}}renderDrawer(){if(!this.commentsDrawer||!this.commentsDrawerList)return;this.commentsDrawer.classList.toggle("hidden",!this.supported||!this.drawerOpen),this.commentsDrawerList.replaceChildren();let e=this.getThreadGroups();if(this.commentsDrawerEmpty?.classList.toggle("hidden",e.length>0),!this.supported||e.length===0)return;let t=document.createDocumentFragment();e.forEach(i=>{let s=document.createElement("button");s.type="button",s.className="comments-drawer-item",s.classList.toggle("is-active",this.activeCard?.groupKey===i.key),s.addEventListener("pointerdown",c=>{c.preventDefault()}),s.addEventListener("click",()=>{this.openThreadGroup(i,{anchor:i.anchor,origin:"drawer",sourceRect:s.getBoundingClientRect()})});let r=document.createElement("div");r.className="comments-drawer-item-header";let a=document.createElement("span");a.className="comments-drawer-item-title",a.textContent=di(i.anchor);let o=document.createElement("span");o.className="comments-drawer-item-count",o.textContent=String(i.threads.length),r.append(a,o);let l=document.createElement("p");l.className="comments-drawer-item-quote",l.textContent=i.anchor.quote||i.anchor.excerpt||"Source anchored comment";let d=document.createElement("div");d.className="comments-drawer-item-footer",d.textContent=`${i.threads.length} thread${i.threads.length===1?"":"s"}`,s.append(r,l,d),t.appendChild(s)}),this.commentsDrawerList.appendChild(t)}ensureEditorLayer(){if(this.editorLayer?.isConnected&&this.editorLayer.parentElement===this.editorContainer)return this.editorLayer;let e=document.createElement("div");return e.className="comment-editor-layer",this.editorContainer?.appendChild(e),this.editorLayer=e,e}renderEditorLayer(){let e=this.ensureEditorLayer();if(e.replaceChildren(),!this.supported||!this.session)return;let t=this.editorContainer?.getBoundingClientRect?.();if(!t)return;let i=this.getThreadGroups(),s=[];if(i.forEach(c=>{let p=this.session.getCommentAnchorClientRect?.(c.anchor);if(!p)return;let f=mi(p,t),h=document.createElement("button");h.type="button",h.className="comment-editor-badge",h.dataset.count=String(c.threads.length),h.classList.toggle("is-active",this.activeCard?.groupKey===c.key),h.setAttribute("aria-label",`${c.threads.length} comment thread${c.threads.length===1?"":"s"}`),h.appendChild(pi(c.threads.length));let v=Math.max(f.top,8);h.style.top=`${v}px`,h.style.left=`${Math.max(t.width-36,8)}px`,h.title=`${c.threads.length} comment${c.threads.length===1?"":"s"}`,h.addEventListener("pointerdown",y=>{y.preventDefault()}),h.addEventListener("click",()=>{this.openThreadGroup(c,{anchor:c.anchor,origin:"editor",sourceRect:p})}),e.appendChild(h),s.push(v)}),!this.committedSelectionAnchor||this.activeCard?.mode==="create")return;let r=this.session.getCommentAnchorClientRect?.(this.committedSelectionAnchor),a=this.session.getSelectionChipClientRect?.(this.committedSelectionAnchor)??r;if(!a)return;let o=mi(a,t);if(o.bottom<0||o.top>t.height)return;let l=se(o.top,8,Math.max(t.height-$e,8));for(;s.some(c=>Math.abs(c-l)<$e-4);)l=se(l+$e,8,Math.max(t.height-$e,8));let d=document.createElement("button");d.type="button",d.className="comment-selection-chip",d.textContent="Comment",d.style.top=`${l}px`,d.style.right=`${Di}px`,d.addEventListener("pointerdown",c=>{c.preventDefault(),c.stopPropagation(),this.openComposerForSelection("editor",d.getBoundingClientRect())}),e.appendChild(d)}ensurePreviewLayer(){if(this.previewLayer?.isConnected&&this.previewLayer.parentElement===this.previewElement)return this.previewLayer;let e=document.createElement("div");e.className="comment-preview-highlights";let t=document.createElement("div");return t.className="comment-preview-layer",this.previewElement?.append(e,t),this.previewHighlightLayer=e,this.previewLayer=t,t}renderPreviewLayer(){if(this.ensurePreviewLayer(),this.previewLayer?.replaceChildren(),this.previewHighlightLayer?.replaceChildren(),!this.supported||!this.previewElement)return;let e=this.previewElement.getBoundingClientRect();this.getThreadGroups().forEach(i=>{let s=this.resolvePreviewTarget(i.anchor);if(!s?.bubbleRect)return;s.highlightRects?.forEach(a=>{let o=document.createElement("div");o.className="comment-preview-highlight",o.style.left=`${a.left-e.left}px`,o.style.top=`${a.top-e.top}px`,o.style.width=`${a.width}px`,o.style.height=`${a.height}px`,this.previewHighlightLayer?.appendChild(o)});let r=document.createElement("button");r.type="button",r.className="comment-preview-badge",r.classList.toggle("is-active",this.activeCard?.groupKey===i.key),r.setAttribute("aria-label",`${i.threads.length} comment thread${i.threads.length===1?"":"s"}`),r.appendChild(pi(i.threads.length)),r.style.left=`${se(s.bubbleRect.right-e.left+6,6,this.previewElement.clientWidth-34)}px`,r.style.top=`${Math.max(s.bubbleRect.top-e.top,6)}px`,r.title=`${i.threads.length} comment${i.threads.length===1?"":"s"}`,r.addEventListener("pointerdown",a=>{a.preventDefault()}),r.addEventListener("click",()=>{this.openThreadGroup(i,{anchor:i.anchor,origin:"preview",sourceRect:s.bubbleRect})}),this.previewLayer?.appendChild(r)})}resolvePreviewTarget(e){if(!this.previewElement||!e)return null;let t=Array.from(this.previewElement.querySelectorAll(".mermaid-shell, .plantuml-shell")).find(r=>ui(r,e));if(t)return{bubbleRect:t.getBoundingClientRect(),highlightRects:[]};let i=Array.from(this.previewElement.querySelectorAll("[data-source-line]")).filter(r=>zi(r)&&ui(r,e));if(e.kind==="text"&&e.quote){let r=i.map(a=>({element:a,range:Oi(a,e.quote)})).filter(a=>a.range);if(r.length===1){let a=Array.from(r[0].range.getClientRects());return{bubbleRect:qi(a)||r[0].element.getBoundingClientRect(),highlightRects:a}}}let s=i[0];return s?{bubbleRect:s.getBoundingClientRect(),highlightRects:[]}:null}ensureCardRoot(){if(this.cardRoot?.isConnected&&this.cardRoot.parentElement===document.body)return this.cardRoot;let e=document.createElement("div");return e.className="comment-card-root hidden",document.body.appendChild(e),this.cardRoot=e,e}openComposerForSelection(e="editor",t=null){let i=this.session?.getCurrentSelectionCommentAnchor?.();if(!i)return;this.selectionAnchor=i;let s=e==="editor"&&t?"editor-chip":e,r=t??(e==="toolbar"?this.commentSelectionButton?.getBoundingClientRect?.():this.session?.getCommentAnchorClientRect?.(i));this.activeCard={anchor:i,mode:"create",origin:s,replyThreadId:null,sourceRect:r},this.render()}openThreadGroup(e,{anchor:t,origin:i,sourceRect:s}){this.activeCard={anchor:t,groupKey:e.key,mode:"group",origin:i,replyThreadId:null,sourceRect:s},this.renderDrawer(),this.renderCard()}closeCard(){this.activeCard=null,this.pendingCardFocusElement=null,this.renderCard(),this.scheduleLayoutRefresh()}getThreadGroups(){let e=new Map;return this.threads.forEach(t=>{let i=_i(t.anchor),s=e.get(i);if(s){s.threads.push(t);return}e.set(i,{anchor:t.anchor,key:i,threads:[t]})}),Array.from(e.values()).sort((t,i)=>(t.anchor?.startLine??0)-(i.anchor?.startLine??0))}updateCardSourceRect(){return this.activeCard?this.activeCard.origin==="editor"?this.session?.getCommentAnchorClientRect?.(this.activeCard.anchor)??this.activeCard.sourceRect:this.activeCard.origin==="editor-chip"?this.activeCard.sourceRect:this.activeCard.origin==="preview"?this.resolvePreviewTarget(this.activeCard.anchor)?.bubbleRect??this.activeCard.sourceRect:this.activeCard.origin==="toolbar"?this.commentSelectionButton?.getBoundingClientRect?.()??this.activeCard.sourceRect:this.activeCard.sourceRect:null}renderCard(){let e=this.ensureCardRoot();if(e.replaceChildren(),e.classList.toggle("hidden",!this.activeCard),!this.activeCard){this.pendingCardFocusElement=null,e.style.visibility="";return}this.pendingCardFocusElement=null;let t=document.createElement("section");t.className="comment-card";let i=document.createElement("div");i.className="comment-card-header";let s=document.createElement("div");s.className="comment-card-title-wrap";let r=document.createElement("h3");r.className="comment-card-title",r.textContent=this.activeCard.mode==="create"?"New comment":"Comment threads";let a=document.createElement("p");a.className="comment-card-meta",a.textContent=di(this.activeCard.anchor),s.append(r,a);let o=document.createElement("button");if(o.type="button",o.className="comment-card-close",o.setAttribute("aria-label","Close comments"),o.textContent="Close",o.addEventListener("click",()=>this.closeCard()),i.append(s,o),t.appendChild(i),this.activeCard.anchor?.quote){let l=document.createElement("p");l.className="comment-card-quote",l.textContent=this.activeCard.anchor.quote,t.appendChild(l)}if(this.activeCard.mode==="create")t.appendChild(this.createComposer());else{let l=this.getThreadGroups().find(d=>d.key===this.activeCard.groupKey);if(!l){this.closeCard();return}l.threads.forEach(d=>{t.appendChild(this.createThreadElement(d))})}e.appendChild(t),this.flushPendingCardFocus(),e.style.visibility="hidden",this.scheduleLayoutRefresh()}repositionActiveCard(){let e=this.cardRoot?.firstElementChild;if(!e||!this.activeCard){this.cardRoot&&(this.cardRoot.style.visibility="");return}this.positionCard(e),this.cardRoot.style.visibility="",this.flushPendingCardFocus()}createComposer(){let e=document.createElement("form");e.className="comment-card-form";let t=document.createElement("textarea");t.className="input comment-card-input",t.rows=4,t.maxLength=ct,t.placeholder="Add context, feedback, or a question...";let i=document.createElement("div");i.className="comment-card-actions";let s=document.createElement("button");s.type="button",s.className="btn btn-secondary",s.textContent="Cancel",s.addEventListener("click",()=>this.closeCard());let r=document.createElement("button");return r.type="submit",r.className="btn btn-primary",r.textContent="Post comment",i.append(s,r),e.append(t,i),e.addEventListener("submit",async a=>{if(a.preventDefault(),!await this.onCreateThread?.({anchor:this.activeCard?.anchor,body:t.value})){t.focus();return}this.closeCard()}),this.pendingCardFocusElement=t,e}createThreadElement(e){let t=document.createElement("article");t.className="comment-thread-card";let i=document.createElement("div");i.className="comment-thread-card-header";let s=document.createElement("span");s.className="comment-thread-card-author",s.textContent=e.createdByName;let r=document.createElement("span");r.className="comment-thread-card-time",r.textContent=this.formatTimestamp(e.createdAt);let a=document.createElement("div");a.className="comment-thread-card-actions";let o=document.createElement("button");o.type="button",o.className="comment-thread-card-action",o.textContent="Jump",o.addEventListener("click",()=>this.onNavigateToLine?.(e.anchor?.startLine??1));let l=document.createElement("button");l.type="button",l.className="comment-thread-card-action";let d=this.activeCard?.replyThreadId===e.id;l.classList.toggle("is-active",d),l.textContent="Reply",l.setAttribute("aria-pressed",String(d)),l.setAttribute("aria-label",d?"Cancel reply":"Reply to thread"),l.title=d?"Cancel reply":"Reply to thread",l.addEventListener("click",()=>{this.activeCard={...this.activeCard,replyThreadId:d?null:e.id},this.renderCard()});let c=document.createElement("button");return c.type="button",c.className="comment-thread-card-action is-danger",c.textContent="Resolve",c.addEventListener("click",async()=>{await this.onResolveThread?.(e.id)}),a.append(o,l,c),i.append(s,r,a),t.append(i),e.messages.forEach(p=>{t.appendChild(this.createMessageElement(p))}),this.activeCard?.replyThreadId===e.id&&t.appendChild(this.createReplyComposer(e)),t}createMessageElement(e){let t=document.createElement("div");t.className="comment-message-card";let i=document.createElement("div");i.className="comment-message-card-meta";let s=document.createElement("span");s.className="comment-message-card-author",s.textContent=e.userName;let r=document.createElement("span");r.className="comment-message-card-time",r.textContent=this.formatTimestamp(e.createdAt);let a=document.createElement("p");return a.className="comment-message-card-body",a.textContent=e.body,i.append(s,r),t.append(i,a),t}createReplyComposer(e){let t=document.createElement("form");t.className="comment-reply-form";let i=document.createElement("textarea");i.className="input comment-card-input",i.rows=3,i.maxLength=ct,i.placeholder="Reply to thread...";let s=document.createElement("div");s.className="comment-card-actions";let r=document.createElement("button");r.type="button",r.className="btn btn-secondary",r.textContent="Cancel",r.addEventListener("click",()=>{this.activeCard={...this.activeCard,replyThreadId:null},this.renderCard()});let a=document.createElement("button");return a.type="submit",a.className="btn btn-primary",a.textContent="Reply",s.append(r,a),t.append(i,s),this.pendingCardFocusElement=i,t.addEventListener("submit",async o=>{if(o.preventDefault(),!await this.onReplyToThread?.(e.id,i.value)){i.focus();return}this.activeCard={...this.activeCard,replyThreadId:null},this.renderCard()}),t}positionCard(e){let t=this.updateCardSourceRect(),i=window.innerWidth,s=window.innerHeight,r=e.getBoundingClientRect(),a=se((i-r.width)/2,16,i-r.width-16),o=se((s-r.height)/4,16,s-r.height-16),l=a,d=o;t&&(l=se(t.left,16,i-Math.min(r.width,li)-16),d=t.bottom+oi,d+r.height>s-16&&(d=Math.max(t.top-r.height-oi,16))),this.cardRoot.style.left=`${l}px`,this.cardRoot.style.top=`${d}px`,this.cardRoot.style.width=`${Math.min(Math.max(r.width,li),i-32)}px`}formatTimestamp(e){if(!Number.isFinite(e))return"";try{return this.timeFormatter.format(new Date(e))}catch{return""}}flushPendingCardFocus(){let e=this.pendingCardFocusElement;if(!(e instanceof HTMLElement)||!e.isConnected){this.pendingCardFocusElement=null;return}this.pendingCardFocusElement=null,e.focus({preventScroll:!0})}clearSelectionRevealTimer(){this.selectionRevealTimer&&(clearTimeout(this.selectionRevealTimer),this.selectionRevealTimer=0)}scheduleSelectionReveal(e){this.clearSelectionRevealTimer(),this.selectionRevealTimer=window.setTimeout(()=>{this.selectionRevealTimer=0,!(this.pointerSelecting||this.activeCard?.mode==="create"||!ci(this.pendingSelectionAnchor,e))&&(this.committedSelectionAnchor=e,this.scheduleLayoutRefresh())},Hi)}};function qe(n,e){let t=new Map;e.forEach(s=>{let a=n.get(s.key)??{filePath:s.filePath,iframe:null,instanceId:null,key:s.key,label:s.label,placeholder:s.placeholder,queued:!1,reusedFromEmbed:!1,wrapper:null};a.filePath=s.filePath,a.key=s.key,a.label=s.label,a.placeholder=s.placeholder,t.set(s.key,a)});let i=[];return n.forEach((s,r)=>{t.has(r)||i.push(s)}),{nextEntries:t,removedEntries:i}}var he=420,Wi=500,Vi=15e3,Ki=800,Gi=3,ji=200,Qi="/excalidraw-editor.html";function Zi(n,e){return typeof window.requestIdleCallback=="function"?window.requestIdleCallback(n,{timeout:e}):window.setTimeout(()=>{n({didTimeout:!1,timeRemaining:()=>0})},1)}function We(n){if(n!==null){if(typeof window.cancelIdleCallback=="function"){window.cancelIdleCallback(n);return}window.clearTimeout(n)}}function Ji(n,e,t){if(!n||!e)return!1;let i=e.getBoundingClientRect(),s=n.getBoundingClientRect();return s.bottom>=i.top-t&&s.top<=i.bottom+t}var Ve=class{constructor({getTheme:e,getLocalUser:t,onOpenFile:i=null,previewContainer:s,previewElement:r,toastController:a}){this.getTheme=e,this.getLocalUser=t,this.onOpenFile=i,this.previewContainer=s,this.previewElement=r,this.toastController=a,this.embedEntries=new Map,this.hydrationQueue=[],this.hydrationIdleId=null,this.hydrationPaused=!1,this.hydrationInProgress=!1,this.instanceCounter=0,this.isLargeDocument=!1,this.maximizedEmbed=null,this.overlayRoot=null,this.maximizedRoot=null,this.placeholderObserver=null,this.followedPeerIdsByFilePath=new Map,this._onMessage=this._onMessage.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onPreviewClick=this._onPreviewClick.bind(this),window.addEventListener("message",this._onMessage),window.addEventListener("keydown",this._onKeyDown),this.previewElement?.addEventListener("click",this._onPreviewClick)}destroy(){window.removeEventListener("message",this._onMessage),window.removeEventListener("keydown",this._onKeyDown),this.previewElement?.removeEventListener("click",this._onPreviewClick),this._disconnectPlaceholderObserver(),We(this.hydrationIdleId),this.hydrationIdleId=null,this.hydrationQueue=[],this._exitMaximizedEmbed(),document.body.classList.remove("excalidraw-maximized-open"),this.embedEntries.forEach(e=>{this._clearEntryBootTimeout(e),e.wrapper?.remove(),e.placeholder=null}),this.embedEntries.clear(),this.followedPeerIdsByFilePath.clear(),this.overlayRoot?.remove(),this.overlayRoot=null,this.maximizedRoot?.remove(),this.maximizedRoot=null}async setFollowedUser(e,t=null){if(!e)return!1;this.followedPeerIdsByFilePath.set(e,t||null);let i=this._findEntryByFilePath(e);return i&&(i.wrapper||await this._hydrateEntry(i),i.followedPeerId=this.followedPeerIdsByFilePath.get(e)??null,this._syncEntryFollowState(i)),!0}detachForCommit(){this._disconnectPlaceholderObserver(),We(this.hydrationIdleId),this.hydrationIdleId=null,this.hydrationQueue=[],this.hydrationInProgress=!1,this.overlayRoot&&(this.overlayRoot.hidden=!0),this.maximizedRoot&&(this.maximizedRoot.hidden=!0),this.embedEntries.forEach(e=>{e.queued=!1,e.placeholder=null})}setHydrationPaused(e){if(this.hydrationPaused=!!e,this.hydrationPaused){We(this.hydrationIdleId),this.hydrationIdleId=null;return}this.hydrateVisibleEmbeds(),this._scheduleHydration()}reconcileEmbeds(e,{isLargeDocument:t=!1}={}){this.isLargeDocument=!!t,this._disconnectPlaceholderObserver(),We(this.hydrationIdleId),this.hydrationIdleId=null,this.hydrationQueue=[],this.hydrationInProgress=!1;let i=Array.from(e.querySelectorAll(".excalidraw-embed-placeholder[data-embed-key]")).map(a=>({filePath:a.dataset.embedTarget,key:a.dataset.embedKey,label:a.dataset.embedLabel||a.dataset.embedTarget,placeholder:a})),{nextEntries:s,removedEntries:r}=qe(this.embedEntries,i);this._adoptReusableEntries(s,r),r.forEach(a=>this._destroyEntry(a)),this.embedEntries=s,this._ensurePlaceholderObserver(),this.embedEntries.forEach(a=>{if(a.queued=!1,a.followedPeerId=this.followedPeerIdsByFilePath.get(a.filePath),a.wrapper){this._updateEmbedLabel(a),this._attachWrapper(a);return}a.placeholder&&this.placeholderObserver?.observe(a.placeholder)}),this.hydrationPaused||this.hydrateVisibleEmbeds(),this.syncLayout()}hydrateVisibleEmbeds(){if(this.hydrationPaused)return;let e=this.isLargeDocument?180:420;this.embedEntries.forEach(t=>{t.wrapper||!t.placeholder?.isConnected||Ji(t.placeholder,this.previewContainer,e)&&this._enqueueHydration(t,{prioritize:!0})})}updateTheme(e){this.embedEntries.forEach(t=>{this._postMessageToEntry(t,{source:"collabmd-host",type:"set-theme",theme:e})})}updateLocalUser(e){this.embedEntries.forEach(t=>{this._syncEntryUser(t,e)})}_ensurePlaceholderObserver(){this.previewContainer&&(this.placeholderObserver=new IntersectionObserver(e=>{e.forEach(t=>{if(!t.isIntersecting)return;let i=this.embedEntries.get(t.target.dataset.embedKey);i&&this._enqueueHydration(i)})},{root:this.previewContainer,rootMargin:this.isLargeDocument?"180px 0px":"420px 0px"}))}_disconnectPlaceholderObserver(){this.placeholderObserver&&(this.placeholderObserver.disconnect(),this.placeholderObserver=null)}_enqueueHydration(e,{prioritize:t=!1}={}){if(!(!e||e.wrapper||e.queued)&&(e.queued=!0,t?this.hydrationQueue.unshift(e.key):this.hydrationQueue.push(e.key),!this.hydrationPaused)){if(t&&!this.hydrationInProgress&&this.hydrationIdleId===null){this._flushHydrationQueue();return}this._scheduleHydration()}}_scheduleHydration(){this.hydrationPaused||this.hydrationInProgress||this.hydrationIdleId!==null||(this.hydrationIdleId=Zi(()=>{this.hydrationIdleId=null,this._flushHydrationQueue()},Wi))}async _flushHydrationQueue(){if(this.hydrationPaused||this.hydrationInProgress)return;let e=null;for(;this.hydrationQueue.length>0&&!e;){let t=this.hydrationQueue.shift(),i=this.embedEntries.get(t);if(!i||i.wrapper||!i.placeholder?.isConnected){i&&(i.queued=!1);continue}e=i}e&&(this.hydrationInProgress=!0,e.queued=!1,await this._hydrateEntry(e),this.hydrationInProgress=!1,this.hydrationQueue.length>0&&this._scheduleHydration())}async _hydrateEntry(e){if(!(!e.placeholder?.isConnected&&!e.wrapper)){if(!e.wrapper){let t=this._createEmbedContainer(e);e.wrapper=t.wrapper,e.iframe=t.iframe,e.labelElement=t.labelElement,e.instanceId=t.instanceId,e.isReady=!1,e.bootAttempts=(e.bootAttempts??0)+1,this._armEntryBootTimeout(e)}e.followedPeerId=this.followedPeerIdsByFilePath.get(e.filePath),this._updateEmbedLabel(e),this._attachWrapper(e)}}_attachWrapper(e){let t=e.placeholder?.isConnected?e.placeholder:this.previewElement?.querySelector(`.excalidraw-embed-placeholder[data-embed-key="${e.key}"]`);if(!t)return;if(e.placeholder=t,this._syncMountedEntryMetadata(e),this._shouldInlineFilePreview(e)){e.wrapper.style.position="",e.wrapper.style.top="",e.wrapper.style.left="",e.wrapper.style.width="",e.wrapper.style.margin="",e.wrapper.style.pointerEvents="auto",t.replaceWith(e.wrapper),e.placeholder=null;return}let i=this._ensureOverlayRoot();i.hidden=!1,e.wrapper?.parentElement!==i&&i.appendChild(e.wrapper),this._syncEntryLayout(e)}_adoptReusableEntries(e,t){e.forEach((i,s)=>{if(i.wrapper||i.iframe)return;let r=t.findIndex(o=>o.filePath===i.filePath&&this._getEntryMode(o)===this._getEntryMode(i)&&(o.wrapper||o.iframe));if(r<0)return;let[a]=t.splice(r,1);a.filePath=i.filePath,a.key=i.key,a.label=i.label,a.placeholder=i.placeholder,a.queued=!1,a.reusedFromEmbed=this._isFilePreviewEntry(i),e.set(s,a)})}_destroyEntry(e){this.maximizedEmbed?.wrapper===e.wrapper&&this._exitMaximizedEmbed(),this._clearEntryBootTimeout(e),this._resetPlaceholderLayout(e),e.wrapper?.remove(),e.placeholder=null}_armEntryBootTimeout(e){this._clearEntryBootTimeout(e),e.bootTimerId=window.setTimeout(()=>{this._handleEntryBootTimeout(e)},Vi)}_clearEntryBootTimeout(e){e?.bootTimerId&&(window.clearTimeout(e.bootTimerId),e.bootTimerId=null)}async _handleEntryBootTimeout(e){if(e?.iframe?.isConnected){if((e.bootAttempts??0)>=Gi){this._clearEntryBootTimeout(e),this.toastController?.show(`Excalidraw embed timed out: ${e.label}`);return}await this._retryEntryBootstrap(e)}}async _retryEntryBootstrap(e){e&&(this._clearEntryBootTimeout(e),this._resetPlaceholderLayout(e),this.maximizedEmbed?.wrapper===e.wrapper&&this._exitMaximizedEmbed(),e.wrapper?.remove(),e.wrapper=null,e.iframe=null,e.labelElement=null,e.instanceId=null,e.isReady=!1,await this._hydrateEntry(e))}_findEntryByContentWindow(e){if(!e)return null;for(let t of this.embedEntries.values())if(t.iframe?.contentWindow===e)return t;return null}_findEntryByFilePath(e){if(!e)return null;for(let t of this.embedEntries.values())if(t.filePath===e)return t;return null}_updateEmbedLabel(e){e.labelElement&&(e.labelElement.textContent=e.label.replace(/\.excalidraw$/i,""))}_syncMountedEntryMetadata(e){e.wrapper&&(e.wrapper.dataset.embedKey=e.key,e.wrapper.dataset.file=e.filePath),e.iframe&&(e.iframe.title=`Excalidraw: ${e.filePath}`)}_buildIframeUrl(e){let t=new URL(bt(Qi)),i=this.getTheme?.()||"dark";t.searchParams.set("file",e.filePath),t.searchParams.set("theme",i),t.searchParams.set("boot",e.instanceId||""),this._isFilePreviewEntry(e)||t.searchParams.set("mode","preview");let s=this.getLocalUser?.();s?.name&&t.searchParams.set("userName",s.name),s?.color&&t.searchParams.set("userColor",s.color),s?.colorLight&&t.searchParams.set("userColorLight",s.colorLight),s?.peerId&&t.searchParams.set("userPeerId",s.peerId);let r=new URLSearchParams(window.location.search),a=r.get("server");return a&&t.searchParams.set("server",a),r.get("test")==="1"&&t.searchParams.set("test","1"),r.has("syncTimeoutMs")&&t.searchParams.set("syncTimeoutMs",r.get("syncTimeoutMs")),t}_createEmbedContainer(e){let t=document.createElement("div");t.className="excalidraw-embed diagram-preview-shell",t.dataset.embedKey=e.key,t.dataset.file=e.filePath;let i=document.createElement("div");i.className="excalidraw-embed-header diagram-preview-toolbar";let s=document.createElement("span");s.className="excalidraw-embed-icon",s.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>';let r=document.createElement("span");r.className="excalidraw-embed-label",r.textContent=e.label.replace(/\.excalidraw$/i,"");let a=document.createElement("button");a.type="button",a.className="excalidraw-embed-btn diagram-preview-action-btn",a.title="Edit in Excalidraw",a.setAttribute("aria-label","Edit in Excalidraw"),T(a,"edit");let o=document.createElement("button");o.type="button",o.className="excalidraw-embed-btn diagram-preview-action-btn",o.title="Maximize diagram",o.setAttribute("aria-label","Maximize diagram"),T(o,"maximize"),i.append(s,r),this._isFilePreviewEntry(e)||i.append(a),i.append(o);let l=document.createElement("iframe");l.className="excalidraw-embed-iframe",l.dataset.instanceId=String(++this.instanceCounter),e.instanceId=l.dataset.instanceId,l.src=this._buildIframeUrl(e).toString(),l.setAttribute("loading","eager"),l.title=`Excalidraw: ${e.filePath}`,l.style.height=`${he}px`;let d=document.createElement("div");d.className="excalidraw-embed-resizer",d.title="Drag to resize",this._setupResizer(d,l,()=>this._syncEntryLayout(e)),t.append(i,l,d);let c=!1,p=`${he}px`,f=()=>{T(o,c?"restore":"maximize"),o.title=c?"Restore diagram size":"Maximize diagram",o.setAttribute("aria-label",c?"Restore diagram size":"Maximize diagram")},h=()=>{c&&(c=!1,t.classList.remove("is-maximized"),f(),document.body.classList.remove("excalidraw-maximized-open"),this._restoreWrapperMount(e),l.style.height=p,this.maximizedEmbed?.wrapper===t&&(this.maximizedEmbed=null),this._syncEntryLayout(e))},v=()=>{c||(this._exitMaximizedEmbed(),c=!0,p=l.style.height||`${he}px`,this._mountWrapperInMaximizedRoot(e),t.classList.add("is-maximized"),f(),document.body.classList.add("excalidraw-maximized-open"),this.maximizedEmbed={wrapper:t,exit:h},this._syncEntryLayout(e))};return o.addEventListener("click",()=>{c?h():v()}),a.addEventListener("click",()=>{this.onOpenFile?.(e.filePath)}),f(),{iframe:l,instanceId:l.dataset.instanceId,labelElement:r,wrapper:t}}_setupResizer(e,t,i=null){let s=0,r=0,a=l=>{let d=l.clientY-s,c=Math.min(Math.max(r+d,ji),Ki);t.style.height=`${c}px`,t.style.pointerEvents="none"},o=()=>{t.style.pointerEvents="",document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",o),i?.()};e.addEventListener("pointerdown",l=>{l.preventDefault(),s=l.clientY,r=t.offsetHeight,document.addEventListener("pointermove",a),document.addEventListener("pointerup",o)})}_ensureOverlayRoot(){if(this.overlayRoot?.isConnected&&this.overlayRoot.parentElement===this.previewElement)return this.overlayRoot;let e=this.previewElement?.querySelector('[data-excalidraw-overlay-root="true"]');return e||(e=document.createElement("div"),e.dataset.excalidrawOverlayRoot="true",e.className="excalidraw-embed-overlay-root",this.previewElement?.appendChild(e)),this.overlayRoot=e,e}_ensureMaximizedRoot(){if(this.maximizedRoot?.isConnected&&this.maximizedRoot.parentElement===document.body)return this.maximizedRoot;let e=document.body.querySelector('[data-excalidraw-maximized-root="true"]');return e||(e=document.createElement("div"),e.dataset.excalidrawMaximizedRoot="true",e.className="excalidraw-maximized-root",document.body.appendChild(e)),this.maximizedRoot=e,e}_isFilePreviewEntry(e){return e?.key===`${e?.filePath}#file-preview`}_getEntryMode(e){return this._isFilePreviewEntry(e)?"edit":"preview"}_shouldInlineFilePreview(e){return this._isFilePreviewEntry(e)&&!e?.reusedFromEmbed}_resetPlaceholderLayout(e){!e?.placeholder?.isConnected||this._shouldInlineFilePreview(e)||(e.placeholder.classList.remove("is-hydrated"),e.placeholder.removeAttribute("data-embed-hydrated"),e.placeholder.style.height="",e.placeholder.style.pointerEvents="")}_mountWrapperInMaximizedRoot(e){if(!e?.wrapper)return;let t=this._ensureMaximizedRoot();t.hidden=!1,e.restoreParent=e.wrapper.parentElement||null,e.restoreNextSibling=e.wrapper.nextSibling||null,e.wrapper.style.position="",e.wrapper.style.top="",e.wrapper.style.left="",e.wrapper.style.width="",e.wrapper.style.margin="",e.wrapper.parentElement!==t&&t.appendChild(e.wrapper)}_restoreWrapperMount(e){if(e?.wrapper){if(this._shouldInlineFilePreview(e)){let{restoreParent:t,restoreNextSibling:i}=e;t?.isConnected&&(i?.parentElement===t?t.insertBefore(e.wrapper,i):t.appendChild(e.wrapper))}else{let t=this._ensureOverlayRoot();t.hidden=!1,e.wrapper.parentElement!==t&&t.appendChild(e.wrapper)}e.restoreParent=null,e.restoreNextSibling=null,this.maximizedRoot&&this.maximizedRoot.childElementCount===0&&(this.maximizedRoot.hidden=!0)}}_syncEntryLayout(e){if(!e?.wrapper||this._shouldInlineFilePreview(e))return;let t=e.placeholder?.isConnected?e.placeholder:this.previewElement?.querySelector(`.excalidraw-embed-placeholder[data-embed-key="${e.key}"]`);if(!t)return;e.placeholder=t,t.classList.add("is-hydrated"),t.dataset.embedHydrated="true",t.style.pointerEvents="none",this._isFilePreviewEntry(e)&&t.childElementCount>0&&t.replaceChildren();let i=e.wrapper.classList.contains("is-maximized"),s=e.wrapper.querySelector(".excalidraw-embed-header")?.offsetHeight||0,r=e.iframe?.offsetHeight||Number.parseFloat(e.iframe?.style.height||"")||he,a=i?0:e.wrapper.querySelector(".excalidraw-embed-resizer")?.offsetHeight||0,o=Math.ceil(s+r+a);if(i||(e.inlineHeightPx=o),t.style.height=`${Math.ceil(e.inlineHeightPx||o||he)}px`,e.wrapper.style.pointerEvents="auto",i){e.wrapper.style.position="",e.wrapper.style.top="",e.wrapper.style.left="",e.wrapper.style.width="",e.wrapper.style.margin="";return}e.wrapper.style.position="absolute",e.wrapper.style.top=`${t.offsetTop}px`,e.wrapper.style.left=`${t.offsetLeft}px`,e.wrapper.style.width=`${t.offsetWidth}px`,e.wrapper.style.margin="0"}syncLayout(){this.embedEntries.forEach(e=>{e.wrapper&&!this._shouldInlineFilePreview(e)&&this._syncEntryLayout(e)})}_onPreviewClick(e){let t=e.target.closest(".excalidraw-embed-placeholder-btn");if(!t)return;e.preventDefault();let i=this.embedEntries.get(t.dataset.embedKey);i&&this._hydrateEntry(i)}_onMessage(e){if(e.origin!==window.location.origin)return;let t=e.data;if(!t||t.source!=="excalidraw-editor")return;let i=this._findEntryByContentWindow(e.source);if(i){if(t.type==="ready"){i.isReady=!0,this._clearEntryBootTimeout(i),this._syncEntryUser(i),this._postMessageToEntry(i,{source:"collabmd-host",type:"set-theme",theme:this.getTheme?.()||"dark"}),this._syncEntryFollowState(i);return}t.type==="error"&&(i.isReady=!1,this._handleEntryBootTimeout(i))}}_onKeyDown(e){e.key==="Escape"&&this._exitMaximizedEmbed()}_exitMaximizedEmbed(){this.maximizedEmbed?.exit&&this.maximizedEmbed.exit(),this.maximizedEmbed=null,document.body.classList.remove("excalidraw-maximized-open")}_postMessageToEntry(e,t){e?.iframe?.contentWindow?.postMessage(t,window.location.origin)}_syncEntryUser(e,t=null){let i=t||this.getLocalUser?.();i&&this._postMessageToEntry(e,{source:"collabmd-host",type:"set-user",user:{color:i.color||"",colorLight:i.colorLight||"",name:i.name||"",peerId:i.peerId||""}})}_syncEntryFollowState(e){!e?.isReady||e.followedPeerId===void 0||this._postMessageToEntry(e,{source:"collabmd-host",type:"follow-user",peerId:e.followedPeerId})}};function Yi(n){return String(n??"").replace(/\/+$/u,"").split("/").filter(Boolean).pop()||""}function Xi(){return JSON.stringify({type:"excalidraw",version:2,source:"collabmd",elements:[],appState:{viewBackgroundColor:"#ffffff",gridSize:null},files:{}})}var Ke=class{constructor({onFileDelete:e,onFileSelect:t,state:i,toastController:s,vaultClient:r,view:a,refresh:o}){this.onFileDelete=e,this.onFileSelect=t,this.state=i,this.toastController=s,this.vaultClient=r,this.view=a,this.refresh=o,this.newFileButton=document.getElementById("newFileBtn"),this.newDrawingButton=document.getElementById("newDrawingBtn"),this.newMermaidButton=document.getElementById("newMermaidBtn"),this.newPlantumlButton=document.getElementById("newPlantumlBtn"),this.newFolderButton=document.getElementById("newFolderBtn"),this.refreshButton=document.getElementById("refreshFilesBtn"),this.actionDialog=document.getElementById("fileActionDialog"),this.actionForm=document.getElementById("fileActionForm"),this.actionTitle=document.getElementById("fileActionTitle"),this.actionCopy=document.getElementById("fileActionCopy"),this.actionField=document.getElementById("fileActionField"),this.actionLabel=document.getElementById("fileActionLabel"),this.actionInput=document.getElementById("fileActionInput"),this.actionHint=document.getElementById("fileActionHint"),this.actionNote=document.getElementById("fileActionNote"),this.actionCancelButton=document.getElementById("fileActionCancel"),this.actionSubmitButton=document.getElementById("fileActionSubmit"),this.pendingAction=null,this.actionBusy=!1}initialize(){this.newFileButton?.addEventListener("click",()=>this.handleNewFile()),this.newDrawingButton?.addEventListener("click",()=>this.handleNewDrawing()),this.newMermaidButton?.addEventListener("click",()=>this.handleNewMermaid()),this.newPlantumlButton?.addEventListener("click",()=>this.handleNewPlantUml()),this.newFolderButton?.addEventListener("click",()=>this.handleNewFolder()),this.refreshButton?.addEventListener("click",()=>this.refresh()),this.actionCancelButton?.addEventListener("click",()=>this.closeActionDialog()),this.actionForm?.addEventListener("submit",e=>{e.preventDefault(),this.handleActionSubmit()}),this.actionDialog?.addEventListener("close",()=>this.resetActionDialog())}createContextMenuItems(e=""){return[{label:"New markdown file",onSelect:()=>this.handleNewFile({parentDir:e})},{label:"New Excalidraw drawing",onSelect:()=>this.handleNewDrawing({parentDir:e})},{label:"New Mermaid diagram",onSelect:()=>this.handleNewMermaid({parentDir:e})},{label:"New PlantUML diagram",onSelect:()=>this.handleNewPlantUml({parentDir:e})},{label:"New folder",onSelect:()=>this.handleNewFolder({parentDir:e})}]}getFileContextMenuItems(e){return[{label:"Rename",onSelect:()=>this.handleRename(e)},{label:"Delete",danger:!0,onSelect:()=>this.handleDelete(e)}]}showToast(e){e&&this.toastController?.show(String(e))}showError(e,t){this.showToast(t?.message?`${e}: ${t.message}`:e)}ensureExtension(e,t){return Vt(e,t)}openActionDialog({title:e,copy:t,label:i="Path",hint:s="",note:r="",placeholder:a="",value:o="",submitLabel:l="Save",destructive:d=!1,requiresInput:c=!0,emptyMessage:p="A value is required",onSubmit:f}){!this.actionDialog||!this.actionTitle||!this.actionCopy||!this.actionSubmitButton||!this.actionCancelButton||c&&!this.actionInput||(this.actionDialog.open&&(typeof this.actionDialog.close=="function"?this.actionDialog.close():(this.actionDialog.removeAttribute("open"),this.resetActionDialog())),this.pendingAction={requiresInput:c,emptyMessage:p,onSubmit:f},this.view?.removeContextMenu?.(),this.actionTitle.textContent=e,this.actionCopy.textContent=t,this.actionField&&(this.actionField.hidden=!c),this.actionLabel&&(this.actionLabel.textContent=i),this.actionInput&&(this.actionInput.value=o,this.actionInput.placeholder=a,this.actionInput.required=c,this.actionInput.disabled=!1),this.actionHint&&(this.actionHint.textContent=s,this.actionHint.hidden=!c||!s),this.actionNote&&(this.actionNote.textContent=r,this.actionNote.hidden=!r,this.actionNote.classList.toggle("is-danger",d)),this.actionSubmitButton.textContent=l,this.actionSubmitButton.disabled=!1,this.actionSubmitButton.classList.toggle("btn-primary",!d),this.actionSubmitButton.classList.toggle("btn-danger",d),this.actionCancelButton.disabled=!1,typeof this.actionDialog.showModal=="function"?this.actionDialog.showModal():this.actionDialog.setAttribute("open","true"),requestAnimationFrame(()=>{if(!c||!this.actionInput){this.actionSubmitButton.focus();return}this.actionInput.focus(),o&&this.actionInput.select()}))}resetActionDialog(){this.pendingAction=null,this.actionBusy=!1,this.actionField&&(this.actionField.hidden=!1),this.actionLabel&&(this.actionLabel.textContent="Path"),this.actionInput&&(this.actionInput.value="",this.actionInput.placeholder="",this.actionInput.required=!0,this.actionInput.disabled=!1),this.actionHint&&(this.actionHint.textContent="",this.actionHint.hidden=!0),this.actionNote&&(this.actionNote.textContent="",this.actionNote.hidden=!0,this.actionNote.classList.remove("is-danger")),this.actionSubmitButton&&(this.actionSubmitButton.textContent="Save",this.actionSubmitButton.disabled=!1,this.actionSubmitButton.classList.add("btn-primary"),this.actionSubmitButton.classList.remove("btn-danger")),this.actionCancelButton&&(this.actionCancelButton.disabled=!1)}closeActionDialog(){if(this.actionDialog){if(this.actionDialog.open&&typeof this.actionDialog.close=="function"){this.actionDialog.close();return}this.actionDialog.removeAttribute("open"),this.resetActionDialog()}}setActionDialogBusy(e){this.actionBusy=e,this.actionInput&&(this.actionInput.disabled=e||!(this.pendingAction?.requiresInput??!0)),this.actionCancelButton&&(this.actionCancelButton.disabled=e),this.actionSubmitButton&&(this.actionSubmitButton.disabled=e)}async handleActionSubmit(){if(!this.pendingAction?.onSubmit||this.actionBusy)return;let e=this.pendingAction.requiresInput,t=e?this.actionInput?.value.trim()??"":void 0;if(e&&!t){this.showToast(this.pendingAction.emptyMessage),this.actionInput?.focus();return}this.setActionDialogBusy(!0);let i=!1;try{i=await this.pendingAction.onSubmit(t)}catch(s){i=!1,this.showError("Failed to complete action",s)}if(this.setActionDialogBusy(!1),i!==!1){this.closeActionDialog();return}e&&this.actionInput&&(this.actionInput.focus(),this.actionInput.select())}async createVaultFile(e,t,{openAfterCreate:i=!1,errorMessage:s="Failed to create file"}={}){try{return await this.vaultClient.createFile({content:t,path:e}),this.state.expandDirectoryPath(e,{includeLeaf:!1}),await this.refresh(),i&&this.onFileSelect?.(e),!0}catch(r){return this.showToast(r?.message||s),!1}}async createDirectory(e){let t=k(e);if(!t)return this.showToast("Folder path is required"),!1;try{return await this.vaultClient.createDirectory(t),this.state.expandDirectoryPath(t),await this.refresh(),!0}catch(i){return this.showToast(i?.message||"Failed to create folder"),!1}}async renameVaultFile(e,t,i){let s=String(t??"").trim();if(!s)return this.showToast("File name is required"),!1;if(/[\\/]/u.test(s))return this.showToast("Rename only supports the file name right now"),!1;let r=q(s).trim();if(!r)return this.showToast("File name is required"),!1;let o=`${e.includes("/")?e.substring(0,e.lastIndexOf("/")+1):""}${r}${i}`;if(o===e)return!0;try{return await this.vaultClient.renameFile({newPath:o,oldPath:e}),this.state.expandDirectoryPath(o,{includeLeaf:!1}),await this.refresh(),this.state.activeFilePath===e&&(this.state.activeFilePath=o,this.onFileSelect?.(o)),!0}catch(l){return this.showToast(l?.message||"Failed to rename"),!1}}async deleteVaultFile(e){try{return await this.vaultClient.deleteFile(e),await this.refresh(),this.state.activeFilePath===e&&(this.state.activeFilePath=null,this.onFileDelete?.(e)),!0}catch(t){return this.showToast(t?.message||"Failed to delete"),!1}}getCreateContext(e=""){let t=k(e);return{hintPrefix:t?'Use "/" to create nested items under this folder.':'Use "/" to place it inside a folder.',inputLabelSuffix:t?"name or path":"path",note:t?`Parent folder: ${t}`:"",normalizedParentDir:t}}handleNewFile({parentDir:e=""}={}){let t=this.getCreateContext(e);this.openActionDialog({title:"Create markdown file",copy:t.normalizedParentDir?"Add a new note inside the selected folder. It opens immediately after creation.":"Add a new note to the vault. It opens immediately after creation.",label:`File ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".md" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?"my-note":"notes/my-note",submitLabel:"Create file",emptyMessage:"File path is required",onSubmit:i=>{let s=k(i);if(!s)return this.showToast("File path is required"),!1;let r=this.ensureExtension(ie(t.normalizedParentDir,s),".md");return this.createVaultFile(r,ke(r),{errorMessage:"Failed to create file",openAfterCreate:!0})}})}handleNewFolder({parentDir:e=""}={}){let t=this.getCreateContext(e);this.openActionDialog({title:"Create folder",copy:t.normalizedParentDir?"Add a new folder inside the selected folder.":"Add a new folder to organize notes and diagrams.",label:`Folder ${t.inputLabelSuffix}`,hint:t.hintPrefix,note:t.note,placeholder:t.normalizedParentDir?"archive":"notes/archive",submitLabel:"Create folder",emptyMessage:"Folder path is required",onSubmit:i=>this.createDirectory(ie(t.normalizedParentDir,i))})}handleNewDrawing({parentDir:e=""}={}){let t=this.getCreateContext(e);this.openActionDialog({title:"Create Excalidraw drawing",copy:t.normalizedParentDir?"Start a new drawing inside the selected folder.":"Start a new drawing file in the vault.",label:`Drawing ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".excalidraw" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?"architecture":"diagrams/architecture",submitLabel:"Create drawing",emptyMessage:"Drawing path is required",onSubmit:i=>{let s=k(i);if(!s)return this.showToast("Drawing path is required"),!1;let r=this.ensureExtension(ie(t.normalizedParentDir,s),".excalidraw");return this.createVaultFile(r,Xi(),{errorMessage:"Failed to create drawing",openAfterCreate:!0})}})}handleNewMermaid({parentDir:e=""}={}){let t=this.getCreateContext(e);this.openActionDialog({title:"Create Mermaid diagram",copy:t.normalizedParentDir?"Create a new `.mmd` or `.mermaid` file inside the selected folder.":"Create a new `.mmd` or `.mermaid` file with starter diagram content.",label:`Diagram ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".mmd" is added automatically unless you enter ".mermaid".`,note:t.note,placeholder:t.normalizedParentDir?"flow":"diagrams/flow",submitLabel:"Create diagram",emptyMessage:"Diagram path is required",onSubmit:i=>{let s=k(i);if(!s)return this.showToast("Diagram path is required"),!1;let r=Kt(ie(t.normalizedParentDir,s));return this.createVaultFile(r.path,r.content,{errorMessage:"Failed to create Mermaid diagram",openAfterCreate:!0})}})}handleNewPlantUml({parentDir:e=""}={}){let t=this.getCreateContext(e);this.openActionDialog({title:"Create PlantUML diagram",copy:t.normalizedParentDir?"Create a new `.puml` or `.plantuml` file inside the selected folder.":"Create a new `.puml` or `.plantuml` file with starter diagram content.",label:`Diagram ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".puml" is added automatically unless you enter ".plantuml".`,note:t.note,placeholder:t.normalizedParentDir?"sequence-flow":"diagrams/sequence-flow",submitLabel:"Create diagram",emptyMessage:"Diagram path is required",onSubmit:i=>{let s=k(i);if(!s)return this.showToast("Diagram path is required"),!1;let r=Gt(ie(t.normalizedParentDir,s));return this.createVaultFile(r.path,r.content,{errorMessage:"Failed to create PlantUML diagram",openAfterCreate:!0})}})}handleRename(e){let t=Yi(e),i=Lt(t)??".md";this.openActionDialog({title:"Rename file",copy:"Update the file name without changing its current type.",label:"Name",hint:`${i} is kept automatically.`,value:q(t),submitLabel:"Rename file",emptyMessage:"File name is required",onSubmit:s=>this.renameVaultFile(e,s,i)})}handleDelete(e){this.openActionDialog({title:"Delete file",copy:"This permanently removes the file from the vault.",note:e,submitLabel:"Delete file",destructive:!0,requiresInput:!1,onSubmit:()=>this.deleteVaultFile(e)})}};function fi(n,e=[]){for(let t of n){if(t.type==="file"||t.type==="excalidraw"||t.type==="mermaid"||t.type==="plantuml"){e.push(t.path);continue}t.type==="directory"&&Array.isArray(t.children)&&fi(t.children,e)}return e}var Ge=class{constructor(){this.tree=[],this.flatFiles=[],this.activeFilePath=null,this.expandedDirs=new Set,this.searchQuery=""}setTree(e){this.tree=Array.isArray(e)?e:[],this.flatFiles=fi(this.tree,[])}setSearchQuery(e){this.searchQuery=String(e??"").trim().toLowerCase()}getSearchMatches(){return this.searchQuery?this.flatFiles.filter(e=>e.toLowerCase().includes(this.searchQuery)):[]}setActiveFile(e){this.activeFilePath=e||null,e&&this.expandDirectoryPath(e,{includeLeaf:!1})}toggleDirectory(e){return this.expandedDirs.has(e)?(this.expandedDirs.delete(e),!1):(this.expandedDirs.add(e),!0)}expandDirectoryPath(e,{includeLeaf:t=!0}={}){let i=k(e);if(!i)return;let s=i.split("/"),r=t?s.length:Math.max(s.length-1,0),a="";for(let o=0;o<r;o+=1)a=a?`${a}/${s[o]}`:s[o],this.expandedDirs.add(a)}};function en(n){return String(n??"").replace(/\/+$/u,"").split("/").filter(Boolean).pop()||""}var je=class{constructor({onDirectoryToggle:e,onFileContextMenu:t,onFileSelect:i,onSearchChange:s,onTreeContextMenu:r}){this.onDirectoryToggle=e,this.onFileContextMenu=t,this.onFileSelect=i,this.onSearchChange=s,this.onTreeContextMenu=r,this.treeContainer=document.getElementById("fileTree"),this.searchInput=document.getElementById("fileSearchInput")}initialize(){this.searchInput?.addEventListener("input",e=>{this.onSearchChange?.(e.target.value)}),this.treeContainer?.addEventListener("contextmenu",e=>{e.target.closest(".file-tree-item")||(e.preventDefault(),this.onTreeContextMenu?.(e))})}render({activeFilePath:e,expandedDirs:t,searchMatches:i,searchQuery:s,tree:r}){if(!this.treeContainer)return;if(s){this.renderSearchResults(i,e);return}if(this.treeContainer.innerHTML="",r.length===0){this.treeContainer.innerHTML='<div class="file-tree-empty">No vault files found</div>';return}let a=document.createDocumentFragment();this.renderNodes(r,a,{activeFilePath:e,depth:0,expandedDirs:t}),this.treeContainer.appendChild(a)}renderSearchResults(e,t){if(!this.treeContainer)return;if(this.treeContainer.innerHTML="",e.length===0){this.treeContainer.innerHTML='<div class="file-tree-empty">No matches</div>';return}let i=document.createDocumentFragment();for(let s of e)i.appendChild(this.createFileItem({activeFilePath:t,depth:0,filePath:s,fileType:xt(s)??"file",name:en(s)}));this.treeContainer.appendChild(i)}renderNodes(e,t,{activeFilePath:i,depth:s,expandedDirs:r}){for(let a of e){if(a.type==="directory"){t.appendChild(this.createDirectoryItem(a,{activeFilePath:i,depth:s,expandedDirs:r}));continue}t.appendChild(this.createFileItem({activeFilePath:i,depth:s,filePath:a.path,fileType:a.type,name:a.name}))}}createDirectoryItem(e,{activeFilePath:t,depth:i,expandedDirs:s}){let r=document.createElement("div");r.className="file-tree-group";let a=document.createElement("button");a.className="file-tree-item file-tree-dir",a.style.setProperty("--depth",i),a.dataset.depth=i;let o=s.has(e.path);if(a.setAttribute("aria-expanded",String(o)),a.innerHTML=`
|
|
48
|
+
<svg class="file-tree-chevron${o?" expanded":""}" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
|
|
49
|
+
<svg class="file-tree-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
|
50
|
+
<span class="file-tree-name">${m(e.name)}</span>
|
|
51
|
+
`,a.addEventListener("click",()=>{this.onDirectoryToggle?.(e.path)}),a.addEventListener("contextmenu",l=>{l.preventDefault(),this.onFileContextMenu?.(l,{directoryPath:e.path,type:"directory"})}),r.appendChild(a),o&&Array.isArray(e.children)){let l=document.createElement("div");l.className="file-tree-children",this.renderNodes(e.children,l,{activeFilePath:t,depth:i+1,expandedDirs:s}),r.appendChild(l)}return r}createFileItem({activeFilePath:e,depth:t,filePath:i,fileType:s="file",name:r}){let a=document.createElement("button");a.className="file-tree-item file-tree-file";let o=s==="excalidraw",l=s==="mermaid",d=s==="plantuml";return o&&a.classList.add("is-excalidraw"),l&&a.classList.add("is-mermaid"),d&&a.classList.add("is-plantuml"),i===e&&a.classList.add("active"),a.style.setProperty("--depth",t),a.dataset.depth=t,a.dataset.path=i,a.innerHTML=`
|
|
52
|
+
${this.getFileIconSvg({isExcalidraw:o,isMermaid:l,isPlantUml:d})}
|
|
53
|
+
<span class="file-tree-name">${m(q(r))}</span>
|
|
54
|
+
`,a.addEventListener("click",()=>{this.onFileSelect?.(i)}),a.addEventListener("contextmenu",c=>{c.preventDefault(),this.onFileContextMenu?.(c,{filePath:i,type:"file"})}),a}getFileIconSvg({isExcalidraw:e,isMermaid:t,isPlantUml:i}){return e?'<svg class="file-tree-icon" 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>':t?'<svg class="file-tree-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 7.5c0-1.38 1.12-2.5 2.5-2.5 1.04 0 1.93.64 2.3 1.56A2.5 2.5 0 0 1 14 8.5v1"/><path d="M19 16.5c0 1.38-1.12 2.5-2.5 2.5-1.04 0-1.93-.64-2.3-1.56A2.5 2.5 0 0 1 10 15.5v-1"/><path d="M8 10.5h8"/><path d="M8 13.5h8"/><path d="M10 8.5v7"/><path d="M14 8.5v7"/></svg>':i?'<svg class="file-tree-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="7" height="6" rx="1"/><rect x="14" y="4" width="7" height="6" rx="1"/><rect x="8.5" y="14" width="7" height="6" rx="1"/><path d="M10 7h4"/><path d="M17.5 10v2.5"/><path d="M6.5 10v2.5"/><path d="M6.5 12.5h11"/></svg>':'<svg class="file-tree-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>'}showContextMenu(e,t){if(this.removeContextMenu(),!Array.isArray(t)||t.length===0)return;let i=document.createElement("div");i.className="file-context-menu";for(let l of t){let d=document.createElement("button");d.className=`file-context-item${l.danger?" file-context-danger":""}`,d.textContent=l.label,d.addEventListener("click",()=>{this.removeContextMenu(),l.onSelect?.()}),i.appendChild(d)}document.body.appendChild(i);let s=i.getBoundingClientRect(),r=Math.max(8,window.innerWidth-s.width-8),a=Math.max(8,window.innerHeight-s.height-8);i.style.left=`${Math.max(8,Math.min(e.clientX,r))}px`,i.style.top=`${Math.max(8,Math.min(e.clientY,a))}px`;let o=l=>{i.contains(l.target)||(this.removeContextMenu(),document.removeEventListener("click",o))};setTimeout(()=>document.addEventListener("click",o),0)}removeContextMenu(){document.querySelectorAll(".file-context-menu").forEach(e=>e.remove())}};var Qe=class{constructor({onFileSelect:e,onFileDelete:t,toastController:i,vaultClient:s=de}){this.onFileSelect=e,this.onFileDelete=t,this.toastController=i,this.vaultClient=s,this.state=new Ge,this.view=new je({onDirectoryToggle:r=>{this.state.toggleDirectory(r),this.renderTree()},onFileContextMenu:(r,a)=>{if(a.type==="directory"){this.view.showContextMenu(r,this.actionController.createContextMenuItems(a.directoryPath));return}this.view.showContextMenu(r,this.actionController.getFileContextMenuItems(a.filePath))},onFileSelect:r=>{this.onFileSelect?.(r)},onSearchChange:r=>{this.state.setSearchQuery(r),this.renderTree()},onTreeContextMenu:r=>{this.view.showContextMenu(r,this.actionController.createContextMenuItems())}}),this.actionController=new Ke({onFileDelete:this.onFileDelete,onFileSelect:this.onFileSelect,refresh:()=>this.refresh(),state:this.state,toastController:this.toastController,vaultClient:this.vaultClient,view:this.view})}initialize(){this.view.initialize(),this.actionController.initialize()}async refresh(){try{let e=await this.vaultClient.readTree();this.state.setTree(e.tree||[]),this.renderTree()}catch(e){console.error("[explorer] Failed to load file tree:",e.message)}}setActiveFile(e){this.state.setActiveFile(e),this.renderTree()}get flatFiles(){return this.state.flatFiles}renderTree(){this.view.render({activeFilePath:this.state.activeFilePath,expandedDirs:this.state.expandedDirs,searchMatches:this.state.getSearchMatches(),searchQuery:this.state.searchQuery,tree:this.state.tree})}};function tn(n){return String(n??"").split("/").pop()||""}function ue(n){switch(n){case"added":case"untracked":return"added";case"deleted":return"deleted";case"renamed":return"renamed";default:return"modified"}}function nn(n,e){let t=0;for(;t<n.length&&t<e.length&&n[t]===e[t];)t+=1;return t}function sn(n,e,t){let i=0,s=Math.min(n.length,e.length)-t;for(;i<s;){let r=n.length-1-i,a=e.length-1-i;if(n[r]!==e[a])break;i+=1}return i}function yi(n,e){let t=nn(n,e),i=sn(n,e,t),s=Math.max(t,n.length-i),r=Math.max(t,e.length-i),a=`${m(n.slice(0,t))}${s>t?`<span class="diff-highlight-del">${m(n.slice(t,s))}</span>`:""}${m(n.slice(s))}`,o=`${m(e.slice(0,t))}${r>t?`<span class="diff-highlight-add">${m(e.slice(t,r))}</span>`:""}${m(e.slice(r))}`;return{leftHtml:a,rightHtml:o}}function gi(n=[]){let e=[];for(let t=0;t<n.length;t+=1){let i=n[t];if(i.type==="context"||i.type==="note"){e.push({additions:[],context:[i],deletions:[]});continue}if(i.type!=="deletion"&&i.type!=="addition")continue;let s=[],r=[];for(;t<n.length&&n[t].type==="deletion";)s.push(n[t]),t+=1;for(;t<n.length&&n[t].type==="addition";)r.push(n[t]),t+=1;t-=1,e.push({additions:r,context:[],deletions:s})}return e}function wt(n,e,t){let i=Number.isInteger(n.oldLine)?n.oldLine:"",s=Number.isInteger(n.newLine)?n.newLine:"",r=n.type==="note"?"note":n.type,a=n.type==="context"||n.type==="note"?" ":e;return`
|
|
55
|
+
<div class="diff-line ${r}">
|
|
56
|
+
<div class="diff-line-numbers">
|
|
57
|
+
<span class="diff-line-num">${i}</span>
|
|
58
|
+
<span class="diff-line-num">${s}</span>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="diff-line-prefix">${m(a)}</div>
|
|
61
|
+
<div class="diff-line-content">${t}</div>
|
|
62
|
+
</div>
|
|
63
|
+
`}function wi(n,e){let t=n?m(n.content):"",i=e?m(e.content):"";if(n&&e&&n.type==="deletion"&&e.type==="addition"){let s=yi(n.content,e.content);t=s.leftHtml,i=s.rightHtml}return`
|
|
64
|
+
<div class="diff-split-row">
|
|
65
|
+
<div class="diff-split-line ${n?.type||"empty"}">
|
|
66
|
+
<span class="diff-split-num">${Number.isInteger(n?.oldLine)?n.oldLine:""}</span>
|
|
67
|
+
<span class="diff-split-content">${t}</span>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="diff-split-line ${e?.type||"empty"}">
|
|
70
|
+
<span class="diff-split-num">${Number.isInteger(e?.newLine)?e.newLine:""}</span>
|
|
71
|
+
<span class="diff-split-content">${i}</span>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
`}var Ze=class{constructor({onCommitStaged:e=null,onOpenFile:t=null,onStageFile:i=null,onUnstageFile:s=null,toastController:r=null}={}){this.onCommitStaged=e,this.onOpenFile=t,this.onStageFile=i,this.onUnstageFile=s,this.toastController=r,this.page=document.getElementById("diff-page"),this.content=document.getElementById("diffContent"),this.scrollContainer=document.getElementById("diffScroll"),this.fileIndicator=document.getElementById("diffFileIndicator"),this.openEditorButton=document.getElementById("diffOpenEditorBtn"),this.primaryActionButton=document.getElementById("diffPrimaryActionBtn"),this.commitButton=document.getElementById("diffCommitBtn"),this.stats=document.getElementById("diffStats"),this.prevButton=document.getElementById("diffPrevBtn"),this.nextButton=document.getElementById("diffNextBtn"),this.modeButtons=Array.from(document.querySelectorAll("[data-diff-mode]")),this.mode="unified",this.data=null,this.currentIndex=0,this.fileCache=new Map,this.loadingFilePath=null,this.requestScope="all",this.pendingAction=null,this.repoStatus=null}initialize(){this.prevButton?.addEventListener("click",()=>this.navigateFile(-1)),this.nextButton?.addEventListener("click",()=>this.navigateFile(1)),this.openEditorButton?.addEventListener("click",()=>{let e=this.getCurrentFile();e?.path&&this.onOpenFile?.(e.path)}),this.primaryActionButton?.addEventListener("click",()=>{let e=this.getPrimaryAction();e&&this.handleFileAction(e)}),this.commitButton?.addEventListener("click",()=>{this.handleFileAction("commit")}),this.content?.addEventListener("click",e=>{e.target instanceof Element&&e.target.closest("[data-load-full-diff]")&&this.loadCurrentFile({forceFullPatch:!0})}),this.modeButtons.forEach(e=>{e.addEventListener("click",()=>{let t=e.getAttribute("data-diff-mode");!t||t===this.mode||(this.mode=t,this.render())})})}hide(){this.page?.classList.add("hidden"),this.content&&(this.content.innerHTML=""),this.data=null,this.currentIndex=0,this.fileCache.clear(),this.loadingFilePath=null,this.pendingAction=null,this.repoStatus=null,this.syncToolbar()}async open({filePath:e=null,scope:t="all"}={}){this.fileCache.clear(),this.loadingFilePath=null,this.requestScope=t,this.renderLoading("Loading diff summary...");try{let i=new URLSearchParams;i.set("scope",t),e&&i.set("path",e),i.set("metaOnly","true");let s=await fetch(b(`/git/diff?${i.toString()}`)),r=await s.json();if(!s.ok)throw new Error(r.error||"Failed to load git diff");this.data=r;let a=e?Math.max(0,r.files.findIndex(o=>o.path===e)):0;return this.currentIndex=a,(r.files?.length??0)===0?(this.render(),r):(await this.loadCurrentFile(),r)}catch(i){return console.error("[git-diff] Failed to load diff:",i),this.toastController?.show("Failed to load git diff"),this.data={files:[],metaOnly:!1,summary:{additions:0,deletions:0,filesChanged:0}},this.renderEmpty("Failed to load git diff"),this.data}}navigateFile(e){if(!this.data?.files?.length)return;let t=Math.max(0,Math.min(this.currentIndex+e,this.data.files.length-1));t!==this.currentIndex&&(this.currentIndex=t,this.scrollContainer?.scrollTo({top:0,behavior:"auto"}),this.loadCurrentFile())}renderLoading(e="Loading git diff..."){this.page?.classList.remove("hidden"),this.content&&(this.content.innerHTML=`<div class="diff-empty-state">${m(e)}</div>`),this.data=null,this.syncToolbar()}renderEmpty(e){this.page?.classList.remove("hidden"),this.content&&(this.content.innerHTML=`<div class="diff-empty-state">${m(e)}</div>`),this.syncToolbar()}renderUnifiedHunk(e){let t=[];for(let i of gi(e.lines)){if(i.context.length>0){for(let r of i.context)t.push(wt(r," ",m(r.content)));continue}let s=Math.max(i.deletions.length,i.additions.length);for(let r=0;r<s;r+=1){let a=i.deletions[r]??null,o=i.additions[r]??null,l=a&&o?yi(a.content,o.content):null;a&&t.push(wt(a,"-",l?.leftHtml??m(a.content))),o&&t.push(wt(o,"+",l?.rightHtml??m(o.content)))}}return`
|
|
75
|
+
<div class="diff-hunk-header">${m(e.header)}</div>
|
|
76
|
+
${t.join("")}
|
|
77
|
+
`}renderUnifiedFile(e,t){return`
|
|
78
|
+
<section class="diff-file-block" data-diff-file-index="${t}">
|
|
79
|
+
<div class="diff-file-header">
|
|
80
|
+
<span class="diff-file-path">${m(e.path)}</span>
|
|
81
|
+
<span class="git-status-badge ${ue(e.status)}">${m(e.status)}</span>
|
|
82
|
+
<span class="diff-file-header-stats"><span class="diff-stats-add">+${e.stats?.additions??0}</span><span class="diff-stats-del">-${e.stats?.deletions??0}</span></span>
|
|
83
|
+
</div>
|
|
84
|
+
${e.isBinary?`<div class="diff-binary-message">${m(e.binaryMessage||"Binary file changed")}</div>`:""}
|
|
85
|
+
${e.hunks.map(i=>this.renderUnifiedHunk(i)).join("")}
|
|
86
|
+
</section>
|
|
87
|
+
`}renderSplitFile(e,t){let i=e.hunks.map(s=>{let r=[];for(let a of gi(s.lines)){if(a.context.length>0){for(let l of a.context)r.push(wi(l,l));continue}let o=Math.max(a.deletions.length,a.additions.length);for(let l=0;l<o;l+=1)r.push(wi(a.deletions[l]??null,a.additions[l]??null))}return`
|
|
88
|
+
<div class="diff-split-hunk">${m(s.header)}</div>
|
|
89
|
+
${r.join("")}
|
|
90
|
+
`}).join("");return`
|
|
91
|
+
<section class="diff-file-block" data-diff-file-index="${t}">
|
|
92
|
+
<div class="diff-file-header">
|
|
93
|
+
<span class="diff-file-path">${m(e.path)}</span>
|
|
94
|
+
<span class="git-status-badge ${ue(e.status)}">${m(e.status)}</span>
|
|
95
|
+
<span class="diff-file-header-stats"><span class="diff-stats-add">+${e.stats?.additions??0}</span><span class="diff-stats-del">-${e.stats?.deletions??0}</span></span>
|
|
96
|
+
</div>
|
|
97
|
+
<div class="diff-split">
|
|
98
|
+
<div class="diff-split-pane">
|
|
99
|
+
<div class="diff-split-pane-header">Before</div>
|
|
100
|
+
${i}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</section>
|
|
104
|
+
`}getCurrentFile(){let e=this.data?.files??[];return e.length===0?null:e[this.currentIndex]??e[0]??null}getCurrentCacheKey(){let e=this.getCurrentFile();return e?.path?`${this.requestScope}:${e.path}`:null}getCurrentFileDetail(){let e=this.getCurrentCacheKey();return e?this.fileCache.get(e):null}getCurrentActionState(){let e=this.getCurrentFile(),t=this.getCurrentFileDetail()??e,i=Number(this.repoStatus?.summary?.staged||0);return t?.path?{canCommit:i>0,canStage:!!(t.hasWorkingTreeChanges||t.hasUntrackedChanges),canUnstage:!!t.hasStagedChanges}:{canCommit:i>0,canStage:!1,canUnstage:!1}}getPrimaryAction(){let e=this.getCurrentActionState();return e.canStage&&!e.canUnstage?"stage":e.canUnstage&&!e.canStage||this.requestScope==="staged"&&e.canUnstage?"unstage":e.canStage?"stage":e.canUnstage?"unstage":null}async handleFileAction(e){let t=this.getCurrentFile();if(!(!t?.path||this.pendingAction)){this.pendingAction=e,this.syncToolbar();try{e==="stage"?await this.onStageFile?.(t.path,{scope:this.requestScope}):e==="unstage"?await this.onUnstageFile?.(t.path,{scope:this.requestScope}):e==="commit"&&await this.onCommitStaged?.()}finally{this.pendingAction=null,this.syncToolbar()}}}setRepoStatus(e){this.repoStatus=e,this.syncToolbar()}async loadCurrentFile({forceFullPatch:e=!1}={}){let t=this.getCurrentFile();if(!t?.path)return this.render(),null;let i=this.getCurrentCacheKey(),s=i?this.fileCache.get(i):null;if(s&&(!s.tooLarge||!e))return this.loadingFilePath=null,this.render(),s;this.loadingFilePath=t.path,this.render();try{let r=new URLSearchParams;r.set("scope",this.requestScope),r.set("path",t.path),e&&r.set("allowLargePatch","true");let a=await fetch(b(`/git/diff?${r.toString()}`)),o=await a.json();if(!a.ok)throw new Error(o.error||"Failed to load file diff");let l={...t,...o.files?.[0]??{}};return i&&this.fileCache.set(i,l),this.loadingFilePath=null,this.render(),l}catch(r){return console.error("[git-diff] Failed to load file diff:",r),this.toastController?.show("Failed to load file diff"),this.loadingFilePath=null,this.render(),null}}renderCurrentFile(){let e=this.getCurrentFile();if(!e)return'<div class="diff-empty-state">No changes to display.</div>';let t=this.getCurrentFileDetail();return this.loadingFilePath===e.path?`
|
|
105
|
+
<section class="diff-file-block">
|
|
106
|
+
<div class="diff-file-header">
|
|
107
|
+
<span class="diff-file-path">${m(e.path)}</span>
|
|
108
|
+
<span class="git-status-badge ${ue(e.status)}">${m(e.status)}</span>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="diff-empty-state">Loading file diff...</div>
|
|
111
|
+
</section>
|
|
112
|
+
`:t?t.tooLarge?`
|
|
113
|
+
<section class="diff-file-block">
|
|
114
|
+
<div class="diff-file-header">
|
|
115
|
+
<span class="diff-file-path">${m(t.path)}</span>
|
|
116
|
+
<span class="git-status-badge ${ue(t.status)}">${m(t.status)}</span>
|
|
117
|
+
<span class="diff-file-header-stats"><span class="diff-stats-add">+${t.stats?.additions??0}</span><span class="diff-stats-del">-${t.stats?.deletions??0}</span></span>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="diff-limit-card">
|
|
120
|
+
<strong>Large diff withheld</strong>
|
|
121
|
+
<span>This file diff is large enough to impact rendering performance.</span>
|
|
122
|
+
<button class="btn btn-secondary diff-load-full-btn" type="button" data-load-full-diff>Load full diff</button>
|
|
123
|
+
</div>
|
|
124
|
+
</section>
|
|
125
|
+
`:this.mode==="split"?this.renderSplitFile(t,this.currentIndex):this.renderUnifiedFile(t,this.currentIndex):`
|
|
126
|
+
<section class="diff-file-block">
|
|
127
|
+
<div class="diff-file-header">
|
|
128
|
+
<span class="diff-file-path">${m(e.path)}</span>
|
|
129
|
+
<span class="git-status-badge ${ue(e.status)}">${m(e.status)}</span>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="diff-empty-state">Select a file to load its diff.</div>
|
|
132
|
+
</section>
|
|
133
|
+
`}syncToolbar(){let e=this.data?.files?.length??0,t=e===0?0:this.currentIndex+1;if(this.fileIndicator&&(this.fileIndicator.textContent=e>0?`${t} / ${e} files`:"0 / 0 files"),this.stats){let a=this.data?.summary?.additions??0,o=this.data?.summary?.deletions??0;this.stats.innerHTML=`
|
|
134
|
+
<span class="diff-stats-add">+${a}</span>
|
|
135
|
+
<span class="diff-stats-del">-${o}</span>
|
|
136
|
+
`}this.modeButtons.forEach(a=>{a.classList.toggle("active",a.getAttribute("data-diff-mode")===this.mode)});let i=!!this.getCurrentFile()?.path,s=this.getCurrentActionState(),r=this.getPrimaryAction();this.openEditorButton?.toggleAttribute("disabled",!i),this.primaryActionButton&&(this.primaryActionButton.textContent=this.pendingAction===r?"Working...":r==="unstage"?"Unstage":"Stage",this.primaryActionButton.toggleAttribute("disabled",!i||!r||!!this.pendingAction)),this.commitButton&&(this.commitButton.textContent=this.pendingAction==="commit"?"Working...":"Commit Staged"),this.commitButton?.toggleAttribute("disabled",!s.canCommit||!!this.pendingAction),this.prevButton?.toggleAttribute("disabled",this.currentIndex<=0),this.nextButton?.toggleAttribute("disabled",e===0||this.currentIndex>=e-1)}render(){if(this.page?.classList.remove("hidden"),(this.data?.files??[]).length===0){this.renderEmpty("No changes to display.");return}this.content&&(this.content.innerHTML=this.renderCurrentFile(),this.syncToolbar())}getToolbarTitle({filePath:e=null,scope:t="all"}={}){return e?tn(e):t==="staged"?"Staged Changes":t==="working-tree"?"Working Tree Changes":"All Changes"}};var rn=1e4;function an(n){let e=String(n??"").split("/");return e.pop(),e.join("/")}function on(n){return String(n??"").split("/").pop()||""}function ln(){return'<svg class="git-file-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>'}function cn(){return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M13 6h3a2 2 0 0 1 2 2v7"/><path d="M6 9v12"/></svg>'}function dn(n){return`<svg class="git-section-chevron${n?" collapsed":""}" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>`}function Je(n){switch(n){case"commit":return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>';case"pull":return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="m18 13-6 6-6-6"/></svg>';case"push":return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5"/><path d="m6 11 6-6 6 6"/></svg>';case"unstage":return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 12H8"/><path d="m12 16-4-4 4-4"/></svg>';case"reset":return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/></svg>';default:return'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="M5 12h14"/></svg>'}}function hn(n){switch(n){case"added":return"added";case"deleted":return"deleted";case"renamed":return"renamed";case"untracked":return"untracked";default:return"modified"}}function un(n={},e={}){let t=Number(n.additions||0),i=Number(n.deletions||0);return Number(n.changedFiles||0)>0||t>0||i>0?`
|
|
137
|
+
<span class="git-change-stats" aria-label="Local diff summary">
|
|
138
|
+
<span class="git-change-add">+${t}</span>
|
|
139
|
+
<span class="git-change-del">-${i}</span>
|
|
140
|
+
</span>
|
|
141
|
+
`:e.upstream||Number(e.ahead||0)>0||Number(e.behind||0)>0?`
|
|
142
|
+
<span class="git-sync-info" aria-label="Remote sync status">
|
|
143
|
+
<span style="color: var(--color-success);">↑${Number(e.ahead||0)}</span>
|
|
144
|
+
<span style="color: var(--color-text-faint);">↓${Number(e.behind||0)}</span>
|
|
145
|
+
</span>
|
|
146
|
+
`:'<span class="git-sync-info git-sync-info-muted">Clean</span>'}var Ye=class{constructor({enabled:e=!0,onCommitStaged:t=()=>{},onPullBranch:i=()=>{},onPushBranch:s=()=>{},onRepoChange:r=()=>{},onResetFile:a=()=>{},onSelectDiff:o=()=>{},onStageFile:l=()=>{},onUnstageFile:d=()=>{},onViewAllDiff:c=()=>{},searchInput:p=null,toastController:f=null}={}){this.enabled=e,this.onCommitStaged=t,this.onPullBranch=i,this.onPushBranch=s,this.onRepoChange=r,this.onResetFile=a,this.onSelectDiff=o,this.onStageFile=l,this.onUnstageFile=d,this.onViewAllDiff=c,this.searchInput=p,this.toastController=f,this.panel=document.getElementById("gitPanel"),this.status=null,this.active=!1,this.refreshTimer=null,this.searchQuery="",this.collapsedSections=new Set,this.selection={path:null,scope:null},this.pendingActionKey=null}initialize(){this.panel?.addEventListener("click",e=>{let t=e.target instanceof Element?e.target.closest("[data-git-section-toggle]"):null;if(t){let l=t.getAttribute("data-git-section-toggle");this.toggleSection(l);return}let i=e.target instanceof Element?e.target.closest("[data-git-path]"):null;if(i&&!e.target.closest("[data-git-file-action]")){let l=i.getAttribute("data-git-path"),d=i.getAttribute("data-git-scope")||"working-tree";if(!l)return;this.onSelectDiff(l,{scope:d});return}let s=e.target instanceof Element?e.target.closest("[data-git-file-action]"):null;if(s){let l=s.getAttribute("data-git-file-action"),d=s.getAttribute("data-git-path"),c=s.getAttribute("data-git-scope")||"working-tree";if(!l||!d)return;e.preventDefault(),e.stopPropagation(),this.handleFileAction(l,d,c);return}if(e.target instanceof Element?e.target.closest("[data-git-view-all]"):null){this.onViewAllDiff();return}if(e.target instanceof Element?e.target.closest("[data-git-commit-staged]"):null){this.handleCommitStaged();return}let o=e.target instanceof Element?e.target.closest("[data-git-sync-action]"):null;if(o){let l=o.getAttribute("data-git-sync-action");(l==="pull"||l==="push")&&this.handleSyncAction(l)}}),this.searchInput?.addEventListener("input",e=>{this.searchQuery=String(e.target?.value??"").trim().toLowerCase(),this.render()})}setActive(e){let t=!!e;if(!(this.active===t&&(!t||this.refreshTimer))){if(this.active=t,!this.active){clearInterval(this.refreshTimer),this.refreshTimer=null;return}this.refresh(),this.refreshTimer||(this.refreshTimer=setInterval(()=>{this.refresh()},rn))}}setSelection({path:e=null,scope:t=null}={}){this.selection={path:e,scope:t},this.render()}toggleSection(e){e&&(this.collapsedSections.has(e)?this.collapsedSections.delete(e):this.collapsedSections.add(e),this.render())}async refresh({force:e=!1}={}){if(!this.enabled)return this.status={isGitRepo:!1,sections:[],summary:{changedFiles:0}},this.onRepoChange(!1,this.status),this.render(),this.status;try{let t=await fetch(b(`/git/status${e?"?force=true":""}`)),i=await t.json();if(!t.ok)throw new Error(i.error||"Failed to load git status");return this.status=i,this.onRepoChange(!!i.isGitRepo,i),this.render(),i}catch(t){return console.error("[git-panel] Failed to load git status:",t),this.toastController?.show("Failed to load git status"),this.status={isGitRepo:!1,sections:[],summary:{changedFiles:0}},this.onRepoChange(!1,this.status),this.render(),this.status}}filterFiles(e=[]){return this.searchQuery?e.filter(t=>t.path.toLowerCase().includes(this.searchQuery)||String(t.oldPath||"").toLowerCase().includes(this.searchQuery)):e}async handleFileAction(e,t,i){let s=`${e}:${i}:${t}`;if(this.pendingActionKey!==s){this.pendingActionKey=s,this.render();try{e==="stage"?await this.onStageFile(t,{scope:i}):e==="unstage"?await this.onUnstageFile(t,{scope:i}):e==="reset"&&await this.onResetFile(t,{scope:i})}finally{this.pendingActionKey=null,this.render()}}}async handleCommitStaged(){let e="commit-staged";if(this.pendingActionKey!==e){this.pendingActionKey=e,this.render();try{await this.onCommitStaged()}finally{this.pendingActionKey=null,this.render()}}}async handleSyncAction(e){let t=`sync:${e}`;if(this.pendingActionKey!==t){this.pendingActionKey=t,this.render();try{e==="pull"?await this.onPullBranch():e==="push"&&await this.onPushBranch()}finally{this.pendingActionKey=null,this.render()}}}renderSection(e){let t=this.filterFiles(e.files);if(t.length===0)return"";let i=this.collapsedSections.has(e.key);return`
|
|
147
|
+
<section class="git-section">
|
|
148
|
+
<button class="git-section-header" type="button" data-git-section-toggle="${m(e.key)}">
|
|
149
|
+
${dn(i)}
|
|
150
|
+
${m(e.label)}
|
|
151
|
+
<span class="git-section-count">${t.length}</span>
|
|
152
|
+
</button>
|
|
153
|
+
<div class="git-file-list${i?" hidden":""}">
|
|
154
|
+
${t.map(s=>this.renderFile(s)).join("")}
|
|
155
|
+
</div>
|
|
156
|
+
</section>
|
|
157
|
+
`}renderFile(e){let t=this.selection.path===e.path&&this.selection.scope===e.scope,i=an(e.path),s=on(e.path),r=hn(e.status),a=e.scope==="staged"?{label:"Unstage",value:"unstage"}:{label:"Stage",value:"stage"},o=`${a.value}:${e.scope}:${e.path}`,l=this.pendingActionKey===o,d=`reset:${e.scope}:${e.path}`,c=this.pendingActionKey===d;return`
|
|
158
|
+
<div class="git-file-row${t?" active":""}">
|
|
159
|
+
<button
|
|
160
|
+
class="git-file-item${t?" active":""}"
|
|
161
|
+
type="button"
|
|
162
|
+
data-git-path="${m(e.path)}"
|
|
163
|
+
data-git-scope="${m(e.scope)}"
|
|
164
|
+
>
|
|
165
|
+
${ln()}
|
|
166
|
+
<span class="git-file-copy">
|
|
167
|
+
<span class="git-file-name">${m(s)}</span>
|
|
168
|
+
${i?`<span class="git-file-path">${m(i)}</span>`:""}
|
|
169
|
+
</span>
|
|
170
|
+
<span class="git-status-badge ${r}">${m(e.code)}</span>
|
|
171
|
+
</button>
|
|
172
|
+
<div class="git-file-actions">
|
|
173
|
+
<button
|
|
174
|
+
class="git-file-action-btn"
|
|
175
|
+
type="button"
|
|
176
|
+
data-git-file-action="reset"
|
|
177
|
+
data-git-path="${m(e.path)}"
|
|
178
|
+
data-git-scope="${m(e.scope)}"
|
|
179
|
+
aria-label="Reset ${m(s)}"
|
|
180
|
+
title="Reset to current branch"
|
|
181
|
+
${c?"disabled":""}
|
|
182
|
+
>
|
|
183
|
+
${c?"...":Je("reset")}
|
|
184
|
+
</button>
|
|
185
|
+
<button
|
|
186
|
+
class="git-file-action-btn"
|
|
187
|
+
type="button"
|
|
188
|
+
data-git-file-action="${a.value}"
|
|
189
|
+
data-git-path="${m(e.path)}"
|
|
190
|
+
data-git-scope="${m(e.scope)}"
|
|
191
|
+
aria-label="${m(a.label)} ${m(s)}"
|
|
192
|
+
title="${m(a.label)}"
|
|
193
|
+
${l?"disabled":""}
|
|
194
|
+
>
|
|
195
|
+
${l?"...":Je(a.value)}
|
|
196
|
+
</button>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
`}renderEmpty(e){this.panel&&(this.panel.innerHTML=`<div class="git-panel-empty">${m(e)}</div>`)}render(){if(!this.panel)return;if(!this.status){this.renderEmpty("Loading git status...");return}if(!this.status.isGitRepo){this.renderEmpty("Git is unavailable for this vault.");return}let e=this.status.branch??{},t=(this.status.sections??[]).map(d=>this.renderSection(d)).filter(Boolean).join(""),i=!!this.status.summary?.changedFiles,s=Number(this.status.summary?.staged||0)>0,r=this.pendingActionKey==="commit-staged",a=!!e.upstream,o=this.pendingActionKey==="sync:pull",l=this.pendingActionKey==="sync:push";this.panel.innerHTML=`
|
|
200
|
+
<div class="git-branch-bar">
|
|
201
|
+
<div class="git-branch-meta">
|
|
202
|
+
<span class="git-branch-name">
|
|
203
|
+
${cn()}
|
|
204
|
+
${m(e.name||"HEAD")}
|
|
205
|
+
</span>
|
|
206
|
+
${un(this.status.summary,e)}
|
|
207
|
+
</div>
|
|
208
|
+
<div class="git-branch-actions" role="group" aria-label="Remote sync actions">
|
|
209
|
+
<button
|
|
210
|
+
class="git-branch-action-btn"
|
|
211
|
+
type="button"
|
|
212
|
+
data-git-sync-action="pull"
|
|
213
|
+
title="${a?"Pull remote changes (fast-forward only)":"No upstream branch configured"}"
|
|
214
|
+
aria-label="Pull branch"
|
|
215
|
+
${!a||o?"disabled":""}
|
|
216
|
+
>
|
|
217
|
+
${o?"...":`${Je("pull")}<span>Pull</span>`}
|
|
218
|
+
</button>
|
|
219
|
+
<button
|
|
220
|
+
class="git-branch-action-btn"
|
|
221
|
+
type="button"
|
|
222
|
+
data-git-sync-action="push"
|
|
223
|
+
title="${a?"Push local commits":"No upstream branch configured"}"
|
|
224
|
+
aria-label="Push branch"
|
|
225
|
+
${!a||l?"disabled":""}
|
|
226
|
+
>
|
|
227
|
+
${l?"...":`${Je("push")}<span>Push</span>`}
|
|
228
|
+
</button>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
${t||'<div class="git-panel-empty">No local changes</div>'}
|
|
232
|
+
${i?`
|
|
233
|
+
<div class="git-panel-footer">
|
|
234
|
+
<div class="git-panel-footer-actions">
|
|
235
|
+
<button class="git-view-all-btn" type="button" data-git-view-all>
|
|
236
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M2 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
237
|
+
View Full Diff
|
|
238
|
+
</button>
|
|
239
|
+
<button
|
|
240
|
+
class="git-footer-commit-btn"
|
|
241
|
+
type="button"
|
|
242
|
+
data-git-commit-staged
|
|
243
|
+
${!s||r?"disabled":""}
|
|
244
|
+
>
|
|
245
|
+
${r?"Working...":"Commit Staged"}
|
|
246
|
+
</button>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
`:""}
|
|
250
|
+
`}};var Xe=class{constructor({mobileBreakpointQuery:e=window.matchMedia("(max-width: 768px)"),onMeasureEditor:t}){this.mobileBreakpointQuery=e,this.onMeasureEditor=t,this.preferredView="split",this.mobileShowsEditor=!this.isMobileViewport(),this.currentView=this.mobileShowsEditor?this.preferredView:"preview",this.editorLayout=document.getElementById("editorLayout"),this.editorPane=document.getElementById("editorPane"),this.previewPane=document.getElementById("previewPane"),this.mobileToggleButton=document.getElementById("mobileViewToggle"),this.resizer=document.getElementById("resizer"),this.viewButtons=Array.from(document.querySelectorAll(".view-btn"))}isMobileViewport(){return this.mobileBreakpointQuery.matches}initialize(){this.viewButtons.forEach(e=>{e.addEventListener("click",()=>this.setView(e.dataset.view))}),this.mobileToggleButton?.addEventListener("click",()=>this.toggleMobileView()),this.initializeResizer(),this.restorePreferredView()}reset(){this.restorePreferredView(),this.editorPane&&(this.editorPane.style.flex=""),this.previewPane&&(this.previewPane.style.flex=""),this.updateResizerValue()}restorePreferredView(){let e=this.isMobileViewport()?this.mobileShowsEditor?"split":"preview":this.preferredView;this.applyView(e),this.updateMobileToggleButton(this.mobileShowsEditor?"Preview":"Editor")}applyView(e){this.currentView=e,this.editorLayout?.setAttribute("data-view",e),this.syncViewButtons()}setView(e,{persist:t=!0}={}){e&&(t&&(this.preferredView=e),this.applyView(e),(e==="split"||e==="editor")&&this.scheduleEditorMeasure())}toggleMobileView(){this.mobileShowsEditor=!this.mobileShowsEditor,this.applyView(this.mobileShowsEditor?"split":"preview"),this.updateMobileToggleButton(this.mobileShowsEditor?"Preview":"Editor"),this.mobileShowsEditor&&this.scheduleEditorMeasure()}scheduleEditorMeasure(){this.onMeasureEditor&&setTimeout(()=>this.onMeasureEditor(),50)}updateMobileToggleButton(e){if(!this.mobileToggleButton)return;let t='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>',i='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="8" y1="8" x2="16" y2="8"/><line x1="8" y1="12" x2="14" y2="12"/><line x1="8" y1="16" x2="12" y2="16"/></svg>';this.mobileToggleButton.innerHTML=`${e==="Editor"?i:t}<span class="toolbar-btn-label">${e}</span>`}syncViewButtons(){this.viewButtons.forEach(e=>{let t=e.dataset.view===this.currentView;e.classList.toggle("active",t),e.setAttribute("aria-pressed",String(t))})}updateResizerValue(){if(!this.resizer||!this.editorLayout||!this.editorPane)return;let e=this.editorLayout.offsetWidth;if(!Number.isFinite(e)||e<=0)return;let t=Math.round(this.editorPane.offsetWidth/e*100);this.resizer.setAttribute("aria-valuenow",String(Math.max(20,Math.min(80,t))))}applyEditorPaneWidth(e){if(!this.editorLayout||!this.editorPane||!this.previewPane)return;let t=this.editorLayout.offsetWidth;if(!Number.isFinite(t)||t<=0)return;let i=200,r=Math.max(i,Math.min(t-i,e))/t*100;this.editorPane.style.flex=`0 0 ${r}%`,this.previewPane.style.flex="1",this.updateResizerValue()}initializeResizer(){if(!this.resizer||!this.editorLayout||!this.editorPane||!this.previewPane)return;let e=!1,t=0,i=0;this.resizer.addEventListener("mousedown",s=>{e=!0,t=s.clientX,i=this.editorPane.offsetWidth,this.resizer.classList.add("dragging"),document.body.style.cursor="col-resize",document.body.style.userSelect="none",s.preventDefault()}),document.addEventListener("mousemove",s=>{if(!e)return;let r=s.clientX-t;this.applyEditorPaneWidth(i+r)}),document.addEventListener("mouseup",()=>{e&&(e=!1,this.resizer.classList.remove("dragging"),document.body.style.cursor="",document.body.style.userSelect="",this.scheduleEditorMeasure())}),this.resizer.addEventListener("keydown",s=>{let r=this.editorLayout.offsetWidth;if(!Number.isFinite(r)||r<=0)return;let a=Math.max(24,Math.round(r*.05));if(s.key==="ArrowLeft"){s.preventDefault(),this.applyEditorPaneWidth(this.editorPane.offsetWidth-a),this.scheduleEditorMeasure();return}if(s.key==="ArrowRight"){s.preventDefault(),this.applyEditorPaneWidth(this.editorPane.offsetWidth+a),this.scheduleEditorMeasure();return}if(s.key==="Home"){s.preventDefault(),this.applyEditorPaneWidth(r*.2),this.scheduleEditorMeasure();return}s.key==="End"&&(s.preventDefault(),this.applyEditorPaneWidth(r*.8),this.scheduleEditorMeasure())}),this.updateResizerValue()}};var et=class{constructor({mobileBreakpointQuery:e=window.matchMedia("(max-width: 768px)"),onNavigateToHeading:t}={}){this.outlineOpen=!1,this.activeHeadingFrame=null,this.activeHeadingId=null,this.headings=[],this.pinnedHeadingId=null,this.onNavigateToHeading=t,this.panel=document.getElementById("outlinePanel"),this.navigation=document.getElementById("outlineNav"),this.previewContainer=document.getElementById("previewContainer"),this.toggleButton=document.getElementById("outlineToggle"),this.mobileBreakpointQuery=e,this.handlePreviewScroll=()=>this.scheduleActiveHeadingUpdate()}initialize(){this.toggleButton?.addEventListener("click",()=>this.toggle())}toggle(){this.setOpenState(!this.outlineOpen)}close(){this.setOpenState(!1)}setOpenState(e){if(this.outlineOpen=e,this.panel?.classList.toggle("hidden",!this.outlineOpen),this.toggleButton?.classList.toggle("active",this.outlineOpen),this.outlineOpen){this.refresh();return}this.cleanup()}refresh(){if(!this.navigation)return;if(!this.outlineOpen){this.cleanup();return}let t=document.getElementById("previewContent")?.querySelectorAll("h1, h2, h3, h4, h5, h6")??[];if(t.length===0){this.navigation.innerHTML='<div class="outline-empty">No headings found</div>',this.cleanup();return}let i=Array.from(t).map((s,r)=>(s.id||(s.id=`heading-${r}-${s.textContent.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40)}`),{id:s.id,level:Number.parseInt(s.tagName[1],10),sourceLine:Number.parseInt(s.getAttribute("data-source-line")||"",10),text:s.textContent.trim()}));this.navigation.innerHTML=i.map(s=>`<button class="outline-item" data-level="${s.level}" data-target="${s.id}"${Number.isFinite(s.sourceLine)?` data-source-line="${s.sourceLine}"`:""} title="${s.text.replace(/"/g,""")}">${s.text}</button>`).join(""),this.navigation.querySelectorAll(".outline-item").forEach(s=>{s.addEventListener("click",()=>{let r=document.getElementById(s.dataset.target);this.pinnedHeadingId=s.dataset.target,this.notifyHeadingNavigation(r,s.dataset.target),this.scrollHeadingIntoView(r,{behavior:"auto"}),this.setActiveItem(s.dataset.target,{behavior:"auto"}),this.mobileBreakpointQuery.matches&&this.close()})}),this.observeHeadings(Array.from(t))}cleanup(){this.activeHeadingFrame&&(cancelAnimationFrame(this.activeHeadingFrame),this.activeHeadingFrame=null),this.previewContainer?.removeEventListener("scroll",this.handlePreviewScroll),this.headings=[],this.pinnedHeadingId=null}setActiveItem(e,{scrollIntoView:t=!0,behavior:i="smooth"}={}){this.activeHeadingId=e,this.navigation?.querySelectorAll(".outline-item").forEach(s=>{s.classList.toggle("active",s.dataset.target===e)}),t&&this.navigation?.querySelector(".outline-item.active")?.scrollIntoView({behavior:i,block:"nearest"})}observeHeadings(e){this.cleanup(),!(!this.previewContainer||e.length===0)&&(this.headings=e,this.previewContainer.addEventListener("scroll",this.handlePreviewScroll,{passive:!0}),this.updateActiveHeading())}scheduleActiveHeadingUpdate(){this.activeHeadingFrame||(this.activeHeadingFrame=requestAnimationFrame(()=>{this.activeHeadingFrame=null,this.updateActiveHeading()}))}updateActiveHeading(){if(!this.previewContainer||this.headings.length===0)return;let e=this.getPinnedHeading();if(e&&this.shouldKeepPinnedHeadingActive(e)){this.setActiveItem(e.id,{behavior:"auto",scrollIntoView:!0});return}this.pinnedHeadingId=null;let t=this.previewContainer.scrollTop,i=this.headings[0];for(let s of this.headings){if(this.getHeadingScrollTop(s)>t)break;i=s}this.setActiveItem(i.id,{behavior:"auto",scrollIntoView:!0})}getHeadingScrollTop(e){if(!this.previewContainer)return 0;let t=this.previewContainer.getBoundingClientRect(),i=e.getBoundingClientRect();return this.previewContainer.scrollTop+(i.top-t.top)}getPinnedHeading(){return this.pinnedHeadingId?this.headings.find(e=>e.id===this.pinnedHeadingId)??null:null}shouldKeepPinnedHeadingActive(e){if(!this.previewContainer||!e?.isConnected)return!1;let t=this.getHeadingScrollTop(e)-this.previewContainer.scrollTop,i=t+e.getBoundingClientRect().height,s=this.previewContainer.clientHeight*.45;return i>-48&&t<s}notifyHeadingNavigation(e,t){if(!e)return;let i=Number.parseInt(e.getAttribute("data-source-line")||"",10);this.onNavigateToHeading?.({headingId:t,sourceLine:Number.isFinite(i)?i:null})}scrollHeadingIntoView(e,{behavior:t="smooth"}={}){if(!e||!this.previewContainer)return;let i=this.previewContainer.getBoundingClientRect(),s=e.getBoundingClientRect(),r=this.previewContainer.scrollTop+(s.top-i.top);this.previewContainer.scrollTo({behavior:t,top:Math.max(r,0)})}};var Ci=.35,mn=120,pn=12,fn=2;function tt(n){return Math.max(n.scrollHeight-n.clientHeight,0)}function gn(n){return Math.max(n,0)}function vi(n){return Math.max(n.clientHeight*Ci,pn)}function wn(n){return(n?.scrollTop??0)<=fn}function yn(n,e){let t=n.getBoundingClientRect();return e.getBoundingClientRect().top-t.top+n.scrollTop}function vn(n){return!n.querySelector("[data-source-line]")}function bn(n){return typeof window.requestIdleCallback=="function"?window.requestIdleCallback(n,{timeout:500}):window.setTimeout(()=>{n({didTimeout:!1,timeRemaining:()=>0})},1)}function bi(n){if(n!==null){if(typeof window.cancelIdleCallback=="function"){window.cancelIdleCallback(n);return}window.clearTimeout(n)}}var it=class{constructor({getEditorLineNumber:e,onEditorScrollActivityChange:t,previewContainer:i,previewElement:s,scrollEditorToLine:r}){this.getEditorLineNumber=e,this.onEditorScrollActivityChange=t,this.previewContainer=i,this.previewElement=s,this.scrollEditorToLine=r,this.editorScroller=null,this.editorScrollActive=!1,this.editorScrollIdleTimer=null,this.lockedElements=new Set,this.pendingSync=null,this.frameId=null,this.previewBlocks=null,this.previewBlocksWarmId=null,this.previewBlocksReadyCallbacks=[],this.largeDocumentMode=!1,this.lastInteractionSource="editor",this.suspendedUntil=0,this.handleEditorScroll=()=>{if(!(!this.editorScroller||this.lockedElements.has(this.editorScroller)||this.isSuspended())){if(this.lastInteractionSource="editor",this.largeDocumentMode){this.setEditorScrollActive(!0),this.scheduleEditorScrollIdle(),this.scheduleSync(this.editorScroller,this.previewContainer,{preferApproximateMapping:!0});return}this.scheduleSync(this.editorScroller,this.previewContainer)}},this.handlePreviewScroll=()=>{!this.previewContainer||this.lockedElements.has(this.previewContainer)||this.isSuspended()||(this.lastInteractionSource="preview",this.scheduleSync(this.previewContainer,this.editorScroller))}}initialize(){this.previewContainer?.addEventListener("scroll",this.handlePreviewScroll,{passive:!0})}attachEditorScroller(e){this.editorScroller!==e&&(this.editorScroller?.removeEventListener("scroll",this.handleEditorScroll),this.editorScroller=e,this.editorScroller?.addEventListener("scroll",this.handleEditorScroll,{passive:!0}))}syncPreviewToEditor(){this.lastInteractionSource="editor",this.sync(this.editorScroller,this.previewContainer)}syncEditorToPreview(){this.lastInteractionSource="preview",this.sync(this.previewContainer,this.editorScroller)}destroy(){this.previewContainer?.removeEventListener("scroll",this.handlePreviewScroll),this.editorScroller?.removeEventListener("scroll",this.handleEditorScroll),this.editorScroller=null,clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=null,this.pendingSync=null,this.previewBlocks=null,bi(this.previewBlocksWarmId),this.previewBlocksWarmId=null,this.previewBlocksReadyCallbacks=[],this.lockedElements.clear(),this.editorScrollActive=!1,this.lastInteractionSource="editor",this.suspendedUntil=0,this.frameId&&(cancelAnimationFrame(this.frameId),this.frameId=null)}scheduleSync(e,t,{preferApproximateMapping:i=!1}={}){!e||!t||this.lockedElements.has(e)||this.isSuspended()||(this.pendingSync={preferApproximateMapping:i,source:e,target:t},!this.frameId&&(this.frameId=requestAnimationFrame(()=>{if(this.frameId=null,!this.pendingSync)return;let{preferApproximateMapping:s,source:r,target:a}=this.pendingSync;this.pendingSync=null,this.sync(r,a,{preferApproximateMapping:s})})))}invalidatePreviewBlocks(){this.previewBlocks=null,bi(this.previewBlocksWarmId),this.previewBlocksWarmId=null,this.previewBlocksReadyCallbacks=[]}setLargeDocumentMode(e){this.largeDocumentMode=!!e,this.largeDocumentMode||(clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=null,this.setEditorScrollActive(!1))}warmPreviewBlocks({onReady:e}={}){if(typeof e=="function"&&(this.previewBlocks?e(this.previewBlocks):this.previewBlocksReadyCallbacks.push(e)),!this.largeDocumentMode){this.previewBlocks||(this.previewBlocks=this.buildPreviewBlocks()),this.flushPreviewBlocksReadyCallbacks();return}this.previewBlocks||this.previewBlocksWarmId!==null||(this.previewBlocksWarmId=bn(()=>{this.previewBlocksWarmId=null,this.previewBlocks=this.buildPreviewBlocks(),this.flushPreviewBlocksReadyCallbacks()}))}realignAfterLayoutChange(){let e=()=>{if(this.lastInteractionSource==="preview"){this.syncEditorToPreview();return}this.syncPreviewToEditor()};if(this.largeDocumentMode&&!this.previewBlocks){this.warmPreviewBlocks({onReady:()=>e()});return}e()}suspendSync(e=250){this.suspendedUntil=performance.now()+e}isSuspended(){return performance.now()<this.suspendedUntil}flushPreviewBlocksReadyCallbacks(){if(this.previewBlocksReadyCallbacks.length===0)return;this.previewBlocksReadyCallbacks.splice(0).forEach(t=>{try{t(this.previewBlocks??[])}catch(i){console.warn("[scroll-sync] Preview block callback failed:",i)}})}setEditorScrollActive(e){this.editorScrollActive!==e&&(this.editorScrollActive=e,this.onEditorScrollActivityChange?.(e))}scheduleEditorScrollIdle(){clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=setTimeout(()=>{this.editorScrollIdleTimer=null,this.setEditorScrollActive(!1),this.syncPreviewToEditor()},mn)}sync(e,t,{preferApproximateMapping:i=!1}={}){if(!e||!t||this.lockedElements.has(e)||this.isSuspended())return;if(!i&&e===this.editorScroller&&t===this.previewContainer){let l=this.getPreviewScrollTopForEditorLine();if(l!==null){this.setScrollTop(t,l);return}}if(e===this.previewContainer&&t===this.editorScroller){let l=this.getEditorLineNumberForPreviewScroll();if(l!==null){this.lockedElements.add(t),this.scrollEditorToLine?.(l,Ci),requestAnimationFrame(()=>{this.lockedElements.delete(t)});return}}let s=tt(e),r=tt(t),a=s>0?e.scrollTop/s:0,o=r>0?r*a:0;this.setScrollTop(t,o)}setScrollTop(e,t){this.lockedElements.add(e),e.scrollTop=gn(t),requestAnimationFrame(()=>{this.lockedElements.delete(e)})}getPreviewScrollTopForEditorLine(){if(wn(this.editorScroller))return 0;let e=this.getEditorLineNumber?.();if(!Number.isFinite(e))return null;let t=this.getPreviewBlocks();if(t.length===0||!this.previewContainer)return null;let{block:i,index:s}=this.findBlockForLine(t,e),r=this.getPreviewSpan(t,s),a=Math.max(i.end-i.start,1),o=F((e-i.start)/a,0,1),l=tt(this.previewContainer),d=vi(this.previewContainer);return F(i.top+r*o-d,0,l)}getEditorLineNumberForPreviewScroll(){if(!this.previewContainer)return null;let e=this.getPreviewBlocks();if(e.length===0)return null;let t=this.previewContainer.scrollTop+vi(this.previewContainer),{block:i,index:s}=this.findBlockForScrollTop(e,t),r=this.getPreviewSpan(e,s),a=Math.max(i.end-i.start,1),o=r>0?F((t-i.top)/r,0,1):0;return Math.round(i.start+a*o)}getPreviewBlocks(){return this.previewBlocks?this.previewBlocks:!this.previewContainer||!this.previewElement?[]:this.largeDocumentMode?[]:(this.previewBlocks=this.buildPreviewBlocks(),this.previewBlocks)}buildPreviewBlocks(){let e=Array.from(this.previewElement.querySelectorAll("[data-source-line]")).map(s=>{let r=Number.parseInt(s.getAttribute("data-source-line")||"",10),a=Number.parseInt(s.getAttribute("data-source-line-end")||"",10);return Number.isFinite(r)?{element:s,end:Number.isFinite(a)?Math.max(a,r+1):r+1,start:r,top:yn(this.previewContainer,s)}:null}).filter(Boolean).sort((s,r)=>s.top-r.top||s.start-r.start||s.end-r.end),t=e.filter(s=>vn(s.element)),i=t.length>0?t:e;return i.filter((s,r)=>{let a=i[r-1];return!a||Math.abs(a.top-s.top)>1||a.start!==s.start||a.end!==s.end})}findBlockForLine(e,t){let i=null,s=-1;for(let a=0;a<e.length;a+=1){let o=e[a];if(t>=o.start&&t<o.end){if(!i){i=o,s=a;continue}let l=i.end-i.start,d=o.end-o.start;(d<l||d===l&&o.start>=i.start)&&(i=o,s=a)}}if(i)return{block:i,index:s};let r=0;for(let a=0;a<e.length&&!(e[a].start>t);a+=1)r=a;return{block:e[r],index:r}}findBlockForScrollTop(e,t){for(let s=0;s<e.length;s+=1){let r=this.getPreviewSpan(e,s)+e[s].top;if(t<r)return{block:e[s],index:s}}let i=e.length-1;return{block:e[i],index:i}}getPreviewSpan(e,t){if(!this.previewContainer)return 1;let i=e[t],s=e[t+1],r=i.element.getBoundingClientRect().height;if(!s){let a=tt(this.previewContainer);return Math.max(a-i.top+this.previewContainer.clientHeight,r,1)}return Math.max(s.top-i.top,r,1)}};var Cn='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>',En='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>',nt=class{constructor({storageKey:e="collabmd-theme",onChange:t}){this.storageKey=e,this.onChange=t,this.currentTheme="dark"}initialize(){this.currentTheme=this.readPreferredTheme(),this.applyTheme(),document.querySelectorAll("[data-theme-toggle]").forEach(e=>{e.addEventListener("click",()=>this.toggle())})}getTheme(){return this.currentTheme}toggle(){this.currentTheme=this.currentTheme==="dark"?"light":"dark",this.persistTheme(),this.applyTheme()}readPreferredTheme(){try{let e=window.localStorage.getItem(this.storageKey);if(e==="light"||e==="dark")return e}catch{}return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}persistTheme(){try{window.localStorage.setItem(this.storageKey,this.currentTheme)}catch{}}applyTheme(){document.documentElement.setAttribute("data-theme",this.currentTheme),this.updateToggleIcons(),this.onChange?.(this.currentTheme)}updateToggleIcons(){let e=this.currentTheme==="dark"?Cn:En;document.querySelectorAll("[data-theme-toggle]").forEach(t=>{t.innerHTML=e})}};var me=class{constructor(e){this.container=e}show(e,t=3e3){if(!this.container)return;let i=document.createElement("div");i.className="toast",i.textContent=e,this.container.appendChild(i),setTimeout(()=>{i.classList.add("leaving"),i.addEventListener("animationend",()=>i.remove(),{once:!0})},t)}};var Ei=16/9,Sn=240,xn=720,Ln=180;function kn(n){return Math.max(Ln,Math.min(xn,Math.ceil(n||Sn)))}var st=class{constructor({previewElement:e}){this.previewElement=e,this.embedEntries=new Map,this.overlayRoot=null}destroy(){this.embedEntries.forEach(e=>{e.hydrateFrameId&&(cancelAnimationFrame(e.hydrateFrameId),e.hydrateFrameId=null),e.wrapper?.remove(),e.placeholder=null}),this.embedEntries.clear(),this.overlayRoot?.remove(),this.overlayRoot=null}detachForCommit(){this.embedEntries.forEach(e=>{e.placeholder=null})}reconcileEmbeds(e=this.previewElement){if(this.previewElement=e,!e)return;let t=Array.from(e.querySelectorAll(".video-embed-placeholder[data-video-embed-key]")).map(r=>({filePath:r.dataset.videoEmbedSource,key:r.dataset.videoEmbedKey,label:r.dataset.videoEmbedLabel||"Embedded video",placeholder:r,source:r.dataset.videoEmbedSource||"",kind:r.dataset.videoEmbedKind||"",url:r.dataset.videoEmbedUrl||"",mimeType:r.dataset.videoEmbedMimeType||""})),{nextEntries:i,removedEntries:s}=qe(this.embedEntries,t);s.forEach(r=>this._destroyEntry(r)),this.embedEntries=i,this.embedEntries.forEach(r=>{r.aspectRatio=r.aspectRatio||Ei,r.kind=r.placeholder?.dataset.videoEmbedKind||r.kind,r.label=r.placeholder?.dataset.videoEmbedLabel||r.label,r.mimeType=r.placeholder?.dataset.videoEmbedMimeType||r.mimeType,r.source=r.placeholder?.dataset.videoEmbedSource||r.source,r.url=r.placeholder?.dataset.videoEmbedUrl||r.url,r.wrapper||this._createEmbed(r),this._attachWrapper(r)}),this.syncLayout(),this.embedEntries.size===0&&(this.overlayRoot?.remove(),this.overlayRoot=null)}syncLayout(){this.embedEntries.forEach(e=>{e.wrapper&&this._syncEntryLayout(e)})}_destroyEntry(e){e.hydrateFrameId&&(cancelAnimationFrame(e.hydrateFrameId),e.hydrateFrameId=null),e.wrapper?.remove(),e.placeholder=null}_createEmbed(e){let t=document.createElement("div");if(t.className=`video-embed video-embed-shell diagram-preview-shell is-${e.kind}`,e.kind==="youtube"){let i=document.createElement("div");i.className="video-embed-frame video-embed-frame-youtube";let s=document.createElement("iframe");s.className="video-embed-iframe",s.title=e.label||"Embedded YouTube video",s.referrerPolicy="strict-origin-when-cross-origin",s.allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",s.allowFullscreen=!0,i.appendChild(s),t.appendChild(i),e.mediaElement=s}else{let i=document.createElement("video");i.className="video-embed-player",i.controls=!0,i.preload="metadata",i.playsInline=!0,e.label&&(i.title=e.label,i.setAttribute("aria-label",e.label));let s=document.createElement("source");s.src=e.url,e.mimeType&&(s.type=e.mimeType),i.appendChild(s),i.addEventListener("loadedmetadata",()=>{Number.isFinite(i.videoWidth)&&Number.isFinite(i.videoHeight)&&i.videoWidth>0&&i.videoHeight>0&&(e.aspectRatio=i.videoWidth/i.videoHeight,this._syncEntryLayout(e))}),t.appendChild(i),e.mediaElement=i}e.wrapper=t}_attachWrapper(e){let t=e.placeholder?.isConnected?e.placeholder:this.previewElement?.querySelector(`.video-embed-placeholder[data-video-embed-key="${e.key}"]`);if(!t)return;e.placeholder=t,t.classList.add("is-hydrated"),t.dataset.videoEmbedHydrated="true",t.style.pointerEvents="none";let i=this._ensureOverlayRoot();e.wrapper?.parentElement!==i&&i.appendChild(e.wrapper)}_syncEntryLayout(e){let t=e.placeholder?.isConnected?e.placeholder:this.previewElement?.querySelector(`.video-embed-placeholder[data-video-embed-key="${e.key}"]`);if(!t||!e.wrapper)return;e.placeholder=t;let i=t.offsetWidth||t.clientWidth||0;if(i<=0&&e.inlineHeightPx)return;let s=kn(i>0?i/(e.aspectRatio||Ei):e.inlineHeightPx);e.inlineHeightPx=s,Q(t,"height",`${s}px`),Q(e.wrapper,"position","absolute"),Q(e.wrapper,"top",`${t.offsetTop}px`),Q(e.wrapper,"left",`${t.offsetLeft}px`),Q(e.wrapper,"width",`${t.offsetWidth}px`),Q(e.wrapper,"height",`${s}px`),Q(e.wrapper,"margin","0"),Q(e.wrapper,"pointerEvents","auto"),this._hydrateEntryMedia(e)}_ensureOverlayRoot(){let e=this.previewElement?.querySelector('[data-video-overlay-root="true"]');return e||(e=document.createElement("div"),e.dataset.videoOverlayRoot="true",e.className="video-embed-overlay-root",this.previewElement?.appendChild(e)),this.overlayRoot=e,e}_hydrateEntryMedia(e){if(e.kind!=="youtube")return;let t=e.mediaElement;t instanceof HTMLIFrameElement&&(!e.url||t.getAttribute("src")===e.url||e.wrapper?.offsetWidth<=0||e.wrapper?.offsetHeight<=0||e.hydrateFrameId||(e.hydrateFrameId=requestAnimationFrame(()=>{if(e.hydrateFrameId=null,!e.url||t.getAttribute("src")===e.url)return;let i=Math.round(e.wrapper?.offsetWidth||0),s=Math.round(e.wrapper?.offsetHeight||0);i<=0||s<=0||(t.width=String(i),t.height=String(s),t.src=e.url)})))}};function Q(n,e,t){!n||n.style[e]===t||(n.style[e]=t)}var Fn=Object.freeze({chat:Qt,comments:Zt,git:Yt,presence:Xt,ui:ei,workspace:ti});function In(n){let e={};Object.entries(Fn).forEach(([t,i])=>{Object.entries(i).forEach(([s,r])=>{if(typeof r=="function"){if(Object.hasOwn(e,s))throw new Error(`CollabMdAppShell feature method "${s}" is declared by both "${e[s]}" and "${t}".`);if(s in n)throw new Error(`CollabMdAppShell feature method "${s}" conflicts with an existing app shell member.`);Object.defineProperty(n,s,{configurable:!0,enumerable:!1,value:r.bind(n),writable:!1}),e[s]=t}})}),Object.defineProperty(n,"featureMethodOwners",{configurable:!1,enumerable:!1,value:Object.freeze(e),writable:!1})}var rt=class{constructor(){In(this),this.elements=jt(document),this.runtimeConfig=ye(),this.stateStore=new Me,this.navigation=new Be,this.preferences=new He({chatNotificationsKey:"collabmd-chat-notifications-enabled",lineWrappingKey:"collabmd-editor-line-wrap",sidebarVisibleKey:"collabmd-sidebar-visible",userNameKey:"collabmd-user-name"}),this.notifications=new Ne,this.vaultApiClient=de,this._session=null,this._hasPromptedForDisplayName=!1,this._backlinkRefreshTimer=null,this._pendingPreviewLayoutSync=!1,this._previewHydrationPaused=!1,this._previewLayoutResizeObserver=null,this._previewLayoutSyncTimer=null,this.pendingGitResetPath=null,this.chatTimeFormatter=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"2-digit"}),this.chatNotificationsEnabled=this.preferences.getChatNotificationsEnabled(),this.chatNotificationPermission=this.notifications.getPermission(),this.lobbyChatMessageMaxLength=mt,this.quickSwitcher=null,this.quickSwitcherModulePromise=null,this.fileExplorerReadyPromise=Promise.resolve(),this.mobileBreakpointQuery=window.matchMedia("(max-width: 768px)"),this.lobby=new Re({preferredUserName:this.getStoredUserName(),onChange:e=>this.updateGlobalUsers(e),onChatChange:(e,t)=>this.updateChatMessages(e,t),onWorkspaceEvent:e=>{this.handleIncomingWorkspaceEvent(e)}}),this.toastController=new me(this.elements.toastContainer),this.chatToastController=new me(this.elements.chatToastContainer),this.fileExplorer=new Qe({onFileDelete:()=>this.navigation.navigateToFile(null),onFileSelect:e=>this.handleFileSelection(e,{closeSidebarOnMobile:!0}),toastController:this.toastController}),this.gitPanel=new Ye({enabled:this.runtimeConfig.gitEnabled!==!1,onCommitStaged:()=>this.openGitCommitDialog(),onPullBranch:()=>this.pullGitBranch(),onPushBranch:()=>this.pushGitBranch(),onRepoChange:(e,t)=>this.handleGitRepoChange(e,t),onResetFile:(e,{scope:t})=>this.openGitResetDialog(e,{scope:t}),onSelectDiff:(e,{scope:t})=>this.handleGitDiffSelection(e,{closeSidebarOnMobile:!0,scope:t}),onStageFile:(e,{scope:t})=>this.stageGitFile(e,{scope:t}),onUnstageFile:(e,{scope:t})=>this.unstageGitFile(e,{scope:t}),onViewAllDiff:()=>this.handleGitDiffSelection(null,{closeSidebarOnMobile:!0,scope:"all"}),searchInput:this.elements.gitSearchInput,toastController:this.toastController}),this.outlineController=new et({mobileBreakpointQuery:this.mobileBreakpointQuery,onNavigateToHeading:({sourceLine:e})=>{Number.isFinite(e)&&(this.scrollSyncController.suspendSync(250),this.session?.scrollToLine(e,0))}}),this.videoEmbed=new st({previewElement:this.elements.previewContent}),this.previewRenderer=new xe({getContent:()=>this.getPreviewSource(),getFileList:()=>this.fileExplorer.flatFiles,onAfterRenderCommit:(e,t)=>{this.videoEmbed.reconcileEmbeds(this.elements.previewContent),this.videoEmbed.syncLayout(),this.excalidrawEmbed.reconcileEmbeds(this.elements.previewContent,{isLargeDocument:t.isLargeDocument}),this.excalidrawEmbed.syncLayout(),this.scrollSyncController.setLargeDocumentMode(t.isLargeDocument),this.schedulePreviewLayoutSync({delayMs:0}),this.refreshCommentUiLayout()},onBeforeRenderCommit:()=>{this.videoEmbed.detachForCommit(),this.excalidrawEmbed.detachForCommit()},onRenderComplete:()=>{this.videoEmbed.syncLayout(),this.excalidrawEmbed.syncLayout(),this.schedulePreviewLayoutSync({delayMs:0}),this.refreshCommentUiLayout()},outlineController:this.outlineController,previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent}),this.themeController=new nt({onChange:e=>this.handleThemeChange(e)}),this.layoutController=new Xe({mobileBreakpointQuery:this.mobileBreakpointQuery,onMeasureEditor:()=>this.session?.requestMeasure()}),this.scrollSyncController=new it({getEditorLineNumber:()=>this.session?.getTopVisibleLineNumber(.35)??1,onEditorScrollActivityChange:e=>this.handleEditorScrollActivityChange(e),previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,scrollEditorToLine:(e,t)=>this.session?.scrollToLine(e,t)}),this.backlinksPanel=new ze({onFileSelect:e=>this.handleFileSelection(e,{closeSidebarOnMobile:!0}),panelElement:this.elements.backlinksPanel}),this.excalidrawEmbed=new Ve({getLocalUser:()=>this.lobby.getLocalUser(),getTheme:()=>this.themeController.getTheme(),onOpenFile:e=>e&&this.navigation.navigateToFile(e),previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,toastController:this.toastController}),this.commentUi=new Oe({commentSelectionButton:this.elements.commentSelectionButton,commentsDrawer:this.elements.commentsDrawer,commentsDrawerEmpty:this.elements.commentsDrawerEmpty,commentsDrawerList:this.elements.commentsDrawerList,commentsToggleButton:this.elements.commentsToggleButton,editorContainer:this.elements.editorContainer,previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,onCreateThread:({anchor:e,body:t})=>this.session?.createCommentThread({anchor:e,body:t}),onNavigateToLine:e=>{this.scrollSyncController.suspendSync(250),this.session?.scrollToLine(e,.2)},onReplyToThread:(e,t)=>this.session?.replyToCommentThread(e,t),onResolveThread:e=>this.session?.deleteCommentThread(e)}),this.workspacePreviewController=new Ie({backlinksPanel:this.backlinksPanel,elements:this.elements,excalidrawEmbed:this.excalidrawEmbed,getDisplayName:e=>this.getDisplayName(e),getSession:()=>this.session,isExcalidrawFile:e=>this.isExcalidrawFile(e),isMermaidFile:e=>this.isMermaidFile(e),isPlantUmlFile:e=>this.isPlantUmlFile(e),layoutController:this.layoutController,outlineController:this.outlineController,previewRenderer:this.previewRenderer,schedulePreviewLayoutSync:e=>this.schedulePreviewLayoutSync(e),scrollSyncController:this.scrollSyncController,videoEmbed:this.videoEmbed}),this.wikiLinkFileController=new Fe({getFileList:()=>this.fileExplorer.flatFiles,navigation:this.navigation,refreshExplorer:()=>this.fileExplorer.refresh(),toastController:this.toastController,vaultApiClient:this.vaultApiClient}),this.gitDiffView=new Ze({onCommitStaged:()=>this.openGitCommitDialog(),onOpenFile:e=>e&&this.navigation.navigateToFile(e),onStageFile:(e,{scope:t})=>this.stageGitFile(e,{scope:t}),onUnstageFile:(e,{scope:t})=>this.unstageGitFile(e,{scope:t}),toastController:this.toastController}),this.tabActivityLock=new Ue({onActivated:({takeover:e})=>this.handleTabActivated({takeover:e}),onBlocked:()=>this.handleTabBlocked({reason:"active-elsewhere"}),onStolen:()=>this.handleTabBlocked({reason:"taken-over"})}),this.workspaceCoordinator=new Ae({attachEditorScroller:e=>this.scrollSyncController.attachEditorScroller(e),beginDocumentLoad:()=>this.previewRenderer.beginDocumentLoad(),cleanupAfterSessionDestroy:()=>{this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.outlineController.cleanup(),this.followedCursorSignature="",clearTimeout(this._backlinkRefreshTimer)},createEditorSession:(e,t)=>new e({editorContainer:this.elements.editorContainer,getFileList:t.getFileList,initialTheme:t.theme,lineInfoElement:this.elements.lineInfo,lineWrappingEnabled:t.lineWrappingEnabled,localUser:t.localUser,onAwarenessChange:t.onAwarenessChange,onCommentsChange:t.onCommentsChange,onConnectionChange:t.onConnectionChange,onContentChange:t.onContentChange,onSelectionChange:t.onSelectionChange,preferredUserName:t.preferredUserName}),getDisplayName:e=>this.getDisplayName(e),getFileList:()=>this.fileExplorer.flatFiles,getLineWrappingEnabled:()=>this.getStoredLineWrapping(),getLocalUser:()=>this.lobby.getLocalUser(),getStoredUserName:()=>this.getStoredUserName(),getTheme:()=>this.themeController.getTheme(),isExcalidrawFile:e=>this.isExcalidrawFile(e),isMermaidFile:e=>this.isMermaidFile(e),isPlantUmlFile:e=>this.isPlantUmlFile(e),isTabActive:()=>this.isTabActive,loadEditorSessionClass:()=>this.loadEditorSessionClass(),loadBacklinks:e=>this.backlinksPanel.load(e),onBeforeFileOpen:()=>{this.session=null,this.commentUi.attachSession(null),this.layoutController.reset(),this.resetPreviewMode(),this.elements.emptyState?.classList.add("hidden"),this.elements.editorPage?.classList.remove("hidden"),this.elements.diffPage?.classList.add("hidden"),this.clearInitialFileBootstrap()},onConnectionChange:e=>this.handleConnectionChange(e),onContentChange:({isMermaid:e,isPlantUml:t})=>{this.handleCommentEditorContentChange(),this.previewRenderer.queueRender(),!e&&!t&&this.scheduleBacklinkRefresh()},onCommentsChange:e=>this.handleCommentThreadsChange(e),onFileAwarenessChange:e=>this.updateFileAwareness(e),onFileOpenError:()=>{this.showEditorLoadError(),this.syncWrapToggle(),this.toastController.show("Failed to initialize editor")},onFileOpenReady:()=>{this.hideEditorLoading()},onSelectionChange:e=>this.handleCommentSelectionChange(e),onSessionAssigned:e=>{this.session=e,this.commentUi.attachSession(e)},onRenderExcalidrawPreview:e=>this.renderExcalidrawFilePreview(e),onSyncWrapToggle:()=>this.syncWrapToggle(),onUpdateActiveFile:e=>this.fileExplorer.setActiveFile(e),onUpdateCurrentFile:e=>{this.currentFilePath=e},onUpdateLobbyCurrentFile:e=>this.lobby.setCurrentFile(e),onUpdateVisibleChrome:(e,{displayName:t})=>{this.syncFileChrome(e),this.syncCommentChrome(e),this.elements.activeFileName&&(this.elements.activeFileName.textContent=t)},onViewModeReset:()=>this.resetPreviewMode(),renderPresence:()=>this.renderPresence(),scrollContainerForSession:e=>e.getScrollContainer(),showEditorLoading:()=>this.showEditorLoading(),stateStore:this.stateStore}),this.workspaceRouteController=new Le({backlinksPanel:this.backlinksPanel,clearInitialFileBootstrap:()=>this.clearInitialFileBootstrap(),closeSidebarOnMobile:()=>this.closeSidebarOnMobile(),elements:this.elements,excalidrawEmbed:this.excalidrawEmbed,fileExplorer:this.fileExplorer,getIsTabActive:()=>this.isTabActive,getSessionLoadToken:()=>this.sessionLoadToken,gitDiffView:this.gitDiffView,gitPanel:this.gitPanel,layoutController:this.layoutController,lobby:this.lobby,navigation:this.navigation,previewRenderer:this.previewRenderer,renderAvatars:()=>this.renderAvatars(),renderPresence:()=>this.renderPresence(),resetPreviewMode:()=>this.resetPreviewMode(),scrollSyncController:this.scrollSyncController,setCurrentFilePath:e=>{this.currentFilePath=e,e||(this.commentUi.setCurrentFile(null,{supported:!1}),this.handleCommentThreadsChange([]),this.handleCommentSelectionChange(null))},setSession:e=>{this.session=e,this.commentUi.attachSession(e)},setSessionLoadToken:e=>{this.sessionLoadToken=e},setSidebarTab:e=>this.setSidebarTab(e),showGitDiff:e=>this.showGitDiff(e),syncMainChrome:e=>this.syncMainChrome(e),videoEmbed:this.videoEmbed,workspaceCoordinator:this.workspaceCoordinator}),this.chatNotificationPermission!=="granted"&&(this.chatNotificationsEnabled=!1)}get session(){return this._session}set session(e){this._session=e}get currentFilePath(){return this.stateStore.get("currentFilePath")}set currentFilePath(e){this.stateStore.set("currentFilePath",e)}get globalUsers(){return this.stateStore.get("globalUsers")}set globalUsers(e){this.stateStore.set("globalUsers",e)}get connectionState(){return this.stateStore.get("connectionState")}set connectionState(e){this.stateStore.set("connectionState",e)}get sessionLoadToken(){return this.stateStore.get("sessionLoadToken")}set sessionLoadToken(e){this.stateStore.set("sessionLoadToken",e)}get connectionHelpShown(){return this.stateStore.get("connectionHelpShown")}set connectionHelpShown(e){this.stateStore.set("connectionHelpShown",e)}get chatMessages(){return this.stateStore.get("chatMessages")}set chatMessages(e){this.stateStore.set("chatMessages",e)}get chatMessageIds(){return this.stateStore.get("chatMessageIds")}set chatMessageIds(e){this.stateStore.set("chatMessageIds",e)}get chatUnreadCount(){return this.stateStore.get("chatUnreadCount")}set chatUnreadCount(e){this.stateStore.set("chatUnreadCount",e)}get chatIsOpen(){return this.stateStore.get("chatIsOpen")}set chatIsOpen(e){this.stateStore.set("chatIsOpen",e)}get chatInitialSyncComplete(){return this.stateStore.get("chatInitialSyncComplete")}set chatInitialSyncComplete(e){this.stateStore.set("chatInitialSyncComplete",e)}get isTabActive(){return this.stateStore.get("isTabActive")}set isTabActive(e){this.stateStore.set("isTabActive",e)}get fileExplorerReady(){return this.stateStore.get("fileExplorerReady")}set fileExplorerReady(e){this.stateStore.set("fileExplorerReady",e)}get gitRepoAvailable(){return this.stateStore.get("gitRepoAvailable")}set gitRepoAvailable(e){this.stateStore.set("gitRepoAvailable",e)}get activeSidebarTab(){return this.stateStore.get("activeSidebarTab")}set activeSidebarTab(e){this.stateStore.set("activeSidebarTab",e)}get followedUserClientId(){return this.stateStore.get("followedUserClientId")}set followedUserClientId(e){this.stateStore.set("followedUserClientId",e)}get followedCursorSignature(){return this.stateStore.get("followedCursorSignature")}set followedCursorSignature(e){this.stateStore.set("followedCursorSignature",e)}loadEditorSessionClass(){return this._editorSessionModulePromise||(this._editorSessionModulePromise=import("./chunks/editor-session-IHFTYG5D.js").then(e=>e.EditorSession)),this._editorSessionModulePromise}scheduleEditorSessionPrewarm({timeout:e=1500}={}){if(this._editorSessionModulePromise||this._editorSessionPrewarmHandle)return;let t=()=>{this._editorSessionPrewarmHandle=null,this.loadEditorSessionClass()};if(typeof window.requestIdleCallback=="function"){this._editorSessionPrewarmHandle=window.requestIdleCallback(t,{timeout:e});return}this._editorSessionPrewarmHandle=window.setTimeout(t,0)}async ensureQuickSwitcher(){if(this.quickSwitcher)return this.quickSwitcher;this.quickSwitcherModulePromise||(this.quickSwitcherModulePromise=import("./chunks/quick-switcher-controller-JYDIJVAJ.js").then(t=>t.QuickSwitcherController));let e=await this.quickSwitcherModulePromise;return this.quickSwitcher||(this.quickSwitcher=new e({getFileList:()=>this.fileExplorer.flatFiles,onFileSelect:t=>this.handleFileSelection(t,{closeSidebarOnMobile:!0})})),this.quickSwitcher}async toggleQuickSwitcher(){(await this.ensureQuickSwitcher()).toggle()}};var Tn={enabled:!1,implemented:!0,passwordLabel:"Password",requiresLogin:!1,sessionEndpoint:"/api/auth/session",statusEndpoint:"/api/auth/status",strategy:"none",submitLabel:"Continue"},Si=!1;function Pn(){if(Si||!document.head)return;let n=document.createElement("style");n.textContent=`
|
|
251
|
+
.auth-gate-overlay {
|
|
252
|
+
position: fixed;
|
|
253
|
+
inset: 0;
|
|
254
|
+
z-index: 5000;
|
|
255
|
+
display: flex;
|
|
256
|
+
align-items: center;
|
|
257
|
+
justify-content: center;
|
|
258
|
+
padding: 24px;
|
|
259
|
+
background:
|
|
260
|
+
radial-gradient(circle at top, rgba(59, 130, 246, 0.18), transparent 42%),
|
|
261
|
+
rgba(10, 15, 29, 0.74);
|
|
262
|
+
backdrop-filter: blur(14px);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.auth-gate-card {
|
|
266
|
+
width: min(100%, 420px);
|
|
267
|
+
padding: 28px;
|
|
268
|
+
border-radius: 18px;
|
|
269
|
+
border: 1px solid rgba(148, 163, 184, 0.24);
|
|
270
|
+
background: rgba(15, 23, 42, 0.94);
|
|
271
|
+
color: #e2e8f0;
|
|
272
|
+
box-shadow: 0 24px 80px rgba(15, 23, 42, 0.36);
|
|
273
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.auth-gate-card h1 {
|
|
277
|
+
margin: 0 0 10px;
|
|
278
|
+
font-size: 1.35rem;
|
|
279
|
+
line-height: 1.2;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.auth-gate-card p {
|
|
283
|
+
margin: 0 0 18px;
|
|
284
|
+
color: #cbd5e1;
|
|
285
|
+
line-height: 1.5;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.auth-gate-form {
|
|
289
|
+
display: grid;
|
|
290
|
+
gap: 12px;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.auth-gate-label {
|
|
294
|
+
display: grid;
|
|
295
|
+
gap: 8px;
|
|
296
|
+
font-size: 0.92rem;
|
|
297
|
+
color: #cbd5e1;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.auth-gate-input {
|
|
301
|
+
width: 100%;
|
|
302
|
+
padding: 12px 14px;
|
|
303
|
+
border: 1px solid rgba(148, 163, 184, 0.28);
|
|
304
|
+
border-radius: 12px;
|
|
305
|
+
background: rgba(15, 23, 42, 0.72);
|
|
306
|
+
color: inherit;
|
|
307
|
+
font: inherit;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.auth-gate-input:focus {
|
|
311
|
+
outline: 2px solid rgba(59, 130, 246, 0.5);
|
|
312
|
+
outline-offset: 2px;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.auth-gate-actions {
|
|
316
|
+
display: flex;
|
|
317
|
+
align-items: center;
|
|
318
|
+
justify-content: space-between;
|
|
319
|
+
gap: 12px;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.auth-gate-button,
|
|
323
|
+
.auth-gate-secondary-button {
|
|
324
|
+
border: 0;
|
|
325
|
+
border-radius: 999px;
|
|
326
|
+
font: inherit;
|
|
327
|
+
cursor: pointer;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.auth-gate-button {
|
|
331
|
+
padding: 11px 16px;
|
|
332
|
+
background: linear-gradient(135deg, #0f766e, #0284c7);
|
|
333
|
+
color: #f8fafc;
|
|
334
|
+
font-weight: 600;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.auth-gate-secondary-button {
|
|
338
|
+
padding: 10px 0;
|
|
339
|
+
background: transparent;
|
|
340
|
+
color: #93c5fd;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.auth-gate-button[disabled],
|
|
344
|
+
.auth-gate-secondary-button[disabled] {
|
|
345
|
+
opacity: 0.7;
|
|
346
|
+
cursor: wait;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.auth-gate-error {
|
|
350
|
+
min-height: 1.25rem;
|
|
351
|
+
color: #fca5a5;
|
|
352
|
+
font-size: 0.92rem;
|
|
353
|
+
}
|
|
354
|
+
`,document.head.append(n),Si=!0}function An(){return{...Tn,...ye().auth??{}}}function ki(){let n=window.location.hash.startsWith("#")?window.location.hash.slice(1):window.location.hash;return new URLSearchParams(n)}function Mn(){return ki().get("auth_password")||""}function xi(){let n=ki();if(!n.has("auth_password"))return;n.delete("auth_password");let e=n.toString(),t=`${window.location.pathname}${window.location.search}${e?`#${e}`:""}`;window.history.replaceState(null,"",t)}async function Rn(n){let e=await fetch(n.statusEndpoint,{headers:{Accept:"application/json"}}),t=await e.json().catch(()=>({}));if(!e.ok)throw new Error(t.error||"Failed to read auth status");return t}async function Li(n,e){let t=await fetch(n.sessionEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:e})}),i=await t.json().catch(()=>({}));if(!t.ok)throw new Error(i.error||"Authentication failed");return i}function Bn(){Pn();let n=document.createElement("div");n.className="auth-gate-overlay";let e=document.createElement("section");return e.className="auth-gate-card",n.append(e),{card:e,overlay:n}}function yt(n,{title:e,body:t,secondaryActionLabel:i="",onSecondaryAction:s=null}){n.replaceChildren();let r=document.createElement("h1");r.textContent=e;let a=document.createElement("p");if(a.textContent=t,n.append(r,a),i&&typeof s=="function"){let o=document.createElement("button");o.className="auth-gate-secondary-button",o.type="button",o.textContent=i,o.addEventListener("click",()=>{s()}),n.append(o)}}function Nn(n,e,{onSubmit:t,onRetryStatus:i}){n.replaceChildren();let s=document.createElement("h1");s.textContent="Authentication required";let r=document.createElement("p");r.textContent="Enter the host password to join this shared session.";let a=document.createElement("form");a.className="auth-gate-form";let o=document.createElement("label");o.className="auth-gate-label",o.textContent=e.passwordLabel;let l=document.createElement("input");l.className="auth-gate-input",l.type="password",l.name="password",l.autocomplete="current-password",l.required=!0;let d=document.createElement("div");d.className="auth-gate-error";let c=document.createElement("div");c.className="auth-gate-actions";let p=document.createElement("button");p.className="auth-gate-secondary-button",p.type="button",p.textContent="Retry status";let f=document.createElement("button");f.className="auth-gate-button",f.type="submit",f.textContent=e.submitLabel,c.append(p,f),o.append(l),a.append(s,r,o,d,c),n.append(a),p.addEventListener("click",()=>{i()}),a.addEventListener("submit",h=>{h.preventDefault();let v=l.value;l.disabled=!0,f.disabled=!0,p.disabled=!0,d.textContent="",t(v).catch(y=>{d.textContent=y instanceof Error?y.message:"Authentication failed",l.disabled=!1,f.disabled=!1,p.disabled=!1,l.select(),l.focus()})}),queueMicrotask(()=>{l.focus()})}async function Fi(){let n=An();if(!n.enabled||n.strategy==="none")return{authenticated:!0,auth:n};let{card:e,overlay:t}=Bn();return document.body.append(t),new Promise(i=>{let s=()=>{xi(),t.remove(),i({authenticated:!0,auth:n})},r=async()=>{yt(e,{body:"Checking access to this session\u2026",title:"CollabMD"});try{if((await Rn(n)).authenticated){s();return}}catch(a){yt(e,{body:a instanceof Error?a.message:"Failed to contact the auth service.",secondaryActionLabel:"Retry",title:"Cannot verify access",onSecondaryAction:r});return}if(n.strategy==="password"){let a=Mn();if(a)try{xi(),await Li(n,a),s();return}catch{}Nn(e,n,{onRetryStatus:r,onSubmit:async o=>{await Li(n,o),s()}});return}yt(e,{body:n.strategy==="oidc"?"OIDC authentication is configured but not implemented in this build yet.":"This authentication strategy is not available.",secondaryActionLabel:"Retry status",title:"Authentication unavailable",onSecondaryAction:r})};r()})}async function Ii(){await Fi(),new rt().initialize()}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{Ii()},{once:!0}):Ii();
|