termdock 1.4.327 → 1.4.328
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/dist/client/assets/{App-C0c83Pxp.js → App-xr2R4dST.js} +6 -6
- package/dist/client/assets/App-xr2R4dST.js.br +0 -0
- package/dist/client/assets/App-xr2R4dST.js.gz +0 -0
- package/dist/client/assets/{ArchitecturePanel-znWmrZsF.js → ArchitecturePanel-XprzcGMT.js} +2 -2
- package/dist/client/assets/ArchitecturePanel-XprzcGMT.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-XprzcGMT.js.gz +0 -0
- package/dist/client/assets/{ChangeWalkthroughPanel-Bt4fjEoD.js → ChangeWalkthroughPanel-g83lCwJi.js} +1 -1
- package/dist/client/assets/ChangeWalkthroughPanel-g83lCwJi.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-g83lCwJi.js.gz +0 -0
- package/dist/client/assets/{CollaborationMainWorkspace-0s90d39f.js → CollaborationMainWorkspace-BbkFTnw1.js} +1 -1
- package/dist/client/assets/CollaborationMainWorkspace-BbkFTnw1.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-BbkFTnw1.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-C8Nrrlcz.js +2 -0
- package/dist/client/assets/ComputerControlView-yBUQcmwF.js +6 -0
- package/dist/client/assets/ComputerControlView-yBUQcmwF.js.br +0 -0
- package/dist/client/assets/ComputerControlView-yBUQcmwF.js.gz +0 -0
- package/dist/client/assets/{DagPlayground-311LPbK_.js → DagPlayground--KDWJkVL.js} +1 -1
- package/dist/client/assets/DagPlayground--KDWJkVL.js.br +0 -0
- package/dist/client/assets/DagPlayground--KDWJkVL.js.gz +0 -0
- package/dist/client/assets/{DiffLab-CHZ0EL2E.js → DiffLab-BAyGlKKp.js} +1 -1
- package/dist/client/assets/DiffLab-BAyGlKKp.js.br +0 -0
- package/dist/client/assets/DiffLab-BAyGlKKp.js.gz +0 -0
- package/dist/client/assets/{DiffReview-BA7zArOA.js → DiffReview-CLKpyDPZ.js} +1 -1
- package/dist/client/assets/DiffReview-CLKpyDPZ.js.br +0 -0
- package/dist/client/assets/DiffReview-CLKpyDPZ.js.gz +0 -0
- package/dist/client/assets/{DiffReviewLab-C_6SxWtH.js → DiffReviewLab-BoFElesI.js} +1 -1
- package/dist/client/assets/DiffReviewLab-BoFElesI.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-BoFElesI.js.gz +0 -0
- package/dist/client/assets/{DiffViewer-B0YoRCEi.js → DiffViewer-DDiASWHf.js} +1 -1
- package/dist/client/assets/DiffViewer-DDiASWHf.js.br +0 -0
- package/dist/client/assets/DiffViewer-DDiASWHf.js.gz +0 -0
- package/dist/client/assets/{ModelPreview-BboTxu4_.js → ModelPreview-PJWJT35T.js} +1 -1
- package/dist/client/assets/ModelPreview-PJWJT35T.js.br +0 -0
- package/dist/client/assets/ModelPreview-PJWJT35T.js.gz +0 -0
- package/dist/client/assets/{RightSidebar-TFRZlsFX.js → RightSidebar-CfOJHcXO.js} +3 -3
- package/dist/client/assets/RightSidebar-CfOJHcXO.js.br +0 -0
- package/dist/client/assets/RightSidebar-CfOJHcXO.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-BK2-PKkq.js → abnfDiagram-VCTEODGH-CwEvSK80.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-CwEvSK80.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-CwEvSK80.js.gz +0 -0
- package/dist/client/assets/{app-D2yRvfNE.js → app-DNnVU3VK.js} +10 -10
- package/dist/client/assets/app-DNnVU3VK.js.br +0 -0
- package/dist/client/assets/app-DNnVU3VK.js.gz +0 -0
- package/dist/client/assets/{arc-DqI6rAeJ.js → arc-Ctz1KMpY.js} +1 -1
- package/dist/client/assets/arc-Ctz1KMpY.js.br +0 -0
- package/dist/client/assets/arc-Ctz1KMpY.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-CZBYAIxt.js → architectureDiagram-5GKGNRK7-DJSgVQQQ.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DJSgVQQQ.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DJSgVQQQ.js.gz +0 -0
- package/dist/client/assets/{blockDiagram-I7D4REHJ-BAZ4LopQ.js → blockDiagram-I7D4REHJ-N_yr-Q8w.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-N_yr-Q8w.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-N_yr-Q8w.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-Boh80g9D.js → c4Diagram-7LVT6UL2-DVQnawpY.js} +1 -1
- package/dist/client/assets/c4Diagram-7LVT6UL2-DVQnawpY.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DVQnawpY.js.gz +0 -0
- package/dist/client/assets/channel-b8iCTsm_.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-CQtYmkXv.js → chunk-2Q5K7J3B-BXZwjzSA.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-lfjEsOLd.js → chunk-5VM5RSS4-mKa-FMDa.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-B3iWUfsu.js → chunk-F27PBJKO-BW5JuQIW.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-BW5JuQIW.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-BW5JuQIW.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-BV8W69Xy.js → chunk-IMKFNOWR-CDGBumC-.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-CDGBumC-.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-CDGBumC-.js.gz +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-BHn7J2ij.js → chunk-JWPE2WC7-CGx9O6IX.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-1UAKkjro.js → chunk-POPQ4Y6H-BkWYxDSy.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DMDJrwWD.js → chunk-SVP7TREG-BGwkXakv.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-BGwkXakv.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-BGwkXakv.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-DViVpzs1.js → chunk-TICWLB2K-CMxjLRcv.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-CMxjLRcv.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-CMxjLRcv.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-Cyg6qo-b.js → chunk-XXDRQBXY-DCIQ1i4z.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-DrGmXJ_R.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-DrGmXJ_R.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-Dq6PJ-un.js → cose-bilkent-JH36ORCC-Des2am0k.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-Des2am0k.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-Des2am0k.js.gz +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX--pc9zClZ.js → cynefin-OW5HDTMX-BOJs6wCD.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-BOJs6wCD.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-BOJs6wCD.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-1whKia5t.js → cynefinDiagram-5FMLGOSQ-DVLqWiJ6.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DVLqWiJ6.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DVLqWiJ6.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-8TjGkCEP.js → dagre-GXQ25YYZ-e7mtFW8V.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-e7mtFW8V.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-e7mtFW8V.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-BTgsveUu.js → diagram-S7CK7UJ4-B9P-CEm4.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-B9P-CEm4.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-B9P-CEm4.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-CPxoDqq7.js → diagram-UQ7AKVKN-DvTmtjeC.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-DvTmtjeC.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-DvTmtjeC.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-BtNBFyC3.js → diagram-VSXAHHWV-BmwhsB8_.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-BmwhsB8_.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-BmwhsB8_.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-DLfdx0dh.js → diagram-VX7I27RA-CvV9NUzM.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-CvV9NUzM.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-CvV9NUzM.js.gz +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-C9FdZJ41.js → diagram-Z3DM3KII-DT1POaEF.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-DT1POaEF.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-DT1POaEF.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-CAxaqCAJ.js → ebnfDiagram-PWID7BFC-QZNS7lcr.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-QZNS7lcr.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-QZNS7lcr.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-BBO2Iz-B.js → erDiagram-RLTQ6QDP-C9KhKBAJ.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-C9KhKBAJ.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-C9KhKBAJ.js.gz +0 -0
- package/dist/client/assets/{flowDiagram-HODETNUW-DQ-nPGNL.js → flowDiagram-HODETNUW-Du-YKajw.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-Du-YKajw.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-Du-YKajw.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-C4bKdSCF.js → ganttDiagram-EL5Y4UJY-I9ibR23C.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-I9ibR23C.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-I9ibR23C.js.gz +0 -0
- package/dist/client/assets/{gestureArbiter-miROLzXb.js → gestureArbiter-BE8k_FL7.js} +1 -1
- package/dist/client/assets/gestureArbiter-BE8k_FL7.js.br +0 -0
- package/dist/client/assets/gestureArbiter-BE8k_FL7.js.gz +0 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-cAbsg4ei.js → gitGraphDiagram-WWUBYQGX-BK6myYCK.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BK6myYCK.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BK6myYCK.js.gz +0 -0
- package/dist/client/assets/{index-Dd_3ISCb.css → index-C6xPtOPw.css} +1 -1
- package/dist/client/assets/index-C6xPtOPw.css.br +0 -0
- package/dist/client/assets/{index-Dd_3ISCb.css.gz → index-C6xPtOPw.css.gz} +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-EV88OFTf.js → infoDiagram-27XIBGKW-D1tExNKF.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bi-60w6U.js → ishikawaDiagram-5VMMS53U-CwY6cf7s.js} +1 -1
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-CwY6cf7s.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-CwY6cf7s.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-Bgbk61sp.js → journeyDiagram-3NMN7TZE-Cqy1TbUI.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-Cqy1TbUI.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-Cqy1TbUI.js.gz +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-Ly6IeL8s.js → kanban-definition-UXKFOSKX-SXzevtXv.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-SXzevtXv.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-SXzevtXv.js.gz +0 -0
- package/dist/client/assets/{layout-CEjMszLD.js → layout-CFH4KsMu.js} +1 -1
- package/dist/client/assets/layout-CFH4KsMu.js.br +0 -0
- package/dist/client/assets/{layout-CEjMszLD.js.gz → layout-CFH4KsMu.js.gz} +0 -0
- package/dist/client/assets/{linear-BCB67kKS.js → linear-DSGS6T8F.js} +1 -1
- package/dist/client/assets/linear-DSGS6T8F.js.br +0 -0
- package/dist/client/assets/linear-DSGS6T8F.js.gz +0 -0
- package/dist/client/assets/{mermaid.core-BmSOfxMH.js → mermaid.core-BpDQIw7m.js} +5 -5
- package/dist/client/assets/mermaid.core-BpDQIw7m.js.br +0 -0
- package/dist/client/assets/mermaid.core-BpDQIw7m.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-VEZ7qGHM.js → mindmap-definition-YA3MSWOX-D7H6k38f.js} +1 -1
- package/dist/client/assets/mindmap-definition-YA3MSWOX-D7H6k38f.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-D7H6k38f.js.gz +0 -0
- package/dist/client/assets/{passwordBootstrap-BUV0AT5k.js → passwordBootstrap-B4SLDWeK.js} +1 -1
- package/dist/client/assets/passwordBootstrap-B4SLDWeK.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-B4SLDWeK.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-DtFnROHy.js → pegDiagram-XKGWAZYB-DT21hoef.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-DT21hoef.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DT21hoef.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-CrRFKgsg.js → pieDiagram-E7YTZNPT-CP_7qBRV.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-CP_7qBRV.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CP_7qBRV.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-DrxOcCWy.js → quadrantDiagram-AXDQQJYC-CLBVrI3n.js} +1 -1
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-CLBVrI3n.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-CLBVrI3n.js.gz +0 -0
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-BaXzskST.js → railroadDiagram-O6MQD6OU-DJoM5WtF.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DJoM5WtF.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DJoM5WtF.js.gz +0 -0
- package/dist/client/assets/rdpSession-C0jVZfFV.js +1 -0
- package/dist/client/assets/rdpSession-C0jVZfFV.js.br +0 -0
- package/dist/client/assets/rdpSession-C0jVZfFV.js.gz +0 -0
- package/dist/client/assets/{referenceLongPress-DqibFmuj.js → referenceLongPress-LCYPFdN8.js} +1 -1
- package/dist/client/assets/referenceLongPress-LCYPFdN8.js.br +0 -0
- package/dist/client/assets/referenceLongPress-LCYPFdN8.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-BdwuNHm0.js → requirementDiagram-BXWQKSXE-BHLyxBdU.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BHLyxBdU.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BHLyxBdU.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-L8-WTgQS.js → sankeyDiagram-P5KCCOFB-CUgEsLUw.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-CUgEsLUw.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-CUgEsLUw.js.gz +0 -0
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-Hloa_AO5.js → sequenceDiagram-WJ2MYXX4-qEb89gHp.js} +1 -1
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-qEb89gHp.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-qEb89gHp.js.gz +0 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-0sRpfplV.js → sizeCapture-INFHLROL-BUOHBGK2.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-BUOHBGK2.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-BUOHBGK2.js.gz +0 -0
- package/dist/client/assets/{sparkles-CgDDXr95.js → sparkles-Cm9xs8pz.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-DqT3kcLM.js → stateDiagram-D77RDMKH-Dx0afnU6.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-Dx0afnU6.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-Dx0afnU6.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CzHE6VoX.js +1 -0
- package/dist/client/assets/{swimlanes-42K2YHIH-BH5xHrJq.js → swimlanes-42K2YHIH-DeG8X6CN.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH-DeG8X6CN.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-DeG8X6CN.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-B4wu-iuA.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-D3Ez5FZh.js → timeline-definition-24CTP7MA-Bkts868I.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-Bkts868I.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-Bkts868I.js.gz +0 -0
- package/dist/client/assets/{triangle-alert-DqUvQ_x8.js → triangle-alert-D1VnXjVL.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-DEGLdtyy.js → vennDiagram-4TSXK5OY-BOoHxntl.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-DEGLdtyy.js.br → vennDiagram-4TSXK5OY-BOoHxntl.js.br} +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-BOoHxntl.js.gz +0 -0
- package/dist/client/assets/{videoCompression-DIBRptEJ.js → videoCompression-BONtNnBl.js} +1 -1
- package/dist/client/assets/videoCompression-BONtNnBl.js.br +0 -0
- package/dist/client/assets/videoCompression-BONtNnBl.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-BWXojK8h.js → wardleyDiagram-VM6X3IG4-BAuuRkvt.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BAuuRkvt.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BAuuRkvt.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-CI95cYmG.js → xychartDiagram-S5SC5T6Z-DvJOw2Ss.js} +1 -1
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-DvJOw2Ss.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-DvJOw2Ss.js.gz +0 -0
- package/dist/client/index.html +2 -2
- package/dist/client/index.html.br +0 -0
- package/dist/client/index.html.gz +0 -0
- package/dist/client/sw.js +1 -1
- package/dist/client/sw.js.br +0 -0
- package/dist/client/sw.js.gz +0 -0
- package/dist/server/agent/collaborationCli.js +3 -0
- package/dist/server/agent/integrationRecoveryBinding.js +34 -0
- package/dist/server/agent/integrationServer.js +1 -0
- package/dist/server/agent/integrationSessions.js +79 -3
- package/dist/server/entry.js +4 -0
- package/dist/server/routes/terminal.js +90 -0
- package/docs/integrations.md +27 -0
- package/package.json +1 -1
- package/runtime-manifest.json +3 -3
- package/dist/client/assets/App-C0c83Pxp.js.br +0 -0
- package/dist/client/assets/App-C0c83Pxp.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-znWmrZsF.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-znWmrZsF.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-Bt4fjEoD.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-Bt4fjEoD.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-0s90d39f.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-0s90d39f.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-CHVGId4O.js +0 -2
- package/dist/client/assets/ComputerControlView-BxLiNZeK.js +0 -5
- package/dist/client/assets/ComputerControlView-BxLiNZeK.js.br +0 -0
- package/dist/client/assets/ComputerControlView-BxLiNZeK.js.gz +0 -0
- package/dist/client/assets/DagPlayground-311LPbK_.js.br +0 -0
- package/dist/client/assets/DagPlayground-311LPbK_.js.gz +0 -0
- package/dist/client/assets/DiffLab-CHZ0EL2E.js.br +0 -0
- package/dist/client/assets/DiffLab-CHZ0EL2E.js.gz +0 -0
- package/dist/client/assets/DiffReview-BA7zArOA.js.br +0 -0
- package/dist/client/assets/DiffReview-BA7zArOA.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-C_6SxWtH.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-C_6SxWtH.js.gz +0 -0
- package/dist/client/assets/DiffViewer-B0YoRCEi.js.br +0 -0
- package/dist/client/assets/DiffViewer-B0YoRCEi.js.gz +0 -0
- package/dist/client/assets/ModelPreview-BboTxu4_.js.br +0 -0
- package/dist/client/assets/ModelPreview-BboTxu4_.js.gz +0 -0
- package/dist/client/assets/RightSidebar-TFRZlsFX.js.br +0 -0
- package/dist/client/assets/RightSidebar-TFRZlsFX.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BK2-PKkq.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BK2-PKkq.js.gz +0 -0
- package/dist/client/assets/app-D2yRvfNE.js.br +0 -0
- package/dist/client/assets/app-D2yRvfNE.js.gz +0 -0
- package/dist/client/assets/arc-DqI6rAeJ.js.br +0 -0
- package/dist/client/assets/arc-DqI6rAeJ.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CZBYAIxt.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CZBYAIxt.js.gz +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BAZ4LopQ.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BAZ4LopQ.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-Boh80g9D.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-Boh80g9D.js.gz +0 -0
- package/dist/client/assets/channel-B3pP90yO.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-B3iWUfsu.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-B3iWUfsu.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BV8W69Xy.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BV8W69Xy.js.gz +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DMDJrwWD.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DMDJrwWD.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DViVpzs1.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DViVpzs1.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-CcfJXXoP.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-CcfJXXoP.js +0 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-Dq6PJ-un.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-Dq6PJ-un.js.gz +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX--pc9zClZ.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX--pc9zClZ.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-1whKia5t.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-1whKia5t.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-8TjGkCEP.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-8TjGkCEP.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BTgsveUu.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BTgsveUu.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CPxoDqq7.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CPxoDqq7.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-BtNBFyC3.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-BtNBFyC3.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-DLfdx0dh.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-DLfdx0dh.js.gz +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-C9FdZJ41.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-C9FdZJ41.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CAxaqCAJ.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CAxaqCAJ.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BBO2Iz-B.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BBO2Iz-B.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DQ-nPGNL.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DQ-nPGNL.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-C4bKdSCF.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-C4bKdSCF.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-miROLzXb.js.br +0 -0
- package/dist/client/assets/gestureArbiter-miROLzXb.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-cAbsg4ei.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-cAbsg4ei.js.gz +0 -0
- package/dist/client/assets/index-Dd_3ISCb.css.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-Bi-60w6U.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-Bi-60w6U.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-Bgbk61sp.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-Bgbk61sp.js.gz +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Ly6IeL8s.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Ly6IeL8s.js.gz +0 -0
- package/dist/client/assets/layout-CEjMszLD.js.br +0 -0
- package/dist/client/assets/linear-BCB67kKS.js.br +0 -0
- package/dist/client/assets/linear-BCB67kKS.js.gz +0 -0
- package/dist/client/assets/mermaid.core-BmSOfxMH.js.br +0 -0
- package/dist/client/assets/mermaid.core-BmSOfxMH.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-VEZ7qGHM.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-VEZ7qGHM.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-BUV0AT5k.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-BUV0AT5k.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DtFnROHy.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DtFnROHy.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CrRFKgsg.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CrRFKgsg.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-DrxOcCWy.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-DrxOcCWy.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BaXzskST.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BaXzskST.js.gz +0 -0
- package/dist/client/assets/rdpSession-DtIeoTyy.js +0 -1
- package/dist/client/assets/rdpSession-DtIeoTyy.js.br +0 -0
- package/dist/client/assets/rdpSession-DtIeoTyy.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-DqibFmuj.js.br +0 -0
- package/dist/client/assets/referenceLongPress-DqibFmuj.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BdwuNHm0.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BdwuNHm0.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-L8-WTgQS.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-L8-WTgQS.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Hloa_AO5.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Hloa_AO5.js.gz +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-0sRpfplV.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-0sRpfplV.js.gz +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DqT3kcLM.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DqT3kcLM.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-DjkkxZUN.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-BH5xHrJq.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-BH5xHrJq.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DpLhj_Dx.js +0 -8
- package/dist/client/assets/timeline-definition-24CTP7MA-D3Ez5FZh.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-D3Ez5FZh.js.gz +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-DEGLdtyy.js.gz +0 -0
- package/dist/client/assets/videoCompression-DIBRptEJ.js.br +0 -0
- package/dist/client/assets/videoCompression-DIBRptEJ.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BWXojK8h.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BWXojK8h.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-CI95cYmG.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-CI95cYmG.js.gz +0 -0
|
@@ -61,6 +61,7 @@ export class IntegrationSessions {
|
|
|
61
61
|
lifecycle = new SessionLifecycleCoordinator();
|
|
62
62
|
mutations = new Map();
|
|
63
63
|
coldRetries = new Set();
|
|
64
|
+
reconcilingBindings = new Set();
|
|
64
65
|
closingOperations = new Set();
|
|
65
66
|
timers = new Set();
|
|
66
67
|
stopObservation;
|
|
@@ -302,7 +303,13 @@ export class IntegrationSessions {
|
|
|
302
303
|
return record;
|
|
303
304
|
}
|
|
304
305
|
async restore(principal, id, key) {
|
|
305
|
-
return this.mutate(principal, key, ['restore', id],
|
|
306
|
+
return this.mutate(principal, key, ['restore', id], async () => {
|
|
307
|
+
// A get can reconcile a proven tmux-recovery binding before restore takes
|
|
308
|
+
// the per-session lifecycle lock. restoreOnce then sees the exact live
|
|
309
|
+
// native owner and remains a no-op instead of launching a second Agent.
|
|
310
|
+
await this.get(principal, id);
|
|
311
|
+
return this.lifecycle.run(id, () => this.restoreOnce(principal, id, key));
|
|
312
|
+
});
|
|
306
313
|
}
|
|
307
314
|
async retryCold(principal, id, generation, key) {
|
|
308
315
|
return this.mutate(principal, key, ['retry-cold', id, generation], () => this.lifecycle.run(id, async () => {
|
|
@@ -690,7 +697,7 @@ export class IntegrationSessions {
|
|
|
690
697
|
return record;
|
|
691
698
|
}));
|
|
692
699
|
}
|
|
693
|
-
async refresh(id) {
|
|
700
|
+
async refresh(id, allowBindingReconciliation = true) {
|
|
694
701
|
const record = structuredClone(this.doc.sessions.find(s => s.session_id === id));
|
|
695
702
|
if (!record)
|
|
696
703
|
return;
|
|
@@ -781,8 +788,19 @@ export class IntegrationSessions {
|
|
|
781
788
|
const current = this.doc.sessions.find(s => s.session_id === id);
|
|
782
789
|
if (JSON.stringify(current) !== JSON.stringify(record))
|
|
783
790
|
return;
|
|
791
|
+
if (this.lifecycle.active(id) || this.pending.has(id))
|
|
792
|
+
return;
|
|
784
793
|
const code = error.code;
|
|
785
794
|
const errorCode = typeof code === 'string' ? code : 'SESSION_OBSERVATION_FAILED';
|
|
795
|
+
if (allowBindingReconciliation && errorCode === 'SESSION_IDENTITY_MISMATCH' && this.adapter.reconcileRecoveryBinding
|
|
796
|
+
&& ['ready', 'failed'].includes(record.state) && (record.runtime_present === true || record.state === 'failed')
|
|
797
|
+
&& (!record.error_code || record.error_code === 'SESSION_IDENTITY_MISMATCH')
|
|
798
|
+
&& record.agent_native_session_id && record.terminal_binding && !record.operation_uncertain
|
|
799
|
+
&& !record.close_intent && !record.rename_pending && !record.cold_retry_pending
|
|
800
|
+
&& !this.pending.has(id) && !this.lifecycle.active(id)) {
|
|
801
|
+
if (await this.reconcileRecoveredBinding(record))
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
786
804
|
if (record.state !== 'failed' || record.error_code !== errorCode)
|
|
787
805
|
this.saveRecord({ ...record, state: 'failed', error_code: errorCode,
|
|
788
806
|
launch_diagnostics: record.launch_diagnostics ? launchFailure(record.launch_diagnostics, error, errorCode) : undefined, updated_at: Date.now() });
|
|
@@ -871,11 +889,66 @@ export class IntegrationSessions {
|
|
|
871
889
|
this.saveRecord(next);
|
|
872
890
|
}
|
|
873
891
|
}
|
|
892
|
+
async reconcileRecoveredBinding(expected) {
|
|
893
|
+
const id = expected.session_id;
|
|
894
|
+
const reconcile = this.adapter.reconcileRecoveryBinding;
|
|
895
|
+
if (!reconcile || this.lifecycle.active(id) || this.pending.has(id))
|
|
896
|
+
return false;
|
|
897
|
+
let committed = false;
|
|
898
|
+
try {
|
|
899
|
+
await this.lifecycle.run(id, async () => {
|
|
900
|
+
const current = this.doc.sessions.find(record => record.session_id === id);
|
|
901
|
+
if (!current || JSON.stringify(current) !== JSON.stringify(expected) || this.pending.has(id)
|
|
902
|
+
|| !['ready', 'failed'].includes(current.state) || !(current.runtime_present === true || current.state === 'failed')
|
|
903
|
+
|| (current.error_code && current.error_code !== 'SESSION_IDENTITY_MISMATCH')
|
|
904
|
+
|| current.operation_uncertain || current.close_intent || current.rename_pending || current.cold_retry_pending
|
|
905
|
+
|| !current.agent_native_session_id || !current.terminal_binding)
|
|
906
|
+
return;
|
|
907
|
+
this.reconcilingBindings.add(id);
|
|
908
|
+
let reconciled;
|
|
909
|
+
try {
|
|
910
|
+
reconciled = await reconcile.call(this.adapter, current);
|
|
911
|
+
}
|
|
912
|
+
catch {
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
if (!reconciled || JSON.stringify(reconciled.binding) === JSON.stringify(current.terminal_binding))
|
|
916
|
+
return;
|
|
917
|
+
const latest = this.doc.sessions.find(record => record.session_id === id);
|
|
918
|
+
if (!latest || JSON.stringify(latest) !== JSON.stringify(current))
|
|
919
|
+
return;
|
|
920
|
+
const now = Date.now();
|
|
921
|
+
const next = { ...current, terminal_binding: structuredClone(reconciled.binding), state: 'ready',
|
|
922
|
+
runtime_present: true, error_code: null, operation_uncertain: false, generation: (current.generation ?? 1) + 1,
|
|
923
|
+
operation_id: randomUUID(), updated_at: now,
|
|
924
|
+
binding_reconciliation: { at: now, recovery_operation_id: reconciled.recoveryOperationId,
|
|
925
|
+
previous_binding: structuredClone(current.terminal_binding) },
|
|
926
|
+
startup_input: startupInput(current, now) };
|
|
927
|
+
this.saveRecord(next);
|
|
928
|
+
committed = true;
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
catch {
|
|
932
|
+
return false;
|
|
933
|
+
}
|
|
934
|
+
finally {
|
|
935
|
+
this.reconcilingBindings.delete(id);
|
|
936
|
+
}
|
|
937
|
+
if (committed) {
|
|
938
|
+
try {
|
|
939
|
+
this.adapter.recoveryBindingReconciled?.(id);
|
|
940
|
+
}
|
|
941
|
+
catch { /* The worker also retries on its normal tick. */ }
|
|
942
|
+
}
|
|
943
|
+
return committed;
|
|
944
|
+
}
|
|
874
945
|
/** Only gates configured launches. Native UUID and Agent turn state are not input prerequisites. */
|
|
875
946
|
async deliveryReadiness(id) {
|
|
876
947
|
const existing = this.doc.sessions.find(record => record.session_id === id);
|
|
877
948
|
if (!existing)
|
|
878
949
|
return null;
|
|
950
|
+
if (this.reconcilingBindings.has(id))
|
|
951
|
+
return { allowed: false, reason: 'SESSION_BINDING_RECONCILIATION_PENDING' };
|
|
879
952
|
if (this.closingOperations.has(id))
|
|
880
953
|
return { allowed: false, reason: 'SESSION_OPERATION_IN_PROGRESS' };
|
|
881
954
|
if (existing.state === 'closed')
|
|
@@ -886,7 +959,10 @@ export class IntegrationSessions {
|
|
|
886
959
|
return { allowed: false, reason: existing.state === 'released' ? 'SESSION_RELEASED' : 'SESSION_OPERATION_IN_PROGRESS' };
|
|
887
960
|
if (!existing.startup_input)
|
|
888
961
|
return null;
|
|
889
|
-
|
|
962
|
+
// This callback can run inside the delivery worker's own queue. Binding
|
|
963
|
+
// reconciliation must enter that queue from get/observation, never wait on
|
|
964
|
+
// the worker from within itself.
|
|
965
|
+
await this.refresh(id, false);
|
|
890
966
|
const record = this.doc.sessions.find(record => record.session_id === id);
|
|
891
967
|
if (record.error_code && record.error_code !== 'SESSION_BINDING_TIMEOUT')
|
|
892
968
|
return { allowed: false, reason: record.error_code };
|
package/dist/server/entry.js
CHANGED
|
@@ -116,6 +116,10 @@ function shouldWriteClientLog(level, message) {
|
|
|
116
116
|
clientLogSuppressedCount += 1;
|
|
117
117
|
return false;
|
|
118
118
|
}
|
|
119
|
+
// Motion trace records share a label but contain different ordered samples.
|
|
120
|
+
// Preserve every chunk while retaining the global rate limit above.
|
|
121
|
+
if (message === 'COMPUTER_MOTION_TRACE')
|
|
122
|
+
return true;
|
|
119
123
|
const key = `${String(level ?? 'info')}\u0000${String(message ?? '')}`;
|
|
120
124
|
const last = clientLogRecent.get(key);
|
|
121
125
|
if (last && now - last < CLIENT_LOG_DEDUP_WINDOW_MS) {
|
|
@@ -73,6 +73,7 @@ import { NativeSessionSearch } from '../agent/nativeSessionSearch.js';
|
|
|
73
73
|
import { CollaborationError } from '../agent/collaborationProtocol.js';
|
|
74
74
|
import { resolveCollaborationBackend, resolveCollaborationSessionId } from '../agent/sessionBindingRecovery.js';
|
|
75
75
|
import { CollaborationRoutingStore, selectCollaborationPane, selectDrivePane, assessCollaborationRouteIdentity } from '../agent/collaborationRouting.js';
|
|
76
|
+
import { selectRecoveredIntegrationBinding } from '../agent/integrationRecoveryBinding.js';
|
|
76
77
|
import { CollaborationDeliveryWorker } from '../agent/collaborationDeliveryWorker.js';
|
|
77
78
|
import { approveCollaborationDialog, captureTmuxPaneHistory, captureTmuxPaneText, sendTmuxPaneKey, writeCollaborationTmuxPane } from '../agent/collaborationTmuxDelivery.js';
|
|
78
79
|
import { listAllHookAgents, refreshStaleHooksAtLaunch, installHooksForSlug, uninstallHooksForSlug, } from '../agent/installers.js';
|
|
@@ -2072,6 +2073,28 @@ function integrationTerminalRecord(record) {
|
|
|
2072
2073
|
integrationError('SESSION_IDENTITY_MISMATCH', 'Owned TD terminal binding changed', 409);
|
|
2073
2074
|
return terminal;
|
|
2074
2075
|
}
|
|
2076
|
+
async function integrationRecoveryOwnership(record) {
|
|
2077
|
+
const root = `${TERMDOCK_DIR}/integration-state`;
|
|
2078
|
+
const directories = await fs.promises.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
2079
|
+
const descriptorOwners = [];
|
|
2080
|
+
const principalOwners = [];
|
|
2081
|
+
for (const directory of directories) {
|
|
2082
|
+
if (!directory.isDirectory())
|
|
2083
|
+
continue;
|
|
2084
|
+
const directoryPath = path.join(root, directory.name);
|
|
2085
|
+
const sessions = await readJsonFileIfExists(path.join(directoryPath, 'integration-sessions.json'));
|
|
2086
|
+
for (const session of sessions?.sessions ?? [])
|
|
2087
|
+
if (session.session_id === record.session_id) {
|
|
2088
|
+
descriptorOwners.push({ sessionId: String(session.session_id), groupId: String(session.group_id ?? ''), principalId: String(session.principal_id ?? '') });
|
|
2089
|
+
}
|
|
2090
|
+
const integrations = await readJsonFileIfExists(path.join(directoryPath, 'integrations.json'));
|
|
2091
|
+
for (const principal of integrations?.principals ?? [])
|
|
2092
|
+
if (principal.id === record.principal_id) {
|
|
2093
|
+
principalOwners.push({ principalId: String(principal.id), groupId: String(principal.groupId ?? ''), revoked: principal.revoked === true });
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
return { descriptorOwners, principalOwners };
|
|
2097
|
+
}
|
|
2075
2098
|
async function integrationTmuxPresent(record) {
|
|
2076
2099
|
try {
|
|
2077
2100
|
await runTmux(['has-session', '-t', `=wt-integration-${record.session_id}`]);
|
|
@@ -2299,6 +2322,73 @@ export const integrationSessionAdapter = {
|
|
|
2299
2322
|
collaborationRouting.bind({ ...route, nativeSessionId: nativeId, pane: { ...route.pane, nativeSessionId: nativeId } });
|
|
2300
2323
|
return { exists: true, running: Boolean(pane.agentSlug), shell: await integrationPaneIsIdleShell(pane), agentSlug: pane.agentSlug || null, nativeId };
|
|
2301
2324
|
},
|
|
2325
|
+
async reconcileRecoveryBinding(record) {
|
|
2326
|
+
if (process.platform !== 'linux' || !record.agent_native_session_id || !record.terminal_binding)
|
|
2327
|
+
return null;
|
|
2328
|
+
const expectedNativeSessionId = record.agent_native_session_id;
|
|
2329
|
+
let reconciled = null;
|
|
2330
|
+
const collect = async () => {
|
|
2331
|
+
const sessionName = `wt-integration-${record.session_id}`;
|
|
2332
|
+
const recoveryAfter = Math.max(record.created_at, record.binding_reconciliation?.at ?? 0);
|
|
2333
|
+
const matchingRecovery = tmuxRecoveryOperations.all().reverse().find(operation => operation.items.some(item => item.sessionId === record.session_id && item.state === 'succeeded'
|
|
2334
|
+
&& Number.isSafeInteger(item.completedAt) && item.completedAt > recoveryAfter));
|
|
2335
|
+
const owners = await integrationRecoveryOwnership(record);
|
|
2336
|
+
const groupOwners = collaborationStore.list().filter(group => !group.deleted && group.sessionIds.includes(record.session_id)).map(group => group.id);
|
|
2337
|
+
const globalOwners = globalSessionState.sessions.filter(session => session.sessionId === record.session_id || session.tmuxSessionName === sessionName);
|
|
2338
|
+
const terminal = globalSessionState.sessions.find(session => session.sessionId === record.session_id);
|
|
2339
|
+
const backendMatches = [...terminalSessions].filter(([, backend]) => backend.mode === 'tmux' && backend.tmuxSessionName === sessionName);
|
|
2340
|
+
const backendOwnershipVerified = !!terminal && terminal.mode === 'tmux' && terminal.tmuxSessionName === sessionName
|
|
2341
|
+
&& terminal.agentResume?.slug === record.agent_slug && terminal.agentResume.sessionId === expectedNativeSessionId
|
|
2342
|
+
&& backendMatches.length === 1 && !globalSessionState.sessions.some(other => other.sessionId !== record.session_id
|
|
2343
|
+
&& (other.tmuxSessionName === sessionName || other.backendSessionId === backendMatches[0]?.[0]))
|
|
2344
|
+
&& [null, record.session_id].includes(collaborationRouting.ownerOfBackend(backendMatches[0]?.[0] ?? ''));
|
|
2345
|
+
let panes = [];
|
|
2346
|
+
if (backendOwnershipVerified && backendMatches.length === 1) {
|
|
2347
|
+
await runTmux(['has-session', '-t', `=${sessionName}`]);
|
|
2348
|
+
const layout = await getTmuxLayout(sessionName);
|
|
2349
|
+
if (layout.sessionName === sessionName && layout.windows.flatMap(window => window.panes).length === 1) {
|
|
2350
|
+
const [backendSessionId] = backendMatches[0];
|
|
2351
|
+
const unpinned = { sessionId: record.session_id, backendSessionId, mode: 'tmux',
|
|
2352
|
+
tmuxSessionName: sessionName, agentSlug: record.agent_slug, nativeSessionId: expectedNativeSessionId, pane: null };
|
|
2353
|
+
const inspected = await inspectCollaborationTmux(unpinned, null, false, true, true, true);
|
|
2354
|
+
panes = (inspected.candidates ?? []).map(pane => ({ tmuxSessionName: sessionName,
|
|
2355
|
+
agentSlug: pane.agentSlug, nativeSessionId: pane.nativeSessionId,
|
|
2356
|
+
nativeIdentitySource: pane.nativeIdentitySource ?? null, nativeIdentityVerified: pane.nativeIdentityVerified === true,
|
|
2357
|
+
binding: { serverPid: pane.serverPid, sessionId: pane.sessionId, paneId: pane.paneId, panePid: pane.panePid,
|
|
2358
|
+
agentSlug: pane.agentSlug, nativeSessionId: pane.nativeSessionId } }));
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
const selected = selectRecoveredIntegrationBinding({ sessionId: record.session_id, groupId: record.group_id, principalId: record.principal_id,
|
|
2362
|
+
agentSlug: record.agent_slug, nativeSessionId: expectedNativeSessionId, tmuxSessionName: sessionName,
|
|
2363
|
+
descriptorOwners: owners.descriptorOwners, principalOwners: owners.principalOwners, groupOwners,
|
|
2364
|
+
terminalOwners: globalOwners.map(session => session.sessionId), backendOwnershipVerified,
|
|
2365
|
+
recoveryOperationId: matchingRecovery?.id ?? null, panes });
|
|
2366
|
+
return selected && backendMatches.length === 1 ? { ...selected, backendSessionId: backendMatches[0][0] } : null;
|
|
2367
|
+
};
|
|
2368
|
+
await collaborationDeliveryWorker.reconfigure(record.session_id, async () => {
|
|
2369
|
+
if (routeHasUnconfirmedWrite(record.session_id))
|
|
2370
|
+
throw Object.assign(new Error('A previous terminal write has an uncertain outcome'), { code: 'ROUTE_DELIVERY_OUTCOME_UNCONFIRMED' });
|
|
2371
|
+
const first = await collect();
|
|
2372
|
+
if (!first)
|
|
2373
|
+
throw Object.assign(new Error('Recovery binding evidence is incomplete, ambiguous, or does not match the exact native identity'), { code: 'SESSION_RECOVERY_BINDING_UNCONFIRMED' });
|
|
2374
|
+
const second = await collect();
|
|
2375
|
+
if (!second || first.recoveryOperationId !== second.recoveryOperationId || first.backendSessionId !== second.backendSessionId
|
|
2376
|
+
|| JSON.stringify(first.binding) !== JSON.stringify(second.binding)) {
|
|
2377
|
+
throw Object.assign(new Error('Integration runtime changed while recovery binding was being verified'), { code: 'SESSION_RECOVERY_BINDING_CHANGED' });
|
|
2378
|
+
}
|
|
2379
|
+
if (routeHasUnconfirmedWrite(record.session_id) || collaborationRouting.hasOtherPaneOwner(record.session_id, second.binding)) {
|
|
2380
|
+
throw Object.assign(new Error('A previous write or another route owner prevents automatic binding reconciliation'), { code: 'ROUTE_DELIVERY_OUTCOME_UNCONFIRMED' });
|
|
2381
|
+
}
|
|
2382
|
+
const previous = collaborationRouting.get(record.session_id);
|
|
2383
|
+
collaborationRouting.bind({ sessionId: record.session_id, backendSessionId: second.backendSessionId,
|
|
2384
|
+
mode: 'tmux', tmuxSessionName: `wt-integration-${record.session_id}`, agentSlug: record.agent_slug,
|
|
2385
|
+
nativeSessionId: record.agent_native_session_id, pane: second.binding, routeRevision: crypto.randomUUID(),
|
|
2386
|
+
lastRecovery: { kind: 'native-identity', at: Date.now(), previousPane: previous?.pane ?? record.terminal_binding ?? null } });
|
|
2387
|
+
reconciled = { binding: second.binding, recoveryOperationId: second.recoveryOperationId };
|
|
2388
|
+
});
|
|
2389
|
+
return reconciled;
|
|
2390
|
+
},
|
|
2391
|
+
recoveryBindingReconciled(sessionId) { collaborationDeliveryWorker.wake(sessionId); },
|
|
2302
2392
|
async create(record, prepared, progress) {
|
|
2303
2393
|
await listDetectedAgentLaunchers();
|
|
2304
2394
|
if (!agentBySlug(record.agent_slug))
|
package/docs/integrations.md
CHANGED
|
@@ -1327,3 +1327,30 @@ TD/native session、运行承载、消息/reply、consumer 游标或历史;不
|
|
|
1327
1327
|
`GROUP_ARCHIVE_STATE_UNCONFIRMED`,不会猜测或重建。只允许本机非 federated、未删除
|
|
1328
1328
|
组;删除组、跨服务组和不确定的目标分别返回 `GROUP_NOT_FOUND`、`GROUP_NOT_LOCAL`、
|
|
1329
1329
|
`GROUP_ARCHIVE_TARGET_UNAVAILABLE`。归档不延长消息历史保留期。
|
|
1330
|
+
|
|
1331
|
+
## 1.4.328:IntegrationSession 对账 tmux recovery 的新承载
|
|
1332
|
+
|
|
1333
|
+
最低 CLI / 实际服务 **1.4.328**,能力回读字段为
|
|
1334
|
+
`session_recovery_binding_reconcile=true` 与
|
|
1335
|
+
`session_recovery_binding_reconcile_min_version=1.4.328`。该自动对账目前只在 Linux
|
|
1336
|
+
提供;其它平台返回 capability=false,因为没有同等的当前 writer-lock 身份证明。
|
|
1337
|
+
|
|
1338
|
+
所属 principal 调用现有 `session get` 时,如果 IntegrationSession 因
|
|
1339
|
+
`SESSION_IDENTITY_MISMATCH` 指向旧 pane,而 TD 持久恢复 operation 已成功恢复该逻辑
|
|
1340
|
+
session,服务会尝试受限对账。它要求当前唯一受管终端名严格为
|
|
1341
|
+
`wt-integration-<session_id>`,IntegrationSession 与有效 principal/group 的持久归属唯一,
|
|
1342
|
+
当前组和全局终端记录唯一,只有一个 tmux pane/backend,且该前台 Agent 的当前 Linux
|
|
1343
|
+
flock-owner 身份独立核验出原 agent slug 与原生 UUID。目标元组会连续采样确认未变,
|
|
1344
|
+
并在现有投递 worker 屏障内更新绑定。
|
|
1345
|
+
|
|
1346
|
+
成功后保留逻辑 `session_id`、group、principal、原生 UUID、消息与历史,只更新
|
|
1347
|
+
`terminal_binding`、状态和 `generation`,并在 `binding_reconciliation` 记录旧绑定及
|
|
1348
|
+
对应 `recovery_operation_id`。不会启动或恢复第二个 Agent,也不创建 task、发送正文或
|
|
1349
|
+
重放已写入的消息。此前写入结果不明时不会自动改绑;已写入的消息保持原 receipt,
|
|
1350
|
+
尚未写入的 pending 消息由原 worker 继续处理。
|
|
1351
|
+
|
|
1352
|
+
任一 owner 缺失/重复、tmux 名或 pane 不唯一、native UUID 不同、writer-lock 不可核验、
|
|
1353
|
+
没有该 session 成功的恢复 operation,或绑定在双重采样间再次变化时,服务保持
|
|
1354
|
+
fail-closed,旧绑定与原消息保留,`session get` 仍报告身份错误;不会按 tmux 名称、PID
|
|
1355
|
+
缓存、cwd、argv 中的 resume 参数或显示名猜测认领。此 capability 不新增权限;仅通过
|
|
1356
|
+
`session.read` 认证的所属 principal 可触发其自身记录的对账。
|
package/package.json
CHANGED
package/runtime-manifest.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "termdock",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.328",
|
|
5
5
|
"runtimeProtocolVersion": 1,
|
|
6
6
|
"minimumDesktopVersion": "1.4.46",
|
|
7
7
|
"nodeMajor": 22,
|
|
8
8
|
"dependencyHash": "sha256-oaGYi/P5ob8sd6VnNBOwshKozjhdV+hYiCmLAsn5x00=",
|
|
9
|
-
"serverBundleHash": "sha256-
|
|
10
|
-
"clientBundleHash": "sha256-
|
|
9
|
+
"serverBundleHash": "sha256-TbAZkctDrckV3heGqq3j/WuZeJSNx5/tTHYzQNmiahg=",
|
|
10
|
+
"clientBundleHash": "sha256-faF/1hpcDUHYr8eCLtTq/Xg23fWqv2gWgPNgHTsk1Zs=",
|
|
11
11
|
"entrypoint": "dist/server/cli.js",
|
|
12
12
|
"clientEntrypoint": "dist/client/index.html"
|
|
13
13
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{bA as r}from"./app-D2yRvfNE.js";import{b as m}from"./dnd-BCFAPC0L.js";import{b as n}from"./RightSidebar-TFRZlsFX.js";import"./react-XDCjal2T.js";import"./terminal-C7X98Amf.js";import"./App-C0c83Pxp.js";import"./gestureArbiter-miROLzXb.js";import"./triangle-alert-DqUvQ_x8.js";import"./referenceLongPress-DqibFmuj.js";import"./DiffReview-BA7zArOA.js";import"./sparkles-CgDDXr95.js";import"./DiffViewer-B0YoRCEi.js";import"./ChangeWalkthroughPanel-Bt4fjEoD.js";function g({content:o}){const e=m.useMemo(()=>n(o.split(`
|
|
2
|
-
`),null,null),[o]);return r.jsx("div",{className:"min-w-0 space-y-3 break-words text-sm leading-6 text-foreground [&_h1]:text-lg [&_h2]:text-base [&_h3]:text-sm [&_pre]:max-w-full [&_table]:text-xs",children:e.map((t,i)=>r.jsx("div",{className:"min-w-0",children:typeof t.content=="function"?t.content(null):t.content},i))})}export{g as default};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/rdpSession-DtIeoTyy.js","assets/app-D2yRvfNE.js","assets/react-XDCjal2T.js","assets/dnd-BCFAPC0L.js","assets/terminal-C7X98Amf.js","assets/index-Dd_3ISCb.css","assets/ChangeWalkthroughPanel-Bt4fjEoD.js","assets/sparkles-CgDDXr95.js","assets/triangle-alert-DqUvQ_x8.js","assets/App-C0c83Pxp.js","assets/gestureArbiter-miROLzXb.js","assets/gestureArbiter-C2J0D0kV.css","assets/referenceLongPress-DqibFmuj.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{ah as De,cz as Lt,df as gt,bA as t,cw as Ie,bz as Ve,W as it,o as lt,l as Tt,X as At,_ as ut}from"./app-D2yRvfNE.js";import{b as o,r as dt}from"./dnd-BCFAPC0L.js";import{a as Rt}from"./ChangeWalkthroughPanel-Bt4fjEoD.js";import{s as mt,Y as pt,K as He,j as ft}from"./App-C0c83Pxp.js";import{M as _t}from"./triangle-alert-DqUvQ_x8.js";const Mt=[["path",{d:"M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z",key:"edeuup"}]],ht=De("mouse-pointer-2",Mt);const It=[["path",{d:"M14 17H5",key:"gfn3mx"}],["path",{d:"M19 7h-9",key:"6i9tg"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]],Pt=De("settings-2",It);const Dt=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"11",x2:"11",y1:"8",y2:"14",key:"1vmskp"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],zt=De("zoom-in",Dt);const Ot=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],Ft=De("zoom-out",Ot);function Ye(e){const c=e==="darwin"?"mac":e==="win32"?"windows":"linux",f={host:"127.0.0.1",platform:c,protocol:c==="mac"?"vnc":"rdp",port:"3389",username:"",domain:"",ignoreCert:!1,rememberLogin:!0};return{target:"local",local:f,remote:{...f,host:""},viewOnly:!1,fit:!0,autoConnect:!0}}function xt(e,c){const f=Ye(c);if(!e||typeof e!="object")return f;const u=e,p=(x,d)=>{const s=x&&typeof x=="object"?x:{},v=(g,P)=>typeof s[g]=="string"&&s[g].length<=P&&!/[\x00-\x1f]/.test(s[g])?s[g]:d[g];return{host:v("host",253),username:v("username",255),domain:v("domain",255),platform:["mac","linux","windows"].includes(String(s.platform))?s.platform:d.platform,protocol:s.protocol==="rdp"||s.protocol==="vnc"?s.protocol:d.protocol,port:typeof s.port=="string"&&/^\d{0,5}$/.test(s.port)&&Number(s.port)<=65535?s.port:d.port,ignoreCert:s.ignoreCert===!0,rememberLogin:s.rememberLogin!==!1}};return{target:u.target==="remote"?"remote":"local",local:{...p(u.local,f.local),host:"127.0.0.1"},remote:p(u.remote,f.remote),viewOnly:u.viewOnly===!0,fit:u.fit!==!1,autoConnect:u.autoConnect!==!1}}function bt(e){return JSON.stringify([e.host.trim().toLowerCase(),e.protocol,e.protocol==="vnc"?5900:Number(e.port),e.username.trim(),e.domain.trim()])}function $t(e){const[c,f]=o.useState(Ye),[u,p]=o.useState(!1),[x,d]=o.useState("loading"),[s,v]=o.useState(0),[g,P]=o.useState([]),[W,T]=o.useState("idle"),k=o.useRef(c),A=o.useRef(0),a=o.useRef(0),N=o.useRef(""),b=o.useRef(null),C=o.useRef(new Set),K=o.useCallback(w=>{k.current=w(k.current),A.current++,f(k.current),d("saving")},[]);o.useEffect(()=>{const w=++a.current;A.current=0,N.current="",b.current=null,k.current=Ye(),f(k.current),p(!1),d("loading"),P([]),T("idle");const D=new AbortController;return fetch("/api/computer/preferences",{signal:D.signal}).then(async h=>{if(!h.ok)throw new Error("PREFERENCES_LOAD_FAILED");return await h.json()}).then(h=>{if(w!==a.current||D.signal.aborted)return;let R=xt(h.preferences);const O=A.current>0;if(!h.configured&&!O)try{const E=localStorage.getItem(`termdock:computer-host:${e}`);if(E){const U=/^(127\.0\.0\.1|localhost|::1|\[::1\])$/i.test(E)?"local":"remote";R=xt({...R,target:U,[U]:{...R[U],host:E,platform:localStorage.getItem(`termdock:computer-platform:${e}`)||R[U].platform,protocol:localStorage.getItem(`termdock:computer-protocol:${e}`)||"vnc",port:localStorage.getItem(`termdock:computer-rdp-port:${e}`)||"3389"}}),A.current++}}catch{}O||(k.current=R),N.current=h.configured?JSON.stringify(R):"",f(k.current),p(!0),d(h.configured?"saved":"saving"),P(Array.isArray(h.credentialKeys)?h.credentialKeys.filter(E=>typeof E=="string"):[]),T(h.credentialError?"error":"idle")}).catch(()=>{!D.signal.aborted&&w===a.current&&d("error")}),()=>{++a.current,D.abort();for(const h of C.current)h.abort();C.current.clear()}},[e,s]);const H=o.useCallback(()=>{if(b.current)return b.current;if(!u)return Promise.resolve(!1);const w=a.current,D=(async()=>{for(;N.current!==JSON.stringify(k.current);){const h=JSON.stringify(k.current),R=new AbortController;C.current.add(R),d("saving");try{if(!(await fetch("/api/computer/preferences",{method:"PUT",headers:{"Content-Type":"application/json"},body:h,signal:R.signal})).ok)throw new Error("PREFERENCES_SAVE_FAILED");if(w!==a.current)return!1;N.current=h}catch{return w===a.current&&d("error"),!1}finally{C.current.delete(R)}}return w===a.current&&d("saved"),!0})();return b.current=D,D.finally(()=>{b.current===D&&(b.current=null)}),D},[u]);o.useEffect(()=>{if(!u||N.current===JSON.stringify(c))return;const w=setTimeout(()=>{H()},300);return()=>clearTimeout(w)},[u,c,H]);const Z=o.useCallback(async(w,D,h)=>{const R=a.current,O=new AbortController;w!=="use"&&T("saving");try{if(!await H()||R!==a.current)throw new Error("COMPUTER_CREDENTIALS_FAILED");C.current.add(O);const E=await fetch(`/api/computer/credentials/${w}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({profile:D,...w==="save"?{password:h}:{}}),signal:O.signal});if(R!==a.current)throw new Error("COMPUTER_CREDENTIALS_FAILED");if(!E.ok)throw new Error(w==="use"&&E.status===404?"COMPUTER_CREDENTIALS_MISSING":"COMPUTER_CREDENTIALS_FAILED");const ne=await E.json();if(R!==a.current)throw new Error("COMPUTER_CREDENTIALS_FAILED");const U=bt(D);if(w==="save"&&P(ae=>[...new Set([...ae,U])]),w==="forget"&&P(ae=>ae.filter(pe=>pe!==U)),w==="use"&&(typeof ne.password!="string"||!ne.password))throw new Error("COMPUTER_CREDENTIALS_MISSING");return T("idle"),ne.password}catch(E){throw R===a.current&&!O.signal.aborted&&T("error"),E}finally{C.current.delete(O)}},[H]);return{preferences:c,change:K,loaded:u,saveState:x,flush:H,credentialKeys:g,loginState:W,credentialRequest:Z,retry:()=>u?void H():v(w=>w+1)}}class Ut{binaryType="arraybuffer";protocol="";CONNECTING=0;OPEN=1;CLOSING=2;CLOSED=3;onopen=null;onmessage=null;onerror=null;onclose=null;socket;get readyState(){return this.socket.readyState}constructor(c,f){this.socket=Lt(`/api/computer/ws?host=${encodeURIComponent(c)}`),this.socket.onopen=u=>this.onopen?.(u),this.socket.onerror=u=>this.onerror?.(u),this.socket.onclose=u=>{(u.code!==1e3||u.reason)&&f(u.reason||"COMPUTER_DISCONNECTED"),this.onclose?.(u)},this.socket.onmessage=u=>{try{const p=JSON.parse(u.data);if(p.type!=="data"||typeof p.data!="string"||!Number.isSafeInteger(p.seq))throw new Error("Invalid VNC record");const x=Uint8Array.from(atob(p.data),d=>d.charCodeAt(0));this.onmessage?.(new MessageEvent("message",{data:x.buffer})),this.socket.readyState===1&&this.socket.send(JSON.stringify({type:"ack",seq:p.seq}))}catch{f("COMPUTER_INVALID_MESSAGE"),this.close(),this.onclose?.(new CloseEvent("close",{code:4400}))}}}send(c){const f=ArrayBuffer.isView(c)?new Uint8Array(c.buffer,c.byteOffset,c.byteLength):new Uint8Array(c);for(let u=0;u<f.length;u+=32*1024){const p=f.subarray(u,u+32768);let x="";for(const d of p)x+=String.fromCharCode(d);this.socket.send(JSON.stringify({type:"data",data:btoa(x)}))}}close(){this.socket.close()}}function Vt(e){return e==="mac"||e==="linux"||e==="windows"}function Ht(e){const c=e==="mac"?[65513,"MetaLeft"]:[65507,"ControlLeft"],f=e==="mac"?c:[65515,"MetaLeft"];return{escape:[[65307,"Escape"]],enter:[[65293,"Enter"]],backspace:[[65288,"Backspace"]],tab:[e==="mac"?c:[65513,"AltLeft"],[65289,"Tab"]],search:e==="mac"?[f,[32,"Space"]]:[f],copy:[c,[99,"KeyC"]],paste:[c,[118,"KeyV"]],up:[[65362,"ArrowUp"]],down:[[65364,"ArrowDown"]],left:[[65361,"ArrowLeft"]],right:[[65363,"ArrowRight"]]}}function Bt(e){const c=e;return{size:()=>({width:c._fbWidth,height:c._fbHeight}),surface:()=>c._canvas,send:(f,u,p)=>{const x=c._display.scale,d=(f-c._display.absX(0))*x,s=(u-c._display.absY(0))*x;c._mousePos={x:d,y:s},c._mouseMoveTimer!==null&&clearTimeout(c._mouseMoveTimer),c._mouseMoveTimer=null,c._mouseButtonMask=p,c._mouseLastMoveTime=Date.now(),c._sendMouse(d,s,p)}}}const yt="termdock:computer-touch-mode:v1";function Kt(){try{const e=localStorage.getItem(yt);if(e==="trackpad"||e==="direct")return e}catch{}return navigator.maxTouchPoints>0&&window.matchMedia("(any-pointer: coarse)").matches?"trackpad":"direct"}function Yt(e){try{localStorage.setItem(yt,e)}catch{}}const Xt=8,Wt=300,qt=450,Be=18,Ce=(e,c)=>Math.max(0,Math.min(e,Math.max(0,c-1)));function Zt(e,c,f,u,p={}){const x=new AbortController,d=new Map;let s=0,v=0,g=!1,P=!1,W=!1,T=!1,k=0,A=1,a=0,N=0,b,C=!1,K=!0,H=!0,Z,w=!1;const D=()=>{const n=c.size(),l=u.current??={x:n.width/2,y:n.height/2};return l.x=Ce(l.x,n.width),l.y=Ce(l.y,n.height),l};let h;const R=()=>{const n=c.size();if((!h||h.width!==n.width||h.height!==n.height)&&(H=!0),!H&&h)return h;const l=c.surface(),S=e.getBoundingClientRect(),m=l.getBoundingClientRect(),y=[];for(let L=l.parentElement;L&&L!==e;L=L.parentElement){const j=getComputedStyle(L),$=/auto|scroll/.test(j.overflowX)?Math.max(0,L.scrollWidth-L.clientWidth):0,Re=/auto|scroll/.test(j.overflowY)?Math.max(0,L.scrollHeight-L.clientHeight):0;if(!$&&!Re)continue;const xe=L.getBoundingClientRect();y.push({element:L,left:xe.left-S.left,top:xe.top-S.top,right:xe.right-S.left,bottom:xe.bottom-S.top,maxX:$,maxY:Re})}return h={...n,left:m.left-S.left,top:m.top-S.top,scaleX:n.width&&m.width?m.width/n.width:1,scaleY:n.height&&m.height?m.height/n.height:1,viewportWidth:S.width,viewportHeight:S.height,clientLeft:S.left,clientTop:S.top,scrollers:y},H=!1,h},O=()=>{const n=R(),l=D();if(!n.width||!n.height||!K||T||p.mode==="direct"||p.viewOnly){f.hidden=!0;return}let S=n.left+l.x*n.scaleX,m=n.top+l.y*n.scaleY;for(const y of n.scrollers){if(y.maxX){const L=y.element.scrollLeft,j=S<y.left+20?S-y.left-20:S>y.right-20?S-y.right+20:0,$=Math.max(0,Math.min(y.maxX,L+j));L!==$&&(y.element.scrollLeft=$,S-=$-L,n.left-=$-L)}if(y.maxY){const L=y.element.scrollTop,j=m<y.top+20?m-y.top-20:m>y.bottom-20?m-y.bottom+20:0,$=Math.max(0,Math.min(y.maxY,L+j));L!==$&&(y.element.scrollTop=$,m-=$-L,n.top-=$-L)}}f.hidden=S<0||m<0||S>=n.viewportWidth||m>=n.viewportHeight,f.style.transform=`translate3d(${S}px, ${m}px, 0)`},E=(n=N)=>{if(p.viewOnly)return;const l=D();c.send(Math.round(l.x),Math.round(l.y),n)},ne=()=>{b=void 0,O(),C&&(C=!1,E());let n=0;for(;Math.abs(a)>=Be&&n++<8;){const l=a>0?16:8;E(l),E(0),a-=Math.sign(a)*Be}},U=()=>{w||(b??=requestAnimationFrame(ne))},ae=()=>{b!==void 0&&(cancelAnimationFrame(b),ne())},pe=()=>{clearTimeout(Z),ae(),N&&(N=0,E())},fe=n=>{n.cancelable&&n.preventDefault(),n.stopImmediatePropagation()},je=()=>[...d.values()].reduce((n,l)=>n+l.y,0)/d.size,he=()=>{const[n,l]=[...d.values()];return{distance:Math.hypot(n.x-l.x,n.y-l.y),x:(n.x+l.x)/2,y:(n.y+l.y)/2}},G=n=>{const l=R();u.current={x:Ce((n.clientX-l.clientLeft-l.left)/l.scaleX,l.width),y:Ce((n.clientY-l.clientTop-l.top)/l.scaleY,l.height)}},ke=n=>{if(!(n.pointerType!=="touch"&&n.pointerType!=="pen")){fe(n),K=!0,U(),d.size||(s=performance.now(),v=0,g=!1,P=!1,W=!1,T=!1,a=0,p.mode==="direct"&&G(n)),d.set(n.pointerId,{x:n.clientX,y:n.clientY,startX:n.clientX,startY:n.clientY}),v=Math.max(v,d.size);try{e.setPointerCapture(n.pointerId)}catch{}clearTimeout(Z),d.size===1&&v===1?Z=setTimeout(()=>{!w&&d.size===1&&!g&&!P&&(N=1,E())},qt):(pe(),W=!0,d.size===2&&(k=he().distance,A=p.zoom?.get()??1))}},ie=n=>{if(n.pointerType==="mouse"){const j=R();u.current={x:Ce((n.clientX-j.clientLeft-j.left)/j.scaleX,j.width),y:Ce((n.clientY-j.clientTop-j.top)/j.scaleY,j.height)},K=!1,f.hidden=!0;return}const l=d.get(n.pointerId);if(!l)return;fe(n);const S=je(),m=d.size===2?he():void 0,y=n.clientX-l.x,L=n.clientY-l.y;if(l.x=n.clientX,l.y=n.clientY,Math.hypot(l.x-l.startX,l.y-l.startY)>Xt&&(g=!0,clearTimeout(Z)),d.size===2&&!P){const j=he();if(p.zoom&&k>0&&(T||Math.abs(j.distance/k-1)>.06)){T=!0,g=!0,a=0,p.zoom.set(A*j.distance/k,j),H=!0,m&&p.zoom.pan(j.x-m.x,j.y-m.y),U();return}if(p.mode==="direct"&&p.zoom&&p.zoom.get()>1&&m){g=!0,p.zoom.pan(j.x-m.x,j.y-m.y),H=!0,U();return}a+=S-je(),Math.abs(a)>=Be&&(g=!0,U())}else if(d.size===1&&!W&&!P){if(p.mode==="direct"){G(n),g&&(N=1),C=!0,U();return}const j=D(),$=R();j.x+=y/$.scaleX,j.y+=L/$.scaleY,D(),C=!0,U()}},Y=n=>{if(!d.has(n.pointerId))return;fe(n);const l=N!==0;n.type!=="pointerup"&&(P=!0),pe(),d.delete(n.pointerId);try{e.hasPointerCapture(n.pointerId)&&e.releasePointerCapture(n.pointerId)}catch{}d.size||(a=0,!P&&!l&&!g&&v<=2&&performance.now()-s<=Wt&&(p.mode!=="direct"||v===1)&&(E(v===2?4:1),E(0)))},_=()=>{P=!0,pe();const n=[...d.keys()];d.clear(),a=0;for(const l of n)try{e.hasPointerCapture(l)&&e.releasePointerCapture(l)}catch{}},B={capture:!0,passive:!1,signal:x.signal};e.addEventListener("pointerdown",ke,B),e.addEventListener("pointermove",ie,B),e.addEventListener("pointerup",Y,B),e.addEventListener("pointercancel",Y,B),e.addEventListener("lostpointercapture",Y,B);for(const n of["touchstart","touchmove","touchend","touchcancel","contextmenu"])e.addEventListener(n,fe,B);const J=()=>{H=!0,U()};e.addEventListener("scroll",J,{capture:!0,signal:x.signal}),window.addEventListener("blur",_,{signal:x.signal});const Q=()=>{document.hidden&&_()};document.addEventListener("visibilitychange",Q,{signal:x.signal});const Ne=new ResizeObserver(J);return Ne.observe(e),Ne.observe(c.surface()),O(),()=>{w||(w=!0,x.abort(),_(),Ne.disconnect(),f.hidden=!0)}}function Gt(e,c){e=Math.max(1,e||1280),c=Math.max(1,c||800);const f=Math.max(1,640/e,480/c);return{width:Math.max(640,Math.min(2560,Math.round(e*f))),height:Math.max(480,Math.min(1600,Math.round(c*f)))}}const Ke="",Jt={Enter:"enter",Backspace:"backspace",Delete:"delete",Tab:"tab",ArrowUp:"up",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right"};function Qt({sendText:e,sendKey:c,inputRef:f,onFocusChange:u}){const{t:p}=gt(),x=o.useRef(null),d=o.useRef(!1),s=o.useRef(null),v=f??x,g=o.useRef({sendText:e,sendKey:c});g.current={sendText:e,sendKey:c};const[P,W]=o.useState(!1),T=()=>{v.current&&(v.current.value=Ke,v.current.setSelectionRange(1,1)),W(!1)},k=()=>{const a=(v.current?.value||"").replace(/^\u200b/,"");a&&g.current.sendText(a),T()},A=()=>{s.current!==null&&(cancelAnimationFrame(s.current),s.current=null),k()};return o.useLayoutEffect(()=>{const a=v.current;a.value=Ke,a.setSelectionRange(1,1),a.focus({preventScroll:!0});const N=b=>{if(d.current||b.isComposing)return;const C=b.inputType==="deleteContentBackward"?"backspace":b.inputType==="deleteContentForward"?"delete":["insertLineBreak","insertParagraph"].includes(b.inputType)?"enter":null;if(!C)return;b.preventDefault();const K=C==="enter"&&s.current!==null;A(),K||g.current.sendKey(C)};return a.addEventListener("beforeinput",N),()=>{a.removeEventListener("beforeinput",N),s.current!==null&&cancelAnimationFrame(s.current)}},[]),t.jsxs("div",{className:"relative shrink-0 border-t border-border bg-surface px-3 py-2",children:[!P&&t.jsx("span",{"aria-hidden":"true",className:"pointer-events-none absolute inset-y-2 left-6 flex items-center text-sm text-muted-foreground",children:p("computer.keyboardPlaceholder")}),t.jsx("input",{ref:v,className:"min-h-11 w-full rounded-md border border-border bg-background px-3 text-base outline-none focus:border-primary","aria-label":p("computer.keyboardInput"),autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",spellCheck:!1,inputMode:"text",enterKeyHint:"enter",maxLength:1025,defaultValue:Ke,onChange:a=>{if(W(!!a.target.value.replace(/^\u200b/,"")),d.current||a.nativeEvent.isComposing||s.current!==null)return;a.nativeEvent.inputType==="deleteContentBackward"&&!a.target.value?(g.current.sendKey("backspace"),T()):k()},onCompositionStart:()=>{s.current!==null&&A(),d.current=!0},onCompositionEnd:()=>{d.current=!1,s.current!==null&&cancelAnimationFrame(s.current),s.current=requestAnimationFrame(()=>{s.current=null,k()})},onFocus:()=>u?.(!0),onBlur:()=>{!d.current&&s.current!==null&&A(),u?.(!1)},onKeyDown:a=>{if(d.current||a.nativeEvent.isComposing||a.keyCode===229)return;const N=Jt[a.key];N&&(a.preventDefault(),A(),g.current.sendKey(N))}})]})}function er(e){let c=[],f=null;const u=new Map,p=()=>{f=null,c.splice(0,32).forEach(x=>{e(x),x[2]?u.set(x[0],x):u.delete(x[0])}),c.length&&(f=requestAnimationFrame(p))};return{send(x){c.push(...x),f===null&&p()},clear(){f!==null&&cancelAnimationFrame(f),f=null,c=[];const x=[...u.values()].reverse();u.clear();for(const[d,s]of x)try{e([d,s,!1])}catch{}}}}const tr=e=>Math.max(1,Math.min(8,Number.isFinite(e)?e:1));function rr(e,c){let f=1;const u="viewportZoom"in e,p=e,x=()=>u?e.pointerTarget.surface():p._canvas,d=()=>u?e.viewportScroller:p._screen,s=u?void 0:p._updateScale;return s&&(p._updateScale=function(){s.call(p),p._display.scale*=f}),{get:()=>f,set(v,g){const P=tr(v),W=x(),T=d(),k=W.getBoundingClientRect(),A=T.getBoundingClientRect(),a=g??{x:A.left+A.width/2,y:A.top+A.height/2},N={x:(a.x-k.left)/(k.width||1),y:(a.y-k.top)/(k.height||1)};f=P,u?e.viewportZoom=f:p._updateScale();const b=W.getBoundingClientRect();T.scrollLeft+=b.left+N.x*b.width-a.x,T.scrollTop+=b.top+N.y*b.height-a.y,f===1&&(T.scrollLeft=0,T.scrollTop=0),c(f)},pan(v,g){const P=d();P.scrollLeft-=v,P.scrollTop-=g},dispose(){s&&(p._updateScale=s)}}}const ce="inline-flex min-h-9 items-center justify-center gap-1.5 rounded-md border border-border px-2.5 text-xs hover:bg-surface-2 disabled:opacity-40",me="min-h-11 w-full rounded-md border border-border bg-background px-2 text-sm outline-none focus:border-primary";function Pe(e){return/API_NOT_ALLOWED|AUTHORIZATION|revoked|PAIRING/.test(e)?"computer.permission":e.includes("RDP_BACKEND_UNAVAILABLE")?"computer.rdpBackendUnavailable":e.includes("RDP_CERTIFICATE")?"computer.rdpCertificate":e.includes("CREDENTIALS_MISSING")?"computer.loginExpired":e.includes("CREDENTIALS_FAILED")?"computer.loginSaveFailed":e.includes("AUTH_FAILED")?"computer.authFailed":e.includes("RDP_FAILED")?"computer.rdpFailed":e.includes("SCREEN_SHARING_OFF")?"computer.sharingOff":e.includes("PRIVATE_HOST_ONLY")?"computer.privateOnly":e.includes("INVALID_HOST")?"computer.invalidHost":e.includes("TIMEOUT")?"computer.timeout":e.includes("UNREACHABLE")?"computer.unreachable":e.includes("DISCONNECTED")?"computer.disconnected":"computer.failed"}function nr(){const{t:e}=gt(),[c,f]=o.useState(()=>Ie()?.targetPeerId??""),[u,p]=o.useState(null),{preferences:x,change:d,loaded:s,saveState:v,flush:g,retry:P,credentialKeys:W,loginState:T,credentialRequest:k}=$t(c),A=x.target==="local",a=x[x.target],{host:N,platform:b,protocol:C,port:K,domain:H,ignoreCert:Z,username:w}=a,D=C==="rdp"&&u?.rdpAvailable===!1,{viewOnly:h,fit:R}=x,O=a.rememberLogin&&W.includes(bt(a)),E=r=>d(i=>({...i,[i.target]:{...i[i.target],...r}})),ne=r=>E({username:r}),U=r=>E({domain:r}),ae=r=>{E({ignoreCert:r}),g()},pe=r=>E({port:r}),fe=r=>{r&&(le.current(),Le.clear(),y(null)),d(i=>({...i,viewOnly:r})),g()},[je,he]=o.useState(!1),G=Ht(b),ke=b==="mac"?"⌘V":"Ctrl+V",[ie,Y]=o.useState(""),[_,B]=o.useState("idle"),[J,Q]=o.useState(null),[Ne,n]=o.useState(""),[l,S]=o.useState(!1),[m,y]=o.useState(null),L=o.useRef(null),[j,$]=o.useState(!1),[Re,xe]=o.useState(!1),Xe=o.useRef(0),[q,vt]=o.useState(()=>navigator.maxTouchPoints>0||window.innerWidth<=640);o.useEffect(()=>{const r=()=>vt(navigator.maxTouchPoints>0||window.innerWidth<=640);return window.addEventListener("resize",r),()=>window.removeEventListener("resize",r)},[]);const _e=m==="keyboard"&&j&&(!q||!window.visualViewport||Re),[Ee,We]=o.useState(1),ee=o.useRef(null),ze=o.useRef(null),[Me,qe]=o.useState(""),[wt,Se]=o.useState(!1),[Ct,jt]=o.useState(!1),[oe,kt]=o.useState(Kt),Ze=o.useRef(null),Ge=o.useRef(null),le=o.useRef(()=>{}),[Je,Nt]=o.useState(Ve),ve=o.useRef(!1),ue=o.useRef(""),Qe=o.useRef(()=>{}),et=o.useRef(null),Oe=o.useRef(null),ge=o.useMemo(()=>{const r=document.createElement("div");return r.className="h-full w-full min-h-0 overflow-hidden",r},[]),F=o.useRef(null),Le=o.useMemo(()=>er(([r,i,I])=>F.current?.sendKey(r,i,I)),[]),Fe=o.useRef(null),se=o.useRef(0),$e=o.useRef(void 0),te=o.useCallback(()=>{le.current(),ee.current?.dispose(),ee.current=null,Le.clear(),Ge.current=null,se.current++,clearTimeout($e.current);const r=F.current;F.current=null,r?.disconnect(),Fe.current?.close(),Fe.current=null,ge.replaceChildren()},[ge,Le]);o.useLayoutEffect(()=>(Oe.current?.appendChild(ge),()=>{ge.remove()}),[ge,l]),o.useEffect(()=>()=>te(),[te]),o.useEffect(()=>{const r=()=>{const i=Ve();Nt(i),!i&&(ve.current=!1,ue.current="",te(),B("idle"),Y(""),S(!1),y(null))};return window.addEventListener(it,r),()=>window.removeEventListener(it,r)},[te]),o.useEffect(()=>{const r=()=>f(Ie()?.targetPeerId??"");return window.addEventListener(lt,r),()=>window.removeEventListener(lt,r)},[]),o.useEffect(()=>{te(),ve.current=!1,ue.current="",B("idle"),Q(null),Y(""),p(null),S(!1),y(null),he(!1),n(""),qe(""),Se(!1);const r=new AbortController;return fetch("/api/computer/status",{signal:r.signal}).then(async i=>{if(!i.ok)throw new Error(i.status===403?"API_NOT_ALLOWED":"COMPUTER_FAILED");return await i.json()}).then(i=>{r.signal.aborted||p(i)}).catch(i=>{r.signal.aborted||Q(Pe(String(i)))}),()=>{r.abort(),te()}},[c,te]),o.useEffect(()=>{F.current&&(F.current.viewOnly=h)},[h]),o.useEffect(()=>{F.current&&(F.current.scaleViewport=R)},[R]),o.useEffect(()=>{F.current&&"pauseResize"in F.current&&(F.current.pauseResize=!!m)},[m]),o.useEffect(()=>{const r=F.current;r&&("keyboardActive"in r?r.keyboardActive=m==="keyboard":r.focusOnClick=m!=="keyboard")},[m]);const tt=r=>{r===A||X||!s||(Y(""),Q(null),d(i=>({...i,target:r?"local":"remote"})),g())},rt=()=>{ve.current=!0,ue.current="",te(),B("idle"),Y(""),S(!1),y(null),Se(!1)},nt=async r=>{if(r?.preventDefault(),D)return;if(ve.current=!0,_==="credentials"&&F.current&&"sendCredentials"in F.current){ue.current=ie,F.current.sendCredentials({username:w,password:ie}),B("connecting");return}if(!Ve()||!s||!ie&&!O)return;g(),te(),Q(null),n(""),B("connecting"),Se(!1);const i=se.current,I=z=>{i===se.current&&(te(),B("error"),Q(z),y(null),ue.current="",(z==="computer.authFailed"||z==="computer.permission"||z==="computer.loginExpired")&&Y(""),O&&(z==="computer.authFailed"||z==="computer.loginExpired")&&k("forget",a).catch(()=>{}))};$e.current=setTimeout(()=>I("computer.timeout"),6e4);try{let z=ie||await k("use",a);if(i!==se.current)return;ue.current=z||"";let V;if(C==="rdp"){const{RdpSession:re}=await ut(async()=>{const{RdpSession:Ue}=await import("./rdpSession-DtIeoTyy.js");return{RdpSession:Ue}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]));if(i!==se.current)return;const ye=window.innerWidth<=640,de=ze.current?.getBoundingClientRect(),Ae=Gt(ye?window.innerWidth:de?.width||1280,Math.max(1,(ye?window.innerHeight:de?.height||800)-100));V=new re(ge,{host:N.trim(),port:Number(K),username:w.trim(),password:z||"",domain:H.trim(),ignoreCert:Z,...Ae},Ue=>I(Pe(Ue)))}else{const{default:re}=await ut(async()=>{const{default:Ae}=await import("./rfb-CxsXsMUX.js");return{default:Ae}},[]);if(i!==se.current)return;const ye=new Ut(N.trim(),Ae=>I(Pe(Ae)));Fe.current=ye;const de=new re(ge,ye,{shared:!0,credentials:{username:w.trim()||void 0,password:z}});de.background="var(--chrome-bg)",de.resizeSession=!1,de.qualityLevel=6,de.compressionLevel=2,V=de}z=void 0,F.current=V,V.scaleViewport=R,V.viewOnly=h,V.addEventListener("connect",()=>{if(i!==se.current)return;clearTimeout($e.current),B("connected"),Y(""),window.innerWidth<=640&&(document.activeElement?.blur?.(),S(!0));const re=ue.current;ue.current="",a.rememberLogin&&re&&k("save",a,re).catch(()=>{})}),V.addEventListener("credentialsrequired",re=>{if(i!==se.current)return;const ye=re.detail.types;jt(ye.includes("username")),B("credentials")}),V.addEventListener("securityfailure",()=>I("computer.authFailed")),V.addEventListener("disconnect",()=>I("computer.disconnected")),V.addEventListener("desktopname",re=>{i===se.current&&n(re.detail.name)})}catch(z){I(Pe(String(z)))}},be=r=>{!F.current||_!=="connected"||h||Le.send([...r.map(([I,z])=>[I,z,!0]),...[...r].reverse().map(([I,z])=>[I,z,!1])])},M=_==="connected",X=_==="connecting"||_==="credentials";o.useEffect(()=>{const r=F.current;if(!M||!r||!("viewportZoom"in r)&&!("_display"in r))return;const i=rr(r,We);return ee.current=i,We(1),()=>{i.dispose(),ee.current===i&&(ee.current=null)}},[M]),o.useEffect(()=>{const r=F.current,i=Oe.current,I=Ze.current;if(!M||m&&m!=="keyboard"||oe!=="trackpad"&&!(navigator.maxTouchPoints>0)||!r||!i||!I)return;const z="pointerTarget"in r?r.pointerTarget:Bt(r),V=Zt(i,z,I,Ge,{mode:oe,zoom:ee.current??void 0,viewOnly:h});return le.current=V,()=>{V(),le.current===V&&(le.current=()=>{})}},[M,h,oe,l,m]);const ot=r=>{r!==oe&&(le.current(),kt(r),Yt(r))};Qe.current=()=>{nt()},o.useEffect(()=>{Je&&s&&u&&!D&&x.autoConnect&&O&&_==="idle"&&!ve.current&&Qe.current()},[Je,s,u,D,x.autoConnect,O,_]);const st=()=>{ve.current=!0,k("forget",a).catch(()=>{})},we=r=>{if(r==="keyboard"){if(m==="keyboard"&&!_e){L.current?.blur(),L.current?.focus({preventScroll:!0});return}le.current(),Xe.current=window.visualViewport?.height??window.innerHeight,dt.flushSync(()=>{$(!1),xe(!1),y(i=>i===r?null:r)})}else le.current(),y(i=>i===r?null:r)},Et=()=>{ee.current?.set(1),d(r=>({...r,fit:!0})),g()},St=r=>{if(!F.current||h)return;const i=[];for(const I of r){const z=I.codePointAt(0),V=I===`
|
|
3
|
-
`?65293:I===" "?65289:z<256?z:16777216|z;i.push([V,null,!0],[V,null,!1])}Le.send(i)};o.useEffect(()=>{if(!M||m!=="keyboard"&&m!=="clipboard"||!window.visualViewport)return;const r=window.visualViewport,i=ze.current,I=()=>{m==="keyboard"&&xe(j&&Xe.current-r.height>100),l&&i&&r.height>=160&&(i.style.height=`${r.height}px`,i.style.top=`${r.offsetTop}px`)};return I(),r.addEventListener("resize",I),r.addEventListener("scroll",I),()=>{r.removeEventListener("resize",I),r.removeEventListener("scroll",I),i&&(i.style.height="",i.style.top="")}},[M,m,l,j]);const ct=t.jsxs("div",{className:"flex shrink-0 items-center text-xs",role:"group","aria-label":e("computer.desktopZoom"),title:q?e("computer.pinchHint"):void 0,children:[t.jsx("button",{type:"button",className:"flex min-h-11 min-w-11 items-center justify-center","aria-label":e("computer.zoomOut"),disabled:Ee<=1,onPointerDown:r=>r.preventDefault(),onClick:()=>ee.current?.set(Ee/1.25),children:t.jsx(Ft,{size:16})}),t.jsxs("button",{type:"button",className:"min-h-11 min-w-11","aria-label":e("computer.resetZoom"),onPointerDown:r=>r.preventDefault(),onClick:Et,children:[Math.round(Ee*100),"%"]}),t.jsx("button",{type:"button",className:"flex min-h-11 min-w-11 items-center justify-center","aria-label":e("computer.zoomIn"),disabled:Ee>=8,onPointerDown:r=>r.preventDefault(),onClick:()=>ee.current?.set(Ee*1.25),children:t.jsx(zt,{size:16})}),q&&t.jsx("span",{className:"hidden pr-2 text-[10px] text-muted-foreground sm:inline",children:e("computer.pinchHint")})]}),Te=`flex shrink-0 items-center justify-center rounded-md hover:bg-surface-2 focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary ${q?"min-h-11 min-w-11":"h-8 min-w-8"}`,at=t.jsxs("div",{ref:ze,className:`flex min-h-0 flex-col bg-surface text-foreground ${l?"fixed inset-0 z-modal-panel h-dvh pb-[env(safe-area-inset-bottom)] pt-[env(safe-area-inset-top)]":"relative h-full"}`,role:l?"dialog":void 0,"aria-modal":l||void 0,"aria-label":e("computer.title"),onKeyDown:r=>{r.stopPropagation(),r.key==="Escape"&&!r.nativeEvent.isComposing&&m&&(r.preventDefault(),y(null))},onKeyUp:r=>r.stopPropagation(),children:[t.jsxs("div",{className:`relative z-30 flex shrink-0 items-center gap-2 border-b border-border bg-surface px-2 ${q?"min-h-12":"min-h-8"}`,children:[l&&t.jsx("button",{type:"button",className:Te,onClick:()=>{S(!1),y(null)},"aria-label":e("computer.exitFullscreen"),children:t.jsx(Rt,{size:20})}),t.jsx(Tt,{size:16,className:"shrink-0 text-muted-foreground"}),t.jsx("span",{className:"min-w-0 flex-1 truncate text-xs font-medium",children:M&&(Ne||(A?u?.hostname||Ie()?.serviceName:N))||e("computer.title")}),M&&t.jsx("span",{className:"text-[11px] text-primary",children:e("computer.connected")}),M&&T==="error"&&t.jsx("span",{role:"alert",className:"text-[11px] text-destructive",children:e("computer.loginSaveFailed")}),M&&v==="saving"&&t.jsx("span",{role:"status","aria-label":e("computer.settingsSaving"),title:e("computer.settingsSaving"),children:t.jsx(mt,{size:12,className:"animate-spin text-muted-foreground"})}),M&&v==="error"&&t.jsxs("button",{type:"button",className:ce,title:e("computer.settingsSaveFailed"),"aria-label":e("computer.settingsSaveFailed"),onClick:P,children:["! ",e("computer.retry")]}),X&&t.jsxs("button",{type:"button",className:ce,onClick:rt,children:[t.jsx(pt,{size:14}),e("computer.cancel")]}),M&&!q&&m==="keyboard"&&t.jsx("button",{type:"button",className:Te,onClick:()=>we("keyboard"),"aria-label":e("computer.keyboard"),"aria-pressed":_e,children:t.jsx(He,{size:18})}),M&&!q&&t.jsx("button",{type:"button",className:`${Te} ${m==="clipboard"?"bg-surface-2 text-primary":""}`,disabled:h,onClick:()=>we("clipboard"),"aria-label":e("computer.clipboardTool"),title:e("computer.clipboardTool"),"aria-pressed":m==="clipboard",children:t.jsx(ft,{size:18})}),M&&!l&&t.jsxs("button",{type:"button",className:`${Te} gap-1 px-1 text-xs`,onClick:()=>S(!0),"aria-label":e("computer.fullscreen"),children:[t.jsx(_t,{size:16}),e("computer.expand")]}),M&&t.jsx("button",{type:"button",className:Te,onClick:()=>we("tools"),"aria-label":e("computer.tools"),"aria-expanded":m==="tools",children:t.jsx(Pt,{size:18})})]}),!M&&t.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto p-4 sm:p-6",children:t.jsxs("div",{className:"mx-auto w-full max-w-md",children:[t.jsxs("form",{className:"space-y-3",onSubmit:r=>{nt(r)},"aria-busy":_==="connecting",children:[t.jsxs("div",{className:"grid grid-cols-2 gap-1 rounded-lg bg-background p-1",role:"group","aria-label":e("computer.target"),children:[t.jsx("button",{type:"button",className:`min-h-11 rounded-md px-3 text-sm font-medium ${A?"bg-surface-2 text-foreground":"text-muted-foreground hover:bg-surface"}`,"aria-pressed":A,disabled:X||!u||!s,onClick:()=>tt(!0),children:e("computer.thisComputer")}),t.jsx("button",{type:"button",className:`min-h-11 rounded-md px-3 text-sm font-medium ${A?"text-muted-foreground hover:bg-surface":"bg-surface-2 text-foreground"}`,"aria-pressed":!A,disabled:X||!s,onClick:()=>tt(!1),children:e("computer.otherComputer")})]}),A?t.jsx("p",{className:"text-xs leading-relaxed text-muted-foreground",role:"status",children:u?e("computer.localService",{name:Ie()?.serviceName||u.hostname}):e("computer.loading")}):t.jsxs("label",{className:"block space-y-1 text-xs",children:[t.jsx("span",{children:e("computer.host")}),t.jsx("input",{className:me,value:N,disabled:X||!s,onChange:r=>{E({host:r.target.value,domain:"",ignoreCert:!1}),Y(""),Q(null)},placeholder:e("computer.hostPlaceholder"),onBlur:()=>{g()},autoCapitalize:"none",autoCorrect:"off",spellCheck:!1,required:!0,maxLength:253})]}),t.jsxs("p",{className:"text-xs text-muted-foreground",children:[b==="mac"?"macOS":b==="linux"?"Ubuntu / Linux":"Windows"," · ",C.toUpperCase()," · ",C==="rdp"?K||"3389":"5900",h?` · ${e("computer.viewOnly")}`:""]}),t.jsxs("label",{className:"block space-y-1 text-xs",children:[t.jsx("span",{children:e(C==="rdp"?"computer.rdpUsername":"computer.username")}),t.jsx("input",{className:me,value:w,disabled:_==="connecting"||!s,onChange:r=>ne(r.target.value),onBlur:()=>{g()},autoCapitalize:"none",autoCorrect:"off",autoComplete:"off",required:C==="rdp"||_==="credentials"&&Ct,maxLength:255})]}),t.jsxs("label",{className:"block space-y-1 text-xs",children:[t.jsx("span",{children:e("computer.password")}),t.jsx("input",{className:me,type:"password",value:ie,disabled:_==="connecting"||!s,onChange:r=>Y(r.target.value),placeholder:O&&_!=="credentials"?e("computer.savedPassword"):void 0,autoComplete:"new-password",required:!O||_==="credentials",maxLength:1024})]}),t.jsx("p",{className:"text-[11px] leading-relaxed text-muted-foreground",children:e(C==="rdp"?"computer.rdpLoginHint":"computer.vncLoginHint")}),t.jsxs("div",{className:"flex min-h-11 items-center justify-between gap-2 text-xs",children:[t.jsxs("label",{className:"flex min-h-11 items-center gap-2",children:[t.jsx("input",{type:"checkbox",checked:a.rememberLogin,disabled:X||!s||T==="saving",onChange:r=>{const i=r.target.checked;E({rememberLogin:i}),!i&&O?k("forget",{...a,rememberLogin:i}).catch(()=>{}):g()}}),e("computer.rememberLogin")]}),O&&t.jsx("button",{type:"button",className:"min-h-11 text-muted-foreground underline",disabled:X||T==="saving",onClick:st,children:e("computer.forgetLogin")})]}),T==="error"&&!J&&t.jsx("p",{role:"alert",className:"text-xs text-destructive",children:e("computer.loginSaveFailed")}),D&&t.jsxs("div",{role:"status",className:"space-y-1 text-xs leading-relaxed text-muted-foreground",children:[t.jsx("p",{children:e("computer.rdpBackendUnavailable")}),t.jsx("p",{children:e("computer.rdpBackendRecovery")})]}),_==="credentials"&&t.jsx("p",{className:"text-xs text-primary",children:e("computer.credentials")}),J&&t.jsxs("div",{role:"alert",className:"rounded-md bg-surface-2 p-3 text-xs leading-relaxed text-destructive",children:[e(J),J==="computer.rdpCertificate"&&t.jsxs("label",{className:"mt-1 flex min-h-11 items-center gap-2 text-foreground",children:[t.jsx("input",{type:"checkbox",checked:Z,onChange:r=>ae(r.target.checked)}),e("computer.trustCertificateHere")]}),_==="error"&&J!=="computer.rdpCertificate"&&t.jsx("button",{type:"button",className:"mt-1 block min-h-9 text-foreground underline",onClick:()=>{he(!0),requestAnimationFrame(()=>et.current?.scrollIntoView?.({block:"nearest",behavior:"smooth"}))},children:e("computer.checkSettings")})]}),t.jsxs("button",{type:"submit",className:"inline-flex min-h-11 w-full items-center justify-center gap-2 rounded-md bg-primary px-3 text-sm font-medium text-primary-foreground disabled:opacity-40",disabled:!s||D||_==="connecting"||T==="saving"||A&&!u||!N.trim()||!ie&&(!O||_==="credentials")||C==="rdp"&&(!w.trim()||!Number.isInteger(Number(K))||Number(K)<1||Number(K)>65535),children:[_==="connecting"&&t.jsx(mt,{size:16,className:"animate-spin"}),e(_==="connecting"?"computer.connecting":_==="credentials"?"computer.authenticate":_==="error"?"computer.retryConnect":"computer.connect")]}),t.jsxs("details",{ref:et,className:"border-b border-border text-xs",open:je,onToggle:r=>he(r.currentTarget.open),children:[t.jsxs("summary",{className:"flex min-h-11 cursor-pointer list-none items-center justify-between text-muted-foreground",children:[t.jsx("span",{children:e("computer.advanced")}),t.jsx("span",{"aria-hidden":"true",children:je?"−":"+"})]}),t.jsxs("div",{className:"space-y-3 pb-4",children:[t.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[t.jsxs("label",{className:"block space-y-1",children:[t.jsx("span",{children:e("computer.platform")}),t.jsxs("select",{className:me,value:b,disabled:X||!s,onChange:r=>{Vt(r.target.value)&&E({platform:r.target.value,protocol:r.target.value==="mac"?"vnc":"rdp",ignoreCert:!1}),Y(""),g()},children:[t.jsx("option",{value:"mac",children:"macOS"}),t.jsx("option",{value:"linux",children:"Ubuntu / Linux"}),t.jsx("option",{value:"windows",children:"Windows"})]})]}),t.jsxs("label",{className:"block space-y-1",children:[t.jsx("span",{children:e("computer.protocol")}),t.jsxs("select",{className:me,value:C,disabled:X||!s,onChange:r=>{E({protocol:r.target.value==="rdp"?"rdp":"vnc"}),Y(""),Q(null),g()},children:[t.jsx("option",{value:"rdp",children:"RDP"}),t.jsx("option",{value:"vnc",children:"VNC"})]})]})]}),C==="rdp"&&t.jsxs(t.Fragment,{children:[t.jsxs("label",{className:"block space-y-1",children:[t.jsx("span",{children:e("computer.port")}),t.jsx("input",{className:me,type:"number",min:1,max:65535,step:1,value:K,disabled:X||!s,onBlur:()=>{g()},onChange:r=>pe(r.target.value)})]}),t.jsxs("label",{className:"block space-y-1",children:[t.jsx("span",{children:e("computer.domain")}),t.jsx("input",{className:me,value:H,disabled:X||!s,onBlur:()=>{g()},onChange:r=>U(r.target.value),autoComplete:"off",maxLength:255})]}),t.jsxs("label",{className:"flex min-h-11 items-center gap-2",children:[t.jsx("input",{type:"checkbox",checked:Z,disabled:X||!s,onChange:r=>ae(r.target.checked)}),e("computer.trustCertificate")]})]}),t.jsxs("label",{className:"flex min-h-11 items-center gap-2",children:[t.jsx("input",{type:"checkbox",checked:h,disabled:X||!s,onChange:r=>fe(r.target.checked)}),e("computer.viewOnly")]}),t.jsxs("label",{className:"flex min-h-11 items-center gap-2",children:[t.jsx("input",{type:"checkbox",checked:x.autoConnect,disabled:X||!s,onChange:r=>{d(i=>({...i,autoConnect:r.target.checked})),g()}}),e("computer.autoConnect")]})]})]})]}),t.jsxs("p",{role:"status",className:"mt-2 text-[11px] leading-relaxed text-muted-foreground",children:[e(v==="saved"?"computer.settingsSaved":v==="error"?s?"computer.settingsSaveFailed":"computer.settingsLoadFailed":v==="loading"?"computer.settingsLoading":"computer.settingsSaving"),v==="error"&&t.jsx("button",{type:"button",className:"ml-2 min-h-9 text-primary underline",onClick:P,children:e("computer.retry")})]}),t.jsxs("details",{className:"text-xs",children:[t.jsx("summary",{className:"flex min-h-11 cursor-pointer items-center text-muted-foreground",children:e("computer.setup")}),t.jsxs("ol",{className:"ml-4 list-decimal space-y-2 pt-2 leading-relaxed text-muted-foreground",children:[t.jsx("li",{children:e(C==="rdp"?b==="linux"?"computer.rdpLinuxStep1":"computer.rdpStep1":b==="mac"?"computer.step1":b==="linux"?"computer.linuxStep1":"computer.windowsStep1")}),t.jsx("li",{children:e(C==="rdp"?"computer.rdpStep2":b==="mac"?"computer.step2":b==="linux"?"computer.linuxStep2":"computer.windowsStep2")}),t.jsx("li",{children:e("computer.step3")})]}),C==="vnc"&&b==="linux"&&t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"mt-3 leading-relaxed text-muted-foreground",children:e("computer.linuxCommandHint")}),t.jsx("pre",{className:"mt-2 overflow-x-auto rounded-md bg-background p-2 text-[11px]",children:t.jsx("code",{children:`sudo apt install x11vnc
|
|
4
|
-
x11vnc -storepasswd
|
|
5
|
-
x11vnc -display "$DISPLAY" -auth guess -localhost -usepw -forever -shared -rfbport 5900`})}),t.jsx("p",{className:"mt-2 leading-relaxed text-muted-foreground",children:e("computer.linuxProtocolHint")})]}),t.jsx("p",{className:"mt-3 leading-relaxed text-muted-foreground",children:e(C==="rdp"?"computer.rdpNetworkHint":"computer.networkHint")})]})]})}),M&&m==="tools"&&t.jsx("button",{type:"button",className:`absolute inset-x-0 ${q?"bottom-14 top-12":"bottom-0 top-8"} z-20 bg-background/40`,"aria-label":e("computer.returnToDesktop"),onClick:()=>y(null)}),M&&t.jsxs("div",{hidden:m!=="tools",className:`${m==="tools"?"flex":"hidden"} absolute inset-x-3 ${q?"top-14":"top-10"} z-30 max-h-[calc(100%-7rem)] flex-wrap items-center gap-3 overflow-y-auto rounded-lg border border-border bg-surface px-4 py-3 text-xs shadow-lg [&_button]:min-h-11 [&_select]:min-h-11 [&_label]:min-h-11`,role:"region","aria-label":e("computer.tools"),children:[t.jsxs("div",{className:"flex w-full items-center justify-between",children:[t.jsx("span",{className:"font-medium",children:e("computer.tools")}),t.jsx("button",{type:"button",className:"flex min-w-11 items-center justify-center","aria-label":e("computer.closeTools"),onClick:()=>y(null),children:t.jsx(At,{size:18})})]}),q&&t.jsx("div",{className:"flex w-full items-center gap-2",children:t.jsx("div",{className:"inline-flex rounded-md bg-background p-0.5",role:"group","aria-label":e("computer.touchMode"),children:["trackpad","direct"].map(r=>t.jsx("button",{type:"button",className:`min-h-9 rounded px-3 text-xs ${oe===r?"bg-surface-2 text-foreground":"text-muted-foreground hover:bg-surface"}`,"aria-pressed":oe===r,onClick:()=>ot(r),children:e(r==="trackpad"?"computer.trackpadMode":"computer.directTouchMode")},r))})}),!q&&t.jsxs(t.Fragment,{children:[ct,t.jsxs("button",{type:"button",className:ce,disabled:h,onClick:()=>we("keyboard"),children:[t.jsx(He,{size:14}),e("computer.keyboard")]})]}),t.jsxs("label",{className:"flex min-h-9 items-center gap-1.5",children:[t.jsx("input",{type:"checkbox",checked:h,onChange:r=>fe(r.target.checked)}),e("computer.viewOnly")]}),t.jsx("button",{type:"button",className:ce,onClick:()=>{ee.current?.set(1),d(r=>({...r,fit:!r.fit})),g()},children:e(R?"computer.actualSize":"computer.fit")}),t.jsxs("select",{className:`${ce} min-w-0 bg-surface`,"aria-label":e("computer.shortcuts"),value:"",disabled:h,onChange:r=>{be(G[r.target.value]??[])},children:[t.jsx("option",{value:"",disabled:!0,children:e("computer.shortcuts")}),t.jsxs("option",{value:"tab",children:[b==="mac"?"⌘ Tab":"Alt+Tab"," · ",e("computer.switchApps")]}),t.jsxs("option",{value:"search",children:[b==="mac"?"⌘ Space":"Super / Win"," · ",e(b==="mac"?"computer.spotlight":"computer.systemSearch")]}),t.jsx("option",{value:"copy",children:b==="mac"?"⌘C":"Ctrl+C"}),t.jsx("option",{value:"paste",children:ke}),t.jsx("option",{value:"escape",children:"Esc"}),t.jsx("option",{value:"enter",children:"Enter"}),t.jsx("option",{value:"backspace",children:"⌫"}),t.jsx("option",{value:"up",children:"↑"}),t.jsx("option",{value:"down",children:"↓"}),t.jsx("option",{value:"left",children:"←"}),t.jsx("option",{value:"right",children:"→"})]}),t.jsxs("div",{className:"flex w-full items-center justify-between border-t border-border pt-2",children:[O&&t.jsx("button",{type:"button",className:ce,disabled:T==="saving",onClick:st,children:e("computer.forgetLogin")}),t.jsxs("button",{type:"button",className:`${ce} ml-auto text-destructive`,onClick:rt,children:[t.jsx(pt,{size:14}),e("computer.disconnect")]})]})]}),t.jsx("div",{ref:Oe,"data-sidebar-gesture-ignore":"",className:`relative z-10 min-h-0 flex-1 overflow-hidden bg-[var(--chrome-bg)] ${M?"":"hidden"}`,onMouseDownCapture:r=>{m==="keyboard"&&r.preventDefault()},style:{touchAction:M?"none":void 0},"aria-label":e("computer.remoteTitle"),children:M&&t.jsx("div",{ref:Ze,hidden:!0,"aria-hidden":"true",className:"pointer-events-none absolute left-0 top-0 z-20 h-5 w-5 will-change-transform",children:t.jsx(ht,{size:20,strokeWidth:2,className:"fill-background text-primary drop-shadow"})})}),t.jsx("div",{hidden:m!=="tools",children:M&&q&&!h&&t.jsx("p",{className:"shrink-0 border-t border-border px-2 py-1 text-[10px] leading-relaxed text-muted-foreground",children:e(oe==="trackpad"?"computer.trackpadHint":"computer.directTouchHint")})}),M&&m==="keyboard"&&!h&&t.jsxs(t.Fragment,{children:[t.jsx(Qt,{inputRef:L,onFocusChange:$,sendText:St,sendKey:r=>be(r==="tab"?[[65289,"Tab"]]:r==="delete"?[[65535,"Delete"]]:G[r])}),t.jsx("div",{className:"grid shrink-0 grid-cols-6 gap-1 bg-surface px-1",role:"group","aria-label":e("computer.keyboardNavigation"),children:["escape","left","down","up","right","selectAll"].map(r=>t.jsx("button",{type:"button",className:"min-h-11 rounded-md text-sm hover:bg-surface-2","aria-label":e(`computer.key${r[0].toUpperCase()}${r.slice(1)}`),onPointerDown:i=>i.preventDefault(),onClick:()=>be(r==="selectAll"?[...G.copy.slice(0,1),[97,"KeyA"]]:G[r]),children:{escape:"Esc",left:"←",down:"↓",up:"↑",right:"→",selectAll:b==="mac"?"⌘A":"Ctrl+A"}[r]},r))})]}),M&&m==="clipboard"&&!h&&t.jsxs("form",{className:"shrink-0 space-y-2 border-t border-border p-3",onSubmit:r=>{if(r.preventDefault(),!(!Me||!F.current))try{F.current.clipboardPasteFrom(Me),Se(!0)}catch{Q("computer.clipboardFailed")}},children:[t.jsx("textarea",{className:`${me} min-w-0 resize-none py-2 text-base`,rows:2,"aria-label":e("computer.clipboard"),placeholder:e("computer.clipboardPlaceholder"),value:Me,onChange:r=>{qe(r.target.value),Se(!1)},maxLength:16384}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx("button",{type:"submit",className:`${ce} min-h-11 flex-1`,disabled:!Me,children:e("computer.clipboard")}),t.jsx("button",{type:"button",className:`${ce} min-h-11`,onClick:()=>be(G.paste),children:ke})]}),t.jsx("p",{role:"status",className:"text-[10px] leading-relaxed text-muted-foreground",children:wt?e("computer.clipboardSent"):e("computer.clipboardHint",{shortcut:ke})}),J&&t.jsx("p",{role:"alert",className:"text-xs text-destructive",children:e(J)})]}),M&&q&&t.jsxs("div",{className:"relative z-30 flex shrink-0 items-center border-t border-border bg-surface px-1 py-1 text-[11px]",children:[t.jsxs("div",{className:`grid min-w-0 flex-1 ${m==="keyboard"?"grid-cols-5":"grid-cols-3"}`,children:[t.jsxs("button",{type:"button",className:`flex min-h-11 flex-col items-center justify-center gap-0.5 rounded-md ${_e?"bg-surface-2 text-primary":""}`,disabled:h,onClick:()=>we("keyboard"),"aria-pressed":_e,children:[t.jsx(He,{size:18}),e("computer.keyboard")]}),t.jsxs("button",{type:"button",className:`flex min-h-11 flex-col items-center justify-center gap-0.5 rounded-md ${m==="clipboard"?"bg-surface-2 text-primary":""}`,disabled:h,onClick:()=>we("clipboard"),"aria-pressed":m==="clipboard",children:[t.jsx(ft,{size:18}),e("computer.clipboardTool")]}),m==="keyboard"?t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",className:"min-h-11 rounded-md text-sm",onPointerDown:r=>r.preventDefault(),onClick:()=>be([[65289,"Tab"]]),children:"Tab"}),t.jsx("button",{type:"button",className:"min-h-11 rounded-md text-lg",onPointerDown:r=>r.preventDefault(),onClick:()=>be(G.backspace),children:"⌫"}),t.jsx("button",{type:"button",className:"min-h-11 rounded-md text-lg",onPointerDown:r=>r.preventDefault(),onClick:()=>be(G.enter),children:"↵"})]}):t.jsx(t.Fragment,{children:t.jsxs("button",{type:"button",className:"flex min-h-11 flex-col items-center justify-center gap-0.5 rounded-md",disabled:h,onClick:()=>ot(oe==="trackpad"?"direct":"trackpad"),"aria-label":e("computer.switchTouchMode"),children:[t.jsx(ht,{size:18}),e(oe==="trackpad"?"computer.trackpadMode":"computer.directTouchMode")]})})]}),ct]})]});return l?dt.createPortal(at,document.body):at}const lr=Object.freeze(Object.defineProperty({__proto__:null,default:nr},Symbol.toStringTag,{value:"Module"}));export{lr as C,Gt as c};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as a,C as n}from"./mermaid.core-BmSOfxMH.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as t,C as e}from"./chunk-TICWLB2K-DViVpzs1.js";import{d as i}from"./mermaid.core-BmSOfxMH.js";import"./chunk-5VM5RSS4-lfjEsOLd.js";import"./chunk-XXDRQBXY-Cyg6qo-b.js";import"./chunk-POPQ4Y6H-1UAKkjro.js";import"./chunk-F27PBJKO-B3iWUfsu.js";import"./purify.es-4eNOHKSq.js";import"./app-D2yRvfNE.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as t,C as e}from"./chunk-TICWLB2K-DViVpzs1.js";import{d as i}from"./mermaid.core-BmSOfxMH.js";import"./chunk-5VM5RSS4-lfjEsOLd.js";import"./chunk-XXDRQBXY-Cyg6qo-b.js";import"./chunk-POPQ4Y6H-1UAKkjro.js";import"./chunk-F27PBJKO-B3iWUfsu.js";import"./purify.es-4eNOHKSq.js";import"./app-D2yRvfNE.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|